clk: nuvoton: add read only feature for clk driver
Add a flag to set ahb/apb/fiu/spi clock divider as read-only
The spi clock setting is related to booting flash, it is setup by early
bootloader.
It just protects the clock source and can't modify it in uboot.
Signed-off-by: Jim Liu <JJLIU0@nuvoton.com>
Reviewed-by: Sean Anderson <seanga2@gmail.com>
Link: https://lore.kernel.org/r/20231114090004.3746024-1-JJLIU0@nuvoton.com
diff --git a/drivers/clk/nuvoton/clk_npcm.c b/drivers/clk/nuvoton/clk_npcm.c
index 8d71f2a..18cb9cd 100644
--- a/drivers/clk/nuvoton/clk_npcm.c
+++ b/drivers/clk/nuvoton/clk_npcm.c
@@ -135,7 +135,7 @@
return div;
}
-static u32 npcm_clk_set_div(struct clk *clk, u32 div)
+static int npcm_clk_set_div(struct clk *clk, u32 div)
{
struct npcm_clk_priv *priv = dev_get_priv(clk->dev);
struct npcm_clk_div *divider;
@@ -145,6 +145,9 @@
if (!divider)
return -EINVAL;
+ if (divider->flags & DIV_RO)
+ return 0;
+
if (divider->flags & PRE_DIV2)
div = div >> 1;
@@ -153,6 +156,12 @@
else
clkdiv = ilog2(div);
+ if (clkdiv > (divider->mask >> (ffs(divider->mask) - 1))) {
+ printf("clkdiv(%d) for clk(%ld) is over limit\n",
+ clkdiv, clk->id);
+ return -EINVAL;
+ }
+
val = readl(priv->base + divider->reg);
val &= ~divider->mask;
val |= (clkdiv << (ffs(divider->mask) - 1)) & divider->mask;
@@ -253,8 +262,8 @@
if (ret)
return ret;
- debug("%s: rate %lu, new rate (%lu / %u)\n", __func__, rate, parent_rate, div);
- return (parent_rate / div);
+ debug("%s: rate %lu, new rate %lu\n", __func__, rate, npcm_clk_get_rate(clk));
+ return npcm_clk_get_rate(clk);
}
static int npcm_clk_set_parent(struct clk *clk, struct clk *parent)