From c6406d8fbb014bebdfb5bf3c244548958aec7379 Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Tue, 17 Mar 2015 16:15:08 +1100 Subject: [PATCH] powerpc/eeh: Remove device_node dependency 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 Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/eeh.h | 7 ------ arch/powerpc/include/asm/pci-bridge.h | 14 ----------- arch/powerpc/kernel/eeh.c | 24 ++++++++++--------- arch/powerpc/kernel/eeh_cache.c | 25 +++++++++----------- arch/powerpc/kernel/eeh_driver.c | 22 ----------------- arch/powerpc/kernel/eeh_pe.c | 34 ++++++++++++++++++++------- arch/powerpc/kernel/pci_of_scan.c | 2 +- arch/powerpc/kernel/rtas_pci.c | 2 +- arch/powerpc/platforms/pseries/msi.c | 6 +++-- 9 files changed, 55 insertions(+), 81 deletions(-) diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h index f847fb716653..a52db28ecc1e 100644 --- a/arch/powerpc/include/asm/eeh.h +++ b/arch/powerpc/include/asm/eeh.h @@ -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; diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index 7b74499b728c..2c6dc2a3d14a 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h @@ -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 diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index 1fd2566c87f1..76253eb146be 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c @@ -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; diff --git a/arch/powerpc/kernel/eeh_cache.c b/arch/powerpc/kernel/eeh_cache.c index 07d8a2423a61..eeabeabea49c 100644 --- a/arch/powerpc/kernel/eeh_cache.c +++ b/arch/powerpc/kernel/eeh_cache.c @@ -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; diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c index d099540c0f56..24768ff3cb73 100644 --- a/arch/powerpc/kernel/eeh_driver.c +++ b/arch/powerpc/kernel/eeh_driver.c @@ -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 diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c index 209cd753bf46..f33ceccf6876 100644 --- a/arch/powerpc/kernel/eeh_pe.c +++ b/arch/powerpc/kernel/eeh_pe.c @@ -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; } diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c index e6245e9c7d8d..7122dfece393 100644 --- a/arch/powerpc/kernel/pci_of_scan.c +++ b/arch/powerpc/kernel/pci_of_scan.c @@ -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); diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c index ce230da2c015..af29df2517f7 100644 --- a/arch/powerpc/kernel/rtas_pci.c +++ b/arch/powerpc/kernel/rtas_pci.c @@ -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; diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c index 691a154c286d..c8d24f9a6948 100644 --- a/arch/powerpc/platforms/pseries/msi.c +++ b/arch/powerpc/platforms/pseries/msi.c @@ -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; -- 2.20.1