* [PATCH 1/4] dt-bindings: clock: airoha: Add additional reset for PCIe PERSTOUT
2026-06-25 21:57 [PATCH 0/4] PCI: mediatek-gen3: Add 2-lanes mode support + clock Christian Marangi
@ 2026-06-25 21:57 ` Christian Marangi
2026-06-25 22:07 ` sashiko-bot
2026-06-26 10:58 ` Krzysztof Kozlowski
2026-06-25 21:57 ` [PATCH 2/4] clk: en7523: add support for dedicated PCIe PERSTOUT reset Christian Marangi
` (2 subsequent siblings)
3 siblings, 2 replies; 10+ messages in thread
From: Christian Marangi @ 2026-06-25 21:57 UTC (permalink / raw)
To: Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Rob Herring, Bjorn Helgaas,
Krzysztof Kozlowski, Conor Dooley, Ryder Lee, Michael Turquette,
Stephen Boyd, Brian Masney, Philipp Zabel, Matthias Brugger,
AngeloGioacchino Del Regno, Christian Marangi, Jianjun Wang,
linux-pci, devicetree, linux-kernel, linux-mediatek, linux-clk,
linux-arm-kernel
Add additional reset to control PCIe PERSTOUT reset line for each of the 3
PCIe lines.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
include/dt-bindings/reset/airoha,en7581-reset.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/include/dt-bindings/reset/airoha,en7581-reset.h b/include/dt-bindings/reset/airoha,en7581-reset.h
index 6544a1790b83..25e75534daa9 100644
--- a/include/dt-bindings/reset/airoha,en7581-reset.h
+++ b/include/dt-bindings/reset/airoha,en7581-reset.h
@@ -62,5 +62,9 @@
#define EN7581_CPU_TIMER_RST 50
#define EN7581_PCIE_HB_RST 51
#define EN7581_XPON_MAC_RST 52
+/* RST_PCIC */
+#define EN7581_PCIC_PERSTOUT0_RST 53
+#define EN7581_PCIC_PERSTOUT1_RST 54
+#define EN7581_PCIC_PERSTOUT2_RST 55
#endif /* __DT_BINDINGS_RESET_CONTROLLER_AIROHA_EN7581_H_ */
--
2.53.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH 1/4] dt-bindings: clock: airoha: Add additional reset for PCIe PERSTOUT
2026-06-25 21:57 ` [PATCH 1/4] dt-bindings: clock: airoha: Add additional reset for PCIe PERSTOUT Christian Marangi
@ 2026-06-25 22:07 ` sashiko-bot
2026-06-26 10:58 ` Krzysztof Kozlowski
1 sibling, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-06-25 22:07 UTC (permalink / raw)
To: Christian Marangi; +Cc: conor+dt, linux-pci, robh, devicetree
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Data race between direct MMIO and regmap accesses on the SCU_PCIC register.
--
commit 900fc8364d6744e062fdb68cdff6066cb3ba875d
Author: Christian Marangi <ansuelsmth@gmail.com>
dt-bindings: clock: airoha: Add additional reset for PCIe PERSTOUT
Add additional reset to control PCIe PERSTOUT reset line for each of the 3
PCIe lines.
> diff --git a/include/dt-bindings/reset/airoha,en7581-reset.h b/include/dt-bindings/reset/airoha,en7581-reset.h
> --- a/include/dt-bindings/reset/airoha,en7581-reset.h
> +++ b/include/dt-bindings/reset/airoha,en7581-reset.h
[ ... ]
> @@ -62,5 +62,9 @@
> #define EN7581_CPU_TIMER_RST 50
> #define EN7581_PCIE_HB_RST 51
> #define EN7581_XPON_MAC_RST 52
> +/* RST_PCIC */
> +#define EN7581_PCIC_PERSTOUT0_RST 53
> +#define EN7581_PCIC_PERSTOUT1_RST 54
> +#define EN7581_PCIC_PERSTOUT2_RST 55
[Severity: High]
Will adding these resets expose a data race between the reset controller and
the PCIe controller during link bring-up?
When these resets are asserted, en7523_reset_update() in clk-en7523.c
performs an unlocked direct MMIO read-modify-write on the SCU_PCIC register:
drivers/clk/clk-en7523.c:en7523_reset_update() {
...
val = readl(addr);
val &= ~BIT(id % RST_NR_PER_BANK);
...
writel(val, addr);
}
At the same time, mtk_pcie_en7581_power_up() in pcie-mediatek-gen3.c
modifies the same SCU_PCIC register using a regmap:
drivers/pci/controller/pcie-mediatek-gen3.c:mtk_pcie_en7581_power_up() {
...
regmap_update_bits(pcie->scu, SCU_PCIC, SCU_PCIC_PCIE_CTRL,
FIELD_PREP(SCU_PCIC_PCIE_CTRL, BIT(1)));
}
Since the regmap internal lock does not protect against direct MMIO accesses
from clk-en7523.c, could concurrent operations (like one port triggering a
reset while another powers up) silently corrupt the SCU_PCIC hardware
register state and cause PCIe links to fail?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260625215741.3253212-1-ansuelsmth@gmail.com?part=1
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH 1/4] dt-bindings: clock: airoha: Add additional reset for PCIe PERSTOUT
2026-06-25 21:57 ` [PATCH 1/4] dt-bindings: clock: airoha: Add additional reset for PCIe PERSTOUT Christian Marangi
2026-06-25 22:07 ` sashiko-bot
@ 2026-06-26 10:58 ` Krzysztof Kozlowski
1 sibling, 0 replies; 10+ messages in thread
From: Krzysztof Kozlowski @ 2026-06-26 10:58 UTC (permalink / raw)
To: Christian Marangi
Cc: Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Rob Herring, Bjorn Helgaas,
Krzysztof Kozlowski, Conor Dooley, Ryder Lee, Michael Turquette,
Stephen Boyd, Brian Masney, Philipp Zabel, Matthias Brugger,
AngeloGioacchino Del Regno, Jianjun Wang, linux-pci, devicetree,
linux-kernel, linux-mediatek, linux-clk, linux-arm-kernel
On Thu, Jun 25, 2026 at 11:57:34PM +0200, Christian Marangi wrote:
> Add additional reset to control PCIe PERSTOUT reset line for each of the 3
> PCIe lines.
>
> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> ---
> include/dt-bindings/reset/airoha,en7581-reset.h | 4 ++++
> 1 file changed, 4 insertions(+)
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 2/4] clk: en7523: add support for dedicated PCIe PERSTOUT reset
2026-06-25 21:57 [PATCH 0/4] PCI: mediatek-gen3: Add 2-lanes mode support + clock Christian Marangi
2026-06-25 21:57 ` [PATCH 1/4] dt-bindings: clock: airoha: Add additional reset for PCIe PERSTOUT Christian Marangi
@ 2026-06-25 21:57 ` Christian Marangi
2026-06-26 0:20 ` sashiko-bot
2026-06-25 21:57 ` [PATCH 3/4] dt-bindings: PCI: mediatek-gen3: Split Airoha schema and document 2-lanes Christian Marangi
2026-06-25 21:57 ` [PATCH 4/4] PCI: mediatek-gen3: Add 2-lanes mode support for Airoha AN7581 Christian Marangi
3 siblings, 1 reply; 10+ messages in thread
From: Christian Marangi @ 2026-06-25 21:57 UTC (permalink / raw)
To: Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Rob Herring, Bjorn Helgaas,
Krzysztof Kozlowski, Conor Dooley, Ryder Lee, Michael Turquette,
Stephen Boyd, Brian Masney, Philipp Zabel, Matthias Brugger,
AngeloGioacchino Del Regno, Christian Marangi, Jianjun Wang,
linux-pci, devicetree, linux-kernel, linux-mediatek, linux-clk,
linux-arm-kernel
Add support for resetting the PCIe lines with the PERSTOUT reset. These
special reset are controlled by the PCIC register and are specific to each
of the 3 PCIe lines.
Notice that reset logic is inverted for these bit where 0 is assert and 1
deassert. This is intenrally handled in the reset function.
PCI enable/disable are updated to drop PERSTOUT bits in favor dedicated
reset handling.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/clk/clk-en7523.c | 27 ++++++++++++++++++---------
1 file changed, 18 insertions(+), 9 deletions(-)
diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c
index 1ab0e2eca5d3..a33cf2e1b76f 100644
--- a/drivers/clk/clk-en7523.c
+++ b/drivers/clk/clk-en7523.c
@@ -338,6 +338,7 @@ static const struct en_clk_desc en7581_base_clks[] = {
static const u16 en7581_rst_ofs[] = {
REG_RST_CTRL2,
REG_RST_CTRL1,
+ REG_NP_SCU_PCIC,
};
static const u16 en751221_rst_ofs[] = {
@@ -450,6 +451,11 @@ static const u16 en7581_rst_map[] = {
[EN7581_CPU_TIMER_RST] = RST_NR_PER_BANK + 28,
[EN7581_PCIE_HB_RST] = RST_NR_PER_BANK + 29,
[EN7581_XPON_MAC_RST] = RST_NR_PER_BANK + 31,
+
+ /* RST_PCIC */
+ [EN7581_PCIC_PERSTOUT0_RST] = 2 * RST_NR_PER_BANK + 29,
+ [EN7581_PCIC_PERSTOUT1_RST] = 2 * RST_NR_PER_BANK + 26,
+ [EN7581_PCIC_PERSTOUT2_RST] = 2 * RST_NR_PER_BANK + 16,
};
static const u16 en751221_rst_map[] = {
@@ -635,9 +641,7 @@ static int en7581_pci_enable(struct clk_hw *hw)
void __iomem *np_base = cg->base;
u32 val, mask;
- mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 |
- REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT2 |
- REG_PCI_CONTROL_PERSTOUT;
+ mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1;
val = readl(np_base + REG_PCI_CONTROL);
writel(val | mask, np_base + REG_PCI_CONTROL);
@@ -650,9 +654,7 @@ static void en7581_pci_disable(struct clk_hw *hw)
void __iomem *np_base = cg->base;
u32 val, mask;
- mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 |
- REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT2 |
- REG_PCI_CONTROL_PERSTOUT;
+ mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1;
val = readl(np_base + REG_PCI_CONTROL);
writel(val & ~mask, np_base + REG_PCI_CONTROL);
usleep_range(1000, 2000);
@@ -754,14 +756,21 @@ static int en7523_reset_update(struct reset_controller_dev *rcdev,
unsigned long id, bool assert)
{
struct en_rst_data *rst_data = container_of(rcdev, struct en_rst_data, rcdev);
- void __iomem *addr = rst_data->base + rst_data->bank_ofs[id / RST_NR_PER_BANK];
+ u32 offset = rst_data->bank_ofs[id / RST_NR_PER_BANK];
+ void __iomem *addr = rst_data->base + offset;
+ bool inverted = false;
u32 val;
+ /* For PCIC reset logic is inverted, 0:assert 1:deassert*/
+ if (offset == REG_NP_SCU_PCIC)
+ inverted = true;
+
val = readl(addr);
+ val &= ~BIT(id % RST_NR_PER_BANK);
if (assert)
- val |= BIT(id % RST_NR_PER_BANK);
+ val |= inverted ? 0 : BIT(id % RST_NR_PER_BANK);
else
- val &= ~BIT(id % RST_NR_PER_BANK);
+ val |= inverted ? BIT(id % RST_NR_PER_BANK) : 0;
writel(val, addr);
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH 2/4] clk: en7523: add support for dedicated PCIe PERSTOUT reset
2026-06-25 21:57 ` [PATCH 2/4] clk: en7523: add support for dedicated PCIe PERSTOUT reset Christian Marangi
@ 2026-06-26 0:20 ` sashiko-bot
0 siblings, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-06-26 0:20 UTC (permalink / raw)
To: Christian Marangi; +Cc: robh, conor+dt, linux-pci, devicetree
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
New issues:
- [High] Data race between clock enable/disable and reset assert/deassert on the shared PCIC register (0x88).
- [Medium] The reset status callback does not account for inverted reset logic, reporting incorrect status for PCIC resets.
Pre-existing issues:
- [High] Missing synchronization in the reset controller allows concurrent reset operations to corrupt shared reset registers.
- [High] The `en7581_pci_disable` function calls `usleep_range()`, sleeping in an atomic context.
--
commit 82bdae998b98b49b0cf96f540c945b593f30a899
Author: Christian Marangi <ansuelsmth@gmail.com>
clk: en7523: add support for dedicated PCIe PERSTOUT reset
Add support for resetting the PCIe lines with the PERSTOUT reset. These
special reset are controlled by the PCIC register and are specific to each
of the 3 PCIe lines.
Notice that reset logic is inverted for these bit where 0 is assert and 1
deassert. This is intenrally handled in the reset function.
PCI enable/disable are updated to drop PERSTOUT bits in favor dedicated
reset handling.
> diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c
> index 1ab0e2eca5d32..a33cf2e1b76f8 100644
> --- a/drivers/clk/clk-en7523.c
> +++ b/drivers/clk/clk-en7523.c
[ ... ]
> @@ -650,9 +654,7 @@ static void en7581_pci_disable(struct clk_hw *hw)
> void __iomem *np_base = cg->base;
> u32 val, mask;
>
> - mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 |
> - REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT2 |
> - REG_PCI_CONTROL_PERSTOUT;
> + mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1;
> val = readl(np_base + REG_PCI_CONTROL);
> writel(val & ~mask, np_base + REG_PCI_CONTROL);
> usleep_range(1000, 2000);
[Severity: High]
This is a pre-existing issue, but the Common Clock Framework calls the
.disable callback with the enable_lock spinlock held and hardware interrupts
disabled.
Does calling usleep_range() here sleep in an atomic context and lead to a bug?
[ ... ]
> @@ -754,14 +756,21 @@ static int en7523_reset_update(struct reset_controller_dev *rcdev,
> unsigned long id, bool assert)
> {
> struct en_rst_data *rst_data = container_of(rcdev, struct en_rst_data, rcdev);
> - void __iomem *addr = rst_data->base + rst_data->bank_ofs[id / RST_NR_PER_BANK];
> + u32 offset = rst_data->bank_ofs[id / RST_NR_PER_BANK];
> + void __iomem *addr = rst_data->base + offset;
> + bool inverted = false;
> u32 val;
>
> + /* For PCIC reset logic is inverted, 0:assert 1:deassert*/
> + if (offset == REG_NP_SCU_PCIC)
> + inverted = true;
[Severity: Medium]
It appears en7523_reset_status() wasn't updated to handle the inverted logic:
drivers/clk/clk-en7523.c:en7523_reset_status() {
...
return !!(readl(addr) & BIT(id % RST_NR_PER_BANK));
}
Will callers of reset_control_status() receive incorrect status for these
resets, returning 0 for asserted and 1 for deasserted when querying PCIC
resets?
> +
> val = readl(addr);
> + val &= ~BIT(id % RST_NR_PER_BANK);
> if (assert)
> - val |= BIT(id % RST_NR_PER_BANK);
> + val |= inverted ? 0 : BIT(id % RST_NR_PER_BANK);
> else
> - val &= ~BIT(id % RST_NR_PER_BANK);
> + val |= inverted ? BIT(id % RST_NR_PER_BANK) : 0;
> writel(val, addr);
[Severity: High]
This is a pre-existing issue, but multiple drivers could concurrently probe or
change power states, causing their reset operations on the same register bank
to interleave.
Could this lockless read-modify-write operation allow concurrent reset
operations to corrupt the shared reset registers?
[Severity: High]
en7581_pci_enable() modifies REG_PCI_CONTROL using a lockless
read-modify-write:
drivers/clk/clk-en7523.c:en7581_pci_enable() {
...
val = readl(np_base + REG_PCI_CONTROL);
writel(val | mask, np_base + REG_PCI_CONTROL);
...
}
If REG_NP_SCU_PCIC and REG_PCI_CONTROL point to the same register, a
concurrent clk_enable() and reset_control_assert() could silently corrupt
each other's bits since they belong to different lock domains.
Will this read-modify-write race with the clock framework?
>
> return 0;
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260625215741.3253212-1-ansuelsmth@gmail.com?part=2
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 3/4] dt-bindings: PCI: mediatek-gen3: Split Airoha schema and document 2-lanes
2026-06-25 21:57 [PATCH 0/4] PCI: mediatek-gen3: Add 2-lanes mode support + clock Christian Marangi
2026-06-25 21:57 ` [PATCH 1/4] dt-bindings: clock: airoha: Add additional reset for PCIe PERSTOUT Christian Marangi
2026-06-25 21:57 ` [PATCH 2/4] clk: en7523: add support for dedicated PCIe PERSTOUT reset Christian Marangi
@ 2026-06-25 21:57 ` Christian Marangi
2026-06-25 22:04 ` sashiko-bot
2026-06-25 21:57 ` [PATCH 4/4] PCI: mediatek-gen3: Add 2-lanes mode support for Airoha AN7581 Christian Marangi
3 siblings, 1 reply; 10+ messages in thread
From: Christian Marangi @ 2026-06-25 21:57 UTC (permalink / raw)
To: Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Rob Herring, Bjorn Helgaas,
Krzysztof Kozlowski, Conor Dooley, Ryder Lee, Michael Turquette,
Stephen Boyd, Brian Masney, Philipp Zabel, Matthias Brugger,
AngeloGioacchino Del Regno, Christian Marangi, Jianjun Wang,
linux-pci, devicetree, linux-kernel, linux-mediatek, linux-clk,
linux-arm-kernel
To permit proper documentation of required property to support PCIe
configured for 2-lanes mode, split the Airoha schema part from the
mediatek-gen3 schema to a dedicated schema.
A PCIe configured for 2-lanes mode require an additional reg for the
secondary PCIe to be configured and the airoha,scu phandle to correctly
configure the PCIe MUX.
Rework the mediatek-gen3 schema to drop any redundant constraint previsouly
introduced for Airoha PCIe properties.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
.../bindings/pci/airoha,en7581-pcie.yaml | 251 ++++++++++++++++++
.../bindings/pci/mediatek-pcie-gen3.yaml | 77 +-----
2 files changed, 256 insertions(+), 72 deletions(-)
create mode 100644 Documentation/devicetree/bindings/pci/airoha,en7581-pcie.yaml
diff --git a/Documentation/devicetree/bindings/pci/airoha,en7581-pcie.yaml b/Documentation/devicetree/bindings/pci/airoha,en7581-pcie.yaml
new file mode 100644
index 000000000000..977c1816572c
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/airoha,en7581-pcie.yaml
@@ -0,0 +1,251 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/airoha,en7581-pcie.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Gen3 PCIe controller on Airoha SoCs
+
+maintainers:
+ - Christian Marangi <ansuelsmth@gmail.com>
+
+description: |+
+ PCIe Gen3 MAC controller for Airoha SoCs, it supports Gen3 speed
+ and compatible with Gen2, Gen1 speed.
+
+ This PCIe controller supports up to 256 MSI vectors, the MSI hardware
+ block diagram is as follows:
+
+ +-----+
+ | GIC |
+ +-----+
+ ^
+ |
+ port->irq
+ |
+ +-+-+-+-+-+-+-+-+
+ |0|1|2|3|4|5|6|7| (PCIe intc)
+ +-+-+-+-+-+-+-+-+
+ ^ ^ ^
+ | | ... |
+ +-------+ +------+ +-----------+
+ | | |
+ +-+-+---+--+--+ +-+-+---+--+--+ +-+-+---+--+--+
+ |0|1|...|30|31| |0|1|...|30|31| |0|1|...|30|31| (MSI sets)
+ +-+-+---+--+--+ +-+-+---+--+--+ +-+-+---+--+--+
+ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
+ | | | | | | | | | | | | (MSI vectors)
+ | | | | | | | | | | | |
+
+ (MSI SET0) (MSI SET1) ... (MSI SET7)
+
+ With 256 MSI vectors supported, the MSI vectors are composed of 8 sets,
+ each set has its own address for MSI message, and supports 32 MSI vectors
+ to generate interrupt.
+
+properties:
+ compatible:
+ const: airoha,en7581-pcie
+
+ reg:
+ minItems: 1
+ maxItems: 2
+
+ reg-names:
+ minItems: 1
+ maxItems: 2
+
+ interrupts:
+ maxItems: 1
+
+ ranges:
+ minItems: 1
+ maxItems: 8
+
+ iommu-map:
+ maxItems: 1
+
+ iommu-map-mask:
+ const: 0
+
+ resets:
+ minItems: 1
+ maxItems: 4
+
+ reset-names:
+ minItems: 1
+ maxItems: 4
+
+ clocks:
+ maxItems: 1
+
+ clock-names:
+ items:
+ - const: sys-ck
+
+ phys:
+ maxItems: 1
+
+ phy-names:
+ items:
+ - const: pcie-phy
+
+ num-lanes:
+ enum: [1, 2]
+
+ mediatek,pbus-csr:
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ items:
+ - items:
+ - description: phandle to pbus-csr syscon
+ - description: offset of pbus-csr base address register
+ - description: offset of pbus-csr base address mask register
+ description:
+ Phandle with two arguments to the syscon node used to detect if
+ a given address is accessible on PCIe controller.
+
+ airoha,scu:
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ items:
+ - items:
+ - description: phandle to airoha SCU syscon
+ description:
+ Phandle to SCU syscon to configure PCIe MUX for 2 lines support.
+
+ '#interrupt-cells':
+ const: 1
+
+ interrupt-controller:
+ description: Interrupt controller node for handling legacy PCI interrupts.
+ type: object
+ properties:
+ '#address-cells':
+ const: 0
+ '#interrupt-cells':
+ const: 1
+ interrupt-controller: true
+
+ required:
+ - '#address-cells'
+ - '#interrupt-cells'
+ - interrupt-controller
+
+ additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - reg-names
+ - interrupts
+ - ranges
+ - clocks
+ - clock-names
+ - '#interrupt-cells'
+ - interrupt-controller
+
+allOf:
+ - $ref: /schemas/pci/pci-host-bridge.yaml#
+ - if:
+ properties:
+ num-lanes:
+ const: 2
+ then:
+ properties:
+ regs:
+ minItems: 2
+
+ reg-names:
+ items:
+ - const: pcie-mac
+ - const: sec-pcie-mac
+
+ resets:
+ minItems: 4
+
+ reset-names:
+ items:
+ - const: phy-lane0
+ - const: phy-lane1
+ - const: perstout
+ - const: sec-perstout
+
+ required:
+ - airoha,scu
+
+ else:
+ properties:
+ reg:
+ maxItems: 1
+
+ reg-names:
+ items:
+ - const: pcie-mac
+
+ resets:
+ minItems: 2
+ maxItems: 3
+
+ reset-names:
+ minItems: 2
+ items:
+ - enum: [ phy-lane0, phy-lane1, phy-lan2 ]
+ - enum: [ phy-lane1, perstout ]
+ - const: phy-lane2
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ bus {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ pcie@1fc00000 {
+ compatible = "airoha,en7581-pcie";
+ device_type = "pci";
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ reg = <0x0 0x1fc00000 0x0 0x1670>,
+ <0x0 0x1fc20000 0x0 0x1670>;
+ reg-names = "pcie-mac", "sec-pcie-mac";
+
+ clocks = <&scuclk 7>;
+ clock-names = "sys-ck";
+
+ phys = <&pciephy>;
+ phy-names = "pcie-phy";
+
+ ranges = <0x02000000 0 0x20000000 0x0 0x20000000 0 0x4000000>;
+
+ resets = <&scuclk 48>,
+ <&scuclk 49>,
+ <&scuclk 53>,
+ <&scuclk 54>;
+ reset-names = "phy-lane0", "phy-lane1",
+ "perstout", "sec-perstout";
+
+ num-lanes = <2>;
+
+ mediatek,pbus-csr = <&pbus_csr 0x0 0x4>;
+
+ airoha,scu = <&scuclk>;
+
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+ bus-range = <0x00 0xff>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0x7>;
+ interrupt-map = <0 0 0 1 &pcie_intc 0>,
+ <0 0 0 2 &pcie_intc 1>,
+ <0 0 0 3 &pcie_intc 2>,
+ <0 0 0 4 &pcie_intc 3>;
+ pcie_intc: interrupt-controller {
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml b/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml
index 4db700fc36ba..510f1f2b1c5a 100644
--- a/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml
+++ b/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml
@@ -59,7 +59,6 @@ properties:
- const: mediatek,mt8196-pcie
- const: mediatek,mt8192-pcie
- const: mediatek,mt8196-pcie
- - const: airoha,en7581-pcie
reg:
maxItems: 1
@@ -83,20 +82,20 @@ properties:
resets:
minItems: 1
- maxItems: 3
+ maxItems: 2
reset-names:
minItems: 1
- maxItems: 3
+ maxItems: 2
items:
- enum: [ phy, mac, phy-lane0, phy-lane1, phy-lane2 ]
+ enum: [ phy, mac ]
clocks:
- minItems: 1
+ minItems: 4
maxItems: 6
clock-names:
- minItems: 1
+ minItems: 4
maxItems: 6
assigned-clocks:
@@ -115,17 +114,6 @@ properties:
power-domains:
maxItems: 1
- mediatek,pbus-csr:
- $ref: /schemas/types.yaml#/definitions/phandle-array
- items:
- - items:
- - description: phandle to pbus-csr syscon
- - description: offset of pbus-csr base address register
- - description: offset of pbus-csr base address mask register
- description:
- Phandle with two arguments to the syscon node used to detect if
- a given address is accessible on PCIe controller.
-
'#interrupt-cells':
const: 1
@@ -177,16 +165,6 @@ allOf:
- const: peri_26m
- const: top_133m
- resets:
- minItems: 1
- maxItems: 2
-
- reset-names:
- minItems: 1
- maxItems: 2
-
- mediatek,pbus-csr: false
-
- if:
properties:
compatible:
@@ -208,16 +186,6 @@ allOf:
- const: peri_26m
- const: peri_mem
- resets:
- minItems: 1
- maxItems: 2
-
- reset-names:
- minItems: 1
- maxItems: 2
-
- mediatek,pbus-csr: false
-
- if:
properties:
compatible:
@@ -246,8 +214,6 @@ allOf:
- const: phy
- const: mac
- mediatek,pbus-csr: false
-
- if:
properties:
compatible:
@@ -257,7 +223,6 @@ allOf:
then:
properties:
clocks:
- minItems: 4
maxItems: 4
clock-names:
@@ -267,38 +232,6 @@ allOf:
- const: peri_26m
- const: top_133m
- resets:
- minItems: 1
- maxItems: 2
-
- reset-names:
- minItems: 1
- maxItems: 2
-
- mediatek,pbus-csr: false
-
- - if:
- properties:
- compatible:
- const: airoha,en7581-pcie
- then:
- properties:
- clocks:
- maxItems: 1
-
- clock-names:
- items:
- - const: sys-ck
-
- resets:
- minItems: 3
-
- reset-names:
- items:
- - const: phy-lane0
- - const: phy-lane1
- - const: phy-lane2
-
unevaluatedProperties: false
examples:
--
2.53.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH 3/4] dt-bindings: PCI: mediatek-gen3: Split Airoha schema and document 2-lanes
2026-06-25 21:57 ` [PATCH 3/4] dt-bindings: PCI: mediatek-gen3: Split Airoha schema and document 2-lanes Christian Marangi
@ 2026-06-25 22:04 ` sashiko-bot
0 siblings, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-06-25 22:04 UTC (permalink / raw)
To: Christian Marangi; +Cc: devicetree, robh, conor+dt, linux-pci
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] The schema incorrectly uses `regs` instead of `reg` in the `allOf` conditional block for `num-lanes == 2`, failing to enforce the requirement for a secondary register region.
- [Medium] Typographical error `phy-lan2` instead of `phy-lane2` in the `reset-names` enum constraint for the 1-lane fallback block.
--
commit bb5683e00f2f10ba9133fc862deba2acbfb939ed
Author: Christian Marangi <ansuelsmth@gmail.com>
dt-bindings: PCI: mediatek-gen3: Split Airoha schema and document 2-lanes
This commit splits the Airoha PCIe schema from the mediatek-gen3 schema into
a dedicated file. This allows documenting the required properties for PCIe
configured in 2-lanes mode, while cleaning up the mediatek-gen3 schema.
> diff --git a/Documentation/devicetree/bindings/pci/airoha,en7581-pcie.yaml b/Documentation/devicetree/bindings/pci/airoha,en7581-pcie.yaml
> new file mode 100644
> index 0000000000000..977c1816572cc
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/airoha,en7581-pcie.yaml
[ ... ]
> +allOf:
> + - $ref: /schemas/pci/pci-host-bridge.yaml#
> + - if:
> + properties:
> + num-lanes:
> + const: 2
> + then:
> + properties:
> + regs:
> + minItems: 2
[Severity: Medium]
Does this schema enforce the minItems constraint as intended? It looks like
there's a typo where "regs" is used instead of "reg". This might allow a
node with num-lanes = <2> but only a single register region to silently pass
validation.
> +
> + reg-names:
> + items:
> + - const: pcie-mac
> + - const: sec-pcie-mac
[ ... ]
> + else:
> + properties:
> + reg:
> + maxItems: 1
> +
> + reg-names:
> + items:
> + - const: pcie-mac
> +
> + resets:
> + minItems: 2
> + maxItems: 3
> +
> + reset-names:
> + minItems: 2
> + items:
> + - enum: [ phy-lane0, phy-lane1, phy-lan2 ]
[Severity: Medium]
Will this properly validate phy-lane2? It appears there is a typo here
(phy-lan2 instead of phy-lane2) which would cause valid configurations
to fail schema validation while accepting the misspelled name.
> + - enum: [ phy-lane1, perstout ]
> + - const: phy-lane2
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260625215741.3253212-1-ansuelsmth@gmail.com?part=3
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 4/4] PCI: mediatek-gen3: Add 2-lanes mode support for Airoha AN7581
2026-06-25 21:57 [PATCH 0/4] PCI: mediatek-gen3: Add 2-lanes mode support + clock Christian Marangi
` (2 preceding siblings ...)
2026-06-25 21:57 ` [PATCH 3/4] dt-bindings: PCI: mediatek-gen3: Split Airoha schema and document 2-lanes Christian Marangi
@ 2026-06-25 21:57 ` Christian Marangi
2026-06-25 22:07 ` sashiko-bot
3 siblings, 1 reply; 10+ messages in thread
From: Christian Marangi @ 2026-06-25 21:57 UTC (permalink / raw)
To: Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Rob Herring, Bjorn Helgaas,
Krzysztof Kozlowski, Conor Dooley, Ryder Lee, Michael Turquette,
Stephen Boyd, Brian Masney, Philipp Zabel, Matthias Brugger,
AngeloGioacchino Del Regno, Christian Marangi, Jianjun Wang,
linux-pci, devicetree, linux-kernel, linux-mediatek, linux-clk,
linux-arm-kernel
The Airoha AN7581 SoC supports configuring the first PCIe0 line to 2-lanes
mode by bonding it with the second PCIe line. This is done by configuring
the PCIe MUX in the SCU register.
To correctly configure the line for 2-lanes mode, it's required to define
in DT an additional reg, 'sec-pcie-mac' for the secondary PCIe.
It's also needed to define the additional reset and the PERSTOUT reset.
Also 'airoha,scu' property is mandatory to correctly configure the SCU
register for the PCIe MUX.
Finally to toggle 2-lanes mode, it's needed to define in DT 'num-lanes' as
2.
In such configuration the EQ preset are configured to the same values.
To permit correct configuration of the PCIe line, additional logic is added
to assert and deassert the PERSTOUT resets.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/pci/controller/pcie-mediatek-gen3.c | 98 +++++++++++++++++----
1 file changed, 80 insertions(+), 18 deletions(-)
diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c
index b0accd828589..f750759bbc1d 100644
--- a/drivers/pci/controller/pcie-mediatek-gen3.c
+++ b/drivers/pci/controller/pcie-mediatek-gen3.c
@@ -32,6 +32,11 @@
#include "../pci.h"
+/* AN7581 SCU register */
+#define SCU_PCIC 0x88
+#define SCU_PCIC_PCIE_CTRL GENMASK(7, 0)
+
+/* PCIe register */
#define PCIE_BASE_CFG_REG 0x14
#define PCIE_BASE_CFG_SPEED GENMASK(15, 8)
@@ -131,6 +136,7 @@
#define PCIE_ATR_TLP_TYPE_IO PCIE_ATR_TLP_TYPE(2)
#define MAX_NUM_PHY_RESETS 3
+#define MAX_NUM_PERSTOUT_RESETS 2
#define PCIE_MTK_RESET_TIME_US 10
@@ -203,9 +209,11 @@ struct mtk_msi_set {
struct mtk_gen3_pcie {
struct device *dev;
void __iomem *base;
+ void __iomem *sec_base;
phys_addr_t reg_base;
struct reset_control *mac_reset;
struct reset_control_bulk_data phy_resets[MAX_NUM_PHY_RESETS];
+ struct reset_control_bulk_data perstout_resets[MAX_NUM_PERSTOUT_RESETS];
struct phy *phy;
struct clk_bulk_data *clks;
int num_clks;
@@ -222,6 +230,9 @@ struct mtk_gen3_pcie {
DECLARE_BITMAP(msi_irq_in_use, PCIE_MSI_IRQS_NUM);
const struct mtk_gen3_pcie_pdata *soc;
+
+ /* AN7581 specific */
+ struct regmap *scu;
};
/* LTSSM state in PCIE_LTSSM_STATUS_REG bit[28:24] */
@@ -928,6 +939,14 @@ static int mtk_pcie_parse_port(struct mtk_gen3_pcie *pcie)
if (ret)
return dev_err_probe(dev, ret, "failed to get PHY bulk reset\n");
+ pcie->perstout_resets[0].id = "perstout";
+ pcie->perstout_resets[1].id = "sec-perstout";
+
+ ret = devm_reset_control_bulk_get_optional_exclusive(dev, MAX_NUM_PERSTOUT_RESETS,
+ pcie->perstout_resets);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to get PERSTOUT bulk reset\n");
+
pcie->mac_reset = devm_reset_control_get_optional_exclusive(dev, "mac");
if (IS_ERR(pcie->mac_reset))
return dev_err_probe(dev, PTR_ERR(pcie->mac_reset), "failed to get MAC reset\n");
@@ -955,12 +974,29 @@ static int mtk_pcie_parse_port(struct mtk_gen3_pcie *pcie)
static int mtk_pcie_en7581_power_up(struct mtk_gen3_pcie *pcie)
{
struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
+ unsigned int num_lanes = max(1, pcie->num_lanes);
struct device *dev = pcie->dev;
struct resource_entry *entry;
struct regmap *pbus_regmap;
u32 val, args[2], size;
resource_size_t addr;
- int err;
+ int i, err;
+
+ if (num_lanes == 2) {
+ struct platform_device *pdev = to_platform_device(dev);
+ struct resource *regs;
+
+ regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sec-pcie-mac");
+ if (!regs)
+ return -EINVAL;
+ pcie->sec_base = devm_ioremap_resource(dev, regs);
+ if (IS_ERR(pcie->sec_base))
+ return dev_err_probe(dev, PTR_ERR(pcie->sec_base), "failed to map secondary register base\n");
+
+ pcie->scu = syscon_regmap_lookup_by_phandle(dev->of_node, "airoha,scu");
+ if (IS_ERR(pcie->scu))
+ return dev_err_probe(dev, PTR_ERR(pcie->scu), "failed to map SCU regmap\n");
+ }
/*
* The controller may have been left out of reset by the bootloader
@@ -1024,34 +1060,60 @@ static int mtk_pcie_en7581_power_up(struct mtk_gen3_pcie *pcie)
pm_runtime_enable(dev);
pm_runtime_get_sync(dev);
- val = FIELD_PREP(PCIE_VAL_LN0_DOWNSTREAM, 0x47) |
- FIELD_PREP(PCIE_VAL_LN1_DOWNSTREAM, 0x47) |
- FIELD_PREP(PCIE_VAL_LN0_UPSTREAM, 0x41) |
- FIELD_PREP(PCIE_VAL_LN1_UPSTREAM, 0x41);
- writel_relaxed(val, pcie->base + PCIE_EQ_PRESET_01_REG);
+ /* Assert PERSTOUT for all relevant lines */
+ err = reset_control_bulk_assert(MAX_NUM_PERSTOUT_RESETS,
+ pcie->perstout_resets);
+ if (err) {
+ dev_err(dev, "failed to assert PERSTOUTs\n");
+ goto err_perstout_assert;
+ }
+
+ /* Configure SCU MUX to disable PCIE1 for 2 lines mode */
+ if (num_lanes == 2)
+ regmap_update_bits(pcie->scu, SCU_PCIC, SCU_PCIC_PCIE_CTRL,
+ FIELD_PREP(SCU_PCIC_PCIE_CTRL, BIT(1)));
- val = PCIE_K_PHYPARAM_QUERY | PCIE_K_QUERY_TIMEOUT |
- FIELD_PREP(PCIE_K_PRESET_TO_USE_16G, 0x80) |
- FIELD_PREP(PCIE_K_PRESET_TO_USE, 0x2) |
- FIELD_PREP(PCIE_K_FINETUNE_MAX, 0xf);
- writel_relaxed(val, pcie->base + PCIE_PIPE4_PIE8_REG);
err = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks);
if (err) {
dev_err(dev, "failed to prepare clock\n");
- goto err_clk_prepare_enable;
+ goto err_perstout_assert;
}
- /*
- * Airoha EN7581 performs PCIe reset via clk callbacks since it has a
- * hw issue with PCIE_PE_RSTB signal. Add wait for the time needed to
- * complete the PCIe reset.
- */
+ /* Wait for refclk to stabilize */
msleep(PCIE_T_PVPERL_MS);
+ /* Configure all the lines to the same EQ config */
+ for (i = 0; i < num_lanes; i++) {
+ void __iomem *base = pcie->base;
+
+ if (i == 1)
+ base = pcie->sec_base;
+
+ val = FIELD_PREP(PCIE_VAL_LN0_DOWNSTREAM, 0x47) |
+ FIELD_PREP(PCIE_VAL_LN1_DOWNSTREAM, 0x47) |
+ FIELD_PREP(PCIE_VAL_LN0_UPSTREAM, 0x41) |
+ FIELD_PREP(PCIE_VAL_LN1_UPSTREAM, 0x41);
+ writel_relaxed(val, base + PCIE_EQ_PRESET_01_REG);
+
+ val = PCIE_K_PHYPARAM_QUERY | PCIE_K_QUERY_TIMEOUT |
+ FIELD_PREP(PCIE_K_PRESET_TO_USE_16G, 0x80) |
+ FIELD_PREP(PCIE_K_PRESET_TO_USE, 0x2) |
+ FIELD_PREP(PCIE_K_FINETUNE_MAX, 0xf);
+ writel_relaxed(val, base + PCIE_PIPE4_PIE8_REG);
+ }
+
+ /* Deassert PERSTOUT for all relevant lines */
+ err = reset_control_bulk_deassert(MAX_NUM_PERSTOUT_RESETS,
+ pcie->perstout_resets);
+ if (err) {
+ dev_err(dev, "failed to deassert PERSTOUTs\n");
+ goto err_perstout_assert;
+ }
+
return 0;
-err_clk_prepare_enable:
+err_perstout_assert:
pm_runtime_put_sync(dev);
pm_runtime_disable(dev);
reset_control_bulk_assert(pcie->soc->phy_resets.num_resets,
--
2.53.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH 4/4] PCI: mediatek-gen3: Add 2-lanes mode support for Airoha AN7581
2026-06-25 21:57 ` [PATCH 4/4] PCI: mediatek-gen3: Add 2-lanes mode support for Airoha AN7581 Christian Marangi
@ 2026-06-25 22:07 ` sashiko-bot
0 siblings, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-06-25 22:07 UTC (permalink / raw)
To: Christian Marangi; +Cc: linux-pci, conor+dt, robh, devicetree
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
New issues:
- [High] Calling devm_ioremap_resource() inside the .power_up() callback breaks system resume with -EBUSY.
- [High] Unvalidated num_lanes > 2 causes a NULL pointer dereference in the hardware configuration loop.
- [High] Missing clock disable on error path in mtk_pcie_en7581_power_up().
Pre-existing issues:
- [High] The return value of pm_runtime_get_sync() is ignored, leading to hardware access on suspended devices.
--
commit c4659641288856a22fb57ae4fe5c48d43375cff0
Author: Christian Marangi <ansuelsmth@gmail.com>
PCI: mediatek-gen3: Add 2-lanes mode support for Airoha AN7581
This commit adds 2-lanes mode support for the Airoha AN7581 SoC by
configuring the PCIe MUX in the SCU register. It introduces secondary PCIe
MAC memory mapping, SCU regmap parsing, and additional PERSTOUT reset logic.
> diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c
> index b0accd8285892..f750759bbc1d8 100644
> --- a/drivers/pci/controller/pcie-mediatek-gen3.c
> +++ b/drivers/pci/controller/pcie-mediatek-gen3.c
[ ... ]
> @@ -955,12 +974,29 @@ static int mtk_pcie_parse_port(struct mtk_gen3_pcie *pcie)
> static int mtk_pcie_en7581_power_up(struct mtk_gen3_pcie *pcie)
> {
> struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
> + unsigned int num_lanes = max(1, pcie->num_lanes);
> struct device *dev = pcie->dev;
> struct resource_entry *entry;
> struct regmap *pbus_regmap;
> u32 val, args[2], size;
> resource_size_t addr;
> - int err;
> + int i, err;
> +
> + if (num_lanes == 2) {
> + struct platform_device *pdev = to_platform_device(dev);
> + struct resource *regs;
> +
> + regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sec-pcie-mac");
> + if (!regs)
> + return -EINVAL;
> + pcie->sec_base = devm_ioremap_resource(dev, regs);
[Severity: High]
Since mtk_pcie_en7581_power_up() is assigned as the .power_up callback and
executes during both probe and resume_noirq(), won't calling
devm_ioremap_resource() here cause a conflict on system resume?
The devm-managed resources persist across suspend/resume cycles, so
devm_request_mem_region() will detect a conflict and cause
devm_ioremap_resource() to return -EBUSY. Could this mapping be moved
to the probe path, such as mtk_pcie_parse_port(), to avoid resume failures?
> + if (IS_ERR(pcie->sec_base))
> + return dev_err_probe(dev, PTR_ERR(pcie->sec_base), "failed to map secondary register base\n");
[ ... ]
> @@ -1024,34 +1060,60 @@ static int mtk_pcie_en7581_power_up(struct mtk_gen3_pcie *pcie)
> pm_runtime_enable(dev);
> pm_runtime_get_sync(dev);
[Severity: High]
This is a pre-existing issue, but should the return value
of pm_runtime_get_sync() be checked?
If the device power domain fails to transition to an active state,
pm_runtime_get_sync() will return a negative error code. Proceeding to access
registers on suspended hardware could trigger a synchronous external abort or
system crash.
> - val = FIELD_PREP(PCIE_VAL_LN0_DOWNSTREAM, 0x47) |
> - FIELD_PREP(PCIE_VAL_LN1_DOWNSTREAM, 0x47) |
> - FIELD_PREP(PCIE_VAL_LN0_UPSTREAM, 0x41) |
> - FIELD_PREP(PCIE_VAL_LN1_UPSTREAM, 0x41);
> - writel_relaxed(val, pcie->base + PCIE_EQ_PRESET_01_REG);
[ ... ]
> + /* Wait for refclk to stabilize */
> msleep(PCIE_T_PVPERL_MS);
>
> + /* Configure all the lines to the same EQ config */
> + for (i = 0; i < num_lanes; i++) {
> + void __iomem *base = pcie->base;
> +
> + if (i == 1)
> + base = pcie->sec_base;
> +
> + val = FIELD_PREP(PCIE_VAL_LN0_DOWNSTREAM, 0x47) |
> + FIELD_PREP(PCIE_VAL_LN1_DOWNSTREAM, 0x47) |
> + FIELD_PREP(PCIE_VAL_LN0_UPSTREAM, 0x41) |
> + FIELD_PREP(PCIE_VAL_LN1_UPSTREAM, 0x41);
> + writel_relaxed(val, base + PCIE_EQ_PRESET_01_REG);
[Severity: High]
If the Device Tree specifies a valid num-lanes value greater than 2 (e.g.,
4 or 8), will this loop dereference a NULL pointer?
Earlier in this function, pcie->sec_base is exclusively mapped when
num_lanes == 2. If num_lanes is greater than 2, pcie->sec_base remains NULL.
When i == 1, base becomes NULL, and writel_relaxed() will panic. Should
there be explicit bounds validation before writing to sec_base?
> + val = PCIE_K_PHYPARAM_QUERY | PCIE_K_QUERY_TIMEOUT |
> + FIELD_PREP(PCIE_K_PRESET_TO_USE_16G, 0x80) |
> + FIELD_PREP(PCIE_K_PRESET_TO_USE, 0x2) |
> + FIELD_PREP(PCIE_K_FINETUNE_MAX, 0xf);
> + writel_relaxed(val, base + PCIE_PIPE4_PIE8_REG);
> + }
> +
> + /* Deassert PERSTOUT for all relevant lines */
> + err = reset_control_bulk_deassert(MAX_NUM_PERSTOUT_RESETS,
> + pcie->perstout_resets);
> + if (err) {
> + dev_err(dev, "failed to deassert PERSTOUTs\n");
> + goto err_perstout_assert;
> + }
> +
> return 0;
>
> -err_clk_prepare_enable:
> +err_perstout_assert:
> pm_runtime_put_sync(dev);
> pm_runtime_disable(dev);
[Severity: High]
If reset_control_bulk_deassert() fails, won't jumping to this label leak
the clock prepare/enable references?
The function successfully enables clocks earlier with
clk_bulk_prepare_enable(), but err_perstout_assert entirely omits calling
clk_bulk_disable_unprepare(), which will leave the hardware clocks
permanently running.
> reset_control_bulk_assert(pcie->soc->phy_resets.num_resets,
> pcie->phy_resets);
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260625215741.3253212-1-ansuelsmth@gmail.com?part=4
^ permalink raw reply [flat|nested] 10+ messages in thread