linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: Gavin Shan <shangw@linux.vnet.ibm.com>
To: linuxppc-dev@ozlabs.org
Cc: shangw@linux.vnet.ibm.com
Subject: [PATCH 05/21] pSeries platform EEH operation
Date: Tue, 28 Feb 2012 14:03:55 +0800	[thread overview]
Message-ID: <1330409051-8941-6-git-send-email-shangw@linux.vnet.ibm.com> (raw)
In-Reply-To: <1330409051-8941-1-git-send-email-shangw@linux.vnet.ibm.com>

There're 4 EEH operations that are covered by the dedicated RTAS
call <ibm,set-eeh-option>: enable or disable EEH, enable MMIO and
enable DMA. At early stage of system boot, the EEH would be tried
to enable on PCI device related device node. MMIO and DMA for
particular PE should be enabled when doing recovery on EEH errors
so that the PE could function properly again.

The patch implements it and abstract that through struct
eeh_ops::set_eeh. It would be help for EEH to support multiple
platforms in future.

Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/eeh.h               |    4 ++
 arch/powerpc/include/asm/ppc-pci.h           |    2 -
 arch/powerpc/platforms/pseries/eeh.c         |   26 ++--------------
 arch/powerpc/platforms/pseries/eeh_driver.c  |    4 +-
 arch/powerpc/platforms/pseries/eeh_pseries.c |   39 +++++++++++++++++++++++++-
 5 files changed, 48 insertions(+), 27 deletions(-)

diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index 0666c52..76f7b3f 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -38,6 +38,10 @@ struct device_node;
  * platform should register its own EEH operation callback
  * functions before any EEH further operations.
  */
