Patchwork [29/31] powerpc/eeh: Register OPAL notifier for PCI error

login
register
mail settings
Submitter Gavin Shan
Date June 20, 2013, 5:21 a.m.
Message ID <1371705681-24632-30-git-send-email-shangw@linux.vnet.ibm.com>
Download mbox | patch
Permalink /patch/252746/
State Accepted
Headers show

Comments

Gavin Shan - June 20, 2013, 5:21 a.m.
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: Gavin Shan <shangw@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/powernv/eeh-ioda.c |   24 +++++++++++++++++++++++-
 1 files changed, 23 insertions(+), 1 deletions(-)

Patch

diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c
index a3eebd1..4961270 100644
--- a/arch/powerpc/platforms/powernv/eeh-ioda.c
+++ b/arch/powerpc/platforms/powernv/eeh-ioda.c
@@ -43,6 +43,13 @@ 
 
 static char *hub_diag = NULL;
 
+static void ioda_eeh_event(u64 events)
+{
+	/* We simply send special EEH event */
+	if (events & OPAL_EVENT_PCI_ERROR)
+		eeh_send_failure_event(NULL);
+}
+
 /**
  * ioda_eeh_post_init - Chip dependent post initialization
  * @hose: PCI controller
@@ -54,6 +61,16 @@  static char *hub_diag = NULL;
 static int ioda_eeh_post_init(struct pci_controller *hose)
 {
 	struct pnv_phb *phb = hose->private_data;
+	int ret;
+
+	/* Register OPAL event notifier */
+	ret = opal_notifier_register(OPAL_EVENT_PCI_ERROR,
+				     ioda_eeh_event);
+	if (ret) {
+		pr_err("%s: Failed to register OPAL event notifier (%d)\n",
+		       __func__, ret);
+		return ret;
+	}
 
 	/* FIXME: Enable it for PHB3 later */
 	if (phb->type == PNV_PHB_IODA1) {
@@ -736,8 +753,13 @@  static int ioda_eeh_next_error(struct eeh_pe **pe)
 	long rc;
 	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);
+	opal_notifier_update_evt(OPAL_EVENT_PCI_ERROR, 0x0ul);
 
 	list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
 		/*