[v2] opal/xscom: Clear the xscom status bits from HMER register.

Message ID 149864917619.21097.6423165766607140076.stgit@jupiter.in.ibm.com
State New
Headers show

Commit Message

Mahesh Jagannath Salgaonkar June 28, 2017, 11:26 a.m.
From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>

The completion status of each scom read/write operation is reported through
HMER bits 8,9 and 21-23. These HMER bits are sticky and they remain set
until they are cleared. The current opal code do not care to clear this
until next scom read/write operation is kicked in. Though this may be ok
as long as corresponding bits of HMEER are masked to avoid HMI getting
triggered, but it is always good to clear them as soon as scom operations
are completed.

Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
---
Change in V2:
- Clear the HMER scom status bits in fail path of xscom_reset().
---
 hw/xscom.c |   16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

Patch

diff --git a/hw/xscom.c b/hw/xscom.c
index 63813f1..92f9743 100644
--- a/hw/xscom.c
+++ b/hw/xscom.c
@@ -126,12 +126,18 @@  static void xscom_reset(uint32_t gcid)
 	hmer = xscom_wait_done();
 	if (hmer & SPR_HMER_XSCOM_FAIL)
 		goto fail;
+
+	/* Clear the scom status in HMER */
+	mtspr(SPR_HMER, HMER_CLR_MASK);
 	return;
  fail:
 	/* Fatal error resetting XSCOM */
 	log_simple_error(&e_info(OPAL_RC_XSCOM_RESET),
 		"XSCOM: Fatal error resetting engine after failed access !\n");
 
+	/* Clear the scom status in HMER */
+	mtspr(SPR_HMER, HMER_CLR_MASK);
+
 	/* XXX Generate error log ? attn ? panic ?
 	 * If we decide to panic, change the above severity to PANIC
 	 */
@@ -265,8 +271,11 @@  static int __xscom_read(uint32_t gcid, uint32_t pcb_addr, uint64_t *val)
 		hmer = xscom_wait_done();
 
 		/* Check for error */
-		if (!(hmer & SPR_HMER_XSCOM_FAIL))
+		if (!(hmer & SPR_HMER_XSCOM_FAIL)) {
+			/* Clear the scom status in HMER */
+			mtspr(SPR_HMER, HMER_CLR_MASK);
 			return OPAL_SUCCESS;
+		}
 
 		/* Handle error and possibly eventually retry */
 		ret = xscom_handle_error(hmer, gcid, pcb_addr, false, retries);
@@ -301,8 +310,11 @@  static int __xscom_write(uint32_t gcid, uint32_t pcb_addr, uint64_t val)
 		hmer = xscom_wait_done();
 
 		/* Check for error */
-		if (!(hmer & SPR_HMER_XSCOM_FAIL))
+		if (!(hmer & SPR_HMER_XSCOM_FAIL)) {
+			/* Clear the scom status in HMER */
+			mtspr(SPR_HMER, HMER_CLR_MASK);
 			return OPAL_SUCCESS;
+		}
 
 		/* Handle error and possibly eventually retry */
 		ret = xscom_handle_error(hmer, gcid, pcb_addr, true, retries);