Commit c6406d8f authored by Gavin Shan's avatar Gavin Shan Committed by Benjamin Herrenschmidt

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: default avatarGavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 0bd78587
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
struct pci_dev; struct pci_dev;
struct pci_bus; struct pci_bus;
struct device_node;
struct pci_dn; struct pci_dn;
#ifdef CONFIG_EEH #ifdef CONFIG_EEH
...@@ -137,17 +136,11 @@ struct eeh_dev { ...@@ -137,17 +136,11 @@ struct eeh_dev {
struct eeh_pe *pe; /* Associated PE */ struct eeh_pe *pe; /* Associated PE */
struct list_head list; /* Form link list in the PE */ struct list_head list; /* Form link list in the PE */
struct pci_controller *phb; /* Associated PHB */ struct pci_controller *phb; /* Associated PHB */
struct device_node *dn; /* Associated device node */
struct pci_dn *pdn; /* Associated PCI device node */ struct pci_dn *pdn; /* Associated PCI device node */
struct pci_dev *pdev; /* Associated PCI device */ struct pci_dev *pdev; /* Associated PCI device */
struct pci_bus *bus; /* PCI bus for partial hotplug */ 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) static inline struct pci_dn *eeh_dev_to_pdn(struct eeh_dev *edev)
{ {
return edev ? edev->pdn : NULL; return edev ? edev->pdn : NULL;
......
...@@ -201,25 +201,11 @@ static inline int pci_device_from_OF_node(struct device_node *np, ...@@ -201,25 +201,11 @@ static inline int pci_device_from_OF_node(struct device_node *np,
} }
#if defined(CONFIG_EEH) #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) static inline struct eeh_dev *pdn_to_eeh_dev(struct pci_dn *pdn)
{ {
return pdn ? pdn->edev : NULL; return pdn ? pdn->edev : NULL;
} }
#else #else
#define of_node_to_eeh_dev(x) (NULL)
#define pdn_to_eeh_dev(x) (NULL) #define pdn_to_eeh_dev(x) (NULL)
#endif #endif
......
...@@ -418,11 +418,11 @@ int eeh_dev_check_failure(struct eeh_dev *edev) ...@@ -418,11 +418,11 @@ int eeh_dev_check_failure(struct eeh_dev *edev)
int ret; int ret;
int active_flags = (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE); int active_flags = (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE);
unsigned long flags; unsigned long flags;
struct device_node *dn; struct pci_dn *pdn;
struct pci_dev *dev; struct pci_dev *dev;
struct eeh_pe *pe, *parent_pe, *phb_pe; struct eeh_pe *pe, *parent_pe, *phb_pe;
int rc = 0; int rc = 0;
const char *location; const char *location = NULL;
eeh_stats.total_mmio_ffs++; eeh_stats.total_mmio_ffs++;
...@@ -433,15 +433,14 @@ int eeh_dev_check_failure(struct eeh_dev *edev) ...@@ -433,15 +433,14 @@ int eeh_dev_check_failure(struct eeh_dev *edev)
eeh_stats.no_dn++; eeh_stats.no_dn++;
return 0; return 0;
} }
dn = eeh_dev_to_of_node(edev);
dev = eeh_dev_to_pci_dev(edev); dev = eeh_dev_to_pci_dev(edev);
pe = eeh_dev_to_pe(edev); pe = eeh_dev_to_pe(edev);
/* Access to IO BARs might get this far and still not want checking. */ /* Access to IO BARs might get this far and still not want checking. */
if (!pe) { if (!pe) {
eeh_stats.ignored_check++; eeh_stats.ignored_check++;
pr_debug("EEH: Ignored check for %s %s\n", pr_debug("EEH: Ignored check for %s\n",
eeh_pci_name(dev), dn->full_name); eeh_pci_name(dev));
return 0; return 0;
} }
...@@ -477,10 +476,13 @@ int eeh_dev_check_failure(struct eeh_dev *edev) ...@@ -477,10 +476,13 @@ int eeh_dev_check_failure(struct eeh_dev *edev)
if (pe->state & EEH_PE_ISOLATED) { if (pe->state & EEH_PE_ISOLATED) {
pe->check_count++; pe->check_count++;
if (pe->check_count % EEH_MAX_FAILS == 0) { 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 " printk(KERN_ERR "EEH: %d reads ignored for recovering device at "
"location=%s driver=%s pci addr=%s\n", "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)); eeh_driver_name(dev), eeh_pci_name(dev));
printk(KERN_ERR "EEH: Might be infinite loop in %s driver\n", printk(KERN_ERR "EEH: Might be infinite loop in %s driver\n",
eeh_driver_name(dev)); eeh_driver_name(dev));
...@@ -1035,7 +1037,7 @@ int eeh_init(void) ...@@ -1035,7 +1037,7 @@ int eeh_init(void)
core_initcall_sync(eeh_init); 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 * @pdn: PCI device node for which to set up EEH
* *
* This routine must be used to perform EEH initialization for PCI * This routine must be used to perform EEH initialization for PCI
...@@ -1093,7 +1095,7 @@ EXPORT_SYMBOL_GPL(eeh_add_device_tree_early); ...@@ -1093,7 +1095,7 @@ EXPORT_SYMBOL_GPL(eeh_add_device_tree_early);
*/ */
void eeh_add_device_late(struct pci_dev *dev) void eeh_add_device_late(struct pci_dev *dev)
{ {
struct device_node *dn; struct pci_dn *pdn;
struct eeh_dev *edev; struct eeh_dev *edev;
if (!dev || !eeh_enabled()) if (!dev || !eeh_enabled())
...@@ -1101,8 +1103,8 @@ void eeh_add_device_late(struct pci_dev *dev) ...@@ -1101,8 +1103,8 @@ void eeh_add_device_late(struct pci_dev *dev)
pr_debug("EEH: Adding device %s\n", pci_name(dev)); pr_debug("EEH: Adding device %s\n", pci_name(dev));
dn = pci_device_to_OF_node(dev); pdn = pci_get_pdn_by_devfn(dev->bus, dev->devfn);
edev = of_node_to_eeh_dev(dn); edev = pdn_to_eeh_dev(pdn);
if (edev->pdev == dev) { if (edev->pdev == dev) {
pr_debug("EEH: Already referenced !\n"); pr_debug("EEH: Already referenced !\n");
return; return;
......
...@@ -171,30 +171,27 @@ eeh_addr_cache_insert(struct pci_dev *dev, unsigned long alo, ...@@ -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) static void __eeh_addr_cache_insert_dev(struct pci_dev *dev)
{ {
struct device_node *dn; struct pci_dn *pdn;
struct eeh_dev *edev; struct eeh_dev *edev;
int i; int i;
dn = pci_device_to_OF_node(dev); pdn = pci_get_pdn_by_devfn(dev->bus, dev->devfn);
if (!dn) { if (!pdn) {
pr_warn("PCI: no pci dn found for dev=%s\n", pr_warn("PCI: no pci dn found for dev=%s\n",
pci_name(dev)); pci_name(dev));
return; return;
} }
edev = of_node_to_eeh_dev(dn); edev = pdn_to_eeh_dev(pdn);
if (!edev) { if (!edev) {
pr_warn("PCI: no EEH dev found for dn=%s\n", pr_warn("PCI: no EEH dev found for %s\n",
dn->full_name); pci_name(dev));
return; return;
} }
/* Skip any devices for which EEH is not enabled. */ /* Skip any devices for which EEH is not enabled. */
if (!edev->pe) { if (!edev->pe) {
#ifdef DEBUG dev_dbg(&dev->dev, "EEH: Skip building address cache\n");
pr_info("PCI: skip building address cache for=%s - %s\n",
pci_name(dev), dn->full_name);
#endif
return; return;
} }
...@@ -282,18 +279,18 @@ void eeh_addr_cache_rmv_dev(struct pci_dev *dev) ...@@ -282,18 +279,18 @@ void eeh_addr_cache_rmv_dev(struct pci_dev *dev)
*/ */
void eeh_addr_cache_build(void) void eeh_addr_cache_build(void)
{ {
struct device_node *dn; struct pci_dn *pdn;
struct eeh_dev *edev; struct eeh_dev *edev;
struct pci_dev *dev = NULL; struct pci_dev *dev = NULL;
spin_lock_init(&pci_io_addr_cache_root.piar_lock); spin_lock_init(&pci_io_addr_cache_root.piar_lock);
for_each_pci_dev(dev) { for_each_pci_dev(dev) {
dn = pci_device_to_OF_node(dev); pdn = pci_get_pdn_by_devfn(dev->bus, dev->devfn);
if (!dn) if (!pdn)
continue; continue;
edev = of_node_to_eeh_dev(dn); edev = pdn_to_eeh_dev(pdn);
if (!edev) if (!edev)
continue; continue;
......
...@@ -83,28 +83,6 @@ static inline void eeh_pcid_put(struct pci_dev *pdev) ...@@ -83,28 +83,6 @@ static inline void eeh_pcid_put(struct pci_dev *pdev)
module_put(pdev->driver->driver.owner); 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 * eeh_disable_irq - Disable interrupt for the recovering device
* @dev: PCI device * @dev: PCI device
......
...@@ -348,9 +348,12 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev) ...@@ -348,9 +348,12 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
/* Put the edev to PE */ /* Put the edev to PE */
list_add_tail(&edev->list, &pe->edevs); list_add_tail(&edev->list, &pe->edevs);
pr_debug("EEH: Add %s to Bus PE#%x\n", pr_debug("EEH: Add %04x:%02x:%02x.%01x to Bus PE#%x\n",
edev->dn->full_name, pe->addr); edev->phb->global_number,
edev->config_addr >> 8,
PCI_SLOT(edev->config_addr & 0xFF),
PCI_FUNC(edev->config_addr & 0xFF),
pe->addr);
return 0; return 0;
} else if (pe && (pe->type & EEH_PE_INVALID)) { } else if (pe && (pe->type & EEH_PE_INVALID)) {
list_add_tail(&edev->list, &pe->edevs); list_add_tail(&edev->list, &pe->edevs);
...@@ -366,9 +369,14 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev) ...@@ -366,9 +369,14 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
parent->type &= ~(EEH_PE_INVALID | EEH_PE_KEEP); parent->type &= ~(EEH_PE_INVALID | EEH_PE_KEEP);
parent = parent->parent; 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; return 0;
} }
...@@ -407,8 +415,13 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev) ...@@ -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(&pe->child, &parent->child_list);
list_add_tail(&edev->list, &pe->edevs); list_add_tail(&edev->list, &pe->edevs);
edev->pe = pe; edev->pe = pe;
pr_debug("EEH: Add %s to Device PE#%x, Parent PE#%x\n", pr_debug("EEH: Add %04x:%02x:%02x.%01x to "
edev->dn->full_name, pe->addr, pe->parent->addr); "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; return 0;
} }
...@@ -428,8 +441,11 @@ int eeh_rmv_from_parent_pe(struct eeh_dev *edev) ...@@ -428,8 +441,11 @@ int eeh_rmv_from_parent_pe(struct eeh_dev *edev)
int cnt; int cnt;
if (!edev->pe) { if (!edev->pe) {
pr_debug("%s: No PE found for EEH device %s\n", pr_debug("%s: No PE found for device %04x:%02x:%02x.%01x\n",
__func__, edev->dn->full_name); __func__, edev->phb->global_number,
edev->config_addr >> 8,
PCI_SLOT(edev->config_addr & 0xFF),
PCI_FUNC(edev->config_addr & 0xFF));
return -EEXIST; return -EEXIST;
} }
......
...@@ -305,7 +305,7 @@ static struct pci_dev *of_scan_pci_dev(struct pci_bus *bus, ...@@ -305,7 +305,7 @@ static struct pci_dev *of_scan_pci_dev(struct pci_bus *bus,
const __be32 *reg; const __be32 *reg;
int reglen, devfn; int reglen, devfn;
#ifdef CONFIG_EEH #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 #endif
pr_debug(" * %s\n", dn->full_name); pr_debug(" * %s\n", dn->full_name);
......
...@@ -113,7 +113,7 @@ static int rtas_pci_read_config(struct pci_bus *bus, ...@@ -113,7 +113,7 @@ static int rtas_pci_read_config(struct pci_bus *bus,
ret = rtas_read_config(pdn, where, size, val); ret = rtas_read_config(pdn, where, size, val);
if (*val == EEH_IO_ERROR_VALUE(size) && 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 PCIBIOS_DEVICE_NOT_FOUND;
return ret; return ret;
......
...@@ -195,6 +195,7 @@ static struct device_node *find_pe_total_msi(struct pci_dev *dev, int *total) ...@@ -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) static struct device_node *find_pe_dn(struct pci_dev *dev, int *total)
{ {
struct device_node *dn; struct device_node *dn;
struct pci_dn *pdn;
struct eeh_dev *edev; struct eeh_dev *edev;
/* Found our PE and assume 8 at that point. */ /* 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) ...@@ -204,10 +205,11 @@ static struct device_node *find_pe_dn(struct pci_dev *dev, int *total)
return NULL; return NULL;
/* Get the top level device in the PE */ /* 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) if (edev->pe)
edev = list_first_entry(&edev->pe->edevs, struct eeh_dev, list); 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) if (!dn)
return NULL; return NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment