* [PATCH v6 0/3] clk: add support for Airoha AN7583 clock
@ 2026-08-19 22:14 Christian Marangi
2026-08-19 22:14 ` [PATCH v6 1/3] dt-bindings: clock: airoha: Document support for " Christian Marangi
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Christian Marangi @ 2026-08-19 22:14 UTC (permalink / raw)
To: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Philipp Zabel, Felix Fietkau,
linux-clk, devicetree, linux-kernel
Cc: Christian Marangi
This small series introduce some cleanup and support for
clock and reset of Airoha AN7583.
The implementation is similar to EN7581 but AN7583 introduce
new reset and more clock divisor support.
Changes v6:
- Address bot suggestion for DT patch
- Add further information on chip-scu phandle
- Add dedicated PERSTOUT reset and PCIE_HB reset
Changes v5:
- Rebase on top of linux-next
- Drop even more patch to reduce patch delta
- Make chip-scu specific to AN7583
Link: https://lore.kernel.org/all/20260528190000.9164-1-ansuelsmth@gmail.com
Changes v4:
- Add review tag for DT patch
- Fix clock patch to use en7581-chip-scu compatible
- Drop PCIE SCU SSR write
Changes v3:
- Drop .set_rate patch (will be proposed later)
- Drop chip-scu binding and related patch
Link: https://lore.kernel.org/all/20251106195935.1767696-1-ansuelsmth@gmail.com
Changes v2:
- Add .set_rate support
- Rework DT to EN7581 implementation (clock driver is parent)
- Add additional cleanup patch
- Merge binding with schema patch
- Add chip_scu phandle
Christian Marangi (3):
dt-bindings: clock: airoha: Document support for AN7583 clock
clk: en7523: generalize register clocks function
clk: en7523: add support for Airoha AN7583 clock
.../bindings/clock/airoha,en7523-scu.yaml | 20 ++
drivers/clk/clk-en7523.c | 250 +++++++++++++++++-
include/dt-bindings/clock/en7523-clk.h | 3 +
.../dt-bindings/reset/airoha,an7583-reset.h | 65 +++++
4 files changed, 336 insertions(+), 2 deletions(-)
create mode 100644 include/dt-bindings/reset/airoha,an7583-reset.h
--
2.53.0
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH v6 1/3] dt-bindings: clock: airoha: Document support for AN7583 clock 2026-08-19 22:14 [PATCH v6 0/3] clk: add support for Airoha AN7583 clock Christian Marangi @ 2026-08-19 22:14 ` Christian Marangi 2026-08-19 22:21 ` sashiko-bot 2026-08-19 22:14 ` [PATCH v6 2/3] clk: en7523: generalize register clocks function Christian Marangi 2026-08-19 22:14 ` [PATCH v6 3/3] clk: en7523: add support for Airoha AN7583 clock Christian Marangi 2 siblings, 1 reply; 8+ messages in thread From: Christian Marangi @ 2026-08-19 22:14 UTC (permalink / raw) To: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Philipp Zabel, Felix Fietkau, linux-clk, devicetree, linux-kernel Cc: Christian Marangi Document support for Airoha AN7583 clock. This is based on the EN7523 clock schema with the new requirement of the "airoha,chip-scu". Add additional binding for additional clock and reset lines. Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> --- .../bindings/clock/airoha,en7523-scu.yaml | 20 ++++++ include/dt-bindings/clock/en7523-clk.h | 3 + .../dt-bindings/reset/airoha,an7583-reset.h | 65 +++++++++++++++++++ 3 files changed, 88 insertions(+) create mode 100644 include/dt-bindings/reset/airoha,an7583-reset.h diff --git a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml index eb24a5687639..edecc635807b 100644 --- a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml +++ b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml @@ -30,6 +30,7 @@ properties: compatible: items: - enum: + - airoha,an7583-scu - airoha,en7523-scu - airoha,en7581-scu - econet,en751221-scu @@ -50,12 +51,30 @@ properties: description: ID of the controller reset line const: 1 + airoha,chip-scu: + $ref: /schemas/types.yaml#/definitions/phandle + description: phandle to the Chip SCU providing the registers required + for configuring the PCIe related clocks and resets. + required: - compatible - reg - '#clock-cells' allOf: + - if: + properties: + compatible: + const: airoha,an7583-scu + + then: + required: + - airoha,chip-scu + + else: + properties: + airoha,chip-scu: false + - if: properties: compatible: @@ -69,6 +88,7 @@ allOf: properties: compatible: enum: + - airoha,an7583-scu - airoha,en7581-scu - econet,en751221-scu then: diff --git a/include/dt-bindings/clock/en7523-clk.h b/include/dt-bindings/clock/en7523-clk.h index edfa64045f52..0fbbcb7b1b25 100644 --- a/include/dt-bindings/clock/en7523-clk.h +++ b/include/dt-bindings/clock/en7523-clk.h @@ -14,4 +14,7 @@ #define EN7581_CLK_EMMC 8 +#define AN7583_CLK_MDIO0 9 +#define AN7583_CLK_MDIO1 10 + #endif /* _DT_BINDINGS_CLOCK_AIROHA_EN7523_H_ */ diff --git a/include/dt-bindings/reset/airoha,an7583-reset.h b/include/dt-bindings/reset/airoha,an7583-reset.h new file mode 100644 index 000000000000..410e19802cf7 --- /dev/null +++ b/include/dt-bindings/reset/airoha,an7583-reset.h @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2024 AIROHA Inc + * Author: Christian Marangi <ansuelsmth@gmail.com> + */ + +#ifndef __DT_BINDINGS_RESET_CONTROLLER_AIROHA_AN7583_H_ +#define __DT_BINDINGS_RESET_CONTROLLER_AIROHA_AN7583_H_ + +/* RST_CTRL2 */ +#define AN7583_XPON_PHY_RST 0 +#define AN7583_GPON_OLT_RST 1 +#define AN7583_CPU_TIMER2_RST 2 +#define AN7583_HSUART_RST 3 +#define AN7583_UART4_RST 4 +#define AN7583_UART5_RST 5 +#define AN7583_I2C2_RST 6 +#define AN7583_XSI_MAC_RST 7 +#define AN7583_XSI_PHY_RST 8 +#define AN7583_NPU_RST 9 +#define AN7583_TRNG_MSTART_RST 10 +#define AN7583_DUAL_HSI0_RST 11 +#define AN7583_DUAL_HSI1_RST 12 +#define AN7583_DUAL_HSI0_MAC_RST 13 +#define AN7583_DUAL_HSI1_MAC_RST 14 +#define AN7583_XPON_XFI_RST 15 +#define AN7583_WDMA_RST 16 +#define AN7583_WOE0_RST 17 +#define AN7583_HSDMA_RST 18 +#define AN7583_TDMA_RST 19 +#define AN7583_EMMC_RST 20 +#define AN7583_SOE_RST 21 +#define AN7583_XFP_MAC_RST 22 +#define AN7583_MDIO0_RST 23 +#define AN7583_MDIO1_RST 24 +/* RST_CTRL1 */ +#define AN7583_PCM1_ZSI_ISI_RST 25 +#define AN7583_FE_PDMA_RST 26 +#define AN7583_FE_QDMA_RST 27 +#define AN7583_PCM_SPIWP_RST 28 +#define AN7583_CRYPTO_RST 29 +#define AN7583_TIMER_RST 30 +#define AN7583_PCM1_RST 31 +#define AN7583_UART_RST 32 +#define AN7583_GPIO_RST 33 +#define AN7583_GDMA_RST 34 +#define AN7583_I2C_MASTER_RST 35 +#define AN7583_PCM2_ZSI_ISI_RST 36 +#define AN7583_SFC_RST 37 +#define AN7583_UART2_RST 38 +#define AN7583_GDMP_RST 39 +#define AN7583_FE_RST 40 +#define AN7583_USB_HOST_P0_RST 41 +#define AN7583_GSW_RST 42 +#define AN7583_SFC2_PCM_RST 43 +#define AN7583_PCIE0_RST 44 +#define AN7583_PCIE1_RST 45 +#define AN7583_CPU_TIMER_RST 46 +#define AN7583_PCIE_HB_RST 47 +#define AN7583_XPON_MAC_RST 48 +/* RST_PCIC */ +#define AN7583_PCIC_PERSTOUT0_RST 49 +#define AN7583_PCIC_PERSTOUT1_RST 50 + +#endif /* __DT_BINDINGS_RESET_CONTROLLER_AIROHA_AN7583_H_ */ -- 2.53.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v6 1/3] dt-bindings: clock: airoha: Document support for AN7583 clock 2026-08-19 22:14 ` [PATCH v6 1/3] dt-bindings: clock: airoha: Document support for " Christian Marangi @ 2026-08-19 22:21 ` sashiko-bot 0 siblings, 0 replies; 8+ messages in thread From: sashiko-bot @ 2026-08-19 22:21 UTC (permalink / raw) To: Christian Marangi; +Cc: conor+dt, devicetree, robh, linux-clk Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: Pre-existing issues: - [Medium] The device tree binding defines the SCU as a reset provider but omits `#reset-cells` from the `required` properties list. -- --- Patch [1]: [PATCH v6 1/3] dt-bindings: clock: airoha: Document support for AN7583 clock --- commit d5f1a3bf6c2e7155e5e00666d8f07ae07a173ed5 Author: Christian Marangi <ansuelsmth@gmail.com> dt-bindings: clock: airoha: Document support for AN7583 clock This commit documents support for the Airoha AN7583 clock, building upon the EN7523 clock schema. It introduces a new requirement for airoha,chip-scu and adds supplementary bindings for additional clock and reset lines. > diff --git a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml > index eb24a5687639e..edecc635807be 100644 > --- a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml > +++ b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml [ ... ] > @@ -50,12 +51,30 @@ properties: > description: ID of the controller reset line > const: 1 > > + airoha,chip-scu: > + $ref: /schemas/types.yaml#/definitions/phandle > + description: phandle to the Chip SCU providing the registers required > + for configuring the PCIe related clocks and resets. > + > required: > - compatible > - reg > - '#clock-cells' [Severity: Medium] This is a pre-existing issue, but since the binding defines the SCU as a reset provider and this patch adds dedicated reset definitions, should #reset-cells be included in this global required list? Without it, device tree nodes using the airoha,an7583-scu compatible string (or other variants in this binding) that omit #reset-cells will incorrectly pass schema validation, potentially allowing incomplete device trees to cause runtime failures in dependent drivers. > > allOf: > + - if: > + properties: > + compatible: > + const: airoha,an7583-scu > + > + then: > + required: > + - airoha,chip-scu [Severity: Medium] This is a pre-existing issue regarding reset providers in this file, but if #reset-cells is not meant to be globally required for all compatibles, should it be added to this conditional required list specifically for airoha,an7583-scu alongside airoha,chip-scu? -- Sashiko AI review · https://sashiko.dev/#/patchset/20260819221458.30040-1-ansuelsmth@gmail.com?part=1 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v6 2/3] clk: en7523: generalize register clocks function 2026-08-19 22:14 [PATCH v6 0/3] clk: add support for Airoha AN7583 clock Christian Marangi 2026-08-19 22:14 ` [PATCH v6 1/3] dt-bindings: clock: airoha: Document support for " Christian Marangi @ 2026-08-19 22:14 ` Christian Marangi 2026-08-19 22:27 ` sashiko-bot 2026-08-19 22:14 ` [PATCH v6 3/3] clk: en7523: add support for Airoha AN7583 clock Christian Marangi 2 siblings, 1 reply; 8+ messages in thread From: Christian Marangi @ 2026-08-19 22:14 UTC (permalink / raw) To: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Philipp Zabel, Felix Fietkau, linux-clk, devicetree, linux-kernel Cc: Christian Marangi Airoha AN7583 SoC will use the same logic used by Airoha EN7581 SoC to register clocks. Generalize it to register clocks defined in soc_data. Add the clocks definition in EN7581 SoC to support this new implementation. Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> --- drivers/clk/clk-en7523.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c index 5c45aacb6409..924e4f3e36b6 100644 --- a/drivers/clk/clk-en7523.c +++ b/drivers/clk/clk-en7523.c @@ -116,6 +116,7 @@ struct en_rst_data { struct en_clk_soc_data { u32 num_clocks; + const struct en_clk_desc *base_clks; const struct clk_ops pcie_ops; int (*hw_init)(struct platform_device *pdev, struct clk_hw_onecell_data *clk_data); @@ -714,12 +715,15 @@ static int en7523_clk_hw_init(struct platform_device *pdev, static void en7581_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data, struct regmap *map, void __iomem *base) { + const struct en_clk_soc_data *soc_data; struct clk_hw *hw; u32 rate; int i; - for (i = 0; i < ARRAY_SIZE(en7581_base_clks); i++) { - const struct en_clk_desc *desc = &en7581_base_clks[i]; + soc_data = device_get_match_data(dev); + + for (i = 0; i < soc_data->num_clocks - 1; i++) { + const struct en_clk_desc *desc = &soc_data->base_clks[i]; u32 val, reg = desc->div_reg ? desc->div_reg : desc->base_reg; int err; @@ -1014,6 +1018,7 @@ static const struct en_clk_soc_data en7523_data = { }; static const struct en_clk_soc_data en7581_data = { + .base_clks = en7581_base_clks, /* We increment num_clocks by 1 to account for additional PCIe clock */ .num_clocks = ARRAY_SIZE(en7581_base_clks) + 1, .pcie_ops = { -- 2.53.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v6 2/3] clk: en7523: generalize register clocks function 2026-08-19 22:14 ` [PATCH v6 2/3] clk: en7523: generalize register clocks function Christian Marangi @ 2026-08-19 22:27 ` sashiko-bot 0 siblings, 0 replies; 8+ messages in thread From: sashiko-bot @ 2026-08-19 22:27 UTC (permalink / raw) To: Christian Marangi; +Cc: linux-clk, devicetree, robh, conor+dt Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider: New issues: - [Medium] Fragile loop boundary logic using `num_clocks - 1` risks out-of-bounds array access. Pre-existing issues: - [High] The PCIe clock gate is registered with an unmanaged API, leading to a Use-After-Free if probe fails. - [High] Missing spinlock in reset controller update leads to data races and lost writes. -- --- Patch [2]: [PATCH v6 2/3] clk: en7523: generalize register clocks function --- commit c89fd9565e1664803408c338e740e001e5bb4ff0 Author: Christian Marangi <ansuelsmth@gmail.com> clk: en7523: generalize register clocks function This commit generalizes the clock registration logic for the EN7581 SoC so it can be reused by the upcoming AN7583 SoC. It achieves this by moving the base clocks array definition into the soc_data structure. > diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c > index 1ab0e2eca5d32..087ff4568124f 100644 > --- a/drivers/clk/clk-en7523.c > +++ b/drivers/clk/clk-en7523.c [ ... ] > @@ -711,12 +712,15 @@ static int en7523_clk_hw_init(struct platform_device *pdev, > static void en7581_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data, > struct regmap *map, void __iomem *base) > { > + const struct en_clk_soc_data *soc_data; > struct clk_hw *hw; > u32 rate; > int i; > > - for (i = 0; i < ARRAY_SIZE(en7581_base_clks); i++) { > - const struct en_clk_desc *desc = &en7581_base_clks[i]; > + soc_data = device_get_match_data(dev); > + > + for (i = 0; i < soc_data->num_clocks - 1; i++) { > + const struct en_clk_desc *desc = &soc_data->base_clks[i]; [Severity: Medium] If a future SoC defines a clock provider count (num_clocks) that doesn't exactly equal the number of elements in base_clks plus one, could this loop iterate past the end of the base_clks array? It seems this loop derives the base_clks array length from soc_data->num_clocks - 1, mathematically conflating the total clock count with the base clock array size. While reviewing this, I noticed a couple of pre-existing issues in the same file: drivers/clk/clk-en7523.c:en7523_register_pcie_clk() { ... cg = devm_kzalloc(dev, sizeof(*cg), GFP_KERNEL); if (!cg) return NULL; ... if (clk_hw_register(dev, &cg->hw)) return NULL; ... } [Severity: High] This is a pre-existing issue, but since the clock gate structure is allocated using devres, won't it be automatically freed if probe fails? Because the clock is registered with the non-managed clk_hw_register() API, if a downstream operation during probe fails, the driver's probe will return an error and trigger devres cleanup. Could this leave a dangling pointer inside the Common Clock Framework and lead to a Use-After-Free? drivers/clk/clk-en7523.c:en7523_reset_update() { ... val = readl(addr); if (assert) val |= BIT(id % RST_NR_PER_BANK); else val &= ~BIT(id % RST_NR_PER_BANK); writel(val, addr); ... } [Severity: High] This isn't a bug introduced by this patch, but is it safe to perform this read-modify-write operation on a shared register without a spinlock? The reset core does not serialize .assert and .deassert operations, so if multiple consumer drivers concurrently assert or deassert resets within the same 32-bit register bank, it seems this unprotected read-modify-write could lead to data races and lost writes. -- Sashiko AI review · https://sashiko.dev/#/patchset/20260819221458.30040-1-ansuelsmth@gmail.com?part=2 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v6 3/3] clk: en7523: add support for Airoha AN7583 clock 2026-08-19 22:14 [PATCH v6 0/3] clk: add support for Airoha AN7583 clock Christian Marangi 2026-08-19 22:14 ` [PATCH v6 1/3] dt-bindings: clock: airoha: Document support for " Christian Marangi 2026-08-19 22:14 ` [PATCH v6 2/3] clk: en7523: generalize register clocks function Christian Marangi @ 2026-08-19 22:14 ` Christian Marangi 2026-08-19 22:27 ` sashiko-bot 2 siblings, 1 reply; 8+ messages in thread From: Christian Marangi @ 2026-08-19 22:14 UTC (permalink / raw) To: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Philipp Zabel, Felix Fietkau, linux-clk, devicetree, linux-kernel Cc: Christian Marangi Add support for Airoha AN7583 clock and reset. Airoha AN7583 SoC have the same register address of EN7581 but implement different bits and additional base clocks. Also reset are different with the introduction of 2 dedicated MDIO line and drop of some reset lines. Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> --- drivers/clk/clk-en7523.c | 241 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 241 insertions(+) diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c index 924e4f3e36b6..f57541ecef84 100644 --- a/drivers/clk/clk-en7523.c +++ b/drivers/clk/clk-en7523.c @@ -10,6 +10,7 @@ #include <linux/regmap.h> #include <linux/reset-controller.h> #include <dt-bindings/clock/en7523-clk.h> +#include <dt-bindings/reset/airoha,an7583-reset.h> #include <dt-bindings/reset/airoha,en7523-reset.h> #include <dt-bindings/reset/airoha,en7581-reset.h> #include <dt-bindings/clock/econet,en751221-scu.h> @@ -135,6 +136,14 @@ static const u32 crypto_base[] = { 540000000, 480000000 }; static const u32 emmc7581_base[] = { 200000000, 150000000 }; /* EN751221 */ static const u32 gsw751221_base[] = { 500000000, 250000000, 400000000, 200000000 }; +/* AN7583 */ +static const u32 gsw7583_base[] = { 540672000, 270336000, 400000000, 200000000 }; +static const u32 emi7583_base[] = { 540672000, 480000000, 400000000, 300000000 }; +static const u32 bus7583_base[] = { 600000000, 540672000, 480000000, 400000000 }; +static const u32 spi7583_base[] = { 400000000, 12500000 }; +static const u32 npu7583_base[] = { 666000000, 800000000, 720000000, 600000000 }; +static const u32 crypto7583_base[] = { 540672000, 400000000 }; +static const u32 emmc7583_base[] = { 150000000, 200000000 }; static const struct en_clk_desc en7523_base_clks[] = { { @@ -337,6 +346,138 @@ static const struct en_clk_desc en7581_base_clks[] = { } }; +static const struct en_clk_desc an7583_base_clks[] = { + { + .id = EN7523_CLK_GSW, + .name = "gsw", + + .base_reg = REG_GSW_CLK_DIV_SEL, + .base_bits = 2, + .base_shift = 8, + .base_values = gsw7583_base, + .n_base_values = ARRAY_SIZE(gsw7583_base), + + .div_bits = 3, + .div_shift = 0, + .div_step = 1, + .div_offset = 1, + }, { + .id = EN7523_CLK_EMI, + .name = "emi", + + .base_reg = REG_EMI_CLK_DIV_SEL, + .base_bits = 2, + .base_shift = 8, + .base_values = emi7583_base, + .n_base_values = ARRAY_SIZE(emi7583_base), + + .div_bits = 3, + .div_shift = 0, + .div_step = 1, + .div_offset = 1, + }, { + .id = EN7523_CLK_BUS, + .name = "bus", + + .base_reg = REG_BUS_CLK_DIV_SEL, + .base_bits = 2, + .base_shift = 8, + .base_values = bus7583_base, + .n_base_values = ARRAY_SIZE(bus7583_base), + + .div_bits = 3, + .div_shift = 0, + .div_step = 1, + .div_offset = 1, + }, { + .id = EN7523_CLK_SLIC, + .name = "slic", + + .base_reg = REG_SPI_CLK_FREQ_SEL, + .base_bits = 1, + .base_shift = 1, + .base_values = slic_base, + .n_base_values = ARRAY_SIZE(slic_base), + + .div_reg = REG_SPI_CLK_DIV_SEL, + .div_bits = 5, + .div_shift = 24, + .div_val0 = 20, + .div_step = 2, + }, { + .id = EN7523_CLK_SPI, + .name = "spi", + + .base_reg = REG_SPI_CLK_FREQ_SEL, + .base_bits = 1, + .base_shift = 0, + .base_values = spi7583_base, + .n_base_values = ARRAY_SIZE(spi7583_base), + + .div_reg = REG_SPI_CLK_DIV_SEL, + .div_bits = 5, + .div_shift = 8, + .div_val0 = 40, + .div_step = 2, + }, { + .id = EN7523_CLK_NPU, + .name = "npu", + + .base_reg = REG_NPU_CLK_DIV_SEL, + .base_bits = 2, + .base_shift = 9, + .base_values = npu7583_base, + .n_base_values = ARRAY_SIZE(npu7583_base), + + .div_bits = 3, + .div_shift = 0, + .div_step = 1, + .div_offset = 1, + }, { + .id = EN7523_CLK_CRYPTO, + .name = "crypto", + + .base_reg = REG_CRYPTO_CLKSRC2, + .base_bits = 1, + .base_shift = 0, + .base_values = crypto7583_base, + .n_base_values = ARRAY_SIZE(crypto7583_base), + }, { + .id = EN7581_CLK_EMMC, + .name = "emmc", + + .base_reg = REG_CRYPTO_CLKSRC2, + .base_bits = 1, + .base_shift = 13, + .base_values = emmc7583_base, + .n_base_values = ARRAY_SIZE(emmc7583_base), + }, { + .id = AN7583_CLK_MDIO0, + .name = "mdio0", + + .base_reg = REG_CRYPTO_CLKSRC2, + + .base_value = 25000000, + + .div_bits = 4, + .div_shift = 15, + .div_step = 1, + .div_offset = 1, + }, { + .id = AN7583_CLK_MDIO1, + .name = "mdio1", + + .base_reg = REG_CRYPTO_CLKSRC2, + + .base_value = 25000000, + + .div_bits = 4, + .div_shift = 19, + .div_step = 1, + .div_offset = 1, + } +}; + static const u16 en7581_rst_ofs[] = { REG_RST_CTRL2, REG_RST_CTRL1, @@ -512,6 +653,64 @@ static const u16 en751221_rst_map[] = { [EN751221_USB_PHY_P1_RST] = 3 * RST_NR_PER_BANK + 7, }; +static const u16 an7583_rst_map[] = { + /* RST_CTRL2 */ + [AN7583_XPON_PHY_RST] = 0, + [AN7583_GPON_OLT_RST] = 1, + [AN7583_CPU_TIMER2_RST] = 2, + [AN7583_HSUART_RST] = 3, + [AN7583_UART4_RST] = 4, + [AN7583_UART5_RST] = 5, + [AN7583_I2C2_RST] = 6, + [AN7583_XSI_MAC_RST] = 7, + [AN7583_XSI_PHY_RST] = 8, + [AN7583_NPU_RST] = 9, + [AN7583_TRNG_MSTART_RST] = 12, + [AN7583_DUAL_HSI0_RST] = 13, + [AN7583_DUAL_HSI1_RST] = 14, + [AN7583_DUAL_HSI0_MAC_RST] = 16, + [AN7583_DUAL_HSI1_MAC_RST] = 17, + [AN7583_XPON_XFI_RST] = 18, + [AN7583_WDMA_RST] = 19, + [AN7583_WOE0_RST] = 20, + [AN7583_HSDMA_RST] = 22, + [AN7583_TDMA_RST] = 24, + [AN7583_EMMC_RST] = 25, + [AN7583_SOE_RST] = 26, + [AN7583_XFP_MAC_RST] = 28, + [AN7583_MDIO0_RST] = 30, + [AN7583_MDIO1_RST] = 31, + /* RST_CTRL1 */ + [AN7583_PCM1_ZSI_ISI_RST] = RST_NR_PER_BANK + 0, + [AN7583_FE_PDMA_RST] = RST_NR_PER_BANK + 1, + [AN7583_FE_QDMA_RST] = RST_NR_PER_BANK + 2, + [AN7583_PCM_SPIWP_RST] = RST_NR_PER_BANK + 4, + [AN7583_CRYPTO_RST] = RST_NR_PER_BANK + 6, + [AN7583_TIMER_RST] = RST_NR_PER_BANK + 8, + [AN7583_PCM1_RST] = RST_NR_PER_BANK + 11, + [AN7583_UART_RST] = RST_NR_PER_BANK + 12, + [AN7583_GPIO_RST] = RST_NR_PER_BANK + 13, + [AN7583_GDMA_RST] = RST_NR_PER_BANK + 14, + [AN7583_I2C_MASTER_RST] = RST_NR_PER_BANK + 16, + [AN7583_PCM2_ZSI_ISI_RST] = RST_NR_PER_BANK + 17, + [AN7583_SFC_RST] = RST_NR_PER_BANK + 18, + [AN7583_UART2_RST] = RST_NR_PER_BANK + 19, + [AN7583_GDMP_RST] = RST_NR_PER_BANK + 20, + [AN7583_FE_RST] = RST_NR_PER_BANK + 21, + [AN7583_USB_HOST_P0_RST] = RST_NR_PER_BANK + 22, + [AN7583_GSW_RST] = RST_NR_PER_BANK + 23, + [AN7583_SFC2_PCM_RST] = RST_NR_PER_BANK + 25, + [AN7583_PCIE0_RST] = RST_NR_PER_BANK + 26, + [AN7583_PCIE1_RST] = RST_NR_PER_BANK + 27, + [AN7583_CPU_TIMER_RST] = RST_NR_PER_BANK + 28, + [AN7583_PCIE_HB_RST] = RST_NR_PER_BANK + 29, + [AN7583_XPON_MAC_RST] = RST_NR_PER_BANK + 31, + + /* RST_PCIC */ + [AN7583_PCIC_PERSTOUT0_RST] = 2 * RST_NR_PER_BANK + 29, + [AN7583_PCIC_PERSTOUT1_RST] = 2 * RST_NR_PER_BANK + 26, +}; + static int en7581_reset_register(struct device *dev, void __iomem *base, const u16 *rst_map, int nr_resets, const u16 *rst_reg_ofs); @@ -885,6 +1084,35 @@ static int en7581_clk_hw_init(struct platform_device *pdev, en7581_rst_ofs); } +static int an7583_clk_hw_init(struct platform_device *pdev, + struct clk_hw_onecell_data *clk_data) +{ + struct device *dev = &pdev->dev; + struct regmap *map; + void __iomem *base; + u32 val; + + map = syscon_regmap_lookup_by_phandle(dev->of_node, "airoha,chip-scu"); + if (IS_ERR(map)) + return PTR_ERR(map); + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + en7581_register_clocks(dev, clk_data, map, base); + + val = readl(base + REG_RST_CTRL1); + val |= REG_PCIE_HB_RST; + writel(val, base + REG_RST_CTRL1); + val &= ~REG_PCIE_HB_RST; + writel(val, base + REG_RST_CTRL1); + + return en7581_reset_register(dev, base, an7583_rst_map, + ARRAY_SIZE(an7583_rst_map), + en7581_rst_ofs); +} + static enum en_hir get_hw_id(void __iomem *np_base) { u32 val = FIELD_GET(REG_HIR_MASK, readl(np_base + REG_HIR)); @@ -1029,6 +1257,18 @@ static const struct en_clk_soc_data en7581_data = { .hw_init = en7581_clk_hw_init, }; +static const struct en_clk_soc_data an7583_data = { + .base_clks = an7583_base_clks, + /* We increment num_clocks by 1 to account for additional PCIe clock */ + .num_clocks = ARRAY_SIZE(an7583_base_clks) + 1, + .pcie_ops = { + .is_enabled = en7581_pci_is_enabled, + .enable = en7581_pci_enable, + .disable = en7581_pci_disable, + }, + .hw_init = an7583_clk_hw_init, +}; + static const struct en_clk_soc_data en751221_data = { .num_clocks = EN751221_MAX_CLKS, .pcie_ops = { @@ -1042,6 +1282,7 @@ static const struct en_clk_soc_data en751221_data = { static const struct of_device_id of_match_clk_en7523[] = { { .compatible = "airoha,en7523-scu", .data = &en7523_data }, { .compatible = "airoha,en7581-scu", .data = &en7581_data }, + { .compatible = "airoha,an7583-scu", .data = &an7583_data }, { .compatible = "econet,en751221-scu", .data = &en751221_data }, { /* sentinel */ } }; -- 2.53.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v6 3/3] clk: en7523: add support for Airoha AN7583 clock 2026-08-19 22:14 ` [PATCH v6 3/3] clk: en7523: add support for Airoha AN7583 clock Christian Marangi @ 2026-08-19 22:27 ` sashiko-bot 2026-08-19 22:32 ` Christian Marangi 0 siblings, 1 reply; 8+ messages in thread From: sashiko-bot @ 2026-08-19 22:27 UTC (permalink / raw) To: Christian Marangi; +Cc: linux-clk, robh, conor+dt, devicetree Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider: New issues: - [Critical] The macro `REG_PCIE_HB_RST` is used but never defined, causing a build failure. - [High] Requesting PCIC resets on AN7583 causes an out-of-bounds read on the `en7581_rst_ofs` array, leading to undefined hardware behavior or memory corruption. Pre-existing issues: - [High] Probe error paths cause a use-after-free by mixing `devm_kzalloc` with non-devres `clk_hw_register()` for the PCIe clock. - [High] Read-modify-write operations on shared registers in the reset and clock controllers lack spinlocks, causing data races and lost writes. - [High] The clock `.disable` callback calls `usleep_range()`, which sleeps while holding an IRQ-disabled spinlock. -- --- Patch [3]: [PATCH v6 3/3] clk: en7523: add support for Airoha AN7583 clock --- commit e4983d60cb386b35f51bc20a5f0912039bf92780 Author: Christian Marangi <ansuelsmth@gmail.com> clk: en7523: add support for Airoha AN7583 clock Add support for Airoha AN7583 clock and reset. Airoha AN7583 SoC have the same register address of EN7581 but implement different bits and additional base clocks. Also reset are different with the introduction of 2 dedicated MDIO line and drop of some reset lines. > diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c > index 087ff4568124f..493812c683f53 100644 > --- a/drivers/clk/clk-en7523.c > +++ b/drivers/clk/clk-en7523.c > @@ -505,6 +646,64 @@ static const u16 en751221_rst_map[] = { > [EN751221_USB_PHY_P1_RST] = 3 * RST_NR_PER_BANK + 7, > }; > > +static const u16 an7583_rst_map[] = { > + /* RST_CTRL2 */ > + [AN7583_XPON_PHY_RST] = 0, > + [AN7583_GPON_OLT_RST] = 1, [ ... ] > + /* RST_PCIC */ > + [AN7583_PCIC_PERSTOUT0_RST] = 2 * RST_NR_PER_BANK + 29, > + [AN7583_PCIC_PERSTOUT1_RST] = 2 * RST_NR_PER_BANK + 26, > +}; [Severity: High] Does this out-of-bounds array access corrupt memory when requesting PCIC resets? The an7583_rst_map defines these PCIC resets in bank index 2. When en7581_reset_register() is called later in this patch, it is passed the en7581_rst_ofs array: static const u16 en7581_rst_ofs[] = { REG_RST_CTRL2, REG_RST_CTRL1, }; Since en7581_rst_ofs only has 2 elements, when en7523_reset_update() dynamically calculates the bank index via id / RST_NR_PER_BANK, it evaluates to 2. Accessing bank_ofs[2] will read out of bounds. [ ... ] > +static int an7583_clk_hw_init(struct platform_device *pdev, > + struct clk_hw_onecell_data *clk_data) > +{ > + struct device *dev = &pdev->dev; > + struct regmap *map; > + void __iomem *base; > + u32 val; > + > + map = syscon_regmap_lookup_by_phandle(dev->of_node, "airoha,chip-scu"); > + if (IS_ERR(map)) > + return PTR_ERR(map); > + > + base = devm_platform_ioremap_resource(pdev, 0); > + if (IS_ERR(base)) > + return PTR_ERR(base); > + > + en7581_register_clocks(dev, clk_data, map, base); [Severity: High] This isn't a bug introduced by this patch, but does the probe error path leave us with a use-after-free for the PCIe clock? In en7523_register_pcie_clk() which is called by en7581_register_clocks(), the clk_hw structure is allocated via devm_kzalloc(), but registered with the non-devres clk_hw_register(): cg = devm_kzalloc(dev, sizeof(*cg), GFP_KERNEL); ... if (clk_hw_register(dev, &cg->hw)) If a subsequent initialization step fails in en7523_clk_probe() (like hw_init returning an error), the driver core automatically frees the memory via devres, but the clock framework retains dangling pointers to the freed clk_hw. > + > + val = readl(base + REG_RST_CTRL1); > + val |= REG_PCIE_HB_RST; [Severity: Critical] Will this break the build due to an undefined macro? The REG_PCIE_HB_RST macro is not defined anywhere. The existing code seems to use REG_RESET_CONTROL_PCIEHB for this bit instead. [Severity: High] This is a pre-existing issue, but could this unlocked read-modify-write race with the reset framework? en7523_pci_prepare() modifies REG_RESET_CONTROL1 (0x834) without any locks: val = readl(np_base + REG_RESET_CONTROL1); mask = REG_RESET_CONTROL_PCIE1 | REG_RESET_CONTROL_PCIE2 | REG_RESET_CONTROL_PCIEHB; writel(val & ~mask, np_base + REG_RESET_CONTROL1); Concurrently, en7523_reset_update() performs an unlocked read-modify-write on the same register (REG_RST_CTRL1 is also 0x834): val = readl(addr); if (assert) val |= BIT(id % RST_NR_PER_BANK); ... writel(val, addr); Since .prepare() runs in process context and resets can be triggered by other probing devices concurrently, this seems likely to cause lost writes. > + writel(val, base + REG_RST_CTRL1); > + val &= ~REG_PCIE_HB_RST; > + writel(val, base + REG_RST_CTRL1); > + > + return en7581_reset_register(dev, base, an7583_rst_map, > + ARRAY_SIZE(an7583_rst_map), > + en7581_rst_ofs); > +} [ ... ] > +static const struct en_clk_soc_data an7583_data = { > + .base_clks = an7583_base_clks, > + /* We increment num_clocks by 1 to account for additional PCIe clock */ > + .num_clocks = ARRAY_SIZE(an7583_base_clks) + 1, > + .pcie_ops = { > + .is_enabled = en7581_pci_is_enabled, > + .enable = en7581_pci_enable, > + .disable = en7581_pci_disable, > + }, [Severity: High] This isn't a bug introduced by this patch, but does mapping en7581_pci_disable to the .disable callback result in sleeping while in an atomic context? The core clock framework invokes .disable callbacks with the enable_lock spinlock held and hardware interrupts disabled. However, en7581_pci_disable() explicitly yields and sleeps: writel(val & ~mask, np_base + REG_PCI_CONTROL); usleep_range(1000, 2000); Could this cause a scheduling while atomic panic when the PCIe clock is disabled? > + .hw_init = an7583_clk_hw_init, > +}; -- Sashiko AI review · https://sashiko.dev/#/patchset/20260819221458.30040-1-ansuelsmth@gmail.com?part=3 ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v6 3/3] clk: en7523: add support for Airoha AN7583 clock 2026-08-19 22:27 ` sashiko-bot @ 2026-08-19 22:32 ` Christian Marangi 0 siblings, 0 replies; 8+ messages in thread From: Christian Marangi @ 2026-08-19 22:32 UTC (permalink / raw) To: sashiko-reviews; +Cc: linux-clk, robh, conor+dt, devicetree On Wed, Aug 19, 2026 at 10:27:42PM +0000, sashiko-bot@kernel.org wrote: > Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider: > > New issues: > - [Critical] The macro `REG_PCIE_HB_RST` is used but never defined, causing a build failure. > - [High] Requesting PCIC resets on AN7583 causes an out-of-bounds read on the `en7581_rst_ofs` array, leading to undefined hardware behavior or memory corruption. > For reference, it seems the bot applied the patch to the wrong branch. The reported problems from the bot are not valid as those changes were introduced by the last 2 patch present in linux-next and clk-next. Code was compiled and tested with those 2 changes included. > Pre-existing issues: > - [High] Probe error paths cause a use-after-free by mixing `devm_kzalloc` with non-devres `clk_hw_register()` for the PCIe clock. > - [High] Read-modify-write operations on shared registers in the reset and clock controllers lack spinlocks, causing data races and lost writes. > - [High] The clock `.disable` callback calls `usleep_range()`, which sleeps while holding an IRQ-disabled spinlock. > -- > > --- Patch [3]: [PATCH v6 3/3] clk: en7523: add support for Airoha AN7583 clock --- > commit e4983d60cb386b35f51bc20a5f0912039bf92780 > Author: Christian Marangi <ansuelsmth@gmail.com> > > clk: en7523: add support for Airoha AN7583 clock > > Add support for Airoha AN7583 clock and reset. > > Airoha AN7583 SoC have the same register address of EN7581 but implement > different bits and additional base clocks. Also reset are different with > the introduction of 2 dedicated MDIO line and drop of some reset lines. > > > diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c > > index 087ff4568124f..493812c683f53 100644 > > --- a/drivers/clk/clk-en7523.c > > +++ b/drivers/clk/clk-en7523.c > > @@ -505,6 +646,64 @@ static const u16 en751221_rst_map[] = { > > [EN751221_USB_PHY_P1_RST] = 3 * RST_NR_PER_BANK + 7, > > }; > > > > +static const u16 an7583_rst_map[] = { > > + /* RST_CTRL2 */ > > + [AN7583_XPON_PHY_RST] = 0, > > + [AN7583_GPON_OLT_RST] = 1, > [ ... ] > > + /* RST_PCIC */ > > + [AN7583_PCIC_PERSTOUT0_RST] = 2 * RST_NR_PER_BANK + 29, > > + [AN7583_PCIC_PERSTOUT1_RST] = 2 * RST_NR_PER_BANK + 26, > > +}; > > [Severity: High] > Does this out-of-bounds array access corrupt memory when requesting PCIC resets? > > The an7583_rst_map defines these PCIC resets in bank index 2. > > When en7581_reset_register() is called later in this patch, it is passed > the en7581_rst_ofs array: > > static const u16 en7581_rst_ofs[] = { > REG_RST_CTRL2, > REG_RST_CTRL1, > }; > > Since en7581_rst_ofs only has 2 elements, when en7523_reset_update() > dynamically calculates the bank index via id / RST_NR_PER_BANK, it evaluates > to 2. Accessing bank_ofs[2] will read out of bounds. > > [ ... ] > > +static int an7583_clk_hw_init(struct platform_device *pdev, > > + struct clk_hw_onecell_data *clk_data) > > +{ > > + struct device *dev = &pdev->dev; > > + struct regmap *map; > > + void __iomem *base; > > + u32 val; > > + > > + map = syscon_regmap_lookup_by_phandle(dev->of_node, "airoha,chip-scu"); > > + if (IS_ERR(map)) > > + return PTR_ERR(map); > > + > > + base = devm_platform_ioremap_resource(pdev, 0); > > + if (IS_ERR(base)) > > + return PTR_ERR(base); > > + > > + en7581_register_clocks(dev, clk_data, map, base); > > [Severity: High] > This isn't a bug introduced by this patch, but does the probe error path leave > us with a use-after-free for the PCIe clock? > > In en7523_register_pcie_clk() which is called by en7581_register_clocks(), > the clk_hw structure is allocated via devm_kzalloc(), but registered with the > non-devres clk_hw_register(): > > cg = devm_kzalloc(dev, sizeof(*cg), GFP_KERNEL); > ... > if (clk_hw_register(dev, &cg->hw)) > > If a subsequent initialization step fails in en7523_clk_probe() (like hw_init > returning an error), the driver core automatically frees the memory via devres, > but the clock framework retains dangling pointers to the freed clk_hw. > > > + > > + val = readl(base + REG_RST_CTRL1); > > + val |= REG_PCIE_HB_RST; > > [Severity: Critical] > Will this break the build due to an undefined macro? > > The REG_PCIE_HB_RST macro is not defined anywhere. The existing code seems > to use REG_RESET_CONTROL_PCIEHB for this bit instead. > > [Severity: High] > This is a pre-existing issue, but could this unlocked read-modify-write race > with the reset framework? > > en7523_pci_prepare() modifies REG_RESET_CONTROL1 (0x834) without any locks: > > val = readl(np_base + REG_RESET_CONTROL1); > mask = REG_RESET_CONTROL_PCIE1 | REG_RESET_CONTROL_PCIE2 | > REG_RESET_CONTROL_PCIEHB; > writel(val & ~mask, np_base + REG_RESET_CONTROL1); > > Concurrently, en7523_reset_update() performs an unlocked read-modify-write > on the same register (REG_RST_CTRL1 is also 0x834): > > val = readl(addr); > if (assert) > val |= BIT(id % RST_NR_PER_BANK); > ... > writel(val, addr); > > Since .prepare() runs in process context and resets can be triggered by > other probing devices concurrently, this seems likely to cause lost writes. > > > + writel(val, base + REG_RST_CTRL1); > > + val &= ~REG_PCIE_HB_RST; > > + writel(val, base + REG_RST_CTRL1); > > + > > + return en7581_reset_register(dev, base, an7583_rst_map, > > + ARRAY_SIZE(an7583_rst_map), > > + en7581_rst_ofs); > > +} > [ ... ] > > +static const struct en_clk_soc_data an7583_data = { > > + .base_clks = an7583_base_clks, > > + /* We increment num_clocks by 1 to account for additional PCIe clock */ > > + .num_clocks = ARRAY_SIZE(an7583_base_clks) + 1, > > + .pcie_ops = { > > + .is_enabled = en7581_pci_is_enabled, > > + .enable = en7581_pci_enable, > > + .disable = en7581_pci_disable, > > + }, > > [Severity: High] > This isn't a bug introduced by this patch, but does mapping en7581_pci_disable > to the .disable callback result in sleeping while in an atomic context? > > The core clock framework invokes .disable callbacks with the enable_lock > spinlock held and hardware interrupts disabled. > > However, en7581_pci_disable() explicitly yields and sleeps: > > writel(val & ~mask, np_base + REG_PCI_CONTROL); > usleep_range(1000, 2000); > > Could this cause a scheduling while atomic panic when the PCIe clock is > disabled? > > > + .hw_init = an7583_clk_hw_init, > > +}; > > -- > Sashiko AI review · https://sashiko.dev/#/patchset/20260819221458.30040-1-ansuelsmth@gmail.com?part=3 -- Ansuel ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-08-19 22:32 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-08-19 22:14 [PATCH v6 0/3] clk: add support for Airoha AN7583 clock Christian Marangi 2026-08-19 22:14 ` [PATCH v6 1/3] dt-bindings: clock: airoha: Document support for " Christian Marangi 2026-08-19 22:21 ` sashiko-bot 2026-08-19 22:14 ` [PATCH v6 2/3] clk: en7523: generalize register clocks function Christian Marangi 2026-08-19 22:27 ` sashiko-bot 2026-08-19 22:14 ` [PATCH v6 3/3] clk: en7523: add support for Airoha AN7583 clock Christian Marangi 2026-08-19 22:27 ` sashiko-bot 2026-08-19 22:32 ` Christian Marangi
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox