From nobody Thu Sep 24 20:37:31 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 28CA737AA7D; Mon, 21 Sep 2026 06:45:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789973102; cv=none; b=tGQSUcBegYe0eIDi1XBOuB7yYglO81AoZ6WDVB3erD/RuARXy1Ye0LEu/ymR4L1BVH1lYIwaDdT2md/ugfp4b/c3qOGDv9iCgdsGMNJPmyxcGUkzsZquhr+o9nBixuwKknfpVVTMG2FrGa21v1upJwz//aLD/G+umKBxcQ4Nhrg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789973102; c=relaxed/simple; bh=+tPhraM+bdj0Fx3vG8vtC2+Y/f/VACaVPt4swSxKleE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dXe85W/pqKTYk0SXqF59p88qwh2hR1N4+az5p4wntg+gi0kxpaH/LfU1O08a6CKOzqGjLvBYFrW2U3g3oKA2hDVHVw7xU0MHG8wn/Rt0aludjqTGo/7OVL6iA5ma1fG5bc4sr8YxNoojMaRCHLeYFXmp4IUXA5eTj7cJrXgreOY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=aT+ZgjtJ; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="aT+ZgjtJ" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 859F41A0DF3; Mon, 21 Sep 2026 06:44:59 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 5936360339; Mon, 21 Sep 2026 06:44:59 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 33A2C10328FEC; Mon, 21 Sep 2026 08:44:54 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1789973097; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=11eji1z4W2xZle7rFqNDZq5Blpq5fpa17v9TKg7x1fU=; b=aT+ZgjtJF+A5lbHYsaxdqz43ncPTAC9QWzht3flxCtDEXhY1g6JDvWwSF8dl/vBWH1NUFB lxXmZtrw2mTYu0A5RCVV6dIneM0SP2kxgQ3LR0V2HM9mvW1BegG/f+pE/DG/4/fSpXO8+o dOW5wb+Qf6p4D1C5ZvRWk5FUm7+/iMOjvUvT/ajoIdypS5nvBYJvpGhHxKlxjRINTaRAHP Hb+BnYifgruXOYwtHo4UvbLs2RhXDGWP06Xitk8QPnsIyy/f3sTuBXRp4fgqAJti2MktDY SDMxYuFjGg4cRrW5KOlrThid1/yZdFXOz49VT0/DPnXmdU3aifQFCaetwCEbEQ== From: Miquel Raynal Date: Mon, 21 Sep 2026 08:44:45 +0200 Subject: [PATCH v2 1/3] clk: nuvoton: ma35d1: Add missing WDT/WWDT parent clocks Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260921-perso-ma35d1-upstream-clk-v2-1-209fd32a8b00@bootlin.com> References: <20260921-perso-ma35d1-upstream-clk-v2-0-209fd32a8b00@bootlin.com> In-Reply-To: <20260921-perso-ma35d1-upstream-clk-v2-0-209fd32a8b00@bootlin.com> 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@lists.infradead.org, linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, Krzysztof Kozlowski , devicetree@vger.kernel.org, Miquel Raynal , Jacky Huang , stable@vger.kernel.org X-Mailer: b4 0.14.3 X-Last-TLS-Session-Version: TLSv1.3 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 Closes: https://lore.kernel.org/linux-clk/b8a8a65b-e302-4747-bc90-4920fc487= 95a@gmail.com/ Suggested-by: Jacky Huang Fixes: 691521a367cf ("clk: nuvoton: Add clock driver for ma35d1 clock contr= oller") Cc: stable@vger.kernel.org Signed-off-by: Miquel Raynal --- drivers/clk/nuvoton/clk-ma35d1.c | 2 ++ include/dt-bindings/clock/nuvoton,ma35d1-clk.h | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/clk/nuvoton/clk-ma35d1.c b/drivers/clk/nuvoton/clk-ma3= 5d1.c index 9f65d0623517..9d57de6a1e56 100644 --- a/drivers/clk/nuvoton/clk-ma35d1.c +++ b/drivers/clk/nuvoton/clk-ma35d1.c @@ -543,6 +543,8 @@ static int ma35d1_clocks_probe(struct platform_device *= pdev) hws[HCLK3] =3D ma35d1_clk_fixed_factor(dev, "hclk3", "sysclk1_mux", 1, 2); hws[PCLK3] =3D ma35d1_clk_fixed_factor(dev, "pclk3", "sysclk1_mux", 1, 2); hws[PCLK4] =3D ma35d1_clk_fixed_factor(dev, "pclk4", "sysclk1_mux", 1, 2); + hws[PCLK3_DIV4096] =3D ma35d1_clk_fixed_factor(dev, "pclk3_div4096", "pcl= k3", 1, 4096); + hws[PCLK4_DIV4096] =3D ma35d1_clk_fixed_factor(dev, "pclk4_div4096", "pcl= k4", 1, 4096); =20 hws[USBPHY0] =3D ma35d1_clk_fixed("usbphy0", 480000000); hws[USBPHY1] =3D ma35d1_clk_fixed("usbphy1", 480000000); diff --git a/include/dt-bindings/clock/nuvoton,ma35d1-clk.h b/include/dt-bi= ndings/clock/nuvoton,ma35d1-clk.h index ba2d70f776a6..d3fd8251c806 100644 --- a/include/dt-bindings/clock/nuvoton,ma35d1-clk.h +++ b/include/dt-bindings/clock/nuvoton,ma35d1-clk.h @@ -248,6 +248,8 @@ #define ADC_GATE 233 #define EADC_DIV 234 #define EADC_GATE 235 -#define CLK_MAX_IDX 236 +#define PCLK3_DIV4096 236 +#define PCLK4_DIV4096 237 +#define CLK_MAX_IDX 238 =20 #endif /* __DT_BINDINGS_CLOCK_NUVOTON_MA35D1_CLK_H */ --=20 2.55.0 From nobody Thu Sep 24 20:37:31 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CE0C138944D for ; Mon, 21 Sep 2026 06:45:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789973108; cv=none; b=Sx5h5KgeLqkjUcIXdxMP5Osho4u/yHRei6sBHdcg5BGAvt2RY0LKGwGaaFQ1OE8wmf1YaH8jMr8KIpv2cWwt9u5c0ajw+MvPL29CkF8+TN3opaY29Pf/3loVqmbVOinodnzL+PlfcAqXIVoU/Sg95G2I5zOqITVwT/+q/qJGXVA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789973108; c=relaxed/simple; bh=tzGGNLdfm5wM3Qbp/xS5sUkOI6P9HxNNh7xBUrYmCPU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Gx+5xwCneAYiaxmRci77+rGudlBq1hXnnS+QQRydB4i2kXiGmEgTbWpAIJ5QiYwJLhhhnJkPFApbkz6NlsYPbn+jNBdiMFN3Dxt3LL4Ip0YJxZvgUuPzS2BOGXwVKln1BT67w+hgPAiTMuXtdvvVIcl2l3TlzShd9T27MBardP8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=sFRsNdtH; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="sFRsNdtH" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 66DD21A0DC9; Mon, 21 Sep 2026 06:45:03 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 3086B60339; Mon, 21 Sep 2026 06:45:03 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 52D3B103290D5; Mon, 21 Sep 2026 08:44:58 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1789973101; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=k+dysiiAtPFWhAKarYU92FGj9kA71f0Xp/im2Ad9pRU=; b=sFRsNdtHO/uJs0C0vy+1sj1Mm5HEsLdxVdXTh6R3sKZMWQwxp9l95pKamwkjGayoy1Mm3z qWfgPk7UiFRLXw+Z0vqeRZc7w6HCaVbUKox53SNrIObO6ZZawaax9yN7kWeHFGCq7xF+QU 5+2SlVZ0YH4FpCosTjfqoI6+gjQlRjY9yVCHUCRZI+UHDwCj9M5iIUhHRDI2SqxP/D8ZJB kqpAfyqImYTOXzelpAmjEooUryAx+xjNnRJ0mFX71davx1pBINn3eH1KKAOIlI4rH1EitA 8ceoTLs1IoPbbe+GSAAVAfzskmjC6dNIApK1y0/jObAv6/uSD5eV9fnsC+hkBw== From: Miquel Raynal Date: Mon, 21 Sep 2026 08:44:46 +0200 Subject: [PATCH v2 2/3] clk: nuvoton: ma35d1: Use clk_hw pointers as mux parents Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260921-perso-ma35d1-upstream-clk-v2-2-209fd32a8b00@bootlin.com> References: <20260921-perso-ma35d1-upstream-clk-v2-0-209fd32a8b00@bootlin.com> In-Reply-To: <20260921-perso-ma35d1-upstream-clk-v2-0-209fd32a8b00@bootlin.com> 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@lists.infradead.org, linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, Krzysztof Kozlowski , devicetree@vger.kernel.org, Miquel Raynal , stable@vger.kernel.org X-Mailer: b4 0.14.3 X-Last-TLS-Session-Version: TLSv1.3 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 f= or parent clock") Cc: stable@vger.kernel.org Signed-off-by: Miquel Raynal --- 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-ma3= 5d1.c index 9d57de6a1e56..e45b3b12f359 100644 --- a/drivers/clk/nuvoton/clk-ma35d1.c +++ b/drivers/clk/nuvoton/clk-ma35d1.c @@ -62,300 +62,49 @@ static DEFINE_SPINLOCK(ma35d1_lock); #define PLL_MODE_FRAC 1 #define PLL_MODE_SS 2 =20 -static const struct clk_parent_data ca35clk_sel_clks[] =3D { - { .fw_name =3D "hxt", }, - { .fw_name =3D "capll", }, - { .fw_name =3D "ddrpll", }, -}; +#define MA35D1_MUX_MAX_PARENTS 10 =20 -static const struct clk_parent_data sysclk0_sel_clks[] =3D { - { .fw_name =3D "epll_div2", }, - { .fw_name =3D "syspll", }, -}; - -static const struct clk_parent_data sysclk1_sel_clks[] =3D { - { .fw_name =3D "hxt", }, - { .fw_name =3D "syspll", }, -}; - -static const struct clk_parent_data axiclk_sel_clks[] =3D { - { .fw_name =3D "capll_div2", }, - { .fw_name =3D "capll_div4", }, -}; - -static const struct clk_parent_data ccap_sel_clks[] =3D { - { .fw_name =3D "hxt", }, - { .fw_name =3D "vpll", }, - { .fw_name =3D "apll", }, - { .fw_name =3D "syspll", }, -}; - -static const struct clk_parent_data sdh_sel_clks[] =3D { - { .fw_name =3D "syspll", }, - { .fw_name =3D "apll", }, -}; - -static const struct clk_parent_data dcu_sel_clks[] =3D { - { .fw_name =3D "epll_div2", }, - { .fw_name =3D "syspll", }, -}; - -static const struct clk_parent_data gfx_sel_clks[] =3D { - { .fw_name =3D "epll", }, - { .fw_name =3D "syspll", }, -}; - -static const struct clk_parent_data dbg_sel_clks[] =3D { - { .fw_name =3D "hirc", }, - { .fw_name =3D "syspll", }, -}; - -static const struct clk_parent_data timer0_sel_clks[] =3D { - { .fw_name =3D "hxt", }, - { .fw_name =3D "lxt", }, - { .fw_name =3D "pclk0", }, - { .index =3D -1, }, - { .index =3D -1, }, - { .fw_name =3D "lirc", }, - { .index =3D -1, }, - { .fw_name =3D "hirc", }, -}; - -static const struct clk_parent_data timer1_sel_clks[] =3D { - { .fw_name =3D "hxt", }, - { .fw_name =3D "lxt", }, - { .fw_name =3D "pclk0", }, - { .index =3D -1, }, - { .index =3D -1, }, - { .fw_name =3D "lirc", }, - { .index =3D -1, }, - { .fw_name =3D "hirc", }, -}; - -static const struct clk_parent_data timer2_sel_clks[] =3D { - { .fw_name =3D "hxt", }, - { .fw_name =3D "lxt", }, - { .fw_name =3D "pclk1", }, - { .index =3D -1, }, - { .index =3D -1, }, - { .fw_name =3D "lirc", }, - { .index =3D -1, }, - { .fw_name =3D "hirc", }, -}; - -static const struct clk_parent_data timer3_sel_clks[] =3D { - { .fw_name =3D "hxt", }, - { .fw_name =3D "lxt", }, - { .fw_name =3D "pclk1", }, - { .index =3D -1, }, - { .index =3D -1, }, - { .fw_name =3D "lirc", }, - { .index =3D -1, }, - { .fw_name =3D "hirc", }, -}; - -static const struct clk_parent_data timer4_sel_clks[] =3D { - { .fw_name =3D "hxt", }, - { .fw_name =3D "lxt", }, - { .fw_name =3D "pclk2", }, - { .index =3D -1, }, - { .index =3D -1, }, - { .fw_name =3D "lirc", }, - { .index =3D -1, }, - { .fw_name =3D "hirc", }, -}; - -static const struct clk_parent_data timer5_sel_clks[] =3D { - { .fw_name =3D "hxt", }, - { .fw_name =3D "lxt", }, - { .fw_name =3D "pclk2", }, - { .index =3D -1, }, - { .index =3D -1, }, - { .fw_name =3D "lirc", }, - { .index =3D -1, }, - { .fw_name =3D "hirc", }, -}; - -static const struct clk_parent_data timer6_sel_clks[] =3D { - { .fw_name =3D "hxt", }, - { .fw_name =3D "lxt", }, - { .fw_name =3D "pclk0", }, - { .index =3D -1, }, - { .index =3D -1, }, - { .fw_name =3D "lirc", }, - { .index =3D -1, }, - { .fw_name =3D "hirc", }, -}; - -static const struct clk_parent_data timer7_sel_clks[] =3D { - { .fw_name =3D "hxt", }, - { .fw_name =3D "lxt", }, - { .fw_name =3D "pclk0", }, - { .index =3D -1, }, - { .index =3D -1, }, - { .fw_name =3D "lirc", }, - { .index =3D -1, }, - { .fw_name =3D "hirc", }, -}; - -static const struct clk_parent_data timer8_sel_clks[] =3D { - { .fw_name =3D "hxt", }, - { .fw_name =3D "lxt", }, - { .fw_name =3D "pclk1", }, - { .index =3D -1, }, - { .index =3D -1, }, - { .fw_name =3D "lirc", }, - { .index =3D -1, }, - { .fw_name =3D "hirc", }, -}; - -static const struct clk_parent_data timer9_sel_clks[] =3D { - { .fw_name =3D "hxt", }, - { .fw_name =3D "lxt", }, - { .fw_name =3D "pclk1", }, - { .index =3D -1, }, - { .index =3D -1, }, - { .fw_name =3D "lirc", }, - { .index =3D -1, }, - { .fw_name =3D "hirc", }, -}; - -static const struct clk_parent_data timer10_sel_clks[] =3D { - { .fw_name =3D "hxt", }, - { .fw_name =3D "lxt", }, - { .fw_name =3D "pclk2", }, - { .index =3D -1, }, - { .index =3D -1, }, - { .fw_name =3D "lirc", }, - { .index =3D -1, }, - { .fw_name =3D "hirc", }, -}; - -static const struct clk_parent_data timer11_sel_clks[] =3D { - { .fw_name =3D "hxt", }, - { .fw_name =3D "lxt", }, - { .fw_name =3D "pclk2", }, - { .index =3D -1, }, - { .index =3D -1, }, - { .fw_name =3D "lirc", }, - { .index =3D -1, }, - { .fw_name =3D "hirc", }, -}; - -static const struct clk_parent_data uart_sel_clks[] =3D { - { .fw_name =3D "hxt", }, - { .fw_name =3D "sysclk1_div2", }, -}; - -static const struct clk_parent_data wdt0_sel_clks[] =3D { - { .index =3D -1, }, - { .fw_name =3D "lxt", }, - { .fw_name =3D "pclk3_div4096", }, - { .fw_name =3D "lirc", }, -}; - -static const struct clk_parent_data wdt1_sel_clks[] =3D { - { .index =3D -1, }, - { .fw_name =3D "lxt", }, - { .fw_name =3D "pclk3_div4096", }, - { .fw_name =3D "lirc", }, -}; - -static const struct clk_parent_data wdt2_sel_clks[] =3D { - { .index =3D -1, }, - { .fw_name =3D "lxt", }, - { .fw_name =3D "pclk4_div4096", }, - { .fw_name =3D "lirc", }, -}; - -static const struct clk_parent_data wwdt0_sel_clks[] =3D { - { .index =3D -1, }, - { .index =3D -1, }, - { .fw_name =3D "pclk3_div4096", }, - { .fw_name =3D "lirc", }, -}; - -static const struct clk_parent_data wwdt1_sel_clks[] =3D { - { .index =3D -1, }, - { .index =3D -1, }, - { .fw_name =3D "pclk3_div4096", }, - { .fw_name =3D "lirc", }, -}; - -static const struct clk_parent_data wwdt2_sel_clks[] =3D { - { .index =3D -1, }, - { .index =3D -1, }, - { .fw_name =3D "pclk4_div4096", }, - { .fw_name =3D "lirc", }, -}; - -static const struct clk_parent_data spi0_sel_clks[] =3D { - { .fw_name =3D "pclk1", }, - { .fw_name =3D "apll", }, -}; - -static const struct clk_parent_data spi1_sel_clks[] =3D { - { .fw_name =3D "pclk2", }, - { .fw_name =3D "apll", }, -}; - -static const struct clk_parent_data spi2_sel_clks[] =3D { - { .fw_name =3D "pclk1", }, - { .fw_name =3D "apll", }, -}; - -static const struct clk_parent_data spi3_sel_clks[] =3D { - { .fw_name =3D "pclk2", }, - { .fw_name =3D "apll", }, -}; - -static const struct clk_parent_data qspi0_sel_clks[] =3D { - { .fw_name =3D "pclk0", }, - { .fw_name =3D "apll", }, -}; - -static const struct clk_parent_data qspi1_sel_clks[] =3D { - { .fw_name =3D "pclk0", }, - { .fw_name =3D "apll", }, -}; - -static const struct clk_parent_data i2s0_sel_clks[] =3D { - { .fw_name =3D "apll", }, - { .fw_name =3D "sysclk1_div2", }, -}; - -static const struct clk_parent_data i2s1_sel_clks[] =3D { - { .fw_name =3D "apll", }, - { .fw_name =3D "sysclk1_div2", }, -}; - -static const struct clk_parent_data can_sel_clks[] =3D { - { .fw_name =3D "apll", }, - { .fw_name =3D "vpll", }, -}; - -static const struct clk_parent_data cko_sel_clks[] =3D { - { .fw_name =3D "hxt", }, - { .fw_name =3D "lxt", }, - { .fw_name =3D "hirc", }, - { .fw_name =3D "lirc", }, - { .fw_name =3D "capll_div4", }, - { .fw_name =3D "syspll", }, - { .fw_name =3D "ddrpll", }, - { .fw_name =3D "epll_div2", }, - { .fw_name =3D "apll", }, - { .fw_name =3D "vpll", }, -}; - -static const struct clk_parent_data smc_sel_clks[] =3D { - { .fw_name =3D "hxt", }, - { .fw_name =3D "pclk4", }, -}; - -static const struct clk_parent_data kpi_sel_clks[] =3D { - { .fw_name =3D "hxt", }, - { .fw_name =3D "lxt", }, -}; +/* Mux parent selection, by index into the controller's clock table */ +static const int ca35clk_parent_idx[] =3D { HXT, CAPLL, DDRPLL }; +static const int sysclk0_parent_idx[] =3D { EPLL_DIV2, SYSPLL }; +static const int sysclk1_parent_idx[] =3D { HXT, SYSPLL }; +static const int axiclk_parent_idx[] =3D { AXICLK_DIV2, AXICLK_DIV4 }; +static const int ccap_parent_idx[] =3D { HXT, VPLL, APLL, SYSPLL }; +static const int sdh_parent_idx[] =3D { SYSPLL, APLL }; +static const int dcu_parent_idx[] =3D { EPLL_DIV2, SYSPLL }; +static const int gfx_parent_idx[] =3D { EPLL, SYSPLL }; +static const int dbg_parent_idx[] =3D { HIRC, SYSPLL }; +static const int timer0_parent_idx[] =3D { HXT, LXT, PCLK0, -1, -1, LIRC, = -1, HIRC }; +static const int timer1_parent_idx[] =3D { HXT, LXT, PCLK0, -1, -1, LIRC, = -1, HIRC }; +static const int timer2_parent_idx[] =3D { HXT, LXT, PCLK1, -1, -1, LIRC, = -1, HIRC }; +static const int timer3_parent_idx[] =3D { HXT, LXT, PCLK1, -1, -1, LIRC, = -1, HIRC }; +static const int timer4_parent_idx[] =3D { HXT, LXT, PCLK2, -1, -1, LIRC, = -1, HIRC }; +static const int timer5_parent_idx[] =3D { HXT, LXT, PCLK2, -1, -1, LIRC, = -1, HIRC }; +static const int timer6_parent_idx[] =3D { HXT, LXT, PCLK0, -1, -1, LIRC, = -1, HIRC }; +static const int timer7_parent_idx[] =3D { HXT, LXT, PCLK0, -1, -1, LIRC, = -1, HIRC }; +static const int timer8_parent_idx[] =3D { HXT, LXT, PCLK1, -1, -1, LIRC, = -1, HIRC }; +static const int timer9_parent_idx[] =3D { HXT, LXT, PCLK1, -1, -1, LIRC, = -1, HIRC }; +static const int timer10_parent_idx[] =3D { HXT, LXT, PCLK2, -1, -1, LIRC,= -1, HIRC }; +static const int timer11_parent_idx[] =3D { HXT, LXT, PCLK2, -1, -1, LIRC,= -1, HIRC }; +static const int uart_parent_idx[] =3D { HXT, SYSCLK1_DIV2 }; +static const int wdt0_parent_idx[] =3D { -1, LXT, PCLK3_DIV4096, LIRC }; +static const int wdt1_parent_idx[] =3D { -1, LXT, PCLK3_DIV4096, LIRC }; +static const int wdt2_parent_idx[] =3D { -1, LXT, PCLK4_DIV4096, LIRC }; +static const int wwdt0_parent_idx[] =3D { -1, -1, PCLK3_DIV4096, LIRC }; +static const int wwdt1_parent_idx[] =3D { -1, -1, PCLK3_DIV4096, LIRC }; +static const int wwdt2_parent_idx[] =3D { -1, -1, PCLK4_DIV4096, LIRC }; +static const int spi0_parent_idx[] =3D { PCLK1, APLL }; +static const int spi1_parent_idx[] =3D { PCLK2, APLL }; +static const int spi2_parent_idx[] =3D { PCLK1, APLL }; +static const int spi3_parent_idx[] =3D { PCLK2, APLL }; +static const int qspi_parent_idx[] =3D { PCLK0, APLL }; +static const int i2s_parent_idx[] =3D { APLL, SYSCLK1_DIV2 }; +static const int can_parent_idx[] =3D { APLL, VPLL }; +static const int cko_parent_idx[] =3D { HXT, LXT, HIRC, LIRC, + AXICLK_DIV4, SYSPLL, DDRPLL, + EPLL_DIV2, APLL, VPLL }; +static const int smc_parent_idx[] =3D { HXT, PCLK4 }; +static const int kpi_parent_idx[] =3D { HXT, LXT }; =20 static const struct clk_div_table ip_div_table[] =3D { {0, 2}, {1, 4}, {2, 6}, {3, 8}, {4, 10}, @@ -374,24 +123,20 @@ static struct clk_hw *ma35d1_clk_fixed(const char *na= me, int rate) return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate); } =20 -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] =3D {}; + int i; + + for (i =3D 0; i < num_parents; i++) + parent_hws[i] =3D (parent_idx[i] >=3D 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); } =20 static struct clk_hw *ma35d1_clk_divider(struct device *dev, const char *n= ame, @@ -514,22 +259,17 @@ static int ma35d1_clocks_probe(struct platform_device= *pdev) hws[EPLL_DIV4] =3D ma35d1_clk_fixed_factor(dev, "epll_div4", "epll", 1, 4= ); hws[EPLL_DIV8] =3D ma35d1_clk_fixed_factor(dev, "epll_div8", "epll", 1, 8= ); =20 - hws[CA35CLK_MUX] =3D 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] =3D ma35d1_clk_mux(dev, "ca35clk_mux", clk_base + REG_CL= K_CLKSEL0, 0, 2, hws, + ca35clk_parent_idx, ARRAY_SIZE(ca35clk_parent_idx)); hws[AXICLK_DIV2] =3D ma35d1_clk_fixed_factor(dev, "capll_div2", "ca35clk_= mux", 1, 2); hws[AXICLK_DIV4] =3D ma35d1_clk_fixed_factor(dev, "capll_div4", "ca35clk_= mux", 1, 4); =20 - hws[AXICLK_MUX] =3D ma35d1_clk_mux(dev, "axiclk_mux", clk_base + REG_CLK_= CLKDIV0, - 26, 1, axiclk_sel_clks, - ARRAY_SIZE(axiclk_sel_clks)); - hws[SYSCLK0_MUX] =3D ma35d1_clk_mux(dev, "sysclk0_mux", clk_base + REG_CL= K_CLKSEL0, - 2, 1, sysclk0_sel_clks, - ARRAY_SIZE(sysclk0_sel_clks)); - hws[SYSCLK1_MUX] =3D ma35d1_clk_mux(dev, "sysclk1_mux", clk_base + REG_CL= K_CLKSEL0, - 4, 1, sysclk1_sel_clks, - ARRAY_SIZE(sysclk1_sel_clks)); + hws[AXICLK_MUX] =3D 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] =3D ma35d1_clk_mux(dev, "sysclk0_mux", clk_base + REG_CL= K_CLKSEL0, 2, 1, hws, + sysclk0_parent_idx, ARRAY_SIZE(sysclk0_parent_idx)); + hws[SYSCLK1_MUX] =3D ma35d1_clk_mux(dev, "sysclk1_mux", clk_base + REG_CL= K_CLKSEL0, 4, 1, hws, + sysclk1_parent_idx, ARRAY_SIZE(sysclk1_parent_idx)); hws[SYSCLK1_DIV2] =3D ma35d1_clk_fixed_factor(dev, "sysclk1_div2", "syscl= k1_mux", 1, 2); =20 /* HCLK0~3 & PCLK0~4 */ @@ -555,41 +295,41 @@ static int ma35d1_clocks_probe(struct platform_device= *pdev) hws[DDR6_GATE] =3D ma35d1_clk_gate(dev, "ddr6_gate", "ddrpll", clk_base + REG_CLK_SYSCLK0, 5); =20 - hws[CAN0_MUX] =3D ma35d1_clk_mux(dev, "can0_mux", clk_base + REG_CLK_CLKS= EL4, - 16, 1, can_sel_clks, ARRAY_SIZE(can_sel_clks)); + hws[CAN0_MUX] =3D ma35d1_clk_mux(dev, "can0_mux", clk_base + REG_CLK_CLKS= EL4, 16, 1, hws, + can_parent_idx, ARRAY_SIZE(can_parent_idx)); hws[CAN0_DIV] =3D ma35d1_clk_divider_table(dev, "can0_div", "can0_mux", clk_base + REG_CLK_CLKDIV0, 0, 3, ip_div_table); hws[CAN0_GATE] =3D ma35d1_clk_gate(dev, "can0_gate", "can0_div", clk_base + REG_CLK_SYSCLK0, 8); - hws[CAN1_MUX] =3D ma35d1_clk_mux(dev, "can1_mux", clk_base + REG_CLK_CLKS= EL4, - 17, 1, can_sel_clks, ARRAY_SIZE(can_sel_clks)); + hws[CAN1_MUX] =3D ma35d1_clk_mux(dev, "can1_mux", clk_base + REG_CLK_CLKS= EL4, 17, 1, hws, + can_parent_idx, ARRAY_SIZE(can_parent_idx)); hws[CAN1_DIV] =3D ma35d1_clk_divider_table(dev, "can1_div", "can1_mux", clk_base + REG_CLK_CLKDIV0, 4, 3, ip_div_table); hws[CAN1_GATE] =3D ma35d1_clk_gate(dev, "can1_gate", "can1_div", clk_base + REG_CLK_SYSCLK0, 9); - hws[CAN2_MUX] =3D ma35d1_clk_mux(dev, "can2_mux", clk_base + REG_CLK_CLKS= EL4, - 18, 1, can_sel_clks, ARRAY_SIZE(can_sel_clks)); + hws[CAN2_MUX] =3D ma35d1_clk_mux(dev, "can2_mux", clk_base + REG_CLK_CLKS= EL4, 18, 1, hws, + can_parent_idx, ARRAY_SIZE(can_parent_idx)); hws[CAN2_DIV] =3D ma35d1_clk_divider_table(dev, "can2_div", "can2_mux", clk_base + REG_CLK_CLKDIV0, 8, 3, ip_div_table); hws[CAN2_GATE] =3D ma35d1_clk_gate(dev, "can2_gate", "can2_div", clk_base + REG_CLK_SYSCLK0, 10); - hws[CAN3_MUX] =3D ma35d1_clk_mux(dev, "can3_mux", clk_base + REG_CLK_CLKS= EL4, - 19, 1, can_sel_clks, ARRAY_SIZE(can_sel_clks)); + hws[CAN3_MUX] =3D ma35d1_clk_mux(dev, "can3_mux", clk_base + REG_CLK_CLKS= EL4, 19, 1, hws, + can_parent_idx, ARRAY_SIZE(can_parent_idx)); hws[CAN3_DIV] =3D ma35d1_clk_divider_table(dev, "can3_div", "can3_mux", clk_base + REG_CLK_CLKDIV0, 12, 3, ip_div_table); hws[CAN3_GATE] =3D ma35d1_clk_gate(dev, "can3_gate", "can3_div", clk_base + REG_CLK_SYSCLK0, 11); =20 - hws[SDH0_MUX] =3D ma35d1_clk_mux(dev, "sdh0_mux", clk_base + REG_CLK_CLKS= EL0, - 16, 2, sdh_sel_clks, ARRAY_SIZE(sdh_sel_clks)); + hws[SDH0_MUX] =3D ma35d1_clk_mux(dev, "sdh0_mux", clk_base + REG_CLK_CLKS= EL0, 16, 2, hws, + sdh_parent_idx, ARRAY_SIZE(sdh_parent_idx)); hws[SDH0_GATE] =3D ma35d1_clk_gate(dev, "sdh0_gate", "sdh0_mux", clk_base + REG_CLK_SYSCLK0, 16); - hws[SDH1_MUX] =3D ma35d1_clk_mux(dev, "sdh1_mux", clk_base + REG_CLK_CLKS= EL0, - 18, 2, sdh_sel_clks, ARRAY_SIZE(sdh_sel_clks)); + hws[SDH1_MUX] =3D ma35d1_clk_mux(dev, "sdh1_mux", clk_base + REG_CLK_CLKS= EL0, 18, 2, hws, + sdh_parent_idx, ARRAY_SIZE(sdh_parent_idx)); hws[SDH1_GATE] =3D ma35d1_clk_gate(dev, "sdh1_gate", "sdh1_mux", clk_base + REG_CLK_SYSCLK0, 17); =20 @@ -605,14 +345,14 @@ static int ma35d1_clocks_probe(struct platform_device= *pdev) hws[HUSBH1_GATE] =3D ma35d1_clk_gate(dev, "husbh1_gate", "usbphy0", clk_base + REG_CLK_SYSCLK0, 22); =20 - hws[GFX_MUX] =3D ma35d1_clk_mux(dev, "gfx_mux", clk_base + REG_CLK_CLKSEL= 0, - 26, 1, gfx_sel_clks, ARRAY_SIZE(gfx_sel_clks)); + hws[GFX_MUX] =3D ma35d1_clk_mux(dev, "gfx_mux", clk_base + REG_CLK_CLKSEL= 0, 26, 1, hws, + gfx_parent_idx, ARRAY_SIZE(gfx_parent_idx)); hws[GFX_GATE] =3D ma35d1_clk_gate(dev, "gfx_gate", "gfx_mux", clk_base + REG_CLK_SYSCLK0, 24); hws[VC8K_GATE] =3D ma35d1_clk_gate(dev, "vc8k_gate", "sysclk0_mux", clk_base + REG_CLK_SYSCLK0, 25); - hws[DCU_MUX] =3D ma35d1_clk_mux(dev, "dcu_mux", clk_base + REG_CLK_CLKSEL= 0, - 24, 1, dcu_sel_clks, ARRAY_SIZE(dcu_sel_clks)); + hws[DCU_MUX] =3D ma35d1_clk_mux(dev, "dcu_mux", clk_base + REG_CLK_CLKSEL= 0, 24, 1, hws, + dcu_parent_idx, ARRAY_SIZE(dcu_parent_idx)); hws[DCU_GATE] =3D ma35d1_clk_gate(dev, "dcu_gate", "dcu_mux", clk_base + REG_CLK_SYSCLK0, 26); hws[DCUP_DIV] =3D ma35d1_clk_divider_table(dev, "dcup_div", "vpll", @@ -624,14 +364,14 @@ static int ma35d1_clocks_probe(struct platform_device= *pdev) hws[EMAC1_GATE] =3D ma35d1_clk_gate(dev, "emac1_gate", "epll_div2", clk_base + REG_CLK_SYSCLK0, 28); =20 - hws[CCAP0_MUX] =3D ma35d1_clk_mux(dev, "ccap0_mux", clk_base + REG_CLK_CL= KSEL0, - 12, 1, ccap_sel_clks, ARRAY_SIZE(ccap_sel_clks)); + hws[CCAP0_MUX] =3D ma35d1_clk_mux(dev, "ccap0_mux", clk_base + REG_CLK_CL= KSEL0, 12, 1, hws, + ccap_parent_idx, ARRAY_SIZE(ccap_parent_idx)); hws[CCAP0_DIV] =3D ma35d1_clk_divider(dev, "ccap0_div", "ccap0_mux", clk_base + REG_CLK_CLKDIV1, 8, 4); hws[CCAP0_GATE] =3D ma35d1_clk_gate(dev, "ccap0_gate", "ccap0_div", clk_base + REG_CLK_SYSCLK0, 29); - hws[CCAP1_MUX] =3D ma35d1_clk_mux(dev, "ccap1_mux", clk_base + REG_CLK_CL= KSEL0, - 14, 1, ccap_sel_clks, ARRAY_SIZE(ccap_sel_clks)); + hws[CCAP1_MUX] =3D ma35d1_clk_mux(dev, "ccap1_mux", clk_base + REG_CLK_CL= KSEL0, 14, 1, hws, + ccap_parent_idx, ARRAY_SIZE(ccap_parent_idx)); hws[CCAP1_DIV] =3D ma35d1_clk_divider(dev, "ccap1_div", "ccap1_mux", clk_base + REG_CLK_CLKDIV1, 12, 4); @@ -669,13 +409,13 @@ static int ma35d1_clocks_probe(struct platform_device= *pdev) hws[TRA_GATE] =3D ma35d1_clk_gate(dev, "tra_gate", "hclk0", clk_base + REG_CLK_SYSCLK1, 11); =20 - hws[DBG_MUX] =3D ma35d1_clk_mux(dev, "dbg_mux", clk_base + REG_CLK_CLKSEL= 0, - 27, 1, dbg_sel_clks, ARRAY_SIZE(dbg_sel_clks)); + hws[DBG_MUX] =3D ma35d1_clk_mux(dev, "dbg_mux", clk_base + REG_CLK_CLKSEL= 0, 27, 1, hws, + dbg_parent_idx, ARRAY_SIZE(dbg_parent_idx)); hws[DBG_GATE] =3D ma35d1_clk_gate(dev, "dbg_gate", "hclk0", clk_base + REG_CLK_SYSCLK1, 12); =20 - hws[CKO_MUX] =3D ma35d1_clk_mux(dev, "cko_mux", clk_base + REG_CLK_CLKSEL= 4, - 24, 4, cko_sel_clks, ARRAY_SIZE(cko_sel_clks)); + hws[CKO_MUX] =3D ma35d1_clk_mux(dev, "cko_mux", clk_base + REG_CLK_CLKSEL= 4, 24, 4, hws, + cko_parent_idx, ARRAY_SIZE(cko_parent_idx)); hws[CKO_DIV] =3D ma35d1_clk_divider_pow2(dev, "cko_div", "cko_mux", clk_base + REG_CLK_CLKOCTL, 0, 4); hws[CKO_GATE] =3D ma35d1_clk_gate(dev, "cko_gate", "cko_div", @@ -713,181 +453,169 @@ static int ma35d1_clocks_probe(struct platform_devi= ce *pdev) hws[GPN_GATE] =3D ma35d1_clk_gate(dev, "gpn_gate", "hclk0", clk_base + REG_CLK_SYSCLK1, 29); =20 - hws[TMR0_MUX] =3D ma35d1_clk_mux(dev, "tmr0_mux", clk_base + REG_CLK_CLKS= EL1, - 0, 3, timer0_sel_clks, - ARRAY_SIZE(timer0_sel_clks)); + hws[TMR0_MUX] =3D ma35d1_clk_mux(dev, "tmr0_mux", clk_base + REG_CLK_CLKS= EL1, 0, 3, hws, + timer0_parent_idx, ARRAY_SIZE(timer0_parent_idx)); hws[TMR0_GATE] =3D ma35d1_clk_gate(dev, "tmr0_gate", "tmr0_mux", clk_base + REG_CLK_APBCLK0, 0); - hws[TMR1_MUX] =3D ma35d1_clk_mux(dev, "tmr1_mux", clk_base + REG_CLK_CLKS= EL1, - 4, 3, timer1_sel_clks, - ARRAY_SIZE(timer1_sel_clks)); + hws[TMR1_MUX] =3D ma35d1_clk_mux(dev, "tmr1_mux", clk_base + REG_CLK_CLKS= EL1, 4, 3, hws, + timer1_parent_idx, ARRAY_SIZE(timer1_parent_idx)); hws[TMR1_GATE] =3D ma35d1_clk_gate(dev, "tmr1_gate", "tmr1_mux", clk_base + REG_CLK_APBCLK0, 1); - hws[TMR2_MUX] =3D ma35d1_clk_mux(dev, "tmr2_mux", clk_base + REG_CLK_CLKS= EL1, - 8, 3, timer2_sel_clks, - ARRAY_SIZE(timer2_sel_clks)); + hws[TMR2_MUX] =3D ma35d1_clk_mux(dev, "tmr2_mux", clk_base + REG_CLK_CLKS= EL1, 8, 3, hws, + timer2_parent_idx, ARRAY_SIZE(timer2_parent_idx)); hws[TMR2_GATE] =3D ma35d1_clk_gate(dev, "tmr2_gate", "tmr2_mux", clk_base + REG_CLK_APBCLK0, 2); - hws[TMR3_MUX] =3D ma35d1_clk_mux(dev, "tmr3_mux", clk_base + REG_CLK_CLKS= EL1, - 12, 3, timer3_sel_clks, - ARRAY_SIZE(timer3_sel_clks)); + hws[TMR3_MUX] =3D ma35d1_clk_mux(dev, "tmr3_mux", clk_base + REG_CLK_CLKS= EL1, 12, 3, hws, + timer3_parent_idx, ARRAY_SIZE(timer3_parent_idx)); hws[TMR3_GATE] =3D ma35d1_clk_gate(dev, "tmr3_gate", "tmr3_mux", clk_base + REG_CLK_APBCLK0, 3); - hws[TMR4_MUX] =3D ma35d1_clk_mux(dev, "tmr4_mux", clk_base + REG_CLK_CLKS= EL1, - 16, 3, timer4_sel_clks, - ARRAY_SIZE(timer4_sel_clks)); + hws[TMR4_MUX] =3D ma35d1_clk_mux(dev, "tmr4_mux", clk_base + REG_CLK_CLKS= EL1, 16, 3, hws, + timer4_parent_idx, ARRAY_SIZE(timer4_parent_idx)); hws[TMR4_GATE] =3D ma35d1_clk_gate(dev, "tmr4_gate", "tmr4_mux", clk_base + REG_CLK_APBCLK0, 4); - hws[TMR5_MUX] =3D ma35d1_clk_mux(dev, "tmr5_mux", clk_base + REG_CLK_CLKS= EL1, - 20, 3, timer5_sel_clks, - ARRAY_SIZE(timer5_sel_clks)); + hws[TMR5_MUX] =3D ma35d1_clk_mux(dev, "tmr5_mux", clk_base + REG_CLK_CLKS= EL1, 20, 3, hws, + timer5_parent_idx, ARRAY_SIZE(timer5_parent_idx)); hws[TMR5_GATE] =3D ma35d1_clk_gate(dev, "tmr5_gate", "tmr5_mux", clk_base + REG_CLK_APBCLK0, 5); - hws[TMR6_MUX] =3D ma35d1_clk_mux(dev, "tmr6_mux", clk_base + REG_CLK_CLKS= EL1, - 24, 3, timer6_sel_clks, - ARRAY_SIZE(timer6_sel_clks)); + hws[TMR6_MUX] =3D ma35d1_clk_mux(dev, "tmr6_mux", clk_base + REG_CLK_CLKS= EL1, 24, 3, hws, + timer6_parent_idx, ARRAY_SIZE(timer6_parent_idx)); hws[TMR6_GATE] =3D ma35d1_clk_gate(dev, "tmr6_gate", "tmr6_mux", clk_base + REG_CLK_APBCLK0, 6); - hws[TMR7_MUX] =3D ma35d1_clk_mux(dev, "tmr7_mux", clk_base + REG_CLK_CLKS= EL1, - 28, 3, timer7_sel_clks, - ARRAY_SIZE(timer7_sel_clks)); + hws[TMR7_MUX] =3D ma35d1_clk_mux(dev, "tmr7_mux", clk_base + REG_CLK_CLKS= EL1, 28, 3, hws, + timer7_parent_idx, ARRAY_SIZE(timer7_parent_idx)); hws[TMR7_GATE] =3D ma35d1_clk_gate(dev, "tmr7_gate", "tmr7_mux", clk_base + REG_CLK_APBCLK0, 7); - hws[TMR8_MUX] =3D ma35d1_clk_mux(dev, "tmr8_mux", clk_base + REG_CLK_CLKS= EL2, - 0, 3, timer8_sel_clks, - ARRAY_SIZE(timer8_sel_clks)); + hws[TMR8_MUX] =3D ma35d1_clk_mux(dev, "tmr8_mux", clk_base + REG_CLK_CLKS= EL2, 0, 3, hws, + timer8_parent_idx, ARRAY_SIZE(timer8_parent_idx)); hws[TMR8_GATE] =3D ma35d1_clk_gate(dev, "tmr8_gate", "tmr8_mux", clk_base + REG_CLK_APBCLK0, 8); - hws[TMR9_MUX] =3D ma35d1_clk_mux(dev, "tmr9_mux", clk_base + REG_CLK_CLKS= EL2, - 4, 3, timer9_sel_clks, - ARRAY_SIZE(timer9_sel_clks)); + hws[TMR9_MUX] =3D ma35d1_clk_mux(dev, "tmr9_mux", clk_base + REG_CLK_CLKS= EL2, 4, 3, hws, + timer9_parent_idx, ARRAY_SIZE(timer9_parent_idx)); hws[TMR9_GATE] =3D ma35d1_clk_gate(dev, "tmr9_gate", "tmr9_mux", clk_base + REG_CLK_APBCLK0, 9); - hws[TMR10_MUX] =3D ma35d1_clk_mux(dev, "tmr10_mux", clk_base + REG_CLK_CL= KSEL2, - 8, 3, timer10_sel_clks, - ARRAY_SIZE(timer10_sel_clks)); + hws[TMR10_MUX] =3D ma35d1_clk_mux(dev, "tmr10_mux", clk_base + REG_CLK_CL= KSEL2, 8, 3, hws, + timer10_parent_idx, ARRAY_SIZE(timer10_parent_idx)); hws[TMR10_GATE] =3D ma35d1_clk_gate(dev, "tmr10_gate", "tmr10_mux", clk_base + REG_CLK_APBCLK0, 10); - hws[TMR11_MUX] =3D ma35d1_clk_mux(dev, "tmr11_mux", clk_base + REG_CLK_CL= KSEL2, - 12, 3, timer11_sel_clks, - ARRAY_SIZE(timer11_sel_clks)); + hws[TMR11_MUX] =3D ma35d1_clk_mux(dev, "tmr11_mux", clk_base + REG_CLK_CL= KSEL2, 12, 3, hws, + timer11_parent_idx, ARRAY_SIZE(timer11_parent_idx)); hws[TMR11_GATE] =3D ma35d1_clk_gate(dev, "tmr11_gate", "tmr11_mux", clk_base + REG_CLK_APBCLK0, 11); =20 - hws[UART0_MUX] =3D ma35d1_clk_mux(dev, "uart0_mux", clk_base + REG_CLK_CL= KSEL2, - 16, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks)); + hws[UART0_MUX] =3D ma35d1_clk_mux(dev, "uart0_mux", clk_base + REG_CLK_CL= KSEL2, 16, 2, hws, + uart_parent_idx, ARRAY_SIZE(uart_parent_idx)); hws[UART0_DIV] =3D ma35d1_clk_divider(dev, "uart0_div", "uart0_mux", clk_base + REG_CLK_CLKDIV1, 16, 4); hws[UART0_GATE] =3D ma35d1_clk_gate(dev, "uart0_gate", "uart0_div", clk_base + REG_CLK_APBCLK0, 12); - hws[UART1_MUX] =3D ma35d1_clk_mux(dev, "uart1_mux", clk_base + REG_CLK_CL= KSEL2, - 18, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks)); + hws[UART1_MUX] =3D ma35d1_clk_mux(dev, "uart1_mux", clk_base + REG_CLK_CL= KSEL2, 18, 2, hws, + uart_parent_idx, ARRAY_SIZE(uart_parent_idx)); hws[UART1_DIV] =3D ma35d1_clk_divider(dev, "uart1_div", "uart1_mux", clk_base + REG_CLK_CLKDIV1, 20, 4); hws[UART1_GATE] =3D ma35d1_clk_gate(dev, "uart1_gate", "uart1_div", clk_base + REG_CLK_APBCLK0, 13); - hws[UART2_MUX] =3D ma35d1_clk_mux(dev, "uart2_mux", clk_base + REG_CLK_CL= KSEL2, - 20, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks)); + hws[UART2_MUX] =3D ma35d1_clk_mux(dev, "uart2_mux", clk_base + REG_CLK_CL= KSEL2, 20, 2, hws, + uart_parent_idx, ARRAY_SIZE(uart_parent_idx)); hws[UART2_DIV] =3D ma35d1_clk_divider(dev, "uart2_div", "uart2_mux", clk_base + REG_CLK_CLKDIV1, 24, 4); hws[UART2_GATE] =3D ma35d1_clk_gate(dev, "uart2_gate", "uart2_div", clk_base + REG_CLK_APBCLK0, 14); - hws[UART3_MUX] =3D ma35d1_clk_mux(dev, "uart3_mux", clk_base + REG_CLK_CL= KSEL2, - 22, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks)); + hws[UART3_MUX] =3D ma35d1_clk_mux(dev, "uart3_mux", clk_base + REG_CLK_CL= KSEL2, 22, 2, hws, + uart_parent_idx, ARRAY_SIZE(uart_parent_idx)); hws[UART3_DIV] =3D ma35d1_clk_divider(dev, "uart3_div", "uart3_mux", clk_base + REG_CLK_CLKDIV1, 28, 4); hws[UART3_GATE] =3D ma35d1_clk_gate(dev, "uart3_gate", "uart3_div", clk_base + REG_CLK_APBCLK0, 15); - hws[UART4_MUX] =3D ma35d1_clk_mux(dev, "uart4_mux", clk_base + REG_CLK_CL= KSEL2, - 24, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks)); + hws[UART4_MUX] =3D ma35d1_clk_mux(dev, "uart4_mux", clk_base + REG_CLK_CL= KSEL2, 24, 2, hws, + uart_parent_idx, ARRAY_SIZE(uart_parent_idx)); hws[UART4_DIV] =3D ma35d1_clk_divider(dev, "uart4_div", "uart4_mux", clk_base + REG_CLK_CLKDIV2, 0, 4); hws[UART4_GATE] =3D ma35d1_clk_gate(dev, "uart4_gate", "uart4_div", clk_base + REG_CLK_APBCLK0, 16); - hws[UART5_MUX] =3D ma35d1_clk_mux(dev, "uart5_mux", clk_base + REG_CLK_CL= KSEL2, - 26, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks)); + hws[UART5_MUX] =3D ma35d1_clk_mux(dev, "uart5_mux", clk_base + REG_CLK_CL= KSEL2, 26, 2, hws, + uart_parent_idx, ARRAY_SIZE(uart_parent_idx)); hws[UART5_DIV] =3D ma35d1_clk_divider(dev, "uart5_div", "uart5_mux", clk_base + REG_CLK_CLKDIV2, 4, 4); hws[UART5_GATE] =3D ma35d1_clk_gate(dev, "uart5_gate", "uart5_div", clk_base + REG_CLK_APBCLK0, 17); - hws[UART6_MUX] =3D ma35d1_clk_mux(dev, "uart6_mux", clk_base + REG_CLK_CL= KSEL2, - 28, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks)); + hws[UART6_MUX] =3D ma35d1_clk_mux(dev, "uart6_mux", clk_base + REG_CLK_CL= KSEL2, 28, 2, hws, + uart_parent_idx, ARRAY_SIZE(uart_parent_idx)); hws[UART6_DIV] =3D ma35d1_clk_divider(dev, "uart6_div", "uart6_mux", clk_base + REG_CLK_CLKDIV2, 8, 4); hws[UART6_GATE] =3D ma35d1_clk_gate(dev, "uart6_gate", "uart6_div", clk_base + REG_CLK_APBCLK0, 18); - hws[UART7_MUX] =3D ma35d1_clk_mux(dev, "uart7_mux", clk_base + REG_CLK_CL= KSEL2, - 30, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks)); + hws[UART7_MUX] =3D ma35d1_clk_mux(dev, "uart7_mux", clk_base + REG_CLK_CL= KSEL2, 30, 2, hws, + uart_parent_idx, ARRAY_SIZE(uart_parent_idx)); hws[UART7_DIV] =3D ma35d1_clk_divider(dev, "uart7_div", "uart7_mux", clk_base + REG_CLK_CLKDIV2, 12, 4); hws[UART7_GATE] =3D ma35d1_clk_gate(dev, "uart7_gate", "uart7_div", clk_base + REG_CLK_APBCLK0, 19); - hws[UART8_MUX] =3D ma35d1_clk_mux(dev, "uart8_mux", clk_base + REG_CLK_CL= KSEL3, - 0, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks)); + hws[UART8_MUX] =3D ma35d1_clk_mux(dev, "uart8_mux", clk_base + REG_CLK_CL= KSEL3, 0, 2, hws, + uart_parent_idx, ARRAY_SIZE(uart_parent_idx)); hws[UART8_DIV] =3D ma35d1_clk_divider(dev, "uart8_div", "uart8_mux", clk_base + REG_CLK_CLKDIV2, 16, 4); hws[UART8_GATE] =3D ma35d1_clk_gate(dev, "uart8_gate", "uart8_div", clk_base + REG_CLK_APBCLK0, 20); - hws[UART9_MUX] =3D ma35d1_clk_mux(dev, "uart9_mux", clk_base + REG_CLK_CL= KSEL3, - 2, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks)); + hws[UART9_MUX] =3D ma35d1_clk_mux(dev, "uart9_mux", clk_base + REG_CLK_CL= KSEL3, 2, 2, hws, + uart_parent_idx, ARRAY_SIZE(uart_parent_idx)); hws[UART9_DIV] =3D ma35d1_clk_divider(dev, "uart9_div", "uart9_mux", clk_base + REG_CLK_CLKDIV2, 20, 4); hws[UART9_GATE] =3D ma35d1_clk_gate(dev, "uart9_gate", "uart9_div", clk_base + REG_CLK_APBCLK0, 21); - hws[UART10_MUX] =3D ma35d1_clk_mux(dev, "uart10_mux", clk_base + REG_CLK_= CLKSEL3, - 4, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks)); + hws[UART10_MUX] =3D 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] =3D ma35d1_clk_divider(dev, "uart10_div", "uart10_mux", clk_base + REG_CLK_CLKDIV2, 24, 4); hws[UART10_GATE] =3D ma35d1_clk_gate(dev, "uart10_gate", "uart10_div", clk_base + REG_CLK_APBCLK0, 22); - hws[UART11_MUX] =3D ma35d1_clk_mux(dev, "uart11_mux", clk_base + REG_CLK_= CLKSEL3, - 6, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks)); + hws[UART11_MUX] =3D 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] =3D ma35d1_clk_divider(dev, "uart11_div", "uart11_mux", clk_base + REG_CLK_CLKDIV2, 28, 4); hws[UART11_GATE] =3D ma35d1_clk_gate(dev, "uart11_gate", "uart11_div", clk_base + REG_CLK_APBCLK0, 23); - hws[UART12_MUX] =3D ma35d1_clk_mux(dev, "uart12_mux", clk_base + REG_CLK_= CLKSEL3, - 8, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks)); + hws[UART12_MUX] =3D 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] =3D ma35d1_clk_divider(dev, "uart12_div", "uart12_mux", clk_base + REG_CLK_CLKDIV3, 0, 4); hws[UART12_GATE] =3D ma35d1_clk_gate(dev, "uart12_gate", "uart12_div", clk_base + REG_CLK_APBCLK0, 24); - hws[UART13_MUX] =3D ma35d1_clk_mux(dev, "uart13_mux", clk_base + REG_CLK_= CLKSEL3, - 10, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks)); + hws[UART13_MUX] =3D 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] =3D ma35d1_clk_divider(dev, "uart13_div", "uart13_mux", clk_base + REG_CLK_CLKDIV3, 4, 4); hws[UART13_GATE] =3D ma35d1_clk_gate(dev, "uart13_gate", "uart13_div", clk_base + REG_CLK_APBCLK0, 25); - hws[UART14_MUX] =3D ma35d1_clk_mux(dev, "uart14_mux", clk_base + REG_CLK_= CLKSEL3, - 12, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks)); + hws[UART14_MUX] =3D 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] =3D ma35d1_clk_divider(dev, "uart14_div", "uart14_mux", clk_base + REG_CLK_CLKDIV3, 8, 4); hws[UART14_GATE] =3D ma35d1_clk_gate(dev, "uart14_gate", "uart14_div", clk_base + REG_CLK_APBCLK0, 26); - hws[UART15_MUX] =3D ma35d1_clk_mux(dev, "uart15_mux", clk_base + REG_CLK_= CLKSEL3, - 14, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks)); + hws[UART15_MUX] =3D 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] =3D ma35d1_clk_divider(dev, "uart15_div", "uart15_mux", clk_base + REG_CLK_CLKDIV3, 12, 4); hws[UART15_GATE] =3D ma35d1_clk_gate(dev, "uart15_gate", "uart15_div", clk_base + REG_CLK_APBCLK0, 27); - hws[UART16_MUX] =3D ma35d1_clk_mux(dev, "uart16_mux", clk_base + REG_CLK_= CLKSEL3, - 16, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks)); + hws[UART16_MUX] =3D 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] =3D ma35d1_clk_divider(dev, "uart16_div", "uart16_mux", clk_base + REG_CLK_CLKDIV3, 16, 4); @@ -899,8 +627,8 @@ static int ma35d1_clocks_probe(struct platform_device *= pdev) hws[DDR_GATE] =3D ma35d1_clk_gate(dev, "ddr_gate", "ddrpll", clk_base + REG_CLK_APBCLK0, 30); =20 - hws[KPI_MUX] =3D ma35d1_clk_mux(dev, "kpi_mux", clk_base + REG_CLK_CLKSEL= 4, - 30, 1, kpi_sel_clks, ARRAY_SIZE(kpi_sel_clks)); + hws[KPI_MUX] =3D ma35d1_clk_mux(dev, "kpi_mux", clk_base + REG_CLK_CLKSEL= 4, 30, 1, hws, + kpi_parent_idx, ARRAY_SIZE(kpi_parent_idx)); hws[KPI_DIV] =3D ma35d1_clk_divider(dev, "kpi_div", "kpi_mux", clk_base + REG_CLK_CLKDIV4, 24, 8); @@ -920,49 +648,49 @@ static int ma35d1_clocks_probe(struct platform_device= *pdev) hws[I2C5_GATE] =3D ma35d1_clk_gate(dev, "i2c5_gate", "pclk2", clk_base + REG_CLK_APBCLK1, 5); =20 - hws[QSPI0_MUX] =3D ma35d1_clk_mux(dev, "qspi0_mux", clk_base + REG_CLK_CL= KSEL4, - 8, 2, qspi0_sel_clks, ARRAY_SIZE(qspi0_sel_clks)); + hws[QSPI0_MUX] =3D ma35d1_clk_mux(dev, "qspi0_mux", clk_base + REG_CLK_CL= KSEL4, 8, 2, hws, + qspi_parent_idx, ARRAY_SIZE(qspi_parent_idx)); hws[QSPI0_GATE] =3D ma35d1_clk_gate(dev, "qspi0_gate", "qspi0_mux", clk_base + REG_CLK_APBCLK1, 6); - hws[QSPI1_MUX] =3D ma35d1_clk_mux(dev, "qspi1_mux", clk_base + REG_CLK_CL= KSEL4, - 10, 2, qspi1_sel_clks, ARRAY_SIZE(qspi1_sel_clks)); + hws[QSPI1_MUX] =3D ma35d1_clk_mux(dev, "qspi1_mux", clk_base + REG_CLK_CL= KSEL4, 10, 2, hws, + qspi_parent_idx, ARRAY_SIZE(qspi_parent_idx)); hws[QSPI1_GATE] =3D ma35d1_clk_gate(dev, "qspi1_gate", "qspi1_mux", clk_base + REG_CLK_APBCLK1, 7); =20 - hws[SMC0_MUX] =3D ma35d1_clk_mux(dev, "smc0_mux", clk_base + REG_CLK_CLKS= EL4, - 28, 1, smc_sel_clks, ARRAY_SIZE(smc_sel_clks)); + hws[SMC0_MUX] =3D ma35d1_clk_mux(dev, "smc0_mux", clk_base + REG_CLK_CLKS= EL4, 28, 1, hws, + smc_parent_idx, ARRAY_SIZE(smc_parent_idx)); hws[SMC0_DIV] =3D ma35d1_clk_divider(dev, "smc0_div", "smc0_mux", clk_base + REG_CLK_CLKDIV1, 0, 4); hws[SMC0_GATE] =3D ma35d1_clk_gate(dev, "smc0_gate", "smc0_div", clk_base + REG_CLK_APBCLK1, 12); - hws[SMC1_MUX] =3D ma35d1_clk_mux(dev, "smc1_mux", clk_base + REG_CLK_CLKS= EL4, - 29, 1, smc_sel_clks, ARRAY_SIZE(smc_sel_clks)); + hws[SMC1_MUX] =3D ma35d1_clk_mux(dev, "smc1_mux", clk_base + REG_CLK_CLKS= EL4, 29, 1, hws, + smc_parent_idx, ARRAY_SIZE(smc_parent_idx)); hws[SMC1_DIV] =3D ma35d1_clk_divider(dev, "smc1_div", "smc1_mux", clk_base + REG_CLK_CLKDIV1, 4, 4); hws[SMC1_GATE] =3D ma35d1_clk_gate(dev, "smc1_gate", "smc1_div", clk_base + REG_CLK_APBCLK1, 13); =20 - hws[WDT0_MUX] =3D ma35d1_clk_mux(dev, "wdt0_mux", clk_base + REG_CLK_CLKS= EL3, - 20, 2, wdt0_sel_clks, ARRAY_SIZE(wdt0_sel_clks)); + hws[WDT0_MUX] =3D ma35d1_clk_mux(dev, "wdt0_mux", clk_base + REG_CLK_CLKS= EL3, 20, 2, hws, + wdt0_parent_idx, ARRAY_SIZE(wdt0_parent_idx)); hws[WDT0_GATE] =3D ma35d1_clk_gate(dev, "wdt0_gate", "wdt0_mux", clk_base + REG_CLK_APBCLK1, 16); - hws[WDT1_MUX] =3D ma35d1_clk_mux(dev, "wdt1_mux", clk_base + REG_CLK_CLKS= EL3, - 24, 2, wdt1_sel_clks, ARRAY_SIZE(wdt1_sel_clks)); + hws[WDT1_MUX] =3D ma35d1_clk_mux(dev, "wdt1_mux", clk_base + REG_CLK_CLKS= EL3, 24, 2, hws, + wdt1_parent_idx, ARRAY_SIZE(wdt1_parent_idx)); hws[WDT1_GATE] =3D ma35d1_clk_gate(dev, "wdt1_gate", "wdt1_mux", clk_base + REG_CLK_APBCLK1, 17); - hws[WDT2_MUX] =3D ma35d1_clk_mux(dev, "wdt2_mux", clk_base + REG_CLK_CLKS= EL3, - 28, 2, wdt2_sel_clks, ARRAY_SIZE(wdt2_sel_clks)); + hws[WDT2_MUX] =3D ma35d1_clk_mux(dev, "wdt2_mux", clk_base + REG_CLK_CLKS= EL3, 28, 2, hws, + wdt2_parent_idx, ARRAY_SIZE(wdt2_parent_idx)); hws[WDT2_GATE] =3D ma35d1_clk_gate(dev, "wdt2_gate", "wdt2_mux", clk_base + REG_CLK_APBCLK1, 18); =20 - hws[WWDT0_MUX] =3D ma35d1_clk_mux(dev, "wwdt0_mux", clk_base + REG_CLK_CL= KSEL3, - 22, 2, wwdt0_sel_clks, ARRAY_SIZE(wwdt0_sel_clks)); - hws[WWDT1_MUX] =3D ma35d1_clk_mux(dev, "wwdt1_mux", clk_base + REG_CLK_CL= KSEL3, - 26, 2, wwdt1_sel_clks, ARRAY_SIZE(wwdt1_sel_clks)); - hws[WWDT2_MUX] =3D ma35d1_clk_mux(dev, "wwdt2_mux", clk_base + REG_CLK_CL= KSEL3, - 30, 2, wwdt2_sel_clks, ARRAY_SIZE(wwdt2_sel_clks)); + hws[WWDT0_MUX] =3D ma35d1_clk_mux(dev, "wwdt0_mux", clk_base + REG_CLK_CL= KSEL3, 22, 2, hws, + wwdt0_parent_idx, ARRAY_SIZE(wwdt0_parent_idx)); + hws[WWDT1_MUX] =3D ma35d1_clk_mux(dev, "wwdt1_mux", clk_base + REG_CLK_CL= KSEL3, 26, 2, hws, + wwdt1_parent_idx, ARRAY_SIZE(wwdt1_parent_idx)); + hws[WWDT2_MUX] =3D ma35d1_clk_mux(dev, "wwdt2_mux", clk_base + REG_CLK_CL= KSEL3, 30, 2, hws, + wwdt2_parent_idx, ARRAY_SIZE(wwdt2_parent_idx)); =20 hws[EPWM0_GATE] =3D ma35d1_clk_gate(dev, "epwm0_gate", "pclk1", clk_base + REG_CLK_APBCLK1, 24); @@ -971,12 +699,12 @@ static int ma35d1_clocks_probe(struct platform_device= *pdev) hws[EPWM2_GATE] =3D ma35d1_clk_gate(dev, "epwm2_gate", "pclk1", clk_base + REG_CLK_APBCLK1, 26); =20 - hws[I2S0_MUX] =3D ma35d1_clk_mux(dev, "i2s0_mux", clk_base + REG_CLK_CLKS= EL4, - 12, 2, i2s0_sel_clks, ARRAY_SIZE(i2s0_sel_clks)); + hws[I2S0_MUX] =3D ma35d1_clk_mux(dev, "i2s0_mux", clk_base + REG_CLK_CLKS= EL4, 12, 2, hws, + i2s_parent_idx, ARRAY_SIZE(i2s_parent_idx)); hws[I2S0_GATE] =3D ma35d1_clk_gate(dev, "i2s0_gate", "i2s0_mux", clk_base + REG_CLK_APBCLK2, 0); - hws[I2S1_MUX] =3D ma35d1_clk_mux(dev, "i2s1_mux", clk_base + REG_CLK_CLKS= EL4, - 14, 2, i2s1_sel_clks, ARRAY_SIZE(i2s1_sel_clks)); + hws[I2S1_MUX] =3D ma35d1_clk_mux(dev, "i2s1_mux", clk_base + REG_CLK_CLKS= EL4, 14, 2, hws, + i2s_parent_idx, ARRAY_SIZE(i2s_parent_idx)); hws[I2S1_GATE] =3D ma35d1_clk_gate(dev, "i2s1_gate", "i2s1_mux", clk_base + REG_CLK_APBCLK2, 1); =20 @@ -985,20 +713,20 @@ static int ma35d1_clocks_probe(struct platform_device= *pdev) hws[SSPCC_GATE] =3D ma35d1_clk_gate(dev, "sspcc_gate", "pclk3", clk_base + REG_CLK_APBCLK2, 3); =20 - hws[SPI0_MUX] =3D ma35d1_clk_mux(dev, "spi0_mux", clk_base + REG_CLK_CLKS= EL4, - 0, 2, spi0_sel_clks, ARRAY_SIZE(spi0_sel_clks)); + hws[SPI0_MUX] =3D ma35d1_clk_mux(dev, "spi0_mux", clk_base + REG_CLK_CLKS= EL4, 0, 2, hws, + spi0_parent_idx, ARRAY_SIZE(spi0_parent_idx)); hws[SPI0_GATE] =3D ma35d1_clk_gate(dev, "spi0_gate", "spi0_mux", clk_base + REG_CLK_APBCLK2, 4); - hws[SPI1_MUX] =3D ma35d1_clk_mux(dev, "spi1_mux", clk_base + REG_CLK_CLKS= EL4, - 2, 2, spi1_sel_clks, ARRAY_SIZE(spi1_sel_clks)); + hws[SPI1_MUX] =3D ma35d1_clk_mux(dev, "spi1_mux", clk_base + REG_CLK_CLKS= EL4, 2, 2, hws, + spi1_parent_idx, ARRAY_SIZE(spi1_parent_idx)); hws[SPI1_GATE] =3D ma35d1_clk_gate(dev, "spi1_gate", "spi1_mux", clk_base + REG_CLK_APBCLK2, 5); - hws[SPI2_MUX] =3D ma35d1_clk_mux(dev, "spi2_mux", clk_base + REG_CLK_CLKS= EL4, - 4, 2, spi2_sel_clks, ARRAY_SIZE(spi2_sel_clks)); + hws[SPI2_MUX] =3D ma35d1_clk_mux(dev, "spi2_mux", clk_base + REG_CLK_CLKS= EL4, 4, 2, hws, + spi2_parent_idx, ARRAY_SIZE(spi2_parent_idx)); hws[SPI2_GATE] =3D ma35d1_clk_gate(dev, "spi2_gate", "spi2_mux", clk_base + REG_CLK_APBCLK2, 6); - hws[SPI3_MUX] =3D ma35d1_clk_mux(dev, "spi3_mux", clk_base + REG_CLK_CLKS= EL4, - 6, 2, spi3_sel_clks, ARRAY_SIZE(spi3_sel_clks)); + hws[SPI3_MUX] =3D ma35d1_clk_mux(dev, "spi3_mux", clk_base + REG_CLK_CLKS= EL4, 6, 2, hws, + spi3_parent_idx, ARRAY_SIZE(spi3_parent_idx)); hws[SPI3_GATE] =3D ma35d1_clk_gate(dev, "spi3_gate", "spi3_mux", clk_base + REG_CLK_APBCLK2, 7); =20 --=20 2.55.0 From nobody Thu Sep 24 20:37:31 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6F009329C48 for ; Mon, 21 Sep 2026 06:45:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789973108; cv=none; b=fHekpmfQFbSI8KmMszclgbEIuIiacZ7Jr2NXyjnIqEmgJp2eTy2T0HTftRoCw83Ln4AEEHchTYRgSODScrEQeki9+LgEwkWTHxRLq6+et0N6c2rNgGTow/QSGdsVLeasZ0pfIaTA3Yqduu3YTmFJSQaqyrKE4qQDNZByUeAgxW4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789973108; c=relaxed/simple; bh=peW1jNhTn70BpnD4GhOZifHibJ4alVb6Iv6FBdZLkdQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TG5zLf6bXuTB67ofLFfmbof/XyXRvlZlY2pGhZUSI8Hp3m4osygHUVDFnvOYKItua4z4TBKUeGLzteKveY2vCR4kdhtP3+eORFRCuW86BMiw7rrFX+6n5sl72WeZgfYTGZI7H1FE+O6cWlIChbj7XMya+gqBu2KPd6xNPCBiT+8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=mLSVt3Nv; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="mLSVt3Nv" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 10E241A0DF7; Mon, 21 Sep 2026 06:45:06 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id D834760339; Mon, 21 Sep 2026 06:45:05 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id EBD17103290BF; Mon, 21 Sep 2026 08:45:01 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1789973104; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=UDplaWJfaunbrVntrk6zp9NxBt0dzB8llgC0vJ6omJM=; b=mLSVt3NvznNsyukRDsWlt4K+0I9Pa3xrVTnGdtXcz1GQRZo2EAPl3+Z/a/rGQmwRJ+wrwz ueT/pOSqPYcwnA+pay7Jv37SghzHgdhdqhDGrI7329L3LLIQJm/CamD+1Zifikd9sxjm1k 63u4g5Y08U0hBqJSJ/UUHnyE2DA1EtvPcMTzE9SHKySjhyS+xFJ+2JAL4DezoSm59fdf0k 0amBfwXWOILlzaxjFrMCTqBUliVx2ckjAFYAkDZsySHg3bf/T0zbUtBsCsxjlOumgDgAPb +KC5B3eODNDXImfvNzv99qLigGUQYW25SOhmsXQheaiRs8Cih6nn/7jtJvSXLw== From: Miquel Raynal Date: Mon, 21 Sep 2026 08:44:47 +0200 Subject: [PATCH v2 3/3] clk: nuvoton: ma35d1: Avoid possible error pointer dereferencing Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260921-perso-ma35d1-upstream-clk-v2-3-209fd32a8b00@bootlin.com> References: <20260921-perso-ma35d1-upstream-clk-v2-0-209fd32a8b00@bootlin.com> In-Reply-To: <20260921-perso-ma35d1-upstream-clk-v2-0-209fd32a8b00@bootlin.com> 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@lists.infradead.org, linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, Krzysztof Kozlowski , devicetree@vger.kernel.org, Miquel Raynal X-Mailer: b4 0.14.3 X-Last-TLS-Session-Version: TLSv1.3 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 --- 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; =20 + if (IS_ERR(parent_hw)) + return parent_hw; + div =3D 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, u= 32 id, u8 u8mode, const c struct clk_hw *hw; int ret; =20 + if (IS_ERR(parent_hw)) + return parent_hw; + pll =3D 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-ma3= 5d1.c index e45b3b12f359..f13e7040f71e 100644 --- a/drivers/clk/nuvoton/clk-ma35d1.c +++ b/drivers/clk/nuvoton/clk-ma35d1.c @@ -129,10 +129,19 @@ static struct clk_hw *ma35d1_clk_mux(struct device *d= ev, const char *name, const int *parent_idx, int num_parents) { const struct clk_hw *parent_hws[MA35D1_MUX_MAX_PARENTS] =3D {}; + struct clk_hw *parent; int i; =20 - for (i =3D 0; i < num_parents; i++) - parent_hws[i] =3D (parent_idx[i] >=3D 0) ? hws[parent_idx[i]] : NULL; + for (i =3D 0; i < num_parents; i++) { + if (parent_idx[i] < 0) + continue; + + parent =3D hws[parent_idx[i]]; + if (IS_ERR(parent)) + return parent; + + parent_hws[i] =3D parent; + } =20 return clk_hw_register_mux_hws(dev, name, parent_hws, num_parents, CLK_SET_RATE_NO_REPARENT, reg, shift, --=20 2.55.0