linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] PCI: Add support for resetting the slots in a platform specific way
@ 2025-04-04  8:22 Manivannan Sadhasivam via B4 Relay
  2025-04-04  8:22 ` [PATCH 1/4] PCI/ERR: Remove misleading TODO regarding kernel panic Manivannan Sadhasivam via B4 Relay
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2025-04-04  8:22 UTC (permalink / raw)
  To: Mahesh J Salgaonkar, Oliver O'Halloran, Bjorn Helgaas,
	Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring
  Cc: dingwei, cassel, Krishna Chaitanya Chundru, linuxppc-dev,
	linux-pci, linux-kernel, linux-arm-msm, Manivannan Sadhasivam

Hi,

Currently, in the event of AER/DPC, PCI core will try to reset the slot 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 slots 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_slot' for the host
bridge drivers to reset the slot when a fatal error happens.

Also, this series allows the host bridge drivers to handle PCI link down event
by resetting the slots and recovering the bus. This is accomplished by the
help of a new API 'pci_host_handle_link_down()'. Host bridge drivers are
expected to call this API (preferrably from a threaded IRQ handler) when a link
down event is detected. 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_slot() callback of the host bridge driver (if exists).

For reference, I've modified the pcie-qcom driver to call
pci_host_handle_link_down() after receiving LINK_DOWN global_irq event and
populated the 'pci_host_bridge::reset_slot()' callback to reset the controller
(there by slots). Since the Qcom PCIe controllers support only a single root
port (slot) per controller instance, reset_slot() callback is going to be
invoked only once. For multi root port controllers, this callback is supposed to
identify the slots using the supplied 'pci_dev' pointer and reset them.

NOTE
====

This series is a reworked version of the earlier series [1] that I submitted for
handling PCI link down event. In this series, I've made use of the AER helpers
to recover the link as it allows notifying the device drivers and also
allows saving/restoring the config space.

Testing
=======

This series is tested on Qcom RB5 and SA8775p Ride boards by triggering the link
down event manually by writing to LTSSM register. For the error recovery to
succeed (if AER is enabled), all the drivers in the bridge hierarchy should have
the 'err_handlers' populated. Otherwise, the link recovery will fail.

[1] https://lore.kernel.org/linux-pci/20250221172309.120009-1-manivannan.sadhasivam@linaro.org

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
Manivannan Sadhasivam (4):
      PCI/ERR: Remove misleading TODO regarding kernel panic
      PCI/ERR: Add support for resetting the slot in a platforms specific way
      PCI: Add link down handling for host bridges
      PCI: qcom: Add support for resetting the slot due to link down event

 drivers/pci/controller/dwc/pcie-qcom.c | 89 +++++++++++++++++++++++++++++++++-
 drivers/pci/pci.h                      | 22 +++++++++
 drivers/pci/pcie/err.c                 | 29 ++++++++---
 drivers/pci/probe.c                    |  7 +++
 include/linux/pci.h                    |  2 +
 5 files changed, 140 insertions(+), 9 deletions(-)
---
base-commit: 08733088b566b58283f0f12fb73f5db6a9a9de30
change-id: 20250404-pcie-reset-slot-730bfa71a202

Best regards,
-- 
Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>




^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/4] PCI/ERR: Remove misleading TODO regarding kernel panic
  2025-04-04  8:22 [PATCH 0/4] PCI: Add support for resetting the slots in a platform specific way Manivannan Sadhasivam via B4 Relay
@ 2025-04-04  8:22 ` Manivannan Sadhasivam via B4 Relay
  2025-04-04  8:22 ` [PATCH 2/4] PCI/ERR: Add support for resetting the slot in a platforms specific way Manivannan Sadhasivam via B4 Relay
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 12+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2025-04-04  8:22 UTC (permalink / raw)
  To: Mahesh J Salgaonkar, Oliver O'Halloran, Bjorn Helgaas,
	Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring
  Cc: dingwei, cassel, Krishna Chaitanya Chundru, linuxppc-dev,
	linux-pci, linux-kernel, linux-arm-msm, Manivannan Sadhasivam

From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

A PCI device is just another peripheral in a system. So failure to
recover it, must not result in a kernel panic. So remove the TODO which
is quite misleading.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 drivers/pci/pcie/err.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/pci/pcie/err.c b/drivers/pci/pcie/err.c
index 31090770fffcc94e15ba6e89f649c6f84bfdf0d5..de6381c690f5c21f00021cdc7bde8d93a5c7db52 100644
--- a/drivers/pci/pcie/err.c
+++ b/drivers/pci/pcie/err.c
@@ -271,7 +271,6 @@ pci_ers_result_t pcie_do_recovery(struct pci_dev *dev,
 
 	pci_uevent_ers(bridge, PCI_ERS_RESULT_DISCONNECT);
 
-	/* TODO: Should kernel panic here? */
 	pci_info(bridge, "device recovery failed\n");
 
 	return status;

-- 
2.43.0




^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 2/4] PCI/ERR: Add support for resetting the slot in a platforms specific way
  2025-04-04  8:22 [PATCH 0/4] PCI: Add support for resetting the slots in a platform specific way Manivannan Sadhasivam via B4 Relay
  2025-04-04  8:22 ` [PATCH 1/4] PCI/ERR: Remove misleading TODO regarding kernel panic Manivannan Sadhasivam via B4 Relay
@ 2025-04-04  8:22 ` Manivannan Sadhasivam via B4 Relay
  2025-04-04  8:46   ` Lukas Wunner
  2025-04-04  8:22 ` [PATCH 3/4] PCI: Add link down handling for host bridges Manivannan Sadhasivam via B4 Relay
  2025-04-04  8:22 ` [PATCH 4/4] PCI: qcom: Add support for resetting the slot due to link down event Manivannan Sadhasivam via B4 Relay
  3 siblings, 1 reply; 12+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2025-04-04  8:22 UTC (permalink / raw)
  To: Mahesh J Salgaonkar, Oliver O'Halloran, Bjorn Helgaas,
	Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring
  Cc: dingwei, cassel, Krishna Chaitanya Chundru, linuxppc-dev,
	linux-pci, linux-kernel, linux-arm-msm, Manivannan Sadhasivam

From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

When the PCI error handling requires resetting the slot, reset it using the
host bridge specific 'reset_slot' callback if available before calling the
'slot_reset' callback of the PCI drivers.

The 'reset_slot' callback is responsible for resetting the given slot
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 slot
reset operation, relevant errno should be returned.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 drivers/pci/pcie/err.c | 15 ++++++++++-----
 include/linux/pci.h    |  1 +
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/pcie/err.c b/drivers/pci/pcie/err.c
index de6381c690f5c21f00021cdc7bde8d93a5c7db52..77ce9354532afee209f658175b86e625bba8a5ee 100644
--- a/drivers/pci/pcie/err.c
+++ b/drivers/pci/pcie/err.c
@@ -234,11 +234,16 @@ 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?
-		 */
+		if (host->reset_slot) {
+			ret = host->reset_slot(host, bridge);
+			if (ret) {
+				pci_err(bridge, "failed to reset slot: %d\n",
+					ret);
+				status = PCI_ERS_RESULT_DISCONNECT;
+				goto failed;
+			}
+		}
+
 		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 0e8e3fd77e96713054388bdc82f439e51023c1bf..8d7d2a49b76cf64b4218b179cec495e0d69ddf6f 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -599,6 +599,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_slot)(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.43.0




^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 3/4] PCI: Add link down handling for host bridges
  2025-04-04  8:22 [PATCH 0/4] PCI: Add support for resetting the slots in a platform specific way Manivannan Sadhasivam via B4 Relay
  2025-04-04  8:22 ` [PATCH 1/4] PCI/ERR: Remove misleading TODO regarding kernel panic Manivannan Sadhasivam via B4 Relay
  2025-04-04  8:22 ` [PATCH 2/4] PCI/ERR: Add support for resetting the slot in a platforms specific way Manivannan Sadhasivam via B4 Relay
