* [PATCH v7 0/4] PCI: Add support for resetting the Root Ports in a platform specific way
@ 2026-03-10 14:01 Manivannan Sadhasivam via B4 Relay
2026-03-10 14:01 ` [PATCH v7 1/4] PCI/ERR: " Manivannan Sadhasivam via B4 Relay
` (6 more replies)
0 siblings, 7 replies; 16+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2026-03-10 14:01 UTC (permalink / raw)
To: Bjorn Helgaas, Mahesh J Salgaonkar, Oliver O'Halloran,
Will Deacon, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Rob Herring, Heiko Stuebner, Philipp Zabel
Cc: linux-pci, linux-kernel, linuxppc-dev, linux-arm-kernel,
linux-arm-msm, linux-rockchip, Niklas Cassel, Wilfred Mallawa,
Krishna Chaitanya Chundru, mani, Lukas Wunner, Richard Zhu,
Brian Norris, Wilson Ding, Manivannan Sadhasivam, Frank Li,
Manivannan Sadhasivam
Hi,
Currently, in the event of AER/DPC, PCI core will try to reset the slot (Root
Port) and its subordinate devices by invoking bridge control reset and FLR. But
in some cases like AER Fatal error, it might be necessary to reset the Root
Ports using the PCI host bridge drivers in a platform specific way (as indicated
by the TODO in the pcie_do_recovery() function in drivers/pci/pcie/err.c).
Otherwise, the PCI link won't be recovered successfully.
So this series adds a new callback 'pci_host_bridge::reset_root_port' for the
host bridge drivers to reset the Root Port when a fatal error happens.
Also, this series allows the host bridge drivers to handle PCI link down event
by resetting the Root Ports and recovering the bus. This is accomplished by the
help of the new 'pci_host_handle_link_down()' API. Host bridge drivers are
expected to call this API (preferrably from a threaded IRQ handler) with
relevant Root Port 'pci_dev' when a link down event is detected for the port.
The API will reuse the pcie_do_recovery() function to recover the link if AER
support is enabled, otherwise it will directly call the reset_root_port()
callback of the host bridge driver (if exists).
For reference, I've modified the pcie-qcom driver to call
pci_host_handle_link_down() API with Root Port 'pci_dev' after receiving the
LDn global_irq event and populated 'pci_host_bridge::reset_root_port()'
callback to reset the Root Ports.
Testing
-------
Tested on Qcom Lemans AU Ride platform with Host and EP SoCs connected over PCIe
link. Simulated the LDn by disabling LTSSM_EN on the EP and I could verify that
the link was getting recovered successfully.
Changes in v7:
- Dropped Rockchip Root port reset patch due to reported issues. But the series
works on other platforms as tested by others.
- Added pci_{lock/unlock}_rescan_remove() to guard pci_bus_error_reset() as the
device could be removed in-between due to Native hotplug interrupt.
- Rebased on top of v7.0-rc1
- Link to v6: https://lore.kernel.org/r/20250715-pci-port-reset-v6-0-6f9cce94e7bb@oss.qualcomm.com
Changes in v6:
- Incorporated the patch: https://lore.kernel.org/all/20250524185304.26698-2-manivannan.sadhasivam@linaro.org/
- Link to v5: https://lore.kernel.org/r/20250715-pci-port-reset-v5-0-26a5d278db40@oss.qualcomm.com
Changes in v5:
* Reworked the pci_host_handle_link_down() to accept Root Port instead of
resetting all Root Ports in the event of link down.
* Renamed 'reset_slot' to 'reset_root_port' to avoid confusion as both terms
were used interchangibly and the series is intended to reset Root Port only.
* Added the Rockchip driver change to this series.
* Dropped the applied patches and review/tested tags due to rework.
* Rebased on top of v6.16-rc1.
Changes in v4:
- Handled link down first in the irq handler
- Updated ICC & OPP bandwidth after link up in reset_slot() callback
- Link to v3: https://lore.kernel.org/r/20250417-pcie-reset-slot-v3-0-59a10811c962@linaro.org
Changes in v3:
- Made the pci-host-common driver as a common library for host controller
drivers
- Moved the reset slot code to pci-host-common library
- Link to v2: https://lore.kernel.org/r/20250416-pcie-reset-slot-v2-0-efe76b278c10@linaro.org
Changes in v2:
- Moved calling reset_slot() callback from pcie_do_recovery() to pcibios_reset_secondary_bus()
- Link to v1: https://lore.kernel.org/r/20250404-pcie-reset-slot-v1-0-98952918bf90@linaro.org
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
Manivannan Sadhasivam (4):
PCI/ERR: Add support for resetting the Root Ports in a platform specific way
PCI: host-common: Add link down handling for Root Ports
PCI: qcom: Add support for resetting the Root Port due to link down event
misc: pci_endpoint_test: Add AER error handlers
drivers/misc/pci_endpoint_test.c | 20 +++++
drivers/pci/controller/dwc/pcie-qcom.c | 143 ++++++++++++++++++++++++++++++-
drivers/pci/controller/pci-host-common.c | 35 ++++++++
drivers/pci/controller/pci-host-common.h | 1 +
drivers/pci/pci.c | 21 +++++
drivers/pci/pcie/err.c | 6 +-
include/linux/pci.h | 1 +
7 files changed, 221 insertions(+), 6 deletions(-)
---
base-commit: 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f
change-id: 20250715-pci-port-reset-4d9519570123
Best regards,
--
Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v7 1/4] PCI/ERR: Add support for resetting the Root Ports in a platform specific way
2026-03-10 14:01 [PATCH v7 0/4] PCI: Add support for resetting the Root Ports in a platform specific way Manivannan Sadhasivam via B4 Relay
@ 2026-03-10 14:01 ` Manivannan Sadhasivam via B4 Relay
2026-03-11 5:26 ` Shawn Lin
2026-03-10 14:02 ` [PATCH v7 2/4] PCI: host-common: Add link down handling for Root Ports Manivannan Sadhasivam via B4 Relay
` (5 subsequent siblings)
6 siblings, 1 reply; 16+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2026-03-10 14:01 UTC (permalink / raw)
To: Bjorn Helgaas, Mahesh J Salgaonkar, Oliver O'Halloran,
Will Deacon, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Rob Herring, Heiko Stuebner, Philipp Zabel
Cc: linux-pci, linux-kernel, linuxppc-dev, linux-arm-kernel,
linux-arm-msm, linux-rockchip, Niklas Cassel, Wilfred Mallawa,
Krishna Chaitanya Chundru, mani, Lukas Wunner, Richard Zhu,
Brian Norris, Wilson Ding, Manivannan Sadhasivam, Frank Li,
Manivannan Sadhasivam
From: Manivannan Sadhasivam <mani@kernel.org>
Some host bridge devices require resetting the Root Ports in a platform
specific way to recover them from error conditions such as Fatal AER
errors, Link Down etc... So introduce pci_host_bridge::reset_root_port()
callback and call it from pcibios_reset_secondary_bus() if available. Also,
save the Root Port config space before reset and restore it afterwards.
The 'reset_root_port' callback is responsible for resetting the given Root
Port referenced by the 'pci_dev' pointer in a platform specific way and
bring it back to the working state if possible. If any error occurs during
the reset operation, relevant errno should be returned.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Tested-by: Brian Norris <briannorris@chromium.org>
Tested-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
Tested-by: Richard Zhu <hongxing.zhu@nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
---
drivers/pci/pci.c | 20 ++++++++++++++++++++
drivers/pci/pcie/err.c | 5 -----
include/linux/pci.h | 1 +
3 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 8479c2e1f74f..6f09057d83e0 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -4812,6 +4812,26 @@ void pci_reset_secondary_bus(struct pci_dev *dev)
void __weak pcibios_reset_secondary_bus(struct pci_dev *dev)
{
+ struct pci_host_bridge *host = pci_find_host_bridge(dev->bus);
+ int ret;
+
+ if (pci_is_root_bus(dev->bus) && host->reset_root_port) {
+ /*
+ * Save the config space of the Root Port before doing the
+ * reset, since the state could be lost. The Endpoint state
+ * should've been saved by the caller.
+ */
+ pci_save_state(dev);
+ ret = host->reset_root_port(host, dev);
+ if (ret)
+ pci_err(dev, "Failed to reset Root Port: %d\n", ret);
+ else
+ /* Now restore it on success */
+ pci_restore_state(dev);
+
+ return;
+ }
+
pci_reset_secondary_bus(dev);
}
diff --git a/drivers/pci/pcie/err.c b/drivers/pci/pcie/err.c
index bebe4bc111d7..13b9d9eb714f 100644
--- a/drivers/pci/pcie/err.c
+++ b/drivers/pci/pcie/err.c
@@ -256,11 +256,6 @@ pci_ers_result_t pcie_do_recovery(struct pci_dev *dev,
}
if (status == PCI_ERS_RESULT_NEED_RESET) {
- /*
- * TODO: Should call platform-specific
- * functions to reset slot before calling
- * drivers' slot_reset callbacks?
- */
status = PCI_ERS_RESULT_RECOVERED;
pci_dbg(bridge, "broadcast slot_reset message\n");
pci_walk_bridge(bridge, report_slot_reset, &status);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 1c270f1d5123..34c434b79abb 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -644,6 +644,7 @@ struct pci_host_bridge {
void (*release_fn)(struct pci_host_bridge *);
int (*enable_device)(struct pci_host_bridge *bridge, struct pci_dev *dev);
void (*disable_device)(struct pci_host_bridge *bridge, struct pci_dev *dev);
+ int (*reset_root_port)(struct pci_host_bridge *bridge, struct pci_dev *dev);
void *release_data;
unsigned int ignore_reset_delay:1; /* For entire hierarchy */
unsigned int no_ext_tags:1; /* No Extended Tags */
--
2.51.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v7 2/4] PCI: host-common: Add link down handling for Root Ports
2026-03-10 14:01 [PATCH v7 0/4] PCI: Add support for resetting the Root Ports in a platform specific way Manivannan Sadhasivam via B4 Relay
2026-03-10 14:01 ` [PATCH v7 1/4] PCI/ERR: " Manivannan Sadhasivam via B4 Relay
@ 2026-03-10 14:02 ` Manivannan Sadhasivam via B4 Relay
2026-03-11 0:55 ` Shawn Lin
2026-03-10 14:02 ` [PATCH v7 3/4] PCI: qcom: Add support for resetting the Root Port due to link down event Manivannan Sadhasivam via B4 Relay
` (4 subsequent siblings)
6 siblings, 1 reply; 16+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2026-03-10 14:02 UTC (permalink / raw)
To: Bjorn Helgaas, Mahesh J Salgaonkar, Oliver O'Halloran,
Will Deacon, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Rob Herring, Heiko Stuebner, Philipp Zabel
Cc: linux-pci, linux-kernel, linuxppc-dev, linux-arm-kernel,
linux-arm-msm, linux-rockchip, Niklas Cassel, Wilfred Mallawa,
Krishna Chaitanya Chundru, mani, Lukas Wunner, Richard Zhu,
Brian Norris, Wilson Ding, Manivannan Sadhasivam, Frank Li,
Manivannan Sadhasivam
From: Manivannan Sadhasivam <mani@kernel.org>
The PCI link, when down, needs to be recovered to bring it back. But on
some platforms, that cannot be done in a generic way as link recovery
procedure is platform specific. So add a new API
pci_host_handle_link_down() that could be called by the host bridge drivers
for a specific Root Port when the link goes down.
The API accepts the 'pci_dev' corresponding to the Root Port which observed
the link down event. If CONFIG_PCIEAER is enabled, the API calls
pcie_do_recovery() function with 'pci_channel_io_frozen' as the state. This
will result in the execution of the AER Fatal error handling code. Since
the link down recovery is pretty much the same as AER Fatal error handling,
pcie_do_recovery() helper is reused here. First, the AER error_detected()
callback will be triggered for the bridge and then for the downstream
devices. Finally, pci_host_reset_root_port() will be called for the Root
Port, which will reset the Root Port using 'reset_root_port' callback to
recover the link. Once that's done, resume message will be broadcasted to
the bridge and the downstream devices, indicating successful link recovery.
But if CONFIG_PCIEAER is not enabled in the kernel, only
pci_host_reset_root_port() API will be called, which will in turn call
pci_bus_error_reset() to just reset the Root Port as there is no way we
could inform the drivers about link recovery.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Tested-by: Brian Norris <briannorris@chromium.org>
Tested-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
Tested-by: Richard Zhu <hongxing.zhu@nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
---
drivers/pci/controller/pci-host-common.c | 35 ++++++++++++++++++++++++++++++++
drivers/pci/controller/pci-host-common.h | 1 +
drivers/pci/pci.c | 1 +
drivers/pci/pcie/err.c | 1 +
4 files changed, 38 insertions(+)
diff --git a/drivers/pci/controller/pci-host-common.c b/drivers/pci/controller/pci-host-common.c
index d6258c1cffe5..15ebff8a542a 100644
--- a/drivers/pci/controller/pci-host-common.c
+++ b/drivers/pci/controller/pci-host-common.c
@@ -12,9 +12,11 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_pci.h>
+#include <linux/pci.h>
#include <linux/pci-ecam.h>
#include <linux/platform_device.h>
+#include "../pci.h"
#include "pci-host-common.h"
static void gen_pci_unmap_cfg(void *ptr)
@@ -106,5 +108,38 @@ void pci_host_common_remove(struct platform_device *pdev)
}
EXPORT_SYMBOL_GPL(pci_host_common_remove);
+static pci_ers_result_t pci_host_reset_root_port(struct pci_dev *dev)
+{
+ int ret;
+
+ pci_lock_rescan_remove();
+ ret = pci_bus_error_reset(dev);
+ pci_unlock_rescan_remove();
+ if (ret) {
+ pci_err(dev, "Failed to reset Root Port: %d\n", ret);
+ return PCI_ERS_RESULT_DISCONNECT;
+ }
+
+ pci_info(dev, "Root Port has been reset\n");
+
+ return PCI_ERS_RESULT_RECOVERED;
+}
+
+static void pci_host_recover_root_port(struct pci_dev *port)
+{
+#if IS_ENABLED(CONFIG_PCIEAER)
+ pcie_do_recovery(port, pci_channel_io_frozen, pci_host_reset_root_port);
+#else
+ pci_host_reset_root_port(port);
+#endif
+}
+
+void pci_host_handle_link_down(struct pci_dev *port)
+{
+ pci_info(port, "Recovering Root Port due to Link Down\n");
+ pci_host_recover_root_port(port);
+}
+EXPORT_SYMBOL_GPL(pci_host_handle_link_down);
+
MODULE_DESCRIPTION("Common library for PCI host controller drivers");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/controller/pci-host-common.h b/drivers/pci/controller/pci-host-common.h
index b5075d4bd7eb..dd12dd1a1b23 100644
--- a/drivers/pci/controller/pci-host-common.h
+++ b/drivers/pci/controller/pci-host-common.h
@@ -17,6 +17,7 @@ int pci_host_common_init(struct platform_device *pdev,
struct pci_host_bridge *bridge,
const struct pci_ecam_ops *ops);
void pci_host_common_remove(struct platform_device *pdev);
+void pci_host_handle_link_down(struct pci_dev *port);
struct pci_config_window *pci_host_common_ecam_create(struct device *dev,
struct pci_host_bridge *bridge, const struct pci_ecam_ops *ops);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 6f09057d83e0..1b37bfe6d079 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -5650,6 +5650,7 @@ int pci_bus_error_reset(struct pci_dev *bridge)
mutex_unlock(&pci_slot_mutex);
return pci_bus_reset(bridge->subordinate, PCI_RESET_DO_RESET);
}
+EXPORT_SYMBOL_GPL(pci_bus_error_reset);
/**
* pci_probe_reset_bus - probe whether a PCI bus can be reset
diff --git a/drivers/pci/pcie/err.c b/drivers/pci/pcie/err.c
index 13b9d9eb714f..d77403d8855b 100644
--- a/drivers/pci/pcie/err.c
+++ b/drivers/pci/pcie/err.c
@@ -292,3 +292,4 @@ pci_ers_result_t pcie_do_recovery(struct pci_dev *dev,
return status;
}
+EXPORT_SYMBOL_GPL(pcie_do_recovery);
--
2.51.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v7 3/4] PCI: qcom: Add support for resetting the Root Port due to link down event
2026-03-10 14:01 [PATCH v7 0/4] PCI: Add support for resetting the Root Ports in a platform specific way Manivannan Sadhasivam via B4 Relay
2026-03-10 14:01 ` [PATCH v7 1/4] PCI/ERR: " Manivannan Sadhasivam via B4 Relay
2026-03-10 14:02 ` [PATCH v7 2/4] PCI: host-common: Add link down handling for Root Ports Manivannan Sadhasivam via B4 Relay
@ 2026-03-10 14:02 ` Manivannan Sadhasivam via B4 Relay
2026-03-10 14:02 ` [PATCH v7 4/4] misc: pci_endpoint_test: Add AER error handlers Manivannan Sadhasivam via B4 Relay
` (3 subsequent siblings)
6 siblings, 0 replies; 16+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2026-03-10 14:02 UTC (permalink / raw)
To: Bjorn Helgaas, Mahesh J Salgaonkar, Oliver O'Halloran,
Will Deacon, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Rob Herring, Heiko Stuebner, Philipp Zabel
Cc: linux-pci, linux-kernel, linuxppc-dev, linux-arm-kernel,
linux-arm-msm, linux-rockchip, Niklas Cassel, Wilfred Mallawa,
Krishna Chaitanya Chundru, mani, Lukas Wunner, Richard Zhu,
Brian Norris, Wilson Ding, Manivannan Sadhasivam,
Manivannan Sadhasivam
From: Manivannan Sadhasivam <mani@kernel.org>
The PCIe link can go down under circumstances such as the device firmware
crash, link instability, etc... When that happens, the PCIe Root Port needs
to be reset to make it operational again. Currently, the driver is not
handling the link down event, due to which the users have to restart the
machine to make PCIe link operational again. So fix it by detecting the
link down event and resetting the Root Port.
Since the Qcom PCIe controllers report the link down event through the
'global' IRQ, enable the link down event by setting PARF_INT_ALL_LINK_DOWN
bit in PARF_INT_ALL_MASK register.
In the case of the event, iterate through the available Root Ports and call
pci_host_handle_link_down() API with Root Port 'pci_dev' to let the PCI
core handle the link down condition. Since Qcom PCIe controllers only
support one Root Port per controller instance, the API will be called only
once. But the looping is necessary as there is no PCI API available to
fetch the Root Port instance without the child 'pci_dev'.
The API will internally call, 'pci_host_bridge::reset_root_port()' callback
to reset the Root Port in a platform specific way. So implement the
callback to reset the Root Port by first resetting the PCIe core, followed
by reinitializing the resources and then finally starting the link again.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Tested-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
---
drivers/pci/controller/dwc/pcie-qcom.c | 143 ++++++++++++++++++++++++++++++++-
1 file changed, 142 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index 67a16af69ddc..e3f08139d33f 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -56,6 +56,10 @@
#define PARF_AXI_MSTR_WR_ADDR_HALT_V2 0x1a8
#define PARF_Q2A_FLUSH 0x1ac
#define PARF_LTSSM 0x1b0
+#define PARF_INT_ALL_STATUS 0x224
+#define PARF_INT_ALL_CLEAR 0x228
+#define PARF_INT_ALL_MASK 0x22c
+#define PARF_STATUS 0x230
#define PARF_SID_OFFSET 0x234
#define PARF_BDF_TRANSLATE_CFG 0x24c
#define PARF_DBI_BASE_ADDR_V2 0x350
@@ -131,6 +135,13 @@
/* PARF_LTSSM register fields */
#define LTSSM_EN BIT(8)
+#define SW_CLEAR_FLUSH_MODE BIT(10)
+#define FLUSH_MODE BIT(11)
+
+/* PARF_INT_ALL_{STATUS/CLEAR/MASK} register fields */
+#define INT_ALL_LINK_DOWN 1
+#define PARF_INT_ALL_LINK_DOWN BIT(INT_ALL_LINK_DOWN)
+#define PARF_INT_MSI_DEV_0_7 GENMASK(30, 23)
/* PARF_NO_SNOOP_OVERRIDE register fields */
#define WR_NO_SNOOP_OVERRIDE_EN BIT(1)
@@ -142,6 +153,9 @@
/* PARF_BDF_TO_SID_CFG fields */
#define BDF_TO_SID_BYPASS BIT(0)
+/* PARF_STATUS fields */
+#define FLUSH_COMPLETED BIT(8)
+
/* ELBI_SYS_CTRL register fields */
#define ELBI_SYS_CTRL_LT_ENABLE BIT(0)
@@ -166,6 +180,7 @@
PCIE_CAP_SLOT_POWER_LIMIT_SCALE)
#define PERST_DELAY_US 1000
+#define FLUSH_TIMEOUT_US 100
#define QCOM_PCIE_CRC8_POLYNOMIAL (BIT(2) | BIT(1) | BIT(0))
@@ -282,11 +297,14 @@ struct qcom_pcie {
const struct qcom_pcie_cfg *cfg;
struct dentry *debugfs;
struct list_head ports;
+ int global_irq;
bool suspended;
bool use_pm_opp;
};
#define to_qcom_pcie(x) dev_get_drvdata((x)->dev)
+static int qcom_pcie_reset_root_port(struct pci_host_bridge *bridge,
+ struct pci_dev *pdev);
static void __qcom_pcie_perst_assert(struct qcom_pcie *pcie, bool assert)
{
@@ -1325,6 +1343,8 @@ static int qcom_pcie_host_init(struct dw_pcie_rp *pp)
goto err_assert_reset;
}
+ pp->bridge->reset_root_port = qcom_pcie_reset_root_port;
+
return 0;
err_assert_reset:
@@ -1608,6 +1628,78 @@ static void qcom_pcie_icc_opp_update(struct qcom_pcie *pcie)
}
}
+/*
+ * Qcom PCIe controllers only support one Root Port per controller instance. So
+ * this function ignores the 'pci_dev' associated with the Root Port and just
+ * resets the host bridge, which in turn resets the Root Port also.
+ */
+static int qcom_pcie_reset_root_port(struct pci_host_bridge *bridge,
+ struct pci_dev *pdev)
+{
+ struct pci_bus *bus = bridge->bus;
+ struct dw_pcie_rp *pp = bus->sysdata;
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+ struct qcom_pcie *pcie = to_qcom_pcie(pci);
+ struct device *dev = pcie->pci->dev;
+ u32 val;
+ int ret;
+
+ /* Wait for the pending transactions to be completed */
+ ret = readl_relaxed_poll_timeout(pcie->parf + PARF_STATUS, val,
+ val & FLUSH_COMPLETED, 10,
+ FLUSH_TIMEOUT_US);
+ if (ret) {
+ dev_err(dev, "Flush completion failed: %d\n", ret);
+ goto err_host_deinit;
+ }
+
+ /* Clear the FLUSH_MODE to allow the core to be reset */
+ val = readl(pcie->parf + PARF_LTSSM);
+ val |= SW_CLEAR_FLUSH_MODE;
+ writel(val, pcie->parf + PARF_LTSSM);
+
+ /* Wait for the FLUSH_MODE to clear */
+ ret = readl_relaxed_poll_timeout(pcie->parf + PARF_LTSSM, val,
+ !(val & FLUSH_MODE), 10,
+ FLUSH_TIMEOUT_US);
+ if (ret) {
+ dev_err(dev, "Flush mode clear failed: %d\n", ret);
+ goto err_host_deinit;
+ }
+
+ qcom_pcie_host_deinit(pp);
+
+ ret = qcom_pcie_host_init(pp);
+ if (ret) {
+ dev_err(dev, "Host init failed\n");
+ return ret;
+ }
+
+ ret = dw_pcie_setup_rc(pp);
+ if (ret)
+ goto err_host_deinit;
+
+ /*
+ * Re-enable global IRQ events as the PARF_INT_ALL_MASK register is
+ * non-sticky.
+ */
+ if (pcie->global_irq)
+ writel_relaxed(PARF_INT_ALL_LINK_DOWN | PARF_INT_MSI_DEV_0_7,
+ pcie->parf + PARF_INT_ALL_MASK);
+
+ qcom_pcie_start_link(pci);
+ dw_pcie_wait_for_link(pci);
+
+ dev_dbg(dev, "Root Port reset completed\n");
+
+ return 0;
+
+err_host_deinit:
+ qcom_pcie_host_deinit(pp);
+
+ return ret;
+}
+
static int qcom_pcie_link_transition_count(struct seq_file *s, void *data)
{
struct qcom_pcie *pcie = (struct qcom_pcie *)dev_get_drvdata(s->private);
@@ -1645,6 +1737,27 @@ static void qcom_pcie_init_debugfs(struct qcom_pcie *pcie)
qcom_pcie_link_transition_count);
}
+static irqreturn_t qcom_pcie_global_irq_thread(int irq, void *data)
+{
+ struct qcom_pcie *pcie = data;
+ struct dw_pcie_rp *pp = &pcie->pci->pp;
+ struct device *dev = pcie->pci->dev;
+ struct pci_dev *port;
+ unsigned long status = readl_relaxed(pcie->parf + PARF_INT_ALL_STATUS);
+
+ writel_relaxed(status, pcie->parf + PARF_INT_ALL_CLEAR);
+
+ if (test_and_clear_bit(INT_ALL_LINK_DOWN, &status)) {
+ dev_dbg(dev, "Received Link down event\n");
+ for_each_pci_bridge(port, pp->bridge->bus) {
+ if (pci_pcie_type(port) == PCI_EXP_TYPE_ROOT_PORT)
+ pci_host_handle_link_down(port);
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
static void qcom_pci_free_msi(void *ptr)
{
struct dw_pcie_rp *pp = (struct dw_pcie_rp *)ptr;
@@ -1847,7 +1960,7 @@ static int qcom_pcie_probe(struct platform_device *pdev)
struct dw_pcie_rp *pp;
struct resource *res;
struct dw_pcie *pci;
- int ret;
+ int ret, irq;
pcie_cfg = of_device_get_match_data(dev);
if (!pcie_cfg) {
@@ -2004,6 +2117,32 @@ static int qcom_pcie_probe(struct platform_device *pdev)
goto err_phy_exit;
}
+ irq = platform_get_irq_byname_optional(pdev, "global");
+ if (irq > 0) {
+ const char *name;
+
+ name = devm_kasprintf(dev, GFP_KERNEL, "qcom_pcie_global_irq%d",
+ pci_domain_nr(pp->bridge->bus));
+ if (!name) {
+ ret = -ENOMEM;
+ goto err_host_deinit;
+ }
+
+ ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
+ qcom_pcie_global_irq_thread,
+ IRQF_ONESHOT, name, pcie);
+ if (ret) {
+ dev_err_probe(&pdev->dev, ret,
+ "Failed to request Global IRQ\n");
+ goto err_host_deinit;
+ }
+
+ writel_relaxed(PARF_INT_ALL_LINK_DOWN | PARF_INT_MSI_DEV_0_7,
+ pcie->parf + PARF_INT_ALL_MASK);
+
+ pcie->global_irq = irq;
+ }
+
qcom_pcie_icc_opp_update(pcie);
if (pcie->mhi)
@@ -2011,6 +2150,8 @@ static int qcom_pcie_probe(struct platform_device *pdev)
return 0;
+err_host_deinit:
+ dw_pcie_host_deinit(pp);
err_phy_exit:
list_for_each_entry_safe(port, tmp_port, &pcie->ports, list) {
list_for_each_entry_safe(perst, tmp_perst, &port->perst, list)
--
2.51.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v7 4/4] misc: pci_endpoint_test: Add AER error handlers
2026-03-10 14:01 [PATCH v7 0/4] PCI: Add support for resetting the Root Ports in a platform specific way Manivannan Sadhasivam via B4 Relay
` (2 preceding siblings ...)
2026-03-10 14:02 ` [PATCH v7 3/4] PCI: qcom: Add support for resetting the Root Port due to link down event Manivannan Sadhasivam via B4 Relay
@ 2026-03-10 14:02 ` Manivannan Sadhasivam via B4 Relay
2026-03-11 8:37 ` [PATCH v7 0/4] PCI: Add support for resetting the Root Ports in a platform specific way Krishna Chaitanya Chundru
` (2 subsequent siblings)
6 siblings, 0 replies; 16+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2026-03-10 14:02 UTC (permalink / raw)
To: Bjorn Helgaas, Mahesh J Salgaonkar, Oliver O'Halloran,
Will Deacon, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Rob Herring, Heiko Stuebner, Philipp Zabel
Cc: linux-pci, linux-kernel, linuxppc-dev, linux-arm-kernel,
linux-arm-msm, linux-rockchip, Niklas Cassel, Wilfred Mallawa,
Krishna Chaitanya Chundru, mani, Lukas Wunner, Richard Zhu,
Brian Norris, Wilson Ding, Manivannan Sadhasivam
From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
This Endpoint test driver doesn't need to do anything fancy in its error
handlers, but just report the correct result. This helps in making sure
that the AER recovery succeeds. Otherwise, AER recovery results in below
log:
AER: device recovery failed
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
drivers/misc/pci_endpoint_test.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
index 74ab5b5b9011..4024fd72fc66 100644
--- a/drivers/misc/pci_endpoint_test.c
+++ b/drivers/misc/pci_endpoint_test.c
@@ -1422,12 +1422,32 @@ static const struct pci_device_id pci_endpoint_test_tbl[] = {
};
MODULE_DEVICE_TABLE(pci, pci_endpoint_test_tbl);
+static pci_ers_result_t pci_endpoint_test_error_detected(struct pci_dev *pdev,
+ pci_channel_state_t state)
+{
+ if (state == pci_channel_io_perm_failure)
+ return PCI_ERS_RESULT_DISCONNECT;
+
+ return PCI_ERS_RESULT_NEED_RESET;
+}
+
+static pci_ers_result_t pci_endpoint_test_slot_reset(struct pci_dev *pdev)
+{
+ return PCI_ERS_RESULT_RECOVERED;
+}
+
+static const struct pci_error_handlers pci_endpoint_test_err_handler = {
+ .error_detected = pci_endpoint_test_error_detected,
+ .slot_reset = pci_endpoint_test_slot_reset,
+};
+
static struct pci_driver pci_endpoint_test_driver = {
.name = DRV_MODULE_NAME,
.id_table = pci_endpoint_test_tbl,
.probe = pci_endpoint_test_probe,
.remove = pci_endpoint_test_remove,
.sriov_configure = pci_sriov_configure_simple,
+ .err_handler = &pci_endpoint_test_err_handler,
};
module_pci_driver(pci_endpoint_test_driver);
--
2.51.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v7 2/4] PCI: host-common: Add link down handling for Root Ports
2026-03-10 14:02 ` [PATCH v7 2/4] PCI: host-common: Add link down handling for Root Ports Manivannan Sadhasivam via B4 Relay
@ 2026-03-11 0:55 ` Shawn Lin
2026-03-11 5:04 ` Manivannan Sadhasivam
0 siblings, 1 reply; 16+ messages in thread
From: Shawn Lin @ 2026-03-11 0:55 UTC (permalink / raw)
To: manivannan.sadhasivam, Bjorn Helgaas, Mahesh J Salgaonkar,
Oliver O'Halloran, Will Deacon, Lorenzo Pieralisi,
Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
Heiko Stuebner, Philipp Zabel
Cc: shawn.lin, linux-pci, linux-kernel, linuxppc-dev,
linux-arm-kernel, linux-arm-msm, linux-rockchip, Niklas Cassel,
Wilfred Mallawa, Krishna Chaitanya Chundru, Lukas Wunner,
Richard Zhu, Brian Norris, Wilson Ding, Frank Li
Hi Mani
在 2026/03/10 星期二 22:02, Manivannan Sadhasivam via B4 Relay 写道:
> From: Manivannan Sadhasivam <mani@kernel.org>
>
> The PCI link, when down, needs to be recovered to bring it back. But on
> some platforms, that cannot be done in a generic way as link recovery
> procedure is platform specific. So add a new API
> pci_host_handle_link_down() that could be called by the host bridge drivers
> for a specific Root Port when the link goes down.
>
> The API accepts the 'pci_dev' corresponding to the Root Port which observed
> the link down event. If CONFIG_PCIEAER is enabled, the API calls
> pcie_do_recovery() function with 'pci_channel_io_frozen' as the state. This
> will result in the execution of the AER Fatal error handling code. Since
> the link down recovery is pretty much the same as AER Fatal error handling,
> pcie_do_recovery() helper is reused here. First, the AER error_detected()
> callback will be triggered for the bridge and then for the downstream
> devices. Finally, pci_host_reset_root_port() will be called for the Root
> Port, which will reset the Root Port using 'reset_root_port' callback to
> recover the link. Once that's done, resume message will be broadcasted to
> the bridge and the downstream devices, indicating successful link recovery.
>
> But if CONFIG_PCIEAER is not enabled in the kernel, only
> pci_host_reset_root_port() API will be called, which will in turn call
> pci_bus_error_reset() to just reset the Root Port as there is no way we
> could inform the drivers about link recovery.
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> Tested-by: Brian Norris <briannorris@chromium.org>
> Tested-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
> Tested-by: Richard Zhu <hongxing.zhu@nxp.com>
> Reviewed-by: Frank Li <Frank.Li@nxp.com>
> ---
> drivers/pci/controller/pci-host-common.c | 35 ++++++++++++++++++++++++++++++++
> drivers/pci/controller/pci-host-common.h | 1 +
> drivers/pci/pci.c | 1 +
> drivers/pci/pcie/err.c | 1 +
> 4 files changed, 38 insertions(+)
>
> diff --git a/drivers/pci/controller/pci-host-common.c b/drivers/pci/controller/pci-host-common.c
> index d6258c1cffe5..15ebff8a542a 100644
> --- a/drivers/pci/controller/pci-host-common.c
> +++ b/drivers/pci/controller/pci-host-common.c
> @@ -12,9 +12,11 @@
> #include <linux/of.h>
> #include <linux/of_address.h>
> #include <linux/of_pci.h>
> +#include <linux/pci.h>
> #include <linux/pci-ecam.h>
> #include <linux/platform_device.h>
>
> +#include "../pci.h"
> #include "pci-host-common.h"
>
> static void gen_pci_unmap_cfg(void *ptr)
> @@ -106,5 +108,38 @@ void pci_host_common_remove(struct platform_device *pdev)
> }
> EXPORT_SYMBOL_GPL(pci_host_common_remove);
>
> +static pci_ers_result_t pci_host_reset_root_port(struct pci_dev *dev)
> +{
> + int ret;
> +
> + pci_lock_rescan_remove();
> + ret = pci_bus_error_reset(dev);
> + pci_unlock_rescan_remove();
> + if (ret) {
> + pci_err(dev, "Failed to reset Root Port: %d\n", ret);
> + return PCI_ERS_RESULT_DISCONNECT;
> + }
> +
> + pci_info(dev, "Root Port has been reset\n");
> +
> + return PCI_ERS_RESULT_RECOVERED;
> +}
> +
> +static void pci_host_recover_root_port(struct pci_dev *port)
> +{
> +#if IS_ENABLED(CONFIG_PCIEAER)
> + pcie_do_recovery(port, pci_channel_io_frozen, pci_host_reset_root_port);
> +#else
> + pci_host_reset_root_port(port);
Since pci_host_reset_root_port() returns pci_ers_result_t, shouldn't we
check the result? If the return value is intentionally ignored here,
maybe pci_host_reset_root_port actually doesn't need a return value at
all?
> +#endif
> +}
> +
> +void pci_host_handle_link_down(struct pci_dev *port)
> +{
> + pci_info(port, "Recovering Root Port due to Link Down\n");
> + pci_host_recover_root_port(port);
> +}
> +EXPORT_SYMBOL_GPL(pci_host_handle_link_down);
This function shouldn't be called like in interrupt context because of
the pci_lock_rescan_remove() and pci_bus_error_reset()::pci_slot_mutex,
but it's not so obvious from the API name. It's prone for host drivers
to use it like:
register_LDn_irq -> irq isr -> pci_host_handle_link_down()
So perhaps add a comment about it would be better.
> +
> MODULE_DESCRIPTION("Common library for PCI host controller drivers");
> MODULE_LICENSE("GPL v2");
> diff --git a/drivers/pci/controller/pci-host-common.h b/drivers/pci/controller/pci-host-common.h
> index b5075d4bd7eb..dd12dd1a1b23 100644
> --- a/drivers/pci/controller/pci-host-common.h
> +++ b/drivers/pci/controller/pci-host-common.h
> @@ -17,6 +17,7 @@ int pci_host_common_init(struct platform_device *pdev,
> struct pci_host_bridge *bridge,
> const struct pci_ecam_ops *ops);
> void pci_host_common_remove(struct platform_device *pdev);
> +void pci_host_handle_link_down(struct pci_dev *port);
>
> struct pci_config_window *pci_host_common_ecam_create(struct device *dev,
> struct pci_host_bridge *bridge, const struct pci_ecam_ops *ops);
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index 6f09057d83e0..1b37bfe6d079 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -5650,6 +5650,7 @@ int pci_bus_error_reset(struct pci_dev *bridge)
> mutex_unlock(&pci_slot_mutex);
> return pci_bus_reset(bridge->subordinate, PCI_RESET_DO_RESET);
> }
> +EXPORT_SYMBOL_GPL(pci_bus_error_reset);
>
> /**
> * pci_probe_reset_bus - probe whether a PCI bus can be reset
> diff --git a/drivers/pci/pcie/err.c b/drivers/pci/pcie/err.c
> index 13b9d9eb714f..d77403d8855b 100644
> --- a/drivers/pci/pcie/err.c
> +++ b/drivers/pci/pcie/err.c
> @@ -292,3 +292,4 @@ pci_ers_result_t pcie_do_recovery(struct pci_dev *dev,
>
> return status;
> }
> +EXPORT_SYMBOL_GPL(pcie_do_recovery);
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v7 2/4] PCI: host-common: Add link down handling for Root Ports
2026-03-11 0:55 ` Shawn Lin
@ 2026-03-11 5:04 ` Manivannan Sadhasivam
2026-03-11 5:20 ` Shawn Lin
0 siblings, 1 reply; 16+ messages in thread
From: Manivannan Sadhasivam @ 2026-03-11 5:04 UTC (permalink / raw)
To: Shawn Lin
Cc: manivannan.sadhasivam, Bjorn Helgaas, Mahesh J Salgaonkar,
Oliver O'Halloran, Will Deacon, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Heiko Stuebner,
Philipp Zabel, linux-pci, linux-kernel, linuxppc-dev,
linux-arm-kernel, linux-arm-msm, linux-rockchip, Niklas Cassel,
Wilfred Mallawa, Krishna Chaitanya Chundru, Lukas Wunner,
Richard Zhu, Brian Norris, Wilson Ding, Frank Li
On Wed, Mar 11, 2026 at 08:55:01AM +0800, Shawn Lin wrote:
> Hi Mani
>
> 在 2026/03/10 星期二 22:02, Manivannan Sadhasivam via B4 Relay 写道:
> > From: Manivannan Sadhasivam <mani@kernel.org>
> >
> > The PCI link, when down, needs to be recovered to bring it back. But on
> > some platforms, that cannot be done in a generic way as link recovery
> > procedure is platform specific. So add a new API
> > pci_host_handle_link_down() that could be called by the host bridge drivers
> > for a specific Root Port when the link goes down.
> >
> > The API accepts the 'pci_dev' corresponding to the Root Port which observed
> > the link down event. If CONFIG_PCIEAER is enabled, the API calls
> > pcie_do_recovery() function with 'pci_channel_io_frozen' as the state. This
> > will result in the execution of the AER Fatal error handling code. Since
> > the link down recovery is pretty much the same as AER Fatal error handling,
> > pcie_do_recovery() helper is reused here. First, the AER error_detected()
> > callback will be triggered for the bridge and then for the downstream
> > devices. Finally, pci_host_reset_root_port() will be called for the Root
> > Port, which will reset the Root Port using 'reset_root_port' callback to
> > recover the link. Once that's done, resume message will be broadcasted to
> > the bridge and the downstream devices, indicating successful link recovery.
> >
> > But if CONFIG_PCIEAER is not enabled in the kernel, only
> > pci_host_reset_root_port() API will be called, which will in turn call
> > pci_bus_error_reset() to just reset the Root Port as there is no way we
> > could inform the drivers about link recovery.
> >
> > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> > Tested-by: Brian Norris <briannorris@chromium.org>
> > Tested-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
> > Tested-by: Richard Zhu <hongxing.zhu@nxp.com>
> > Reviewed-by: Frank Li <Frank.Li@nxp.com>
> > ---
> > drivers/pci/controller/pci-host-common.c | 35 ++++++++++++++++++++++++++++++++
> > drivers/pci/controller/pci-host-common.h | 1 +
> > drivers/pci/pci.c | 1 +
> > drivers/pci/pcie/err.c | 1 +
> > 4 files changed, 38 insertions(+)
> >
> > diff --git a/drivers/pci/controller/pci-host-common.c b/drivers/pci/controller/pci-host-common.c
> > index d6258c1cffe5..15ebff8a542a 100644
> > --- a/drivers/pci/controller/pci-host-common.c
> > +++ b/drivers/pci/controller/pci-host-common.c
> > @@ -12,9 +12,11 @@
> > #include <linux/of.h>
> > #include <linux/of_address.h>
> > #include <linux/of_pci.h>
> > +#include <linux/pci.h>
> > #include <linux/pci-ecam.h>
> > #include <linux/platform_device.h>
> > +#include "../pci.h"
> > #include "pci-host-common.h"
> > static void gen_pci_unmap_cfg(void *ptr)
> > @@ -106,5 +108,38 @@ void pci_host_common_remove(struct platform_device *pdev)
> > }
> > EXPORT_SYMBOL_GPL(pci_host_common_remove);
> > +static pci_ers_result_t pci_host_reset_root_port(struct pci_dev *dev)
> > +{
> > + int ret;
> > +
> > + pci_lock_rescan_remove();
> > + ret = pci_bus_error_reset(dev);
> > + pci_unlock_rescan_remove();
> > + if (ret) {
> > + pci_err(dev, "Failed to reset Root Port: %d\n", ret);
> > + return PCI_ERS_RESULT_DISCONNECT;
> > + }
> > +
> > + pci_info(dev, "Root Port has been reset\n");
> > +
> > + return PCI_ERS_RESULT_RECOVERED;
> > +}
> > +
> > +static void pci_host_recover_root_port(struct pci_dev *port)
> > +{
> > +#if IS_ENABLED(CONFIG_PCIEAER)
> > + pcie_do_recovery(port, pci_channel_io_frozen, pci_host_reset_root_port);
> > +#else
> > + pci_host_reset_root_port(port);
>
> Since pci_host_reset_root_port() returns pci_ers_result_t, shouldn't we
> check the result? If the return value is intentionally ignored here,
> maybe pci_host_reset_root_port actually doesn't need a return value at
> all?
>
The return value is mostly for pcie_do_recovery() which iterates through the
subordinate devices and calls pci_host_reset_root_port(). It also makes use of
the return value, so we cannot make it void.
The reason why I skipped the return value in pci_host_handle_link_down() is
that, we canot do much in the case of failure other than reporting the failure,
which is already taken care in pci_host_reset_root_port().
> > +#endif
> > +}
> > +
> > +void pci_host_handle_link_down(struct pci_dev *port)
> > +{
> > + pci_info(port, "Recovering Root Port due to Link Down\n");
> > + pci_host_recover_root_port(port);
> > +}
> > +EXPORT_SYMBOL_GPL(pci_host_handle_link_down);
>
> This function shouldn't be called like in interrupt context because of
> the pci_lock_rescan_remove() and pci_bus_error_reset()::pci_slot_mutex,
> but it's not so obvious from the API name. It's prone for host drivers
> to use it like:
>
> register_LDn_irq -> irq isr -> pci_host_handle_link_down()
>
> So perhaps add a comment about it would be better.
>
Yes, I agree. I mentioned in the cover letter that this API should be called
from a threaded IRQ handler, but it should be mentioned in the API description
too. I will add it in next version or ammend it while applying.
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v7 2/4] PCI: host-common: Add link down handling for Root Ports
2026-03-11 5:04 ` Manivannan Sadhasivam
@ 2026-03-11 5:20 ` Shawn Lin
0 siblings, 0 replies; 16+ messages in thread
From: Shawn Lin @ 2026-03-11 5:20 UTC (permalink / raw)
To: Manivannan Sadhasivam
Cc: shawn.lin, manivannan.sadhasivam, Bjorn Helgaas,
Mahesh J Salgaonkar, Oliver O'Halloran, Will Deacon,
Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring,
Heiko Stuebner, Philipp Zabel, linux-pci, linux-kernel,
linuxppc-dev, linux-arm-kernel, linux-arm-msm, linux-rockchip,
Niklas Cassel, Wilfred Mallawa, Krishna Chaitanya Chundru,
Lukas Wunner, Richard Zhu, Brian Norris, Wilson Ding, Frank Li
在 2026/03/11 星期三 13:04, Manivannan Sadhasivam 写道:
> On Wed, Mar 11, 2026 at 08:55:01AM +0800, Shawn Lin wrote:
>> Hi Mani
>>
>> 在 2026/03/10 星期二 22:02, Manivannan Sadhasivam via B4 Relay 写道:
>>> From: Manivannan Sadhasivam <mani@kernel.org>
>>>
>>> The PCI link, when down, needs to be recovered to bring it back. But on
>>> some platforms, that cannot be done in a generic way as link recovery
>>> procedure is platform specific. So add a new API
>>> pci_host_handle_link_down() that could be called by the host bridge drivers
>>> for a specific Root Port when the link goes down.
>>>
>>> The API accepts the 'pci_dev' corresponding to the Root Port which observed
>>> the link down event. If CONFIG_PCIEAER is enabled, the API calls
>>> pcie_do_recovery() function with 'pci_channel_io_frozen' as the state. This
>>> will result in the execution of the AER Fatal error handling code. Since
>>> the link down recovery is pretty much the same as AER Fatal error handling,
>>> pcie_do_recovery() helper is reused here. First, the AER error_detected()
>>> callback will be triggered for the bridge and then for the downstream
>>> devices. Finally, pci_host_reset_root_port() will be called for the Root
>>> Port, which will reset the Root Port using 'reset_root_port' callback to
>>> recover the link. Once that's done, resume message will be broadcasted to
>>> the bridge and the downstream devices, indicating successful link recovery.
>>>
>>> But if CONFIG_PCIEAER is not enabled in the kernel, only
>>> pci_host_reset_root_port() API will be called, which will in turn call
>>> pci_bus_error_reset() to just reset the Root Port as there is no way we
>>> could inform the drivers about link recovery.
>>>
>>> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
>>> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
>>> Tested-by: Brian Norris <briannorris@chromium.org>
>>> Tested-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
>>> Tested-by: Richard Zhu <hongxing.zhu@nxp.com>
>>> Reviewed-by: Frank Li <Frank.Li@nxp.com>
>>> ---
>>> drivers/pci/controller/pci-host-common.c | 35 ++++++++++++++++++++++++++++++++
>>> drivers/pci/controller/pci-host-common.h | 1 +
>>> drivers/pci/pci.c | 1 +
>>> drivers/pci/pcie/err.c | 1 +
>>> 4 files changed, 38 insertions(+)
>>>
>>> diff --git a/drivers/pci/controller/pci-host-common.c b/drivers/pci/controller/pci-host-common.c
>>> index d6258c1cffe5..15ebff8a542a 100644
>>> --- a/drivers/pci/controller/pci-host-common.c
>>> +++ b/drivers/pci/controller/pci-host-common.c
>>> @@ -12,9 +12,11 @@
>>> #include <linux/of.h>
>>> #include <linux/of_address.h>
>>> #include <linux/of_pci.h>
>>> +#include <linux/pci.h>
>>> #include <linux/pci-ecam.h>
>>> #include <linux/platform_device.h>
>>> +#include "../pci.h"
>>> #include "pci-host-common.h"
>>> static void gen_pci_unmap_cfg(void *ptr)
>>> @@ -106,5 +108,38 @@ void pci_host_common_remove(struct platform_device *pdev)
>>> }
>>> EXPORT_SYMBOL_GPL(pci_host_common_remove);
>>> +static pci_ers_result_t pci_host_reset_root_port(struct pci_dev *dev)
>>> +{
>>> + int ret;
>>> +
>>> + pci_lock_rescan_remove();
>>> + ret = pci_bus_error_reset(dev);
>>> + pci_unlock_rescan_remove();
>>> + if (ret) {
>>> + pci_err(dev, "Failed to reset Root Port: %d\n", ret);
>>> + return PCI_ERS_RESULT_DISCONNECT;
>>> + }
>>> +
>>> + pci_info(dev, "Root Port has been reset\n");
>>> +
>>> + return PCI_ERS_RESULT_RECOVERED;
>>> +}
>>> +
>>> +static void pci_host_recover_root_port(struct pci_dev *port)
>>> +{
>>> +#if IS_ENABLED(CONFIG_PCIEAER)
>>> + pcie_do_recovery(port, pci_channel_io_frozen, pci_host_reset_root_port);
>>> +#else
>>> + pci_host_reset_root_port(port);
>>
>> Since pci_host_reset_root_port() returns pci_ers_result_t, shouldn't we
>> check the result? If the return value is intentionally ignored here,
>> maybe pci_host_reset_root_port actually doesn't need a return value at
>> all?
>>
>
> The return value is mostly for pcie_do_recovery() which iterates through the
> subordinate devices and calls pci_host_reset_root_port(). It also makes use of
> the return value, so we cannot make it void.
>
> The reason why I skipped the return value in pci_host_handle_link_down() is
> that, we canot do much in the case of failure other than reporting the failure,
> which is already taken care in pci_host_reset_root_port().
>
Ok, it makes sense to me, thanks for the explanation.
Feel free to add:
Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com>
>>> +#endif
>>> +}
>>> +
>>> +void pci_host_handle_link_down(struct pci_dev *port)
>>> +{
>>> + pci_info(port, "Recovering Root Port due to Link Down\n");
>>> + pci_host_recover_root_port(port);
>>> +}
>>> +EXPORT_SYMBOL_GPL(pci_host_handle_link_down);
>>
>> This function shouldn't be called like in interrupt context because of
>> the pci_lock_rescan_remove() and pci_bus_error_reset()::pci_slot_mutex,
>> but it's not so obvious from the API name. It's prone for host drivers
>> to use it like:
>>
>> register_LDn_irq -> irq isr -> pci_host_handle_link_down()
>>
>> So perhaps add a comment about it would be better.
>>
>
> Yes, I agree. I mentioned in the cover letter that this API should be called
> from a threaded IRQ handler, but it should be mentioned in the API description
> too. I will add it in next version or ammend it while applying.
>
> - Mani
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v7 1/4] PCI/ERR: Add support for resetting the Root Ports in a platform specific way
2026-03-10 14:01 ` [PATCH v7 1/4] PCI/ERR: " Manivannan Sadhasivam via B4 Relay
@ 2026-03-11 5:26 ` Shawn Lin
0 siblings, 0 replies; 16+ messages in thread
From: Shawn Lin @ 2026-03-11 5:26 UTC (permalink / raw)
To: manivannan.sadhasivam, Bjorn Helgaas, Mahesh J Salgaonkar,
Oliver O'Halloran, Will Deacon, Lorenzo Pieralisi,
Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
Heiko Stuebner, Philipp Zabel
Cc: shawn.lin, linux-pci, linux-kernel, linuxppc-dev,
linux-arm-kernel, linux-arm-msm, linux-rockchip, Niklas Cassel,
Wilfred Mallawa, Krishna Chaitanya Chundru, Lukas Wunner,
Richard Zhu, Brian Norris, Wilson Ding, Frank Li
在 2026/03/10 星期二 22:01, Manivannan Sadhasivam via B4 Relay 写道:
> From: Manivannan Sadhasivam <mani@kernel.org>
>
> Some host bridge devices require resetting the Root Ports in a platform
> specific way to recover them from error conditions such as Fatal AER
> errors, Link Down etc... So introduce pci_host_bridge::reset_root_port()
> callback and call it from pcibios_reset_secondary_bus() if available. Also,
> save the Root Port config space before reset and restore it afterwards.
>
> The 'reset_root_port' callback is responsible for resetting the given Root
> Port referenced by the 'pci_dev' pointer in a platform specific way and
> bring it back to the working state if possible. If any error occurs during
> the reset operation, relevant errno should be returned.
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> Tested-by: Brian Norris <briannorris@chromium.org>
> Tested-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
> Tested-by: Richard Zhu <hongxing.zhu@nxp.com>
> Reviewed-by: Frank Li <Frank.Li@nxp.com>
> ---
> drivers/pci/pci.c | 20 ++++++++++++++++++++
> drivers/pci/pcie/err.c | 5 -----
> include/linux/pci.h | 1 +
> 3 files changed, 21 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index 8479c2e1f74f..6f09057d83e0 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -4812,6 +4812,26 @@ void pci_reset_secondary_bus(struct pci_dev *dev)
>
> void __weak pcibios_reset_secondary_bus(struct pci_dev *dev)
> {
> + struct pci_host_bridge *host = pci_find_host_bridge(dev->bus);
> + int ret;
> +
> + if (pci_is_root_bus(dev->bus) && host->reset_root_port) {
> + /*
> + * Save the config space of the Root Port before doing the
> + * reset, since the state could be lost. The Endpoint state
> + * should've been saved by the caller.
> + */
> + pci_save_state(dev);
> + ret = host->reset_root_port(host, dev);
> + if (ret)
> + pci_err(dev, "Failed to reset Root Port: %d\n", ret);
> + else
> + /* Now restore it on success */
> + pci_restore_state(dev);
> +
> + return;
> + }
> +
> pci_reset_secondary_bus(dev);
> }
>
LGTM,
Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com>
> diff --git a/drivers/pci/pcie/err.c b/drivers/pci/pcie/err.c
> index bebe4bc111d7..13b9d9eb714f 100644
> --- a/drivers/pci/pcie/err.c
> +++ b/drivers/pci/pcie/err.c
> @@ -256,11 +256,6 @@ pci_ers_result_t pcie_do_recovery(struct pci_dev *dev,
> }
>
> if (status == PCI_ERS_RESULT_NEED_RESET) {
> - /*
> - * TODO: Should call platform-specific
> - * functions to reset slot before calling
> - * drivers' slot_reset callbacks?
> - */
> status = PCI_ERS_RESULT_RECOVERED;
> pci_dbg(bridge, "broadcast slot_reset message\n");
> pci_walk_bridge(bridge, report_slot_reset, &status);
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 1c270f1d5123..34c434b79abb 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -644,6 +644,7 @@ struct pci_host_bridge {
> void (*release_fn)(struct pci_host_bridge *);
> int (*enable_device)(struct pci_host_bridge *bridge, struct pci_dev *dev);
> void (*disable_device)(struct pci_host_bridge *bridge, struct pci_dev *dev);
> + int (*reset_root_port)(struct pci_host_bridge *bridge, struct pci_dev *dev);
> void *release_data;
> unsigned int ignore_reset_delay:1; /* For entire hierarchy */
> unsigned int no_ext_tags:1; /* No Extended Tags */
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v7 0/4] PCI: Add support for resetting the Root Ports in a platform specific way
2026-03-10 14:01 [PATCH v7 0/4] PCI: Add support for resetting the Root Ports in a platform specific way Manivannan Sadhasivam via B4 Relay
` (3 preceding siblings ...)
2026-03-10 14:02 ` [PATCH v7 4/4] misc: pci_endpoint_test: Add AER error handlers Manivannan Sadhasivam via B4 Relay
@ 2026-03-11 8:37 ` Krishna Chaitanya Chundru
2026-03-11 11:05 ` Niklas Cassel
2026-03-25 7:06 ` Hongxing Zhu
6 siblings, 0 replies; 16+ messages in thread
From: Krishna Chaitanya Chundru @ 2026-03-11 8:37 UTC (permalink / raw)
To: manivannan.sadhasivam, Bjorn Helgaas, Mahesh J Salgaonkar,
Oliver O'Halloran, Will Deacon, Lorenzo Pieralisi,
Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
Heiko Stuebner, Philipp Zabel
Cc: linux-pci, linux-kernel, linuxppc-dev, linux-arm-kernel,
linux-arm-msm, linux-rockchip, Niklas Cassel, Wilfred Mallawa,
Lukas Wunner, Richard Zhu, Brian Norris, Wilson Ding, Frank Li
On 3/10/2026 7:31 PM, Manivannan Sadhasivam via B4 Relay wrote:
> Hi,
>
> Currently, in the event of AER/DPC, PCI core will try to reset the slot (Root
> Port) and its subordinate devices by invoking bridge control reset and FLR. But
> in some cases like AER Fatal error, it might be necessary to reset the Root
> Ports using the PCI host bridge drivers in a platform specific way (as indicated
> by the TODO in the pcie_do_recovery() function in drivers/pci/pcie/err.c).
> Otherwise, the PCI link won't be recovered successfully.
>
> So this series adds a new callback 'pci_host_bridge::reset_root_port' for the
> host bridge drivers to reset the Root Port when a fatal error happens.
>
> Also, this series allows the host bridge drivers to handle PCI link down event
> by resetting the Root Ports and recovering the bus. This is accomplished by the
> help of the new 'pci_host_handle_link_down()' API. Host bridge drivers are
> expected to call this API (preferrably from a threaded IRQ handler) with
> relevant Root Port 'pci_dev' when a link down event is detected for the port.
> The API will reuse the pcie_do_recovery() function to recover the link if AER
> support is enabled, otherwise it will directly call the reset_root_port()
> callback of the host bridge driver (if exists).
>
> For reference, I've modified the pcie-qcom driver to call
> pci_host_handle_link_down() API with Root Port 'pci_dev' after receiving the
> LDn global_irq event and populated 'pci_host_bridge::reset_root_port()'
> callback to reset the Root Ports.
>
> Testing
> -------
>
> Tested on Qcom Lemans AU Ride platform with Host and EP SoCs connected over PCIe
> link. Simulated the LDn by disabling LTSSM_EN on the EP and I could verify that
> the link was getting recovered successfully.
>
> Changes in v7:
> - Dropped Rockchip Root port reset patch due to reported issues. But the series
> works on other platforms as tested by others.
> - Added pci_{lock/unlock}_rescan_remove() to guard pci_bus_error_reset() as the
> device could be removed in-between due to Native hotplug interrupt.
> - Rebased on top of v7.0-rc1
> - Link to v6: https://lore.kernel.org/r/20250715-pci-port-reset-v6-0-6f9cce94e7bb@oss.qualcomm.com
>
> Changes in v6:
> - Incorporated the patch: https://lore.kernel.org/all/20250524185304.26698-2-manivannan.sadhasivam@linaro.org/
> - Link to v5: https://lore.kernel.org/r/20250715-pci-port-reset-v5-0-26a5d278db40@oss.qualcomm.com
>
> Changes in v5:
> * Reworked the pci_host_handle_link_down() to accept Root Port instead of
> resetting all Root Ports in the event of link down.
> * Renamed 'reset_slot' to 'reset_root_port' to avoid confusion as both terms
> were used interchangibly and the series is intended to reset Root Port only.
> * Added the Rockchip driver change to this series.
> * Dropped the applied patches and review/tested tags due to rework.
> * Rebased on top of v6.16-rc1.
>
> Changes in v4:
> - Handled link down first in the irq handler
> - Updated ICC & OPP bandwidth after link up in reset_slot() callback
> - Link to v3: https://lore.kernel.org/r/20250417-pcie-reset-slot-v3-0-59a10811c962@linaro.org
>
> Changes in v3:
> - Made the pci-host-common driver as a common library for host controller
> drivers
> - Moved the reset slot code to pci-host-common library
> - Link to v2: https://lore.kernel.org/r/20250416-pcie-reset-slot-v2-0-efe76b278c10@linaro.org
>
> Changes in v2:
> - Moved calling reset_slot() callback from pcie_do_recovery() to pcibios_reset_secondary_bus()
> - Link to v1: https://lore.kernel.org/r/20250404-pcie-reset-slot-v1-0-98952918bf90@linaro.org
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
For entire series,
Reviewed-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
- Krishna Chaitanya.
> ---
> Manivannan Sadhasivam (4):
> PCI/ERR: Add support for resetting the Root Ports in a platform specific way
> PCI: host-common: Add link down handling for Root Ports
> PCI: qcom: Add support for resetting the Root Port due to link down event
> misc: pci_endpoint_test: Add AER error handlers
>
> drivers/misc/pci_endpoint_test.c | 20 +++++
> drivers/pci/controller/dwc/pcie-qcom.c | 143 ++++++++++++++++++++++++++++++-
> drivers/pci/controller/pci-host-common.c | 35 ++++++++
> drivers/pci/controller/pci-host-common.h | 1 +
> drivers/pci/pci.c | 21 +++++
> drivers/pci/pcie/err.c | 6 +-
> include/linux/pci.h | 1 +
> 7 files changed, 221 insertions(+), 6 deletions(-)
> ---
> base-commit: 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f
> change-id: 20250715-pci-port-reset-4d9519570123
>
> Best regards,
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v7 0/4] PCI: Add support for resetting the Root Ports in a platform specific way
2026-03-10 14:01 [PATCH v7 0/4] PCI: Add support for resetting the Root Ports in a platform specific way Manivannan Sadhasivam via B4 Relay
` (4 preceding siblings ...)
2026-03-11 8:37 ` [PATCH v7 0/4] PCI: Add support for resetting the Root Ports in a platform specific way Krishna Chaitanya Chundru
@ 2026-03-11 11:05 ` Niklas Cassel
2026-03-11 14:39 ` Manivannan Sadhasivam
2026-03-25 7:06 ` Hongxing Zhu
6 siblings, 1 reply; 16+ messages in thread
From: Niklas Cassel @ 2026-03-11 11:05 UTC (permalink / raw)
To: manivannan.sadhasivam
Cc: Bjorn Helgaas, Mahesh J Salgaonkar, Oliver O'Halloran,
Will Deacon, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Rob Herring, Heiko Stuebner, Philipp Zabel,
linux-pci, linux-kernel, linuxppc-dev, linux-arm-kernel,
linux-arm-msm, linux-rockchip, Wilfred Mallawa,
Krishna Chaitanya Chundru, Lukas Wunner, Richard Zhu,
Brian Norris, Wilson Ding, Frank Li
On Tue, Mar 10, 2026 at 07:31:58PM +0530, Manivannan Sadhasivam via B4 Relay wrote:
> Changes in v7:
> - Dropped Rockchip Root port reset patch due to reported issues. But the series
> works on other platforms as tested by others.
Are you referring to
## On EP side:
# echo 0 > /sys/kernel/config/pci_ep/controllers/a40000000.pcie-ep/start && \
sleep 0.1 && echo 1 > /sys/kernel/config/pci_ep/controllers/a40000000.pcie-ep/start
Then running pcitest only having 7 / 16 tests passed ?
If so, isn't that a problem also for qcom?
There is no chance that the patch:
"misc: pci_endpoint_test: Add AER error handlers"
improves things in this regard?
Or will it simply avoid the "AER: device recovery failed" print?
Kind regards,
Niklas
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v7 0/4] PCI: Add support for resetting the Root Ports in a platform specific way
2026-03-11 11:05 ` Niklas Cassel
@ 2026-03-11 14:39 ` Manivannan Sadhasivam
2026-03-11 15:14 ` Manivannan Sadhasivam
0 siblings, 1 reply; 16+ messages in thread
From: Manivannan Sadhasivam @ 2026-03-11 14:39 UTC (permalink / raw)
To: Niklas Cassel
Cc: manivannan.sadhasivam, Bjorn Helgaas, Mahesh J Salgaonkar,
Oliver O'Halloran, Will Deacon, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Heiko Stuebner,
Philipp Zabel, linux-pci, linux-kernel, linuxppc-dev,
linux-arm-kernel, linux-arm-msm, linux-rockchip, Wilfred Mallawa,
Krishna Chaitanya Chundru, Lukas Wunner, Richard Zhu,
Brian Norris, Wilson Ding, Frank Li
On Wed, Mar 11, 2026 at 12:05:15PM +0100, Niklas Cassel wrote:
> On Tue, Mar 10, 2026 at 07:31:58PM +0530, Manivannan Sadhasivam via B4 Relay wrote:
> > Changes in v7:
> > - Dropped Rockchip Root port reset patch due to reported issues. But the series
> > works on other platforms as tested by others.
>
> Are you referring to
>
> ## On EP side:
> # echo 0 > /sys/kernel/config/pci_ep/controllers/a40000000.pcie-ep/start && \
> sleep 0.1 && echo 1 > /sys/kernel/config/pci_ep/controllers/a40000000.pcie-ep/start
>
> Then running pcitest only having 7 / 16 tests passed ?
>
> If so, isn't that a problem also for qcom?
>
No, tests are passing on my setup after link up.
>
> There is no chance that the patch:
> "misc: pci_endpoint_test: Add AER error handlers"
> improves things in this regard?
>
> Or will it simply avoid the "AER: device recovery failed" print?
>
Yes, as mentioned in the commit message, it just avoids the AER recovery failure
message.
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v7 0/4] PCI: Add support for resetting the Root Ports in a platform specific way
2026-03-11 14:39 ` Manivannan Sadhasivam
@ 2026-03-11 15:14 ` Manivannan Sadhasivam
2026-03-17 11:16 ` Niklas Cassel
0 siblings, 1 reply; 16+ messages in thread
From: Manivannan Sadhasivam @ 2026-03-11 15:14 UTC (permalink / raw)
To: Niklas Cassel
Cc: manivannan.sadhasivam, Bjorn Helgaas, Mahesh J Salgaonkar,
Oliver O'Halloran, Will Deacon, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Heiko Stuebner,
Philipp Zabel, linux-pci, linux-kernel, linuxppc-dev,
linux-arm-kernel, linux-arm-msm, linux-rockchip, Wilfred Mallawa,
Krishna Chaitanya Chundru, Lukas Wunner, Richard Zhu,
Brian Norris, Wilson Ding, Frank Li
On Wed, Mar 11, 2026 at 08:09:53PM +0530, Manivannan Sadhasivam wrote:
> On Wed, Mar 11, 2026 at 12:05:15PM +0100, Niklas Cassel wrote:
> > On Tue, Mar 10, 2026 at 07:31:58PM +0530, Manivannan Sadhasivam via B4 Relay wrote:
> > > Changes in v7:
> > > - Dropped Rockchip Root port reset patch due to reported issues. But the series
> > > works on other platforms as tested by others.
> >
> > Are you referring to
> >
> > ## On EP side:
> > # echo 0 > /sys/kernel/config/pci_ep/controllers/a40000000.pcie-ep/start && \
> > sleep 0.1 && echo 1 > /sys/kernel/config/pci_ep/controllers/a40000000.pcie-ep/start
> >
> > Then running pcitest only having 7 / 16 tests passed ?
> >
> > If so, isn't that a problem also for qcom?
> >
>
> No, tests are passing on my setup after link up.
>
> >
> > There is no chance that the patch:
> > "misc: pci_endpoint_test: Add AER error handlers"
> > improves things in this regard?
> >
> > Or will it simply avoid the "AER: device recovery failed" print?
> >
>
> Yes, as mentioned in the commit message, it just avoids the AER recovery failure
> message.
>
I also realized that Endpoint state is not saved in all the code paths. So the
pci_endpoint_test driver has to save/restore the state also. But it is still not
clear why that didn't help you.
Can you share the snapshot of the entire config space before and after reset
using 'lspci -xxxx -s "0000:01:00"'?
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v7 0/4] PCI: Add support for resetting the Root Ports in a platform specific way
2026-03-11 15:14 ` Manivannan Sadhasivam
@ 2026-03-17 11:16 ` Niklas Cassel
2026-03-17 13:11 ` Niklas Cassel
0 siblings, 1 reply; 16+ messages in thread
From: Niklas Cassel @ 2026-03-17 11:16 UTC (permalink / raw)
To: Manivannan Sadhasivam
Cc: manivannan.sadhasivam, Bjorn Helgaas, Mahesh J Salgaonkar,
Oliver O'Halloran, Will Deacon, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Heiko Stuebner,
Philipp Zabel, linux-pci, linux-kernel, linuxppc-dev,
linux-arm-kernel, linux-arm-msm, linux-rockchip, Wilfred Mallawa,
Krishna Chaitanya Chundru, Lukas Wunner, Richard Zhu,
Brian Norris, Wilson Ding, Frank Li
[-- Attachment #1: Type: text/plain, Size: 3797 bytes --]
On Wed, Mar 11, 2026 at 08:44:15PM +0530, Manivannan Sadhasivam wrote:
> On Wed, Mar 11, 2026 at 08:09:53PM +0530, Manivannan Sadhasivam wrote:
> > On Wed, Mar 11, 2026 at 12:05:15PM +0100, Niklas Cassel wrote:
> > > On Tue, Mar 10, 2026 at 07:31:58PM +0530, Manivannan Sadhasivam via B4 Relay wrote:
> > > > Changes in v7:
> > > > - Dropped Rockchip Root port reset patch due to reported issues. But the series
> > > > works on other platforms as tested by others.
> > >
> > > Are you referring to
> > >
> > > ## On EP side:
> > > # echo 0 > /sys/kernel/config/pci_ep/controllers/a40000000.pcie-ep/start && \
> > > sleep 0.1 && echo 1 > /sys/kernel/config/pci_ep/controllers/a40000000.pcie-ep/start
> > >
> > > Then running pcitest only having 7 / 16 tests passed ?
> > >
> > > If so, isn't that a problem also for qcom?
> > >
> >
> > No, tests are passing on my setup after link up.
> >
> > >
> > > There is no chance that the patch:
> > > "misc: pci_endpoint_test: Add AER error handlers"
> > > improves things in this regard?
> > >
> > > Or will it simply avoid the "AER: device recovery failed" print?
> > >
> >
> > Yes, as mentioned in the commit message, it just avoids the AER recovery failure
> > message.
> >
>
> I also realized that Endpoint state is not saved in all the code paths. So the
> pci_endpoint_test driver has to save/restore the state also. But it is still not
> clear why that didn't help you.
>
> Can you share the snapshot of the entire config space before and after reset
> using 'lspci -xxxx -s "0000:01:00"'?
If I don't add something like:
diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
index 1eced7a419eb..9d7ee39164d4 100644
--- a/drivers/misc/pci_endpoint_test.c
+++ b/drivers/misc/pci_endpoint_test.c
@@ -1059,6 +1059,9 @@ static int pci_endpoint_test_set_irq(struct pci_endpoint_test *test,
return ret;
}
+ pr_info("saving PCI state (irq_type: %d)\n", req_irq_type);
+ pci_save_state(pdev);
+
return 0;
}
@@ -1453,6 +1456,7 @@ static pci_ers_result_t pci_endpoint_test_error_detected(struct pci_dev *pdev,
static pci_ers_result_t pci_endpoint_test_slot_reset(struct pci_dev *pdev)
{
+ pci_restore_state(pdev);
return PCI_ERS_RESULT_RECOVERED;
}
On top of your patch.
Then all the BAR tests + MSI and MSI-X tests fail.
There is a huge difference in lspci -vvv output (as I guess is expected),
including all BARs being marked as disabled.
With the patch above. There is zero difference before/after reset, and all
the BAR tests pass. However, MSI/MSI-X tests still fail with:
# pci_endpoint_test.c:143:MSI_TEST:Expected 0 (0) == ret (-110)
# pci_endpoint_test.c:143:MSI_TEST:Test failed for MSI1
ETIMEDOUT.
This suggests that pci_endpoint_test on the host side did not receive an
interrupt.
I don't know why, but considering that lspci output is now (with the
save+restore) identical, I assume that the problem is not related to
the host. Unless somehow the host will use a new/different MSI address
after the root port has been reset, and we restore the old MSI address,
but looking at the code, dw_pcie_msi_init() is called by
dw_pcie_setup_rc(), so I would expect the MSI address to be the same.
I will be very busy for a few weeks, so I don't have time to debug this.
If anyone wants to debug this on rk3588, I'm attaching the patches for
this new feature for rk3588 that can be applied on top of this series.
Personally, I'm fine with this series getting merged even though this
new feature will only be supported by the QCOM driver.
But, I don't understand how e.g. pci endpoint test can work on QCOM
platforms, after the root port has been reset, without something like
the save/restore diff above.
Kind regards,
Niklas
[-- Attachment #2: 0001-Revert-PCI-dw-rockchip-Simplify-regulator-setup-with.patch --]
[-- Type: text/plain, Size: 2280 bytes --]
From c6416291bdbe2a3964b60183492208b41208f5a0 Mon Sep 17 00:00:00 2001
From: Niklas Cassel <cassel@kernel.org>
Date: Tue, 17 Mar 2026 09:59:09 +0100
Subject: [PATCH 1/2] Revert "PCI: dw-rockchip: Simplify regulator setup with
devm_regulator_get_enable_optional()"
This reverts commit c930b10f17c03858cfe19b9873ba5240128b4d1b.
---
drivers/pci/controller/dwc/pcie-dw-rockchip.c | 23 ++++++++++++++-----
1 file changed, 17 insertions(+), 6 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
index 8db27199cfa6..bec42fe646d8 100644
--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
+++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
@@ -95,6 +95,7 @@ struct rockchip_pcie {
unsigned int clk_cnt;
struct reset_control *rst;
struct gpio_desc *rst_gpio;
+ struct regulator *vpcie3v3;
struct irq_domain *irq_domain;
const struct rockchip_pcie_of_data *data;
bool supports_clkreq;
@@ -673,15 +674,22 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
return ret;
/* DON'T MOVE ME: must be enable before PHY init */
- ret = devm_regulator_get_enable_optional(dev, "vpcie3v3");
- if (ret < 0 && ret != -ENODEV)
- return dev_err_probe(dev, ret,
- "failed to enable vpcie3v3 regulator\n");
+ rockchip->vpcie3v3 = devm_regulator_get_optional(dev, "vpcie3v3");
+ if (IS_ERR(rockchip->vpcie3v3)) {
+ if (PTR_ERR(rockchip->vpcie3v3) != -ENODEV)
+ return dev_err_probe(dev, PTR_ERR(rockchip->vpcie3v3),
+ "failed to get vpcie3v3 regulator\n");
+ rockchip->vpcie3v3 = NULL;
+ } else {
+ ret = regulator_enable(rockchip->vpcie3v3);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "failed to enable vpcie3v3 regulator\n");
+ }
ret = rockchip_pcie_phy_init(rockchip);
if (ret)
- return dev_err_probe(dev, ret,
- "failed to initialize the phy\n");
+ goto disable_regulator;
ret = reset_control_deassert(rockchip->rst);
if (ret)
@@ -714,6 +722,9 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
clk_bulk_disable_unprepare(rockchip->clk_cnt, rockchip->clks);
deinit_phy:
rockchip_pcie_phy_deinit(rockchip);
+disable_regulator:
+ if (rockchip->vpcie3v3)
+ regulator_disable(rockchip->vpcie3v3);
return ret;
}
--
2.53.0
[-- Attachment #3: 0002-PCI-dw-rockchip-Add-support-to-reset-Root-Port-upon-.patch --]
[-- Type: text/plain, Size: 7850 bytes --]
From 47b29e709bb209b2877a072cd3a9c3e5f1b66399 Mon Sep 17 00:00:00 2001
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
Date: Tue, 17 Mar 2026 09:30:57 +0100
Subject: [PATCH 2/2] PCI: dw-rockchip: Add support to reset Root Port upon
link down event
The PCIe link may go down in cases like firmware crashes or unstable
connections. When this occurs, the PCIe Root Port must be reset to restore
the functionality. However, the current driver lacks link down handling,
forcing users to reboot the system to recover.
This patch implements the `reset_root_port` callback for link down handling
for Rockchip DWC PCIe host controller. In which, the RC is reset,
reconfigured and link training initiated to recover from the link down
event.
This also by extension fixes issues with sysfs initiated bus resets. In
that, currently, when a sysfs initiated bus reset is issued, the endpoint
device is non-functional after (may link up with downgraded link status).
With the link down handling support, a sysfs initiated bus reset works as
intended. Testing conducted on a ROCK5B board with an M.2 NVMe drive.
Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
---
drivers/pci/controller/dwc/Kconfig | 1 +
drivers/pci/controller/dwc/pcie-dw-rockchip.c | 137 +++++++++++++++++-
2 files changed, 135 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
index d0aa031397fa..ecaf79da843b 100644
--- a/drivers/pci/controller/dwc/Kconfig
+++ b/drivers/pci/controller/dwc/Kconfig
@@ -361,6 +361,7 @@ config PCIE_ROCKCHIP_DW_HOST
depends on OF
select PCIE_DW_HOST
select PCIE_ROCKCHIP_DW
+ select PCI_HOST_COMMON
help
Enables support for the DesignWare PCIe controller in the
Rockchip SoC (except RK3399) to work in host mode.
diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
index bec42fe646d8..75928057acee 100644
--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
+++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
@@ -24,6 +24,7 @@
#include <linux/reset.h>
#include "../../pci.h"
+#include "../pci-host-common.h"
#include "pcie-designware.h"
/*
@@ -106,6 +107,9 @@ struct rockchip_pcie_of_data {
const struct pci_epc_features *epc_features;
};
+static int rockchip_pcie_rc_reset_root_port(struct pci_host_bridge *bridge,
+ struct pci_dev *pdev);
+
static int rockchip_pcie_readl_apb(struct rockchip_pcie *rockchip, u32 reg)
{
return readl_relaxed(rockchip->apb_base + reg);
@@ -326,6 +330,7 @@ static int rockchip_pcie_host_init(struct dw_pcie_rp *pp)
rockchip_pcie_configure_l1ss(pci);
rockchip_pcie_enable_l0s(pci);
+ pp->bridge->reset_root_port = rockchip_pcie_rc_reset_root_port;
/* Disable Root Ports BAR0 and BAR1 as they report bogus size */
dw_pcie_writel_dbi2(pci, PCI_BASE_ADDRESS_0, 0x0);
@@ -524,6 +529,32 @@ static const struct dw_pcie_ops dw_pcie_ops = {
.get_ltssm = rockchip_pcie_get_ltssm,
};
+static irqreturn_t rockchip_pcie_rc_sys_irq_thread(int irq, void *arg)
+{
+ struct rockchip_pcie *rockchip = arg;
+ struct dw_pcie *pci = &rockchip->pci;
+ struct dw_pcie_rp *pp = &pci->pp;
+ struct device *dev = pci->dev;
+ struct pci_dev *port;
+ u32 reg;
+
+ reg = rockchip_pcie_readl_apb(rockchip, PCIE_CLIENT_INTR_STATUS_MISC);
+ rockchip_pcie_writel_apb(rockchip, reg, PCIE_CLIENT_INTR_STATUS_MISC);
+
+ dev_dbg(dev, "PCIE_CLIENT_INTR_STATUS_MISC: %#x\n", reg);
+ dev_dbg(dev, "LTSSM_STATUS: %#x\n", rockchip_pcie_get_ltssm_reg(rockchip));
+
+ if (reg & PCIE_LINK_REQ_RST_NOT_INT) {
+ dev_dbg(dev, "hot reset or link-down reset\n");
+ for_each_pci_bridge(port, pp->bridge->bus) {
+ if (pci_pcie_type(port) == PCI_EXP_TYPE_ROOT_PORT)
+ pci_host_handle_link_down(port);
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
static irqreturn_t rockchip_pcie_ep_sys_irq_thread(int irq, void *arg)
{
struct rockchip_pcie *rockchip = arg;
@@ -556,14 +587,29 @@ static irqreturn_t rockchip_pcie_ep_sys_irq_thread(int irq, void *arg)
return IRQ_HANDLED;
}
-static int rockchip_pcie_configure_rc(struct rockchip_pcie *rockchip)
+static int rockchip_pcie_configure_rc(struct platform_device *pdev,
+ struct rockchip_pcie *rockchip)
{
+ struct device *dev = &pdev->dev;
struct dw_pcie_rp *pp;
+ int irq, ret;
u32 val;
if (!IS_ENABLED(CONFIG_PCIE_ROCKCHIP_DW_HOST))
return -ENODEV;
+ irq = platform_get_irq_byname(pdev, "sys");
+ if (irq < 0)
+ return irq;
+
+ ret = devm_request_threaded_irq(dev, irq, NULL,
+ rockchip_pcie_rc_sys_irq_thread,
+ IRQF_ONESHOT, "pcie-sys-rc", rockchip);
+ if (ret) {
+ dev_err(dev, "failed to request PCIe sys IRQ\n");
+ return ret;
+ }
+
/* LTSSM enable control mode */
val = FIELD_PREP_WM16(PCIE_LTSSM_ENABLE_ENHANCE, 1);
rockchip_pcie_writel_apb(rockchip, val, PCIE_CLIENT_HOT_RESET_CTRL);
@@ -575,7 +621,17 @@ static int rockchip_pcie_configure_rc(struct rockchip_pcie *rockchip)
pp = &rockchip->pci.pp;
pp->ops = &rockchip_pcie_host_ops;
- return dw_pcie_host_init(pp);
+ ret = dw_pcie_host_init(pp);
+ if (ret) {
+ dev_err(dev, "failed to initialize host\n");
+ return ret;
+ }
+
+ /* unmask hot reset/link-down reset */
+ val = FIELD_PREP_WM16(PCIE_LINK_REQ_RST_NOT_INT, 0);
+ rockchip_pcie_writel_apb(rockchip, val, PCIE_CLIENT_INTR_MASK_MISC);
+
+ return ret;
}
static int rockchip_pcie_configure_ep(struct platform_device *pdev,
@@ -701,7 +757,7 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
switch (data->mode) {
case DW_PCIE_RC_TYPE:
- ret = rockchip_pcie_configure_rc(rockchip);
+ ret = rockchip_pcie_configure_rc(pdev, rockchip);
if (ret)
goto deinit_clk;
break;
@@ -729,6 +785,81 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
return ret;
}
+static int rockchip_pcie_rc_reset_root_port(struct pci_host_bridge *bridge,
+ struct pci_dev *pdev)
+{
+ struct pci_bus *bus = bridge->bus;
+ struct dw_pcie_rp *pp = bus->sysdata;
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+ struct rockchip_pcie *rockchip = to_rockchip_pcie(pci);
+ struct device *dev = rockchip->pci.dev;
+ u32 val;
+ int ret;
+
+ dw_pcie_stop_link(pci);
+ clk_bulk_disable_unprepare(rockchip->clk_cnt, rockchip->clks);
+ rockchip_pcie_phy_deinit(rockchip);
+
+ ret = reset_control_assert(rockchip->rst);
+ if (ret)
+ return ret;
+
+ ret = rockchip_pcie_phy_init(rockchip);
+ if (ret)
+ goto disable_regulator;
+
+ ret = reset_control_deassert(rockchip->rst);
+ if (ret)
+ goto deinit_phy;
+
+ ret = rockchip_pcie_clk_init(rockchip);
+ if (ret)
+ goto deinit_phy;
+
+ ret = pp->ops->init(pp);
+ if (ret) {
+ dev_err(dev, "Host init failed: %d\n", ret);
+ goto deinit_clk;
+ }
+
+ /* LTSSM enable control mode */
+ val = FIELD_PREP_WM16(PCIE_LTSSM_ENABLE_ENHANCE, 1);
+ rockchip_pcie_writel_apb(rockchip, val, PCIE_CLIENT_HOT_RESET_CTRL);
+
+ rockchip_pcie_writel_apb(rockchip,
+ PCIE_CLIENT_SET_MODE(PCIE_CLIENT_MODE_RC),
+ PCIE_CLIENT_GENERAL_CON);
+
+ ret = dw_pcie_setup_rc(pp);
+ if (ret) {
+ dev_err(dev, "Failed to setup RC: %d\n", ret);
+ goto deinit_clk;
+ }
+
+ /* unmask hot reset/link-down reset */
+ val = FIELD_PREP_WM16(PCIE_LINK_REQ_RST_NOT_INT, 0);
+ rockchip_pcie_writel_apb(rockchip, val, PCIE_CLIENT_INTR_MASK_MISC);
+
+ ret = dw_pcie_start_link(pci);
+ if (ret)
+ goto deinit_clk;
+
+ /* Ignore errors, the link may come up later */
+ dw_pcie_wait_for_link(pci);
+ dev_dbg(dev, "Root Port reset completed\n");
+ return ret;
+
+deinit_clk:
+ clk_bulk_disable_unprepare(rockchip->clk_cnt, rockchip->clks);
+deinit_phy:
+ rockchip_pcie_phy_deinit(rockchip);
+disable_regulator:
+ if (rockchip->vpcie3v3)
+ regulator_disable(rockchip->vpcie3v3);
+
+ return ret;
+}
+
static const struct rockchip_pcie_of_data rockchip_pcie_rc_of_data_rk3568 = {
.mode = DW_PCIE_RC_TYPE,
};
--
2.53.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v7 0/4] PCI: Add support for resetting the Root Ports in a platform specific way
2026-03-17 11:16 ` Niklas Cassel
@ 2026-03-17 13:11 ` Niklas Cassel
0 siblings, 0 replies; 16+ messages in thread
From: Niklas Cassel @ 2026-03-17 13:11 UTC (permalink / raw)
To: Manivannan Sadhasivam
Cc: manivannan.sadhasivam, Bjorn Helgaas, Mahesh J Salgaonkar,
Oliver O'Halloran, Will Deacon, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Heiko Stuebner,
Philipp Zabel, linux-pci, linux-kernel, linuxppc-dev,
linux-arm-kernel, linux-arm-msm, linux-rockchip, Wilfred Mallawa,
Krishna Chaitanya Chundru, Lukas Wunner, Richard Zhu,
Brian Norris, Wilson Ding, Frank Li, Shawn Lin
[-- Attachment #1: Type: text/plain, Size: 406 bytes --]
On Tue, Mar 17, 2026 at 12:17:19PM +0100, Niklas Cassel wrote:
>
> I will be very busy for a few weeks, so I don't have time to debug this.
> If anyone wants to debug this on rk3588, I'm attaching the patches for
> this new feature for rk3588 that can be applied on top of this series.
For what it is worth, attaching an improved patch for rk3588 that does not
require any revert.
Kind regards,
Niklas
[-- Attachment #2: 0001-PCI-dw-rockchip-Add-support-to-reset-Root-Port-upon-.patch --]
[-- Type: text/plain, Size: 7746 bytes --]
From a69679430750d7371e65e1b209059803cea2f5de Mon Sep 17 00:00:00 2001
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
Date: Tue, 17 Mar 2026 09:30:57 +0100
Subject: [PATCH] PCI: dw-rockchip: Add support to reset Root Port upon link
down event
The PCIe link may go down in cases like firmware crashes or unstable
connections. When this occurs, the PCIe Root Port must be reset to restore
the functionality. However, the current driver lacks link down handling,
forcing users to reboot the system to recover.
This patch implements the `reset_root_port` callback for link down handling
for Rockchip DWC PCIe host controller. In which, the RC is reset,
reconfigured and link training initiated to recover from the link down
event.
This also by extension fixes issues with sysfs initiated bus resets. In
that, currently, when a sysfs initiated bus reset is issued, the endpoint
device is non-functional after (may link up with downgraded link status).
With the link down handling support, a sysfs initiated bus reset works as
intended. Testing conducted on a ROCK5B board with an M.2 NVMe drive.
Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
---
drivers/pci/controller/dwc/Kconfig | 1 +
drivers/pci/controller/dwc/pcie-dw-rockchip.c | 134 +++++++++++++++++-
2 files changed, 132 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
index d0aa031397fa..ecaf79da843b 100644
--- a/drivers/pci/controller/dwc/Kconfig
+++ b/drivers/pci/controller/dwc/Kconfig
@@ -361,6 +361,7 @@ config PCIE_ROCKCHIP_DW_HOST
depends on OF
select PCIE_DW_HOST
select PCIE_ROCKCHIP_DW
+ select PCI_HOST_COMMON
help
Enables support for the DesignWare PCIe controller in the
Rockchip SoC (except RK3399) to work in host mode.
diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
index 8db27199cfa6..988d98effcd7 100644
--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
+++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
@@ -24,6 +24,7 @@
#include <linux/reset.h>
#include "../../pci.h"
+#include "../pci-host-common.h"
#include "pcie-designware.h"
/*
@@ -105,6 +106,9 @@ struct rockchip_pcie_of_data {
const struct pci_epc_features *epc_features;
};
+static int rockchip_pcie_rc_reset_root_port(struct pci_host_bridge *bridge,
+ struct pci_dev *pdev);
+
static int rockchip_pcie_readl_apb(struct rockchip_pcie *rockchip, u32 reg)
{
return readl_relaxed(rockchip->apb_base + reg);
@@ -325,6 +329,7 @@ static int rockchip_pcie_host_init(struct dw_pcie_rp *pp)
rockchip_pcie_configure_l1ss(pci);
rockchip_pcie_enable_l0s(pci);
+ pp->bridge->reset_root_port = rockchip_pcie_rc_reset_root_port;
/* Disable Root Ports BAR0 and BAR1 as they report bogus size */
dw_pcie_writel_dbi2(pci, PCI_BASE_ADDRESS_0, 0x0);
@@ -523,6 +528,32 @@ static const struct dw_pcie_ops dw_pcie_ops = {
.get_ltssm = rockchip_pcie_get_ltssm,
};
+static irqreturn_t rockchip_pcie_rc_sys_irq_thread(int irq, void *arg)
+{
+ struct rockchip_pcie *rockchip = arg;
+ struct dw_pcie *pci = &rockchip->pci;
+ struct dw_pcie_rp *pp = &pci->pp;
+ struct device *dev = pci->dev;
+ struct pci_dev *port;
+ u32 reg;
+
+ reg = rockchip_pcie_readl_apb(rockchip, PCIE_CLIENT_INTR_STATUS_MISC);
+ rockchip_pcie_writel_apb(rockchip, reg, PCIE_CLIENT_INTR_STATUS_MISC);
+
+ dev_dbg(dev, "PCIE_CLIENT_INTR_STATUS_MISC: %#x\n", reg);
+ dev_dbg(dev, "LTSSM_STATUS: %#x\n", rockchip_pcie_get_ltssm_reg(rockchip));
+
+ if (reg & PCIE_LINK_REQ_RST_NOT_INT) {
+ dev_dbg(dev, "hot reset or link-down reset\n");
+ for_each_pci_bridge(port, pp->bridge->bus) {
+ if (pci_pcie_type(port) == PCI_EXP_TYPE_ROOT_PORT)
+ pci_host_handle_link_down(port);
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
static irqreturn_t rockchip_pcie_ep_sys_irq_thread(int irq, void *arg)
{
struct rockchip_pcie *rockchip = arg;
@@ -555,14 +586,29 @@ static irqreturn_t rockchip_pcie_ep_sys_irq_thread(int irq, void *arg)
return IRQ_HANDLED;
}
-static int rockchip_pcie_configure_rc(struct rockchip_pcie *rockchip)
+static int rockchip_pcie_configure_rc(struct platform_device *pdev,
+ struct rockchip_pcie *rockchip)
{
+ struct device *dev = &pdev->dev;
struct dw_pcie_rp *pp;
+ int irq, ret;
u32 val;
if (!IS_ENABLED(CONFIG_PCIE_ROCKCHIP_DW_HOST))
return -ENODEV;
+ irq = platform_get_irq_byname(pdev, "sys");
+ if (irq < 0)
+ return irq;
+
+ ret = devm_request_threaded_irq(dev, irq, NULL,
+ rockchip_pcie_rc_sys_irq_thread,
+ IRQF_ONESHOT, "pcie-sys-rc", rockchip);
+ if (ret) {
+ dev_err(dev, "failed to request PCIe sys IRQ\n");
+ return ret;
+ }
+
/* LTSSM enable control mode */
val = FIELD_PREP_WM16(PCIE_LTSSM_ENABLE_ENHANCE, 1);
rockchip_pcie_writel_apb(rockchip, val, PCIE_CLIENT_HOT_RESET_CTRL);
@@ -574,7 +620,17 @@ static int rockchip_pcie_configure_rc(struct rockchip_pcie *rockchip)
pp = &rockchip->pci.pp;
pp->ops = &rockchip_pcie_host_ops;
- return dw_pcie_host_init(pp);
+ ret = dw_pcie_host_init(pp);
+ if (ret) {
+ dev_err(dev, "failed to initialize host\n");
+ return ret;
+ }
+
+ /* unmask hot reset/link-down reset */
+ val = FIELD_PREP_WM16(PCIE_LINK_REQ_RST_NOT_INT, 0);
+ rockchip_pcie_writel_apb(rockchip, val, PCIE_CLIENT_INTR_MASK_MISC);
+
+ return ret;
}
static int rockchip_pcie_configure_ep(struct platform_device *pdev,
@@ -693,7 +749,7 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
switch (data->mode) {
case DW_PCIE_RC_TYPE:
- ret = rockchip_pcie_configure_rc(rockchip);
+ ret = rockchip_pcie_configure_rc(pdev, rockchip);
if (ret)
goto deinit_clk;
break;
@@ -718,6 +774,78 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
return ret;
}
+static int rockchip_pcie_rc_reset_root_port(struct pci_host_bridge *bridge,
+ struct pci_dev *pdev)
+{
+ struct pci_bus *bus = bridge->bus;
+ struct dw_pcie_rp *pp = bus->sysdata;
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+ struct rockchip_pcie *rockchip = to_rockchip_pcie(pci);
+ struct device *dev = rockchip->pci.dev;
+ u32 val;
+ int ret;
+
+ dw_pcie_stop_link(pci);
+ clk_bulk_disable_unprepare(rockchip->clk_cnt, rockchip->clks);
+ rockchip_pcie_phy_deinit(rockchip);
+
+ ret = reset_control_assert(rockchip->rst);
+ if (ret)
+ return ret;
+
+ ret = rockchip_pcie_phy_init(rockchip);
+ if (ret)
+ return ret;
+
+ ret = reset_control_deassert(rockchip->rst);
+ if (ret)
+ goto deinit_phy;
+
+ ret = rockchip_pcie_clk_init(rockchip);
+ if (ret)
+ goto deinit_phy;
+
+ ret = pp->ops->init(pp);
+ if (ret) {
+ dev_err(dev, "Host init failed: %d\n", ret);
+ goto deinit_clk;
+ }
+
+ /* LTSSM enable control mode */
+ val = FIELD_PREP_WM16(PCIE_LTSSM_ENABLE_ENHANCE, 1);
+ rockchip_pcie_writel_apb(rockchip, val, PCIE_CLIENT_HOT_RESET_CTRL);
+
+ rockchip_pcie_writel_apb(rockchip,
+ PCIE_CLIENT_SET_MODE(PCIE_CLIENT_MODE_RC),
+ PCIE_CLIENT_GENERAL_CON);
+
+ ret = dw_pcie_setup_rc(pp);
+ if (ret) {
+ dev_err(dev, "Failed to setup RC: %d\n", ret);
+ goto deinit_clk;
+ }
+
+ /* unmask hot reset/link-down reset */
+ val = FIELD_PREP_WM16(PCIE_LINK_REQ_RST_NOT_INT, 0);
+ rockchip_pcie_writel_apb(rockchip, val, PCIE_CLIENT_INTR_MASK_MISC);
+
+ ret = dw_pcie_start_link(pci);
+ if (ret)
+ goto deinit_clk;
+
+ /* Ignore errors, the link may come up later */
+ dw_pcie_wait_for_link(pci);
+ dev_dbg(dev, "Root Port reset completed\n");
+ return ret;
+
+deinit_clk:
+ clk_bulk_disable_unprepare(rockchip->clk_cnt, rockchip->clks);
+deinit_phy:
+ rockchip_pcie_phy_deinit(rockchip);
+
+ return ret;
+}
+
static const struct rockchip_pcie_of_data rockchip_pcie_rc_of_data_rk3568 = {
.mode = DW_PCIE_RC_TYPE,
};
--
2.53.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* RE: [PATCH v7 0/4] PCI: Add support for resetting the Root Ports in a platform specific way
2026-03-10 14:01 [PATCH v7 0/4] PCI: Add support for resetting the Root Ports in a platform specific way Manivannan Sadhasivam via B4 Relay
` (5 preceding siblings ...)
2026-03-11 11:05 ` Niklas Cassel
@ 2026-03-25 7:06 ` Hongxing Zhu
6 siblings, 0 replies; 16+ messages in thread
From: Hongxing Zhu @ 2026-03-25 7:06 UTC (permalink / raw)
To: manivannan.sadhasivam@oss.qualcomm.com, Bjorn Helgaas,
Mahesh J Salgaonkar, Oliver O'Halloran, Will Deacon,
Lorenzo Pieralisi, Krzysztof Wilczy��ski,
Manivannan Sadhasivam, Rob Herring, Heiko Stuebner, Philipp Zabel
Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
linuxppc-dev@lists.ozlabs.org,
linux-arm-kernel@lists.infradead.org,
linux-arm-msm@vger.kernel.org, linux-rockchip@lists.infradead.org,
Niklas Cassel, Wilfred Mallawa, Krishna Chaitanya Chundru,
Lukas Wunner, Brian Norris, Wilson Ding
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="gb2312", Size: 16040 bytes --]
Hi Mani:
I've accidentally encountered a new issue based on the reset root port patch-set.
After performing a few hot-reset operations, the PCIe link enters a continuous up/down cycling pattern.
I found that calling pci_reset_secondary_bus() first in pcibios_reset_secondary_bus() appears to resolve this issue.
Have you experienced a similar problem?
"
...
[ 141.897701] imx6q-pcie 4c300000.pcie: PCIe(LNK_STS:0x00000700) link up detected
[ 142.086341] imx6q-pcie 4c300000.pcie: PCIe Gen.3 x1 link up
[ 142.092038] imx6q-pcie 4c300000.pcie: PCIe(LNK_STS:0x00000c00) link down detected
...
"
Platform: i.MX95 EVK board plus local Root Ports reset supports based on the #1 and #2 patches of v7 patch-set.
Notes of the logs:
- One Gen3 NVME device is connected.
- "./memtool 4c341058=0;./memtool 4c341058=1;" is used to toggle the LTSSM_EN bit to trigger the link down.
- Toggle BIT6 of Bridge Control Register to trigger hot reset by "./memtool 4c30003c=004001ff; ./memtool 4c30003c=000001ff;"
- The Root Port reset patches works correctly at first.
However, after several hot-reset triggers, the link enters a repeated down/up cycling state.
Logs:
[ 3.553188] imx6q-pcie 4c300000.pcie: host bridge /soc/pcie@4c300000 ranges:
[ 3.560308] imx6q-pcie 4c300000.pcie: IO 0x006ff00000..0x006fffffff -> 0x0000000000
[ 3.568525] imx6q-pcie 4c300000.pcie: MEM 0x0910000000..0x091fffffff -> 0x0010000000
[ 3.577314] imx6q-pcie 4c300000.pcie: config reg[1] 0x60100000 == cpu 0x60100000
[ 3.796029] imx6q-pcie 4c300000.pcie: iATU: unroll T, 128 ob, 128 ib, align 4K, limit 1024G
[ 4.003746] imx6q-pcie 4c300000.pcie: PCIe Gen.3 x1 link up
[ 4.009553] imx6q-pcie 4c300000.pcie: PCI host bridge to bus 0000:00
root@imx95evk:~#
root@imx95evk:~#
root@imx95evk:~# ./memtool 4c341058=0;./memtool 4c341058=1; Writing 32-bit value 0x0 to address 0x4C341058
Writing 32-bit v
[ 87.265348] imx6q-pcie 4c300000.pcie: PCIe(LNK_STS:0x00000d01) link down detected
alue 0x1 to adder
[ 87.273106] imx6q-pcie 4c300000.pcie: Stop root bus and handle link down
ss 0x4C341058
[ 87.281264] pcieport 0000:00:00.0: Recovering Root Port due to Link Down
[ 87.289245] pci 0000:01:00.0: AER: can't recover (no error_detected callback)
root@imx95evk:~# [ 87.514216] imx6q-pcie 4c300000.pcie: PCIe(LNK_STS:0x00000700) link up detected
[ 87.702968] imx6q-pcie 4c300000.pcie: PCIe Gen.3 x1 link up
[ 87.834983] pcieport 0000:00:00.0: Root Port has been reset
[ 87.840714] pcieport 0000:00:00.0: AER: device recovery failed
[ 87.846592] imx6q-pcie 4c300000.pcie: Rescan bus after link up is detected
[ 87.855947] pcieport 0000:00:00.0: bridge configuration invalid ([bus 00-00]), reconfiguring
[ 87.864423] pci_bus 0000:01: busn_res: [bus 01-ff] end is updated to 01
root@imx95evk:~#
root@imx95evk:~# cat /proc/interrupts | grep lnk;
273: 2 0 0 0 0 0 GICv3 342 Level PCIe PME, lnk_notify
root@imx95evk:~#
root@imx95evk:~#
root@imx95evk:~# ./memtool 4c30003c=004001ff; ./memtool 4c30003c=000001ff; Writing 32-bit va
[ 107.028086] imx6q-pcie 4c300000.pcie: PCIe(LNK_STS:0x00000d00) link down detected lue 0x4001FF to a
[ 107.037018] imx6q-pcie 4c300000.pcie: Stop root bus and handle link down ddress 0x4C30003C
[ 107.045137] pcieport 0000:00:00.0: Recovering Root Port due to Link Down
Writing 32-bit
[ 107.053332] pci 0000:01:00.0: AER: can't recover (no error_detected callback) value 0x1FF to address 0x4C30003C root@imx95evk:~#
[ 107.282146] imx6q-pcie 4c300000.pcie: PCIe(LNK_STS:0x00000700) link up detected
[ 107.470801] imx6q-pcie 4c300000.pcie: PCIe Gen.3 x1 link up
[ 107.602823] pcieport 0000:00:00.0: Root Port has been reset
[ 107.608601] pcieport 0000:00:00.0: AER: device recovery failed
[ 107.614497] imx6q-pcie 4c300000.pcie: Rescan bus after link up is detected
[ 107.623805] pcieport 0000:00:00.0: bridge configuration invalid ([bus 00-00]), reconfiguring
[ 107.632281] pci_bus 0000:01: busn_res: [bus 01] end is updated to 01
root@imx95evk:~#
root@imx95evk:~# cat /proc/interrupts | grep lnk;
273: 4 0 0 0 0 0 GICv3 342 Level PCIe PME, lnk_notify
root@imx95evk:~#
root@imx95evk:~# ./memtool 4c30003c=004001ff; ./memtool 4c30003c=000001ff; Writing 32-bit va
[ 133.424041] imx6q-pcie 4c300000.pcie: PCIe(LNK_STS:0x00000d00) link down detected lue 0x4001FF to a
[ 133.432954] imx6q-pcie 4c300000.pcie: Stop root bus and handle link down ddress 0x4C30003C
[ 133.441106] pcieport 0000:00:00.0: Recovering Root Port due to Link Down
Writing 32-bit
[ 133.449309] pci 0000:01:00.0: AER: can't recover (no error_detected callback) value 0x1FF to address 0x4C30003C root@imx95evk:~#
[ 133.677824] imx6q-pcie 4c300000.pcie: PCIe(LNK_STS:0x00000700) link up detected
[ 133.870414] imx6q-pcie 4c300000.pcie: PCIe Gen.3 x1 link up
[ 134.002534] pcieport 0000:00:00.0: Root Port has been reset
[ 134.008307] pcieport 0000:00:00.0: AER: device recovery failed
[ 134.014193] imx6q-pcie 4c300000.pcie: Rescan bus after link up is detected
[ 134.023418] pcieport 0000:00:00.0: bridge configuration invalid ([bus 00-00]), reconfiguring
[ 134.031881] pci_bus 0000:01: busn_res: [bus 01] end is updated to 01
root@imx95evk:~# ./memtool 4c30003c=004001ff; ./memtool 4c30003c=000001ff; Writing 32-bit va
[ 140.149713] imx6q-pcie 4c300000.pcie: PCIe(LNK_STS:0x00000d00) link down detected lue 0x4001FF to a
[ 140.158614] imx6q-pcie 4c300000.pcie: Stop root bus and handle link down ddress 0x4C30003C
[ 140.166779] pcieport 0000:00:00.0: Recovering Root Port due to Link Down
[ 140.174981] pci 0000:01:00.0: AER: can't recover (no error_detected callback) Writing 32-bit value 0x1FF to address 0x4C30003C root@imx95evk:~#
[ 140.401605] imx6q-pcie 4c300000.pcie: PCIe(LNK_STS:0x00000700) link up detected
[ 140.590491] imx6q-pcie 4c300000.pcie: PCIe Gen.3 x1 link up
[ 140.596206] imx6q-pcie 4c300000.pcie: PCIe(LNK_STS:0x00000c00) link down detected
root@imx95evk:~#
[ 141.630311] pcieport 0000:00:00.0: Data Link Layer Link Active not set in 100 msec
[ 141.637950] pcieport 0000:00:00.0: Failed to reset Root Port: -25
[ 141.644095] pcieport 0000:00:00.0: AER: subordinate device reset failed
[ 141.650883] pcieport 0000:00:00.0: AER: device recovery failed
[ 141.656784] imx6q-pcie 4c300000.pcie: Stop root bus and handle link down
[ 141.663520] pcieport 0000:00:00.0: Recovering Root Port due to Link Down
[ 141.670271] pci 0000:01:00.0: AER: can't recover (no error_detected callback)
[ 141.897701] imx6q-pcie 4c300000.pcie: PCIe(LNK_STS:0x00000700) link up detected
[ 142.086341] imx6q-pcie 4c300000.pcie: PCIe Gen.3 x1 link up
[ 142.092038] imx6q-pcie 4c300000.pcie: PCIe(LNK_STS:0x00000c00) link down detected
[ 143.126273] pcieport 0000:00:00.0: Data Link Layer Link Active not set in 100 msec
[ 143.133919] pcieport 0000:00:00.0: Failed to reset Root Port: -25
[ 143.140052] pcieport 0000:00:00.0: AER: subordinate device reset failed
[ 143.146747] pcieport 0000:00:00.0: AER: device recovery failed
[ 143.152604] imx6q-pcie 4c300000.pcie: Stop root bus and handle link down
[ 143.159314] pcieport 0000:00:00.0: Recovering Root Port due to Link Down
[ 143.166022] pci 0000:01:00.0: AER: can't recover (no error_detected callback)
[ 143.389723] imx6q-pcie 4c300000.pcie: PCIe(LNK_STS:0x00000700) link up detected
[ 143.582294] imx6q-pcie 4c300000.pcie: PCIe Gen.3 x1 link up
[ 143.587996] imx6q-pcie 4c300000.pcie: PCIe(LNK_STS:0x00000c00) link down detected
Thanks.
Best Regards
Richard Zhu
> -----Original Message-----
> From: Manivannan Sadhasivam via B4 Relay
> <devnull+manivannan.sadhasivam.oss.qualcomm.com@kernel.org>
> Sent: 2026Äê3ÔÂ10ÈÕ 22:02
> To: Bjorn Helgaas <bhelgaas@google.com>; Mahesh J Salgaonkar
> <mahesh@linux.ibm.com>; Oliver O'Halloran <oohall@gmail.com>; Will
> Deacon <will@kernel.org>; Lorenzo Pieralisi <lpieralisi@kernel.org>;
> Krzysztof Wilczy¨½ski <kwilczynski@kernel.org>; Manivannan Sadhasivam
> <mani@kernel.org>; Rob Herring <robh@kernel.org>; Heiko Stuebner
> <heiko@sntech.de>; Philipp Zabel <p.zabel@pengutronix.de>
> Cc: linux-pci@vger.kernel.org; linux-kernel@vger.kernel.org;
> linuxppc-dev@lists.ozlabs.org; linux-arm-kernel@lists.infradead.org;
> linux-arm-msm@vger.kernel.org; linux-rockchip@lists.infradead.org; Niklas
> Cassel <cassel@kernel.org>; Wilfred Mallawa <wilfred.mallawa@wdc.com>;
> Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>;
> mani@kernel.org; Lukas Wunner <lukas@wunner.de>; Hongxing Zhu
> <hongxing.zhu@nxp.com>; Brian Norris <briannorris@chromium.org>;
> Wilson Ding <dingwei@marvell.com>; Manivannan Sadhasivam
> <manivannan.sadhasivam@oss.qualcomm.com>; Frank Li
> <frank.li@nxp.com>; Manivannan Sadhasivam <mani@kernel.org>
> Subject: [PATCH v7 0/4] PCI: Add support for resetting the Root Ports in a
> platform specific way
>
> Hi,
>
> Currently, in the event of AER/DPC, PCI core will try to reset the slot (Root
> Port) and its subordinate devices by invoking bridge control reset and FLR.
> But in some cases like AER Fatal error, it might be necessary to reset the
> Root Ports using the PCI host bridge drivers in a platform specific way (as
> indicated by the TODO in the pcie_do_recovery() function in
> drivers/pci/pcie/err.c).
> Otherwise, the PCI link won't be recovered successfully.
>
> So this series adds a new callback 'pci_host_bridge::reset_root_port' for the
> host bridge drivers to reset the Root Port when a fatal error happens.
>
> Also, this series allows the host bridge drivers to handle PCI link down event
> by resetting the Root Ports and recovering the bus. This is accomplished by
> the help of the new 'pci_host_handle_link_down()' API. Host bridge drivers
> are expected to call this API (preferrably from a threaded IRQ handler) with
> relevant Root Port 'pci_dev' when a link down event is detected for the port.
> The API will reuse the pcie_do_recovery() function to recover the link if AER
> support is enabled, otherwise it will directly call the reset_root_port()
> callback of the host bridge driver (if exists).
>
> For reference, I've modified the pcie-qcom driver to call
> pci_host_handle_link_down() API with Root Port 'pci_dev' after receiving the
> LDn global_irq event and populated 'pci_host_bridge::reset_root_port()'
> callback to reset the Root Ports.
>
> Testing
> -------
>
> Tested on Qcom Lemans AU Ride platform with Host and EP SoCs connected
> over PCIe link. Simulated the LDn by disabling LTSSM_EN on the EP and I
> could verify that the link was getting recovered successfully.
>
> Changes in v7:
> - Dropped Rockchip Root port reset patch due to reported issues. But the
> series
> works on other platforms as tested by others.
> - Added pci_{lock/unlock}_rescan_remove() to guard pci_bus_error_reset()
> as the
> device could be removed in-between due to Native hotplug interrupt.
> - Rebased on top of v7.0-rc1
> - Link to v6:
> https://lore.ke/
> rnel.org%2Fr%2F20250715-pci-port-reset-v6-0-6f9cce94e7bb%40oss.qualcom
> m.com&data=05%7C02%7Chongxing.zhu%40nxp.com%7Cfc7ebf6f8fbf44e7e2
> 9d08de7eada6e1%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63
> 9087481469497457%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRy
> dWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3
> D%3D%7C0%7C%7C%7C&sdata=0Jfe20c6n9OcTMUApKYRXuDd%2B0o85QzjG
> %2B4IbIT%2BT6k%3D&reserved=0
>
> Changes in v6:
> - Incorporated the patch:
> https://lore.ke/
> rnel.org%2Fall%2F20250524185304.26698-2-manivannan.sadhasivam%40lina
> ro.org%2F&data=05%7C02%7Chongxing.zhu%40nxp.com%7Cfc7ebf6f8fbf44e7
> e29d08de7eada6e1%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C
> 639087481469541004%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOn
> RydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ
> %3D%3D%7C0%7C%7C%7C&sdata=Y8Qjn9yJfxJ41h%2FRHjPITgY%2BQOqh5LEr
> zir%2Fe3s%2B8g8%3D&reserved=0
> - Link to v5:
> https://lore.ke/
> rnel.org%2Fr%2F20250715-pci-port-reset-v5-0-26a5d278db40%40oss.qualco
> mm.com&data=05%7C02%7Chongxing.zhu%40nxp.com%7Cfc7ebf6f8fbf44e7e
> 29d08de7eada6e1%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C6
> 39087481469572178%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnR
> ydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%
> 3D%3D%7C0%7C%7C%7C&sdata=JUoqvSMB2sMZAxmGlGlN3iKYIQ9edjQhEfD
> kQpqdeWQ%3D&reserved=0
>
> Changes in v5:
> * Reworked the pci_host_handle_link_down() to accept Root Port instead of
> resetting all Root Ports in the event of link down.
> * Renamed 'reset_slot' to 'reset_root_port' to avoid confusion as both terms
> were used interchangibly and the series is intended to reset Root Port
> only.
> * Added the Rockchip driver change to this series.
> * Dropped the applied patches and review/tested tags due to rework.
> * Rebased on top of v6.16-rc1.
>
> Changes in v4:
> - Handled link down first in the irq handler
> - Updated ICC & OPP bandwidth after link up in reset_slot() callback
> - Link to v3:
> https://lore.ke/
> rnel.org%2Fr%2F20250417-pcie-reset-slot-v3-0-59a10811c962%40linaro.org&
> data=05%7C02%7Chongxing.zhu%40nxp.com%7Cfc7ebf6f8fbf44e7e29d08de7
> eada6e1%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C6390874814
> 69600118%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYi
> OiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7
> C0%7C%7C%7C&sdata=k39HxA8Zgft%2FGJ9HaugboOoPbQQkctqWRtiiGa0H95
> I%3D&reserved=0
>
> Changes in v3:
> - Made the pci-host-common driver as a common library for host controller
> drivers
> - Moved the reset slot code to pci-host-common library
> - Link to v2:
> https://lore.ke/
> rnel.org%2Fr%2F20250416-pcie-reset-slot-v2-0-efe76b278c10%40linaro.org&
> data=05%7C02%7Chongxing.zhu%40nxp.com%7Cfc7ebf6f8fbf44e7e29d08de7
> eada6e1%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C6390874814
> 69625186%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYi
> OiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7
> C0%7C%7C%7C&sdata=kQx%2B%2BgCe5TUTDDEwHttUGmqx0WYgL20WfPMf
> WmfA1dk%3D&reserved=0
>
> Changes in v2:
> - Moved calling reset_slot() callback from pcie_do_recovery() to
> pcibios_reset_secondary_bus()
> - Link to v1:
> https://lore.ke/
> rnel.org%2Fr%2F20250404-pcie-reset-slot-v1-0-98952918bf90%40linaro.org&
> data=05%7C02%7Chongxing.zhu%40nxp.com%7Cfc7ebf6f8fbf44e7e29d08de7
> eada6e1%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C6390874814
> 69647067%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYi
> OiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7
> C0%7C%7C%7C&sdata=kag0bpW2uzExYJAl84eHiMcUMVJmMcBPCahete6bDq
> 8%3D&reserved=0
>
> Signed-off-by: Manivannan Sadhasivam
> <manivannan.sadhasivam@oss.qualcomm.com>
> ---
> Manivannan Sadhasivam (4):
> PCI/ERR: Add support for resetting the Root Ports in a platform
> specific way
> PCI: host-common: Add link down handling for Root Ports
> PCI: qcom: Add support for resetting the Root Port due to link down
> event
> misc: pci_endpoint_test: Add AER error handlers
>
> drivers/misc/pci_endpoint_test.c | 20 +++++
> drivers/pci/controller/dwc/pcie-qcom.c | 143
> ++++++++++++++++++++++++++++++-
> drivers/pci/controller/pci-host-common.c | 35 ++++++++
> drivers/pci/controller/pci-host-common.h | 1 +
> drivers/pci/pci.c | 21 +++++
> drivers/pci/pcie/err.c | 6 +-
> include/linux/pci.h | 1 +
> 7 files changed, 221 insertions(+), 6 deletions(-)
> ---
> base-commit: 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f
> change-id: 20250715-pci-port-reset-4d9519570123
>
> Best regards,
> --
> Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
>
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2026-03-25 7:06 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-10 14:01 [PATCH v7 0/4] PCI: Add support for resetting the Root Ports in a platform specific way Manivannan Sadhasivam via B4 Relay
2026-03-10 14:01 ` [PATCH v7 1/4] PCI/ERR: " Manivannan Sadhasivam via B4 Relay
2026-03-11 5:26 ` Shawn Lin
2026-03-10 14:02 ` [PATCH v7 2/4] PCI: host-common: Add link down handling for Root Ports Manivannan Sadhasivam via B4 Relay
2026-03-11 0:55 ` Shawn Lin
2026-03-11 5:04 ` Manivannan Sadhasivam
2026-03-11 5:20 ` Shawn Lin
2026-03-10 14:02 ` [PATCH v7 3/4] PCI: qcom: Add support for resetting the Root Port due to link down event Manivannan Sadhasivam via B4 Relay
2026-03-10 14:02 ` [PATCH v7 4/4] misc: pci_endpoint_test: Add AER error handlers Manivannan Sadhasivam via B4 Relay
2026-03-11 8:37 ` [PATCH v7 0/4] PCI: Add support for resetting the Root Ports in a platform specific way Krishna Chaitanya Chundru
2026-03-11 11:05 ` Niklas Cassel
2026-03-11 14:39 ` Manivannan Sadhasivam
2026-03-11 15:14 ` Manivannan Sadhasivam
2026-03-17 11:16 ` Niklas Cassel
2026-03-17 13:11 ` Niklas Cassel
2026-03-25 7:06 ` Hongxing Zhu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox