* [PATCH] PCI: dwc: Make Link Up IRQ logic handle already powered on PCIe switches
@ 2025-11-27 13:43 Niklas Cassel
2025-11-28 1:06 ` Shawn Lin
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Niklas Cassel @ 2025-11-27 13:43 UTC (permalink / raw)
To: Jingoo Han, Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas,
Heiko Stuebner, Niklas Cassel
Cc: FUKAUMI Naoki, linux-pci, linux-arm-kernel, linux-rockchip,
linux-arm-msm
The DWC glue drivers always call pci_host_probe() during probe(), which
will allocate upstream bridge resources and enumerate the bus.
For controllers without Link Up IRQ support, pci_host_probe() is called
after dw_pcie_wait_for_link(), which will also wait the time required by
the PCIe specification before performing PCI Configuration Space reads.
For controllers with Link Up IRQ support, the pci_host_probe() call (which
will perform PCI Configuration Space reads) is done without any of the
delays mandated by the PCIe specification.
For controllers with Link Up IRQ support, since the pci_host_probe() call
is done without any delay (link training might still be ongoing), it is
very unlikely that this scan will find any devices. Once the Link Up IRQ
triggers, the Link Up IRQ handler will call pci_rescan_bus().
This works fine for PCIe endpoints connected to the Root Port, since they
don't extend the bus. However, if the pci_rescan_bus() call detects a PCIe
switch, then there will be a problem when the downstream busses starts
showing up, because the PCIe controller is not hotplug capable, so we are
not allowed to extend the subordinate bus number after the initial scan,
resulting in error messages such as:
pci_bus 0004:43: busn_res: can not insert [bus 43-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci_bus 0004:43: busn_res: [bus 43-41] end is updated to 43
pci_bus 0004:43: busn_res: can not insert [bus 43] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci 0004:42:00.0: devices behind bridge are unusable because [bus 43] cannot be assigned for them
pci_bus 0004:44: busn_res: can not insert [bus 44-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci_bus 0004:44: busn_res: [bus 44-41] end is updated to 44
pci_bus 0004:44: busn_res: can not insert [bus 44] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci 0004:42:02.0: devices behind bridge are unusable because [bus 44] cannot be assigned for them
pci_bus 0004:45: busn_res: can not insert [bus 45-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci_bus 0004:45: busn_res: [bus 45-41] end is updated to 45
pci_bus 0004:45: busn_res: can not insert [bus 45] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci 0004:42:06.0: devices behind bridge are unusable because [bus 45] cannot be assigned for them
pci_bus 0004:46: busn_res: can not insert [bus 46-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci_bus 0004:46: busn_res: [bus 46-41] end is updated to 46
pci_bus 0004:46: busn_res: can not insert [bus 46] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci 0004:42:0e.0: devices behind bridge are unusable because [bus 46] cannot be assigned for them
pci_bus 0004:42: busn_res: [bus 42-41] end is updated to 46
pci_bus 0004:42: busn_res: can not insert [bus 42-46] under [bus 41] (conflicts with (null) [bus 41])
pci 0004:41:00.0: devices behind bridge are unusable because [bus 42-46] cannot be assigned for them
pcieport 0004:40:00.0: bridge has subordinate 41 but max busn 46
While we would like to set the is_hotplug_bridge flag
(quirk_hotplug_bridge()), many embedded SoCs that use the DWC controller
have synthesized the controller without hot-plug support.
Thus, the Link Up IRQ logic is only mimicking hot-plug functionality, i.e.
it is not compliant with the PCI Hot-Plug Specification, so we cannot make
use of the is_hotplug_bridge flag.
In order to let the Link Up IRQ logic handle PCIe switches that are already
powered on (PCIe switches that not powered on already need to implement a
pwrctrl driver), don't perform a pci_host_probe() call during probe()
(which disregards the delays required by the PCIe specification).
Instead let the first Link Up IRQ call pci_host_probe(). Any follow up
Link Up IRQ will call pci_rescan_bus().
Fixes: ec9fd499b9c6 ("PCI: dw-rockchip: Don't wait for link since we can detect Link Up")
Fixes: 0e0b45ab5d77 ("PCI: dw-rockchip: Enumerate endpoints based on dll_link_up IRQ")
Reported-by: FUKAUMI Naoki <naoki@radxa.com>
Closes: https://lore.kernel.org/linux-pci/1E8E4DB773970CB5+5a52c9e1-01b8-4872-99b7-021099f04031@radxa.com/
Signed-off-by: Niklas Cassel <cassel@kernel.org>
---
.../pci/controller/dwc/pcie-designware-host.c | 70 ++++++++++++++++---
drivers/pci/controller/dwc/pcie-designware.h | 5 ++
drivers/pci/controller/dwc/pcie-dw-rockchip.c | 5 +-
drivers/pci/controller/dwc/pcie-qcom.c | 5 +-
4 files changed, 68 insertions(+), 17 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index e92513c5bda51..8654346729574 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -565,6 +565,59 @@ static int dw_pcie_host_get_resources(struct dw_pcie_rp *pp)
return 0;
}
+static int dw_pcie_host_initial_scan(struct dw_pcie_rp *pp)
+{
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+ struct pci_host_bridge *bridge = pp->bridge;
+ int ret;
+
+ ret = pci_host_probe(bridge);
+ if (ret)
+ return ret;
+
+ if (pp->ops->post_init)
+ pp->ops->post_init(pp);
+
+ dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
+
+ return 0;
+}
+
+void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp)
+{
+ if (!pp->initial_linkup_irq_done) {
+ int ret;
+
+ ret = dw_pcie_host_initial_scan(pp);
+ if (ret) {
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+ struct device *dev = pci->dev;
+
+ dev_err(dev, "Initial scan from IRQ failed: %d\n", ret);
+
+ dw_pcie_stop_link(pci);
+
+ dw_pcie_edma_remove(pci);
+
+ if (pp->has_msi_ctrl)
+ dw_pcie_free_msi(pp);
+
+ if (pp->ops->deinit)
+ pp->ops->deinit(pp);
+
+ if (pp->cfg)
+ pci_ecam_free(pp->cfg);
+ } else {
+ pp->initial_linkup_irq_done = true;
+ }
+ } else {
+ /* Rescan the bus to enumerate endpoint devices */
+ pci_lock_rescan_remove();
+ pci_rescan_bus(pp->bridge->bus);
+ pci_unlock_rescan_remove();
+ }
+}
+
int dw_pcie_host_init(struct dw_pcie_rp *pp)
{
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
@@ -669,18 +722,17 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
* If there is no Link Up IRQ, we should not bypass the delay
* because that would require users to manually rescan for devices.
*/
- if (!pp->use_linkup_irq)
+ if (!pp->use_linkup_irq) {
/* Ignore errors, the link may come up later */
dw_pcie_wait_for_link(pci);
- ret = pci_host_probe(bridge);
- if (ret)
- goto err_stop_link;
-
- if (pp->ops->post_init)
- pp->ops->post_init(pp);
-
- dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
+ /*
+ * For platforms with Link Up IRQ, initial scan will be done
+ * on first Link Up IRQ.
+ */
+ if (dw_pcie_host_initial_scan(pp))
+ goto err_stop_link;
+ }
return 0;
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index e995f692a1ecd..a31bd93490dcd 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -427,6 +427,7 @@ struct dw_pcie_rp {
int msg_atu_index;
struct resource *msg_res;
bool use_linkup_irq;
+ bool initial_linkup_irq_done;
struct pci_eq_presets presets;
struct pci_config_window *cfg;
bool ecam_enabled;
@@ -807,6 +808,7 @@ void dw_pcie_msi_init(struct dw_pcie_rp *pp);
int dw_pcie_msi_host_init(struct dw_pcie_rp *pp);
void dw_pcie_free_msi(struct dw_pcie_rp *pp);
int dw_pcie_setup_rc(struct dw_pcie_rp *pp);
+void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp);
int dw_pcie_host_init(struct dw_pcie_rp *pp);
void dw_pcie_host_deinit(struct dw_pcie_rp *pp);
int dw_pcie_allocate_domains(struct dw_pcie_rp *pp);
@@ -844,6 +846,9 @@ static inline int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
return 0;
}
+static inline void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp)
+{ }
+
static inline int dw_pcie_host_init(struct dw_pcie_rp *pp)
{
return 0;
diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
index 3e2752c7dd096..8f2cc1ef25e3d 100644
--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
+++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
@@ -466,10 +466,7 @@ static irqreturn_t rockchip_pcie_rc_sys_irq_thread(int irq, void *arg)
if (rockchip_pcie_link_up(pci)) {
msleep(PCIE_RESET_CONFIG_WAIT_MS);
dev_dbg(dev, "Received Link up event. Starting enumeration!\n");
- /* Rescan the bus to enumerate endpoint devices */
- pci_lock_rescan_remove();
- pci_rescan_bus(pp->bridge->bus);
- pci_unlock_rescan_remove();
+ dw_pcie_handle_link_up_irq(pp);
}
}
diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index c48a20602d7fa..2d8aca6630949 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -1617,10 +1617,7 @@ static irqreturn_t qcom_pcie_global_irq_thread(int irq, void *data)
if (FIELD_GET(PARF_INT_ALL_LINK_UP, status)) {
msleep(PCIE_RESET_CONFIG_WAIT_MS);
dev_dbg(dev, "Received Link up event. Starting enumeration!\n");
- /* Rescan the bus to enumerate endpoint devices */
- pci_lock_rescan_remove();
- pci_rescan_bus(pp->bridge->bus);
- pci_unlock_rescan_remove();
+ dw_pcie_handle_link_up_irq(pp);
qcom_pcie_icc_opp_update(pcie);
} else {
--
2.52.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] PCI: dwc: Make Link Up IRQ logic handle already powered on PCIe switches
2025-11-27 13:43 [PATCH] PCI: dwc: Make Link Up IRQ logic handle already powered on PCIe switches Niklas Cassel
@ 2025-11-28 1:06 ` Shawn Lin
2025-11-28 6:55 ` FUKAUMI Naoki
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Shawn Lin @ 2025-11-28 1:06 UTC (permalink / raw)
To: Niklas Cassel, Jingoo Han, Manivannan Sadhasivam,
Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring,
Bjorn Helgaas, Heiko Stuebner
Cc: shawn.lin, FUKAUMI Naoki, linux-pci, linux-arm-kernel,
linux-rockchip, linux-arm-msm
在 2025/11/27 星期四 21:43, Niklas Cassel 写道:
> The DWC glue drivers always call pci_host_probe() during probe(), which
> will allocate upstream bridge resources and enumerate the bus.
>
> For controllers without Link Up IRQ support, pci_host_probe() is called
> after dw_pcie_wait_for_link(), which will also wait the time required by
> the PCIe specification before performing PCI Configuration Space reads.
>
> For controllers with Link Up IRQ support, the pci_host_probe() call (which
> will perform PCI Configuration Space reads) is done without any of the
> delays mandated by the PCIe specification.
>
> For controllers with Link Up IRQ support, since the pci_host_probe() call
> is done without any delay (link training might still be ongoing), it is
> very unlikely that this scan will find any devices. Once the Link Up IRQ
> triggers, the Link Up IRQ handler will call pci_rescan_bus().
>
> This works fine for PCIe endpoints connected to the Root Port, since they
> don't extend the bus. However, if the pci_rescan_bus() call detects a PCIe
> switch, then there will be a problem when the downstream busses starts
> showing up, because the PCIe controller is not hotplug capable, so we are
> not allowed to extend the subordinate bus number after the initial scan,
> resulting in error messages such as:
>
> pci_bus 0004:43: busn_res: can not insert [bus 43-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:43: busn_res: [bus 43-41] end is updated to 43
> pci_bus 0004:43: busn_res: can not insert [bus 43] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:00.0: devices behind bridge are unusable because [bus 43] cannot be assigned for them
> pci_bus 0004:44: busn_res: can not insert [bus 44-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:44: busn_res: [bus 44-41] end is updated to 44
> pci_bus 0004:44: busn_res: can not insert [bus 44] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:02.0: devices behind bridge are unusable because [bus 44] cannot be assigned for them
> pci_bus 0004:45: busn_res: can not insert [bus 45-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:45: busn_res: [bus 45-41] end is updated to 45
> pci_bus 0004:45: busn_res: can not insert [bus 45] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:06.0: devices behind bridge are unusable because [bus 45] cannot be assigned for them
> pci_bus 0004:46: busn_res: can not insert [bus 46-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:46: busn_res: [bus 46-41] end is updated to 46
> pci_bus 0004:46: busn_res: can not insert [bus 46] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:0e.0: devices behind bridge are unusable because [bus 46] cannot be assigned for them
> pci_bus 0004:42: busn_res: [bus 42-41] end is updated to 46
> pci_bus 0004:42: busn_res: can not insert [bus 42-46] under [bus 41] (conflicts with (null) [bus 41])
> pci 0004:41:00.0: devices behind bridge are unusable because [bus 42-46] cannot be assigned for them
> pcieport 0004:40:00.0: bridge has subordinate 41 but max busn 46
>
> While we would like to set the is_hotplug_bridge flag
> (quirk_hotplug_bridge()), many embedded SoCs that use the DWC controller
> have synthesized the controller without hot-plug support.
> Thus, the Link Up IRQ logic is only mimicking hot-plug functionality, i.e.
> it is not compliant with the PCI Hot-Plug Specification, so we cannot make
> use of the is_hotplug_bridge flag.
>
> In order to let the Link Up IRQ logic handle PCIe switches that are already
> powered on (PCIe switches that not powered on already need to implement a
> pwrctrl driver), don't perform a pci_host_probe() call during probe()
> (which disregards the delays required by the PCIe specification).
>
> Instead let the first Link Up IRQ call pci_host_probe(). Any follow up
> Link Up IRQ will call pci_rescan_bus().
>
Thanks for fixing this, I'v tested it on RK3588S-EVB1 with both of PCIe
switch + 2 NVMe and NVMe directly connected.
FWIW,
Tested-by: Shawn Lin <shawn.lin@rock-chips.com>
> Fixes: ec9fd499b9c6 ("PCI: dw-rockchip: Don't wait for link since we can detect Link Up")
> Fixes: 0e0b45ab5d77 ("PCI: dw-rockchip: Enumerate endpoints based on dll_link_up IRQ")
> Reported-by: FUKAUMI Naoki <naoki@radxa.com>
> Closes: https://lore.kernel.org/linux-pci/1E8E4DB773970CB5+5a52c9e1-01b8-4872-99b7-021099f04031@radxa.com/
> Signed-off-by: Niklas Cassel <cassel@kernel.org>
> ---
> .../pci/controller/dwc/pcie-designware-host.c | 70 ++++++++++++++++---
> drivers/pci/controller/dwc/pcie-designware.h | 5 ++
> drivers/pci/controller/dwc/pcie-dw-rockchip.c | 5 +-
> drivers/pci/controller/dwc/pcie-qcom.c | 5 +-
> 4 files changed, 68 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> index e92513c5bda51..8654346729574 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -565,6 +565,59 @@ static int dw_pcie_host_get_resources(struct dw_pcie_rp *pp)
> return 0;
> }
>
> +static int dw_pcie_host_initial_scan(struct dw_pcie_rp *pp)
> +{
> + struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> + struct pci_host_bridge *bridge = pp->bridge;
> + int ret;
> +
> + ret = pci_host_probe(bridge);
> + if (ret)
> + return ret;
> +
> + if (pp->ops->post_init)
> + pp->ops->post_init(pp);
> +
> + dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
> +
> + return 0;
> +}
> +
> +void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp)
> +{
> + if (!pp->initial_linkup_irq_done) {
> + int ret;
> +
> + ret = dw_pcie_host_initial_scan(pp);
> + if (ret) {
> + struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> + struct device *dev = pci->dev;
> +
> + dev_err(dev, "Initial scan from IRQ failed: %d\n", ret);
> +
> + dw_pcie_stop_link(pci);
> +
> + dw_pcie_edma_remove(pci);
> +
> + if (pp->has_msi_ctrl)
> + dw_pcie_free_msi(pp);
> +
> + if (pp->ops->deinit)
> + pp->ops->deinit(pp);
> +
> + if (pp->cfg)
> + pci_ecam_free(pp->cfg);
> + } else {
> + pp->initial_linkup_irq_done = true;
> + }
> + } else {
> + /* Rescan the bus to enumerate endpoint devices */
> + pci_lock_rescan_remove();
> + pci_rescan_bus(pp->bridge->bus);
> + pci_unlock_rescan_remove();
> + }
> +}
> +
> int dw_pcie_host_init(struct dw_pcie_rp *pp)
> {
> struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> @@ -669,18 +722,17 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
> * If there is no Link Up IRQ, we should not bypass the delay
> * because that would require users to manually rescan for devices.
> */
> - if (!pp->use_linkup_irq)
> + if (!pp->use_linkup_irq) {
> /* Ignore errors, the link may come up later */
> dw_pcie_wait_for_link(pci);
>
> - ret = pci_host_probe(bridge);
> - if (ret)
> - goto err_stop_link;
> -
> - if (pp->ops->post_init)
> - pp->ops->post_init(pp);
> -
> - dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
> + /*
> + * For platforms with Link Up IRQ, initial scan will be done
> + * on first Link Up IRQ.
> + */
> + if (dw_pcie_host_initial_scan(pp))
> + goto err_stop_link;
> + }
>
> return 0;
>
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> index e995f692a1ecd..a31bd93490dcd 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -427,6 +427,7 @@ struct dw_pcie_rp {
> int msg_atu_index;
> struct resource *msg_res;
> bool use_linkup_irq;
> + bool initial_linkup_irq_done;
> struct pci_eq_presets presets;
> struct pci_config_window *cfg;
> bool ecam_enabled;
> @@ -807,6 +808,7 @@ void dw_pcie_msi_init(struct dw_pcie_rp *pp);
> int dw_pcie_msi_host_init(struct dw_pcie_rp *pp);
> void dw_pcie_free_msi(struct dw_pcie_rp *pp);
> int dw_pcie_setup_rc(struct dw_pcie_rp *pp);
> +void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp);
> int dw_pcie_host_init(struct dw_pcie_rp *pp);
> void dw_pcie_host_deinit(struct dw_pcie_rp *pp);
> int dw_pcie_allocate_domains(struct dw_pcie_rp *pp);
> @@ -844,6 +846,9 @@ static inline int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
> return 0;
> }
>
> +static inline void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp)
> +{ }
> +
> static inline int dw_pcie_host_init(struct dw_pcie_rp *pp)
> {
> return 0;
> diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> index 3e2752c7dd096..8f2cc1ef25e3d 100644
> --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> @@ -466,10 +466,7 @@ static irqreturn_t rockchip_pcie_rc_sys_irq_thread(int irq, void *arg)
> if (rockchip_pcie_link_up(pci)) {
> msleep(PCIE_RESET_CONFIG_WAIT_MS);
> dev_dbg(dev, "Received Link up event. Starting enumeration!\n");
> - /* Rescan the bus to enumerate endpoint devices */
> - pci_lock_rescan_remove();
> - pci_rescan_bus(pp->bridge->bus);
> - pci_unlock_rescan_remove();
> + dw_pcie_handle_link_up_irq(pp);
> }
> }
>
> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> index c48a20602d7fa..2d8aca6630949 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> @@ -1617,10 +1617,7 @@ static irqreturn_t qcom_pcie_global_irq_thread(int irq, void *data)
> if (FIELD_GET(PARF_INT_ALL_LINK_UP, status)) {
> msleep(PCIE_RESET_CONFIG_WAIT_MS);
> dev_dbg(dev, "Received Link up event. Starting enumeration!\n");
> - /* Rescan the bus to enumerate endpoint devices */
> - pci_lock_rescan_remove();
> - pci_rescan_bus(pp->bridge->bus);
> - pci_unlock_rescan_remove();
> + dw_pcie_handle_link_up_irq(pp);
>
> qcom_pcie_icc_opp_update(pcie);
> } else {
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] PCI: dwc: Make Link Up IRQ logic handle already powered on PCIe switches
2025-11-27 13:43 [PATCH] PCI: dwc: Make Link Up IRQ logic handle already powered on PCIe switches Niklas Cassel
2025-11-28 1:06 ` Shawn Lin
@ 2025-11-28 6:55 ` FUKAUMI Naoki
2025-11-29 2:46 ` Manivannan Sadhasivam
2025-11-29 16:50 ` Dan Carpenter
3 siblings, 0 replies; 5+ messages in thread
From: FUKAUMI Naoki @ 2025-11-28 6:55 UTC (permalink / raw)
To: Niklas Cassel, Jingoo Han, Manivannan Sadhasivam,
Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring,
Bjorn Helgaas, Heiko Stuebner
Cc: linux-pci, linux-arm-kernel, linux-rockchip, linux-arm-msm
Hi Niklas,
On 11/27/25 22:43, Niklas Cassel wrote:
> The DWC glue drivers always call pci_host_probe() during probe(), which
> will allocate upstream bridge resources and enumerate the bus.
>
> For controllers without Link Up IRQ support, pci_host_probe() is called
> after dw_pcie_wait_for_link(), which will also wait the time required by
> the PCIe specification before performing PCI Configuration Space reads.
>
> For controllers with Link Up IRQ support, the pci_host_probe() call (which
> will perform PCI Configuration Space reads) is done without any of the
> delays mandated by the PCIe specification.
>
> For controllers with Link Up IRQ support, since the pci_host_probe() call
> is done without any delay (link training might still be ongoing), it is
> very unlikely that this scan will find any devices. Once the Link Up IRQ
> triggers, the Link Up IRQ handler will call pci_rescan_bus().
>
> This works fine for PCIe endpoints connected to the Root Port, since they
> don't extend the bus. However, if the pci_rescan_bus() call detects a PCIe
> switch, then there will be a problem when the downstream busses starts
> showing up, because the PCIe controller is not hotplug capable, so we are
> not allowed to extend the subordinate bus number after the initial scan,
> resulting in error messages such as:
>
> pci_bus 0004:43: busn_res: can not insert [bus 43-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:43: busn_res: [bus 43-41] end is updated to 43
> pci_bus 0004:43: busn_res: can not insert [bus 43] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:00.0: devices behind bridge are unusable because [bus 43] cannot be assigned for them
> pci_bus 0004:44: busn_res: can not insert [bus 44-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:44: busn_res: [bus 44-41] end is updated to 44
> pci_bus 0004:44: busn_res: can not insert [bus 44] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:02.0: devices behind bridge are unusable because [bus 44] cannot be assigned for them
> pci_bus 0004:45: busn_res: can not insert [bus 45-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:45: busn_res: [bus 45-41] end is updated to 45
> pci_bus 0004:45: busn_res: can not insert [bus 45] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:06.0: devices behind bridge are unusable because [bus 45] cannot be assigned for them
> pci_bus 0004:46: busn_res: can not insert [bus 46-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:46: busn_res: [bus 46-41] end is updated to 46
> pci_bus 0004:46: busn_res: can not insert [bus 46] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:0e.0: devices behind bridge are unusable because [bus 46] cannot be assigned for them
> pci_bus 0004:42: busn_res: [bus 42-41] end is updated to 46
> pci_bus 0004:42: busn_res: can not insert [bus 42-46] under [bus 41] (conflicts with (null) [bus 41])
> pci 0004:41:00.0: devices behind bridge are unusable because [bus 42-46] cannot be assigned for them
> pcieport 0004:40:00.0: bridge has subordinate 41 but max busn 46
>
> While we would like to set the is_hotplug_bridge flag
> (quirk_hotplug_bridge()), many embedded SoCs that use the DWC controller
> have synthesized the controller without hot-plug support.
> Thus, the Link Up IRQ logic is only mimicking hot-plug functionality, i.e.
> it is not compliant with the PCI Hot-Plug Specification, so we cannot make
> use of the is_hotplug_bridge flag.
>
> In order to let the Link Up IRQ logic handle PCIe switches that are already
> powered on (PCIe switches that not powered on already need to implement a
> pwrctrl driver), don't perform a pci_host_probe() call during probe()
> (which disregards the delays required by the PCIe specification).
>
> Instead let the first Link Up IRQ call pci_host_probe(). Any follow up
> Link Up IRQ will call pci_rescan_bus().
I'm pleased to inform you that your patch worked perfectly with devices
behind the ASM2806 switch (Radxa Dual 2.5G Router HAT) connected to the
PCIe 2.1 bus of the Radxa ROCK 5A, 5B, and 5C Lite.
So,
Tested-by: FUKAUMI Naoki <naoki@radxa.com>
Thank you very much for your work, and I apologize for any confusion
caused by my test report.
Best regards,
--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.
> Fixes: ec9fd499b9c6 ("PCI: dw-rockchip: Don't wait for link since we can detect Link Up")
> Fixes: 0e0b45ab5d77 ("PCI: dw-rockchip: Enumerate endpoints based on dll_link_up IRQ")
> Reported-by: FUKAUMI Naoki <naoki@radxa.com>
> Closes: https://lore.kernel.org/linux-pci/1E8E4DB773970CB5+5a52c9e1-01b8-4872-99b7-021099f04031@radxa.com/
> Signed-off-by: Niklas Cassel <cassel@kernel.org>
> ---
> .../pci/controller/dwc/pcie-designware-host.c | 70 ++++++++++++++++---
> drivers/pci/controller/dwc/pcie-designware.h | 5 ++
> drivers/pci/controller/dwc/pcie-dw-rockchip.c | 5 +-
> drivers/pci/controller/dwc/pcie-qcom.c | 5 +-
> 4 files changed, 68 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> index e92513c5bda51..8654346729574 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -565,6 +565,59 @@ static int dw_pcie_host_get_resources(struct dw_pcie_rp *pp)
> return 0;
> }
>
> +static int dw_pcie_host_initial_scan(struct dw_pcie_rp *pp)
> +{
> + struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> + struct pci_host_bridge *bridge = pp->bridge;
> + int ret;
> +
> + ret = pci_host_probe(bridge);
> + if (ret)
> + return ret;
> +
> + if (pp->ops->post_init)
> + pp->ops->post_init(pp);
> +
> + dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
> +
> + return 0;
> +}
> +
> +void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp)
> +{
> + if (!pp->initial_linkup_irq_done) {
> + int ret;
> +
> + ret = dw_pcie_host_initial_scan(pp);
> + if (ret) {
> + struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> + struct device *dev = pci->dev;
> +
> + dev_err(dev, "Initial scan from IRQ failed: %d\n", ret);
> +
> + dw_pcie_stop_link(pci);
> +
> + dw_pcie_edma_remove(pci);
> +
> + if (pp->has_msi_ctrl)
> + dw_pcie_free_msi(pp);
> +
> + if (pp->ops->deinit)
> + pp->ops->deinit(pp);
> +
> + if (pp->cfg)
> + pci_ecam_free(pp->cfg);
> + } else {
> + pp->initial_linkup_irq_done = true;
> + }
> + } else {
> + /* Rescan the bus to enumerate endpoint devices */
> + pci_lock_rescan_remove();
> + pci_rescan_bus(pp->bridge->bus);
> + pci_unlock_rescan_remove();
> + }
> +}
> +
> int dw_pcie_host_init(struct dw_pcie_rp *pp)
> {
> struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> @@ -669,18 +722,17 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
> * If there is no Link Up IRQ, we should not bypass the delay
> * because that would require users to manually rescan for devices.
> */
> - if (!pp->use_linkup_irq)
> + if (!pp->use_linkup_irq) {
> /* Ignore errors, the link may come up later */
> dw_pcie_wait_for_link(pci);
>
> - ret = pci_host_probe(bridge);
> - if (ret)
> - goto err_stop_link;
> -
> - if (pp->ops->post_init)
> - pp->ops->post_init(pp);
> -
> - dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
> + /*
> + * For platforms with Link Up IRQ, initial scan will be done
> + * on first Link Up IRQ.
> + */
> + if (dw_pcie_host_initial_scan(pp))
> + goto err_stop_link;
> + }
>
> return 0;
>
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> index e995f692a1ecd..a31bd93490dcd 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -427,6 +427,7 @@ struct dw_pcie_rp {
> int msg_atu_index;
> struct resource *msg_res;
> bool use_linkup_irq;
> + bool initial_linkup_irq_done;
> struct pci_eq_presets presets;
> struct pci_config_window *cfg;
> bool ecam_enabled;
> @@ -807,6 +808,7 @@ void dw_pcie_msi_init(struct dw_pcie_rp *pp);
> int dw_pcie_msi_host_init(struct dw_pcie_rp *pp);
> void dw_pcie_free_msi(struct dw_pcie_rp *pp);
> int dw_pcie_setup_rc(struct dw_pcie_rp *pp);
> +void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp);
> int dw_pcie_host_init(struct dw_pcie_rp *pp);
> void dw_pcie_host_deinit(struct dw_pcie_rp *pp);
> int dw_pcie_allocate_domains(struct dw_pcie_rp *pp);
> @@ -844,6 +846,9 @@ static inline int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
> return 0;
> }
>
> +static inline void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp)
> +{ }
> +
> static inline int dw_pcie_host_init(struct dw_pcie_rp *pp)
> {
> return 0;
> diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> index 3e2752c7dd096..8f2cc1ef25e3d 100644
> --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> @@ -466,10 +466,7 @@ static irqreturn_t rockchip_pcie_rc_sys_irq_thread(int irq, void *arg)
> if (rockchip_pcie_link_up(pci)) {
> msleep(PCIE_RESET_CONFIG_WAIT_MS);
> dev_dbg(dev, "Received Link up event. Starting enumeration!\n");
> - /* Rescan the bus to enumerate endpoint devices */
> - pci_lock_rescan_remove();
> - pci_rescan_bus(pp->bridge->bus);
> - pci_unlock_rescan_remove();
> + dw_pcie_handle_link_up_irq(pp);
> }
> }
>
> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> index c48a20602d7fa..2d8aca6630949 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> @@ -1617,10 +1617,7 @@ static irqreturn_t qcom_pcie_global_irq_thread(int irq, void *data)
> if (FIELD_GET(PARF_INT_ALL_LINK_UP, status)) {
> msleep(PCIE_RESET_CONFIG_WAIT_MS);
> dev_dbg(dev, "Received Link up event. Starting enumeration!\n");
> - /* Rescan the bus to enumerate endpoint devices */
> - pci_lock_rescan_remove();
> - pci_rescan_bus(pp->bridge->bus);
> - pci_unlock_rescan_remove();
> + dw_pcie_handle_link_up_irq(pp);
>
> qcom_pcie_icc_opp_update(pcie);
> } else {
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] PCI: dwc: Make Link Up IRQ logic handle already powered on PCIe switches
2025-11-27 13:43 [PATCH] PCI: dwc: Make Link Up IRQ logic handle already powered on PCIe switches Niklas Cassel
2025-11-28 1:06 ` Shawn Lin
2025-11-28 6:55 ` FUKAUMI Naoki
@ 2025-11-29 2:46 ` Manivannan Sadhasivam
2025-11-29 16:50 ` Dan Carpenter
3 siblings, 0 replies; 5+ messages in thread
From: Manivannan Sadhasivam @ 2025-11-29 2:46 UTC (permalink / raw)
To: Niklas Cassel
Cc: Jingoo Han, Lorenzo Pieralisi, Krzysztof Wilczyński,
Rob Herring, Bjorn Helgaas, Heiko Stuebner, FUKAUMI Naoki,
linux-pci, linux-arm-kernel, linux-rockchip, linux-arm-msm
On Thu, Nov 27, 2025 at 02:43:18PM +0100, Niklas Cassel wrote:
> The DWC glue drivers always call pci_host_probe() during probe(), which
> will allocate upstream bridge resources and enumerate the bus.
>
> For controllers without Link Up IRQ support, pci_host_probe() is called
> after dw_pcie_wait_for_link(), which will also wait the time required by
> the PCIe specification before performing PCI Configuration Space reads.
>
> For controllers with Link Up IRQ support, the pci_host_probe() call (which
> will perform PCI Configuration Space reads) is done without any of the
> delays mandated by the PCIe specification.
>
> For controllers with Link Up IRQ support, since the pci_host_probe() call
> is done without any delay (link training might still be ongoing), it is
> very unlikely that this scan will find any devices. Once the Link Up IRQ
> triggers, the Link Up IRQ handler will call pci_rescan_bus().
>
> This works fine for PCIe endpoints connected to the Root Port, since they
> don't extend the bus. However, if the pci_rescan_bus() call detects a PCIe
> switch, then there will be a problem when the downstream busses starts
> showing up, because the PCIe controller is not hotplug capable, so we are
> not allowed to extend the subordinate bus number after the initial scan,
> resulting in error messages such as:
>
> pci_bus 0004:43: busn_res: can not insert [bus 43-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:43: busn_res: [bus 43-41] end is updated to 43
> pci_bus 0004:43: busn_res: can not insert [bus 43] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:00.0: devices behind bridge are unusable because [bus 43] cannot be assigned for them
> pci_bus 0004:44: busn_res: can not insert [bus 44-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:44: busn_res: [bus 44-41] end is updated to 44
> pci_bus 0004:44: busn_res: can not insert [bus 44] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:02.0: devices behind bridge are unusable because [bus 44] cannot be assigned for them
> pci_bus 0004:45: busn_res: can not insert [bus 45-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:45: busn_res: [bus 45-41] end is updated to 45
> pci_bus 0004:45: busn_res: can not insert [bus 45] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:06.0: devices behind bridge are unusable because [bus 45] cannot be assigned for them
> pci_bus 0004:46: busn_res: can not insert [bus 46-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:46: busn_res: [bus 46-41] end is updated to 46
> pci_bus 0004:46: busn_res: can not insert [bus 46] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:0e.0: devices behind bridge are unusable because [bus 46] cannot be assigned for them
> pci_bus 0004:42: busn_res: [bus 42-41] end is updated to 46
> pci_bus 0004:42: busn_res: can not insert [bus 42-46] under [bus 41] (conflicts with (null) [bus 41])
> pci 0004:41:00.0: devices behind bridge are unusable because [bus 42-46] cannot be assigned for them
> pcieport 0004:40:00.0: bridge has subordinate 41 but max busn 46
>
> While we would like to set the is_hotplug_bridge flag
> (quirk_hotplug_bridge()), many embedded SoCs that use the DWC controller
> have synthesized the controller without hot-plug support.
> Thus, the Link Up IRQ logic is only mimicking hot-plug functionality, i.e.
> it is not compliant with the PCI Hot-Plug Specification, so we cannot make
> use of the is_hotplug_bridge flag.
>
> In order to let the Link Up IRQ logic handle PCIe switches that are already
> powered on (PCIe switches that not powered on already need to implement a
> pwrctrl driver), don't perform a pci_host_probe() call during probe()
> (which disregards the delays required by the PCIe specification).
>
> Instead let the first Link Up IRQ call pci_host_probe(). Any follow up
> Link Up IRQ will call pci_rescan_bus().
>
> Fixes: ec9fd499b9c6 ("PCI: dw-rockchip: Don't wait for link since we can detect Link Up")
> Fixes: 0e0b45ab5d77 ("PCI: dw-rockchip: Enumerate endpoints based on dll_link_up IRQ")
> Reported-by: FUKAUMI Naoki <naoki@radxa.com>
> Closes: https://lore.kernel.org/linux-pci/1E8E4DB773970CB5+5a52c9e1-01b8-4872-99b7-021099f04031@radxa.com/
> Signed-off-by: Niklas Cassel <cassel@kernel.org>
> ---
> .../pci/controller/dwc/pcie-designware-host.c | 70 ++++++++++++++++---
> drivers/pci/controller/dwc/pcie-designware.h | 5 ++
> drivers/pci/controller/dwc/pcie-dw-rockchip.c | 5 +-
> drivers/pci/controller/dwc/pcie-qcom.c | 5 +-
> 4 files changed, 68 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> index e92513c5bda51..8654346729574 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -565,6 +565,59 @@ static int dw_pcie_host_get_resources(struct dw_pcie_rp *pp)
> return 0;
> }
>
> +static int dw_pcie_host_initial_scan(struct dw_pcie_rp *pp)
> +{
> + struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> + struct pci_host_bridge *bridge = pp->bridge;
> + int ret;
> +
> + ret = pci_host_probe(bridge);
> + if (ret)
> + return ret;
> +
> + if (pp->ops->post_init)
> + pp->ops->post_init(pp);
> +
> + dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
> +
> + return 0;
> +}
> +
> +void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp)
> +{
> + if (!pp->initial_linkup_irq_done) {
> + int ret;
> +
> + ret = dw_pcie_host_initial_scan(pp);
> + if (ret) {
> + struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> + struct device *dev = pci->dev;
> +
> + dev_err(dev, "Initial scan from IRQ failed: %d\n", ret);
> +
> + dw_pcie_stop_link(pci);
> +
> + dw_pcie_edma_remove(pci);
> +
> + if (pp->has_msi_ctrl)
> + dw_pcie_free_msi(pp);
> +
> + if (pp->ops->deinit)
> + pp->ops->deinit(pp);
> +
> + if (pp->cfg)
> + pci_ecam_free(pp->cfg);
> + } else {
> + pp->initial_linkup_irq_done = true;
> + }
> + } else {
> + /* Rescan the bus to enumerate endpoint devices */
> + pci_lock_rescan_remove();
> + pci_rescan_bus(pp->bridge->bus);
> + pci_unlock_rescan_remove();
> + }
> +}
> +
> int dw_pcie_host_init(struct dw_pcie_rp *pp)
> {
> struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> @@ -669,18 +722,17 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
> * If there is no Link Up IRQ, we should not bypass the delay
> * because that would require users to manually rescan for devices.
> */
> - if (!pp->use_linkup_irq)
> + if (!pp->use_linkup_irq) {
> /* Ignore errors, the link may come up later */
> dw_pcie_wait_for_link(pci);
>
> - ret = pci_host_probe(bridge);
> - if (ret)
> - goto err_stop_link;
> -
> - if (pp->ops->post_init)
> - pp->ops->post_init(pp);
> -
> - dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
> + /*
> + * For platforms with Link Up IRQ, initial scan will be done
> + * on first Link Up IRQ.
> + */
> + if (dw_pcie_host_initial_scan(pp))
> + goto err_stop_link;
This is causing NULL ptr dereference on Qcom platforms as 'pp->bridge->bus' is
dereferenced after dw_pcie_host_init() for registering the IRQ.
I still feel that a revert would be the safest option.
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] PCI: dwc: Make Link Up IRQ logic handle already powered on PCIe switches
2025-11-27 13:43 [PATCH] PCI: dwc: Make Link Up IRQ logic handle already powered on PCIe switches Niklas Cassel
` (2 preceding siblings ...)
2025-11-29 2:46 ` Manivannan Sadhasivam
@ 2025-11-29 16:50 ` Dan Carpenter
3 siblings, 0 replies; 5+ messages in thread
From: Dan Carpenter @ 2025-11-29 16:50 UTC (permalink / raw)
To: oe-kbuild, Niklas Cassel, Jingoo Han, Manivannan Sadhasivam,
Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring,
Bjorn Helgaas, Heiko Stuebner
Cc: lkp, oe-kbuild-all, FUKAUMI Naoki, linux-pci, linux-arm-kernel,
linux-rockchip, linux-arm-msm
Hi Niklas,
kernel test robot noticed the following build warnings:
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Niklas-Cassel/PCI-dwc-Make-Link-Up-IRQ-logic-handle-already-powered-on-PCIe-switches/20251127-214649
base: https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git next
patch link: https://lore.kernel.org/r/20251127134318.3655052-2-cassel%40kernel.org
patch subject: [PATCH] PCI: dwc: Make Link Up IRQ logic handle already powered on PCIe switches
config: x86_64-randconfig-r071-20251128 (https://download.01.org/0day-ci/archive/20251129/202511290255.uBLXDIG5-lkp@intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
| Closes: https://lore.kernel.org/r/202511290255.uBLXDIG5-lkp@intel.com/
smatch warnings:
drivers/pci/controller/dwc/pcie-designware-host.c:737 dw_pcie_host_init() warn: missing error code 'ret'
vim +/ret +737 drivers/pci/controller/dwc/pcie-designware-host.c
59fbab1ae40eb0 drivers/pci/controller/dwc/pcie-designware-host.c Rob Herring 2020-11-05 712
939fbcd568fd29 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin 2023-01-13 713 ret = dw_pcie_setup_rc(pp);
939fbcd568fd29 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin 2023-01-13 714 if (ret)
939fbcd568fd29 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin 2023-01-13 715 goto err_remove_edma;
939fbcd568fd29 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin 2023-01-13 716
c5097b9869a136 drivers/pci/controller/dwc/pcie-designware-host.c Johan Hovold 2023-07-06 717 if (!dw_pcie_link_up(pci)) {
a37beefbde8802 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin 2022-06-24 718 ret = dw_pcie_start_link(pci);
886a9c1347558f drivers/pci/controller/dwc/pcie-designware-host.c Rob Herring 2020-11-05 719 if (ret)
939fbcd568fd29 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin 2023-01-13 720 goto err_remove_edma;
da56a1bfbab551 drivers/pci/controller/dwc/pcie-designware-host.c Ajay Agarwal 2023-04-12 721 }
886a9c1347558f drivers/pci/controller/dwc/pcie-designware-host.c Rob Herring 2020-11-05 722
8d3bf19f1b585a drivers/pci/controller/dwc/pcie-designware-host.c Krishna chaitanya chundru 2024-11-23 723 /*
8d3bf19f1b585a drivers/pci/controller/dwc/pcie-designware-host.c Krishna chaitanya chundru 2024-11-23 724 * Note: Skip the link up delay only when a Link Up IRQ is present.
8d3bf19f1b585a drivers/pci/controller/dwc/pcie-designware-host.c Krishna chaitanya chundru 2024-11-23 725 * If there is no Link Up IRQ, we should not bypass the delay
8d3bf19f1b585a drivers/pci/controller/dwc/pcie-designware-host.c Krishna chaitanya chundru 2024-11-23 726 * because that would require users to manually rescan for devices.
8d3bf19f1b585a drivers/pci/controller/dwc/pcie-designware-host.c Krishna chaitanya chundru 2024-11-23 727 */
cd723d3dce14ac drivers/pci/controller/dwc/pcie-designware-host.c Niklas Cassel 2025-11-27 728 if (!pp->use_linkup_irq) {
c5097b9869a136 drivers/pci/controller/dwc/pcie-designware-host.c Johan Hovold 2023-07-06 729 /* Ignore errors, the link may come up later */
c5097b9869a136 drivers/pci/controller/dwc/pcie-designware-host.c Johan Hovold 2023-07-06 730 dw_pcie_wait_for_link(pci);
c5097b9869a136 drivers/pci/controller/dwc/pcie-designware-host.c Johan Hovold 2023-07-06 731
cd723d3dce14ac drivers/pci/controller/dwc/pcie-designware-host.c Niklas Cassel 2025-11-27 732 /*
cd723d3dce14ac drivers/pci/controller/dwc/pcie-designware-host.c Niklas Cassel 2025-11-27 733 * For platforms with Link Up IRQ, initial scan will be done
cd723d3dce14ac drivers/pci/controller/dwc/pcie-designware-host.c Niklas Cassel 2025-11-27 734 * on first Link Up IRQ.
cd723d3dce14ac drivers/pci/controller/dwc/pcie-designware-host.c Niklas Cassel 2025-11-27 735 */
cd723d3dce14ac drivers/pci/controller/dwc/pcie-designware-host.c Niklas Cassel 2025-11-27 736 if (dw_pcie_host_initial_scan(pp))
113fa857b74c94 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin 2022-06-24 @737 goto err_stop_link;
ret = dw_pcie_host_initial_scan(pp);
if (ret)
goto err_stop_link;
cd723d3dce14ac drivers/pci/controller/dwc/pcie-designware-host.c Niklas Cassel 2025-11-27 738 }
4fbfa17f9a0755 drivers/pci/controller/dwc/pcie-designware-host.c Shradha Todi 2025-02-21 739
feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 740 return 0;
feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 741
113fa857b74c94 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin 2022-06-24 742 err_stop_link:
a37beefbde8802 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin 2022-06-24 743 dw_pcie_stop_link(pci);
113fa857b74c94 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin 2022-06-24 744
939fbcd568fd29 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin 2023-01-13 745 err_remove_edma:
939fbcd568fd29 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin 2023-01-13 746 dw_pcie_edma_remove(pci);
939fbcd568fd29 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin 2023-01-13 747
9e2b5de5604a6f drivers/pci/controller/dwc/pcie-designware-host.c Jisheng Zhang 2019-03-29 748 err_free_msi:
f78f02638af594 drivers/pci/controller/dwc/pcie-designware-host.c Rob Herring 2020-11-05 749 if (pp->has_msi_ctrl)
9e2b5de5604a6f drivers/pci/controller/dwc/pcie-designware-host.c Jisheng Zhang 2019-03-29 750 dw_pcie_free_msi(pp);
c6481d51dc65f2 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin 2022-06-24 751
c6481d51dc65f2 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin 2022-06-24 752 err_deinit_host:
aea370b2aec9d3 drivers/pci/controller/dwc/pcie-designware-host.c Yoshihiro Shimoda 2023-12-20 753 if (pp->ops->deinit)
aea370b2aec9d3 drivers/pci/controller/dwc/pcie-designware-host.c Yoshihiro Shimoda 2023-12-20 754 pp->ops->deinit(pp);
c6481d51dc65f2 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin 2022-06-24 755
f6fd357f7afbeb drivers/pci/controller/dwc/pcie-designware-host.c Krishna Chaitanya Chundru 2025-09-23 756 err_free_ecam:
f6fd357f7afbeb drivers/pci/controller/dwc/pcie-designware-host.c Krishna Chaitanya Chundru 2025-09-23 757 if (pp->cfg)
f6fd357f7afbeb drivers/pci/controller/dwc/pcie-designware-host.c Krishna Chaitanya Chundru 2025-09-23 758 pci_ecam_free(pp->cfg);
f6fd357f7afbeb drivers/pci/controller/dwc/pcie-designware-host.c Krishna Chaitanya Chundru 2025-09-23 759
feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 760 return ret;
feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 761 }
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-11-29 16:50 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-27 13:43 [PATCH] PCI: dwc: Make Link Up IRQ logic handle already powered on PCIe switches Niklas Cassel
2025-11-28 1:06 ` Shawn Lin
2025-11-28 6:55 ` FUKAUMI Naoki
2025-11-29 2:46 ` Manivannan Sadhasivam
2025-11-29 16:50 ` Dan Carpenter
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).