@@ -843,7 +843,7 @@ out:
return 0;
}
-static int pnv_eeh_bridge_reset(struct pci_dev *dev, int option)
+static int __pnv_eeh_bridge_reset(struct pci_dev *dev, int option)
{
struct pci_dn *pdn = pci_get_pdn_by_devfn(dev->bus, dev->devfn);
struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
@@ -894,6 +894,48 @@ static int pnv_eeh_bridge_reset(struct pci_dev *dev, int option)
return 0;
}
+static int pnv_eeh_bridge_reset(struct pci_dev *pdev, int option)
+{
+ struct pci_controller *hose;
+ struct pnv_phb *phb;
+ struct device_node *dn = pdev ? pci_device_to_OF_node(pdev) : NULL;
+ uint64_t id = (0x1ul << 60);
+ uint8_t scope;
+ int64_t rc;
+
+ /*
+ * If the firmware can't handle it, we will issue hot reset
+ * on the secondary bus despite the requested reset type.
+ */
+ if (!dn || !of_get_property(dn, "ibm,reset-by-firmware", NULL))
+ return __pnv_eeh_bridge_reset(pdev, option);
+
+ /* The firmware can handle the request */
+ switch (option) {
+ case EEH_RESET_HOT:
+ scope = OPAL_RESET_PCI_HOT;
+ break;
+ case EEH_RESET_FUNDAMENTAL:
+ scope = OPAL_RESET_PCI_FUNDAMENTAL;
+ break;
+ case EEH_RESET_DEACTIVATE:
+ return 0;
+ default:
+ dev_warn(&pdev->dev, "%s: Unsupported reset %d\n",
+ __func__, option);
+ return -EINVAL;
+ }
+
+ hose = pci_bus_to_host(pdev->bus);
+ phb = hose->private_data;
+ id |= (pdev->bus->number << 24) | (pdev->devfn << 16) | phb->opal_id;
+ rc = opal_pci_reset(id, scope, OPAL_ASSERT_RESET);
+ if (rc > 0)
+ rc = pnv_eeh_poll(id);
+
+ return (rc == OPAL_SUCCESS) ? 0 : -EIO;
+}
+
static void pnv_eeh_wait_for_pending(struct pci_dn *pdn, int pos,
u16 mask, bool af_flr_rst)
{
The skiboot firmware might provide the capability of resetting PCI slot by property "ibm,reset-by-firmware" on the PCI slot associated device node. The patch checks on the property and route the reset to firmware if the property exists. Otherwise, we fail back to the old path as before. Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com> --- arch/powerpc/platforms/powernv/eeh-powernv.c | 44 +++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-)