@ 2025-04-04  8:22 ` Manivannan Sadhasivam via B4 Relay
  2025-04-04  8:22 ` [PATCH 4/4] PCI: qcom: Add support for resetting the slot due to link down event Manivannan Sadhasivam via B4 Relay
  3 siblings, 0 replies; 12+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2025-04-04  8:22 UTC (permalink / raw)
  To: Mahesh J Salgaonkar, Oliver O'Halloran, Bjorn Helgaas,
	Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring
  Cc: dingwei, cassel, Krishna Chaitanya Chundru, linuxppc-dev,
	linux-pci, linux-kernel, linux-arm-msm, Manivannan Sadhasivam

From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

The PCI link, when down, needs to be recovered to bring it back. But that
cannot be done in a generic way as link recovery procedure is specific to
host bridges. So add a new API pci_host_handle_link_down() that could be
called by the host bridge drivers when the link goes down.

The API will iterate through all the slots and calls the 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 the downstream devices, then
the 'reset_slot' callback for the host bridge will be called to recover the
link. Once that's done, resume message will be broadcasted to the bridge
and the downstream devices indicating successful link recovery.

In case if the AER support is not enabled in the kernel, only the
'reset_slot' callback will be called for each slots as there is no way we
could inform the drivers about link recovery.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 drivers/pci/pci.h      | 22 ++++++++++++++++++++++
 drivers/pci/pcie/err.c | 13 ++++++++++++-
 drivers/pci/probe.c    |  7 +++++++
 include/linux/pci.h    |  1 +
 4 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index b81e99cd4b62a3022c8b07a09f212f6888674487..7ea81d596d5f9608237f5897c5c13288d9169207 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -966,6 +966,7 @@ int pci_aer_clear_status(struct pci_dev *dev);
 int pci_aer_raw_clear_status(struct pci_dev *dev);
 void pci_save_aer_state(struct pci_dev *dev);
 void pci_restore_aer_state(struct pci_dev *dev);
+void pcie_do_recover_slots(struct pci_host_bridge *host);
 #else
 static inline void pci_no_aer(void) { }
 static inline void pci_aer_init(struct pci_dev *d) { }
@@ -975,6 +976,27 @@ static inline int pci_aer_clear_status(struct pci_dev *dev) { return -EINVAL; }
 static inline int pci_aer_raw_clear_status(struct pci_dev *dev) { return -EINVAL; }
 static inline void pci_save_aer_state(struct pci_dev *dev) { }
 static inline void pci_restore_aer_state(struct pci_dev *dev) { }
+static inline void pcie_do_recover_slots(struct pci_host_bridge *host)
+{
+	struct pci_bus *bus = host->bus;
+	struct pci_dev *dev;
+	int ret;
+
+	if (!host->reset_slot) {
+		dev_warn(&host->dev, "Missing reset_slot() callback\n");
+		return;
+	}
+
+	for_each_pci_bridge(dev, bus) {
+		ret = host->reset_slot(host, dev);
+		if (ret)
+			dev_err(&host->dev, "failed to reset slot (%s): %d\n",
+				pci_name(dev), ret);
+		else
+			dev_dbg(&host->dev, "recovered slot (%s)\n",
+				pci_name(dev));
+	}
+}
 #endif
 
 #ifdef CONFIG_ACPI
