powerpc/eeh: Remove device_node dependency
authorGavin Shan <gwshan@linux.vnet.ibm.com>
Tue, 17 Mar 2015 05:15:08 +0000 (16:15 +1100)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Tue, 24 Mar 2015 02:15:53 +0000 (13:15 +1100)
The patch removes struct eeh_dev::dn and the corresponding helper
functions: eeh_dev_to_of_node() and of_node_to_eeh_dev(). Instead,
eeh_dev_to_pdn() and pdn_to_eeh_dev() should be used to get the
pdn, which might contain device_node on PowerNV platform.

Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/include/asm/eeh.h
arch/powerpc/include/asm/pci-bridge.h
arch/powerpc/kernel/eeh.c
arch/powerpc/kernel/eeh_cache.c
arch/powerpc/kernel/eeh_driver.c
arch/powerpc/kernel/eeh_pe.c
arch/powerpc/kernel/pci_of_scan.c
arch/powerpc/kernel/rtas_pci.c
arch/powerpc/platforms/pseries/msi.c

index f847fb716653674d2b8cb1b068d2fd04bcfe902e..a52db28ecc1e1f45287d24806f554a46ec87c6f6 100644 (file)
@@ -29,7 +29,6 @@
 
 struct pci_dev;
 struct pci_bus;
-struct device_node;
 struct pci_dn;
 
 #ifdef CONFIG_EEH
@@ -137,17 +136,11 @@ struct eeh_dev {
        struct eeh_pe *pe;              /* Associated PE                */
        struct list_head list;          /* Form link list in the PE     */
        struct pci_controller *phb;     /* Associated PHB               */
-       struct device_node *dn;         /* Associated device node       */
        struct pci_dn *pdn;             /* Associated PCI device node   */
        struct pci_dev *pdev;           /* Associated PCI device        */
        struct pci_bus *bus;            /* PCI bus for partial hotplug  */
 };
 
-static inline struct device_node *eeh_dev_to_of_node(struct eeh_dev *edev)
-{
-       return edev ? edev->dn : NULL;
-}
-
 static inline struct pci_dn *eeh_dev_to_pdn(struct eeh_dev *edev)
 {
        return edev ? edev->pdn : NULL;
index 7b74499b728c707462ec6d1a2223bff087b9132a..2c6dc2a3d14a54f4878c252c9a56ca24b5655ba9 100644 (file)
@@ -201,25 +201,11 @@ static inline int pci_device_from_OF_node(struct device_node *np,
 }
 
 #if defined(CONFIG_EEH)
-static inline struct eeh_dev *of_node_to_eeh_dev(struct device_node *dn)
-{
-       /*
-        * For those OF nodes whose parent isn't PCI bridge, they
-        * don't have PCI_DN actually. So we have to skip them for
-        * any EEH operations.
-        */
-       if (!dn || !PCI_DN(dn))
-               return NULL;
-
-       return PCI_DN(dn)->edev;
-}
-
 static inline struct eeh_dev *pdn_to_eeh_dev(struct pci_dn *pdn)
 {
        return pdn ? pdn->edev : NULL;
 }
 #else
-#define of_node_to_eeh_dev(x)  (NULL)
 #define pdn_to_eeh_dev(x)      (NULL)
 #endif
 
index 1fd2566c87f1eef08f84a62a6dd2d18341980318..76253eb146be2e6865a146fd76e4416da40b4421 100644 (file)
@@ -418,11 +418,11 @@ int eeh_dev_check_failure(struct eeh_dev *edev)
        int ret;
        int active_flags = (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE);
        unsigned long flags;
-       struct device_node *dn;
+       struct pci_dn *pdn;
        struct pci_dev *dev;
        struct eeh_pe *pe, *parent_pe, *phb_pe;
        int rc = 0;
-       const char *location;
+       const char *location = NULL;
 
        eeh_stats.total_mmio_ffs++;
 
@@ -433,15 +433,14 @@ int eeh_dev_check_failure(struct eeh_dev *edev)
                eeh_stats.no_dn++;
                return 0;
        }
