Commit 7cb9d93d authored by Gavin Shan's avatar Gavin Shan Committed by Benjamin Herrenschmidt

powerpc/eeh: Register OPAL notifier for PCI error

The patch registers OPAL event notifier and process the PCI errors
from firmware. If we have pending PCI errors, special EEH event
(without binding PE) will be sent to EEH core for processing.
Signed-off-by: default avatarGavin Shan <shangw@linux.vnet.ibm.com>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent e8e71fa4
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/msi.h> #include <linux/msi.h>
#include <linux/notifier.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/string.h> #include <linux/string.h>
...@@ -42,6 +43,26 @@ ...@@ -42,6 +43,26 @@
#endif #endif
static char *hub_diag = NULL; static char *hub_diag = NULL;
static int ioda_eeh_nb_init = 0;
static int ioda_eeh_event(struct notifier_block *nb,
unsigned long events, void *change)
{
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_send_failure_event(NULL);
return 0;
}
static struct notifier_block ioda_eeh_nb = {
.notifier_call = ioda_eeh_event,
.next = NULL,
.priority = 0
};
/** /**
* ioda_eeh_post_init - Chip dependent post initialization * ioda_eeh_post_init - Chip dependent post initialization
...@@ -54,6 +75,19 @@ static char *hub_diag = NULL; ...@@ -54,6 +75,19 @@ static char *hub_diag = NULL;
static int ioda_eeh_post_init(struct pci_controller *hose) static int ioda_eeh_post_init(struct pci_controller *hose)
{ {
struct pnv_phb *phb = hose->private_data; struct pnv_phb *phb = hose->private_data;
int ret;
/* Register OPAL event notifier */
if (!ioda_eeh_nb_init) {
ret = opal_notifier_register(&ioda_eeh_nb);
if (ret) {
pr_err("%s: Can't register OPAL event notifier (%d)\n",
__func__, ret);
return ret;
}
ioda_eeh_nb_init = 1;
}
/* FIXME: Enable it for PHB3 later */ /* FIXME: Enable it for PHB3 later */
if (phb->type == PNV_PHB_IODA1) { if (phb->type == PNV_PHB_IODA1) {
...@@ -736,8 +770,13 @@ static int ioda_eeh_next_error(struct eeh_pe **pe) ...@@ -736,8 +770,13 @@ static int ioda_eeh_next_error(struct eeh_pe **pe)
long rc; long rc;
int ret = 1; int ret = 1;
/* While running here, it's safe to purge the event queue */ /*
* While running here, it's safe to purge the event queue.
* And we should keep the cached OPAL notifier event sychronized
* between the kernel and firmware.
*/
eeh_remove_event(NULL); eeh_remove_event(NULL);
opal_notifier_update_evt(OPAL_EVENT_PCI_ERROR, 0x0ul);
list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
/* /*
......
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