* [PATCH v4 0/6] clk: nuvoton: ma35d1: Fix mux parenting and peripheral clock rates
@ 2026-09-25 15:10 Miquel Raynal
2026-09-25 15:10 ` [PATCH v4 1/6] clk: nuvoton: ma35d1: Keep the clock count in the driver Miquel Raynal
` (5 more replies)
0 siblings, 6 replies; 12+ messages in thread
From: Miquel Raynal @ 2026-09-25 15:10 UTC (permalink / raw)
To: Jacky Huang, Shan-Chun Hung, Michael Turquette, Stephen Boyd,
Richard Cochran, Arnd Bergmann, Brian Masney, Jerome Brunet,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Thomas Petazzoni, Steam Lin, linux-arm-kernel, linux-clk,
linux-kernel, Krzysztof Kozlowski, devicetree, Miquel Raynal,
Jacky Huang, stable
I am in possession of an MA35D1 NuMaker board. The SPI controller has
been contributed, but at this stage it does not work with the current
clock driver.
The clock controller registers its muxes with .fw_name parent data,
which requires every internal clock name to be declared in the DT. As
the DT does not declare them, all parent lookups fail: muxes end up
registered as root clocks and most peripherals read a zero rate.
This conversion exposed an issue with the WDT/WWDT parents which were
actually missing in the clock driver. I am not using these clocks myself
but it is worth fixing.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
Changes in v4:
- I forgot to bump the clock counter in the driver after adding the two
new clocks in the bindings. Sashiko will keep complaining about the
incoherency though. Since binding and driver changes should be kept
separated, I cannot do both at the same time.
- Link to v3: https://lore.kernel.org/r/20260925-perso-ma35d1-upstream-clk-v3-0-ffbae7e020a8@bootlin.com
Changes in v3:
- Drop the number of clocks from the binding, set it in the driver only
- Split the binding/driver patches completely
- Link to v2: https://lore.kernel.org/r/20260921-perso-ma35d1-upstream-clk-v2-0-209fd32a8b00@bootlin.com
Changes in v2:
- New patch 1/3: register the missing WDT/WWDT parent clocks
- New patch 3/3: harden the code
- Link to v1: https://lore.kernel.org/r/20260813-perso-ma35d1-upstream-clk-v1-1-e78e5e6172ea@bootlin.com
---
Miquel Raynal (6):
clk: nuvoton: ma35d1: Keep the clock count in the driver
dt-bindings: clock: ma35d1: Drop CLK_MAX_IDX define
dt-bindings: clock: ma35d1: Add missing WDT/WWDT parent clocks
clk: nuvoton: ma35d1: Add missing WDT/WWDT parent clocks
clk: nuvoton: ma35d1: Use clk_hw pointers as mux parents
clk: nuvoton: ma35d1: Avoid possible error pointer dereferencing
drivers/clk/nuvoton/clk-ma35d1-divider.c | 3 +
drivers/clk/nuvoton/clk-ma35d1-pll.c | 3 +
drivers/clk/nuvoton/clk-ma35d1.c | 642 ++++++++-----------------
include/dt-bindings/clock/nuvoton,ma35d1-clk.h | 3 +-
4 files changed, 199 insertions(+), 452 deletions(-)
---
base-commit: cee9395acd8043be0644b25c34bfa86623f2b935
change-id: 20260813-perso-ma35d1-upstream-clk-65cacfc1a86b
Best regards,
--
Miquel Raynal <miquel.raynal@bootlin.com>
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v4 1/6] clk: nuvoton: ma35d1: Keep the clock count in the driver
2026-09-25 15:10 [PATCH v4 0/6] clk: nuvoton: ma35d1: Fix mux parenting and peripheral clock rates Miquel Raynal
@ 2026-09-25 15:10 ` Miquel Raynal
2026-09-25 15:10 ` [PATCH v4 2/6] dt-bindings: clock: ma35d1: Drop CLK_MAX_IDX define Miquel Raynal
` (4 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Miquel Raynal @ 2026-09-25 15:10 UTC (permalink / raw)
To: Jacky Huang, Shan-Chun Hung, Michael Turquette, Stephen Boyd,
Richard Cochran, Arnd Bergmann, Brian Masney, Jerome Brunet,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Thomas Petazzoni, Steam Lin, linux-arm-kernel, linux-clk,
linux-kernel, Krzysztof Kozlowski, devicetree, Miquel Raynal
The number of clocks is not a binding since this is a value that can
change. As such, in order to support the missing watchdog clocks and
allow the deprecation and removal of CLK_MAX_IDX from the bindings, we
need to switch to a local definition first.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
drivers/clk/nuvoton/clk-ma35d1.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/nuvoton/clk-ma35d1.c b/drivers/clk/nuvoton/clk-ma35d1.c
index 9f65d0623517..6aa42a3e1be3 100644
--- a/drivers/clk/nuvoton/clk-ma35d1.c
+++ b/drivers/clk/nuvoton/clk-ma35d1.c
@@ -17,6 +17,7 @@
static DEFINE_SPINLOCK(ma35d1_lock);
#define PLL_MAX_NUM 5
+#define MA35D1_CLK_COUNT 236
/* Clock Control Registers Offset */
#define REG_CLK_PWRCTL 0x00
@@ -467,12 +468,12 @@ static int ma35d1_clocks_probe(struct platform_device *pdev)
int ret;
ma35d1_hw_data = devm_kzalloc(dev,
- struct_size(ma35d1_hw_data, hws, CLK_MAX_IDX),
+ struct_size(ma35d1_hw_data, hws, MA35D1_CLK_COUNT),
GFP_KERNEL);
if (!ma35d1_hw_data)
return -ENOMEM;
- ma35d1_hw_data->num = CLK_MAX_IDX;
+ ma35d1_hw_data->num = MA35D1_CLK_COUNT;
hws = ma35d1_hw_data->hws;
clk_base = devm_platform_ioremap_resource(pdev, 0);
--
2.55.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v4 2/6] dt-bindings: clock: ma35d1: Drop CLK_MAX_IDX define
2026-09-25 15:10 [PATCH v4 0/6] clk: nuvoton: ma35d1: Fix mux parenting and peripheral clock rates Miquel Raynal
2026-09-25 15:10 ` [PATCH v4 1/6] clk: nuvoton: ma35d1: Keep the clock count in the driver Miquel Raynal
@ 2026-09-25 15:10 ` Miquel Raynal
2026-09-25 16:41 ` Conor Dooley
2026-09-25 15:10 ` [PATCH v4 3/6] dt-bindings: clock: ma35d1: Add missing WDT/WWDT parent clocks Miquel Raynal
` (3 subsequent siblings)
5 siblings, 1 reply; 12+ messages in thread
From: Miquel Raynal @ 2026-09-25 15:10 UTC (permalink / raw)
To: Jacky Huang, Shan-Chun Hung, Michael Turquette, Stephen Boyd,
Richard Cochran, Arnd Bergmann, Brian Masney, Jerome Brunet,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Thomas Petazzoni, Steam Lin, linux-arm-kernel, linux-clk,
linux-kernel, Krzysztof Kozlowski, devicetree, Miquel Raynal
Drop CLK_MAX_IDX define of MA35D1 include. This is not a binding and
should not be placed here. Value is defined in the user driver.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
include/dt-bindings/clock/nuvoton,ma35d1-clk.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/include/dt-bindings/clock/nuvoton,ma35d1-clk.h b/include/dt-bindings/clock/nuvoton,ma35d1-clk.h
index ba2d70f776a6..2d6a44a7e55c 100644
--- a/include/dt-bindings/clock/nuvoton,ma35d1-clk.h
+++ b/include/dt-bindings/clock/nuvoton,ma35d1-clk.h
@@ -248,6 +248,5 @@
#define ADC_GATE 233
#define EADC_DIV 234
#define EADC_GATE 235
-#define CLK_MAX_IDX 236
#endif /* __DT_BINDINGS_CLOCK_NUVOTON_MA35D1_CLK_H */
--
2.55.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v4 3/6] dt-bindings: clock: ma35d1: Add missing WDT/WWDT parent clocks
2026-09-25 15:10 [PATCH v4 0/6] clk: nuvoton: ma35d1: Fix mux parenting and peripheral clock rates Miquel Raynal
2026-09-25 15:10 ` [PATCH v4 1/6] clk: nuvoton: ma35d1: Keep the clock count in the driver Miquel Raynal
2026-09-25 15:10 ` [PATCH v4 2/6] dt-bindings: clock: ma35d1: Drop CLK_MAX_IDX define Miquel Raynal
@ 2026-09-25 15:10 ` Miquel Raynal
2026-09-25 16:42 ` Conor Dooley
2026-09-25 15:10 ` [PATCH v4 4/6] clk: nuvoton: " Miquel Raynal
` (2 subsequent siblings)
5 siblings, 1 reply; 12+ messages in thread
From: Miquel Raynal @ 2026-09-25 15:10 UTC (permalink / raw)
To: Jacky Huang, Shan-Chun Hung, Michael Turquette, Stephen Boyd,
Richard Cochran, Arnd Bergmann, Brian Masney, Jerome Brunet,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Thomas Petazzoni, Steam Lin, linux-arm-kernel, linux-clk,
linux-kernel, Krzysztof Kozlowski, devicetree, Miquel Raynal
The WDT and WWDT muxes have PCLK3/4096 and PCLK4/4096 among their
possible parents, but these fixed factor clocks are currently not
defined, even though they are needed to properly describe the clock
tree. Add them to the binding.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
include/dt-bindings/clock/nuvoton,ma35d1-clk.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/dt-bindings/clock/nuvoton,ma35d1-clk.h b/include/dt-bindings/clock/nuvoton,ma35d1-clk.h
index 2d6a44a7e55c..764d837d6162 100644
--- a/include/dt-bindings/clock/nuvoton,ma35d1-clk.h
+++ b/include/dt-bindings/clock/nuvoton,ma35d1-clk.h
@@ -248,5 +248,7 @@
#define ADC_GATE 233
#define EADC_DIV 234
#define EADC_GATE 235
+#define PCLK3_DIV4096 236
+#define PCLK4_DIV4096 237
#endif /* __DT_BINDINGS_CLOCK_NUVOTON_MA35D1_CLK_H */
--
2.55.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v4 4/6] clk: nuvoton: ma35d1: Add missing WDT/WWDT parent clocks
2026-09-25 15:10 [PATCH v4 0/6] clk: nuvoton: ma35d1: Fix mux parenting and peripheral clock rates Miquel Raynal
` (2 preceding siblings ...)
2026-09-25 15:10 ` [PATCH v4 3/6] dt-bindings: clock: ma35d1: Add missing WDT/WWDT parent clocks Miquel Raynal
@ 2026-09-25 15:10 ` Miquel Raynal
2026-09-27 17:04 ` Jerome Brunet
2026-09-25 15:10 ` [PATCH v4 5/6] clk: nuvoton: ma35d1: Use clk_hw pointers as mux parents Miquel Raynal
2026-09-25 15:10 ` [PATCH v4 6/6] clk: nuvoton: ma35d1: Avoid possible error pointer dereferencing Miquel Raynal
5 siblings, 1 reply; 12+ messages in thread
From: Miquel Raynal @ 2026-09-25 15:10 UTC (permalink / raw)
To: Jacky Huang, Shan-Chun Hung, Michael Turquette, Stephen Boyd,
Richard Cochran, Arnd Bergmann, Brian Masney, Jerome Brunet,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Thomas Petazzoni, Steam Lin, linux-arm-kernel, linux-clk,
linux-kernel, Krzysztof Kozlowski, devicetree, Miquel Raynal,
Jacky Huang, stable
The WDT and WWDT muxes list PCLK3/4096 and PCLK4/4096 among their
possible parents, but the driver never registers the corresponding
clocks, so these parents could never be used.
Add pclk3_div4096 and pclk4_div4096 as fixed factor children of pclk3
and pclk4 and expose them through the clock provider.
Reported-by: Jacky Huang <ychuang570808@gmail.com>
Closes: https://lore.kernel.org/linux-clk/b8a8a65b-e302-4747-bc90-4920fc48795a@gmail.com/
Suggested-by: Jacky Huang <ychuang570808@gmail.com>
Fixes: 691521a367cf ("clk: nuvoton: Add clock driver for ma35d1 clock controller")
Cc: stable@vger.kernel.org
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
drivers/clk/nuvoton/clk-ma35d1.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/nuvoton/clk-ma35d1.c b/drivers/clk/nuvoton/clk-ma35d1.c
index 6aa42a3e1be3..c914079cee2d 100644
--- a/drivers/clk/nuvoton/clk-ma35d1.c
+++ b/drivers/clk/nuvoton/clk-ma35d1.c
@@ -17,7 +17,7 @@
static DEFINE_SPINLOCK(ma35d1_lock);
#define PLL_MAX_NUM 5
-#define MA35D1_CLK_COUNT 236
+#define MA35D1_CLK_COUNT 238
/* Clock Control Registers Offset */
#define REG_CLK_PWRCTL 0x00
@@ -544,6 +544,8 @@ static int ma35d1_clocks_probe(struct platform_device *pdev)
hws[HCLK3] = ma35d1_clk_fixed_factor(dev, "hclk3", "sysclk1_mux", 1, 2);
hws[PCLK3] = ma35d1_clk_fixed_factor(dev, "pclk3", "sysclk1_mux", 1, 2);
hws[PCLK4] = ma35d1_clk_fixed_factor(dev, "pclk4", "sysclk1_mux", 1, 2);
+ hws[PCLK3_DIV4096] = ma35d1_clk_fixed_factor(dev, "pclk3_div4096", "pclk3", 1, 4096);
+ hws[PCLK4_DIV4096] = ma35d1_clk_fixed_factor(dev, "pclk4_div4096", "pclk4", 1, 4096);
hws[USBPHY0] = ma35d1_clk_fixed("usbphy0", 480000000);
hws[USBPHY1] = ma35d1_clk_fixed("usbphy1", 480000000);
--
2.55.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v4 5/6] clk: nuvoton: ma35d1: Use clk_hw pointers as mux parents
2026-09-25 15:10 [PATCH v4 0/6] clk: nuvoton: ma35d1: Fix mux parenting and peripheral clock rates Miquel Raynal
` (3 preceding siblings ...)
2026-09-25 15:10 ` [PATCH v4 4/6] clk: nuvoton: " Miquel Raynal
@ 2026-09-25 15:10 ` Miquel Raynal
2026-09-27 17:00 ` Jerome Brunet
2026-09-25 15:10 ` [PATCH v4 6/6] clk: nuvoton: ma35d1: Avoid possible error pointer dereferencing Miquel Raynal
5 siblings, 1 reply; 12+ messages in thread
From: Miquel Raynal @ 2026-09-25 15:10 UTC (permalink / raw)
To: Jacky Huang, Shan-Chun Hung, Michael Turquette, Stephen Boyd,
Richard Cochran, Arnd Bergmann, Brian Masney, Jerome Brunet,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Thomas Petazzoni, Steam Lin, linux-arm-kernel, linux-clk,
linux-kernel, Krzysztof Kozlowski, devicetree, Miquel Raynal,
stable
The MA35D1 clock provider registers its muxes with parent data
structures filling .fw_name. This is not the ideal approach since that
would require a massive amount of internal clock names declaration in
the DT. Since the DT does not play the game of exposing all these names,
none of the parent lookups performed when instantiating the muxes
succeed. As a result, these muxes get registered as root clocks, leading
to a sadly flat clock tree and no frequency assigned to most of the
peripheral clocks:
enable prepare protect
clock count count count rate
usbphy1 0 0 0 480000000
usbphy0 0 0 0 480000000
husbh1_gate 0 0 0 480000000
husbh0_gate 0 0 0 480000000
usbh_gate 0 0 0 480000000
usbd_gate 0 0 0 480000000
syspll 0 0 0 180000000
lirc 0 0 0 32000
lirc_gate 0 0 0 32000
hirc 0 0 0 12000000
gtmr_gate 0 0 0 12000000
hirc_gate 0 0 0 12000000
lxt 0 0 0 32768
rtc_gate 0 0 0 32768
lxt_gate 0 0 0 32768
hxt 0 0 0 24000000
vpll 0 0 0 1224000000
dcup_div 0 0 0 612000000
epll 0 0 0 6000000000
epll_div8 0 0 0 750000000
epll_div4 0 0 0 1500000000
epll_div2 0 0 0 3000000000
emac1_gate 0 0 0 3000000000
emac0_gate 0 0 0 3000000000
apll 0 0 0 6048000000
ddrpll 0 0 0 266460000
ddr_gate 0 0 0 266460000
ddr6_gate 0 0 0 266460000
ddr0_gate 0 0 0 266460000
capll 0 0 0 2400000000
hxt_gate 0 0 0 24000000
clk_hxt 0 0 0 24000000
spi3_mux 0 0 0 0
spi3_gate 0 0 0 0
spi2_mux 0 0 0 0
spi2_gate 0 0 0 0
spi1_mux 0 0 0 0
spi1_gate 0 0 0 0
spi0_mux 0 0 0 0
spi0_gate 0 0 0 0
i2s1_mux 0 0 0 0
i2s1_gate 0 0 0 0
i2s0_mux 0 0 0 0
i2s0_gate 0 0 0 0
...
Apart from the wrong clock tree representation, it means that none of
the device drivers (spi & i2c in the excerpt above) can actually query
their clock rate, or they would get 0Hz.
Instead of declaring the parents in the clk_parent_data structure, use
the actual HW clocks to lookup the parents directly: parents are
described by an array of indices into the controller's main clock table
(like in other clock controller drivers), which the "new" mux helper now
resolves.
The WDT and WWDT muxes list the /4096 children of PCLK3 and PCLK4 among
their possible parents. Those two clocks are now registered by the
previous commit, so their entries in the parent tables are restored
instead of being turned into invalid slots.
enable prepare protect
clock count count count rate
usbphy1 0 0 0 480000000
usbphy0 0 0 0 480000000
husbh1_gate 0 0 0 480000000
husbh0_gate 0 0 0 480000000
usbh_gate 0 0 0 480000000
usbd_gate 0 0 0 480000000
syspll 1 1 0 180000000
dbg_mux 0 0 0 180000000
sdh1_mux 0 0 0 180000000
sdh1_gate 0 0 0 180000000
sdh0_mux 0 0 0 180000000
sdh0_gate 0 0 0 180000000
sysclk1_mux 2 2 0 180000000
pclk4 0 0 0 90000000
pclk3 0 0 0 90000000
sspcc_gate 0 0 0 90000000
ssmcc_gate 0 0 0 90000000
hclk3 0 0 0 90000000
pclk2 0 0 0 180000000
eadc_div 0 0 0 90000000
eadc_gate 0 0 0 90000000
qei1_gate 0 0 0 180000000
ecap1_gate 0 0 0 180000000
spi3_mux 0 0 0 180000000
spi3_gate 0 0 0 180000000
spi1_mux 0 0 0 180000000
spi1_gate 0 0 0 180000000
epwm1_gate 0 0 0 180000000
i2c5_gate 0 0 0 180000000
i2c2_gate 0 0 0 180000000
pclk1 0 0 0 180000000
qei2_gate 0 0 0 180000000
qei0_gate 0 0 0 180000000
ecap2_gate 0 0 0 180000000
ecap0_gate 0 0 0 180000000
spi2_mux 0 0 0 180000000
spi2_gate 0 0 0 180000000
spi0_mux 0 0 0 180000000
spi0_gate 0 0 0 180000000
epwm2_gate 0 0 0 180000000
epwm0_gate 0 0 0 180000000
i2c4_gate 0 0 0 180000000
i2c1_gate 0 0 0 180000000
pclk0 1 1 0 180000000
adc_div 0 0 0 90000000
adc_gate 0 0 0 90000000
qspi1_mux 0 0 0 180000000
qspi1_gate 0 0 0 180000000
qspi0_mux 1 1 0 180000000
qspi0_gate 1 1 0 180000000
i2c3_gate 0 0 0 180000000
i2c0_gate 0 0 0 180000000
Fixes: f50a000b4219 ("clk: nuvoton: Use clk_parent_data instead of string for parent clock")
Cc: stable@vger.kernel.org
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
drivers/clk/nuvoton/clk-ma35d1.c | 626 +++++++++++----------------------------
1 file changed, 177 insertions(+), 449 deletions(-)
diff --git a/drivers/clk/nuvoton/clk-ma35d1.c b/drivers/clk/nuvoton/clk-ma35d1.c
index c914079cee2d..1a857f28310f 100644
--- a/drivers/clk/nuvoton/clk-ma35d1.c
+++ b/drivers/clk/nuvoton/clk-ma35d1.c
@@ -63,300 +63,49 @@ static DEFINE_SPINLOCK(ma35d1_lock);
#define PLL_MODE_FRAC 1
#define PLL_MODE_SS 2
-static const struct clk_parent_data ca35clk_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "capll", },
- { .fw_name = "ddrpll", },
-};
+#define MA35D1_MUX_MAX_PARENTS 10
-static const struct clk_parent_data sysclk0_sel_clks[] = {
- { .fw_name = "epll_div2", },
- { .fw_name = "syspll", },
-};
-
-static const struct clk_parent_data sysclk1_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "syspll", },
-};
-
-static const struct clk_parent_data axiclk_sel_clks[] = {
- { .fw_name = "capll_div2", },
- { .fw_name = "capll_div4", },
-};
-
-static const struct clk_parent_data ccap_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "vpll", },
- { .fw_name = "apll", },
- { .fw_name = "syspll", },
-};
-
-static const struct clk_parent_data sdh_sel_clks[] = {
- { .fw_name = "syspll", },
- { .fw_name = "apll", },
-};
-
-static const struct clk_parent_data dcu_sel_clks[] = {
- { .fw_name = "epll_div2", },
- { .fw_name = "syspll", },
-};
-
-static const struct clk_parent_data gfx_sel_clks[] = {
- { .fw_name = "epll", },
- { .fw_name = "syspll", },
-};
-
-static const struct clk_parent_data dbg_sel_clks[] = {
- { .fw_name = "hirc", },
- { .fw_name = "syspll", },
-};
-
-static const struct clk_parent_data timer0_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "lxt", },
- { .fw_name = "pclk0", },
- { .index = -1, },
- { .index = -1, },
- { .fw_name = "lirc", },
- { .index = -1, },
- { .fw_name = "hirc", },
-};
-
-static const struct clk_parent_data timer1_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "lxt", },
- { .fw_name = "pclk0", },
- { .index = -1, },
- { .index = -1, },
- { .fw_name = "lirc", },
- { .index = -1, },
- { .fw_name = "hirc", },
-};
-
-static const struct clk_parent_data timer2_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "lxt", },
- { .fw_name = "pclk1", },
- { .index = -1, },
- { .index = -1, },
- { .fw_name = "lirc", },
- { .index = -1, },
- { .fw_name = "hirc", },
-};
-
-static const struct clk_parent_data timer3_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "lxt", },
- { .fw_name = "pclk1", },
- { .index = -1, },
- { .index = -1, },
- { .fw_name = "lirc", },
- { .index = -1, },
- { .fw_name = "hirc", },
-};
-
-static const struct clk_parent_data timer4_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "lxt", },
- { .fw_name = "pclk2", },
- { .index = -1, },
- { .index = -1, },
- { .fw_name = "lirc", },
- { .index = -1, },
- { .fw_name = "hirc", },
-};
-
-static const struct clk_parent_data timer5_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "lxt", },
- { .fw_name = "pclk2", },
- { .index = -1, },
- { .index = -1, },
- { .fw_name = "lirc", },
- { .index = -1, },
- { .fw_name = "hirc", },
-};
-
-static const struct clk_parent_data timer6_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "lxt", },
- { .fw_name = "pclk0", },
- { .index = -1, },
- { .index = -1, },
- { .fw_name = "lirc", },
- { .index = -1, },
- { .fw_name = "hirc", },
-};
-
-static const struct clk_parent_data timer7_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "lxt", },
- { .fw_name = "pclk0", },
- { .index = -1, },
- { .index = -1, },
- { .fw_name = "lirc", },
- { .index = -1, },
- { .fw_name = "hirc", },
-};
-
-static const struct clk_parent_data timer8_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "lxt", },
- { .fw_name = "pclk1", },
- { .index = -1, },
- { .index = -1, },
- { .fw_name = "lirc", },
- { .index = -1, },
- { .fw_name = "hirc", },
-};
-
-static const struct clk_parent_data timer9_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "lxt", },
- { .fw_name = "pclk1", },
- { .index = -1, },
- { .index = -1, },
- { .fw_name = "lirc", },
- { .index = -1, },
- { .fw_name = "hirc", },
-};
-
-static const struct clk_parent_data timer10_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "lxt", },
- { .fw_name = "pclk2", },
- { .index = -1, },
- { .index = -1, },
- { .fw_name = "lirc", },
- { .index = -1, },
- { .fw_name = "hirc", },
-};
-
-static const struct clk_parent_data timer11_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "lxt", },
- { .fw_name = "pclk2", },
- { .index = -1, },
- { .index = -1, },
- { .fw_name = "lirc", },
- { .index = -1, },
- { .fw_name = "hirc", },
-};
-
-static const struct clk_parent_data uart_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "sysclk1_div2", },
-};
-
-static const struct clk_parent_data wdt0_sel_clks[] = {
- { .index = -1, },
- { .fw_name = "lxt", },
- { .fw_name = "pclk3_div4096", },
- { .fw_name = "lirc", },
-};
-
-static const struct clk_parent_data wdt1_sel_clks[] = {
- { .index = -1, },
- { .fw_name = "lxt", },
- { .fw_name = "pclk3_div4096", },
- { .fw_name = "lirc", },
-};
-
-static const struct clk_parent_data wdt2_sel_clks[] = {
- { .index = -1, },
- { .fw_name = "lxt", },
- { .fw_name = "pclk4_div4096", },
- { .fw_name = "lirc", },
-};
-
-static const struct clk_parent_data wwdt0_sel_clks[] = {
- { .index = -1, },
- { .index = -1, },
- { .fw_name = "pclk3_div4096", },
- { .fw_name = "lirc", },
-};
-
-static const struct clk_parent_data wwdt1_sel_clks[] = {
- { .index = -1, },
- { .index = -1, },
- { .fw_name = "pclk3_div4096", },
- { .fw_name = "lirc", },
-};
-
-static const struct clk_parent_data wwdt2_sel_clks[] = {
- { .index = -1, },
- { .index = -1, },
- { .fw_name = "pclk4_div4096", },
- { .fw_name = "lirc", },
-};
-
-static const struct clk_parent_data spi0_sel_clks[] = {
- { .fw_name = "pclk1", },
- { .fw_name = "apll", },
-};
-
-static const struct clk_parent_data spi1_sel_clks[] = {
- { .fw_name = "pclk2", },
- { .fw_name = "apll", },
-};
-
-static const struct clk_parent_data spi2_sel_clks[] = {
- { .fw_name = "pclk1", },
- { .fw_name = "apll", },
-};
-
-static const struct clk_parent_data spi3_sel_clks[] = {
- { .fw_name = "pclk2", },
- { .fw_name = "apll", },
-};
-
-static const struct clk_parent_data qspi0_sel_clks[] = {
- { .fw_name = "pclk0", },
- { .fw_name = "apll", },
-};
-
-static const struct clk_parent_data qspi1_sel_clks[] = {
- { .fw_name = "pclk0", },
- { .fw_name = "apll", },
-};
-
-static const struct clk_parent_data i2s0_sel_clks[] = {
- { .fw_name = "apll", },
- { .fw_name = "sysclk1_div2", },
-};
-
-static const struct clk_parent_data i2s1_sel_clks[] = {
- { .fw_name = "apll", },
- { .fw_name = "sysclk1_div2", },
-};
-
-static const struct clk_parent_data can_sel_clks[] = {
- { .fw_name = "apll", },
- { .fw_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", },
-};
-
-static const struct clk_parent_data smc_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "pclk4", },
-};
-
-static const struct clk_parent_data kpi_sel_clks[] = {
- { .fw_name = "hxt", },
- { .fw_name = "lxt", },
-};
+/* Mux parent selection, by index into the controller's clock table */
+static const int ca35clk_parent_idx[] = { HXT, CAPLL, DDRPLL };
+static const int sysclk0_parent_idx[] = { EPLL_DIV2, SYSPLL };
+static const int sysclk1_parent_idx[] = { HXT, SYSPLL };
+static const int axiclk_parent_idx[] = { AXICLK_DIV2, AXICLK_DIV4 };
+static const int ccap_parent_idx[] = { HXT, VPLL, APLL, SYSPLL };
+static const int sdh_parent_idx[] = { SYSPLL, APLL };
+static const int dcu_parent_idx[] = { EPLL_DIV2, SYSPLL };
+static const int gfx_parent_idx[] = { EPLL, SYSPLL };
+static const int dbg_parent_idx[] = { HIRC, SYSPLL };
+static const int timer0_parent_idx[] = { HXT, LXT, PCLK0, -1, -1, LIRC, -1, HIRC };
+static const int timer1_parent_idx[] = { HXT, LXT, PCLK0, -1, -1, LIRC, -1, HIRC };
+static const int timer2_parent_idx[] = { HXT, LXT, PCLK1, -1, -1, LIRC, -1, HIRC };
+static const int timer3_parent_idx[] = { HXT, LXT, PCLK1, -1, -1, LIRC, -1, HIRC };
+static const int timer4_parent_idx[] = { HXT, LXT, PCLK2, -1, -1, LIRC, -1, HIRC };
+static const int timer5_parent_idx[] = { HXT, LXT, PCLK2, -1, -1, LIRC, -1, HIRC };
+static const int timer6_parent_idx[] = { HXT, LXT, PCLK0, -1, -1, LIRC, -1, HIRC };
+static const int timer7_parent_idx[] = { HXT, LXT, PCLK0, -1, -1, LIRC, -1, HIRC };
+static const int timer8_parent_idx[] = { HXT, LXT, PCLK1, -1, -1, LIRC, -1, HIRC };
+static const int timer9_parent_idx[] = { HXT, LXT, PCLK1, -1, -1, LIRC, -1, HIRC };
+static const int timer10_parent_idx[] = { HXT, LXT, PCLK2, -1, -1, LIRC, -1, HIRC };
+static const int timer11_parent_idx[] = { HXT, LXT, PCLK2, -1, -1, LIRC, -1, HIRC };
+static const int uart_parent_idx[] = { HXT, SYSCLK1_DIV2 };
+static const int wdt0_parent_idx[] = { -1, LXT, PCLK3_DIV4096, LIRC };
+static const int wdt1_parent_idx[] = { -1, LXT, PCLK3_DIV4096, LIRC };
+static const int wdt2_parent_idx[] = { -1, LXT, PCLK4_DIV4096, LIRC };
+static const int wwdt0_parent_idx[] = { -1, -1, PCLK3_DIV4096, LIRC };
+static const int wwdt1_parent_idx[] = { -1, -1, PCLK3_DIV4096, LIRC };
+static const int wwdt2_parent_idx[] = { -1, -1, PCLK4_DIV4096, LIRC };
+static const int spi0_parent_idx[] = { PCLK1, APLL };
+static const int spi1_parent_idx[] = { PCLK2, APLL };
+static const int spi2_parent_idx[] = { PCLK1, APLL };
+static const int spi3_parent_idx[] = { PCLK2, APLL };
+static const int qspi_parent_idx[] = { PCLK0, APLL };
+static const int i2s_parent_idx[] = { APLL, SYSCLK1_DIV2 };
+static const int can_parent_idx[] = { APLL, VPLL };
+static const int cko_parent_idx[] = { HXT, LXT, HIRC, LIRC,
+ AXICLK_DIV4, SYSPLL, DDRPLL,
+ EPLL_DIV2, APLL, VPLL };
+static const int smc_parent_idx[] = { HXT, PCLK4 };
+static const int kpi_parent_idx[] = { HXT, LXT };
static const struct clk_div_table ip_div_table[] = {
{0, 2}, {1, 4}, {2, 6}, {3, 8}, {4, 10},
@@ -375,24 +124,20 @@ static struct clk_hw *ma35d1_clk_fixed(const char *name, int rate)
return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate);
}
-static struct clk_hw *ma35d1_clk_mux_parent(struct device *dev, const char *name,
- void __iomem *reg, u8 shift, u8 width,
- const struct clk_parent_data *pdata,
- int num_pdata)
-{
- return clk_hw_register_mux_parent_data(dev, name, pdata, num_pdata,
- CLK_SET_RATE_NO_REPARENT, reg, shift,
- width, 0, &ma35d1_lock);
-}
-
static struct clk_hw *ma35d1_clk_mux(struct device *dev, const char *name,
void __iomem *reg, u8 shift, u8 width,
- const struct clk_parent_data *pdata,
- int num_pdata)
+ struct clk_hw **hws,
+ const int *parent_idx, int num_parents)
{
- return clk_hw_register_mux_parent_data(dev, name, pdata, num_pdata,
- CLK_SET_RATE_NO_REPARENT, reg, shift,
- width, 0, &ma35d1_lock);
+ const struct clk_hw *parent_hws[MA35D1_MUX_MAX_PARENTS] = {};
+ int i;
+
+ for (i = 0; i < num_parents; i++)
+ parent_hws[i] = (parent_idx[i] >= 0) ? hws[parent_idx[i]] : NULL;
+
+ return clk_hw_register_mux_hws(dev, name, parent_hws, num_parents,
+ CLK_SET_RATE_NO_REPARENT, reg, shift,
+ width, 0, &ma35d1_lock);
}
static struct clk_hw *ma35d1_clk_divider(struct device *dev, const char *name,
@@ -515,22 +260,17 @@ static int ma35d1_clocks_probe(struct platform_device *pdev)
hws[EPLL_DIV4] = ma35d1_clk_fixed_factor(dev, "epll_div4", "epll", 1, 4);
hws[EPLL_DIV8] = ma35d1_clk_fixed_factor(dev, "epll_div8", "epll", 1, 8);
- hws[CA35CLK_MUX] = ma35d1_clk_mux_parent(dev, "ca35clk_mux",
- clk_base + REG_CLK_CLKSEL0, 0, 2,
- ca35clk_sel_clks,
- ARRAY_SIZE(ca35clk_sel_clks));
+ hws[CA35CLK_MUX] = ma35d1_clk_mux(dev, "ca35clk_mux", clk_base + REG_CLK_CLKSEL0, 0, 2, hws,
+ ca35clk_parent_idx, ARRAY_SIZE(ca35clk_parent_idx));
hws[AXICLK_DIV2] = ma35d1_clk_fixed_factor(dev, "capll_div2", "ca35clk_mux", 1, 2);
hws[AXICLK_DIV4] = ma35d1_clk_fixed_factor(dev, "capll_div4", "ca35clk_mux", 1, 4);
- hws[AXICLK_MUX] = ma35d1_clk_mux(dev, "axiclk_mux", clk_base + REG_CLK_CLKDIV0,
- 26, 1, axiclk_sel_clks,
- ARRAY_SIZE(axiclk_sel_clks));
- hws[SYSCLK0_MUX] = ma35d1_clk_mux(dev, "sysclk0_mux", clk_base + REG_CLK_CLKSEL0,
- 2, 1, sysclk0_sel_clks,
- ARRAY_SIZE(sysclk0_sel_clks));
- hws[SYSCLK1_MUX] = ma35d1_clk_mux(dev, "sysclk1_mux", clk_base + REG_CLK_CLKSEL0,
- 4, 1, sysclk1_sel_clks,
- ARRAY_SIZE(sysclk1_sel_clks));
+ hws[AXICLK_MUX] = ma35d1_clk_mux(dev, "axiclk_mux", clk_base + REG_CLK_CLKDIV0, 26, 1, hws,
+ axiclk_parent_idx, ARRAY_SIZE(axiclk_parent_idx));
+ hws[SYSCLK0_MUX] = ma35d1_clk_mux(dev, "sysclk0_mux", clk_base + REG_CLK_CLKSEL0, 2, 1, hws,
+ sysclk0_parent_idx, ARRAY_SIZE(sysclk0_parent_idx));
+ hws[SYSCLK1_MUX] = ma35d1_clk_mux(dev, "sysclk1_mux", clk_base + REG_CLK_CLKSEL0, 4, 1, hws,
+ sysclk1_parent_idx, ARRAY_SIZE(sysclk1_parent_idx));
hws[SYSCLK1_DIV2] = ma35d1_clk_fixed_factor(dev, "sysclk1_div2", "sysclk1_mux", 1, 2);
/* HCLK0~3 & PCLK0~4 */
@@ -556,41 +296,41 @@ static int ma35d1_clocks_probe(struct platform_device *pdev)
hws[DDR6_GATE] = ma35d1_clk_gate(dev, "ddr6_gate", "ddrpll",
clk_base + REG_CLK_SYSCLK0, 5);
- hws[CAN0_MUX] = ma35d1_clk_mux(dev, "can0_mux", clk_base + REG_CLK_CLKSEL4,
- 16, 1, can_sel_clks, ARRAY_SIZE(can_sel_clks));
+ hws[CAN0_MUX] = ma35d1_clk_mux(dev, "can0_mux", clk_base + REG_CLK_CLKSEL4, 16, 1, hws,
+ can_parent_idx, ARRAY_SIZE(can_parent_idx));
hws[CAN0_DIV] = ma35d1_clk_divider_table(dev, "can0_div", "can0_mux",
clk_base + REG_CLK_CLKDIV0,
0, 3, ip_div_table);
hws[CAN0_GATE] = ma35d1_clk_gate(dev, "can0_gate", "can0_div",
clk_base + REG_CLK_SYSCLK0, 8);
- hws[CAN1_MUX] = ma35d1_clk_mux(dev, "can1_mux", clk_base + REG_CLK_CLKSEL4,
- 17, 1, can_sel_clks, ARRAY_SIZE(can_sel_clks));
+ hws[CAN1_MUX] = ma35d1_clk_mux(dev, "can1_mux", clk_base + REG_CLK_CLKSEL4, 17, 1, hws,
+ can_parent_idx, ARRAY_SIZE(can_parent_idx));
hws[CAN1_DIV] = ma35d1_clk_divider_table(dev, "can1_div", "can1_mux",
clk_base + REG_CLK_CLKDIV0,
4, 3, ip_div_table);
hws[CAN1_GATE] = ma35d1_clk_gate(dev, "can1_gate", "can1_div",
clk_base + REG_CLK_SYSCLK0, 9);
- hws[CAN2_MUX] = ma35d1_clk_mux(dev, "can2_mux", clk_base + REG_CLK_CLKSEL4,
- 18, 1, can_sel_clks, ARRAY_SIZE(can_sel_clks));
+ hws[CAN2_MUX] = ma35d1_clk_mux(dev, "can2_mux", clk_base + REG_CLK_CLKSEL4, 18, 1, hws,
+ can_parent_idx, ARRAY_SIZE(can_parent_idx));
hws[CAN2_DIV] = ma35d1_clk_divider_table(dev, "can2_div", "can2_mux",
clk_base + REG_CLK_CLKDIV0,
8, 3, ip_div_table);
hws[CAN2_GATE] = ma35d1_clk_gate(dev, "can2_gate", "can2_div",
clk_base + REG_CLK_SYSCLK0, 10);
- hws[CAN3_MUX] = ma35d1_clk_mux(dev, "can3_mux", clk_base + REG_CLK_CLKSEL4,
- 19, 1, can_sel_clks, ARRAY_SIZE(can_sel_clks));
+ hws[CAN3_MUX] = ma35d1_clk_mux(dev, "can3_mux", clk_base + REG_CLK_CLKSEL4, 19, 1, hws,
+ can_parent_idx, ARRAY_SIZE(can_parent_idx));
hws[CAN3_DIV] = ma35d1_clk_divider_table(dev, "can3_div", "can3_mux",
clk_base + REG_CLK_CLKDIV0,
12, 3, ip_div_table);
hws[CAN3_GATE] = ma35d1_clk_gate(dev, "can3_gate", "can3_div",
clk_base + REG_CLK_SYSCLK0, 11);
- hws[SDH0_MUX] = ma35d1_clk_mux(dev, "sdh0_mux", clk_base + REG_CLK_CLKSEL0,
- 16, 2, sdh_sel_clks, ARRAY_SIZE(sdh_sel_clks));
+ hws[SDH0_MUX] = ma35d1_clk_mux(dev, "sdh0_mux", clk_base + REG_CLK_CLKSEL0, 16, 2, hws,
+ sdh_parent_idx, ARRAY_SIZE(sdh_parent_idx));
hws[SDH0_GATE] = ma35d1_clk_gate(dev, "sdh0_gate", "sdh0_mux",
clk_base + REG_CLK_SYSCLK0, 16);
- hws[SDH1_MUX] = ma35d1_clk_mux(dev, "sdh1_mux", clk_base + REG_CLK_CLKSEL0,
- 18, 2, sdh_sel_clks, ARRAY_SIZE(sdh_sel_clks));
+ hws[SDH1_MUX] = ma35d1_clk_mux(dev, "sdh1_mux", clk_base + REG_CLK_CLKSEL0, 18, 2, hws,
+ sdh_parent_idx, ARRAY_SIZE(sdh_parent_idx));
hws[SDH1_GATE] = ma35d1_clk_gate(dev, "sdh1_gate", "sdh1_mux",
clk_base + REG_CLK_SYSCLK0, 17);
@@ -606,14 +346,14 @@ static int ma35d1_clocks_probe(struct platform_device *pdev)
hws[HUSBH1_GATE] = ma35d1_clk_gate(dev, "husbh1_gate", "usbphy0",
clk_base + REG_CLK_SYSCLK0, 22);
- hws[GFX_MUX] = ma35d1_clk_mux(dev, "gfx_mux", clk_base + REG_CLK_CLKSEL0,
- 26, 1, gfx_sel_clks, ARRAY_SIZE(gfx_sel_clks));
+ hws[GFX_MUX] = ma35d1_clk_mux(dev, "gfx_mux", clk_base + REG_CLK_CLKSEL0, 26, 1, hws,
+ gfx_parent_idx, ARRAY_SIZE(gfx_parent_idx));
hws[GFX_GATE] = ma35d1_clk_gate(dev, "gfx_gate", "gfx_mux",
clk_base + REG_CLK_SYSCLK0, 24);
hws[VC8K_GATE] = ma35d1_clk_gate(dev, "vc8k_gate", "sysclk0_mux",
clk_base + REG_CLK_SYSCLK0, 25);
- hws[DCU_MUX] = ma35d1_clk_mux(dev, "dcu_mux", clk_base + REG_CLK_CLKSEL0,
- 24, 1, dcu_sel_clks, ARRAY_SIZE(dcu_sel_clks));
+ hws[DCU_MUX] = ma35d1_clk_mux(dev, "dcu_mux", clk_base + REG_CLK_CLKSEL0, 24, 1, hws,
+ dcu_parent_idx, ARRAY_SIZE(dcu_parent_idx));
hws[DCU_GATE] = ma35d1_clk_gate(dev, "dcu_gate", "dcu_mux",
clk_base + REG_CLK_SYSCLK0, 26);
hws[DCUP_DIV] = ma35d1_clk_divider_table(dev, "dcup_div", "vpll",
@@ -625,14 +365,14 @@ static int ma35d1_clocks_probe(struct platform_device *pdev)
hws[EMAC1_GATE] = ma35d1_clk_gate(dev, "emac1_gate", "epll_div2",
clk_base + REG_CLK_SYSCLK0, 28);
- hws[CCAP0_MUX] = ma35d1_clk_mux(dev, "ccap0_mux", clk_base + REG_CLK_CLKSEL0,
- 12, 1, ccap_sel_clks, ARRAY_SIZE(ccap_sel_clks));
+ hws[CCAP0_MUX] = ma35d1_clk_mux(dev, "ccap0_mux", clk_base + REG_CLK_CLKSEL0, 12, 1, hws,
+ ccap_parent_idx, ARRAY_SIZE(ccap_parent_idx));
hws[CCAP0_DIV] = ma35d1_clk_divider(dev, "ccap0_div", "ccap0_mux",
clk_base + REG_CLK_CLKDIV1, 8, 4);
hws[CCAP0_GATE] = ma35d1_clk_gate(dev, "ccap0_gate", "ccap0_div",
clk_base + REG_CLK_SYSCLK0, 29);
- hws[CCAP1_MUX] = ma35d1_clk_mux(dev, "ccap1_mux", clk_base + REG_CLK_CLKSEL0,
- 14, 1, ccap_sel_clks, ARRAY_SIZE(ccap_sel_clks));
+ hws[CCAP1_MUX] = ma35d1_clk_mux(dev, "ccap1_mux", clk_base + REG_CLK_CLKSEL0, 14, 1, hws,
+ ccap_parent_idx, ARRAY_SIZE(ccap_parent_idx));
hws[CCAP1_DIV] = ma35d1_clk_divider(dev, "ccap1_div", "ccap1_mux",
clk_base + REG_CLK_CLKDIV1,
12, 4);
@@ -670,13 +410,13 @@ static int ma35d1_clocks_probe(struct platform_device *pdev)
hws[TRA_GATE] = ma35d1_clk_gate(dev, "tra_gate", "hclk0",
clk_base + REG_CLK_SYSCLK1, 11);
- hws[DBG_MUX] = ma35d1_clk_mux(dev, "dbg_mux", clk_base + REG_CLK_CLKSEL0,
- 27, 1, dbg_sel_clks, ARRAY_SIZE(dbg_sel_clks));
+ hws[DBG_MUX] = ma35d1_clk_mux(dev, "dbg_mux", clk_base + REG_CLK_CLKSEL0, 27, 1, hws,
+ dbg_parent_idx, ARRAY_SIZE(dbg_parent_idx));
hws[DBG_GATE] = ma35d1_clk_gate(dev, "dbg_gate", "hclk0",
clk_base + REG_CLK_SYSCLK1, 12);
- hws[CKO_MUX] = ma35d1_clk_mux(dev, "cko_mux", clk_base + REG_CLK_CLKSEL4,
- 24, 4, cko_sel_clks, ARRAY_SIZE(cko_sel_clks));
+ hws[CKO_MUX] = ma35d1_clk_mux(dev, "cko_mux", clk_base + REG_CLK_CLKSEL4, 24, 4, hws,
+ cko_parent_idx, ARRAY_SIZE(cko_parent_idx));
hws[CKO_DIV] = ma35d1_clk_divider_pow2(dev, "cko_div", "cko_mux",
clk_base + REG_CLK_CLKOCTL, 0, 4);
hws[CKO_GATE] = ma35d1_clk_gate(dev, "cko_gate", "cko_div",
@@ -714,181 +454,169 @@ static int ma35d1_clocks_probe(struct platform_device *pdev)
hws[GPN_GATE] = ma35d1_clk_gate(dev, "gpn_gate", "hclk0",
clk_base + REG_CLK_SYSCLK1, 29);
- hws[TMR0_MUX] = ma35d1_clk_mux(dev, "tmr0_mux", clk_base + REG_CLK_CLKSEL1,
- 0, 3, timer0_sel_clks,
- ARRAY_SIZE(timer0_sel_clks));
+ hws[TMR0_MUX] = ma35d1_clk_mux(dev, "tmr0_mux", clk_base + REG_CLK_CLKSEL1, 0, 3, hws,
+ timer0_parent_idx, ARRAY_SIZE(timer0_parent_idx));
hws[TMR0_GATE] = ma35d1_clk_gate(dev, "tmr0_gate", "tmr0_mux",
clk_base + REG_CLK_APBCLK0, 0);
- hws[TMR1_MUX] = ma35d1_clk_mux(dev, "tmr1_mux", clk_base + REG_CLK_CLKSEL1,
- 4, 3, timer1_sel_clks,
- ARRAY_SIZE(timer1_sel_clks));
+ hws[TMR1_MUX] = ma35d1_clk_mux(dev, "tmr1_mux", clk_base + REG_CLK_CLKSEL1, 4, 3, hws,
+ timer1_parent_idx, ARRAY_SIZE(timer1_parent_idx));
hws[TMR1_GATE] = ma35d1_clk_gate(dev, "tmr1_gate", "tmr1_mux",
clk_base + REG_CLK_APBCLK0, 1);
- hws[TMR2_MUX] = ma35d1_clk_mux(dev, "tmr2_mux", clk_base + REG_CLK_CLKSEL1,
- 8, 3, timer2_sel_clks,
- ARRAY_SIZE(timer2_sel_clks));
+ hws[TMR2_MUX] = ma35d1_clk_mux(dev, "tmr2_mux", clk_base + REG_CLK_CLKSEL1, 8, 3, hws,
+ timer2_parent_idx, ARRAY_SIZE(timer2_parent_idx));
hws[TMR2_GATE] = ma35d1_clk_gate(dev, "tmr2_gate", "tmr2_mux",
clk_base + REG_CLK_APBCLK0, 2);
- hws[TMR3_MUX] = ma35d1_clk_mux(dev, "tmr3_mux", clk_base + REG_CLK_CLKSEL1,
- 12, 3, timer3_sel_clks,
- ARRAY_SIZE(timer3_sel_clks));
+ hws[TMR3_MUX] = ma35d1_clk_mux(dev, "tmr3_mux", clk_base + REG_CLK_CLKSEL1, 12, 3, hws,
+ timer3_parent_idx, ARRAY_SIZE(timer3_parent_idx));
hws[TMR3_GATE] = ma35d1_clk_gate(dev, "tmr3_gate", "tmr3_mux",
clk_base + REG_CLK_APBCLK0, 3);
- hws[TMR4_MUX] = ma35d1_clk_mux(dev, "tmr4_mux", clk_base + REG_CLK_CLKSEL1,
- 16, 3, timer4_sel_clks,
- ARRAY_SIZE(timer4_sel_clks));
+ hws[TMR4_MUX] = ma35d1_clk_mux(dev, "tmr4_mux", clk_base + REG_CLK_CLKSEL1, 16, 3, hws,
+ timer4_parent_idx, ARRAY_SIZE(timer4_parent_idx));
hws[TMR4_GATE] = ma35d1_clk_gate(dev, "tmr4_gate", "tmr4_mux",
clk_base + REG_CLK_APBCLK0, 4);
- hws[TMR5_MUX] = ma35d1_clk_mux(dev, "tmr5_mux", clk_base + REG_CLK_CLKSEL1,
- 20, 3, timer5_sel_clks,
- ARRAY_SIZE(timer5_sel_clks));
+ hws[TMR5_MUX] = ma35d1_clk_mux(dev, "tmr5_mux", clk_base + REG_CLK_CLKSEL1, 20, 3, hws,
+ timer5_parent_idx, ARRAY_SIZE(timer5_parent_idx));
hws[TMR5_GATE] = ma35d1_clk_gate(dev, "tmr5_gate", "tmr5_mux",
clk_base + REG_CLK_APBCLK0, 5);
- hws[TMR6_MUX] = ma35d1_clk_mux(dev, "tmr6_mux", clk_base + REG_CLK_CLKSEL1,
- 24, 3, timer6_sel_clks,
- ARRAY_SIZE(timer6_sel_clks));
+ hws[TMR6_MUX] = ma35d1_clk_mux(dev, "tmr6_mux", clk_base + REG_CLK_CLKSEL1, 24, 3, hws,
+ timer6_parent_idx, ARRAY_SIZE(timer6_parent_idx));
hws[TMR6_GATE] = ma35d1_clk_gate(dev, "tmr6_gate", "tmr6_mux",
clk_base + REG_CLK_APBCLK0, 6);
- hws[TMR7_MUX] = ma35d1_clk_mux(dev, "tmr7_mux", clk_base + REG_CLK_CLKSEL1,
- 28, 3, timer7_sel_clks,
- ARRAY_SIZE(timer7_sel_clks));
+ hws[TMR7_MUX] = ma35d1_clk_mux(dev, "tmr7_mux", clk_base + REG_CLK_CLKSEL1, 28, 3, hws,
+ timer7_parent_idx, ARRAY_SIZE(timer7_parent_idx));
hws[TMR7_GATE] = ma35d1_clk_gate(dev, "tmr7_gate", "tmr7_mux",
clk_base + REG_CLK_APBCLK0, 7);
- hws[TMR8_MUX] = ma35d1_clk_mux(dev, "tmr8_mux", clk_base + REG_CLK_CLKSEL2,
- 0, 3, timer8_sel_clks,
- ARRAY_SIZE(timer8_sel_clks));
+ hws[TMR8_MUX] = ma35d1_clk_mux(dev, "tmr8_mux", clk_base + REG_CLK_CLKSEL2, 0, 3, hws,
+ timer8_parent_idx, ARRAY_SIZE(timer8_parent_idx));
hws[TMR8_GATE] = ma35d1_clk_gate(dev, "tmr8_gate", "tmr8_mux",
clk_base + REG_CLK_APBCLK0, 8);
- hws[TMR9_MUX] = ma35d1_clk_mux(dev, "tmr9_mux", clk_base + REG_CLK_CLKSEL2,
- 4, 3, timer9_sel_clks,
- ARRAY_SIZE(timer9_sel_clks));
+ hws[TMR9_MUX] = ma35d1_clk_mux(dev, "tmr9_mux", clk_base + REG_CLK_CLKSEL2, 4, 3, hws,
+ timer9_parent_idx, ARRAY_SIZE(timer9_parent_idx));
hws[TMR9_GATE] = ma35d1_clk_gate(dev, "tmr9_gate", "tmr9_mux",
clk_base + REG_CLK_APBCLK0, 9);
- hws[TMR10_MUX] = ma35d1_clk_mux(dev, "tmr10_mux", clk_base + REG_CLK_CLKSEL2,
- 8, 3, timer10_sel_clks,
- ARRAY_SIZE(timer10_sel_clks));
+ hws[TMR10_MUX] = ma35d1_clk_mux(dev, "tmr10_mux", clk_base + REG_CLK_CLKSEL2, 8, 3, hws,
+ timer10_parent_idx, ARRAY_SIZE(timer10_parent_idx));
hws[TMR10_GATE] = ma35d1_clk_gate(dev, "tmr10_gate", "tmr10_mux",
clk_base + REG_CLK_APBCLK0, 10);
- hws[TMR11_MUX] = ma35d1_clk_mux(dev, "tmr11_mux", clk_base + REG_CLK_CLKSEL2,
- 12, 3, timer11_sel_clks,
- ARRAY_SIZE(timer11_sel_clks));
+ hws[TMR11_MUX] = ma35d1_clk_mux(dev, "tmr11_mux", clk_base + REG_CLK_CLKSEL2, 12, 3, hws,
+ timer11_parent_idx, ARRAY_SIZE(timer11_parent_idx));
hws[TMR11_GATE] = ma35d1_clk_gate(dev, "tmr11_gate", "tmr11_mux",
clk_base + REG_CLK_APBCLK0, 11);
- hws[UART0_MUX] = ma35d1_clk_mux(dev, "uart0_mux", clk_base + REG_CLK_CLKSEL2,
- 16, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
+ hws[UART0_MUX] = ma35d1_clk_mux(dev, "uart0_mux", clk_base + REG_CLK_CLKSEL2, 16, 2, hws,
+ uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
hws[UART0_DIV] = ma35d1_clk_divider(dev, "uart0_div", "uart0_mux",
clk_base + REG_CLK_CLKDIV1,
16, 4);
hws[UART0_GATE] = ma35d1_clk_gate(dev, "uart0_gate", "uart0_div",
clk_base + REG_CLK_APBCLK0, 12);
- hws[UART1_MUX] = ma35d1_clk_mux(dev, "uart1_mux", clk_base + REG_CLK_CLKSEL2,
- 18, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
+ hws[UART1_MUX] = ma35d1_clk_mux(dev, "uart1_mux", clk_base + REG_CLK_CLKSEL2, 18, 2, hws,
+ uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
hws[UART1_DIV] = ma35d1_clk_divider(dev, "uart1_div", "uart1_mux",
clk_base + REG_CLK_CLKDIV1,
20, 4);
hws[UART1_GATE] = ma35d1_clk_gate(dev, "uart1_gate", "uart1_div",
clk_base + REG_CLK_APBCLK0, 13);
- hws[UART2_MUX] = ma35d1_clk_mux(dev, "uart2_mux", clk_base + REG_CLK_CLKSEL2,
- 20, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
+ hws[UART2_MUX] = ma35d1_clk_mux(dev, "uart2_mux", clk_base + REG_CLK_CLKSEL2, 20, 2, hws,
+ uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
hws[UART2_DIV] = ma35d1_clk_divider(dev, "uart2_div", "uart2_mux",
clk_base + REG_CLK_CLKDIV1,
24, 4);
hws[UART2_GATE] = ma35d1_clk_gate(dev, "uart2_gate", "uart2_div",
clk_base + REG_CLK_APBCLK0, 14);
- hws[UART3_MUX] = ma35d1_clk_mux(dev, "uart3_mux", clk_base + REG_CLK_CLKSEL2,
- 22, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
+ hws[UART3_MUX] = ma35d1_clk_mux(dev, "uart3_mux", clk_base + REG_CLK_CLKSEL2, 22, 2, hws,
+ uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
hws[UART3_DIV] = ma35d1_clk_divider(dev, "uart3_div", "uart3_mux",
clk_base + REG_CLK_CLKDIV1,
28, 4);
hws[UART3_GATE] = ma35d1_clk_gate(dev, "uart3_gate", "uart3_div",
clk_base + REG_CLK_APBCLK0, 15);
- hws[UART4_MUX] = ma35d1_clk_mux(dev, "uart4_mux", clk_base + REG_CLK_CLKSEL2,
- 24, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
+ hws[UART4_MUX] = ma35d1_clk_mux(dev, "uart4_mux", clk_base + REG_CLK_CLKSEL2, 24, 2, hws,
+ uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
hws[UART4_DIV] = ma35d1_clk_divider(dev, "uart4_div", "uart4_mux",
clk_base + REG_CLK_CLKDIV2,
0, 4);
hws[UART4_GATE] = ma35d1_clk_gate(dev, "uart4_gate", "uart4_div",
clk_base + REG_CLK_APBCLK0, 16);
- hws[UART5_MUX] = ma35d1_clk_mux(dev, "uart5_mux", clk_base + REG_CLK_CLKSEL2,
- 26, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
+ hws[UART5_MUX] = ma35d1_clk_mux(dev, "uart5_mux", clk_base + REG_CLK_CLKSEL2, 26, 2, hws,
+ uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
hws[UART5_DIV] = ma35d1_clk_divider(dev, "uart5_div", "uart5_mux",
clk_base + REG_CLK_CLKDIV2,
4, 4);
hws[UART5_GATE] = ma35d1_clk_gate(dev, "uart5_gate", "uart5_div",
clk_base + REG_CLK_APBCLK0, 17);
- hws[UART6_MUX] = ma35d1_clk_mux(dev, "uart6_mux", clk_base + REG_CLK_CLKSEL2,
- 28, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
+ hws[UART6_MUX] = ma35d1_clk_mux(dev, "uart6_mux", clk_base + REG_CLK_CLKSEL2, 28, 2, hws,
+ uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
hws[UART6_DIV] = ma35d1_clk_divider(dev, "uart6_div", "uart6_mux",
clk_base + REG_CLK_CLKDIV2,
8, 4);
hws[UART6_GATE] = ma35d1_clk_gate(dev, "uart6_gate", "uart6_div",
clk_base + REG_CLK_APBCLK0, 18);
- hws[UART7_MUX] = ma35d1_clk_mux(dev, "uart7_mux", clk_base + REG_CLK_CLKSEL2,
- 30, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
+ hws[UART7_MUX] = ma35d1_clk_mux(dev, "uart7_mux", clk_base + REG_CLK_CLKSEL2, 30, 2, hws,
+ uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
hws[UART7_DIV] = ma35d1_clk_divider(dev, "uart7_div", "uart7_mux",
clk_base + REG_CLK_CLKDIV2,
12, 4);
hws[UART7_GATE] = ma35d1_clk_gate(dev, "uart7_gate", "uart7_div",
clk_base + REG_CLK_APBCLK0, 19);
- hws[UART8_MUX] = ma35d1_clk_mux(dev, "uart8_mux", clk_base + REG_CLK_CLKSEL3,
- 0, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
+ hws[UART8_MUX] = ma35d1_clk_mux(dev, "uart8_mux", clk_base + REG_CLK_CLKSEL3, 0, 2, hws,
+ uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
hws[UART8_DIV] = ma35d1_clk_divider(dev, "uart8_div", "uart8_mux",
clk_base + REG_CLK_CLKDIV2,
16, 4);
hws[UART8_GATE] = ma35d1_clk_gate(dev, "uart8_gate", "uart8_div",
clk_base + REG_CLK_APBCLK0, 20);
- hws[UART9_MUX] = ma35d1_clk_mux(dev, "uart9_mux", clk_base + REG_CLK_CLKSEL3,
- 2, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
+ hws[UART9_MUX] = ma35d1_clk_mux(dev, "uart9_mux", clk_base + REG_CLK_CLKSEL3, 2, 2, hws,
+ uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
hws[UART9_DIV] = ma35d1_clk_divider(dev, "uart9_div", "uart9_mux",
clk_base + REG_CLK_CLKDIV2,
20, 4);
hws[UART9_GATE] = ma35d1_clk_gate(dev, "uart9_gate", "uart9_div",
clk_base + REG_CLK_APBCLK0, 21);
- hws[UART10_MUX] = ma35d1_clk_mux(dev, "uart10_mux", clk_base + REG_CLK_CLKSEL3,
- 4, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
+ hws[UART10_MUX] = ma35d1_clk_mux(dev, "uart10_mux", clk_base + REG_CLK_CLKSEL3, 4, 2, hws,
+ uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
hws[UART10_DIV] = ma35d1_clk_divider(dev, "uart10_div", "uart10_mux",
clk_base + REG_CLK_CLKDIV2,
24, 4);
hws[UART10_GATE] = ma35d1_clk_gate(dev, "uart10_gate", "uart10_div",
clk_base + REG_CLK_APBCLK0, 22);
- hws[UART11_MUX] = ma35d1_clk_mux(dev, "uart11_mux", clk_base + REG_CLK_CLKSEL3,
- 6, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
+ hws[UART11_MUX] = ma35d1_clk_mux(dev, "uart11_mux", clk_base + REG_CLK_CLKSEL3, 6, 2, hws,
+ uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
hws[UART11_DIV] = ma35d1_clk_divider(dev, "uart11_div", "uart11_mux",
clk_base + REG_CLK_CLKDIV2,
28, 4);
hws[UART11_GATE] = ma35d1_clk_gate(dev, "uart11_gate", "uart11_div",
clk_base + REG_CLK_APBCLK0, 23);
- hws[UART12_MUX] = ma35d1_clk_mux(dev, "uart12_mux", clk_base + REG_CLK_CLKSEL3,
- 8, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
+ hws[UART12_MUX] = ma35d1_clk_mux(dev, "uart12_mux", clk_base + REG_CLK_CLKSEL3, 8, 2, hws,
+ uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
hws[UART12_DIV] = ma35d1_clk_divider(dev, "uart12_div", "uart12_mux",
clk_base + REG_CLK_CLKDIV3,
0, 4);
hws[UART12_GATE] = ma35d1_clk_gate(dev, "uart12_gate", "uart12_div",
clk_base + REG_CLK_APBCLK0, 24);
- hws[UART13_MUX] = ma35d1_clk_mux(dev, "uart13_mux", clk_base + REG_CLK_CLKSEL3,
- 10, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
+ hws[UART13_MUX] = ma35d1_clk_mux(dev, "uart13_mux", clk_base + REG_CLK_CLKSEL3, 10, 2, hws,
+ uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
hws[UART13_DIV] = ma35d1_clk_divider(dev, "uart13_div", "uart13_mux",
clk_base + REG_CLK_CLKDIV3,
4, 4);
hws[UART13_GATE] = ma35d1_clk_gate(dev, "uart13_gate", "uart13_div",
clk_base + REG_CLK_APBCLK0, 25);
- hws[UART14_MUX] = ma35d1_clk_mux(dev, "uart14_mux", clk_base + REG_CLK_CLKSEL3,
- 12, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
+ hws[UART14_MUX] = ma35d1_clk_mux(dev, "uart14_mux", clk_base + REG_CLK_CLKSEL3, 12, 2, hws,
+ uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
hws[UART14_DIV] = ma35d1_clk_divider(dev, "uart14_div", "uart14_mux",
clk_base + REG_CLK_CLKDIV3,
8, 4);
hws[UART14_GATE] = ma35d1_clk_gate(dev, "uart14_gate", "uart14_div",
clk_base + REG_CLK_APBCLK0, 26);
- hws[UART15_MUX] = ma35d1_clk_mux(dev, "uart15_mux", clk_base + REG_CLK_CLKSEL3,
- 14, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
+ hws[UART15_MUX] = ma35d1_clk_mux(dev, "uart15_mux", clk_base + REG_CLK_CLKSEL3, 14, 2, hws,
+ uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
hws[UART15_DIV] = ma35d1_clk_divider(dev, "uart15_div", "uart15_mux",
clk_base + REG_CLK_CLKDIV3,
12, 4);
hws[UART15_GATE] = ma35d1_clk_gate(dev, "uart15_gate", "uart15_div",
clk_base + REG_CLK_APBCLK0, 27);
- hws[UART16_MUX] = ma35d1_clk_mux(dev, "uart16_mux", clk_base + REG_CLK_CLKSEL3,
- 16, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
+ hws[UART16_MUX] = ma35d1_clk_mux(dev, "uart16_mux", clk_base + REG_CLK_CLKSEL3, 16, 2, hws,
+ uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
hws[UART16_DIV] = ma35d1_clk_divider(dev, "uart16_div", "uart16_mux",
clk_base + REG_CLK_CLKDIV3,
16, 4);
@@ -900,8 +628,8 @@ static int ma35d1_clocks_probe(struct platform_device *pdev)
hws[DDR_GATE] = ma35d1_clk_gate(dev, "ddr_gate", "ddrpll",
clk_base + REG_CLK_APBCLK0, 30);
- hws[KPI_MUX] = ma35d1_clk_mux(dev, "kpi_mux", clk_base + REG_CLK_CLKSEL4,
- 30, 1, kpi_sel_clks, ARRAY_SIZE(kpi_sel_clks));
+ hws[KPI_MUX] = ma35d1_clk_mux(dev, "kpi_mux", clk_base + REG_CLK_CLKSEL4, 30, 1, hws,
+ kpi_parent_idx, ARRAY_SIZE(kpi_parent_idx));
hws[KPI_DIV] = ma35d1_clk_divider(dev, "kpi_div", "kpi_mux",
clk_base + REG_CLK_CLKDIV4,
24, 8);
@@ -921,49 +649,49 @@ static int ma35d1_clocks_probe(struct platform_device *pdev)
hws[I2C5_GATE] = ma35d1_clk_gate(dev, "i2c5_gate", "pclk2",
clk_base + REG_CLK_APBCLK1, 5);
- hws[QSPI0_MUX] = ma35d1_clk_mux(dev, "qspi0_mux", clk_base + REG_CLK_CLKSEL4,
- 8, 2, qspi0_sel_clks, ARRAY_SIZE(qspi0_sel_clks));
+ hws[QSPI0_MUX] = ma35d1_clk_mux(dev, "qspi0_mux", clk_base + REG_CLK_CLKSEL4, 8, 2, hws,
+ qspi_parent_idx, ARRAY_SIZE(qspi_parent_idx));
hws[QSPI0_GATE] = ma35d1_clk_gate(dev, "qspi0_gate", "qspi0_mux",
clk_base + REG_CLK_APBCLK1, 6);
- hws[QSPI1_MUX] = ma35d1_clk_mux(dev, "qspi1_mux", clk_base + REG_CLK_CLKSEL4,
- 10, 2, qspi1_sel_clks, ARRAY_SIZE(qspi1_sel_clks));
+ hws[QSPI1_MUX] = ma35d1_clk_mux(dev, "qspi1_mux", clk_base + REG_CLK_CLKSEL4, 10, 2, hws,
+ qspi_parent_idx, ARRAY_SIZE(qspi_parent_idx));
hws[QSPI1_GATE] = ma35d1_clk_gate(dev, "qspi1_gate", "qspi1_mux",
clk_base + REG_CLK_APBCLK1, 7);
- hws[SMC0_MUX] = ma35d1_clk_mux(dev, "smc0_mux", clk_base + REG_CLK_CLKSEL4,
- 28, 1, smc_sel_clks, ARRAY_SIZE(smc_sel_clks));
+ hws[SMC0_MUX] = ma35d1_clk_mux(dev, "smc0_mux", clk_base + REG_CLK_CLKSEL4, 28, 1, hws,
+ smc_parent_idx, ARRAY_SIZE(smc_parent_idx));
hws[SMC0_DIV] = ma35d1_clk_divider(dev, "smc0_div", "smc0_mux",
clk_base + REG_CLK_CLKDIV1,
0, 4);
hws[SMC0_GATE] = ma35d1_clk_gate(dev, "smc0_gate", "smc0_div",
clk_base + REG_CLK_APBCLK1, 12);
- hws[SMC1_MUX] = ma35d1_clk_mux(dev, "smc1_mux", clk_base + REG_CLK_CLKSEL4,
- 29, 1, smc_sel_clks, ARRAY_SIZE(smc_sel_clks));
+ hws[SMC1_MUX] = ma35d1_clk_mux(dev, "smc1_mux", clk_base + REG_CLK_CLKSEL4, 29, 1, hws,
+ smc_parent_idx, ARRAY_SIZE(smc_parent_idx));
hws[SMC1_DIV] = ma35d1_clk_divider(dev, "smc1_div", "smc1_mux",
clk_base + REG_CLK_CLKDIV1,
4, 4);
hws[SMC1_GATE] = ma35d1_clk_gate(dev, "smc1_gate", "smc1_div",
clk_base + REG_CLK_APBCLK1, 13);
- hws[WDT0_MUX] = ma35d1_clk_mux(dev, "wdt0_mux", clk_base + REG_CLK_CLKSEL3,
- 20, 2, wdt0_sel_clks, ARRAY_SIZE(wdt0_sel_clks));
+ hws[WDT0_MUX] = ma35d1_clk_mux(dev, "wdt0_mux", clk_base + REG_CLK_CLKSEL3, 20, 2, hws,
+ wdt0_parent_idx, ARRAY_SIZE(wdt0_parent_idx));
hws[WDT0_GATE] = ma35d1_clk_gate(dev, "wdt0_gate", "wdt0_mux",
clk_base + REG_CLK_APBCLK1, 16);
- hws[WDT1_MUX] = ma35d1_clk_mux(dev, "wdt1_mux", clk_base + REG_CLK_CLKSEL3,
- 24, 2, wdt1_sel_clks, ARRAY_SIZE(wdt1_sel_clks));
+ hws[WDT1_MUX] = ma35d1_clk_mux(dev, "wdt1_mux", clk_base + REG_CLK_CLKSEL3, 24, 2, hws,
+ wdt1_parent_idx, ARRAY_SIZE(wdt1_parent_idx));
hws[WDT1_GATE] = ma35d1_clk_gate(dev, "wdt1_gate", "wdt1_mux",
clk_base + REG_CLK_APBCLK1, 17);
- hws[WDT2_MUX] = ma35d1_clk_mux(dev, "wdt2_mux", clk_base + REG_CLK_CLKSEL3,
- 28, 2, wdt2_sel_clks, ARRAY_SIZE(wdt2_sel_clks));
+ hws[WDT2_MUX] = ma35d1_clk_mux(dev, "wdt2_mux", clk_base + REG_CLK_CLKSEL3, 28, 2, hws,
+ wdt2_parent_idx, ARRAY_SIZE(wdt2_parent_idx));
hws[WDT2_GATE] = ma35d1_clk_gate(dev, "wdt2_gate", "wdt2_mux",
clk_base + REG_CLK_APBCLK1, 18);
- hws[WWDT0_MUX] = ma35d1_clk_mux(dev, "wwdt0_mux", clk_base + REG_CLK_CLKSEL3,
- 22, 2, wwdt0_sel_clks, ARRAY_SIZE(wwdt0_sel_clks));
- hws[WWDT1_MUX] = ma35d1_clk_mux(dev, "wwdt1_mux", clk_base + REG_CLK_CLKSEL3,
- 26, 2, wwdt1_sel_clks, ARRAY_SIZE(wwdt1_sel_clks));
- hws[WWDT2_MUX] = ma35d1_clk_mux(dev, "wwdt2_mux", clk_base + REG_CLK_CLKSEL3,
- 30, 2, wwdt2_sel_clks, ARRAY_SIZE(wwdt2_sel_clks));
+ hws[WWDT0_MUX] = ma35d1_clk_mux(dev, "wwdt0_mux", clk_base + REG_CLK_CLKSEL3, 22, 2, hws,
+ wwdt0_parent_idx, ARRAY_SIZE(wwdt0_parent_idx));
+ hws[WWDT1_MUX] = ma35d1_clk_mux(dev, "wwdt1_mux", clk_base + REG_CLK_CLKSEL3, 26, 2, hws,
+ wwdt1_parent_idx, ARRAY_SIZE(wwdt1_parent_idx));
+ hws[WWDT2_MUX] = ma35d1_clk_mux(dev, "wwdt2_mux", clk_base + REG_CLK_CLKSEL3, 30, 2, hws,
+ wwdt2_parent_idx, ARRAY_SIZE(wwdt2_parent_idx));
hws[EPWM0_GATE] = ma35d1_clk_gate(dev, "epwm0_gate", "pclk1",
clk_base + REG_CLK_APBCLK1, 24);
@@ -972,12 +700,12 @@ static int ma35d1_clocks_probe(struct platform_device *pdev)
hws[EPWM2_GATE] = ma35d1_clk_gate(dev, "epwm2_gate", "pclk1",
clk_base + REG_CLK_APBCLK1, 26);
- hws[I2S0_MUX] = ma35d1_clk_mux(dev, "i2s0_mux", clk_base + REG_CLK_CLKSEL4,
- 12, 2, i2s0_sel_clks, ARRAY_SIZE(i2s0_sel_clks));
+ hws[I2S0_MUX] = ma35d1_clk_mux(dev, "i2s0_mux", clk_base + REG_CLK_CLKSEL4, 12, 2, hws,
+ i2s_parent_idx, ARRAY_SIZE(i2s_parent_idx));
hws[I2S0_GATE] = ma35d1_clk_gate(dev, "i2s0_gate", "i2s0_mux",
clk_base + REG_CLK_APBCLK2, 0);
- hws[I2S1_MUX] = ma35d1_clk_mux(dev, "i2s1_mux", clk_base + REG_CLK_CLKSEL4,
- 14, 2, i2s1_sel_clks, ARRAY_SIZE(i2s1_sel_clks));
+ hws[I2S1_MUX] = ma35d1_clk_mux(dev, "i2s1_mux", clk_base + REG_CLK_CLKSEL4, 14, 2, hws,
+ i2s_parent_idx, ARRAY_SIZE(i2s_parent_idx));
hws[I2S1_GATE] = ma35d1_clk_gate(dev, "i2s1_gate", "i2s1_mux",
clk_base + REG_CLK_APBCLK2, 1);
@@ -986,20 +714,20 @@ static int ma35d1_clocks_probe(struct platform_device *pdev)
hws[SSPCC_GATE] = ma35d1_clk_gate(dev, "sspcc_gate", "pclk3",
clk_base + REG_CLK_APBCLK2, 3);
- hws[SPI0_MUX] = ma35d1_clk_mux(dev, "spi0_mux", clk_base + REG_CLK_CLKSEL4,
- 0, 2, spi0_sel_clks, ARRAY_SIZE(spi0_sel_clks));
+ hws[SPI0_MUX] = ma35d1_clk_mux(dev, "spi0_mux", clk_base + REG_CLK_CLKSEL4, 0, 2, hws,
+ spi0_parent_idx, ARRAY_SIZE(spi0_parent_idx));
hws[SPI0_GATE] = ma35d1_clk_gate(dev, "spi0_gate", "spi0_mux",
clk_base + REG_CLK_APBCLK2, 4);
- hws[SPI1_MUX] = ma35d1_clk_mux(dev, "spi1_mux", clk_base + REG_CLK_CLKSEL4,
- 2, 2, spi1_sel_clks, ARRAY_SIZE(spi1_sel_clks));
+ hws[SPI1_MUX] = ma35d1_clk_mux(dev, "spi1_mux", clk_base + REG_CLK_CLKSEL4, 2, 2, hws,
+ spi1_parent_idx, ARRAY_SIZE(spi1_parent_idx));
hws[SPI1_GATE] = ma35d1_clk_gate(dev, "spi1_gate", "spi1_mux",
clk_base + REG_CLK_APBCLK2, 5);
- hws[SPI2_MUX] = ma35d1_clk_mux(dev, "spi2_mux", clk_base + REG_CLK_CLKSEL4,
- 4, 2, spi2_sel_clks, ARRAY_SIZE(spi2_sel_clks));
+ hws[SPI2_MUX] = ma35d1_clk_mux(dev, "spi2_mux", clk_base + REG_CLK_CLKSEL4, 4, 2, hws,
+ spi2_parent_idx, ARRAY_SIZE(spi2_parent_idx));
hws[SPI2_GATE] = ma35d1_clk_gate(dev, "spi2_gate", "spi2_mux",
clk_base + REG_CLK_APBCLK2, 6);
- hws[SPI3_MUX] = ma35d1_clk_mux(dev, "spi3_mux", clk_base + REG_CLK_CLKSEL4,
- 6, 2, spi3_sel_clks, ARRAY_SIZE(spi3_sel_clks));
+ hws[SPI3_MUX] = ma35d1_clk_mux(dev, "spi3_mux", clk_base + REG_CLK_CLKSEL4, 6, 2, hws,
+ spi3_parent_idx, ARRAY_SIZE(spi3_parent_idx));
hws[SPI3_GATE] = ma35d1_clk_gate(dev, "spi3_gate", "spi3_mux",
clk_base + REG_CLK_APBCLK2, 7);
--
2.55.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v4 6/6] clk: nuvoton: ma35d1: Avoid possible error pointer dereferencing
2026-09-25 15:10 [PATCH v4 0/6] clk: nuvoton: ma35d1: Fix mux parenting and peripheral clock rates Miquel Raynal
` (4 preceding siblings ...)
2026-09-25 15:10 ` [PATCH v4 5/6] clk: nuvoton: ma35d1: Use clk_hw pointers as mux parents Miquel Raynal
@ 2026-09-25 15:10 ` Miquel Raynal
5 siblings, 0 replies; 12+ messages in thread
From: Miquel Raynal @ 2026-09-25 15:10 UTC (permalink / raw)
To: Jacky Huang, Shan-Chun Hung, Michael Turquette, Stephen Boyd,
Richard Cochran, Arnd Bergmann, Brian Masney, Jerome Brunet,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Thomas Petazzoni, Steam Lin, linux-arm-kernel, linux-clk,
linux-kernel, Krzysztof Kozlowski, devicetree, Miquel Raynal
MA35D1 registration helpers store their parent_hw
argument straight into the parent data, without checking it first. In
case of registration failure an error pointer will be stored in the
table, which is then forwarded to the clk core, which treats any
non-NULL parent as valid handles.
Bail out early when the parent is an error pointer, instead of building
the parent data.
This issue is mostly theoretical in practice, since reaching such an
error would involve a very early -ENOMEM.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
drivers/clk/nuvoton/clk-ma35d1-divider.c | 3 +++
drivers/clk/nuvoton/clk-ma35d1-pll.c | 3 +++
drivers/clk/nuvoton/clk-ma35d1.c | 13 +++++++++++--
3 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/nuvoton/clk-ma35d1-divider.c b/drivers/clk/nuvoton/clk-ma35d1-divider.c
index e992e7c30341..57a7b4ed3b5e 100644
--- a/drivers/clk/nuvoton/clk-ma35d1-divider.c
+++ b/drivers/clk/nuvoton/clk-ma35d1-divider.c
@@ -90,6 +90,9 @@ struct clk_hw *ma35d1_reg_adc_clkdiv(struct device *dev, const char *name,
int ret;
int i;
+ if (IS_ERR(parent_hw))
+ return parent_hw;
+
div = devm_kzalloc(dev, sizeof(*div), GFP_KERNEL);
if (!div)
return ERR_PTR(-ENOMEM);
diff --git a/drivers/clk/nuvoton/clk-ma35d1-pll.c b/drivers/clk/nuvoton/clk-ma35d1-pll.c
index c7c0dc91a012..92424e9c669d 100644
--- a/drivers/clk/nuvoton/clk-ma35d1-pll.c
+++ b/drivers/clk/nuvoton/clk-ma35d1-pll.c
@@ -336,6 +336,9 @@ struct clk_hw *ma35d1_reg_clk_pll(struct device *dev, u32 id, u8 u8mode, const c
struct clk_hw *hw;
int ret;
+ if (IS_ERR(parent_hw))
+ return parent_hw;
+
pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL);
if (!pll)
return ERR_PTR(-ENOMEM);
diff --git a/drivers/clk/nuvoton/clk-ma35d1.c b/drivers/clk/nuvoton/clk-ma35d1.c
index 1a857f28310f..ceebcbd8c18b 100644
--- a/drivers/clk/nuvoton/clk-ma35d1.c
+++ b/drivers/clk/nuvoton/clk-ma35d1.c
@@ -130,10 +130,19 @@ static struct clk_hw *ma35d1_clk_mux(struct device *dev, const char *name,
const int *parent_idx, int num_parents)
{
const struct clk_hw *parent_hws[MA35D1_MUX_MAX_PARENTS] = {};
+ struct clk_hw *parent;
int i;
- for (i = 0; i < num_parents; i++)
- parent_hws[i] = (parent_idx[i] >= 0) ? hws[parent_idx[i]] : NULL;
+ for (i = 0; i < num_parents; i++) {
+ if (parent_idx[i] < 0)
+ continue;
+
+ parent = hws[parent_idx[i]];
+ if (IS_ERR(parent))
+ return parent;
+
+ parent_hws[i] = parent;
+ }
return clk_hw_register_mux_hws(dev, name, parent_hws, num_parents,
CLK_SET_RATE_NO_REPARENT, reg, shift,
--
2.55.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4 2/6] dt-bindings: clock: ma35d1: Drop CLK_MAX_IDX define
2026-09-25 15:10 ` [PATCH v4 2/6] dt-bindings: clock: ma35d1: Drop CLK_MAX_IDX define Miquel Raynal
@ 2026-09-25 16:41 ` Conor Dooley
0 siblings, 0 replies; 12+ messages in thread
From: Conor Dooley @ 2026-09-25 16:41 UTC (permalink / raw)
To: Miquel Raynal
Cc: Jacky Huang, Shan-Chun Hung, Michael Turquette, Stephen Boyd,
Richard Cochran, Arnd Bergmann, Brian Masney, Jerome Brunet,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Thomas Petazzoni,
Steam Lin, linux-arm-kernel, linux-clk, linux-kernel,
Krzysztof Kozlowski, devicetree
[-- Attachment #1: Type: text/plain, Size: 75 bytes --]
Acked-by: Conor Dooley <conor.dooley@microchip.com>
pw-bot: not-applicable
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4 3/6] dt-bindings: clock: ma35d1: Add missing WDT/WWDT parent clocks
2026-09-25 15:10 ` [PATCH v4 3/6] dt-bindings: clock: ma35d1: Add missing WDT/WWDT parent clocks Miquel Raynal
@ 2026-09-25 16:42 ` Conor Dooley
0 siblings, 0 replies; 12+ messages in thread
From: Conor Dooley @ 2026-09-25 16:42 UTC (permalink / raw)
To: Miquel Raynal
Cc: Jacky Huang, Shan-Chun Hung, Michael Turquette, Stephen Boyd,
Richard Cochran, Arnd Bergmann, Brian Masney, Jerome Brunet,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Thomas Petazzoni,
Steam Lin, linux-arm-kernel, linux-clk, linux-kernel,
Krzysztof Kozlowski, devicetree
[-- Attachment #1: Type: text/plain, Size: 75 bytes --]
Acked-by: Conor Dooley <conor.dooley@microchip.com>
pw-bot: not-applicable
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4 5/6] clk: nuvoton: ma35d1: Use clk_hw pointers as mux parents
2026-09-25 15:10 ` [PATCH v4 5/6] clk: nuvoton: ma35d1: Use clk_hw pointers as mux parents Miquel Raynal
@ 2026-09-27 17:00 ` Jerome Brunet
2026-09-28 16:02 ` Miquel Raynal
0 siblings, 1 reply; 12+ messages in thread
From: Jerome Brunet @ 2026-09-27 17:00 UTC (permalink / raw)
To: Miquel Raynal, Jacky Huang, Shan-Chun Hung, Michael Turquette,
Stephen Boyd, Richard Cochran, Arnd Bergmann, Brian Masney,
Jerome Brunet, Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Thomas Petazzoni, Steam Lin, linux-arm-kernel, linux-clk,
linux-kernel, Krzysztof Kozlowski, devicetree, Miquel Raynal,
stable
On ven. 25 sept. 2026 at 17:10, Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> The MA35D1 clock provider registers its muxes with parent data
> structures filling .fw_name. This is not the ideal approach since that
> would require a massive amount of internal clock names declaration in
> the DT. Since the DT does not play the game of exposing all these names,
> none of the parent lookups performed when instantiating the muxes
> succeed. As a result, these muxes get registered as root clocks, leading
> to a sadly flat clock tree and no frequency assigned to most of the
> peripheral clocks:
>
> enable prepare protect
> clock count count count rate
>
> usbphy1 0 0 0 480000000
> usbphy0 0 0 0 480000000
> husbh1_gate 0 0 0 480000000
> husbh0_gate 0 0 0 480000000
> usbh_gate 0 0 0 480000000
> usbd_gate 0 0 0 480000000
> syspll 0 0 0 180000000
> lirc 0 0 0 32000
> lirc_gate 0 0 0 32000
> hirc 0 0 0 12000000
> gtmr_gate 0 0 0 12000000
> hirc_gate 0 0 0 12000000
> lxt 0 0 0 32768
> rtc_gate 0 0 0 32768
> lxt_gate 0 0 0 32768
> hxt 0 0 0 24000000
> vpll 0 0 0 1224000000
> dcup_div 0 0 0 612000000
> epll 0 0 0 6000000000
> epll_div8 0 0 0 750000000
>
> epll_div4 0 0 0 1500000000
> epll_div2 0 0 0 3000000000
> emac1_gate 0 0 0 3000000000
>
> emac0_gate 0 0 0 3000000000
>
> apll 0 0 0 6048000000
> ddrpll 0 0 0 266460000
> ddr_gate 0 0 0 266460000
> ddr6_gate 0 0 0 266460000
> ddr0_gate 0 0 0 266460000
> capll 0 0 0 2400000000
> hxt_gate 0 0 0 24000000
> clk_hxt 0 0 0 24000000
> spi3_mux 0 0 0 0
> spi3_gate 0 0 0 0
> spi2_mux 0 0 0 0
> spi2_gate 0 0 0 0
> spi1_mux 0 0 0 0
> spi1_gate 0 0 0 0
> spi0_mux 0 0 0 0
> spi0_gate 0 0 0 0
> i2s1_mux 0 0 0 0
> i2s1_gate 0 0 0 0
> i2s0_mux 0 0 0 0
> i2s0_gate 0 0 0 0
> ...
>
> Apart from the wrong clock tree representation, it means that none of
> the device drivers (spi & i2c in the excerpt above) can actually query
> their clock rate, or they would get 0Hz.
>
> Instead of declaring the parents in the clk_parent_data structure, use
> the actual HW clocks to lookup the parents directly: parents are
> described by an array of indices into the controller's main clock table
> (like in other clock controller drivers), which the "new" mux helper now
> resolves.
>
> The WDT and WWDT muxes list the /4096 children of PCLK3 and PCLK4 among
> their possible parents. Those two clocks are now registered by the
> previous commit, so their entries in the parent tables are restored
> instead of being turned into invalid slots.
>
> enable prepare protect
> clock count count count rate
>
> usbphy1 0 0 0 480000000
> usbphy0 0 0 0 480000000
> husbh1_gate 0 0 0 480000000
> husbh0_gate 0 0 0 480000000
> usbh_gate 0 0 0 480000000
> usbd_gate 0 0 0 480000000
> syspll 1 1 0 180000000
> dbg_mux 0 0 0 180000000
> sdh1_mux 0 0 0 180000000
> sdh1_gate 0 0 0 180000000
> sdh0_mux 0 0 0 180000000
> sdh0_gate 0 0 0 180000000
> sysclk1_mux 2 2 0 180000000
> pclk4 0 0 0 90000000
> pclk3 0 0 0 90000000
> sspcc_gate 0 0 0 90000000
> ssmcc_gate 0 0 0 90000000
> hclk3 0 0 0 90000000
> pclk2 0 0 0 180000000
> eadc_div 0 0 0 90000000
> eadc_gate 0 0 0 90000000
> qei1_gate 0 0 0 180000000
> ecap1_gate 0 0 0 180000000
> spi3_mux 0 0 0 180000000
> spi3_gate 0 0 0 180000000
> spi1_mux 0 0 0 180000000
> spi1_gate 0 0 0 180000000
> epwm1_gate 0 0 0 180000000
> i2c5_gate 0 0 0 180000000
> i2c2_gate 0 0 0 180000000
> pclk1 0 0 0 180000000
> qei2_gate 0 0 0 180000000
> qei0_gate 0 0 0 180000000
> ecap2_gate 0 0 0 180000000
> ecap0_gate 0 0 0 180000000
> spi2_mux 0 0 0 180000000
> spi2_gate 0 0 0 180000000
> spi0_mux 0 0 0 180000000
> spi0_gate 0 0 0 180000000
> epwm2_gate 0 0 0 180000000
> epwm0_gate 0 0 0 180000000
> i2c4_gate 0 0 0 180000000
> i2c1_gate 0 0 0 180000000
> pclk0 1 1 0 180000000
> adc_div 0 0 0 90000000
> adc_gate 0 0 0 90000000
> qspi1_mux 0 0 0 180000000
> qspi1_gate 0 0 0 180000000
> qspi0_mux 1 1 0 180000000
> qspi0_gate 1 1 0 180000000
>
> i2c3_gate 0 0 0 180000000
> i2c0_gate 0 0 0 180000000
>
> Fixes: f50a000b4219 ("clk: nuvoton: Use clk_parent_data instead of string for parent clock")
> Cc: stable@vger.kernel.org
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> ---
> drivers/clk/nuvoton/clk-ma35d1.c | 626 +++++++++++----------------------------
> 1 file changed, 177 insertions(+), 449 deletions(-)
>
> diff --git a/drivers/clk/nuvoton/clk-ma35d1.c b/drivers/clk/nuvoton/clk-ma35d1.c
> index c914079cee2d..1a857f28310f 100644
> --- a/drivers/clk/nuvoton/clk-ma35d1.c
> +++ b/drivers/clk/nuvoton/clk-ma35d1.c
> @@ -63,300 +63,49 @@ static DEFINE_SPINLOCK(ma35d1_lock);
> #define PLL_MODE_FRAC 1
> #define PLL_MODE_SS 2
>
> -static const struct clk_parent_data ca35clk_sel_clks[] = {
> - { .fw_name = "hxt", },
> - { .fw_name = "capll", },
> - { .fw_name = "ddrpll", },
> -};
> +#define MA35D1_MUX_MAX_PARENTS 10
I'm bit puzzled how this was supposed to work before. Most of those
inputs are not present in binding doc. The controller was supposed get
clocks from itself through DT ???
There is one input documented though. It seems to be hxt, so you should
probably continue to use fw_name for this one at least.
That being said, the bindings doc seems wrong. Looking at the driver you
should have 4 inputs (hxt, lxt, hirc, lirc), unless those are actually
generated on SoC ? Since there is already a DT using these, I suppose it
is too late for the last 3 and you'll be stuck pretending they are
generated in this controller :/
>
> -static const struct clk_parent_data sysclk0_sel_clks[] = {
> - { .fw_name = "epll_div2", },
> - { .fw_name = "syspll", },
> -};
> -
> -static const struct clk_parent_data sysclk1_sel_clks[] = {
> - { .fw_name = "hxt", },
> - { .fw_name = "syspll", },
> -};
> -
> -static const struct clk_parent_data axiclk_sel_clks[] = {
> - { .fw_name = "capll_div2", },
> - { .fw_name = "capll_div4", },
> -};
> -
> -static const struct clk_parent_data ccap_sel_clks[] = {
> - { .fw_name = "hxt", },
> - { .fw_name = "vpll", },
> - { .fw_name = "apll", },
> - { .fw_name = "syspll", },
> -};
> -
> -static const struct clk_parent_data sdh_sel_clks[] = {
> - { .fw_name = "syspll", },
> - { .fw_name = "apll", },
> -};
> -
> -static const struct clk_parent_data dcu_sel_clks[] = {
> - { .fw_name = "epll_div2", },
> - { .fw_name = "syspll", },
> -};
> -
> -static const struct clk_parent_data gfx_sel_clks[] = {
> - { .fw_name = "epll", },
> - { .fw_name = "syspll", },
> -};
> -
> -static const struct clk_parent_data dbg_sel_clks[] = {
> - { .fw_name = "hirc", },
> - { .fw_name = "syspll", },
> -};
> -
> -static const struct clk_parent_data timer0_sel_clks[] = {
> - { .fw_name = "hxt", },
> - { .fw_name = "lxt", },
> - { .fw_name = "pclk0", },
> - { .index = -1, },
> - { .index = -1, },
> - { .fw_name = "lirc", },
> - { .index = -1, },
> - { .fw_name = "hirc", },
> -};
> -
> -static const struct clk_parent_data timer1_sel_clks[] = {
> - { .fw_name = "hxt", },
> - { .fw_name = "lxt", },
> - { .fw_name = "pclk0", },
> - { .index = -1, },
> - { .index = -1, },
> - { .fw_name = "lirc", },
> - { .index = -1, },
> - { .fw_name = "hirc", },
> -};
> -
> -static const struct clk_parent_data timer2_sel_clks[] = {
> - { .fw_name = "hxt", },
> - { .fw_name = "lxt", },
> - { .fw_name = "pclk1", },
> - { .index = -1, },
> - { .index = -1, },
> - { .fw_name = "lirc", },
> - { .index = -1, },
> - { .fw_name = "hirc", },
> -};
> -
> -static const struct clk_parent_data timer3_sel_clks[] = {
> - { .fw_name = "hxt", },
> - { .fw_name = "lxt", },
> - { .fw_name = "pclk1", },
> - { .index = -1, },
> - { .index = -1, },
> - { .fw_name = "lirc", },
> - { .index = -1, },
> - { .fw_name = "hirc", },
> -};
> -
> -static const struct clk_parent_data timer4_sel_clks[] = {
> - { .fw_name = "hxt", },
> - { .fw_name = "lxt", },
> - { .fw_name = "pclk2", },
> - { .index = -1, },
> - { .index = -1, },
> - { .fw_name = "lirc", },
> - { .index = -1, },
> - { .fw_name = "hirc", },
> -};
> -
> -static const struct clk_parent_data timer5_sel_clks[] = {
> - { .fw_name = "hxt", },
> - { .fw_name = "lxt", },
> - { .fw_name = "pclk2", },
> - { .index = -1, },
> - { .index = -1, },
> - { .fw_name = "lirc", },
> - { .index = -1, },
> - { .fw_name = "hirc", },
> -};
> -
> -static const struct clk_parent_data timer6_sel_clks[] = {
> - { .fw_name = "hxt", },
> - { .fw_name = "lxt", },
> - { .fw_name = "pclk0", },
> - { .index = -1, },
> - { .index = -1, },
> - { .fw_name = "lirc", },
> - { .index = -1, },
> - { .fw_name = "hirc", },
> -};
> -
> -static const struct clk_parent_data timer7_sel_clks[] = {
> - { .fw_name = "hxt", },
> - { .fw_name = "lxt", },
> - { .fw_name = "pclk0", },
> - { .index = -1, },
> - { .index = -1, },
> - { .fw_name = "lirc", },
> - { .index = -1, },
> - { .fw_name = "hirc", },
> -};
> -
> -static const struct clk_parent_data timer8_sel_clks[] = {
> - { .fw_name = "hxt", },
> - { .fw_name = "lxt", },
> - { .fw_name = "pclk1", },
> - { .index = -1, },
> - { .index = -1, },
> - { .fw_name = "lirc", },
> - { .index = -1, },
> - { .fw_name = "hirc", },
> -};
> -
> -static const struct clk_parent_data timer9_sel_clks[] = {
> - { .fw_name = "hxt", },
> - { .fw_name = "lxt", },
> - { .fw_name = "pclk1", },
> - { .index = -1, },
> - { .index = -1, },
> - { .fw_name = "lirc", },
> - { .index = -1, },
> - { .fw_name = "hirc", },
> -};
> -
> -static const struct clk_parent_data timer10_sel_clks[] = {
> - { .fw_name = "hxt", },
> - { .fw_name = "lxt", },
> - { .fw_name = "pclk2", },
> - { .index = -1, },
> - { .index = -1, },
> - { .fw_name = "lirc", },
> - { .index = -1, },
> - { .fw_name = "hirc", },
> -};
> -
> -static const struct clk_parent_data timer11_sel_clks[] = {
> - { .fw_name = "hxt", },
> - { .fw_name = "lxt", },
> - { .fw_name = "pclk2", },
> - { .index = -1, },
> - { .index = -1, },
> - { .fw_name = "lirc", },
> - { .index = -1, },
> - { .fw_name = "hirc", },
> -};
> -
> -static const struct clk_parent_data uart_sel_clks[] = {
> - { .fw_name = "hxt", },
> - { .fw_name = "sysclk1_div2", },
> -};
> -
> -static const struct clk_parent_data wdt0_sel_clks[] = {
> - { .index = -1, },
> - { .fw_name = "lxt", },
> - { .fw_name = "pclk3_div4096", },
> - { .fw_name = "lirc", },
> -};
> -
> -static const struct clk_parent_data wdt1_sel_clks[] = {
> - { .index = -1, },
> - { .fw_name = "lxt", },
> - { .fw_name = "pclk3_div4096", },
> - { .fw_name = "lirc", },
> -};
> -
> -static const struct clk_parent_data wdt2_sel_clks[] = {
> - { .index = -1, },
> - { .fw_name = "lxt", },
> - { .fw_name = "pclk4_div4096", },
> - { .fw_name = "lirc", },
> -};
> -
> -static const struct clk_parent_data wwdt0_sel_clks[] = {
> - { .index = -1, },
> - { .index = -1, },
> - { .fw_name = "pclk3_div4096", },
> - { .fw_name = "lirc", },
> -};
> -
> -static const struct clk_parent_data wwdt1_sel_clks[] = {
> - { .index = -1, },
> - { .index = -1, },
> - { .fw_name = "pclk3_div4096", },
> - { .fw_name = "lirc", },
> -};
> -
> -static const struct clk_parent_data wwdt2_sel_clks[] = {
> - { .index = -1, },
> - { .index = -1, },
> - { .fw_name = "pclk4_div4096", },
> - { .fw_name = "lirc", },
> -};
> -
> -static const struct clk_parent_data spi0_sel_clks[] = {
> - { .fw_name = "pclk1", },
> - { .fw_name = "apll", },
> -};
> -
> -static const struct clk_parent_data spi1_sel_clks[] = {
> - { .fw_name = "pclk2", },
> - { .fw_name = "apll", },
> -};
> -
> -static const struct clk_parent_data spi2_sel_clks[] = {
> - { .fw_name = "pclk1", },
> - { .fw_name = "apll", },
> -};
> -
> -static const struct clk_parent_data spi3_sel_clks[] = {
> - { .fw_name = "pclk2", },
> - { .fw_name = "apll", },
> -};
> -
> -static const struct clk_parent_data qspi0_sel_clks[] = {
> - { .fw_name = "pclk0", },
> - { .fw_name = "apll", },
> -};
> -
> -static const struct clk_parent_data qspi1_sel_clks[] = {
> - { .fw_name = "pclk0", },
> - { .fw_name = "apll", },
> -};
> -
> -static const struct clk_parent_data i2s0_sel_clks[] = {
> - { .fw_name = "apll", },
> - { .fw_name = "sysclk1_div2", },
> -};
> -
> -static const struct clk_parent_data i2s1_sel_clks[] = {
> - { .fw_name = "apll", },
> - { .fw_name = "sysclk1_div2", },
> -};
> -
> -static const struct clk_parent_data can_sel_clks[] = {
> - { .fw_name = "apll", },
> - { .fw_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", },
> -};
> -
> -static const struct clk_parent_data smc_sel_clks[] = {
> - { .fw_name = "hxt", },
> - { .fw_name = "pclk4", },
> -};
> -
> -static const struct clk_parent_data kpi_sel_clks[] = {
> - { .fw_name = "hxt", },
> - { .fw_name = "lxt", },
> -};
> +/* Mux parent selection, by index into the controller's clock table */
> +static const int ca35clk_parent_idx[] = { HXT, CAPLL, DDRPLL };
> +static const int sysclk0_parent_idx[] = { EPLL_DIV2, SYSPLL };
> +static const int sysclk1_parent_idx[] = { HXT, SYSPLL };
> +static const int axiclk_parent_idx[] = { AXICLK_DIV2, AXICLK_DIV4 };
> +static const int ccap_parent_idx[] = { HXT, VPLL, APLL, SYSPLL };
> +static const int sdh_parent_idx[] = { SYSPLL, APLL };
> +static const int dcu_parent_idx[] = { EPLL_DIV2, SYSPLL };
> +static const int gfx_parent_idx[] = { EPLL, SYSPLL };
> +static const int dbg_parent_idx[] = { HIRC, SYSPLL };
> +static const int timer0_parent_idx[] = { HXT, LXT, PCLK0, -1, -1, LIRC, -1, HIRC };
> +static const int timer1_parent_idx[] = { HXT, LXT, PCLK0, -1, -1, LIRC, -1, HIRC };
> +static const int timer2_parent_idx[] = { HXT, LXT, PCLK1, -1, -1, LIRC, -1, HIRC };
> +static const int timer3_parent_idx[] = { HXT, LXT, PCLK1, -1, -1, LIRC, -1, HIRC };
> +static const int timer4_parent_idx[] = { HXT, LXT, PCLK2, -1, -1, LIRC, -1, HIRC };
> +static const int timer5_parent_idx[] = { HXT, LXT, PCLK2, -1, -1, LIRC, -1, HIRC };
> +static const int timer6_parent_idx[] = { HXT, LXT, PCLK0, -1, -1, LIRC, -1, HIRC };
> +static const int timer7_parent_idx[] = { HXT, LXT, PCLK0, -1, -1, LIRC, -1, HIRC };
> +static const int timer8_parent_idx[] = { HXT, LXT, PCLK1, -1, -1, LIRC, -1, HIRC };
> +static const int timer9_parent_idx[] = { HXT, LXT, PCLK1, -1, -1, LIRC, -1, HIRC };
> +static const int timer10_parent_idx[] = { HXT, LXT, PCLK2, -1, -1, LIRC, -1, HIRC };
> +static const int timer11_parent_idx[] = { HXT, LXT, PCLK2, -1, -1, LIRC, -1, HIRC };
> +static const int uart_parent_idx[] = { HXT, SYSCLK1_DIV2 };
> +static const int wdt0_parent_idx[] = { -1, LXT, PCLK3_DIV4096, LIRC };
> +static const int wdt1_parent_idx[] = { -1, LXT, PCLK3_DIV4096, LIRC };
> +static const int wdt2_parent_idx[] = { -1, LXT, PCLK4_DIV4096, LIRC };
> +static const int wwdt0_parent_idx[] = { -1, -1, PCLK3_DIV4096, LIRC };
> +static const int wwdt1_parent_idx[] = { -1, -1, PCLK3_DIV4096, LIRC };
> +static const int wwdt2_parent_idx[] = { -1, -1, PCLK4_DIV4096, LIRC };
> +static const int spi0_parent_idx[] = { PCLK1, APLL };
> +static const int spi1_parent_idx[] = { PCLK2, APLL };
> +static const int spi2_parent_idx[] = { PCLK1, APLL };
> +static const int spi3_parent_idx[] = { PCLK2, APLL };
> +static const int qspi_parent_idx[] = { PCLK0, APLL };
> +static const int i2s_parent_idx[] = { APLL, SYSCLK1_DIV2 };
> +static const int can_parent_idx[] = { APLL, VPLL };
> +static const int cko_parent_idx[] = { HXT, LXT, HIRC, LIRC,
> + AXICLK_DIV4, SYSPLL, DDRPLL,
> + EPLL_DIV2, APLL, VPLL };
> +static const int smc_parent_idx[] = { HXT, PCLK4 };
> +static const int kpi_parent_idx[] = { HXT, LXT };
>
> static const struct clk_div_table ip_div_table[] = {
> {0, 2}, {1, 4}, {2, 6}, {3, 8}, {4, 10},
> @@ -375,24 +124,20 @@ static struct clk_hw *ma35d1_clk_fixed(const char *name, int rate)
> return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate);
> }
>
> -static struct clk_hw *ma35d1_clk_mux_parent(struct device *dev, const char *name,
> - void __iomem *reg, u8 shift, u8 width,
> - const struct clk_parent_data *pdata,
> - int num_pdata)
> -{
> - return clk_hw_register_mux_parent_data(dev, name, pdata, num_pdata,
> - CLK_SET_RATE_NO_REPARENT, reg, shift,
> - width, 0, &ma35d1_lock);
> -}
> -
> static struct clk_hw *ma35d1_clk_mux(struct device *dev, const char *name,
> void __iomem *reg, u8 shift, u8 width,
> - const struct clk_parent_data *pdata,
> - int num_pdata)
> + struct clk_hw **hws,
> + const int *parent_idx, int num_parents)
> {
> - return clk_hw_register_mux_parent_data(dev, name, pdata, num_pdata,
> - CLK_SET_RATE_NO_REPARENT, reg, shift,
> - width, 0, &ma35d1_lock);
> + const struct clk_hw *parent_hws[MA35D1_MUX_MAX_PARENTS] = {};
> + int i;
> +
> + for (i = 0; i < num_parents; i++)
> + parent_hws[i] = (parent_idx[i] >= 0) ? hws[parent_idx[i]] : NULL;
> +
> + return clk_hw_register_mux_hws(dev, name, parent_hws, num_parents,
> + CLK_SET_RATE_NO_REPARENT, reg, shift,
> + width, 0, &ma35d1_lock);
> }
>
> static struct clk_hw *ma35d1_clk_divider(struct device *dev, const char *name,
> @@ -515,22 +260,17 @@ static int ma35d1_clocks_probe(struct platform_device *pdev)
> hws[EPLL_DIV4] = ma35d1_clk_fixed_factor(dev, "epll_div4", "epll", 1, 4);
> hws[EPLL_DIV8] = ma35d1_clk_fixed_factor(dev, "epll_div8", "epll", 1, 8);
>
> - hws[CA35CLK_MUX] = ma35d1_clk_mux_parent(dev, "ca35clk_mux",
> - clk_base + REG_CLK_CLKSEL0, 0, 2,
> - ca35clk_sel_clks,
> - ARRAY_SIZE(ca35clk_sel_clks));
> + hws[CA35CLK_MUX] = ma35d1_clk_mux(dev, "ca35clk_mux", clk_base + REG_CLK_CLKSEL0, 0, 2, hws,
> + ca35clk_parent_idx, ARRAY_SIZE(ca35clk_parent_idx));
> hws[AXICLK_DIV2] = ma35d1_clk_fixed_factor(dev, "capll_div2", "ca35clk_mux", 1, 2);
> hws[AXICLK_DIV4] = ma35d1_clk_fixed_factor(dev, "capll_div4", "ca35clk_mux", 1, 4);
>
> - hws[AXICLK_MUX] = ma35d1_clk_mux(dev, "axiclk_mux", clk_base + REG_CLK_CLKDIV0,
> - 26, 1, axiclk_sel_clks,
> - ARRAY_SIZE(axiclk_sel_clks));
> - hws[SYSCLK0_MUX] = ma35d1_clk_mux(dev, "sysclk0_mux", clk_base + REG_CLK_CLKSEL0,
> - 2, 1, sysclk0_sel_clks,
> - ARRAY_SIZE(sysclk0_sel_clks));
> - hws[SYSCLK1_MUX] = ma35d1_clk_mux(dev, "sysclk1_mux", clk_base + REG_CLK_CLKSEL0,
> - 4, 1, sysclk1_sel_clks,
> - ARRAY_SIZE(sysclk1_sel_clks));
> + hws[AXICLK_MUX] = ma35d1_clk_mux(dev, "axiclk_mux", clk_base + REG_CLK_CLKDIV0, 26, 1, hws,
> + axiclk_parent_idx, ARRAY_SIZE(axiclk_parent_idx));
> + hws[SYSCLK0_MUX] = ma35d1_clk_mux(dev, "sysclk0_mux", clk_base + REG_CLK_CLKSEL0, 2, 1, hws,
> + sysclk0_parent_idx, ARRAY_SIZE(sysclk0_parent_idx));
> + hws[SYSCLK1_MUX] = ma35d1_clk_mux(dev, "sysclk1_mux", clk_base + REG_CLK_CLKSEL0, 4, 1, hws,
> + sysclk1_parent_idx, ARRAY_SIZE(sysclk1_parent_idx));
> hws[SYSCLK1_DIV2] = ma35d1_clk_fixed_factor(dev, "sysclk1_div2", "sysclk1_mux", 1, 2);
>
> /* HCLK0~3 & PCLK0~4 */
> @@ -556,41 +296,41 @@ static int ma35d1_clocks_probe(struct platform_device *pdev)
> hws[DDR6_GATE] = ma35d1_clk_gate(dev, "ddr6_gate", "ddrpll",
> clk_base + REG_CLK_SYSCLK0, 5);
>
> - hws[CAN0_MUX] = ma35d1_clk_mux(dev, "can0_mux", clk_base + REG_CLK_CLKSEL4,
> - 16, 1, can_sel_clks, ARRAY_SIZE(can_sel_clks));
> + hws[CAN0_MUX] = ma35d1_clk_mux(dev, "can0_mux", clk_base + REG_CLK_CLKSEL4, 16, 1, hws,
> + can_parent_idx, ARRAY_SIZE(can_parent_idx));
> hws[CAN0_DIV] = ma35d1_clk_divider_table(dev, "can0_div", "can0_mux",
> clk_base + REG_CLK_CLKDIV0,
> 0, 3, ip_div_table);
> hws[CAN0_GATE] = ma35d1_clk_gate(dev, "can0_gate", "can0_div",
> clk_base + REG_CLK_SYSCLK0, 8);
> - hws[CAN1_MUX] = ma35d1_clk_mux(dev, "can1_mux", clk_base + REG_CLK_CLKSEL4,
> - 17, 1, can_sel_clks, ARRAY_SIZE(can_sel_clks));
> + hws[CAN1_MUX] = ma35d1_clk_mux(dev, "can1_mux", clk_base + REG_CLK_CLKSEL4, 17, 1, hws,
> + can_parent_idx, ARRAY_SIZE(can_parent_idx));
> hws[CAN1_DIV] = ma35d1_clk_divider_table(dev, "can1_div", "can1_mux",
> clk_base + REG_CLK_CLKDIV0,
> 4, 3, ip_div_table);
> hws[CAN1_GATE] = ma35d1_clk_gate(dev, "can1_gate", "can1_div",
> clk_base + REG_CLK_SYSCLK0, 9);
> - hws[CAN2_MUX] = ma35d1_clk_mux(dev, "can2_mux", clk_base + REG_CLK_CLKSEL4,
> - 18, 1, can_sel_clks, ARRAY_SIZE(can_sel_clks));
> + hws[CAN2_MUX] = ma35d1_clk_mux(dev, "can2_mux", clk_base + REG_CLK_CLKSEL4, 18, 1, hws,
> + can_parent_idx, ARRAY_SIZE(can_parent_idx));
> hws[CAN2_DIV] = ma35d1_clk_divider_table(dev, "can2_div", "can2_mux",
> clk_base + REG_CLK_CLKDIV0,
> 8, 3, ip_div_table);
> hws[CAN2_GATE] = ma35d1_clk_gate(dev, "can2_gate", "can2_div",
> clk_base + REG_CLK_SYSCLK0, 10);
> - hws[CAN3_MUX] = ma35d1_clk_mux(dev, "can3_mux", clk_base + REG_CLK_CLKSEL4,
> - 19, 1, can_sel_clks, ARRAY_SIZE(can_sel_clks));
> + hws[CAN3_MUX] = ma35d1_clk_mux(dev, "can3_mux", clk_base + REG_CLK_CLKSEL4, 19, 1, hws,
> + can_parent_idx, ARRAY_SIZE(can_parent_idx));
> hws[CAN3_DIV] = ma35d1_clk_divider_table(dev, "can3_div", "can3_mux",
> clk_base + REG_CLK_CLKDIV0,
> 12, 3, ip_div_table);
> hws[CAN3_GATE] = ma35d1_clk_gate(dev, "can3_gate", "can3_div",
> clk_base + REG_CLK_SYSCLK0, 11);
>
> - hws[SDH0_MUX] = ma35d1_clk_mux(dev, "sdh0_mux", clk_base + REG_CLK_CLKSEL0,
> - 16, 2, sdh_sel_clks, ARRAY_SIZE(sdh_sel_clks));
> + hws[SDH0_MUX] = ma35d1_clk_mux(dev, "sdh0_mux", clk_base + REG_CLK_CLKSEL0, 16, 2, hws,
> + sdh_parent_idx, ARRAY_SIZE(sdh_parent_idx));
> hws[SDH0_GATE] = ma35d1_clk_gate(dev, "sdh0_gate", "sdh0_mux",
> clk_base + REG_CLK_SYSCLK0, 16);
> - hws[SDH1_MUX] = ma35d1_clk_mux(dev, "sdh1_mux", clk_base + REG_CLK_CLKSEL0,
> - 18, 2, sdh_sel_clks, ARRAY_SIZE(sdh_sel_clks));
> + hws[SDH1_MUX] = ma35d1_clk_mux(dev, "sdh1_mux", clk_base + REG_CLK_CLKSEL0, 18, 2, hws,
> + sdh_parent_idx, ARRAY_SIZE(sdh_parent_idx));
> hws[SDH1_GATE] = ma35d1_clk_gate(dev, "sdh1_gate", "sdh1_mux",
> clk_base + REG_CLK_SYSCLK0, 17);
>
> @@ -606,14 +346,14 @@ static int ma35d1_clocks_probe(struct platform_device *pdev)
> hws[HUSBH1_GATE] = ma35d1_clk_gate(dev, "husbh1_gate", "usbphy0",
> clk_base + REG_CLK_SYSCLK0, 22);
>
> - hws[GFX_MUX] = ma35d1_clk_mux(dev, "gfx_mux", clk_base + REG_CLK_CLKSEL0,
> - 26, 1, gfx_sel_clks, ARRAY_SIZE(gfx_sel_clks));
> + hws[GFX_MUX] = ma35d1_clk_mux(dev, "gfx_mux", clk_base + REG_CLK_CLKSEL0, 26, 1, hws,
> + gfx_parent_idx, ARRAY_SIZE(gfx_parent_idx));
> hws[GFX_GATE] = ma35d1_clk_gate(dev, "gfx_gate", "gfx_mux",
> clk_base + REG_CLK_SYSCLK0, 24);
> hws[VC8K_GATE] = ma35d1_clk_gate(dev, "vc8k_gate", "sysclk0_mux",
> clk_base + REG_CLK_SYSCLK0, 25);
> - hws[DCU_MUX] = ma35d1_clk_mux(dev, "dcu_mux", clk_base + REG_CLK_CLKSEL0,
> - 24, 1, dcu_sel_clks, ARRAY_SIZE(dcu_sel_clks));
> + hws[DCU_MUX] = ma35d1_clk_mux(dev, "dcu_mux", clk_base + REG_CLK_CLKSEL0, 24, 1, hws,
> + dcu_parent_idx, ARRAY_SIZE(dcu_parent_idx));
> hws[DCU_GATE] = ma35d1_clk_gate(dev, "dcu_gate", "dcu_mux",
> clk_base + REG_CLK_SYSCLK0, 26);
> hws[DCUP_DIV] = ma35d1_clk_divider_table(dev, "dcup_div", "vpll",
> @@ -625,14 +365,14 @@ static int ma35d1_clocks_probe(struct platform_device *pdev)
> hws[EMAC1_GATE] = ma35d1_clk_gate(dev, "emac1_gate", "epll_div2",
> clk_base + REG_CLK_SYSCLK0, 28);
>
> - hws[CCAP0_MUX] = ma35d1_clk_mux(dev, "ccap0_mux", clk_base + REG_CLK_CLKSEL0,
> - 12, 1, ccap_sel_clks, ARRAY_SIZE(ccap_sel_clks));
> + hws[CCAP0_MUX] = ma35d1_clk_mux(dev, "ccap0_mux", clk_base + REG_CLK_CLKSEL0, 12, 1, hws,
> + ccap_parent_idx, ARRAY_SIZE(ccap_parent_idx));
> hws[CCAP0_DIV] = ma35d1_clk_divider(dev, "ccap0_div", "ccap0_mux",
> clk_base + REG_CLK_CLKDIV1, 8, 4);
> hws[CCAP0_GATE] = ma35d1_clk_gate(dev, "ccap0_gate", "ccap0_div",
> clk_base + REG_CLK_SYSCLK0, 29);
> - hws[CCAP1_MUX] = ma35d1_clk_mux(dev, "ccap1_mux", clk_base + REG_CLK_CLKSEL0,
> - 14, 1, ccap_sel_clks, ARRAY_SIZE(ccap_sel_clks));
> + hws[CCAP1_MUX] = ma35d1_clk_mux(dev, "ccap1_mux", clk_base + REG_CLK_CLKSEL0, 14, 1, hws,
> + ccap_parent_idx, ARRAY_SIZE(ccap_parent_idx));
> hws[CCAP1_DIV] = ma35d1_clk_divider(dev, "ccap1_div", "ccap1_mux",
> clk_base + REG_CLK_CLKDIV1,
> 12, 4);
> @@ -670,13 +410,13 @@ static int ma35d1_clocks_probe(struct platform_device *pdev)
> hws[TRA_GATE] = ma35d1_clk_gate(dev, "tra_gate", "hclk0",
> clk_base + REG_CLK_SYSCLK1, 11);
>
> - hws[DBG_MUX] = ma35d1_clk_mux(dev, "dbg_mux", clk_base + REG_CLK_CLKSEL0,
> - 27, 1, dbg_sel_clks, ARRAY_SIZE(dbg_sel_clks));
> + hws[DBG_MUX] = ma35d1_clk_mux(dev, "dbg_mux", clk_base + REG_CLK_CLKSEL0, 27, 1, hws,
> + dbg_parent_idx, ARRAY_SIZE(dbg_parent_idx));
> hws[DBG_GATE] = ma35d1_clk_gate(dev, "dbg_gate", "hclk0",
> clk_base + REG_CLK_SYSCLK1, 12);
>
> - hws[CKO_MUX] = ma35d1_clk_mux(dev, "cko_mux", clk_base + REG_CLK_CLKSEL4,
> - 24, 4, cko_sel_clks, ARRAY_SIZE(cko_sel_clks));
> + hws[CKO_MUX] = ma35d1_clk_mux(dev, "cko_mux", clk_base + REG_CLK_CLKSEL4, 24, 4, hws,
> + cko_parent_idx, ARRAY_SIZE(cko_parent_idx));
> hws[CKO_DIV] = ma35d1_clk_divider_pow2(dev, "cko_div", "cko_mux",
> clk_base + REG_CLK_CLKOCTL, 0, 4);
> hws[CKO_GATE] = ma35d1_clk_gate(dev, "cko_gate", "cko_div",
> @@ -714,181 +454,169 @@ static int ma35d1_clocks_probe(struct platform_device *pdev)
> hws[GPN_GATE] = ma35d1_clk_gate(dev, "gpn_gate", "hclk0",
> clk_base + REG_CLK_SYSCLK1, 29);
>
> - hws[TMR0_MUX] = ma35d1_clk_mux(dev, "tmr0_mux", clk_base + REG_CLK_CLKSEL1,
> - 0, 3, timer0_sel_clks,
> - ARRAY_SIZE(timer0_sel_clks));
> + hws[TMR0_MUX] = ma35d1_clk_mux(dev, "tmr0_mux", clk_base + REG_CLK_CLKSEL1, 0, 3, hws,
> + timer0_parent_idx, ARRAY_SIZE(timer0_parent_idx));
> hws[TMR0_GATE] = ma35d1_clk_gate(dev, "tmr0_gate", "tmr0_mux",
> clk_base + REG_CLK_APBCLK0, 0);
> - hws[TMR1_MUX] = ma35d1_clk_mux(dev, "tmr1_mux", clk_base + REG_CLK_CLKSEL1,
> - 4, 3, timer1_sel_clks,
> - ARRAY_SIZE(timer1_sel_clks));
> + hws[TMR1_MUX] = ma35d1_clk_mux(dev, "tmr1_mux", clk_base + REG_CLK_CLKSEL1, 4, 3, hws,
> + timer1_parent_idx, ARRAY_SIZE(timer1_parent_idx));
> hws[TMR1_GATE] = ma35d1_clk_gate(dev, "tmr1_gate", "tmr1_mux",
> clk_base + REG_CLK_APBCLK0, 1);
> - hws[TMR2_MUX] = ma35d1_clk_mux(dev, "tmr2_mux", clk_base + REG_CLK_CLKSEL1,
> - 8, 3, timer2_sel_clks,
> - ARRAY_SIZE(timer2_sel_clks));
> + hws[TMR2_MUX] = ma35d1_clk_mux(dev, "tmr2_mux", clk_base + REG_CLK_CLKSEL1, 8, 3, hws,
> + timer2_parent_idx, ARRAY_SIZE(timer2_parent_idx));
> hws[TMR2_GATE] = ma35d1_clk_gate(dev, "tmr2_gate", "tmr2_mux",
> clk_base + REG_CLK_APBCLK0, 2);
> - hws[TMR3_MUX] = ma35d1_clk_mux(dev, "tmr3_mux", clk_base + REG_CLK_CLKSEL1,
> - 12, 3, timer3_sel_clks,
> - ARRAY_SIZE(timer3_sel_clks));
> + hws[TMR3_MUX] = ma35d1_clk_mux(dev, "tmr3_mux", clk_base + REG_CLK_CLKSEL1, 12, 3, hws,
> + timer3_parent_idx, ARRAY_SIZE(timer3_parent_idx));
> hws[TMR3_GATE] = ma35d1_clk_gate(dev, "tmr3_gate", "tmr3_mux",
> clk_base + REG_CLK_APBCLK0, 3);
> - hws[TMR4_MUX] = ma35d1_clk_mux(dev, "tmr4_mux", clk_base + REG_CLK_CLKSEL1,
> - 16, 3, timer4_sel_clks,
> - ARRAY_SIZE(timer4_sel_clks));
> + hws[TMR4_MUX] = ma35d1_clk_mux(dev, "tmr4_mux", clk_base + REG_CLK_CLKSEL1, 16, 3, hws,
> + timer4_parent_idx, ARRAY_SIZE(timer4_parent_idx));
> hws[TMR4_GATE] = ma35d1_clk_gate(dev, "tmr4_gate", "tmr4_mux",
> clk_base + REG_CLK_APBCLK0, 4);
> - hws[TMR5_MUX] = ma35d1_clk_mux(dev, "tmr5_mux", clk_base + REG_CLK_CLKSEL1,
> - 20, 3, timer5_sel_clks,
> - ARRAY_SIZE(timer5_sel_clks));
> + hws[TMR5_MUX] = ma35d1_clk_mux(dev, "tmr5_mux", clk_base + REG_CLK_CLKSEL1, 20, 3, hws,
> + timer5_parent_idx, ARRAY_SIZE(timer5_parent_idx));
> hws[TMR5_GATE] = ma35d1_clk_gate(dev, "tmr5_gate", "tmr5_mux",
> clk_base + REG_CLK_APBCLK0, 5);
> - hws[TMR6_MUX] = ma35d1_clk_mux(dev, "tmr6_mux", clk_base + REG_CLK_CLKSEL1,
> - 24, 3, timer6_sel_clks,
> - ARRAY_SIZE(timer6_sel_clks));
> + hws[TMR6_MUX] = ma35d1_clk_mux(dev, "tmr6_mux", clk_base + REG_CLK_CLKSEL1, 24, 3, hws,
> + timer6_parent_idx, ARRAY_SIZE(timer6_parent_idx));
> hws[TMR6_GATE] = ma35d1_clk_gate(dev, "tmr6_gate", "tmr6_mux",
> clk_base + REG_CLK_APBCLK0, 6);
> - hws[TMR7_MUX] = ma35d1_clk_mux(dev, "tmr7_mux", clk_base + REG_CLK_CLKSEL1,
> - 28, 3, timer7_sel_clks,
> - ARRAY_SIZE(timer7_sel_clks));
> + hws[TMR7_MUX] = ma35d1_clk_mux(dev, "tmr7_mux", clk_base + REG_CLK_CLKSEL1, 28, 3, hws,
> + timer7_parent_idx, ARRAY_SIZE(timer7_parent_idx));
> hws[TMR7_GATE] = ma35d1_clk_gate(dev, "tmr7_gate", "tmr7_mux",
> clk_base + REG_CLK_APBCLK0, 7);
> - hws[TMR8_MUX] = ma35d1_clk_mux(dev, "tmr8_mux", clk_base + REG_CLK_CLKSEL2,
> - 0, 3, timer8_sel_clks,
> - ARRAY_SIZE(timer8_sel_clks));
> + hws[TMR8_MUX] = ma35d1_clk_mux(dev, "tmr8_mux", clk_base + REG_CLK_CLKSEL2, 0, 3, hws,
> + timer8_parent_idx, ARRAY_SIZE(timer8_parent_idx));
> hws[TMR8_GATE] = ma35d1_clk_gate(dev, "tmr8_gate", "tmr8_mux",
> clk_base + REG_CLK_APBCLK0, 8);
> - hws[TMR9_MUX] = ma35d1_clk_mux(dev, "tmr9_mux", clk_base + REG_CLK_CLKSEL2,
> - 4, 3, timer9_sel_clks,
> - ARRAY_SIZE(timer9_sel_clks));
> + hws[TMR9_MUX] = ma35d1_clk_mux(dev, "tmr9_mux", clk_base + REG_CLK_CLKSEL2, 4, 3, hws,
> + timer9_parent_idx, ARRAY_SIZE(timer9_parent_idx));
> hws[TMR9_GATE] = ma35d1_clk_gate(dev, "tmr9_gate", "tmr9_mux",
> clk_base + REG_CLK_APBCLK0, 9);
> - hws[TMR10_MUX] = ma35d1_clk_mux(dev, "tmr10_mux", clk_base + REG_CLK_CLKSEL2,
> - 8, 3, timer10_sel_clks,
> - ARRAY_SIZE(timer10_sel_clks));
> + hws[TMR10_MUX] = ma35d1_clk_mux(dev, "tmr10_mux", clk_base + REG_CLK_CLKSEL2, 8, 3, hws,
> + timer10_parent_idx, ARRAY_SIZE(timer10_parent_idx));
> hws[TMR10_GATE] = ma35d1_clk_gate(dev, "tmr10_gate", "tmr10_mux",
> clk_base + REG_CLK_APBCLK0, 10);
> - hws[TMR11_MUX] = ma35d1_clk_mux(dev, "tmr11_mux", clk_base + REG_CLK_CLKSEL2,
> - 12, 3, timer11_sel_clks,
> - ARRAY_SIZE(timer11_sel_clks));
> + hws[TMR11_MUX] = ma35d1_clk_mux(dev, "tmr11_mux", clk_base + REG_CLK_CLKSEL2, 12, 3, hws,
> + timer11_parent_idx, ARRAY_SIZE(timer11_parent_idx));
> hws[TMR11_GATE] = ma35d1_clk_gate(dev, "tmr11_gate", "tmr11_mux",
> clk_base + REG_CLK_APBCLK0, 11);
>
> - hws[UART0_MUX] = ma35d1_clk_mux(dev, "uart0_mux", clk_base + REG_CLK_CLKSEL2,
> - 16, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
> + hws[UART0_MUX] = ma35d1_clk_mux(dev, "uart0_mux", clk_base + REG_CLK_CLKSEL2, 16, 2, hws,
> + uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
> hws[UART0_DIV] = ma35d1_clk_divider(dev, "uart0_div", "uart0_mux",
> clk_base + REG_CLK_CLKDIV1,
> 16, 4);
> hws[UART0_GATE] = ma35d1_clk_gate(dev, "uart0_gate", "uart0_div",
> clk_base + REG_CLK_APBCLK0, 12);
> - hws[UART1_MUX] = ma35d1_clk_mux(dev, "uart1_mux", clk_base + REG_CLK_CLKSEL2,
> - 18, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
> + hws[UART1_MUX] = ma35d1_clk_mux(dev, "uart1_mux", clk_base + REG_CLK_CLKSEL2, 18, 2, hws,
> + uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
> hws[UART1_DIV] = ma35d1_clk_divider(dev, "uart1_div", "uart1_mux",
> clk_base + REG_CLK_CLKDIV1,
> 20, 4);
> hws[UART1_GATE] = ma35d1_clk_gate(dev, "uart1_gate", "uart1_div",
> clk_base + REG_CLK_APBCLK0, 13);
> - hws[UART2_MUX] = ma35d1_clk_mux(dev, "uart2_mux", clk_base + REG_CLK_CLKSEL2,
> - 20, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
> + hws[UART2_MUX] = ma35d1_clk_mux(dev, "uart2_mux", clk_base + REG_CLK_CLKSEL2, 20, 2, hws,
> + uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
> hws[UART2_DIV] = ma35d1_clk_divider(dev, "uart2_div", "uart2_mux",
> clk_base + REG_CLK_CLKDIV1,
> 24, 4);
> hws[UART2_GATE] = ma35d1_clk_gate(dev, "uart2_gate", "uart2_div",
> clk_base + REG_CLK_APBCLK0, 14);
> - hws[UART3_MUX] = ma35d1_clk_mux(dev, "uart3_mux", clk_base + REG_CLK_CLKSEL2,
> - 22, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
> + hws[UART3_MUX] = ma35d1_clk_mux(dev, "uart3_mux", clk_base + REG_CLK_CLKSEL2, 22, 2, hws,
> + uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
> hws[UART3_DIV] = ma35d1_clk_divider(dev, "uart3_div", "uart3_mux",
> clk_base + REG_CLK_CLKDIV1,
> 28, 4);
> hws[UART3_GATE] = ma35d1_clk_gate(dev, "uart3_gate", "uart3_div",
> clk_base + REG_CLK_APBCLK0, 15);
> - hws[UART4_MUX] = ma35d1_clk_mux(dev, "uart4_mux", clk_base + REG_CLK_CLKSEL2,
> - 24, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
> + hws[UART4_MUX] = ma35d1_clk_mux(dev, "uart4_mux", clk_base + REG_CLK_CLKSEL2, 24, 2, hws,
> + uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
> hws[UART4_DIV] = ma35d1_clk_divider(dev, "uart4_div", "uart4_mux",
> clk_base + REG_CLK_CLKDIV2,
> 0, 4);
> hws[UART4_GATE] = ma35d1_clk_gate(dev, "uart4_gate", "uart4_div",
> clk_base + REG_CLK_APBCLK0, 16);
> - hws[UART5_MUX] = ma35d1_clk_mux(dev, "uart5_mux", clk_base + REG_CLK_CLKSEL2,
> - 26, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
> + hws[UART5_MUX] = ma35d1_clk_mux(dev, "uart5_mux", clk_base + REG_CLK_CLKSEL2, 26, 2, hws,
> + uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
> hws[UART5_DIV] = ma35d1_clk_divider(dev, "uart5_div", "uart5_mux",
> clk_base + REG_CLK_CLKDIV2,
> 4, 4);
> hws[UART5_GATE] = ma35d1_clk_gate(dev, "uart5_gate", "uart5_div",
> clk_base + REG_CLK_APBCLK0, 17);
> - hws[UART6_MUX] = ma35d1_clk_mux(dev, "uart6_mux", clk_base + REG_CLK_CLKSEL2,
> - 28, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
> + hws[UART6_MUX] = ma35d1_clk_mux(dev, "uart6_mux", clk_base + REG_CLK_CLKSEL2, 28, 2, hws,
> + uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
> hws[UART6_DIV] = ma35d1_clk_divider(dev, "uart6_div", "uart6_mux",
> clk_base + REG_CLK_CLKDIV2,
> 8, 4);
> hws[UART6_GATE] = ma35d1_clk_gate(dev, "uart6_gate", "uart6_div",
> clk_base + REG_CLK_APBCLK0, 18);
> - hws[UART7_MUX] = ma35d1_clk_mux(dev, "uart7_mux", clk_base + REG_CLK_CLKSEL2,
> - 30, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
> + hws[UART7_MUX] = ma35d1_clk_mux(dev, "uart7_mux", clk_base + REG_CLK_CLKSEL2, 30, 2, hws,
> + uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
> hws[UART7_DIV] = ma35d1_clk_divider(dev, "uart7_div", "uart7_mux",
> clk_base + REG_CLK_CLKDIV2,
> 12, 4);
> hws[UART7_GATE] = ma35d1_clk_gate(dev, "uart7_gate", "uart7_div",
> clk_base + REG_CLK_APBCLK0, 19);
> - hws[UART8_MUX] = ma35d1_clk_mux(dev, "uart8_mux", clk_base + REG_CLK_CLKSEL3,
> - 0, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
> + hws[UART8_MUX] = ma35d1_clk_mux(dev, "uart8_mux", clk_base + REG_CLK_CLKSEL3, 0, 2, hws,
> + uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
> hws[UART8_DIV] = ma35d1_clk_divider(dev, "uart8_div", "uart8_mux",
> clk_base + REG_CLK_CLKDIV2,
> 16, 4);
> hws[UART8_GATE] = ma35d1_clk_gate(dev, "uart8_gate", "uart8_div",
> clk_base + REG_CLK_APBCLK0, 20);
> - hws[UART9_MUX] = ma35d1_clk_mux(dev, "uart9_mux", clk_base + REG_CLK_CLKSEL3,
> - 2, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
> + hws[UART9_MUX] = ma35d1_clk_mux(dev, "uart9_mux", clk_base + REG_CLK_CLKSEL3, 2, 2, hws,
> + uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
> hws[UART9_DIV] = ma35d1_clk_divider(dev, "uart9_div", "uart9_mux",
> clk_base + REG_CLK_CLKDIV2,
> 20, 4);
> hws[UART9_GATE] = ma35d1_clk_gate(dev, "uart9_gate", "uart9_div",
> clk_base + REG_CLK_APBCLK0, 21);
> - hws[UART10_MUX] = ma35d1_clk_mux(dev, "uart10_mux", clk_base + REG_CLK_CLKSEL3,
> - 4, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
> + hws[UART10_MUX] = ma35d1_clk_mux(dev, "uart10_mux", clk_base + REG_CLK_CLKSEL3, 4, 2, hws,
> + uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
> hws[UART10_DIV] = ma35d1_clk_divider(dev, "uart10_div", "uart10_mux",
> clk_base + REG_CLK_CLKDIV2,
> 24, 4);
> hws[UART10_GATE] = ma35d1_clk_gate(dev, "uart10_gate", "uart10_div",
> clk_base + REG_CLK_APBCLK0, 22);
> - hws[UART11_MUX] = ma35d1_clk_mux(dev, "uart11_mux", clk_base + REG_CLK_CLKSEL3,
> - 6, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
> + hws[UART11_MUX] = ma35d1_clk_mux(dev, "uart11_mux", clk_base + REG_CLK_CLKSEL3, 6, 2, hws,
> + uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
> hws[UART11_DIV] = ma35d1_clk_divider(dev, "uart11_div", "uart11_mux",
> clk_base + REG_CLK_CLKDIV2,
> 28, 4);
> hws[UART11_GATE] = ma35d1_clk_gate(dev, "uart11_gate", "uart11_div",
> clk_base + REG_CLK_APBCLK0, 23);
> - hws[UART12_MUX] = ma35d1_clk_mux(dev, "uart12_mux", clk_base + REG_CLK_CLKSEL3,
> - 8, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
> + hws[UART12_MUX] = ma35d1_clk_mux(dev, "uart12_mux", clk_base + REG_CLK_CLKSEL3, 8, 2, hws,
> + uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
> hws[UART12_DIV] = ma35d1_clk_divider(dev, "uart12_div", "uart12_mux",
> clk_base + REG_CLK_CLKDIV3,
> 0, 4);
> hws[UART12_GATE] = ma35d1_clk_gate(dev, "uart12_gate", "uart12_div",
> clk_base + REG_CLK_APBCLK0, 24);
> - hws[UART13_MUX] = ma35d1_clk_mux(dev, "uart13_mux", clk_base + REG_CLK_CLKSEL3,
> - 10, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
> + hws[UART13_MUX] = ma35d1_clk_mux(dev, "uart13_mux", clk_base + REG_CLK_CLKSEL3, 10, 2, hws,
> + uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
> hws[UART13_DIV] = ma35d1_clk_divider(dev, "uart13_div", "uart13_mux",
> clk_base + REG_CLK_CLKDIV3,
> 4, 4);
> hws[UART13_GATE] = ma35d1_clk_gate(dev, "uart13_gate", "uart13_div",
> clk_base + REG_CLK_APBCLK0, 25);
> - hws[UART14_MUX] = ma35d1_clk_mux(dev, "uart14_mux", clk_base + REG_CLK_CLKSEL3,
> - 12, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
> + hws[UART14_MUX] = ma35d1_clk_mux(dev, "uart14_mux", clk_base + REG_CLK_CLKSEL3, 12, 2, hws,
> + uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
> hws[UART14_DIV] = ma35d1_clk_divider(dev, "uart14_div", "uart14_mux",
> clk_base + REG_CLK_CLKDIV3,
> 8, 4);
> hws[UART14_GATE] = ma35d1_clk_gate(dev, "uart14_gate", "uart14_div",
> clk_base + REG_CLK_APBCLK0, 26);
> - hws[UART15_MUX] = ma35d1_clk_mux(dev, "uart15_mux", clk_base + REG_CLK_CLKSEL3,
> - 14, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
> + hws[UART15_MUX] = ma35d1_clk_mux(dev, "uart15_mux", clk_base + REG_CLK_CLKSEL3, 14, 2, hws,
> + uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
> hws[UART15_DIV] = ma35d1_clk_divider(dev, "uart15_div", "uart15_mux",
> clk_base + REG_CLK_CLKDIV3,
> 12, 4);
> hws[UART15_GATE] = ma35d1_clk_gate(dev, "uart15_gate", "uart15_div",
> clk_base + REG_CLK_APBCLK0, 27);
> - hws[UART16_MUX] = ma35d1_clk_mux(dev, "uart16_mux", clk_base + REG_CLK_CLKSEL3,
> - 16, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
> + hws[UART16_MUX] = ma35d1_clk_mux(dev, "uart16_mux", clk_base + REG_CLK_CLKSEL3, 16, 2, hws,
> + uart_parent_idx, ARRAY_SIZE(uart_parent_idx));
> hws[UART16_DIV] = ma35d1_clk_divider(dev, "uart16_div", "uart16_mux",
> clk_base + REG_CLK_CLKDIV3,
> 16, 4);
> @@ -900,8 +628,8 @@ static int ma35d1_clocks_probe(struct platform_device *pdev)
> hws[DDR_GATE] = ma35d1_clk_gate(dev, "ddr_gate", "ddrpll",
> clk_base + REG_CLK_APBCLK0, 30);
>
> - hws[KPI_MUX] = ma35d1_clk_mux(dev, "kpi_mux", clk_base + REG_CLK_CLKSEL4,
> - 30, 1, kpi_sel_clks, ARRAY_SIZE(kpi_sel_clks));
> + hws[KPI_MUX] = ma35d1_clk_mux(dev, "kpi_mux", clk_base + REG_CLK_CLKSEL4, 30, 1, hws,
> + kpi_parent_idx, ARRAY_SIZE(kpi_parent_idx));
> hws[KPI_DIV] = ma35d1_clk_divider(dev, "kpi_div", "kpi_mux",
> clk_base + REG_CLK_CLKDIV4,
> 24, 8);
> @@ -921,49 +649,49 @@ static int ma35d1_clocks_probe(struct platform_device *pdev)
> hws[I2C5_GATE] = ma35d1_clk_gate(dev, "i2c5_gate", "pclk2",
> clk_base + REG_CLK_APBCLK1, 5);
>
> - hws[QSPI0_MUX] = ma35d1_clk_mux(dev, "qspi0_mux", clk_base + REG_CLK_CLKSEL4,
> - 8, 2, qspi0_sel_clks, ARRAY_SIZE(qspi0_sel_clks));
> + hws[QSPI0_MUX] = ma35d1_clk_mux(dev, "qspi0_mux", clk_base + REG_CLK_CLKSEL4, 8, 2, hws,
> + qspi_parent_idx, ARRAY_SIZE(qspi_parent_idx));
> hws[QSPI0_GATE] = ma35d1_clk_gate(dev, "qspi0_gate", "qspi0_mux",
> clk_base + REG_CLK_APBCLK1, 6);
> - hws[QSPI1_MUX] = ma35d1_clk_mux(dev, "qspi1_mux", clk_base + REG_CLK_CLKSEL4,
> - 10, 2, qspi1_sel_clks, ARRAY_SIZE(qspi1_sel_clks));
> + hws[QSPI1_MUX] = ma35d1_clk_mux(dev, "qspi1_mux", clk_base + REG_CLK_CLKSEL4, 10, 2, hws,
> + qspi_parent_idx, ARRAY_SIZE(qspi_parent_idx));
> hws[QSPI1_GATE] = ma35d1_clk_gate(dev, "qspi1_gate", "qspi1_mux",
> clk_base + REG_CLK_APBCLK1, 7);
>
> - hws[SMC0_MUX] = ma35d1_clk_mux(dev, "smc0_mux", clk_base + REG_CLK_CLKSEL4,
> - 28, 1, smc_sel_clks, ARRAY_SIZE(smc_sel_clks));
> + hws[SMC0_MUX] = ma35d1_clk_mux(dev, "smc0_mux", clk_base + REG_CLK_CLKSEL4, 28, 1, hws,
> + smc_parent_idx, ARRAY_SIZE(smc_parent_idx));
> hws[SMC0_DIV] = ma35d1_clk_divider(dev, "smc0_div", "smc0_mux",
> clk_base + REG_CLK_CLKDIV1,
> 0, 4);
> hws[SMC0_GATE] = ma35d1_clk_gate(dev, "smc0_gate", "smc0_div",
> clk_base + REG_CLK_APBCLK1, 12);
> - hws[SMC1_MUX] = ma35d1_clk_mux(dev, "smc1_mux", clk_base + REG_CLK_CLKSEL4,
> - 29, 1, smc_sel_clks, ARRAY_SIZE(smc_sel_clks));
> + hws[SMC1_MUX] = ma35d1_clk_mux(dev, "smc1_mux", clk_base + REG_CLK_CLKSEL4, 29, 1, hws,
> + smc_parent_idx, ARRAY_SIZE(smc_parent_idx));
> hws[SMC1_DIV] = ma35d1_clk_divider(dev, "smc1_div", "smc1_mux",
> clk_base + REG_CLK_CLKDIV1,
> 4, 4);
> hws[SMC1_GATE] = ma35d1_clk_gate(dev, "smc1_gate", "smc1_div",
> clk_base + REG_CLK_APBCLK1, 13);
>
> - hws[WDT0_MUX] = ma35d1_clk_mux(dev, "wdt0_mux", clk_base + REG_CLK_CLKSEL3,
> - 20, 2, wdt0_sel_clks, ARRAY_SIZE(wdt0_sel_clks));
> + hws[WDT0_MUX] = ma35d1_clk_mux(dev, "wdt0_mux", clk_base + REG_CLK_CLKSEL3, 20, 2, hws,
> + wdt0_parent_idx, ARRAY_SIZE(wdt0_parent_idx));
> hws[WDT0_GATE] = ma35d1_clk_gate(dev, "wdt0_gate", "wdt0_mux",
> clk_base + REG_CLK_APBCLK1, 16);
> - hws[WDT1_MUX] = ma35d1_clk_mux(dev, "wdt1_mux", clk_base + REG_CLK_CLKSEL3,
> - 24, 2, wdt1_sel_clks, ARRAY_SIZE(wdt1_sel_clks));
> + hws[WDT1_MUX] = ma35d1_clk_mux(dev, "wdt1_mux", clk_base + REG_CLK_CLKSEL3, 24, 2, hws,
> + wdt1_parent_idx, ARRAY_SIZE(wdt1_parent_idx));
> hws[WDT1_GATE] = ma35d1_clk_gate(dev, "wdt1_gate", "wdt1_mux",
> clk_base + REG_CLK_APBCLK1, 17);
> - hws[WDT2_MUX] = ma35d1_clk_mux(dev, "wdt2_mux", clk_base + REG_CLK_CLKSEL3,
> - 28, 2, wdt2_sel_clks, ARRAY_SIZE(wdt2_sel_clks));
> + hws[WDT2_MUX] = ma35d1_clk_mux(dev, "wdt2_mux", clk_base + REG_CLK_CLKSEL3, 28, 2, hws,
> + wdt2_parent_idx, ARRAY_SIZE(wdt2_parent_idx));
> hws[WDT2_GATE] = ma35d1_clk_gate(dev, "wdt2_gate", "wdt2_mux",
> clk_base + REG_CLK_APBCLK1, 18);
>
> - hws[WWDT0_MUX] = ma35d1_clk_mux(dev, "wwdt0_mux", clk_base + REG_CLK_CLKSEL3,
> - 22, 2, wwdt0_sel_clks, ARRAY_SIZE(wwdt0_sel_clks));
> - hws[WWDT1_MUX] = ma35d1_clk_mux(dev, "wwdt1_mux", clk_base + REG_CLK_CLKSEL3,
> - 26, 2, wwdt1_sel_clks, ARRAY_SIZE(wwdt1_sel_clks));
> - hws[WWDT2_MUX] = ma35d1_clk_mux(dev, "wwdt2_mux", clk_base + REG_CLK_CLKSEL3,
> - 30, 2, wwdt2_sel_clks, ARRAY_SIZE(wwdt2_sel_clks));
> + hws[WWDT0_MUX] = ma35d1_clk_mux(dev, "wwdt0_mux", clk_base + REG_CLK_CLKSEL3, 22, 2, hws,
> + wwdt0_parent_idx, ARRAY_SIZE(wwdt0_parent_idx));
> + hws[WWDT1_MUX] = ma35d1_clk_mux(dev, "wwdt1_mux", clk_base + REG_CLK_CLKSEL3, 26, 2, hws,
> + wwdt1_parent_idx, ARRAY_SIZE(wwdt1_parent_idx));
> + hws[WWDT2_MUX] = ma35d1_clk_mux(dev, "wwdt2_mux", clk_base + REG_CLK_CLKSEL3, 30, 2, hws,
> + wwdt2_parent_idx, ARRAY_SIZE(wwdt2_parent_idx));
>
> hws[EPWM0_GATE] = ma35d1_clk_gate(dev, "epwm0_gate", "pclk1",
> clk_base + REG_CLK_APBCLK1, 24);
> @@ -972,12 +700,12 @@ static int ma35d1_clocks_probe(struct platform_device *pdev)
> hws[EPWM2_GATE] = ma35d1_clk_gate(dev, "epwm2_gate", "pclk1",
> clk_base + REG_CLK_APBCLK1, 26);
>
> - hws[I2S0_MUX] = ma35d1_clk_mux(dev, "i2s0_mux", clk_base + REG_CLK_CLKSEL4,
> - 12, 2, i2s0_sel_clks, ARRAY_SIZE(i2s0_sel_clks));
> + hws[I2S0_MUX] = ma35d1_clk_mux(dev, "i2s0_mux", clk_base + REG_CLK_CLKSEL4, 12, 2, hws,
> + i2s_parent_idx, ARRAY_SIZE(i2s_parent_idx));
> hws[I2S0_GATE] = ma35d1_clk_gate(dev, "i2s0_gate", "i2s0_mux",
> clk_base + REG_CLK_APBCLK2, 0);
> - hws[I2S1_MUX] = ma35d1_clk_mux(dev, "i2s1_mux", clk_base + REG_CLK_CLKSEL4,
> - 14, 2, i2s1_sel_clks, ARRAY_SIZE(i2s1_sel_clks));
> + hws[I2S1_MUX] = ma35d1_clk_mux(dev, "i2s1_mux", clk_base + REG_CLK_CLKSEL4, 14, 2, hws,
> + i2s_parent_idx, ARRAY_SIZE(i2s_parent_idx));
> hws[I2S1_GATE] = ma35d1_clk_gate(dev, "i2s1_gate", "i2s1_mux",
> clk_base + REG_CLK_APBCLK2, 1);
>
> @@ -986,20 +714,20 @@ static int ma35d1_clocks_probe(struct platform_device *pdev)
> hws[SSPCC_GATE] = ma35d1_clk_gate(dev, "sspcc_gate", "pclk3",
> clk_base + REG_CLK_APBCLK2, 3);
>
> - hws[SPI0_MUX] = ma35d1_clk_mux(dev, "spi0_mux", clk_base + REG_CLK_CLKSEL4,
> - 0, 2, spi0_sel_clks, ARRAY_SIZE(spi0_sel_clks));
> + hws[SPI0_MUX] = ma35d1_clk_mux(dev, "spi0_mux", clk_base + REG_CLK_CLKSEL4, 0, 2, hws,
> + spi0_parent_idx, ARRAY_SIZE(spi0_parent_idx));
> hws[SPI0_GATE] = ma35d1_clk_gate(dev, "spi0_gate", "spi0_mux",
> clk_base + REG_CLK_APBCLK2, 4);
> - hws[SPI1_MUX] = ma35d1_clk_mux(dev, "spi1_mux", clk_base + REG_CLK_CLKSEL4,
> - 2, 2, spi1_sel_clks, ARRAY_SIZE(spi1_sel_clks));
> + hws[SPI1_MUX] = ma35d1_clk_mux(dev, "spi1_mux", clk_base + REG_CLK_CLKSEL4, 2, 2, hws,
> + spi1_parent_idx, ARRAY_SIZE(spi1_parent_idx));
> hws[SPI1_GATE] = ma35d1_clk_gate(dev, "spi1_gate", "spi1_mux",
> clk_base + REG_CLK_APBCLK2, 5);
> - hws[SPI2_MUX] = ma35d1_clk_mux(dev, "spi2_mux", clk_base + REG_CLK_CLKSEL4,
> - 4, 2, spi2_sel_clks, ARRAY_SIZE(spi2_sel_clks));
> + hws[SPI2_MUX] = ma35d1_clk_mux(dev, "spi2_mux", clk_base + REG_CLK_CLKSEL4, 4, 2, hws,
> + spi2_parent_idx, ARRAY_SIZE(spi2_parent_idx));
> hws[SPI2_GATE] = ma35d1_clk_gate(dev, "spi2_gate", "spi2_mux",
> clk_base + REG_CLK_APBCLK2, 6);
> - hws[SPI3_MUX] = ma35d1_clk_mux(dev, "spi3_mux", clk_base + REG_CLK_CLKSEL4,
> - 6, 2, spi3_sel_clks, ARRAY_SIZE(spi3_sel_clks));
> + hws[SPI3_MUX] = ma35d1_clk_mux(dev, "spi3_mux", clk_base + REG_CLK_CLKSEL4, 6, 2, hws,
> + spi3_parent_idx, ARRAY_SIZE(spi3_parent_idx));
> hws[SPI3_GATE] = ma35d1_clk_gate(dev, "spi3_gate", "spi3_mux",
> clk_base + REG_CLK_APBCLK2, 7);
>
>
> --
> 2.55.0
>
--
Jerome
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4 4/6] clk: nuvoton: ma35d1: Add missing WDT/WWDT parent clocks
2026-09-25 15:10 ` [PATCH v4 4/6] clk: nuvoton: " Miquel Raynal
@ 2026-09-27 17:04 ` Jerome Brunet
0 siblings, 0 replies; 12+ messages in thread
From: Jerome Brunet @ 2026-09-27 17:04 UTC (permalink / raw)
To: Miquel Raynal, Jacky Huang, Shan-Chun Hung, Michael Turquette,
Stephen Boyd, Richard Cochran, Arnd Bergmann, Brian Masney,
Jerome Brunet, Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Thomas Petazzoni, Steam Lin, linux-arm-kernel, linux-clk,
linux-kernel, Krzysztof Kozlowski, devicetree, Miquel Raynal,
Jacky Huang, stable
On ven. 25 sept. 2026 at 17:10, Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> The WDT and WWDT muxes list PCLK3/4096 and PCLK4/4096 among their
> possible parents, but the driver never registers the corresponding
> clocks, so these parents could never be used.
>
> Add pclk3_div4096 and pclk4_div4096 as fixed factor children of pclk3
> and pclk4 and expose them through the clock provider.
>
> Reported-by: Jacky Huang <ychuang570808@gmail.com>
> Closes: https://lore.kernel.org/linux-clk/b8a8a65b-e302-4747-bc90-4920fc48795a@gmail.com/
> Suggested-by: Jacky Huang <ychuang570808@gmail.com>
> Fixes: 691521a367cf ("clk: nuvoton: Add clock driver for ma35d1 clock controller")
> Cc: stable@vger.kernel.org
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Reviewed-by: Jerome Brunet <jbrunet@baylibre.com>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4 5/6] clk: nuvoton: ma35d1: Use clk_hw pointers as mux parents
2026-09-27 17:00 ` Jerome Brunet
@ 2026-09-28 16:02 ` Miquel Raynal
0 siblings, 0 replies; 12+ messages in thread
From: Miquel Raynal @ 2026-09-28 16:02 UTC (permalink / raw)
To: Jerome Brunet
Cc: Jacky Huang, Shan-Chun Hung, Michael Turquette, Stephen Boyd,
Richard Cochran, Arnd Bergmann, Brian Masney, Jerome Brunet,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Thomas Petazzoni,
Steam Lin, linux-arm-kernel, linux-clk, linux-kernel,
Krzysztof Kozlowski, devicetree, stable
On 27/09/2026 at 19:00:07 +02, Jerome Brunet <jbrunet@baylibre.com> wrote:
> On ven. 25 sept. 2026 at 17:10, Miquel Raynal <miquel.raynal@bootlin.com> wrote:
>
>> The MA35D1 clock provider registers its muxes with parent data
>> structures filling .fw_name. This is not the ideal approach since that
>> would require a massive amount of internal clock names declaration in
>> the DT. Since the DT does not play the game of exposing all these names,
>> none of the parent lookups performed when instantiating the muxes
>> succeed. As a result, these muxes get registered as root clocks, leading
>> to a sadly flat clock tree and no frequency assigned to most of the
>> peripheral clocks:
>>
>> enable prepare protect
>> clock count count count rate
>>
>> usbphy1 0 0 0 480000000
>> usbphy0 0 0 0 480000000
>> husbh1_gate 0 0 0 480000000
>> husbh0_gate 0 0 0 480000000
>> usbh_gate 0 0 0 480000000
>> usbd_gate 0 0 0 480000000
>> syspll 0 0 0 180000000
>> lirc 0 0 0 32000
>> lirc_gate 0 0 0 32000
>> hirc 0 0 0 12000000
>> gtmr_gate 0 0 0 12000000
>> hirc_gate 0 0 0 12000000
>> lxt 0 0 0 32768
>> rtc_gate 0 0 0 32768
>> lxt_gate 0 0 0 32768
>> hxt 0 0 0 24000000
>> vpll 0 0 0 1224000000
>> dcup_div 0 0 0 612000000
>> epll 0 0 0 6000000000
>> epll_div8 0 0 0 750000000
>>
>> epll_div4 0 0 0 1500000000
>> epll_div2 0 0 0 3000000000
>> emac1_gate 0 0 0 3000000000
>>
>> emac0_gate 0 0 0 3000000000
>>
>> apll 0 0 0 6048000000
>> ddrpll 0 0 0 266460000
>> ddr_gate 0 0 0 266460000
>> ddr6_gate 0 0 0 266460000
>> ddr0_gate 0 0 0 266460000
>> capll 0 0 0 2400000000
>> hxt_gate 0 0 0 24000000
>> clk_hxt 0 0 0 24000000
>> spi3_mux 0 0 0 0
>> spi3_gate 0 0 0 0
>> spi2_mux 0 0 0 0
>> spi2_gate 0 0 0 0
>> spi1_mux 0 0 0 0
>> spi1_gate 0 0 0 0
>> spi0_mux 0 0 0 0
>> spi0_gate 0 0 0 0
>> i2s1_mux 0 0 0 0
>> i2s1_gate 0 0 0 0
>> i2s0_mux 0 0 0 0
>> i2s0_gate 0 0 0 0
>> ...
>>
>> Apart from the wrong clock tree representation, it means that none of
>> the device drivers (spi & i2c in the excerpt above) can actually query
>> their clock rate, or they would get 0Hz.
>>
>> Instead of declaring the parents in the clk_parent_data structure, use
>> the actual HW clocks to lookup the parents directly: parents are
>> described by an array of indices into the controller's main clock table
>> (like in other clock controller drivers), which the "new" mux helper now
>> resolves.
>>
>> The WDT and WWDT muxes list the /4096 children of PCLK3 and PCLK4 among
>> their possible parents. Those two clocks are now registered by the
>> previous commit, so their entries in the parent tables are restored
>> instead of being turned into invalid slots.
>>
>> enable prepare protect
>> clock count count count rate
>>
>> usbphy1 0 0 0 480000000
>> usbphy0 0 0 0 480000000
>> husbh1_gate 0 0 0 480000000
>> husbh0_gate 0 0 0 480000000
>> usbh_gate 0 0 0 480000000
>> usbd_gate 0 0 0 480000000
>> syspll 1 1 0 180000000
>> dbg_mux 0 0 0 180000000
>> sdh1_mux 0 0 0 180000000
>> sdh1_gate 0 0 0 180000000
>> sdh0_mux 0 0 0 180000000
>> sdh0_gate 0 0 0 180000000
>> sysclk1_mux 2 2 0 180000000
>> pclk4 0 0 0 90000000
>> pclk3 0 0 0 90000000
>> sspcc_gate 0 0 0 90000000
>> ssmcc_gate 0 0 0 90000000
>> hclk3 0 0 0 90000000
>> pclk2 0 0 0 180000000
>> eadc_div 0 0 0 90000000
>> eadc_gate 0 0 0 90000000
>> qei1_gate 0 0 0 180000000
>> ecap1_gate 0 0 0 180000000
>> spi3_mux 0 0 0 180000000
>> spi3_gate 0 0 0 180000000
>> spi1_mux 0 0 0 180000000
>> spi1_gate 0 0 0 180000000
>> epwm1_gate 0 0 0 180000000
>> i2c5_gate 0 0 0 180000000
>> i2c2_gate 0 0 0 180000000
>> pclk1 0 0 0 180000000
>> qei2_gate 0 0 0 180000000
>> qei0_gate 0 0 0 180000000
>> ecap2_gate 0 0 0 180000000
>> ecap0_gate 0 0 0 180000000
>> spi2_mux 0 0 0 180000000
>> spi2_gate 0 0 0 180000000
>> spi0_mux 0 0 0 180000000
>> spi0_gate 0 0 0 180000000
>> epwm2_gate 0 0 0 180000000
>> epwm0_gate 0 0 0 180000000
>> i2c4_gate 0 0 0 180000000
>> i2c1_gate 0 0 0 180000000
>> pclk0 1 1 0 180000000
>> adc_div 0 0 0 90000000
>> adc_gate 0 0 0 90000000
>> qspi1_mux 0 0 0 180000000
>> qspi1_gate 0 0 0 180000000
>> qspi0_mux 1 1 0 180000000
>> qspi0_gate 1 1 0 180000000
>>
>> i2c3_gate 0 0 0 180000000
>> i2c0_gate 0 0 0 180000000
>>
>> Fixes: f50a000b4219 ("clk: nuvoton: Use clk_parent_data instead of string for parent clock")
>> Cc: stable@vger.kernel.org
>> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
>> ---
>> drivers/clk/nuvoton/clk-ma35d1.c | 626 +++++++++++----------------------------
>> 1 file changed, 177 insertions(+), 449 deletions(-)
>>
>> diff --git a/drivers/clk/nuvoton/clk-ma35d1.c b/drivers/clk/nuvoton/clk-ma35d1.c
>> index c914079cee2d..1a857f28310f 100644
>> --- a/drivers/clk/nuvoton/clk-ma35d1.c
>> +++ b/drivers/clk/nuvoton/clk-ma35d1.c
>> @@ -63,300 +63,49 @@ static DEFINE_SPINLOCK(ma35d1_lock);
>> #define PLL_MODE_FRAC 1
>> #define PLL_MODE_SS 2
>>
>> -static const struct clk_parent_data ca35clk_sel_clks[] = {
>> - { .fw_name = "hxt", },
>> - { .fw_name = "capll", },
>> - { .fw_name = "ddrpll", },
>> -};
>> +#define MA35D1_MUX_MAX_PARENTS 10
>
> I'm bit puzzled how this was supposed to work before. Most of those
> inputs are not present in binding doc. The controller was supposed get
> clocks from itself through DT ???
No idea why it has been written like that. Just to keep things clear, my
re-write is a fix, not a cleanup. Without it, the SPI controller does
not probe and I care about the SPI controller being fixed in this cycle.
> There is one input documented though. It seems to be hxt, so you should
> probably continue to use fw_name for this one at least.
"documented" is maybe a bit strong. There is one reference to a phandle
named clk_hxt, that's it? I don't think it qualifies as a validated
binding :)
> That being said, the bindings doc seems wrong. Looking at the driver you
> should have 4 inputs (hxt, lxt, hirc, lirc), unless those are actually
> generated on SoC ? Since there is already a DT using these, I suppose it
> is too late for the last 3 and you'll be stuck pretending they are
> generated in this controller :/
The TRM identifies:
- HXT and LXT as external crystal oscillators
- HIRC and LIRC as internal RC oscillators
So we want an accurate description, HXT/LXT are worth declaring, but not
HIRC/LIRC.
There is no way to fix this without a breaking change.
My approach for these clocks:
- Describe lxt like hxt in the DT. In the driver, I will take it from
DT, or fallback to a known base rate otherwise (so no breaking
change). This is possible since the TRM itself forces the rate of the
two oscillators. I will also ask for clock names in the binding.
- Fix the name of the output clocks to match the driver (use "hxt"
instead of "clk_hxt" in the DT). I could fix the driver instead, but
all other clocks would be named differently, which would be
strange. So since we anyway *need* a DT update, let's go for a clean
naming.
The other patches can still go like they are.
Thanks,
Miquèl
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-09-28 16:02 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-25 15:10 [PATCH v4 0/6] clk: nuvoton: ma35d1: Fix mux parenting and peripheral clock rates Miquel Raynal
2026-09-25 15:10 ` [PATCH v4 1/6] clk: nuvoton: ma35d1: Keep the clock count in the driver Miquel Raynal
2026-09-25 15:10 ` [PATCH v4 2/6] dt-bindings: clock: ma35d1: Drop CLK_MAX_IDX define Miquel Raynal
2026-09-25 16:41 ` Conor Dooley
2026-09-25 15:10 ` [PATCH v4 3/6] dt-bindings: clock: ma35d1: Add missing WDT/WWDT parent clocks Miquel Raynal
2026-09-25 16:42 ` Conor Dooley
2026-09-25 15:10 ` [PATCH v4 4/6] clk: nuvoton: " Miquel Raynal
2026-09-27 17:04 ` Jerome Brunet
2026-09-25 15:10 ` [PATCH v4 5/6] clk: nuvoton: ma35d1: Use clk_hw pointers as mux parents Miquel Raynal
2026-09-27 17:00 ` Jerome Brunet
2026-09-28 16:02 ` Miquel Raynal
2026-09-25 15:10 ` [PATCH v4 6/6] clk: nuvoton: ma35d1: Avoid possible error pointer dereferencing Miquel Raynal
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®