diff --git a/drivers/pci/pcie/err.c b/drivers/pci/pcie/err.c
index 77ce9354532afee209f658175b86e625bba8a5ee..0f86c228245ef80c5bba4433c109ec37c57f4a67 100644
--- a/drivers/pci/pcie/err.c
+++ b/drivers/pci/pcie/err.c
@@ -196,6 +196,7 @@ pci_ers_result_t pcie_do_recovery(struct pci_dev *dev,
 	struct pci_dev *bridge;
 	pci_ers_result_t status = PCI_ERS_RESULT_CAN_RECOVER;
 	struct pci_host_bridge *host = pci_find_host_bridge(dev->bus);
+	int ret;
 
 	/*
 	 * If the error was detected by a Root Port, Downstream Port, RCEC,
@@ -219,7 +220,8 @@ pci_ers_result_t pcie_do_recovery(struct pci_dev *dev,
 	pci_dbg(bridge, "broadcast error_detected message\n");
 	if (state == pci_channel_io_frozen) {
 		pci_walk_bridge(bridge, report_frozen_detected, &status);
-		if (reset_subordinates(bridge) != PCI_ERS_RESULT_RECOVERED) {
+		if (reset_subordinates && reset_subordinates(bridge) !=
+						PCI_ERS_RESULT_RECOVERED) {
 			pci_warn(bridge, "subordinate device reset failed\n");
 			goto failed;
 		}
@@ -280,3 +282,12 @@ pci_ers_result_t pcie_do_recovery(struct pci_dev *dev,
 
 	return status;
 }
+
+void pcie_do_recover_slots(struct pci_host_bridge *host)
+{
+	struct pci_bus *bus = host->bus;
+	struct pci_dev *dev;
+
+	for_each_pci_bridge(dev, bus)
+		pcie_do_recovery(dev, pci_channel_io_frozen, NULL);
+}
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 364fa2a514f8a68fb18bded3259c6847d3932f8b..60ad20eea0259797e68afa7979bb1fc24b6f213b 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -3249,6 +3249,13 @@ int pci_host_probe(struct pci_host_bridge *bridge)
 }
 EXPORT_SYMBOL_GPL(pci_host_probe);
 
+void pci_host_handle_link_down(struct pci_host_bridge *bridge)
+{
+	dev_info(&bridge->dev, "Recovering slots due to Link Down\n");
+	pcie_do_recover_slots(bridge);
+}
+EXPORT_SYMBOL_GPL(pci_host_handle_link_down);
+
 int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max)
 {
 	struct resource *res = &b->busn_res;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 8d7d2a49b76cf64b4218b179cec495e0d69ddf6f..76e977af2d524200b67f39a6d0417ee565cf5116 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1157,6 +1157,7 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 				    struct pci_ops *ops, void *sysdata,
 				    struct list_head *resources);
 int pci_host_probe(struct pci_host_bridge *bridge);
+void pci_host_handle_link_down(struct pci_host_bridge *bridge);
 int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax);
 int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax);
 void pci_bus_release_busn_res(struct pci_bus *b);

-- 
2.43.0




^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 4/4] PCI: qcom: Add support for resetting the slot due to link down event
  2025-04-04  8:22 [PATCH 0/4] PCI: Add support for resetting the slots in a platform specific way Manivannan Sadhasivam via B4 Relay
                   ` (2 preceding siblings ...)
  2025-04-04  8:22 ` [PATCH 3/4] PCI: Add link down handling for host bridges Manivannan Sadhasivam via B4 Relay
@ 2025-04-04  8:22 ` Manivannan Sadhasivam via B4 Relay
  3 siblings, 0 replies; 12+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2025-04-04  8:22 UTC (permalink / raw)
  To: Mahesh J Salgaonkar, Oliver O'Halloran, Bjorn Helgaas,
	Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring
  Cc: dingwei, cassel, Krishna Chaitanya Chundru, linuxppc-dev,
	linux-pci, linux-kernel, linux-arm-msm, Manivannan Sadhasivam

From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

The PCIe link can go down under circumstances such as the device firmware
crash, link instability, etc... When that happens, the PCIe slot 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 adding support to resetting the slot.

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.

Then in the case of the event, call pci_host_handle_link_down() API
in the handler to let the PCI core handle the link down condition.

The API will internally call, 'pci_host_bridge::reset_slot()' callback to
reset the slot in a platform specific way. So implement the callback to
reset the slot 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>
---
 drivers/pci/controller/dwc/pcie-qcom.c | 89 +++++++++++++++++++++++++++++++++-
 1 file changed, 87 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index dc98ae63362db0422384b1879a2b9a7dc564d091..b0df108fb4f3c6a8b8290062ecb3e1c5c34ddd4c 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -55,6 +55,7 @@
 #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
@@ -130,8 +131,11 @@
 
 /* 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 PARF_INT_ALL_LINK_DOWN			BIT(1)
 #define PARF_INT_ALL_LINK_UP			BIT(13)
 #define PARF_INT_MSI_DEV_0_7			GENMASK(30, 23)
 
@@ -145,6 +149,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)
 
@@ -169,6 +176,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))
 
@@ -274,11 +282,14 @@ struct qcom_pcie {
 	struct icc_path *icc_cpu;
 	const struct qcom_pcie_cfg *cfg;
 	struct dentry *debugfs;
+	int global_irq;
 	bool suspended;
 	bool use_pm_opp;
 };
 
 #define to_qcom_pcie(x)		dev_get_drvdata((x)->dev)
+static int qcom_pcie_reset_slot(struct pci_host_bridge *bridge,
+				  struct pci_dev *pdev);
 
 static void qcom_ep_reset_assert(struct qcom_pcie *pcie)
 {
@@ -1263,6 +1274,8 @@ static int qcom_pcie_host_init(struct dw_pcie_rp *pp)
 			goto err_assert_reset;
 	}
 
+	pp->bridge->reset_slot = qcom_pcie_reset_slot;
+
 	return 0;
 
 err_assert_reset:
@@ -1300,6 +1313,73 @@ static const struct dw_pcie_host_ops qcom_pcie_dw_ops = {
 	.post_init	= qcom_pcie_host_post_init,
 };
 
+static int qcom_pcie_reset_slot(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_UP | 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, "Slot reset completed\n");
+
+	return 0;
+
+err_host_deinit:
+	qcom_pcie_host_deinit(pp);
+
+	return ret;
+}
+
 /* Qcom IP rev.: 2.1.0	Synopsys IP rev.: 4.01a */
 static const struct qcom_pcie_ops ops_2_1_0 = {
 	.get_resources = qcom_pcie_get_resources_2_1_0,
@@ -1571,6 +1651,9 @@ static irqreturn_t qcom_pcie_global_irq_thread(int irq, void *data)
 		pci_unlock_rescan_remove();
 
 		qcom_pcie_icc_opp_update(pcie);
+	} else if (FIELD_GET(PARF_INT_ALL_LINK_DOWN, status)) {
+		dev_dbg(dev, "Received Link down event\n");
+		pci_host_handle_link_down(pp->bridge);
 	} else {
 		dev_WARN_ONCE(dev, 1, "Received unknown event. INT_STATUS: 0x%08x\n",
 			      status);
@@ -1732,8 +1815,10 @@ static int qcom_pcie_probe(struct platform_device *pdev)
 			goto err_host_deinit;
 		}
 
-		writel_relaxed(PARF_INT_ALL_LINK_UP | PARF_INT_MSI_DEV_0_7,
-			       pcie->parf + PARF_INT_ALL_MASK);
+		writel_relaxed(PARF_INT_ALL_LINK_UP | 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);

-- 
2.43.0




^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/4] PCI/ERR: Add support for resetting the slot in a platforms specific way
  2025-04-04  8:22 ` [PATCH 2/4] PCI/ERR: Add support for resetting the slot in a platforms specific way Manivannan Sadhasivam via B4 Relay
@ 2025-04-04  8:46   ` Lukas Wunner
  2025-04-15 13:33     ` Manivannan Sadhasivam
  0 siblings, 1 reply; 12+ messages in thread
From: Lukas Wunner @ 2025-04-04  8:46 UTC (permalink / raw)
  To: manivannan.sadhasivam
  Cc: Mahesh J Salgaonkar, Oliver O'Halloran, Bjorn Helgaas,
	Lorenzo Pieralisi, Krzysztof Wilczy??ski, Rob Herring, dingwei,
	cassel, Krishna Chaitanya Chundru, linuxppc-dev, linux-pci,
	linux-kernel, linux-arm-msm

On Fri, Apr 04, 2025 at 01:52:22PM +0530, Manivannan Sadhasivam via B4 Relay wrote:
> When the PCI error handling requires resetting the slot, reset it using the
> host bridge specific 'reset_slot' callback if available before calling the
> 'slot_reset' callback of the PCI drivers.
> 
> The 'reset_slot' callback is responsible for resetting the given slot
> 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 slot
> reset operation, relevant errno should be returned.
[...]
> --- a/drivers/pci/pcie/err.c
> +++ b/drivers/pci/pcie/err.c
> @@ -234,11 +234,16 @@ 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?
> -		 */
> +		if (host->reset_slot) {
> +			ret = host->reset_slot(host, bridge);
> +			if (ret) {
> +				pci_err(bridge, "failed to reset slot: %d\n",
> +					ret);
> +				status = PCI_ERS_RESULT_DISCONNECT;
> +				goto failed;
> +			}
> +		}
> +

This feels like something that should be plumbed into
pcibios_reset_secondary_bus(), rather than pcie_do_recovery().

Note that in the DPC case, pcie_do_recovery() doesn't issue a reset
itself.  The reset has already happened, it was automatically done
by the hardware and all the kernel needs to do is bring up the link
again.  Do you really need any special handling for that in the
host controller driver?

Only in the AER case do you want to issue a reset on the secondary bus
and if there's any platform-specific support needed for that, it needs
to go into pcibios_reset_secondary_bus().

Thanks,

Lukas


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/4] PCI/ERR: Add support for resetting the slot in a platforms specific way
  2025-04-04  8:46   ` Lukas Wunner
@ 2025-04-15 13:33     ` Manivannan Sadhasivam
  2025-04-16 14:38       ` Lukas Wunner
  0 siblings, 1 reply; 12+ messages in thread
From: Manivannan Sadhasivam @ 2025-04-15 13:33 UTC (permalink / raw)
  To: Lukas Wunner
  Cc: Mahesh J Salgaonkar, Oliver O'Halloran, Bjorn Helgaas,
	Lorenzo Pieralisi, Krzysztof Wilczy??ski, Rob Herring, dingwei,
	cassel, Krishna Chaitanya Chundru, linuxppc-dev, linux-pci,
	linux-kernel, linux-arm-msm

On Fri, Apr 04, 2025 at 10:46:27AM +0200, Lukas Wunner wrote:
> On Fri, Apr 04, 2025 at 01:52:22PM +0530, Manivannan Sadhasivam via B4 Relay wrote:
> > When the PCI error handling requires resetting the slot, reset it using the
> > host bridge specific 'reset_slot' callback if available before calling the
> > 'slot_reset' callback of the PCI drivers.
> > 
> > The 'reset_slot' callback is responsible for resetting the given slot
> > 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 slot
> > reset operation, relevant errno should be returned.
> [...]
> > --- a/drivers/pci/pcie/err.c
> > +++ b/drivers/pci/pcie/err.c
> > @@ -234,11 +234,16 @@ 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?
> > -		 */
> > +		if (host->reset_slot) {
> > +			ret = host->reset_slot(host, bridge);
> > +			if (ret) {
> > +				pci_err(bridge, "failed to reset slot: %d\n",
> > +					ret);
> > +				status = PCI_ERS_RESULT_DISCONNECT;
> > +				goto failed;
> > +			}
> > +		}
> > +
> 
> This feels like something that should be plumbed into
> pcibios_reset_secondary_bus(), rather than pcie_do_recovery().
> 

I did consider that, but didn't go for it since there was no platform reset code
present in that function. But I will try to use it as I don't have a strong
preference to do reset slot in pcie_do_recovery().

> Note that in the DPC case, pcie_do_recovery() doesn't issue a reset
> itself.  The reset has already happened, it was automatically done
> by the hardware and all the kernel needs to do is bring up the link
> again.  Do you really need any special handling for that in the
> host controller driver?
> 

I haven't tested DPC, so I'm not sure if reset slot is needed or not.

