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 <gwshan@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:
parent
0bd785873c
commit
c6406d8fbb
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue