diff options
author | Gavin Shan <shangw@linux.vnet.ibm.com> | 2012-03-20 17:30:29 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2012-03-27 20:31:58 -0400 |
commit | 1a5c2e63f497bdb5912138888053a02870ed1153 (patch) | |
tree | 08c27e6b0ae05fb89ad3b4906a3aeb0ce2bec728 /arch | |
parent | 39baadbf36cee3ede5fdb8a34006d9109e5e2570 (diff) |
powerpc/eeh: Retrieve PHB from global list
Currently, the existing PHBs are retrieved from the FDT (Flat
Device Tree) based on the name of FDT node. Specificly, those
FDT nodes whose names have prefix "pci" are regarded as PHBs.
That's inappropriate because some PCI bridges possibilly have
names leading with "pci". It caused EEH is enabled on same
PCI devices for towice.
The patch fixes the above issue. Besides, the PHBs are expected
to be figured out from FDT before enable EEH on them. Therefore,
it's resonable to retrieve the PHBs from the global linked list
traced by variable "hose_list" insteading poking them from FDT.
For the EEH implementation on pSeries platform, RTAS is critical
because all low-level functions are implemented based on RTAS.
Therefore, we should make sure "/rtas" OF node is available and
ready before to enable EEH core. However, it actually introduced
duplicate since the previous pSeries platform dependent initialization
function already do the check. Besides, we want to make eeh core
platform independent, so RTAS related staff should be removed there.
The patch removes the duplicate check on "/rtas" OF node for eeh
core.
Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/platforms/pseries/eeh.c | 19 |
1 files changed, 5 insertions, 14 deletions
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index 8011088392d3..309d38ef7322 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c | |||
@@ -984,7 +984,8 @@ int __exit eeh_ops_unregister(const char *name) | |||
984 | */ | 984 | */ |
985 | void __init eeh_init(void) | 985 | void __init eeh_init(void) |
986 | { | 986 | { |
987 | struct device_node *phb, *np; | 987 | struct pci_controller *hose, *tmp; |
988 | struct device_node *phb; | ||
988 | int ret; | 989 | int ret; |
989 | 990 | ||
990 | /* call platform initialization function */ | 991 | /* call platform initialization function */ |
@@ -1000,19 +1001,9 @@ void __init eeh_init(void) | |||
1000 | 1001 | ||
1001 | raw_spin_lock_init(&confirm_error_lock); | 1002 | raw_spin_lock_init(&confirm_error_lock); |
1002 | 1003 | ||
1003 | np = of_find_node_by_path("/rtas"); | 1004 | /* Enable EEH for all adapters */ |
1004 | if (np == NULL) | 1005 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { |
1005 | return; | 1006 | phb = hose->dn; |
1006 | |||
1007 | /* Enable EEH for all adapters. Note that eeh requires buid's */ | ||
1008 | for (phb = of_find_node_by_name(NULL, "pci"); phb; | ||
1009 | phb = of_find_node_by_name(phb, "pci")) { | ||
1010 | unsigned long buid; | ||
1011 | |||
1012 | buid = get_phb_buid(phb); | ||
1013 | if (buid == 0 || !of_node_to_eeh_dev(phb)) | ||
1014 | continue; | ||
1015 | |||
1016 | traverse_pci_devices(phb, eeh_early_enable, NULL); | 1007 | traverse_pci_devices(phb, eeh_early_enable, NULL); |
1017 | } | 1008 | } |
1018 | 1009 | ||