> Only in the AER case do you want to issue a reset on the secondary bus
> and if there's any platform-specific support needed for that, it needs
> to go into pcibios_reset_secondary_bus().
> 

Ok. I'm trying out this right now and will see if it satisfies my requirement
(for both AER fatal and Link Down recovery).

- Mani

-- 
மணிவண்ணன் சதாசிவம்


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/4] PCI/ERR: Add support for resetting the slot in a platforms specific way
  2025-04-15 13:33     ` Manivannan Sadhasivam
@ 2025-04-16 14:38       ` Lukas Wunner
  2025-04-16 15:04         ` Manivannan Sadhasivam
  0 siblings, 1 reply; 12+ messages in thread
From: Lukas Wunner @ 2025-04-16 14:38 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: Mahesh J Salgaonkar, Oliver O'Halloran, Bjorn Helgaas,
	Lorenzo Pieralisi, Krzysztof Wilczy??ski, Rob Herring, dingwei,
	cassel, Krishna Chaitanya Chundru, linuxppc-dev, linux-pci,
	linux-kernel, linux-arm-msm

On Tue, Apr 15, 2025 at 07:03:17PM +0530, Manivannan Sadhasivam wrote:
> On Fri, Apr 04, 2025 at 10:46:27AM +0200, Lukas Wunner wrote:
> > On Fri, Apr 04, 2025 at 01:52:22PM +0530, Manivannan Sadhasivam via B4 Relay wrote:
> > > When the PCI error handling requires resetting the slot, reset it
> > > using the host bridge specific 'reset_slot' callback if available
> > > before calling the 'slot_reset' callback of the PCI drivers.
> > > 
> > > The 'reset_slot' callback is responsible for resetting the given slot
> > > 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 slot reset operation, relevant errno should be returned.
> > 
> > This feels like something that should be plumbed into
> > pcibios_reset_secondary_bus(), rather than pcie_do_recovery().
> 
> I did consider that, but didn't go for it since there was no platform
> reset code present in that function. But I will try to use it as I
> don't have a strong preference to do reset slot in pcie_do_recovery().

The only platform overriding pcibios_reset_secondary_bus() is powerpc,
and it only does that on PowerNV.

I think you could continue to stick with the approach of adding a
->reset_slot() callback to struct pci_host_bridge, but it would
be good if at the same time you could convert PowerNV to use the
newly introduced callback as well.  And then remove the way to
override the reset procedure via pcibios_reset_secondary_bus().

All pci_host_bridge's which do not define a ->reset_slot() could be
assigned a default callback which just calls pci_reset_secondary_bus().

Alternatively, pcibios_reset_secondary_bus() could be made to invoke the
pci_host_bridge's ->reset_slot() callback if it's not NULL, else
pci_reset_secondary_bus().  And in that case, the __weak attribute
could be removed as well as the powerpc-specific version of
pcibios_reset_secondary_bus().

I guess what I'm trying to say is, you don't *have* to plumb this
into pcibios_reset_secondary_bus().  In fact, having a host bridge
specific callback could be useful if the SoC contains several
host bridges which require different callbacks to perform a reset.

I just want to make sure that the code remains maintainable,
i.e. we don't have two separate ways to override how a bus reset
is performed.

Thanks,

Lukas


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/4] PCI/ERR: Add support for resetting the slot in a platforms specific way
  2025-04-16 14:38       ` Lukas Wunner
@ 2025-04-16 15:04         ` Manivannan Sadhasivam
  2025-04-17  0:23           ` Lukas Wunner
  0 siblings, 1 reply; 12+ messages in thread
From: Manivannan Sadhasivam @ 2025-04-16 15:04 UTC (permalink / raw)
  To: Lukas Wunner
  Cc: Mahesh J Salgaonkar, Oliver O'Halloran, Bjorn Helgaas,
	Lorenzo Pieralisi, Krzysztof Wilczy??ski, Rob Herring, dingwei,
	cassel, Krishna Chaitanya Chundru, linuxppc-dev, linux-pci,
	linux-kernel, linux-arm-msm

On Wed, Apr 16, 2025 at 04:38:01PM +0200, Lukas Wunner wrote:
> On Tue, Apr 15, 2025 at 07:03:17PM +0530, Manivannan Sadhasivam wrote:
> > On Fri, Apr 04, 2025 at 10:46:27AM +0200, Lukas Wunner wrote:
> > > On Fri, Apr 04, 2025 at 01:52:22PM +0530, Manivannan Sadhasivam via B4 Relay wrote:
> > > > When the PCI error handling requires resetting the slot, reset it
> > > > using the host bridge specific 'reset_slot' callback if available
> > > > before calling the 'slot_reset' callback of the PCI drivers.
> > > > 
> > > > The 'reset_slot' callback is responsible for resetting the given slot
> > > > 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 slot reset operation, relevant errno should be returned.
> > > 
> > > This feels like something that should be plumbed into
> > > pcibios_reset_secondary_bus(), rather than pcie_do_recovery().
> > 
> > I did consider that, but didn't go for it since there was no platform
> > reset code present in that function. But I will try to use it as I
> > don't have a strong preference to do reset slot in pcie_do_recovery().
> 
> The only platform overriding pcibios_reset_secondary_bus() is powerpc,
> and it only does that on PowerNV.
> 
> I think you could continue to stick with the approach of adding a
> ->reset_slot() callback to struct pci_host_bridge, but it would
> be good if at the same time you could convert PowerNV to use the
> newly introduced callback as well.  And then remove the way to
> override the reset procedure via pcibios_reset_secondary_bus().
> 
> All pci_host_bridge's which do not define a ->reset_slot() could be
> assigned a default callback which just calls pci_reset_secondary_bus().
> 
> Alternatively, pcibios_reset_secondary_bus() could be made to invoke the
> pci_host_bridge's ->reset_slot() callback if it's not NULL, else
> pci_reset_secondary_bus(). 

Yes. This is what I now tried locally as well.

> And in that case, the __weak attribute
> could be removed as well as the powerpc-specific version of
> pcibios_reset_secondary_bus().
> 

I don't think it is possible to get rid of the powerpc version. It has its own
pci_dev::sysdata pointing to 'struct pci_controller' pointer which is internal
to powerpc arch code. And the generic code would need 'struct pci_host_bridge'
to access the callback.

> I guess what I'm trying to say is, you don't *have* to plumb this
> into pcibios_reset_secondary_bus().  In fact, having a host bridge
> specific callback could be useful if the SoC contains several
> host bridges which require different callbacks to perform a reset.
> 
> I just want to make sure that the code remains maintainable,
> i.e. we don't have two separate ways to override how a bus reset
> is performed.
> 

I think we need to have the override in powerpc anyway. But I will move the
'reset_slot' callback to it and get it called from pci_bus_error_reset() (for
both AER and Link Down).

- Mani

