diff options
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/platforms/pseries/eeh.c | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index 57bef2c2f325..46ea4acd9906 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c | |||
@@ -82,6 +82,7 @@ static int ibm_set_slot_reset; | |||
82 | static int ibm_read_slot_reset_state; | 82 | static int ibm_read_slot_reset_state; |
83 | static int ibm_read_slot_reset_state2; | 83 | static int ibm_read_slot_reset_state2; |
84 | static int ibm_slot_error_detail; | 84 | static int ibm_slot_error_detail; |
85 | static int ibm_get_config_addr_info; | ||
85 | 86 | ||
86 | int eeh_subsystem_enabled; | 87 | int eeh_subsystem_enabled; |
87 | EXPORT_SYMBOL(eeh_subsystem_enabled); | 88 | EXPORT_SYMBOL(eeh_subsystem_enabled); |
@@ -457,6 +458,7 @@ eeh_slot_availability(struct pci_dn *pdn) | |||
457 | static void | 458 | static void |
458 | rtas_pci_slot_reset(struct pci_dn *pdn, int state) | 459 | rtas_pci_slot_reset(struct pci_dn *pdn, int state) |
459 | { | 460 | { |
461 | int config_addr; | ||
460 | int rc; | 462 | int rc; |
461 | 463 | ||
462 | BUG_ON (pdn==NULL); | 464 | BUG_ON (pdn==NULL); |
@@ -467,8 +469,13 @@ rtas_pci_slot_reset(struct pci_dn *pdn, int state) | |||
467 | return; | 469 | return; |
468 | } | 470 | } |
469 | 471 | ||
472 | /* Use PE configuration address, if present */ | ||
473 | config_addr = pdn->eeh_config_addr; | ||
474 | if (pdn->eeh_pe_config_addr) | ||
475 | config_addr = pdn->eeh_pe_config_addr; | ||
476 | |||
470 | rc = rtas_call(ibm_set_slot_reset,4,1, NULL, | 477 | rc = rtas_call(ibm_set_slot_reset,4,1, NULL, |
471 | pdn->eeh_config_addr, | 478 | config_addr, |
472 | BUID_HI(pdn->phb->buid), | 479 | BUID_HI(pdn->phb->buid), |
473 | BUID_LO(pdn->phb->buid), | 480 | BUID_LO(pdn->phb->buid), |
474 | state); | 481 | state); |
@@ -695,8 +702,22 @@ static void *early_enable_eeh(struct device_node *dn, void *data) | |||
695 | eeh_subsystem_enabled = 1; | 702 | eeh_subsystem_enabled = 1; |
696 | pdn->eeh_mode |= EEH_MODE_SUPPORTED; | 703 | pdn->eeh_mode |= EEH_MODE_SUPPORTED; |
697 | pdn->eeh_config_addr = regs[0]; | 704 | pdn->eeh_config_addr = regs[0]; |
705 | |||
706 | /* If the newer, better, ibm,get-config-addr-info is supported, | ||
707 | * then use that instead. */ | ||
708 | pdn->eeh_pe_config_addr = 0; | ||
709 | if (ibm_get_config_addr_info != RTAS_UNKNOWN_SERVICE) { | ||
710 | unsigned int rets[2]; | ||
711 | ret = rtas_call (ibm_get_config_addr_info, 4, 2, rets, | ||
712 | pdn->eeh_config_addr, | ||
713 | info->buid_hi, info->buid_lo, | ||
714 | 0); | ||
715 | if (ret == 0) | ||
716 | pdn->eeh_pe_config_addr = rets[0]; | ||
717 | } | ||
698 | #ifdef DEBUG | 718 | #ifdef DEBUG |
699 | printk(KERN_DEBUG "EEH: %s: eeh enabled\n", dn->full_name); | 719 | printk(KERN_DEBUG "EEH: %s: eeh enabled, config=%x pe_config=%x\n", |
720 | dn->full_name, pdn->eeh_config_addr, pdn->eeh_pe_config_addr); | ||
700 | #endif | 721 | #endif |
701 | } else { | 722 | } else { |
702 | 723 | ||
@@ -748,6 +769,7 @@ void __init eeh_init(void) | |||
748 | ibm_read_slot_reset_state2 = rtas_token("ibm,read-slot-reset-state2"); | 769 | ibm_read_slot_reset_state2 = rtas_token("ibm,read-slot-reset-state2"); |
749 | ibm_read_slot_reset_state = rtas_token("ibm,read-slot-reset-state"); | 770 | ibm_read_slot_reset_state = rtas_token("ibm,read-slot-reset-state"); |
750 | ibm_slot_error_detail = rtas_token("ibm,slot-error-detail"); | 771 | ibm_slot_error_detail = rtas_token("ibm,slot-error-detail"); |
772 | ibm_get_config_addr_info = rtas_token("ibm,get-config-addr-info"); | ||
751 | 773 | ||
752 | if (ibm_set_eeh_option == RTAS_UNKNOWN_SERVICE) | 774 | if (ibm_set_eeh_option == RTAS_UNKNOWN_SERVICE) |
753 | return; | 775 | return; |