aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/ppc-pci.h2
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c91
2 files changed, 35 insertions, 58 deletions
diff --git a/arch/powerpc/include/asm/ppc-pci.h b/arch/powerpc/include/asm/ppc-pci.h
index 5e34b10aaa12..2a80f080a7ba 100644
--- a/arch/powerpc/include/asm/ppc-pci.h
+++ b/arch/powerpc/include/asm/ppc-pci.h
@@ -53,7 +53,7 @@ void pci_addr_cache_remove_device(struct pci_dev *dev);
53struct pci_dev *pci_addr_cache_get_device(unsigned long addr); 53struct pci_dev *pci_addr_cache_get_device(unsigned long addr);
54void eeh_slot_error_detail(struct eeh_pe *pe, int severity); 54void eeh_slot_error_detail(struct eeh_pe *pe, int severity);
55int eeh_pci_enable(struct eeh_pe *pe, int function); 55int eeh_pci_enable(struct eeh_pe *pe, int function);
56int eeh_reset_pe(struct eeh_dev *); 56int eeh_reset_pe(struct eeh_pe *);
57int rtas_write_config(struct pci_dn *, int where, int size, u32 val); 57int rtas_write_config(struct pci_dn *, int where, int size, u32 val);
58int rtas_read_config(struct pci_dn *, int where, int size, u32 *val); 58int rtas_read_config(struct pci_dn *, int where, int size, u32 *val);
59void eeh_pe_state_mark(struct eeh_pe *pe, int state); 59void eeh_pe_state_mark(struct eeh_pe *pe, int state);
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;