-- 
மணிவண்ணன் சதாசிவம்


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/4] PCI/ERR: Add support for resetting the slot in a platforms specific way
  2025-04-16 15:04         ` Manivannan Sadhasivam
@ 2025-04-17  0:23           ` Lukas Wunner
  2025-04-17  5:39             ` Manivannan Sadhasivam
  0 siblings, 1 reply; 12+ messages in thread
From: Lukas Wunner @ 2025-04-17  0:23 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: Mahesh J Salgaonkar, Oliver O'Halloran, Bjorn Helgaas,
	Lorenzo Pieralisi, Krzysztof Wilczy??ski, Rob Herring, dingwei,
	cassel, Krishna Chaitanya Chundru, linuxppc-dev, linux-pci,
	linux-kernel, linux-arm-msm

On Wed, Apr 16, 2025 at 08:34:21PM +0530, Manivannan Sadhasivam wrote:
> I don't think it is possible to get rid of the powerpc version. It has
> its own pci_dev::sysdata pointing to 'struct pci_controller' pointer
> which is internal to powerpc arch code. And the generic code would need
> 'struct pci_host_bridge' to access the callback.

Below is my proposal to convert powerpc to the new ->slot_reset() callback.
Compile-tested only.

Feel free to include this in your series, alternatively I can submit it
to powerpc maintainers once your series has landed.  Thanks!

-- >8 --

From: Lukas Wunner <lukas@wunner.de>
Subject: [PATCH] powerpc/powernv/pci: Migrate to pci_host_bridge::reset_slot
 callback

struct pci_host_bridge has just been amended with a ->reset_slot()
callback to allow for a per-host-bridge Secondary Bus Reset procedure.

PowerNV needs a platform-specific reset procedure and has historically
implemented it by overriding pcibios_reset_secondary_bus().

Migrate PowerNV to the new ->reset_slot() callback for simplicity and
cleanliness.  Assign the callback as soon as the pci_host_bridge is
allocated through the following call chain:

pcibios_init()
  pcibios_scan_phb()
    pci_create_root_bus()
      pci_register_host_bridge()
        pcibios_root_bridge_prepare()

The powerpc-specific implementation of pcibios_reset_secondary_bus() can
thus be deleted and the remaining default implementation in the PCI core
can be made private.  The ->reset_secondary_bus() callback in struct
pci_controller_ops likewise becomes obsolete and can be deleted.

Signed-off-by: Lukas Wunner <lukas@wunner.de>
---
 arch/powerpc/include/asm/pci-bridge.h        |  1 -
 arch/powerpc/kernel/pci-common.c             | 12 ------------
 arch/powerpc/platforms/powernv/eeh-powernv.c | 14 +++++++++-----
 arch/powerpc/platforms/powernv/pci-ioda.c    |  9 +++++++--
 arch/powerpc/platforms/powernv/pci.h         |  3 ++-
 drivers/pci/pci.c                            |  2 +-
 include/linux/pci.h                          |  1 -
 7 files changed, 19 insertions(+), 23 deletions(-)

diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 2aa3a091ef20..0de09fc90641 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -36,7 +36,6 @@ struct pci_controller_ops {
 					    unsigned long type);
 	void		(*setup_bridge)(struct pci_bus *bus,
 					unsigned long type);
-	void		(*reset_secondary_bus)(struct pci_dev *pdev);
 
 #ifdef CONFIG_PCI_MSI
 	int		(*setup_msi_irqs)(struct pci_dev *pdev,
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index eac84d687b53..dad15fbec4e0 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -233,18 +233,6 @@ void pcibios_setup_bridge(struct pci_bus *bus, unsigned long type)
 		hose->controller_ops.setup_bridge(bus, type);
 }
 
-void pcibios_reset_secondary_bus(struct pci_dev *dev)
-{
-	struct pci_controller *phb = pci_bus_to_host(dev->bus);
-
-	if (phb->controller_ops.reset_secondary_bus) {
-		phb->controller_ops.reset_secondary_bus(dev);
-		return;
-	}
-
-	pci_reset_secondary_bus(dev);
-}
-
 resource_size_t pcibios_default_alignment(void)
 {
 	if (ppc_md.pcibios_default_alignment)
diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c
index db3370d1673c..9b9517cb6ab7 100644
--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
+++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
@@ -890,18 +890,22 @@ static int pnv_eeh_bridge_reset(struct pci_dev *pdev, int option)
 	return (rc == OPAL_SUCCESS) ? 0 : -EIO;
 }
 
-void pnv_pci_reset_secondary_bus(struct pci_dev *dev)
+int pnv_pci_reset_secondary_bus(struct pci_host_bridge *host,
+				struct pci_dev *dev)
 {
 	struct pci_controller *hose;
+	int rc_hot, rc_dea;
 
 	if (pci_is_root_bus(dev->bus)) {
 		hose = pci_bus_to_host(dev->bus);
-		pnv_eeh_root_reset(hose, EEH_RESET_HOT);
-		pnv_eeh_root_reset(hose, EEH_RESET_DEACTIVATE);
+		rc_hot = pnv_eeh_root_reset(hose, EEH_RESET_HOT);
+		rc_dea = pnv_eeh_root_reset(hose, EEH_RESET_DEACTIVATE);
 	} else {
-		pnv_eeh_bridge_reset(dev, EEH_RESET_HOT);
-		pnv_eeh_bridge_reset(dev, EEH_RESET_DEACTIVATE);
+		rc_hot = pnv_eeh_bridge_reset(dev, EEH_RESET_HOT);
+		rc_dea = pnv_eeh_bridge_reset(dev, EEH_RESET_DEACTIVATE);
 	}
+
+	return rc_hot ? : rc_dea ? : 0;
 }
 
 static void pnv_eeh_wait_for_pending(struct pci_dn *pdn, const char *type,
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index ae4b549b5ca0..e1b75a4bc681 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -2145,6 +2145,12 @@ static void pnv_pci_ioda_fixup(void)
 #endif
 }
 
+static int pnv_pci_root_bridge_prepare(struct pci_host_bridge *bridge)
+{
+	bridge->reset_slot = pnv_pci_reset_secondary_bus;
+	return 0;
+}
+
 /*
  * Returns the alignment for I/O or memory windows for P2P
  * bridges. That actually depends on how PEs are segmented.
@@ -2504,7 +2510,6 @@ static const struct pci_controller_ops pnv_pci_ioda_controller_ops = {
 	.release_device		= pnv_pci_release_device,
 	.window_alignment	= pnv_pci_window_alignment,
 	.setup_bridge		= pnv_pci_fixup_bridge_resources,
-	.reset_secondary_bus	= pnv_pci_reset_secondary_bus,
 	.shutdown		= pnv_pci_ioda_shutdown,
 #ifdef CONFIG_IOMMU_API
 	.device_group		= pnv_pci_device_group,
@@ -2515,7 +2520,6 @@ static const struct pci_controller_ops pnv_npu_ocapi_ioda_controller_ops = {
 	.enable_device_hook	= pnv_ocapi_enable_device_hook,
 	.release_device		= pnv_pci_release_device,
 	.window_alignment	= pnv_pci_window_alignment,
-	.reset_secondary_bus	= pnv_pci_reset_secondary_bus,
 	.shutdown		= pnv_pci_ioda_shutdown,
 };
 
@@ -2724,6 +2728,7 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
 	}
 
 	ppc_md.pcibios_default_alignment = pnv_pci_default_alignment;
+	ppc_md.pcibios_root_bridge_prepare = pnv_pci_root_bridge_prepare;
 
 #ifdef CONFIG_PCI_IOV
 	ppc_md.pcibios_fixup_sriov = pnv_pci_ioda_fixup_iov;
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h
index 42075501663b..44e8969c7729 100644
--- a/arch/powerpc/platforms/powernv/pci.h
+++ b/arch/powerpc/platforms/powernv/pci.h
@@ -275,7 +275,8 @@ extern struct iommu_table *pnv_pci_table_alloc(int nid);
 
 extern void pnv_pci_init_ioda2_phb(struct device_node *np);
 extern void pnv_pci_init_npu2_opencapi_phb(struct device_node *np);
-extern void pnv_pci_reset_secondary_bus(struct pci_dev *dev);
+extern int pnv_pci_reset_secondary_bus(struct pci_host_bridge *host,
+				       struct pci_dev *dev);
 extern int pnv_eeh_phb_reset(struct pci_controller *hose, int option);
 
 extern struct pnv_ioda_pe *pnv_pci_bdfn_to_pe(struct pnv_phb *phb, u16 bdfn);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 13709bb898a9..fe66d69c6429 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -4980,7 +4980,7 @@ void pci_reset_secondary_bus(struct pci_dev *dev)
 	pci_write_config_word(dev, PCI_BRIDGE_CONTROL, ctrl);
 }
 
-void __weak pcibios_reset_secondary_bus(struct pci_dev *dev)
+static void pcibios_reset_secondary_bus(struct pci_dev *dev)
 {
 	struct pci_host_bridge *host = pci_find_host_bridge(dev->bus);
 	int ret;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 76e977af2d52..43d952361e84 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1398,7 +1398,6 @@ int pci_probe_reset_slot(struct pci_slot *slot);
 int pci_probe_reset_bus(struct pci_bus *bus);
 int pci_reset_bus(struct pci_dev *dev);
 void pci_reset_secondary_bus(struct pci_dev *dev);
-void pcibios_reset_secondary_bus(struct pci_dev *dev);
 void pci_update_resource(struct pci_dev *dev, int resno);
 int __must_check pci_assign_resource(struct pci_dev *dev, int i);
 void pci_release_resource(struct pci_dev *dev, int resno);
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/4] PCI/ERR: Add support for resetting the slot in a platforms specific way
  2025-04-17  0:23           ` Lukas Wunner
