* [PATCH 0/3] clk: nuvoton: ma35d1: fix parent lookup and use the generic ADC divider
@ 2026-10-12 6:30 Joey Lu
2026-10-12 6:30 ` [PATCH 1/3] clk: nuvoton: ma35d1: fix parent lookup for clk_parent_data entries Joey Lu
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Joey Lu @ 2026-10-12 6:30 UTC (permalink / raw)
To: sboyd
Cc: ychuang3, schung, yclu4, arnd, bmasney+clk, jbrunet+clk,
linux-arm-kernel, linux-clk, linux-kernel, Joey Lu
The parent tables of the MA35D1 clock controller were converted to
struct clk_parent_data with only .fw_name set, but the controller node
has no clock-names, so the firmware lookup can never succeed and the clk
core only falls back to a global name lookup when .name is set. As a
result sysclk1_mux and everything below it (hclk*, pclk*, and the
peripheral dividers and gates) are orphans with a rate of 0 Hz, and
clk_set_rate() on their consumers returns early without programming the
hardware. This was found while testing the ADC clock, whose divider
register was never written.
Patch 1 fixes the parent lookup. Patches 2 and 3 replace the dedicated
ADC divider driver with the generic clk divider, as suggested in review
of the earlier "use direct formula instead of divider table" series,
which is dropped in favour of this one.
The earlier series:
https://lore.kernel.org/r/20261008064307.2757324-1-a0987203069@gmail.com
Joey Lu (3):
clk: nuvoton: ma35d1: fix parent lookup for clk_parent_data entries
clk: nuvoton: ma35d1: use the generic divider for the ADC clock
clk: nuvoton: ma35d1: remove the unused ADC divider driver
drivers/clk/nuvoton/Makefile | 1 -
drivers/clk/nuvoton/clk-ma35d1-divider.c | 133 -----------
drivers/clk/nuvoton/clk-ma35d1.c | 269 ++++++++++++-----------
drivers/clk/nuvoton/clk-ma35d1.h | 5 -
4 files changed, 135 insertions(+), 273 deletions(-)
delete mode 100644 drivers/clk/nuvoton/clk-ma35d1-divider.c
--
2.43.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/3] clk: nuvoton: ma35d1: fix parent lookup for clk_parent_data entries
2026-10-12 6:30 [PATCH 0/3] clk: nuvoton: ma35d1: fix parent lookup and use the generic ADC divider Joey Lu
@ 2026-10-12 6:30 ` Joey Lu
2026-10-12 6:30 ` [PATCH 2/3] clk: nuvoton: ma35d1: use the generic divider for the ADC clock Joey Lu
2026-10-12 6:30 ` [PATCH 3/3] clk: nuvoton: ma35d1: remove the unused ADC divider driver Joey Lu
2 siblings, 0 replies; 4+ messages in thread
From: Joey Lu @ 2026-10-12 6:30 UTC (permalink / raw)
To: sboyd
Cc: ychuang3, schung, yclu4, arnd, bmasney+clk, jbrunet+clk,
linux-arm-kernel, linux-clk, linux-kernel, Joey Lu
The parent tables were converted to struct clk_parent_data with only
.fw_name set, for example { .fw_name = "hxt" }. The clock controller
node has a single "clocks" entry for the external crystal and no
"clock-names", so a firmware lookup by name can never succeed. The clk
core falls back to a global name lookup only when .name is set, so these
parents are never resolved.
As a result sysclk1_mux and everything below it (hclk*, pclk*, and the
peripheral dividers and gates) stay orphans with a rate of 0, and
clk_set_rate() on any of their consumers returns early without
programming the hardware.
Set .name as well as .fw_name on every entry so the lookup falls back to
the globally registered clock of that name. .fw_name is kept so the
tables still work if clock-names is ever added to the binding.
Fixes: f50a000b4219 ("clk: nuvoton: Use clk_parent_data instead of string for parent clock")
Signed-off-by: Joey Lu <a0987203069@gmail.com>
---
drivers/clk/nuvoton/clk-ma35d1.c | 260 +++++++++++++++----------------
1 file changed, 130 insertions(+), 130 deletions(-)
diff --git a/drivers/clk/nuvoton/clk-ma35d1.c b/drivers/clk/nuvoton/clk-ma35d1.c
index 9f65d0623517a..09e6ceeb2c556 100644
--- a/drivers/clk/nuvoton/clk-ma35d1.c
+++ b/drivers/clk/nuvoton/clk-ma35d1.c
@@ -63,298 +63,298 @@ static DEFINE_SPINLOCK(ma35d1_lock);
#define PLL_MODE_SS 2
static const struct clk_parent_data ca35clk_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "capll", },
- { .fw_name = "ddrpll", },
+ { .fw_name = "hxt", .name = "hxt", },
+ { .fw_name = "capll", .name = "capll", },
+ { .fw_name = "ddrpll", .name = "ddrpll", },
};
static const struct clk_parent_data sysclk0_sel_clks[] = {
- { .fw_name = "epll_div2", },
- { .fw_name = "syspll", },
+ { .fw_name = "epll_div2", .name = "epll_div2", },
+ { .fw_name = "syspll", .name = "syspll", },
};
static const struct clk_parent_data sysclk1_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "syspll", },
+ { .fw_name = "hxt", .name = "hxt", },
+ { .fw_name = "syspll", .name = "syspll", },
};
static const struct clk_parent_data axiclk_sel_clks[] = {
- { .fw_name = "capll_div2", },
- { .fw_name = "capll_div4", },
+ { .fw_name = "capll_div2", .name = "capll_div2", },
+ { .fw_name = "capll_div4", .name = "capll_div4", },
};
static const struct clk_parent_data ccap_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "vpll", },
- { .fw_name = "apll", },
- { .fw_name = "syspll", },
+ { .fw_name = "hxt", .name = "hxt", },
+ { .fw_name = "vpll", .name = "vpll", },
+ { .fw_name = "apll", .name = "apll", },
+ { .fw_name = "syspll", .name = "syspll", },
};
static const struct clk_parent_data sdh_sel_clks[] = {
- { .fw_name = "syspll", },
- { .fw_name = "apll", },
+ { .fw_name = "syspll", .name = "syspll", },
+ { .fw_name = "apll", .name = "apll", },
};
static const struct clk_parent_data dcu_sel_clks[] = {
- { .fw_name = "epll_div2", },
- { .fw_name = "syspll", },
+ { .fw_name = "epll_div2", .name = "epll_div2", },
+ { .fw_name = "syspll", .name = "syspll", },
};
static const struct clk_parent_data gfx_sel_clks[] = {
- { .fw_name = "epll", },
- { .fw_name = "syspll", },
+ { .fw_name = "epll", .name = "epll", },
+ { .fw_name = "syspll", .name = "syspll", },
};
static const struct clk_parent_data dbg_sel_clks[] = {
- { .fw_name = "hirc", },
- { .fw_name = "syspll", },
+ { .fw_name = "hirc", .name = "hirc", },
+ { .fw_name = "syspll", .name = "syspll", },
};
static const struct clk_parent_data timer0_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "lxt", },
- { .fw_name = "pclk0", },
+ { .fw_name = "hxt", .name = "hxt", },
+ { .fw_name = "lxt", .name = "lxt", },
+ { .fw_name = "pclk0", .name = "pclk0", },
{ .index = -1, },
{ .index = -1, },
- { .fw_name = "lirc", },
+ { .fw_name = "lirc", .name = "lirc", },
{ .index = -1, },
- { .fw_name = "hirc", },
+ { .fw_name = "hirc", .name = "hirc", },
};
static const struct clk_parent_data timer1_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "lxt", },
- { .fw_name = "pclk0", },
+ { .fw_name = "hxt", .name = "hxt", },
+ { .fw_name = "lxt", .name = "lxt", },
+ { .fw_name = "pclk0", .name = "pclk0", },
{ .index = -1, },
{ .index = -1, },
- { .fw_name = "lirc", },
+ { .fw_name = "lirc", .name = "lirc", },
{ .index = -1, },
- { .fw_name = "hirc", },
+ { .fw_name = "hirc", .name = "hirc", },
};
static const struct clk_parent_data timer2_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "lxt", },
- { .fw_name = "pclk1", },
+ { .fw_name = "hxt", .name = "hxt", },
+ { .fw_name = "lxt", .name = "lxt", },
+ { .fw_name = "pclk1", .name = "pclk1", },
{ .index = -1, },
{ .index = -1, },
- { .fw_name = "lirc", },
+ { .fw_name = "lirc", .name = "lirc", },
{ .index = -1, },
- { .fw_name = "hirc", },
+ { .fw_name = "hirc", .name = "hirc", },
};
static const struct clk_parent_data timer3_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "lxt", },
- { .fw_name = "pclk1", },
+ { .fw_name = "hxt", .name = "hxt", },
+ { .fw_name = "lxt", .name = "lxt", },
+ { .fw_name = "pclk1", .name = "pclk1", },
{ .index = -1, },
{ .index = -1, },
- { .fw_name = "lirc", },
+ { .fw_name = "lirc", .name = "lirc", },
{ .index = -1, },
- { .fw_name = "hirc", },
+ { .fw_name = "hirc", .name = "hirc", },
};
static const struct clk_parent_data timer4_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "lxt", },
- { .fw_name = "pclk2", },
+ { .fw_name = "hxt", .name = "hxt", },
+ { .fw_name = "lxt", .name = "lxt", },
+ { .fw_name = "pclk2", .name = "pclk2", },
{ .index = -1, },
{ .index = -1, },
- { .fw_name = "lirc", },
+ { .fw_name = "lirc", .name = "lirc", },
{ .index = -1, },
- { .fw_name = "hirc", },
+ { .fw_name = "hirc", .name = "hirc", },
};
static const struct clk_parent_data timer5_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "lxt", },
- { .fw_name = "pclk2", },
+ { .fw_name = "hxt", .name = "hxt", },
+ { .fw_name = "lxt", .name = "lxt", },
+ { .fw_name = "pclk2", .name = "pclk2", },
{ .index = -1, },
{ .index = -1, },
- { .fw_name = "lirc", },
+ { .fw_name = "lirc", .name = "lirc", },
{ .index = -1, },
- { .fw_name = "hirc", },
+ { .fw_name = "hirc", .name = "hirc", },
};
static const struct clk_parent_data timer6_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "lxt", },
- { .fw_name = "pclk0", },
+ { .fw_name = "hxt", .name = "hxt", },
+ { .fw_name = "lxt", .name = "lxt", },
+ { .fw_name = "pclk0", .name = "pclk0", },
{ .index = -1, },
{ .index = -1, },
- { .fw_name = "lirc", },
+ { .fw_name = "lirc", .name = "lirc", },
{ .index = -1, },
- { .fw_name = "hirc", },
+ { .fw_name = "hirc", .name = "hirc", },
};
static const struct clk_parent_data timer7_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "lxt", },
- { .fw_name = "pclk0", },
+ { .fw_name = "hxt", .name = "hxt", },
+ { .fw_name = "lxt", .name = "lxt", },
+ { .fw_name = "pclk0", .name = "pclk0", },
{ .index = -1, },
{ .index = -1, },
- { .fw_name = "lirc", },
+ { .fw_name = "lirc", .name = "lirc", },
{ .index = -1, },
- { .fw_name = "hirc", },
+ { .fw_name = "hirc", .name = "hirc", },
};
static const struct clk_parent_data timer8_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "lxt", },
- { .fw_name = "pclk1", },
+ { .fw_name = "hxt", .name = "hxt", },
+ { .fw_name = "lxt", .name = "lxt", },
+ { .fw_name = "pclk1", .name = "pclk1", },
{ .index = -1, },
{ .index = -1, },
- { .fw_name = "lirc", },
+ { .fw_name = "lirc", .name = "lirc", },
{ .index = -1, },
- { .fw_name = "hirc", },
+ { .fw_name = "hirc", .name = "hirc", },
};
static const struct clk_parent_data timer9_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "lxt", },
- { .fw_name = "pclk1", },
+ { .fw_name = "hxt", .name = "hxt", },
+ { .fw_name = "lxt", .name = "lxt", },
+ { .fw_name = "pclk1", .name = "pclk1", },
{ .index = -1, },
{ .index = -1, },
- { .fw_name = "lirc", },
+ { .fw_name = "lirc", .name = "lirc", },
{ .index = -1, },
- { .fw_name = "hirc", },
+ { .fw_name = "hirc", .name = "hirc", },
};
static const struct clk_parent_data timer10_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "lxt", },
- { .fw_name = "pclk2", },
+ { .fw_name = "hxt", .name = "hxt", },
+ { .fw_name = "lxt", .name = "lxt", },
+ { .fw_name = "pclk2", .name = "pclk2", },
{ .index = -1, },
{ .index = -1, },
- { .fw_name = "lirc", },
+ { .fw_name = "lirc", .name = "lirc", },
{ .index = -1, },
- { .fw_name = "hirc", },
+ { .fw_name = "hirc", .name = "hirc", },
};
static const struct clk_parent_data timer11_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "lxt", },
- { .fw_name = "pclk2", },
+ { .fw_name = "hxt", .name = "hxt", },
+ { .fw_name = "lxt", .name = "lxt", },
+ { .fw_name = "pclk2", .name = "pclk2", },
{ .index = -1, },
{ .index = -1, },
- { .fw_name = "lirc", },
+ { .fw_name = "lirc", .name = "lirc", },
{ .index = -1, },
- { .fw_name = "hirc", },
+ { .fw_name = "hirc", .name = "hirc", },
};
static const struct clk_parent_data uart_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "sysclk1_div2", },
+ { .fw_name = "hxt", .name = "hxt", },
+ { .fw_name = "sysclk1_div2", .name = "sysclk1_div2", },
};
static const struct clk_parent_data wdt0_sel_clks[] = {
{ .index = -1, },
- { .fw_name = "lxt", },
- { .fw_name = "pclk3_div4096", },
- { .fw_name = "lirc", },
+ { .fw_name = "lxt", .name = "lxt", },
+ { .fw_name = "pclk3_div4096", .name = "pclk3_div4096", },
+ { .fw_name = "lirc", .name = "lirc", },
};
static const struct clk_parent_data wdt1_sel_clks[] = {
{ .index = -1, },
- { .fw_name = "lxt", },
- { .fw_name = "pclk3_div4096", },
- { .fw_name = "lirc", },
+ { .fw_name = "lxt", .name = "lxt", },
+ { .fw_name = "pclk3_div4096", .name = "pclk3_div4096", },
+ { .fw_name = "lirc", .name = "lirc", },
};
static const struct clk_parent_data wdt2_sel_clks[] = {
{ .index = -1, },
- { .fw_name = "lxt", },
- { .fw_name = "pclk4_div4096", },
- { .fw_name = "lirc", },
+ { .fw_name = "lxt", .name = "lxt", },
+ { .fw_name = "pclk4_div4096", .name = "pclk4_div4096", },
+ { .fw_name = "lirc", .name = "lirc", },
};
static const struct clk_parent_data wwdt0_sel_clks[] = {
{ .index = -1, },
{ .index = -1, },
- { .fw_name = "pclk3_div4096", },
- { .fw_name = "lirc", },
+ { .fw_name = "pclk3_div4096", .name = "pclk3_div4096", },
+ { .fw_name = "lirc", .name = "lirc", },
};
static const struct clk_parent_data wwdt1_sel_clks[] = {
{ .index = -1, },
{ .index = -1, },
- { .fw_name = "pclk3_div4096", },
- { .fw_name = "lirc", },
+ { .fw_name = "pclk3_div4096", .name = "pclk3_div4096", },
+ { .fw_name = "lirc", .name = "lirc", },
};
static const struct clk_parent_data wwdt2_sel_clks[] = {
{ .index = -1, },
{ .index = -1, },
- { .fw_name = "pclk4_div4096", },
- { .fw_name = "lirc", },
+ { .fw_name = "pclk4_div4096", .name = "pclk4_div4096", },
+ { .fw_name = "lirc", .name = "lirc", },
};
static const struct clk_parent_data spi0_sel_clks[] = {
- { .fw_name = "pclk1", },
- { .fw_name = "apll", },
+ { .fw_name = "pclk1", .name = "pclk1", },
+ { .fw_name = "apll", .name = "apll", },
};
static const struct clk_parent_data spi1_sel_clks[] = {
- { .fw_name = "pclk2", },
- { .fw_name = "apll", },
+ { .fw_name = "pclk2", .name = "pclk2", },
+ { .fw_name = "apll", .name = "apll", },
};
static const struct clk_parent_data spi2_sel_clks[] = {
- { .fw_name = "pclk1", },
- { .fw_name = "apll", },
+ { .fw_name = "pclk1", .name = "pclk1", },
+ { .fw_name = "apll", .name = "apll", },
};
static const struct clk_parent_data spi3_sel_clks[] = {
- { .fw_name = "pclk2", },
- { .fw_name = "apll", },
+ { .fw_name = "pclk2", .name = "pclk2", },
+ { .fw_name = "apll", .name = "apll", },
};
static const struct clk_parent_data qspi0_sel_clks[] = {
- { .fw_name = "pclk0", },
- { .fw_name = "apll", },
+ { .fw_name = "pclk0", .name = "pclk0", },
+ { .fw_name = "apll", .name = "apll", },
};
static const struct clk_parent_data qspi1_sel_clks[] = {
- { .fw_name = "pclk0", },
- { .fw_name = "apll", },
+ { .fw_name = "pclk0", .name = "pclk0", },
+ { .fw_name = "apll", .name = "apll", },
};
static const struct clk_parent_data i2s0_sel_clks[] = {
- { .fw_name = "apll", },
- { .fw_name = "sysclk1_div2", },
+ { .fw_name = "apll", .name = "apll", },
+ { .fw_name = "sysclk1_div2", .name = "sysclk1_div2", },
};
static const struct clk_parent_data i2s1_sel_clks[] = {
- { .fw_name = "apll", },
- { .fw_name = "sysclk1_div2", },
+ { .fw_name = "apll", .name = "apll", },
+ { .fw_name = "sysclk1_div2", .name = "sysclk1_div2", },
};
static const struct clk_parent_data can_sel_clks[] = {
- { .fw_name = "apll", },
- { .fw_name = "vpll", },
+ { .fw_name = "apll", .name = "apll", },
+ { .fw_name = "vpll", .name = "vpll", },
};
static const struct clk_parent_data cko_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "lxt", },
- { .fw_name = "hirc", },
- { .fw_name = "lirc", },
- { .fw_name = "capll_div4", },
- { .fw_name = "syspll", },
- { .fw_name = "ddrpll", },
- { .fw_name = "epll_div2", },
- { .fw_name = "apll", },
- { .fw_name = "vpll", },
+ { .fw_name = "hxt", .name = "hxt", },
+ { .fw_name = "lxt", .name = "lxt", },
+ { .fw_name = "hirc", .name = "hirc", },
+ { .fw_name = "lirc", .name = "lirc", },
+ { .fw_name = "capll_div4", .name = "capll_div4", },
+ { .fw_name = "syspll", .name = "syspll", },
+ { .fw_name = "ddrpll", .name = "ddrpll", },
+ { .fw_name = "epll_div2", .name = "epll_div2", },
+ { .fw_name = "apll", .name = "apll", },
+ { .fw_name = "vpll", .name = "vpll", },
};
static const struct clk_parent_data smc_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "pclk4", },
+ { .fw_name = "hxt", .name = "hxt", },
+ { .fw_name = "pclk4", .name = "pclk4", },
};
static const struct clk_parent_data kpi_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "lxt", },
+ { .fw_name = "hxt", .name = "hxt", },
+ { .fw_name = "lxt", .name = "lxt", },
};
static const struct clk_div_table ip_div_table[] = {
--
2.43.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 2/3] clk: nuvoton: ma35d1: use the generic divider for the ADC clock
2026-10-12 6:30 [PATCH 0/3] clk: nuvoton: ma35d1: fix parent lookup and use the generic ADC divider Joey Lu
2026-10-12 6:30 ` [PATCH 1/3] clk: nuvoton: ma35d1: fix parent lookup for clk_parent_data entries Joey Lu
@ 2026-10-12 6:30 ` Joey Lu
2026-10-12 6:30 ` [PATCH 3/3] clk: nuvoton: ma35d1: remove the unused ADC divider driver Joey Lu
2 siblings, 0 replies; 4+ messages in thread
From: Joey Lu @ 2026-10-12 6:30 UTC (permalink / raw)
To: sboyd
Cc: ychuang3, schung, yclu4, arnd, bmasney+clk, jbrunet+clk,
linux-arm-kernel, linux-clk, linux-kernel, Joey Lu
The ADC clock divider implements rate = parent_rate / (2 * (N + 1)),
which is what the generic clk divider already provides with
CLK_DIVIDER_EVEN_INTEGERS. Use it with CLK_DIVIDER_ROUND_CLOSEST, as the
dedicated driver did, instead of a private clk_ops implementation. This
also keeps the rate request propagation handled by
divider_determine_rate().
The dedicated driver additionally OR'd a caller-supplied mask bit into
the divider register on every set_rate(). Its only caller passed a
bitmask (0x1ffff) rather than a bit index, which made BIT() shift by an
out-of-range amount, and nothing requires an extra bit to be forced, so
that behavior is not carried over.
Signed-off-by: Joey Lu <a0987203069@gmail.com>
---
drivers/clk/nuvoton/clk-ma35d1.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/nuvoton/clk-ma35d1.c b/drivers/clk/nuvoton/clk-ma35d1.c
index 09e6ceeb2c556..523493e42e38c 100644
--- a/drivers/clk/nuvoton/clk-ma35d1.c
+++ b/drivers/clk/nuvoton/clk-ma35d1.c
@@ -1014,10 +1014,11 @@ static int ma35d1_clocks_probe(struct platform_device *pdev)
hws[QEI2_GATE] = ma35d1_clk_gate(dev, "qei2_gate", "pclk1",
clk_base + REG_CLK_APBCLK2, 14);
- hws[ADC_DIV] = ma35d1_reg_adc_clkdiv(dev, "adc_div", hws[PCLK0],
- &ma35d1_lock, 0,
- clk_base + REG_CLK_CLKDIV4,
- 4, 17, 0x1ffff);
+ hws[ADC_DIV] = devm_clk_hw_register_divider_parent_hw(dev, "adc_div", hws[PCLK0], 0,
+ clk_base + REG_CLK_CLKDIV4, 4, 17,
+ CLK_DIVIDER_EVEN_INTEGERS |
+ CLK_DIVIDER_ROUND_CLOSEST,
+ &ma35d1_lock);
hws[ADC_GATE] = ma35d1_clk_gate(dev, "adc_gate", "adc_div",
clk_base + REG_CLK_APBCLK2, 24);
--
2.43.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 3/3] clk: nuvoton: ma35d1: remove the unused ADC divider driver
2026-10-12 6:30 [PATCH 0/3] clk: nuvoton: ma35d1: fix parent lookup and use the generic ADC divider Joey Lu
2026-10-12 6:30 ` [PATCH 1/3] clk: nuvoton: ma35d1: fix parent lookup for clk_parent_data entries Joey Lu
2026-10-12 6:30 ` [PATCH 2/3] clk: nuvoton: ma35d1: use the generic divider for the ADC clock Joey Lu
@ 2026-10-12 6:30 ` Joey Lu
2 siblings, 0 replies; 4+ messages in thread
From: Joey Lu @ 2026-10-12 6:30 UTC (permalink / raw)
To: sboyd
Cc: ychuang3, schung, yclu4, arnd, bmasney+clk, jbrunet+clk,
linux-arm-kernel, linux-clk, linux-kernel, Joey Lu
The ADC divider is now registered with the generic clk divider, so
clk-ma35d1-divider.c and its ma35d1_reg_adc_clkdiv() prototype have no
users. Remove them, including the divider table it built with one entry
per possible divider value.
Signed-off-by: Joey Lu <a0987203069@gmail.com>
---
drivers/clk/nuvoton/Makefile | 1 -
drivers/clk/nuvoton/clk-ma35d1-divider.c | 133 -----------------------
drivers/clk/nuvoton/clk-ma35d1.h | 5 -
3 files changed, 139 deletions(-)
delete mode 100644 drivers/clk/nuvoton/clk-ma35d1-divider.c
diff --git a/drivers/clk/nuvoton/Makefile b/drivers/clk/nuvoton/Makefile
index c3c59dd9f2aaa..3d95466e69b9c 100644
--- a/drivers/clk/nuvoton/Makefile
+++ b/drivers/clk/nuvoton/Makefile
@@ -1,4 +1,3 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_CLK_MA35D1) += clk-ma35d1.o
-obj-$(CONFIG_CLK_MA35D1) += clk-ma35d1-divider.o
obj-$(CONFIG_CLK_MA35D1) += clk-ma35d1-pll.o
diff --git a/drivers/clk/nuvoton/clk-ma35d1-divider.c b/drivers/clk/nuvoton/clk-ma35d1-divider.c
deleted file mode 100644
index e992e7c303419..0000000000000
--- a/drivers/clk/nuvoton/clk-ma35d1-divider.c
+++ /dev/null
@@ -1,133 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2023 Nuvoton Technology Corp.
- * Author: Chi-Fang Li <cfli0@nuvoton.com>
- */
-
-#include <linux/clk-provider.h>
-#include <linux/device.h>
-#include <linux/regmap.h>
-#include <linux/spinlock.h>
-
-#include "clk-ma35d1.h"
-
-struct ma35d1_adc_clk_div {
- struct clk_hw hw;
- void __iomem *reg;
- u8 shift;
- u8 width;
- u32 mask;
- const struct clk_div_table *table;
- /* protects concurrent access to clock divider registers */
- spinlock_t *lock;
-};
-
-static inline struct ma35d1_adc_clk_div *to_ma35d1_adc_clk_div(struct clk_hw *_hw)
-{
- return container_of(_hw, struct ma35d1_adc_clk_div, hw);
-}
-
-static unsigned long ma35d1_clkdiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
-{
- unsigned int val;
- struct ma35d1_adc_clk_div *dclk = to_ma35d1_adc_clk_div(hw);
-
- val = readl_relaxed(dclk->reg) >> dclk->shift;
- val &= clk_div_mask(dclk->width);
- val += 1;
- return divider_recalc_rate(hw, parent_rate, val, dclk->table,
- CLK_DIVIDER_ROUND_CLOSEST, dclk->width);
-}
-
-static int ma35d1_clkdiv_determine_rate(struct clk_hw *hw,
- struct clk_rate_request *req)
-{
- struct ma35d1_adc_clk_div *dclk = to_ma35d1_adc_clk_div(hw);
-
- return divider_determine_rate(hw, req, dclk->table, dclk->width,
- CLK_DIVIDER_ROUND_CLOSEST);
-}
-
-static int ma35d1_clkdiv_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate)
-{
- int value;
- unsigned long flags = 0;
- u32 data;
- struct ma35d1_adc_clk_div *dclk = to_ma35d1_adc_clk_div(hw);
-
- value = divider_get_val(rate, parent_rate, dclk->table,
- dclk->width, CLK_DIVIDER_ROUND_CLOSEST);
-
- spin_lock_irqsave(dclk->lock, flags);
-
- data = readl_relaxed(dclk->reg);
- data &= ~(clk_div_mask(dclk->width) << dclk->shift);
- data |= (value - 1) << dclk->shift;
- data |= dclk->mask;
- writel_relaxed(data, dclk->reg);
-
- spin_unlock_irqrestore(dclk->lock, flags);
- return 0;
-}
-
-static const struct clk_ops ma35d1_adc_clkdiv_ops = {
- .recalc_rate = ma35d1_clkdiv_recalc_rate,
- .determine_rate = ma35d1_clkdiv_determine_rate,
- .set_rate = ma35d1_clkdiv_set_rate,
-};
-
-struct clk_hw *ma35d1_reg_adc_clkdiv(struct device *dev, const char *name,
- struct clk_hw *parent_hw, spinlock_t *lock,
- unsigned long flags, void __iomem *reg,
- u8 shift, u8 width, u32 mask_bit)
-{
- struct ma35d1_adc_clk_div *div;
- struct clk_init_data init;
- struct clk_div_table *table;
- struct clk_parent_data pdata = { .index = 0 };
- u32 max_div, min_div;
- struct clk_hw *hw;
- int ret;
- int i;
-
- div = devm_kzalloc(dev, sizeof(*div), GFP_KERNEL);
- if (!div)
- return ERR_PTR(-ENOMEM);
-
- max_div = clk_div_mask(width) + 1;
- min_div = 1;
-
- table = devm_kcalloc(dev, max_div + 1, sizeof(*table), GFP_KERNEL);
- if (!table)
- return ERR_PTR(-ENOMEM);
-
- for (i = 0; i < max_div; i++) {
- table[i].val = min_div + i;
- table[i].div = 2 * table[i].val;
- }
- table[max_div].val = 0;
- table[max_div].div = 0;
-
- memset(&init, 0, sizeof(init));
- init.name = name;
- init.ops = &ma35d1_adc_clkdiv_ops;
- init.flags |= flags;
- pdata.hw = parent_hw;
- init.parent_data = &pdata;
- init.num_parents = 1;
-
- div->reg = reg;
- div->shift = shift;
- div->width = width;
- div->mask = mask_bit ? BIT(mask_bit) : 0;
- div->lock = lock;
- div->hw.init = &init;
- div->table = table;
-
- hw = &div->hw;
- ret = devm_clk_hw_register(dev, hw);
- if (ret)
- return ERR_PTR(ret);
- return hw;
-}
-EXPORT_SYMBOL_GPL(ma35d1_reg_adc_clkdiv);
diff --git a/drivers/clk/nuvoton/clk-ma35d1.h b/drivers/clk/nuvoton/clk-ma35d1.h
index 3adee440f60a3..06300511987ae 100644
--- a/drivers/clk/nuvoton/clk-ma35d1.h
+++ b/drivers/clk/nuvoton/clk-ma35d1.h
@@ -10,9 +10,4 @@
struct clk_hw *ma35d1_reg_clk_pll(struct device *dev, u32 id, u8 u8mode, const char *name,
struct clk_hw *parent_hw, void __iomem *base);
-struct clk_hw *ma35d1_reg_adc_clkdiv(struct device *dev, const char *name,
- struct clk_hw *parent_hw, spinlock_t *lock,
- unsigned long flags, void __iomem *reg,
- u8 shift, u8 width, u32 mask_bit);
-
#endif /* __DRV_CLK_NUVOTON_MA35D1_H */
--
2.43.0
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-10-12 6:30 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-12 6:30 [PATCH 0/3] clk: nuvoton: ma35d1: fix parent lookup and use the generic ADC divider Joey Lu
2026-10-12 6:30 ` [PATCH 1/3] clk: nuvoton: ma35d1: fix parent lookup for clk_parent_data entries Joey Lu
2026-10-12 6:30 ` [PATCH 2/3] clk: nuvoton: ma35d1: use the generic divider for the ADC clock Joey Lu
2026-10-12 6:30 ` [PATCH 3/3] clk: nuvoton: ma35d1: remove the unused ADC divider driver Joey Lu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®