+#define EEH_OPT_DISABLE		0	/* EEH disable	*/
+#define EEH_OPT_ENABLE		1	/* EEH enable	*/
+#define EEH_OPT_THAW_MMIO	2	/* MMIO enable	*/
+#define EEH_OPT_THAW_DMA	3	/* DMA enable	*/
 struct eeh_ops {
 	char *name;
 	int (*init)(void);
diff --git a/arch/powerpc/include/asm/ppc-pci.h b/arch/powerpc/include/asm/ppc-pci.h
index 605a970..6150349 100644
--- a/arch/powerpc/include/asm/ppc-pci.h
+++ b/arch/powerpc/include/asm/ppc-pci.h
@@ -56,8 +56,6 @@ struct pci_dev *pci_get_device_by_addr(unsigned long addr);
 #define EEH_LOG_TEMP_FAILURE 1
 #define EEH_LOG_PERM_FAILURE 2
 void eeh_slot_error_detail (struct pci_dn *pdn, int severity);
-#define EEH_THAW_MMIO 2
-#define EEH_THAW_DMA  3
 int eeh_pci_enable(struct pci_dn *pdn, int function);
 int eeh_reset_pe(struct pci_dn *);
 int eeh_wait_for_slot_status(struct pci_dn *pdn, int max_wait_msecs);
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index bb6de6c..70a9617 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -87,7 +87,6 @@
 #define PCI_BUS_RESET_WAIT_MSEC (60*1000)
 
 /* RTAS tokens */
-static int ibm_set_eeh_option;
 static int ibm_set_slot_reset;
 static int ibm_read_slot_reset_state;
 static int ibm_read_slot_reset_state2;
@@ -283,7 +282,7 @@ void eeh_slot_error_detail(struct pci_dn *pdn, int severity)
 	size_t loglen = 0;
 	pci_regs_buf[0] = 0;
 
-	eeh_pci_enable(pdn, EEH_THAW_MMIO);
+	eeh_pci_enable(pdn, EEH_OPT_THAW_MMIO);
 	eeh_configure_bridge(pdn);
 	eeh_restore_bars(pdn);
 	loglen = eeh_gather_pci_data(pdn, pci_regs_buf, EEH_PCI_REGS_LOG_LEN);
@@ -698,26 +697,15 @@ EXPORT_SYMBOL(eeh_check_failure);
  */
 int eeh_pci_enable(struct pci_dn *pdn, int function)
 {
-	int config_addr;
 	int rc;
 
-	/* Use PE configuration address, if present */
-	config_addr = pdn->eeh_config_addr;
-	if (pdn->eeh_pe_config_addr)
-		config_addr = pdn->eeh_pe_config_addr;
-
-	rc = rtas_call(ibm_set_eeh_option, 4, 1, NULL,
-	               config_addr,
-	               BUID_HI(pdn->phb->buid),
-	               BUID_LO(pdn->phb->buid),
-		            function);
-
+	rc = eeh_ops->set_option(pdn->node, function);
 	if (rc)
 		printk(KERN_WARNING "EEH: Unexpected state change %d, err=%d dn=%s\n",
 		        function, rc, pdn->node->full_name);
 
 	rc = eeh_wait_for_slot_status(pdn, PCI_BUS_RESET_WAIT_MSEC);
-	if ((rc == 4) && (function == EEH_THAW_MMIO))
+	if ((rc == 4) && (function == EEH_OPT_THAW_MMIO))
 		return 0;
 
 	return rc;
@@ -1158,9 +1146,7 @@ static void *eeh_early_enable(struct device_node *dn, void *data)
 	if (regs) {
 		/* First register entry is addr (00BBSS00)  */
 		/* Try to enable eeh */
-		ret = rtas_call(ibm_set_eeh_option, 4, 1, NULL,
-		                regs[0], info->buid_hi, info->buid_lo,
-		                EEH_ENABLE);
+		ret = eeh_ops->set_option(dn, EEH_OPT_ENABLE);
 
 		enable = 0;
 		if (ret == 0) {
@@ -1299,7 +1285,6 @@ void __init eeh_init(void)
 	if (np == NULL)
 		return;
 
-	ibm_set_eeh_option = rtas_token("ibm,set-eeh-option");
 	ibm_set_slot_reset = rtas_token("ibm,set-slot-reset");
 	ibm_read_slot_reset_state2 = rtas_token("ibm,read-slot-reset-state2");
 	ibm_read_slot_reset_state = rtas_token("ibm,read-slot-reset-state");
@@ -1309,9 +1294,6 @@ void __init eeh_init(void)
 	ibm_configure_bridge = rtas_token("ibm,configure-bridge");
 	ibm_configure_pe = rtas_token("ibm,configure-pe");
 
-	if (ibm_set_eeh_option == RTAS_UNKNOWN_SERVICE)
-		return;
-
 	eeh_error_buf_size = rtas_token("rtas-error-log-max");
 	if (eeh_error_buf_size == RTAS_UNKNOWN_SERVICE) {
 		eeh_error_buf_size = 1024;
diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c
index 5315350..02eab3b 100644
--- a/arch/powerpc/platforms/pseries/eeh_driver.c
+++ b/arch/powerpc/platforms/pseries/eeh_driver.c
@@ -422,7 +422,7 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event)
 
 	/* If all devices reported they can proceed, then re-enable MMIO */
 	if (result == PCI_ERS_RESULT_CAN_RECOVER) {
-		rc = eeh_pci_enable(frozen_pdn, EEH_THAW_MMIO);
+		rc = eeh_pci_enable(frozen_pdn, EEH_OPT_THAW_MMIO);
 
 		if (rc < 0)
 			goto hard_fail;
@@ -436,7 +436,7 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event)
 
 	/* If all devices reported they can proceed, then re-enable DMA */
 	if (result == PCI_ERS_RESULT_CAN_RECOVER) {
-		rc = eeh_pci_enable(frozen_pdn, EEH_THAW_DMA);
+		rc = eeh_pci_enable(frozen_pdn, EEH_OPT_THAW_DMA);
 
 		if (rc < 0)
 			goto hard_fail;
diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
index 1a9410a..c48a9e6 100644
--- a/arch/powerpc/platforms/pseries/eeh_pseries.c
+++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
@@ -121,7 +121,44 @@ static int pseries_eeh_init(void)
  */
 static int pseries_eeh_set_option(struct device_node *dn, int option)
 {
-	return 0;
+	int ret = 0;
+	struct pci_dn *pdn;
+	const u32 *reg;
+	int config_addr;
+
+	pdn = PCI_DN(dn);
+
+	/*
+	 * When we're enabling or disabling EEH functioality on
+	 * the particular PE, the PE config address is possibly
+	 * unavailable. Therefore, we have to figure it out from
+	 * the FDT node.
+	 */
+	switch (option) {
+	case EEH_OPT_DISABLE:
+	case EEH_OPT_ENABLE:
+		reg = of_get_property(dn, "reg", NULL);
+		config_addr = reg[0];
+		break;
+
+	case EEH_OPT_THAW_MMIO:
+	case EEH_OPT_THAW_DMA:
+		config_addr = pdn->eeh_config_addr;
+		if (pdn->eeh_pe_config_addr)
+			config_addr = pdn->eeh_pe_config_addr;
+		break;
+
+	default:
+		pr_err("%s: Invalid option %d\n",
+			__func__, option);
+		return -EINVAL;
+	}
+
+	ret = rtas_call(ibm_set_eeh_option, 4, 1, NULL,
+			config_addr, BUID_HI(pdn->phb->buid),
+			BUID_LO(pdn->phb->buid), option);
+
+	return ret;
 }
 
 /**
-- 
1.7.5.4

  parent reply	other threads:[~2012-02-28  6:04 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-02-28  6:03 [PATCH v5 00/21] EEH reorganization Gavin Shan
2012-02-28  6:03 ` [PATCH 01/21] Cleanup on comments of EEH core Gavin Shan
2012-02-28  6:03 ` [PATCH 02/21] Cleanup on function names " Gavin Shan
2012-02-28  6:03 ` [PATCH 03/21] Platform dependent EEH operations Gavin Shan
2012-02-28  6:03 ` [PATCH 04/21] pSeries platform EEH initialization Gavin Shan
2012-02-28  6:03 ` Gavin Shan [this message]
2012-02-28  6:03 ` [PATCH 06/21] pSeries platform EEH PE address retrieval Gavin Shan
2012-02-28  6:03 ` [PATCH 07/21] pSeries platform PE state retrieval Gavin Shan
2012-02-28  6:03 ` [PATCH 08/21] pSeries platform EEH wait PE state Gavin Shan
2012-02-28  6:03 ` [PATCH 09/21] pSeries platform EEH reset PE Gavin Shan
2012-02-28  6:04 ` [PATCH 10/21] pSeries platform EEH error log retrieval Gavin Shan
2012-02-28  6:04 ` [PATCH 11/21] pSeries platform EEH configure bridge Gavin Shan
2012-02-28  6:04 ` [PATCH 12/21] Cleanup on comments of EEH aux components Gavin Shan
2012-02-28  6:04 ` [PATCH 13/21] Cleanup on function names " Gavin Shan
2012-02-28  6:04 ` [PATCH 14/21] Introduce EEH device Gavin Shan
2012-02-28  6:04 ` [PATCH 15/21] Replace pci_dn with eeh_dev for EEH sysfs Gavin Shan
2012-02-28  6:04 ` [PATCH 16/21] Replace pci_dn with eeh_dev for EEH address cache Gavin Shan
2012-02-28  6:04 ` [PATCH 17/21] Replace pci_dn with eeh_dev for EEH core Gavin Shan
2012-02-28  6:04 ` [PATCH 18/21] Replace pci_dn with eeh_dev for EEH aux components Gavin Shan
2012-02-28  6:04 ` [PATCH 19/21] Replace pci_dn with eeh_dev for EEH on pSeries Gavin Shan
2012-02-28  6:04 ` [PATCH 20/21] Introduce struct eeh_stats for EEH Gavin Shan
2012-02-28 10:04   ` David Laight
2012-02-29  1:08     ` Gavin Shan
2012-02-29  2:25   ` Gavin Shan
2012-02-29 12:56   ` Michael Ellerman
2012-03-01  1:14     ` Gavin Shan
2012-03-01  1:47   ` [PATCH 20/21] Introduce struct eeh_stats for EEH - Reworked Gavin Shan
2012-02-28  6:04 ` [PATCH 21/21] pSeries platform config space access in EEH Gavin Shan
2012-02-29  3:04 ` [PATCH v5 00/21] EEH reorganization Gavin Shan
2012-04-12 21:39 ` Anton Blanchard
2012-04-13  2:03   ` Anton Blanchard
2012-04-17  1:29     ` Gavin Shan
2012-04-17  1:37       ` Anton Blanchard
2012-04-17  1:57         ` Benjamin Herrenschmidt
2012-04-17  5:30           ` Gavin Shan
  -- strict thread matches above, loose matches on Subject: below --
2012-02-24  9:37 [PATCH v4 " Gavin Shan
2012-02-24  9:38 ` [PATCH 05/21] pSeries platform EEH operation Gavin Shan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1330409051-8941-6-git-send-email-shangw@linux.vnet.ibm.com \
    --to=shangw@linux.vnet.ibm.com \
    --cc=linuxppc-dev@ozlabs.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).