*/
 
 #include <linux/delay.h>
+#include <linux/debugfs.h>
 #include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/list.h>
 
 #define IS_BRIDGE(class_code) (((class_code)<<16) == PCI_BASE_CLASS_BRIDGE)
 
+static int __init eeh_setup(char *str)
+{
+       if (!strcmp(str, "off"))
+               eeh_subsystem_flags |= EEH_FORCE_DISABLED;
+
+       return 1;
+}
+__setup("eeh=", eeh_setup);
+
 /**
  * eeh_gather_pci_data - Copy assorted PCI config space registers to buff
  * @edev: device to report data for
        .release   = single_release,
 };
 
+#ifdef CONFIG_DEBUG_FS
+static int eeh_enable_dbgfs_set(void *data, u64 val)
+{
+       if (val)
+               eeh_subsystem_flags &= ~EEH_FORCE_DISABLED;
+       else
+               eeh_subsystem_flags |= EEH_FORCE_DISABLED;
+
+       /* Notify the backend */
+       if (eeh_ops->post_init)
+               eeh_ops->post_init();
+
+       return 0;
+}
+
+static int eeh_enable_dbgfs_get(void *data, u64 *val)
+{
+       if (eeh_enabled())
+               *val = 0x1ul;
+       else
+               *val = 0x0ul;
+       return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(eeh_enable_dbgfs_ops, eeh_enable_dbgfs_get,
+                       eeh_enable_dbgfs_set, "0x%llx\n");
+#endif
+
 static int __init eeh_init_proc(void)
 {
-       if (machine_is(pseries) || machine_is(powernv))
+       if (machine_is(pseries) || machine_is(powernv)) {
                proc_create("powerpc/eeh", 0, NULL, &proc_eeh_operations);
+#ifdef CONFIG_DEBUG_FS
+               debugfs_create_file("eeh_enable", 0600,
+                                    powerpc_debugfs_root, NULL,
+                                    &eeh_enable_dbgfs_ops);
+#endif
+       }
+
        return 0;
 }
 __initcall(eeh_init_proc);
 
 {
        uint64_t changed_evts = (uint64_t)change;
 
-       /* We simply send special EEH event */
-       if ((changed_evts & OPAL_EVENT_PCI_ERROR) &&
-           (events & OPAL_EVENT_PCI_ERROR) &&
-           eeh_enabled())
+       /*
+        * We simply send special EEH event if EEH has
+        * been enabled, or clear pending events in
+        * case that we enable EEH soon
+        */
+       if (!(changed_evts & OPAL_EVENT_PCI_ERROR) ||
+           !(events & OPAL_EVENT_PCI_ERROR))
+               return 0;
+
+       if (eeh_enabled())
                eeh_send_failure_event(NULL);
+       else
+               opal_notifier_update_evt(OPAL_EVENT_PCI_ERROR, 0x0ul);
 
        return 0;
 }
        }
 
 #ifdef CONFIG_DEBUG_FS
-       if (phb->dbgfs) {
+       if (!phb->has_dbgfs && phb->dbgfs) {
+               phb->has_dbgfs = 1;
+
                debugfs_create_file("err_injct_outbound", 0600,
                                    phb->dbgfs, hose,
                                    &ioda_eeh_outb_dbgfs_ops);
        }
 #endif
 
-       phb->flags |= PNV_PHB_FLAG_EEH;
+       /* If EEH is enabled, we're going to rely on that.
+        * Otherwise, we restore to conventional mechanism
+        * to clear frozen PE during PCI config access.
+        */
+       if (eeh_enabled())
+               phb->flags |= PNV_PHB_FLAG_EEH;
+       else
+               phb->flags &= ~PNV_PHB_FLAG_EEH;
 
        return 0;
 }