For EEH on PowerNV platform, we will do EEH probe based on the
real PCI devices. The PCI devices are available after PCI probe.
So we have to call eeh_init() explicitly on PowerNV platform
after PCI probe. The patch also does EEH probe for PowerNV platform
in eeh_init().

Signed-off-by: Gavin Shan <sha...@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/eeh.h       |    6 ++++++
 arch/powerpc/platforms/pseries/eeh.c |   23 +++++++++++++++++++++--
 2 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index 557d82a..1ff2aa9 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -199,6 +199,7 @@ void eeh_pci_dev_traverse(struct pci_bus *bus,
                eeh_pci_traverse_func fn, void *flag);
 void *eeh_dev_init(struct device_node *dn, void *data);
 void eeh_dev_phb_init_dynamic(struct pci_controller *phb);
+int __init eeh_init(void);
 int __init eeh_ops_register(struct eeh_ops *ops);
 int __exit eeh_ops_unregister(const char *name);
 unsigned long eeh_check_failure(const volatile void __iomem *token,
@@ -227,6 +228,11 @@ void eeh_remove_bus_device(struct pci_dev *, int);
 
 #else /* !CONFIG_EEH */
 
+static inline int eeh_init(void)
+{
+       return 0;
+}
+
 static inline void *eeh_dev_init(struct device_node *dn, void *data)
 {
        return NULL;
diff --git a/arch/powerpc/platforms/pseries/eeh.c 
b/arch/powerpc/platforms/pseries/eeh.c
index 6b73d6c..abe26f8 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -674,11 +674,21 @@ int __exit eeh_ops_unregister(const char *name)
  * Even if force-off is set, the EEH hardware is still enabled, so that
  * newer systems can boot.
  */
-static int __init eeh_init(void)
+int __init eeh_init(void)
 {
        struct pci_controller *hose, *tmp;
        struct device_node *phb;
-       int ret;
+       static int cnt = 0;
+       int ret = 0;
+
+       /*
+        * We have to delay the initialization on PowerNV after
+        * the PCI hierarchy tree has been built because the PEs
+        * are figured out based on PCI devices instead of device
+        * tree nodes
+        */
+       if (machine_is(powernv) && cnt++ <= 0)
+               return ret;
 
        /* call platform initialization function */
        if (!eeh_ops) {
@@ -700,6 +710,15 @@ static int __init eeh_init(void)
                        phb = hose->dn;
                        traverse_pci_devices(phb, eeh_ops->of_probe, NULL);
                }
+       } else if (eeh_probe_mode_dev()) {
+               list_for_each_entry_safe(hose, tmp,
+                       &hose_list, list_node) {
+                       eeh_pci_dev_traverse(hose->bus, eeh_ops->dev_probe, 
NULL);
+               }
+       } else {
+               pr_warning("%s: Invalid probe mode %d\n",
+                       __func__, eeh_probe_mode);
+               return -EINVAL;
        }
 
        if (eeh_subsystem_enabled)
-- 
1.7.5.4

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to