aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGavin Shan <gwshan@linux.vnet.ibm.com>2015-03-17 01:15:08 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2015-03-23 22:15:53 -0400
commitc6406d8fbb014bebdfb5bf3c244548958aec7379 (patch)
treed472e1f82ffcaec3d9dd03bd34f11fdea21fdb96
parent0bd785873c6a6c9bd50d2ae19862f69ee5759fb9 (diff)
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>
-rw-r--r--arch/powerpc/include/asm/eeh.h7
-rw-r--r--arch/powerpc/include/asm/pci-bridge.h14
-rw-r--r--arch/powerpc/kernel/eeh.c24
-rw-r--r--arch/powerpc/kernel/eeh_cache.c25
-rw-r--r--arch/powerpc/kernel/eeh_driver.c22
-rw-r--r--arch/powerpc/kernel/eeh_pe.c34
-rw-r--r--arch/powerpc/kernel/pci_of_scan.c2
-rw-r--r--arch/powerpc/kernel/rtas_pci.c2
-rw-r--r--arch/powerpc/platforms/pseries/msi.c6
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 @@
29 29
30struct pci_dev; 30struct pci_dev;
31struct pci_bus; 31struct pci_bus;
32struct device_node;
33struct pci_dn; 32struct pci_dn;
34 33
35#ifdef CONFIG_EEH 34#ifdef CONFIG_EEH
@@ -137,17 +136,11 @@ struct eeh_dev {
137 struct eeh_pe *pe; /* Associated PE */ 136 struct eeh_pe *pe; /* Associated PE */
138 struct list_head list; /* Form link list in the PE */ 137 struct list_head list; /* Form link list in the PE */
139 struct pci_controller *phb; /* Associated PHB */ 138 struct pci_controller *phb; /* Associated PHB */
140 struct device_node *dn; /* Associated device node */
141 struct pci_dn *pdn; /* Associated PCI device node */ 139 struct pci_dn *pdn; /* Associated PCI device node */
142 struct pci_dev *pdev; /* Associated PCI device */ 140 struct pci_dev *pdev; /* Associated PCI device */
143 struct pci_bus *bus; /* PCI bus for partial hotplug */ 141 struct pci_bus *bus; /* PCI bus for partial hotplug */
144}; 142};
145 143
146static inline struct device_node *eeh_dev_to_of_node(struct eeh_dev *edev)
147{
148 return edev ? edev->dn : NULL;
149}
150
151static inline struct pci_dn *eeh_dev_to_pdn(struct eeh_dev *edev) 144static inline struct pci_dn *eeh_dev_to_pdn(struct eeh_dev *edev)
152{ 145{
153 return edev ? edev->pdn : NULL; 146 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,
201} 201}
202 202
203#if defined(CONFIG_EEH) 203#if defined(CONFIG_EEH)
204static inline struct eeh_dev *of_node_to_eeh_dev(struct device_node *dn)
205{
206 /*
207 * For those OF nodes whose parent isn't PCI bridge, they
208 * don't have PCI_DN actually. So we have to skip them for
209 * any EEH operations.
210 */
211 if (!dn || !PCI_DN(dn))
212 return NULL;
213
214 return PCI_DN(dn)->edev;
215}
216
217static inline struct eeh_dev *pdn_to_eeh_dev(struct pci_dn *pdn) 204static inline struct eeh_dev *pdn_to_eeh_dev(struct pci_dn *pdn)
218{ 205{
219 return pdn ? pdn->edev : NULL; 206 return pdn ? pdn->edev : NULL;
220} 207}
221#else 208#else
222#define of_node_to_eeh_dev(x) (NULL)
223#define pdn_to_eeh_dev(x) (NULL) 209#define pdn_to_eeh_dev(x) (NULL)
224#endif 210#endif
225 211
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)
418 int ret; 418 int ret;
419 int active_flags = (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE); 419 int active_flags = (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE);
420 unsigned long flags; 420 unsigned long flags;
421 struct device_node *dn; 421 struct pci_dn *pdn;
422 struct pci_dev *dev; 422 struct pci_dev *dev;
423 struct eeh_pe *pe, *parent_pe, *phb_pe; 423 struct eeh_pe *pe, *parent_pe, *phb_pe;
424 int rc = 0; 424 int rc = 0;
425 const char *location; 425 const char *location = NULL;
426 426
427 eeh_stats.total_mmio_ffs++; 427 eeh_stats.total_mmio_ffs++;
428 428
@@ -433,15 +433,14 @@ int eeh_dev_check_failure(struct eeh_dev *edev)
433 eeh_stats.no_dn++; 433 eeh_stats.no_dn++;
434 return 0; 434 return 0;
435 } 435 }
436 dn = eeh_dev_to_of_node(edev);
437 dev = eeh_dev_to_pci_dev(edev); 436 dev = eeh_dev_to_pci_dev(edev);
438 pe = eeh_dev_to_pe(edev); 437 pe = eeh_dev_to_pe(edev);
439 438
440 /* Access to IO BARs might get this far and still not want checking. */ 439 /* Access to IO BARs might get this far and still not want checking. */
441 if (!pe) { 440 if (!pe) {
442 eeh_stats.ignored_check++; 441 eeh_stats.ignored_check++;
443 pr_debug("EEH: Ignored check for %s %s\n", 442 pr_debug("EEH: Ignored check for %s\n",
444 eeh_pci_name(dev), dn->full_name); 443 eeh_pci_name(dev));
445 return 0; 444 return 0;
446 } 445 }
447 446
@@ -477,10 +476,13 @@ int eeh_dev_check_failure(struct eeh_dev *edev)
477 if (pe->state & EEH_PE_ISOLATED) { 476 if (pe->state & EEH_PE_ISOLATED) {
478 pe->check_count++; 477 pe->check_count++;
479 if (pe->check_count % EEH_MAX_FAILS == 0) { 478 if (pe->check_count % EEH_MAX_FAILS == 0) {
480 location = of_get_property(dn, "ibm,loc-code", NULL); 479 pdn = eeh_dev_to_pdn(edev);
480 if (pdn->node)
481 location = of_get_property(pdn->node, "ibm,loc-code", NULL);
481 printk(KERN_ERR "EEH: %d reads ignored for recovering device at " 482 printk(KERN_ERR "EEH: %d reads ignored for recovering device at "
482 "location=%s driver=%s pci addr=%s\n", 483 "location=%s driver=%s pci addr=%s\n",
483 pe->check_count, location, 484 pe->check_count,
485 location ? location : "unknown",
484 eeh_driver_name(dev), eeh_pci_name(dev)); 486 eeh_driver_name(dev), eeh_pci_name(dev));
485 printk(KERN_ERR "EEH: Might be infinite loop in %s driver\n", 487 printk(KERN_ERR "EEH: Might be infinite loop in %s driver\n",
486 eeh_driver_name(dev)); 488 eeh_driver_name(dev));
@@ -1035,7 +1037,7 @@ int eeh_init(void)
1035core_initcall_sync(eeh_init); 1037core_initcall_sync(eeh_init);
1036 1038
1037/** 1039/**
1038 * eeh_add_device_early - Enable EEH for the indicated device_node 1040 * eeh_add_device_early - Enable EEH for the indicated device node
1039 * @pdn: PCI device node for which to set up EEH 1041 * @pdn: PCI device node for which to set up EEH
1040 * 1042 *
1041 * This routine must be used to perform EEH initialization for PCI 1043 * This routine must be used to perform EEH initialization for PCI
@@ -1093,7 +1095,7 @@ EXPORT_SYMBOL_GPL(eeh_add_device_tree_early);
1093 */ 1095 */
1094void eeh_add_device_late(struct pci_dev *dev) 1096void eeh_add_device_late(struct pci_dev *dev)
1095{ 1097{
1096 struct device_node *dn; 1098 struct pci_dn *pdn;
1097 struct eeh_dev *edev; 1099 struct eeh_dev *edev;
1098 1100
1099 if (!dev || !eeh_enabled()) 1101 if (!dev || !eeh_enabled())
@@ -1101,8 +1103,8 @@ void eeh_add_device_late(struct pci_dev *dev)
1101 1103
1102 pr_debug("EEH: Adding device %s\n", pci_name(dev)); 1104 pr_debug("EEH: Adding device %s\n", pci_name(dev));
1103 1105
1104 dn = pci_device_to_OF_node(dev); 1106 pdn = pci_get_pdn_by_devfn(dev->bus, dev->devfn);
1105 edev = of_node_to_eeh_dev(dn); 1107 edev = pdn_to_eeh_dev(pdn);
1106 if (edev->pdev == dev) { 1108 if (edev->pdev == dev) {
1107 pr_debug("EEH: Already referenced !\n"); 1109 pr_debug("EEH: Already referenced !\n");
1108 return; 1110 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,
171 171
172static void __eeh_addr_cache_insert_dev(struct pci_dev *dev) 172static void __eeh_addr_cache_insert_dev(struct pci_dev *dev)
173{ 173{
174 struct device_node *dn; 174 struct pci_dn *pdn;
175 struct eeh_dev *edev; 175 struct eeh_dev *edev;
176 int i; 176 int i;
177 177
178 dn = pci_device_to_OF_node(dev); 178 pdn = pci_get_pdn_by_devfn(dev->bus, dev->devfn);
179 if (!dn) { 179 if (!pdn) {
180 pr_warn("PCI: no pci dn found for dev=%s\n", 180 pr_warn("PCI: no pci dn found for dev=%s\n",
181 pci_name(dev)); 181 pci_name(dev));
182 return; 182 return;
183 } 183 }
184 184
185 edev = of_node_to_eeh_dev(dn); 185 edev = pdn_to_eeh_dev(pdn);
186 if (!edev) { 186 if (!edev) {
187 pr_warn("PCI: no EEH dev found for dn=%s\n", 187 pr_warn("PCI: no EEH dev found for %s\n",
188 dn->full_name); 188 pci_name(dev));
189 return; 189 return;
190 } 190 }
191 191
192 /* Skip any devices for which EEH is not enabled. */ 192 /* Skip any devices for which EEH is not enabled. */
193 if (!edev->pe) { 193 if (!edev->pe) {
194#ifdef DEBUG 194 dev_dbg(&dev->dev, "EEH: Skip building address cache\n");
195 pr_info("PCI: skip building address cache for=%s - %s\n",
196 pci_name(dev), dn->full_name);
197#endif
198 return; 195 return;
199 } 196 }
200 197
@@ -282,18 +279,18 @@ void eeh_addr_cache_rmv_dev(struct pci_dev *dev)
282 */ 279 */
283void eeh_addr_cache_build(void) 280void eeh_addr_cache_build(void)
284{ 281{
285 struct device_node *dn; 282 struct pci_dn *pdn;
286 struct eeh_dev *edev; 283 struct eeh_dev *edev;
287 struct pci_dev *dev = NULL; 284 struct pci_dev *dev = NULL;
288 285
289 spin_lock_init(&pci_io_addr_cache_root.piar_lock); 286 spin_lock_init(&pci_io_addr_cache_root.piar_lock);
290 287
291 for_each_pci_dev(dev) { 288 for_each_pci_dev(dev) {
292 dn = pci_device_to_OF_node(dev); 289 pdn = pci_get_pdn_by_devfn(dev->bus, dev->devfn);
293 if (!dn) 290 if (!pdn)
294 continue; 291 continue;
295 292
296 edev = of_node_to_eeh_dev(dn); 293 edev = pdn_to_eeh_dev(pdn);
297 if (!edev) 294 if (!edev)
298 continue; 295 continue;
299 296
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)
83 module_put(pdev->driver->driver.owner); 83 module_put(pdev->driver->driver.owner);
84} 84}
85 85
86#if 0
87static void print_device_node_tree(struct pci_dn *pdn, int dent)
88{
89 int i;
90 struct device_node *pc;
91
92 if (!pdn)
93 return;
94 for (i = 0; i < dent; i++)
95 printk(" ");
96 printk("dn=%s mode=%x \tcfg_addr=%x pe_addr=%x \tfull=%s\n",
97 pdn->node->name, pdn->eeh_mode, pdn->eeh_config_addr,
98 pdn->eeh_pe_config_addr, pdn->node->full_name);
99 dent += 3;
100 pc = pdn->node->child;
101 while (pc) {
102 print_device_node_tree(PCI_DN(pc), dent);
103 pc = pc->sibling;
104 }
105}
106#endif
107
108/** 86/**
109 * eeh_disable_irq - Disable interrupt for the recovering device 87 * eeh_disable_irq - Disable interrupt for the recovering device
110 * @dev: PCI device 88 * @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)
348 348
349 /* Put the edev to PE */ 349 /* Put the edev to PE */
350 list_add_tail(&edev->list, &pe->edevs); 350 list_add_tail(&edev->list, &pe->edevs);
351 pr_debug("EEH: Add %s to Bus PE#%x\n", 351 pr_debug("EEH: Add %04x:%02x:%02x.%01x to Bus PE#%x\n",
352 edev->dn->full_name, pe->addr); 352 edev->phb->global_number,
353 353 edev->config_addr >> 8,
354 PCI_SLOT(edev->config_addr & 0xFF),
355 PCI_FUNC(edev->config_addr & 0xFF),
356 pe->addr);
354 return 0; 357 return 0;
355 } else if (pe && (pe->type & EEH_PE_INVALID)) { 358 } else if (pe && (pe->type & EEH_PE_INVALID)) {
356 list_add_tail(&edev->list, &pe->edevs); 359 list_add_tail(&edev->list, &pe->edevs);
@@ -366,9 +369,14 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
366 parent->type &= ~(EEH_PE_INVALID | EEH_PE_KEEP); 369 parent->type &= ~(EEH_PE_INVALID | EEH_PE_KEEP);
367 parent = parent->parent; 370 parent = parent->parent;
368 } 371 }
369 pr_debug("EEH: Add %s to Device PE#%x, Parent PE#%x\n",
370 edev->dn->full_name, pe->addr, pe->parent->addr);
371 372
373 pr_debug("EEH: Add %04x:%02x:%02x.%01x to Device "
374 "PE#%x, Parent PE#%x\n",
375 edev->phb->global_number,
376 edev->config_addr >> 8,
377 PCI_SLOT(edev->config_addr & 0xFF),
378 PCI_FUNC(edev->config_addr & 0xFF),
379 pe->addr, pe->parent->addr);
372 return 0; 380 return 0;
373 } 381 }
374 382
@@ -407,8 +415,13 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
407 list_add_tail(&pe->child, &parent->child_list); 415 list_add_tail(&pe->child, &parent->child_list);
408 list_add_tail(&edev->list, &pe->edevs); 416 list_add_tail(&edev->list, &pe->edevs);
409 edev->pe = pe; 417 edev->pe = pe;
410 pr_debug("EEH: Add %s to Device PE#%x, Parent PE#%x\n", 418 pr_debug("EEH: Add %04x:%02x:%02x.%01x to "
411 edev->dn->full_name, pe->addr, pe->parent->addr); 419 "Device PE#%x, Parent PE#%x\n",
420 edev->phb->global_number,
421 edev->config_addr >> 8,
422 PCI_SLOT(edev->config_addr & 0xFF),
423 PCI_FUNC(edev->config_addr & 0xFF),
424 pe->addr, pe->parent->addr);
412 425
413 return 0; 426 return 0;
414} 427}
@@ -428,8 +441,11 @@ int eeh_rmv_from_parent_pe(struct eeh_dev *edev)
428 int cnt; 441 int cnt;
429 442
430 if (!edev->pe) { 443 if (!edev->pe) {
431 pr_debug("%s: No PE found for EEH device %s\n", 444 pr_debug("%s: No PE found for device %04x:%02x:%02x.%01x\n",
432 __func__, edev->dn->full_name); 445 __func__, edev->phb->global_number,
446 edev->config_addr >> 8,
447 PCI_SLOT(edev->config_addr & 0xFF),
448 PCI_FUNC(edev->config_addr & 0xFF));
433 return -EEXIST; 449 return -EEXIST;
434 } 450 }
435 451
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,
305 const __be32 *reg; 305 const __be32 *reg;
306 int reglen, devfn; 306 int reglen, devfn;
307#ifdef CONFIG_EEH 307#ifdef CONFIG_EEH
308 struct eeh_dev *edev = of_node_to_eeh_dev(dn); 308 struct eeh_dev *edev = pdn_to_eeh_dev(PCI_DN(dn));
309#endif 309#endif
310 310
311 pr_debug(" * %s\n", dn->full_name); 311 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,
113 113
114 ret = rtas_read_config(pdn, where, size, val); 114 ret = rtas_read_config(pdn, where, size, val);
115 if (*val == EEH_IO_ERROR_VALUE(size) && 115 if (*val == EEH_IO_ERROR_VALUE(size) &&
116 eeh_dev_check_failure(of_node_to_eeh_dev(dn))) 116 eeh_dev_check_failure(pdn_to_eeh_dev(pdn)))
117 return PCIBIOS_DEVICE_NOT_FOUND; 117 return PCIBIOS_DEVICE_NOT_FOUND;
118 118
119 return ret; 119 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)
195static struct device_node *find_pe_dn(struct pci_dev *dev, int *total) 195static struct device_node *find_pe_dn(struct pci_dev *dev, int *total)
196{ 196{
197 struct device_node *dn; 197 struct device_node *dn;
198 struct pci_dn *pdn;
198 struct eeh_dev *edev; 199 struct eeh_dev *edev;
199 200
200 /* Found our PE and assume 8 at that point. */ 201 /* 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 return NULL; 205 return NULL;
205 206
206 /* Get the top level device in the PE */ 207 /* Get the top level device in the PE */
207 edev = of_node_to_eeh_dev(dn); 208 edev = pdn_to_eeh_dev(PCI_DN(dn));
208 if (edev->pe) 209 if (edev->pe)
209 edev = list_first_entry(&edev->pe->edevs, struct eeh_dev, list); 210 edev = list_first_entry(&edev->pe->edevs, struct eeh_dev, list);
210 dn = eeh_dev_to_of_node(edev); 211 pdn = eeh_dev_to_pdn(edev);
212 dn = pdn ? pdn->node : NULL;
211 if (!dn) 213 if (!dn)
212 return NULL; 214 return NULL;
213 215