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

Submitted by Gavin Shan on June 20, 2013, 5:21 a.m.

Details

Message ID 1371705681-24632-30-git-send-email-shangw@linux.vnet.ibm.com
State Accepted, archived
Headers show

Commit Message

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 hide | download patch | download mbox

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) {
 		/*