@ 2025-04-17  5:39             ` Manivannan Sadhasivam
  2025-04-17 11:42               ` Lukas Wunner
  0 siblings, 1 reply; 12+ messages in thread
From: Manivannan Sadhasivam @ 2025-04-17  5:39 UTC (permalink / raw)
  To: Lukas Wunner
  Cc: Mahesh J Salgaonkar, Oliver O'Halloran, Bjorn Helgaas,
	Lorenzo Pieralisi, Krzysztof Wilczy??ski, Rob Herring, dingwei,
	cassel, Krishna Chaitanya Chundru, linuxppc-dev, linux-pci,
	linux-kernel, linux-arm-msm

On Thu, Apr 17, 2025 at 02:23:26AM +0200, Lukas Wunner wrote:
> On Wed, Apr 16, 2025 at 08:34:21PM +0530, Manivannan Sadhasivam wrote:
> > I don't think it is possible to get rid of the powerpc version. It has
> > its own pci_dev::sysdata pointing to 'struct pci_controller' pointer
> > which is internal to powerpc arch code. And the generic code would need
> > 'struct pci_host_bridge' to access the callback.
> 
> Below is my proposal to convert powerpc to the new ->slot_reset() callback.
> Compile-tested only.
> 
> Feel free to include this in your series, alternatively I can submit it
> to powerpc maintainers once your series has landed.  Thanks!
> 
> -- >8 --
> 
> From: Lukas Wunner <lukas@wunner.de>
> Subject: [PATCH] powerpc/powernv/pci: Migrate to pci_host_bridge::reset_slot
>  callback
> 
> struct pci_host_bridge has just been amended with a ->reset_slot()
> callback to allow for a per-host-bridge Secondary Bus Reset procedure.
> 
> PowerNV needs a platform-specific reset procedure and has historically
> implemented it by overriding pcibios_reset_secondary_bus().
> 
> Migrate PowerNV to the new ->reset_slot() callback for simplicity and
> cleanliness.  Assign the callback as soon as the pci_host_bridge is
> allocated through the following call chain:
> 
> pcibios_init()
>   pcibios_scan_phb()
>     pci_create_root_bus()
>       pci_register_host_bridge()
>         pcibios_root_bridge_prepare()
> 
> The powerpc-specific implementation of pcibios_reset_secondary_bus() can
> thus be deleted and the remaining default implementation in the PCI core
> can be made private.  The ->reset_secondary_bus() callback in struct
> pci_controller_ops likewise becomes obsolete and can be deleted.
> 

Looks good to me, thanks! I think it would be better if it is submitted once my
series has landed in mainline (just to avoid immutable branch hassle between
powerpc and PCI trees).

- Mani

