Commit 66f9af83 authored by Gavin Shan's avatar Gavin Shan Committed by Benjamin Herrenschmidt

powerpc/eeh: Disable EEH on reboot

We possiblly detect EEH errors during reboot, particularly in kexec
path, but it's impossible for device drivers and EEH core to handle
or recover them properly.

The patch registers one reboot notifier for EEH and disable EEH
subsystem during reboot. That means the EEH errors is going to be
cleared by hardware reset or second kernel during early stage of
PCI probe.
Signed-off-by: default avatarGavin Shan <shangw@linux.vnet.ibm.com>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 2ec5a0ad
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/rbtree.h> #include <linux/rbtree.h>
#include <linux/reboot.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/export.h> #include <linux/export.h>
...@@ -747,6 +748,17 @@ int __exit eeh_ops_unregister(const char *name) ...@@ -747,6 +748,17 @@ int __exit eeh_ops_unregister(const char *name)
return -EEXIST; return -EEXIST;
} }
static int eeh_reboot_notifier(struct notifier_block *nb,
unsigned long action, void *unused)
{
eeh_set_enable(false);
return NOTIFY_DONE;
}
static struct notifier_block eeh_reboot_nb = {
.notifier_call = eeh_reboot_notifier,
};
/** /**
* eeh_init - EEH initialization * eeh_init - EEH initialization
* *
...@@ -778,6 +790,14 @@ int eeh_init(void) ...@@ -778,6 +790,14 @@ int eeh_init(void)
if (machine_is(powernv) && cnt++ <= 0) if (machine_is(powernv) && cnt++ <= 0)
return ret; return ret;
/* Register reboot notifier */
ret = register_reboot_notifier(&eeh_reboot_nb);
if (ret) {
pr_warn("%s: Failed to register notifier (%d)\n",
__func__, ret);
return ret;
}
/* call platform initialization function */ /* call platform initialization function */
if (!eeh_ops) { if (!eeh_ops) {
pr_warning("%s: Platform EEH operation not found\n", pr_warning("%s: Platform EEH operation not found\n",
......
...@@ -44,7 +44,8 @@ static int ioda_eeh_event(struct notifier_block *nb, ...@@ -44,7 +44,8 @@ static int ioda_eeh_event(struct notifier_block *nb,
/* We simply send special EEH event */ /* We simply send special EEH event */
if ((changed_evts & OPAL_EVENT_PCI_ERROR) && if ((changed_evts & OPAL_EVENT_PCI_ERROR) &&
(events & OPAL_EVENT_PCI_ERROR)) (events & OPAL_EVENT_PCI_ERROR) &&
eeh_enabled())
eeh_send_failure_event(NULL); eeh_send_failure_event(NULL);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment