aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms
diff options
context:
space:
mode:
authorGavin Shan <gwshan@linux.vnet.ibm.com>2015-03-17 01:15:06 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2015-03-23 22:15:52 -0400
commitff57b454ddb938d98d48d8df356357000fedc88c (patch)
treeafb1399b36a933d563ee171fd529e6cf526031a5 /arch/powerpc/platforms
parente8e9b34cef237d4d6fdc0d350cd8a95d1adb9ee9 (diff)
powerpc/eeh: Do probe on pci_dn
Originally, EEH core probes on device_node or pci_dev to populate EEH devices and PEs, which conflicts with the fact: SRIOV VFs are usually enabled and created by PF's driver and they don't have the corresponding device_nodes. Instead, SRIOV VFs have dynamically created pci_dn, which can be used for EEH probe. The patch reworks EEH probe for PowerNV and pSeries platforms to do probing based on pci_dn, instead of pci_dev or device_node any more. Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r--arch/powerpc/platforms/powernv/eeh-powernv.c146
-rw-r--r--arch/powerpc/platforms/pseries/eeh_pseries.c82
-rw-r--r--arch/powerpc/platforms/pseries/pci_dlpar.c2
3 files changed, 143 insertions, 87 deletions
diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c
index 8eac8c57ee86..dcc524fe2a30 100644
--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
+++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
@@ -286,10 +286,82 @@ static int pnv_eeh_post_init(void)
286 return ret; 286 return ret;
287} 287}
288 288
289static int pnv_eeh_cap_start(struct pci_dn *pdn)
290{
291 u32 status;
292
293 if (!pdn)
294 return 0;
295
296 pnv_pci_cfg_read(pdn, PCI_STATUS, 2, &status);
297 if (!(status & PCI_STATUS_CAP_LIST))
298 return 0;
299
300 return PCI_CAPABILITY_LIST;
301}
302
303static int pnv_eeh_find_cap(struct pci_dn *pdn, int cap)
304{
305 int pos = pnv_eeh_cap_start(pdn);
306 int cnt = 48; /* Maximal number of capabilities */
307 u32 id;
308
309 if (!pos)
310 return 0;
311
312 while (cnt--) {
313 pnv_pci_cfg_read(pdn, pos, 1, &pos);
314 if (pos < 0x40)
315 break;
316
317 pos &= ~3;
318 pnv_pci_cfg_read(pdn, pos + PCI_CAP_LIST_ID, 1, &id);
319 if (id == 0xff)
320 break;
321
322 /* Found */
323 if (id == cap)
324 return pos;
325
326 /* Next one */
327 pos += PCI_CAP_LIST_NEXT;
328 }
329
330 return 0;
331}
332
333static int pnv_eeh_find_ecap(struct pci_dn *pdn, int cap)
334{
335 struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
336 u32 header;
337 int pos = 256, ttl = (4096 - 256) / 8;
338
339 if (!edev || !edev->pcie_cap)
340 return 0;
341 if (pnv_pci_cfg_read(pdn, pos, 4, &header) != PCIBIOS_SUCCESSFUL)
342 return 0;
343 else if (!header)
344 return 0;
345
346 while (ttl-- > 0) {
347 if (PCI_EXT_CAP_ID(header) == cap && pos)
348 return pos;
349
350 pos = PCI_EXT_CAP_NEXT(header);
351 if (pos < 256)
352 break;
353
354 if (pnv_pci_cfg_read(pdn, pos, 4, &header) != PCIBIOS_SUCCESSFUL)
355 break;
356 }
357
358 return 0;
359}
360
289/** 361/**
290 * pnv_eeh_dev_probe - Do probe on PCI device 362 * pnv_eeh_probe - Do probe on PCI device
291 * @dev: PCI device 363 * @pdn: PCI device node
292 * @flag: unused 364 * @data: unused
293 * 365 *
294 * When EEH module is installed during system boot, all PCI devices 366 * When EEH module is installed during system boot, all PCI devices
295 * are checked one by one to see if it supports EEH. The function 367 * are checked one by one to see if it supports EEH. The function
@@ -303,12 +375,12 @@ static int pnv_eeh_post_init(void)
303 * was possiblly triggered by EEH core, the binding between EEH device 375 * was possiblly triggered by EEH core, the binding between EEH device
304 * and the PCI device isn't built yet. 376 * and the PCI device isn't built yet.
305 */ 377 */
306static int pnv_eeh_dev_probe(struct pci_dev *dev, void *flag) 378static void *pnv_eeh_probe(struct pci_dn *pdn, void *data)
307{ 379{
308 struct pci_controller *hose = pci_bus_to_host(dev->bus); 380 struct pci_controller *hose = pdn->phb;
309 struct pnv_phb *phb = hose->private_data; 381 struct pnv_phb *phb = hose->private_data;
310 struct device_node *dn = pci_device_to_OF_node(dev); 382 struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
311 struct eeh_dev *edev = of_node_to_eeh_dev(dn); 383 uint32_t pcie_flags;
312 int ret; 384 int ret;
313 385
314 /* 386 /*
@@ -317,40 +389,42 @@ static int pnv_eeh_dev_probe(struct pci_dev *dev, void *flag)
317 * the root bridge. So it's not reasonable to continue 389 * the root bridge. So it's not reasonable to continue
318 * the probing. 390 * the probing.
319 */ 391 */
320 if (!dn || !edev || edev->pe) 392 if (!edev || edev->pe)
321 return 0; 393 return NULL;
322 394
323 /* Skip for PCI-ISA bridge */ 395 /* Skip for PCI-ISA bridge */
324 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_ISA) 396 if ((pdn->class_code >> 8) == PCI_CLASS_BRIDGE_ISA)
325 return 0; 397 return NULL;
326 398
327 /* Initialize eeh device */ 399 /* Initialize eeh device */
328 edev->class_code = dev->class; 400 edev->class_code = pdn->class_code;
329 edev->mode &= 0xFFFFFF00; 401 edev->mode &= 0xFFFFFF00;
330 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) 402 edev->pcix_cap = pnv_eeh_find_cap(pdn, PCI_CAP_ID_PCIX);
403 edev->pcie_cap = pnv_eeh_find_cap(pdn, PCI_CAP_ID_EXP);
404 edev->aer_cap = pnv_eeh_find_ecap(pdn, PCI_EXT_CAP_ID_ERR);
405 if ((edev->class_code >> 8) == PCI_CLASS_BRIDGE_PCI) {
331 edev->mode |= EEH_DEV_BRIDGE; 406 edev->mode |= EEH_DEV_BRIDGE;
332 edev->pcix_cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); 407 if (edev->pcie_cap) {
333 if (pci_is_pcie(dev)) { 408 pnv_pci_cfg_read(pdn, edev->pcie_cap + PCI_EXP_FLAGS,
334 edev->pcie_cap = pci_pcie_cap(dev); 409 2, &pcie_flags);
335 410 pcie_flags = (pcie_flags & PCI_EXP_FLAGS_TYPE) >> 4;
336 if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) 411 if (pcie_flags == PCI_EXP_TYPE_ROOT_PORT)
337 edev->mode |= EEH_DEV_ROOT_PORT; 412 edev->mode |= EEH_DEV_ROOT_PORT;
338 else if (pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) 413 else if (pcie_flags == PCI_EXP_TYPE_DOWNSTREAM)
339 edev->mode |= EEH_DEV_DS_PORT; 414 edev->mode |= EEH_DEV_DS_PORT;
340 415 }
341 edev->aer_cap = pci_find_ext_capability(dev,
342 PCI_EXT_CAP_ID_ERR);
343 } 416 }
344 417
345 edev->config_addr = ((dev->bus->number << 8) | dev->devfn); 418 edev->config_addr = (pdn->busno << 8) | (pdn->devfn);
346 edev->pe_config_addr = phb->bdfn_to_pe(phb, dev->bus, dev->devfn & 0xff); 419 edev->pe_config_addr = phb->ioda.pe_rmap[edev->config_addr];
347 420
348 /* Create PE */ 421 /* Create PE */
349 ret = eeh_add_to_parent_pe(edev); 422 ret = eeh_add_to_parent_pe(edev);
350 if (ret) { 423 if (ret) {
351 pr_warn("%s: Can't add PCI dev %s to parent PE (%d)\n", 424 pr_warn("%s: Can't add PCI dev %04x:%02x:%02x.%01x to parent PE (%d)\n",
352 __func__, pci_name(dev), ret); 425 __func__, hose->global_number, pdn->busno,
353 return ret; 426 PCI_SLOT(pdn->devfn), PCI_FUNC(pdn->devfn), ret);
427 return NULL;
354 } 428 }
355 429
356 /* 430 /*
@@ -369,8 +443,10 @@ static int pnv_eeh_dev_probe(struct pci_dev *dev, void *flag)
369 * Broadcom Austin 4-ports NICs (14e4:1657) 443 * Broadcom Austin 4-ports NICs (14e4:1657)
370 * Broadcom Shiner 2-ports 10G NICs (14e4:168e) 444 * Broadcom Shiner 2-ports 10G NICs (14e4:168e)
371 */ 445 */
372 if ((dev->vendor == PCI_VENDOR_ID_BROADCOM && dev->device == 0x1657) || 446 if ((pdn->vendor_id == PCI_VENDOR_ID_BROADCOM &&
373 (dev->vendor == PCI_VENDOR_ID_BROADCOM && dev->device == 0x168e)) 447 pdn->device_id == 0x1657) ||
448 (pdn->vendor_id == PCI_VENDOR_ID_BROADCOM &&
449 pdn->device_id == 0x168e))
374 edev->pe->state |= EEH_PE_CFG_RESTRICTED; 450 edev->pe->state |= EEH_PE_CFG_RESTRICTED;
375 451
376 /* 452 /*
@@ -380,7 +456,8 @@ static int pnv_eeh_dev_probe(struct pci_dev *dev, void *flag)
380 * to PE reset. 456 * to PE reset.
381 */ 457 */
382 if (!edev->pe->bus) 458 if (!edev->pe->bus)
383 edev->pe->bus = dev->bus; 459 edev->pe->bus = pci_find_bus(hose->global_number,
460 pdn->busno);
384 461
385 /* 462 /*
386 * Enable EEH explicitly so that we will do EEH check 463 * Enable EEH explicitly so that we will do EEH check
@@ -391,7 +468,7 @@ static int pnv_eeh_dev_probe(struct pci_dev *dev, void *flag)
391 /* Save memory bars */ 468 /* Save memory bars */
392 eeh_save_bars(edev); 469 eeh_save_bars(edev);
393 470
394 return 0; 471 return NULL;
395} 472}
396 473
397/** 474/**
@@ -1432,8 +1509,7 @@ static struct eeh_ops pnv_eeh_ops = {
1432 .name = "powernv", 1509 .name = "powernv",
1433 .init = pnv_eeh_init, 1510 .init = pnv_eeh_init,
1434 .post_init = pnv_eeh_post_init, 1511 .post_init = pnv_eeh_post_init,
1435 .of_probe = NULL, 1512 .probe = pnv_eeh_probe,
1436 .dev_probe = pnv_eeh_dev_probe,
1437 .set_option = pnv_eeh_set_option, 1513 .set_option = pnv_eeh_set_option,
1438 .get_pe_addr = pnv_eeh_get_pe_addr, 1514 .get_pe_addr = pnv_eeh_get_pe_addr,
1439 .get_state = pnv_eeh_get_state, 1515 .get_state = pnv_eeh_get_state,
diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
index a6c7e19f5eb3..a2946f72d5e7 100644
--- a/arch/powerpc/platforms/pseries/eeh_pseries.c
+++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
@@ -118,9 +118,8 @@ static int pseries_eeh_init(void)
118 return 0; 118 return 0;
119} 119}
120 120
121static int pseries_eeh_cap_start(struct device_node *dn) 121static int pseries_eeh_cap_start(struct pci_dn *pdn)
122{ 122{
123 struct pci_dn *pdn = PCI_DN(dn);
124 u32 status; 123 u32 status;
125 124
126 if (!pdn) 125 if (!pdn)
@@ -134,10 +133,9 @@ static int pseries_eeh_cap_start(struct device_node *dn)
134} 133}
135 134
136 135
137static int pseries_eeh_find_cap(struct device_node *dn, int cap) 136static int pseries_eeh_find_cap(struct pci_dn *pdn, int cap)
138{ 137{
139 struct pci_dn *pdn = PCI_DN(dn); 138 int pos = pseries_eeh_cap_start(pdn);
140 int pos = pseries_eeh_cap_start(dn);
141 int cnt = 48; /* Maximal number of capabilities */ 139 int cnt = 48; /* Maximal number of capabilities */
142 u32 id; 140 u32 id;
143 141
@@ -160,10 +158,9 @@ static int pseries_eeh_find_cap(struct device_node *dn, int cap)
160 return 0; 158 return 0;
161} 159}
162 160
163static int pseries_eeh_find_ecap(struct device_node *dn, int cap) 161static int pseries_eeh_find_ecap(struct pci_dn *pdn, int cap)
164{ 162{
165 struct pci_dn *pdn = PCI_DN(dn); 163 struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
166 struct eeh_dev *edev = of_node_to_eeh_dev(dn);
167 u32 header; 164 u32 header;
168 int pos = 256; 165 int pos = 256;
169 int ttl = (4096 - 256) / 8; 166 int ttl = (4096 - 256) / 8;
@@ -191,53 +188,44 @@ static int pseries_eeh_find_ecap(struct device_node *dn, int cap)
191} 188}
192 189
193/** 190/**
194 * pseries_eeh_of_probe - EEH probe on the given device 191 * pseries_eeh_probe - EEH probe on the given device
195 * @dn: OF node 192 * @pdn: PCI device node
196 * @flag: Unused 193 * @data: Unused
197 * 194 *
198 * When EEH module is installed during system boot, all PCI devices 195 * When EEH module is installed during system boot, all PCI devices
199 * are checked one by one to see if it supports EEH. The function 196 * are checked one by one to see if it supports EEH. The function
200 * is introduced for the purpose. 197 * is introduced for the purpose.
201 */ 198 */
202static void *pseries_eeh_of_probe(struct device_node *dn, void *flag) 199static void *pseries_eeh_probe(struct pci_dn *pdn, void *data)
203{ 200{
204 struct eeh_dev *edev; 201 struct eeh_dev *edev;
205 struct eeh_pe pe; 202 struct eeh_pe pe;
206 struct pci_dn *pdn = PCI_DN(dn);
207 const __be32 *classp, *vendorp, *devicep;
208 u32 class_code;
209 const __be32 *regs;
210 u32 pcie_flags; 203 u32 pcie_flags;
211 int enable = 0; 204 int enable = 0;
212 int ret; 205 int ret;
213 206
214 /* Retrieve OF node and eeh device */ 207 /* Retrieve OF node and eeh device */
215 edev = of_node_to_eeh_dev(dn); 208 edev = pdn_to_eeh_dev(pdn);
216 if (edev->pe || !of_device_is_available(dn)) 209 if (!edev || edev->pe)
217 return NULL; 210 return NULL;
218 211
219 /* Retrieve class/vendor/device IDs */ 212 /* Check class/vendor/device IDs */
220 classp = of_get_property(dn, "class-code", NULL); 213 if (!pdn->vendor_id || !pdn->device_id || !pdn->class_code)
221 vendorp = of_get_property(dn, "vendor-id", NULL);
222 devicep = of_get_property(dn, "device-id", NULL);
223
224 /* Skip for bad OF node or PCI-ISA bridge */
225 if (!classp || !vendorp || !devicep)
226 return NULL;
227 if (dn->type && !strcmp(dn->type, "isa"))
228 return NULL; 214 return NULL;
229 215
230 class_code = of_read_number(classp, 1); 216 /* Skip for PCI-ISA bridge */
217 if ((pdn->class_code >> 8) == PCI_CLASS_BRIDGE_ISA)
218 return NULL;
231 219
232 /* 220 /*
233 * Update class code and mode of eeh device. We need 221 * Update class code and mode of eeh device. We need
234 * correctly reflects that current device is root port 222 * correctly reflects that current device is root port
235 * or PCIe switch downstream port. 223 * or PCIe switch downstream port.
236 */ 224 */
237 edev->class_code = class_code; 225 edev->class_code = pdn->class_code;
238 edev->pcix_cap = pseries_eeh_find_cap(dn, PCI_CAP_ID_PCIX); 226 edev->pcix_cap = pseries_eeh_find_cap(pdn, PCI_CAP_ID_PCIX);
239 edev->pcie_cap = pseries_eeh_find_cap(dn, PCI_CAP_ID_EXP); 227 edev->pcie_cap = pseries_eeh_find_cap(pdn, PCI_CAP_ID_EXP);
240 edev->aer_cap = pseries_eeh_find_ecap(dn, PCI_EXT_CAP_ID_ERR); 228 edev->aer_cap = pseries_eeh_find_ecap(pdn, PCI_EXT_CAP_ID_ERR);
241 edev->mode &= 0xFFFFFF00; 229 edev->mode &= 0xFFFFFF00;
242 if ((edev->class_code >> 8) == PCI_CLASS_BRIDGE_PCI) { 230 if ((edev->class_code >> 8) == PCI_CLASS_BRIDGE_PCI) {
243 edev->mode |= EEH_DEV_BRIDGE; 231 edev->mode |= EEH_DEV_BRIDGE;
@@ -252,24 +240,16 @@ static void *pseries_eeh_of_probe(struct device_node *dn, void *flag)
252 } 240 }
253 } 241 }
254 242
255 /* Retrieve the device address */
256 regs = of_get_property(dn, "reg", NULL);
257 if (!regs) {
258 pr_warn("%s: OF node property %s::reg not found\n",
259 __func__, dn->full_name);
260 return NULL;
261 }
262
263 /* Initialize the fake PE */ 243 /* Initialize the fake PE */
264 memset(&pe, 0, sizeof(struct eeh_pe)); 244 memset(&pe, 0, sizeof(struct eeh_pe));
265 pe.phb = edev->phb; 245 pe.phb = edev->phb;
266 pe.config_addr = of_read_number(regs, 1); 246 pe.config_addr = (pdn->busno << 16) | (pdn->devfn << 8);
267 247
268 /* Enable EEH on the device */ 248 /* Enable EEH on the device */
269 ret = eeh_ops->set_option(&pe, EEH_OPT_ENABLE); 249 ret = eeh_ops->set_option(&pe, EEH_OPT_ENABLE);
270 if (!ret) { 250 if (!ret) {
271 edev->config_addr = of_read_number(regs, 1);
272 /* Retrieve PE address */ 251 /* Retrieve PE address */
252 edev->config_addr = (pdn->busno << 16) | (pdn->devfn << 8);
273 edev->pe_config_addr = eeh_ops->get_pe_addr(&pe); 253 edev->pe_config_addr = eeh_ops->get_pe_addr(&pe);
274 pe.addr = edev->pe_config_addr; 254 pe.addr = edev->pe_config_addr;
275 255
@@ -285,16 +265,17 @@ static void *pseries_eeh_of_probe(struct device_node *dn, void *flag)
285 eeh_add_flag(EEH_ENABLED); 265 eeh_add_flag(EEH_ENABLED);
286 eeh_add_to_parent_pe(edev); 266 eeh_add_to_parent_pe(edev);
287 267
288 pr_debug("%s: EEH enabled on %s PHB#%d-PE#%x, config addr#%x\n", 268 pr_debug("%s: EEH enabled on %02x:%02x.%01x PHB#%d-PE#%x\n",
289 __func__, dn->full_name, pe.phb->global_number, 269 __func__, pdn->busno, PCI_SLOT(pdn->devfn),
290 pe.addr, pe.config_addr); 270 PCI_FUNC(pdn->devfn), pe.phb->global_number,
291 } else if (dn->parent && of_node_to_eeh_dev(dn->parent) && 271 pe.addr);
292 (of_node_to_eeh_dev(dn->parent))->pe) { 272 } else if (pdn->parent && pdn_to_eeh_dev(pdn->parent) &&
273 (pdn_to_eeh_dev(pdn->parent))->pe) {
293 /* This device doesn't support EEH, but it may have an 274 /* This device doesn't support EEH, but it may have an
294 * EEH parent, in which case we mark it as supported. 275 * EEH parent, in which case we mark it as supported.
295 */ 276 */
296 edev->config_addr = of_node_to_eeh_dev(dn->parent)->config_addr; 277 edev->config_addr = pdn_to_eeh_dev(pdn->parent)->config_addr;
297 edev->pe_config_addr = of_node_to_eeh_dev(dn->parent)->pe_config_addr; 278 edev->pe_config_addr = pdn_to_eeh_dev(pdn->parent)->pe_config_addr;
298 eeh_add_to_parent_pe(edev); 279 eeh_add_to_parent_pe(edev);
299 } 280 }
300 } 281 }
@@ -707,8 +688,7 @@ static int pseries_eeh_write_config(struct device_node *dn, int where, int size,
707static struct eeh_ops pseries_eeh_ops = { 688static struct eeh_ops pseries_eeh_ops = {
708 .name = "pseries", 689 .name = "pseries",
709 .init = pseries_eeh_init, 690 .init = pseries_eeh_init,
710 .of_probe = pseries_eeh_of_probe, 691 .probe = pseries_eeh_probe,
711 .dev_probe = NULL,
712 .set_option = pseries_eeh_set_option, 692 .set_option = pseries_eeh_set_option,
713 .get_pe_addr = pseries_eeh_get_pe_addr, 693 .get_pe_addr = pseries_eeh_get_pe_addr,
714 .get_state = pseries_eeh_get_state, 694 .get_state = pseries_eeh_get_state,
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c
index 89e23811199c..f735f4fee48c 100644
--- a/arch/powerpc/platforms/pseries/pci_dlpar.c
+++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
@@ -82,7 +82,7 @@ struct pci_controller *init_phb_dynamic(struct device_node *dn)
82 eeh_dev_phb_init_dynamic(phb); 82 eeh_dev_phb_init_dynamic(phb);
83 83
84 if (dn->child) 84 if (dn->child)
85 eeh_add_device_tree_early(dn); 85 eeh_add_device_tree_early(PCI_DN(dn));
86 86
87 pcibios_scan_phb(phb); 87 pcibios_scan_phb(phb);
88 pcibios_finish_adding_to_bus(phb->bus); 88 pcibios_finish_adding_to_bus(phb->bus);