aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms
diff options
context:
space:
mode:
authorGavin Shan <shangw@linux.vnet.ibm.com>2012-09-07 18:44:17 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-09-09 19:35:42 -0400
commitc270a24c59bd9a4ac7dbcbd964cbd14270b3a361 (patch)
tree1a1be911c6db25795a866ce60a9f43971ee68076 /arch/powerpc/platforms
parentff477966c626e440dd1737801ae4d52cf1f22bff (diff)
powerpc/eeh: Do reset based on PE
The patch implements reset based on PE instead of eeh device. Also, The functions used to retrieve the reset type, either hot or fundamental reset, have been reworked for a little bit. More specificly, it's implemented based the the eeh device traverse function. Signed-off-by: Gavin Shan <shangw@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/pseries/eeh.c91
1 files changed, 34 insertions, 57 deletions
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 45723618b1df..56a022b03651 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -455,17 +455,24 @@ int eeh_pci_enable(struct eeh_pe *pe, int function)
455 */ 455 */
456int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state) 456int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state)
457{ 457{
458 struct device_node *dn = pci_device_to_OF_node(dev); 458 struct eeh_dev *edev = pci_dev_to_eeh_dev(dev);
459 struct eeh_pe *pe = edev->pe;
460
461 if (!pe) {
462 pr_err("%s: No PE found on PCI device %s\n",
463 __func__, pci_name(dev));
464 return -EINVAL;
465 }
459 466
460 switch (state) { 467 switch (state) {
461 case pcie_deassert_reset: 468 case pcie_deassert_reset:
462 eeh_ops->reset(dn, EEH_RESET_DEACTIVATE); 469 eeh_ops->reset(pe, EEH_RESET_DEACTIVATE);
463 break; 470 break;
464 case pcie_hot_reset: 471 case pcie_hot_reset:
465 eeh_ops->reset(dn, EEH_RESET_HOT); 472 eeh_ops->reset(pe, EEH_RESET_HOT);
466 break; 473 break;
467 case pcie_warm_reset: 474 case pcie_warm_reset:
468 eeh_ops->reset(dn, EEH_RESET_FUNDAMENTAL); 475 eeh_ops->reset(pe, EEH_RESET_FUNDAMENTAL);
469 break; 476 break;
470 default: 477 default:
471 return -EINVAL; 478 return -EINVAL;
@@ -475,66 +482,37 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state stat
475} 482}
476 483
477/** 484/**
478 * __eeh_set_pe_freset - Check the required reset for child devices 485 * eeh_set_pe_freset - Check the required reset for the indicated device
479 * @parent: parent device 486 * @data: EEH device
480 * @freset: return value 487 * @flag: return value
481 *
482 * Each device might have its preferred reset type: fundamental or
483 * hot reset. The routine is used to collect the information from
484 * the child devices so that they could be reset accordingly.
485 */
486void __eeh_set_pe_freset(struct device_node *parent, unsigned int *freset)
487{
488 struct device_node *dn;
489
490 for_each_child_of_node(parent, dn) {
491 if (of_node_to_eeh_dev(dn)) {
492 struct pci_dev *dev = of_node_to_eeh_dev(dn)->pdev;
493
494 if (dev && dev->driver)
495 *freset |= dev->needs_freset;
496
497 __eeh_set_pe_freset(dn, freset);
498 }
499 }
500}
501
502/**
503 * eeh_set_pe_freset - Check the required reset for the indicated device and its children
504 * @dn: parent device
505 * @freset: return value
506 * 488 *
507 * Each device might have its preferred reset type: fundamental or 489 * Each device might have its preferred reset type: fundamental or
508 * hot reset. The routine is used to collected the information for 490 * hot reset. The routine is used to collected the information for
509 * the indicated device and its children so that the bunch of the 491 * the indicated device and its children so that the bunch of the
510 * devices could be reset properly. 492 * devices could be reset properly.
511 */ 493 */
512void eeh_set_pe_freset(struct device_node *dn, unsigned int *freset) 494static void *eeh_set_dev_freset(void *data, void *flag)
513{ 495{
514 struct pci_dev *dev; 496 struct pci_dev *dev;
515 dn = eeh_find_device_pe(dn); 497 unsigned int *freset = (unsigned int *)flag;
516 498 struct eeh_dev *edev = (struct eeh_dev *)data;
517 /* Back up one, since config addrs might be shared */
518 if (!pcibios_find_pci_bus(dn) && of_node_to_eeh_dev(dn->parent))
519 dn = dn->parent;
520 499
521 dev = of_node_to_eeh_dev(dn)->pdev; 500 dev = eeh_dev_to_pci_dev(edev);
522 if (dev) 501 if (dev)
523 *freset |= dev->needs_freset; 502 *freset |= dev->needs_freset;
524 503
525 __eeh_set_pe_freset(dn, freset); 504 return NULL;
526} 505}
527 506
528/** 507/**
529 * eeh_reset_pe_once - Assert the pci #RST line for 1/4 second 508 * eeh_reset_pe_once - Assert the pci #RST line for 1/4 second
530 * @edev: pci device node to be reset. 509 * @pe: EEH PE
531 * 510 *
532 * Assert the PCI #RST line for 1/4 second. 511 * Assert the PCI #RST line for 1/4 second.
533 */ 512 */
534static void eeh_reset_pe_once(struct eeh_dev *edev) 513static void eeh_reset_pe_once(struct eeh_pe *pe)
535{ 514{
536 unsigned int freset = 0; 515 unsigned int freset = 0;
537 struct device_node *dn = eeh_dev_to_of_node(edev);
538 516
539 /* Determine type of EEH reset required for 517 /* Determine type of EEH reset required for
540 * Partitionable Endpoint, a hot-reset (1) 518 * Partitionable Endpoint, a hot-reset (1)
@@ -542,12 +520,12 @@ static void eeh_reset_pe_once(struct eeh_dev *edev)
542 * A fundamental reset required by any device under 520 * A fundamental reset required by any device under
543 * Partitionable Endpoint trumps hot-reset. 521 * Partitionable Endpoint trumps hot-reset.
544 */ 522 */
545 eeh_set_pe_freset(dn, &freset); 523 eeh_pe_dev_traverse(pe, eeh_set_dev_freset, &freset);
546 524
547 if (freset) 525 if (freset)
548 eeh_ops->reset(dn, EEH_RESET_FUNDAMENTAL); 526 eeh_ops->reset(pe, EEH_RESET_FUNDAMENTAL);
549 else 527 else
550 eeh_ops->reset(dn, EEH_RESET_HOT); 528 eeh_ops->reset(pe, EEH_RESET_HOT);
551 529
552 /* The PCI bus requires that the reset be held high for at least 530 /* The PCI bus requires that the reset be held high for at least
553 * a 100 milliseconds. We wait a bit longer 'just in case'. 531 * a 100 milliseconds. We wait a bit longer 'just in case'.
@@ -559,9 +537,9 @@ static void eeh_reset_pe_once(struct eeh_dev *edev)
559 * pci slot reset line is dropped. Make sure we don't miss 537 * pci slot reset line is dropped. Make sure we don't miss
560 * these, and clear the flag now. 538 * these, and clear the flag now.
561 */ 539 */
562 eeh_clear_slot(dn, EEH_MODE_ISOLATED); 540 eeh_pe_state_clear(pe, EEH_MODE_ISOLATED);
563 541
564 eeh_ops->reset(dn, EEH_RESET_DEACTIVATE); 542 eeh_ops->reset(pe, EEH_RESET_DEACTIVATE);
565 543
566 /* After a PCI slot has been reset, the PCI Express spec requires 544 /* After a PCI slot has been reset, the PCI Express spec requires
567 * a 1.5 second idle time for the bus to stabilize, before starting 545 * a 1.5 second idle time for the bus to stabilize, before starting
@@ -573,32 +551,31 @@ static void eeh_reset_pe_once(struct eeh_dev *edev)
573 551
574/** 552/**
575 * eeh_reset_pe - Reset the indicated PE 553 * eeh_reset_pe - Reset the indicated PE
576 * @edev: PCI device associated EEH device 554 * @pe: EEH PE
577 * 555 *
578 * This routine should be called to reset indicated device, including 556 * This routine should be called to reset indicated device, including
579 * PE. A PE might include multiple PCI devices and sometimes PCI bridges 557 * PE. A PE might include multiple PCI devices and sometimes PCI bridges
580 * might be involved as well. 558 * might be involved as well.
581 */ 559 */
582int eeh_reset_pe(struct eeh_dev *edev) 560int eeh_reset_pe(struct eeh_pe *pe)
583{ 561{
584 int i, rc; 562 int i, rc;
585 struct device_node *dn = eeh_dev_to_of_node(edev);
586 563
587 /* Take three shots at resetting the bus */ 564 /* Take three shots at resetting the bus */
588 for (i=0; i<3; i++) { 565 for (i=0; i<3; i++) {
589 eeh_reset_pe_once(edev); 566 eeh_reset_pe_once(pe);
590 567
591 rc = eeh_ops->wait_state(dn, PCI_BUS_RESET_WAIT_MSEC); 568 rc = eeh_ops->wait_state(pe, PCI_BUS_RESET_WAIT_MSEC);
592 if (rc == (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE)) 569 if (rc == (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE))
593 return 0; 570 return 0;
594 571
595 if (rc < 0) { 572 if (rc < 0) {
596 printk(KERN_ERR "EEH: unrecoverable slot failure %s\n", 573 pr_err("%s: Unrecoverable slot failure on PHB#%d-PE#%x",
597 dn->full_name); 574 __func__, pe->phb->global_number, pe->addr);
598 return -1; 575 return -1;
599 } 576 }
600 printk(KERN_ERR "EEH: bus reset %d failed on slot %s, rc=%d\n", 577 pr_err("EEH: bus reset %d failed on PHB#%d-PE#%x, rc=%d\n",
601 i+1, dn->full_name, rc); 578 i+1, pe->phb->global_number, pe->addr, rc);
602 } 579 }
603 580
604 return -1; 581 return -1;