-       dn = eeh_dev_to_of_node(edev);
        dev = eeh_dev_to_pci_dev(edev);
        pe = eeh_dev_to_pe(edev);
 
        /* Access to IO BARs might get this far and still not want checking. */
        if (!pe) {
                eeh_stats.ignored_check++;
-               pr_debug("EEH: Ignored check for %s %s\n",
-                       eeh_pci_name(dev), dn->full_name);
+               pr_debug("EEH: Ignored check for %s\n",
+                       eeh_pci_name(dev));
                return 0;
        }
 
@@ -477,10 +476,13 @@ int eeh_dev_check_failure(struct eeh_dev *edev)
        if (pe->state & EEH_PE_ISOLATED) {
                pe->check_count++;
                if (pe->check_count % EEH_MAX_FAILS == 0) {
-                       location = of_get_property(dn, "ibm,loc-code", NULL);
+                       pdn = eeh_dev_to_pdn(edev);
+                       if (pdn->node)
+                               location = of_get_property(pdn->node, "ibm,loc-code", NULL);
                        printk(KERN_ERR "EEH: %d reads ignored for recovering device at "
                                "location=%s driver=%s pci addr=%s\n",
-                               pe->check_count, location,
+                               pe->check_count,
+                               location ? location : "unknown",
                                eeh_driver_name(dev), eeh_pci_name(dev));
                        printk(KERN_ERR "EEH: Might be infinite loop in %s driver\n",
                                eeh_driver_name(dev));
@@ -1035,7 +1037,7 @@ int eeh_init(void)
 core_initcall_sync(eeh_init);
 
 /**
- * eeh_add_device_early - Enable EEH for the indicated device_node
+ * eeh_add_device_early - Enable EEH for the indicated device node
  * @pdn: PCI device node for which to set up EEH
  *
  * This routine must be used to perform EEH initialization for PCI
@@ -1093,7 +1095,7 @@ EXPORT_SYMBOL_GPL(eeh_add_device_tree_early);
  */
 void eeh_add_device_late(struct pci_dev *dev)
 {
-       struct device_node *dn;
+       struct pci_dn *pdn;
        struct eeh_dev *edev;
 
        if (!dev || !eeh_enabled())
@@ -1101,8 +1103,8 @@ void eeh_add_device_late(struct pci_dev *dev)
 
        pr_debug("EEH: Adding device %s\n", pci_name(dev));
 
-       dn = pci_device_to_OF_node(dev);
-       edev = of_node_to_eeh_dev(dn);
+       pdn = pci_get_pdn_by_devfn(dev->bus, dev->devfn);
+       edev = pdn_to_eeh_dev(pdn);
        if (edev->pdev == dev) {
                pr_debug("EEH: Already referenced !\n");
                return;
index 07d8a2423a6140a7ac8320c536f998752a28c868..eeabeabea49c41cec4da2532b290db2fb1c0679b 100644 (file)
@@ -171,30 +171,27 @@ eeh_addr_cache_insert(struct pci_dev *dev, unsigned long alo,
 
 static void __eeh_addr_cache_insert_dev(struct pci_dev *dev)
 {
-       struct device_node *dn;
+       struct pci_dn *pdn;
        struct eeh_dev *edev;
        int i;
 
-       dn = pci_device_to_OF_node(dev);
-       if (!dn) {
+       pdn = pci_get_pdn_by_devfn(dev->bus, dev->devfn);
+       if (!pdn) {
                pr_warn("PCI: no pci dn found for dev=%s\n",
                        pci_name(dev));
                return;
        }
 
-       edev = of_node_to_eeh_dev(dn);
+       edev = pdn_to_eeh_dev(pdn);
        if (!edev) {
-               pr_warn("PCI: no EEH dev found for dn=%s\n",
-                       dn->full_name);
+               pr_warn("PCI: no EEH dev found for %s\n",
+                       pci_name(dev));
                return;
        }
 
        /* Skip any devices for which EEH is not enabled. */
        if (!edev->pe) {
-#ifdef DEBUG
-               pr_info("PCI: skip building address cache for=%s - %s\n",
-                       pci_name(dev), dn->full_name);
-#endif
+               dev_dbg(&dev->dev, "EEH: Skip building address cache\n");
                return;
        }
 
@@ -282,18 +279,18 @@ void eeh_addr_cache_rmv_dev(struct pci_dev *dev)
  */
 void eeh_addr_cache_build(void)
 {
-       struct device_node *dn;
+       struct pci_dn *pdn;
        struct eeh_dev *edev;
        struct pci_dev *dev = NULL;
 
        spin_lock_init(&pci_io_addr_cache_root.piar_lock);
 
        for_each_pci_dev(dev) {
-               dn = pci_device_to_OF_node(dev);
-               if (!dn)
+               pdn = pci_get_pdn_by_devfn(dev->bus, dev->devfn);
+               if (!pdn)
                        continue;
 
-               edev = of_node_to_eeh_dev(dn);
+               edev = pdn_to_eeh_dev(pdn);
                if (!edev)
                        continue;
 
index d099540c0f560de2b8f81ef85e5a51e020b3529b..24768ff3cb7308345248ada7a70f60421c7aea46 100644 (file)
@@ -83,28 +83,6 @@ static inline void eeh_pcid_put(struct pci_dev *pdev)
        module_put(pdev->driver->driver.owner);
 }
 
-#if 0
-static void print_device_node_tree(struct pci_dn *pdn, int dent)
-{
-       int i;
-       struct device_node *pc;
-
-       if (!pdn)
-               return;
-       for (i = 0; i < dent; i++)
-               printk(" ");
-       printk("dn=%s mode=%x \tcfg_addr=%x pe_addr=%x \tfull=%s\n",
-               pdn->node->name, pdn->eeh_mode, pdn->eeh_config_addr,
-               pdn->eeh_pe_config_addr, pdn->node->full_name);
-       dent += 3;
-       pc = pdn->node->child;
-       while (pc) {
-               print_device_node_tree(PCI_DN(pc), dent);
-               pc = pc->sibling;
-       }
-}
-#endif
-
 /**
  * eeh_disable_irq - Disable interrupt for the recovering device
  * @dev: PCI device
index 209cd753bf4655199d06737bf18a9f042857ee0a..f33ceccf687636499f0a4c6c5ffaed7604505b6f 100644 (file)
@@ -348,9 +348,12 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
 
                /* Put the edev to PE */
                list_add_tail(&edev->list, &pe->edevs);
-               pr_debug("EEH: Add %s to Bus PE#%x\n",
-                       edev->dn->full_name, pe->addr);
-
+               pr_debug("EEH: Add %04x:%02x:%02x.%01x to Bus PE#%x\n",
+                       edev->phb->global_number,
+                       edev->config_addr >> 8,
+                       PCI_SLOT(edev->config_addr & 0xFF),
+                       PCI_FUNC(edev->config_addr & 0xFF),
+                       pe->addr);
                return 0;
        } else if (pe && (pe->type & EEH_PE_INVALID)) {
                list_add_tail(&edev->list, &pe->edevs);
@@ -366,9 +369,14 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
                        parent->type &= ~(EEH_PE_INVALID | EEH_PE_KEEP);
                        parent = parent->parent;
                }
-               pr_debug("EEH: Add %s to Device PE#%x, Parent PE#%x\n",
-                       edev->dn->full_name, pe->addr, pe->parent->addr);
 
+               pr_debug("EEH: Add %04x:%02x:%02x.%01x to Device "
+                        "PE#%x, Parent PE#%x\n",
+                       edev->phb->global_number,
+                       edev->config_addr >> 8,
+                        PCI_SLOT(edev->config_addr & 0xFF),
+                        PCI_FUNC(edev->config_addr & 0xFF),
+                       pe->addr, pe->parent->addr);
                return 0;
        }
 
@@ -407,8 +415,13 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
        list_add_tail(&pe->child, &parent->child_list);
        list_add_tail(&edev->list, &pe->edevs);
        edev->pe = pe;
-       pr_debug("EEH: Add %s to Device PE#%x, Parent PE#%x\n",
-               edev->dn->full_name, pe->addr, pe->parent->addr);
+       pr_debug("EEH: Add %04x:%02x:%02x.%01x to "
+                "Device PE#%x, Parent PE#%x\n",
+                edev->phb->global_number,
+                edev->config_addr >> 8,
+                PCI_SLOT(edev->config_addr & 0xFF),
+                PCI_FUNC(edev->config_addr & 0xFF),
+                pe->addr, pe->parent->addr);
 
        return 0;
 }
@@ -428,8 +441,11 @@ int eeh_rmv_from_parent_pe(struct eeh_dev *edev)
        int cnt;
 
        if (!edev->pe) {
-               pr_debug("%s: No PE found for EEH device %s\n",
-                        __func__, edev->dn->full_name);
+               pr_debug("%s: No PE found for device %04x:%02x:%02x.%01x\n",
+                        __func__,  edev->phb->global_number,
+                        edev->config_addr >> 8,
+                        PCI_SLOT(edev->config_addr & 0xFF),
+                        PCI_FUNC(edev->config_addr & 0xFF));
                return -EEXIST;
        }
 
index e6245e9c7d8d7d54022a408e66e64d74d795757a..7122dfece393c1b2e0a03ffe844f8228554bd9f9 100644 (file)
@@ -305,7 +305,7 @@ static struct pci_dev *of_scan_pci_dev(struct pci_bus *bus,
        const __be32 *reg;
        int reglen, devfn;
 #ifdef CONFIG_EEH
-       struct eeh_dev *edev = of_node_to_eeh_dev(dn);
+       struct eeh_dev *edev = pdn_to_eeh_dev(PCI_DN(dn));
 #endif
 
        pr_debug("  * %s\n", dn->full_name);
index ce230da2c015eb828a859aeb8324c1a4158d949e..af29df2517f7cda112c93a998d22653ee456687b 100644 (file)
@@ -113,7 +113,7 @@ static int rtas_pci_read_config(struct pci_bus *bus,
 
        ret = rtas_read_config(pdn, where, size, val);
        if (*val == EEH_IO_ERROR_VALUE(size) &&
-           eeh_dev_check_failure(of_node_to_eeh_dev(dn)))
+           eeh_dev_check_failure(pdn_to_eeh_dev(pdn)))
                return PCIBIOS_DEVICE_NOT_FOUND;
 
        return ret;
index 691a154c286de46b5bc9ed26b9729518ebd023ed..c8d24f9a69481d007fe4bcccb65bad5b2f032e5c 100644 (file)
@@ -195,6 +195,7 @@ static struct device_node *find_pe_total_msi(struct pci_dev *dev, int *total)
 static struct device_node *find_pe_dn(struct pci_dev *dev, int *total)
 {
        struct device_node *dn;
+       struct pci_dn *pdn;
        struct eeh_dev *edev;
 
        /* Found our PE and assume 8 at that point. */
@@ -204,10 +205,11 @@ static struct device_node *find_pe_dn(struct pci_dev *dev, int *total)
                return NULL;
 
        /* Get the top level device in the PE */
-       edev = of_node_to_eeh_dev(dn);
+       edev = pdn_to_eeh_dev(PCI_DN(dn));
        if (edev->pe)
                edev = list_first_entry(&edev->pe->edevs, struct eeh_dev, list);
-       dn = eeh_dev_to_of_node(edev);
+       pdn = eeh_dev_to_pdn(edev);
+       dn = pdn ? pdn->node : NULL;
        if (!dn)
                return NULL;