> Signed-off-by: Lukas Wunner <lukas@wunner.de>
> ---
>  arch/powerpc/include/asm/pci-bridge.h        |  1 -
>  arch/powerpc/kernel/pci-common.c             | 12 ------------
>  arch/powerpc/platforms/powernv/eeh-powernv.c | 14 +++++++++-----
>  arch/powerpc/platforms/powernv/pci-ioda.c    |  9 +++++++--
>  arch/powerpc/platforms/powernv/pci.h         |  3 ++-
>  drivers/pci/pci.c                            |  2 +-
>  include/linux/pci.h                          |  1 -
>  7 files changed, 19 insertions(+), 23 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
> index 2aa3a091ef20..0de09fc90641 100644
> --- a/arch/powerpc/include/asm/pci-bridge.h
> +++ b/arch/powerpc/include/asm/pci-bridge.h
> @@ -36,7 +36,6 @@ struct pci_controller_ops {
>  					    unsigned long type);
>  	void		(*setup_bridge)(struct pci_bus *bus,
>  					unsigned long type);
> -	void		(*reset_secondary_bus)(struct pci_dev *pdev);
>  
>  #ifdef CONFIG_PCI_MSI
>  	int		(*setup_msi_irqs)(struct pci_dev *pdev,
> diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
> index eac84d687b53..dad15fbec4e0 100644
> --- a/arch/powerpc/kernel/pci-common.c
> +++ b/arch/powerpc/kernel/pci-common.c
> @@ -233,18 +233,6 @@ void pcibios_setup_bridge(struct pci_bus *bus, unsigned long type)
>  		hose->controller_ops.setup_bridge(bus, type);
>  }
>  
> -void pcibios_reset_secondary_bus(struct pci_dev *dev)
> -{
> -	struct pci_controller *phb = pci_bus_to_host(dev->bus);
> -
> -	if (phb->controller_ops.reset_secondary_bus) {
> -		phb->controller_ops.reset_secondary_bus(dev);
> -		return;
> -	}
> -
> -	pci_reset_secondary_bus(dev);
> -}
> -
>  resource_size_t pcibios_default_alignment(void)
>  {
>  	if (ppc_md.pcibios_default_alignment)
> diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c
> index db3370d1673c..9b9517cb6ab7 100644
> --- a/arch/powerpc/platforms/powernv/eeh-powernv.c
> +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
> @@ -890,18 +890,22 @@ static int pnv_eeh_bridge_reset(struct pci_dev *pdev, int option)
>  	return (rc == OPAL_SUCCESS) ? 0 : -EIO;
>  }
>  
> -void pnv_pci_reset_secondary_bus(struct pci_dev *dev)
> +int pnv_pci_reset_secondary_bus(struct pci_host_bridge *host,
> +				struct pci_dev *dev)
>  {
>  	struct pci_controller *hose;
> +	int rc_hot, rc_dea;
>  
>  	if (pci_is_root_bus(dev->bus)) {
>  		hose = pci_bus_to_host(dev->bus);
> -		pnv_eeh_root_reset(hose, EEH_RESET_HOT);
> -		pnv_eeh_root_reset(hose, EEH_RESET_DEACTIVATE);
> +		rc_hot = pnv_eeh_root_reset(hose, EEH_RESET_HOT);
> +		rc_dea = pnv_eeh_root_reset(hose, EEH_RESET_DEACTIVATE);
>  	} else {
> -		pnv_eeh_bridge_reset(dev, EEH_RESET_HOT);
> -		pnv_eeh_bridge_reset(dev, EEH_RESET_DEACTIVATE);
> +		rc_hot = pnv_eeh_bridge_reset(dev, EEH_RESET_HOT);
> +		rc_dea = pnv_eeh_bridge_reset(dev, EEH_RESET_DEACTIVATE);
>  	}
> +
> +	return rc_hot ? : rc_dea ? : 0;
>  }
>  
>  static void pnv_eeh_wait_for_pending(struct pci_dn *pdn, const char *type,
> diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
> index ae4b549b5ca0..e1b75a4bc681 100644
> --- a/arch/powerpc/platforms/powernv/pci-ioda.c
> +++ b/arch/powerpc/platforms/powernv/pci-ioda.c
> @@ -2145,6 +2145,12 @@ static void pnv_pci_ioda_fixup(void)
>  #endif
>  }
>  
> +static int pnv_pci_root_bridge_prepare(struct pci_host_bridge *bridge)
> +{
> +	bridge->reset_slot = pnv_pci_reset_secondary_bus;
> +	return 0;
> +}
> +
>  /*
>   * Returns the alignment for I/O or memory windows for P2P
>   * bridges. That actually depends on how PEs are segmented.
> @@ -2504,7 +2510,6 @@ static const struct pci_controller_ops pnv_pci_ioda_controller_ops = {
>  	.release_device		= pnv_pci_release_device,
>  	.window_alignment	= pnv_pci_window_alignment,
>  	.setup_bridge		= pnv_pci_fixup_bridge_resources,
> -	.reset_secondary_bus	= pnv_pci_reset_secondary_bus,
>  	.shutdown		= pnv_pci_ioda_shutdown,
>  #ifdef CONFIG_IOMMU_API
>  	.device_group		= pnv_pci_device_group,
> @@ -2515,7 +2520,6 @@ static const struct pci_controller_ops pnv_npu_ocapi_ioda_controller_ops = {
>  	.enable_device_hook	= pnv_ocapi_enable_device_hook,
>  	.release_device		= pnv_pci_release_device,
>  	.window_alignment	= pnv_pci_window_alignment,
> -	.reset_secondary_bus	= pnv_pci_reset_secondary_bus,
>  	.shutdown		= pnv_pci_ioda_shutdown,
>  };
>  
> @@ -2724,6 +2728,7 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
>  	}
>  
>  	ppc_md.pcibios_default_alignment = pnv_pci_default_alignment;
> +	ppc_md.pcibios_root_bridge_prepare = pnv_pci_root_bridge_prepare;
>  
>  #ifdef CONFIG_PCI_IOV
>  	ppc_md.pcibios_fixup_sriov = pnv_pci_ioda_fixup_iov;
> diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h
> index 42075501663b..44e8969c7729 100644
> --- a/arch/powerpc/platforms/powernv/pci.h
> +++ b/arch/powerpc/platforms/powernv/pci.h
> @@ -275,7 +275,8 @@ extern struct iommu_table *pnv_pci_table_alloc(int nid);
>  
>  extern void pnv_pci_init_ioda2_phb(struct device_node *np);
>  extern void pnv_pci_init_npu2_opencapi_phb(struct device_node *np);
> -extern void pnv_pci_reset_secondary_bus(struct pci_dev *dev);
> +extern int pnv_pci_reset_secondary_bus(struct pci_host_bridge *host,
> +				       struct pci_dev *dev);
>  extern int pnv_eeh_phb_reset(struct pci_controller *hose, int option);
>  
>  extern struct pnv_ioda_pe *pnv_pci_bdfn_to_pe(struct pnv_phb *phb, u16 bdfn);
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index 13709bb898a9..fe66d69c6429 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -4980,7 +4980,7 @@ void pci_reset_secondary_bus(struct pci_dev *dev)
>  	pci_write_config_word(dev, PCI_BRIDGE_CONTROL, ctrl);
>  }
>  
> -void __weak pcibios_reset_secondary_bus(struct pci_dev *dev)
> +static void pcibios_reset_secondary_bus(struct pci_dev *dev)
>  {
>  	struct pci_host_bridge *host = pci_find_host_bridge(dev->bus);
>  	int ret;
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 76e977af2d52..43d952361e84 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -1398,7 +1398,6 @@ int pci_probe_reset_slot(struct pci_slot *slot);
>  int pci_probe_reset_bus(struct pci_bus *bus);
>  int pci_reset_bus(struct pci_dev *dev);
>  void pci_reset_secondary_bus(struct pci_dev *dev);
> -void pcibios_reset_secondary_bus(struct pci_dev *dev);
>  void pci_update_resource(struct pci_dev *dev, int resno);
>  int __must_check pci_assign_resource(struct pci_dev *dev, int i);
>  void pci_release_resource(struct pci_dev *dev, int resno);
> -- 
> 2.43.0
> 

-- 
மணிவண்ணன் சதாசிவம்


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/4] PCI/ERR: Add support for resetting the slot in a platforms specific way
  2025-04-17  5:39             ` Manivannan Sadhasivam
@ 2025-04-17 11:42               ` Lukas Wunner
  0 siblings, 0 replies; 12+ messages in thread
From: Lukas Wunner @ 2025-04-17 11:42 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: Mahesh J Salgaonkar, Oliver O'Halloran, Bjorn Helgaas,
	Lorenzo Pieralisi, Krzysztof Wilczy??ski, Rob Herring, dingwei,
	cassel, Krishna Chaitanya Chundru, linuxppc-dev, linux-pci,
	linux-kernel, linux-arm-msm

On Thu, Apr 17, 2025 at 11:09:21AM +0530, Manivannan Sadhasivam wrote:
> On Thu, Apr 17, 2025 at 02:23:26AM +0200, Lukas Wunner wrote:
> > On Wed, Apr 16, 2025 at 08:34:21PM +0530, Manivannan Sadhasivam wrote:
> > > I don't think it is possible to get rid of the powerpc version. It has
> > > its own pci_dev::sysdata pointing to 'struct pci_controller' pointer
> > > which is internal to powerpc arch code. And the generic code would need
> > > 'struct pci_host_bridge' to access the callback.
> > 
> > Below is my proposal to convert powerpc to the new ->slot_reset() callback.
> > Compile-tested only.
> > 
> > Feel free to include this in your series, alternatively I can submit it
> > to powerpc maintainers once your series has landed.  Thanks!
> 
> Looks good to me, thanks! I think it would be better if it is submitted
> once my series has landed in mainline (just to avoid immutable branch
> hassle between powerpc and PCI trees).

Sure, this can wait until your series has landed.  It would also be
possible to merge through the pci tree if powerpc maintainers ack the
patch.

I've realized that pci_reset_secondary_bus() can be made private as well,
so below is an updated patch.  Just putting this out there FWIW.

-- 8< --

From: Lukas Wunner <lukas@wunner.de>
Subject: [PATCH] powerpc/powernv/pci: Migrate to pci_host_bridge::reset_slot
 callback

struct pci_host_bridge has just been amended with a ->reset_slot()
callback to allow for a host-bridge-specific bus reset procedure.

PowerNV needs a platform-specific bus reset procedure and has historically
implemented it by overriding pcibios_reset_secondary_bus().

Migrate PowerNV to the new ->reset_slot() callback to avoid having to
maintain two different mechanisms for platform- and host-bridge-specific
bus reset procedures.  Assign the callback as soon as the pci_host_bridge
is allocated through the following call chain:

pcibios_init()
  pcibios_scan_phb()
    pci_create_root_bus()
      pci_register_host_bridge()
        pcibios_root_bridge_prepare()

The powerpc-specific implementation of pcibios_reset_secondary_bus() can
thus be deleted and the remaining default implementation in the PCI core
can be made private.  pci_reset_secondary_bus() can also be made private.
The ->reset_secondary_bus() callback in struct pci_controller_ops becomes
obsolete and can be deleted.

Signed-off-by: Lukas Wunner <lukas@wunner.de>
---
 arch/powerpc/include/asm/pci-bridge.h        |  1 -
 arch/powerpc/kernel/pci-common.c             | 12 ------------
 arch/powerpc/platforms/powernv/eeh-powernv.c | 14 +++++++++-----
 arch/powerpc/platforms/powernv/pci-ioda.c    |  9 +++++++--
 arch/powerpc/platforms/powernv/pci.h         |  3 ++-
 drivers/pci/pci.c                            |  4 ++--
 include/linux/pci.h                          |  2 --
 7 files changed, 20 insertions(+), 25 deletions(-)

diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 2aa3a091ef20..0de09fc90641 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -36,7 +36,6 @@ struct pci_controller_ops {
 					    unsigned long type);
 	void		(*setup_bridge)(struct pci_bus *bus,
 					unsigned long type);
-	void		(*reset_secondary_bus)(struct pci_dev *pdev);
 
 #ifdef CONFIG_PCI_MSI
 	int		(*setup_msi_irqs)(struct pci_dev *pdev,
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index eac84d687b53..dad15fbec4e0 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -233,18 +233,6 @@ void pcibios_setup_bridge(struct pci_bus *bus, unsigned long type)
 		hose->controller_ops.setup_bridge(bus, type);
 }
 
-void pcibios_reset_secondary_bus(struct pci_dev *dev)
-{
-	struct pci_controller *phb = pci_bus_to_host(dev->bus);
-
-	if (phb->controller_ops.reset_secondary_bus) {
-		phb->controller_ops.reset_secondary_bus(dev);
-		return;
-	}
-
-	pci_reset_secondary_bus(dev);
-}
-
 resource_size_t pcibios_default_alignment(void)
 {
 	if (ppc_md.pcibios_default_alignment)
diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c
index db3370d1673c..9ea2fa892efc 100644
--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
+++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
@@ -890,18 +890,22 @@ static int pnv_eeh_bridge_reset(struct pci_dev *pdev, int option)
 	return (rc == OPAL_SUCCESS) ? 0 : -EIO;
 }
 
-void pnv_pci_reset_secondary_bus(struct pci_dev *dev)
+int pnv_pci_reset_secondary_bus(struct pci_host_bridge *host,
+				struct pci_dev *dev)
 {
 	struct pci_controller *hose;
+	int rc_hot, rc_dea;
 
 	if (pci_is_root_bus(dev->bus)) {
 		hose = pci_bus_to_host(dev->bus);
-		pnv_eeh_root_reset(hose, EEH_RESET_HOT);
-		pnv_eeh_root_reset(hose, EEH_RESET_DEACTIVATE);
+		rc_hot = pnv_eeh_root_reset(hose, EEH_RESET_HOT);
+		rc_dea = pnv_eeh_root_reset(hose, EEH_RESET_DEACTIVATE);
 	} else {
-		pnv_eeh_bridge_reset(dev, EEH_RESET_HOT);
-		pnv_eeh_bridge_reset(dev, EEH_RESET_DEACTIVATE);
+		rc_hot = pnv_eeh_bridge_reset(dev, EEH_RESET_HOT);
+		rc_dea = pnv_eeh_bridge_reset(dev, EEH_RESET_DEACTIVATE);
 	}
+
+	return rc_hot ? : rc_dea;
 }
 
 static void pnv_eeh_wait_for_pending(struct pci_dn *pdn, const char *type,
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index ae4b549b5ca0..e1b75a4bc681 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -2145,6 +2145,12 @@ static void pnv_pci_ioda_fixup(void)
 #endif
 }
 
+static int pnv_pci_root_bridge_prepare(struct pci_host_bridge *bridge)
+{
+	bridge->reset_slot = pnv_pci_reset_secondary_bus;
+	return 0;
+}
+
 /*
  * Returns the alignment for I/O or memory windows for P2P
  * bridges. That actually depends on how PEs are segmented.
@@ -2504,7 +2510,6 @@ static const struct pci_controller_ops pnv_pci_ioda_controller_ops = {
 	.release_device		= pnv_pci_release_device,
 	.window_alignment	= pnv_pci_window_alignment,
 	.setup_bridge		= pnv_pci_fixup_bridge_resources,
-	.reset_secondary_bus	= pnv_pci_reset_secondary_bus,
 	.shutdown		= pnv_pci_ioda_shutdown,
 #ifdef CONFIG_IOMMU_API
 	.device_group		= pnv_pci_device_group,
@@ -2515,7 +2520,6 @@ static const struct pci_controller_ops pnv_npu_ocapi_ioda_controller_ops = {
 	.enable_device_hook	= pnv_ocapi_enable_device_hook,
 	.release_device		= pnv_pci_release_device,
 	.window_alignment	= pnv_pci_window_alignment,
-	.reset_secondary_bus	= pnv_pci_reset_secondary_bus,
 	.shutdown		= pnv_pci_ioda_shutdown,
 };
 
@@ -2724,6 +2728,7 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
 	}
 
 	ppc_md.pcibios_default_alignment = pnv_pci_default_alignment;
+	ppc_md.pcibios_root_bridge_prepare = pnv_pci_root_bridge_prepare;
 
 #ifdef CONFIG_PCI_IOV
 	ppc_md.pcibios_fixup_sriov = pnv_pci_ioda_fixup_iov;
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h
index 42075501663b..44e8969c7729 100644
--- a/arch/powerpc/platforms/powernv/pci.h
+++ b/arch/powerpc/platforms/powernv/pci.h
@@ -275,7 +275,8 @@ extern struct iommu_table *pnv_pci_table_alloc(int nid);
 
 extern void pnv_pci_init_ioda2_phb(struct device_node *np);
 extern void pnv_pci_init_npu2_opencapi_phb(struct device_node *np);
-extern void pnv_pci_reset_secondary_bus(struct pci_dev *dev);
+extern int pnv_pci_reset_secondary_bus(struct pci_host_bridge *host,
+				       struct pci_dev *dev);
 extern int pnv_eeh_phb_reset(struct pci_controller *hose, int option);
 
 extern struct pnv_ioda_pe *pnv_pci_bdfn_to_pe(struct pnv_phb *phb, u16 bdfn);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 13709bb898a9..28cdcd698914 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -4962,7 +4962,7 @@ int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type)
 			    PCIE_RESET_READY_POLL_MS - delay);
 }
 
-void pci_reset_secondary_bus(struct pci_dev *dev)
+static void pci_reset_secondary_bus(struct pci_dev *dev)
 {
 	u16 ctrl;
 
@@ -4980,7 +4980,7 @@ void pci_reset_secondary_bus(struct pci_dev *dev)
 	pci_write_config_word(dev, PCI_BRIDGE_CONTROL, ctrl);
 }
 
-void __weak pcibios_reset_secondary_bus(struct pci_dev *dev)
+static void pcibios_reset_secondary_bus(struct pci_dev *dev)
 {
 	struct pci_host_bridge *host = pci_find_host_bridge(dev->bus);
 	int ret;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 76e977af2d52..829d7cbbf258 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1397,8 +1397,6 @@ int pci_try_reset_function(struct pci_dev *dev);
 int pci_probe_reset_slot(struct pci_slot *slot);
 int pci_probe_reset_bus(struct pci_bus *bus);
 int pci_reset_bus(struct pci_dev *dev);
-void pci_reset_secondary_bus(struct pci_dev *dev);
-void pcibios_reset_secondary_bus(struct pci_dev *dev);
 void pci_update_resource(struct pci_dev *dev, int resno);
 int __must_check pci_assign_resource(struct pci_dev *dev, int i);
 void pci_release_resource(struct pci_dev *dev, int resno);
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2025-04-17 11:43 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-04  8:22 [PATCH 0/4] PCI: Add support for resetting the slots in a platform specific way Manivannan Sadhasivam via B4 Relay
2025-04-04  8:22 ` [PATCH 1/4] PCI/ERR: Remove misleading TODO regarding kernel panic Manivannan Sadhasivam via B4 Relay
2025-04-04  8:22 ` [PATCH 2/4] PCI/ERR: Add support for resetting the slot in a platforms specific way Manivannan Sadhasivam via B4 Relay
2025-04-04  8:46   ` Lukas Wunner
2025-04-15 13:33     ` Manivannan Sadhasivam
2025-04-16 14:38       ` Lukas Wunner
2025-04-16 15:04         ` Manivannan Sadhasivam
2025-04-17  0:23           ` Lukas Wunner
2025-04-17  5:39             ` Manivannan Sadhasivam
2025-04-17 11:42               ` Lukas Wunner
2025-04-04  8:22 ` [PATCH 3/4] PCI: Add link down handling for host bridges Manivannan Sadhasivam via B4 Relay
2025-04-04  8:22 ` [PATCH 4/4] PCI: qcom: Add support for resetting the slot due to link down event Manivannan Sadhasivam via B4 Relay

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).