OSDN Git Service

qpnp-fg-gen3: fg-memif: Clear CLEAR_LOG bit in DMA_CTL after handling error
authorSubbaraman Narayanamurthy <subbaram@codeaurora.org>
Wed, 15 Mar 2017 03:30:47 +0000 (20:30 -0700)
committerSubbaraman Narayanamurthy <subbaram@codeaurora.org>
Thu, 23 Mar 2017 23:42:10 +0000 (16:42 -0700)
Currently, if a DMA error is present, SW sets CLEAR_LOG bit
in DMA_CTL register to clear it. Since this bit is not self
clearing, one has to reset this back to 0 after error handling
finishes.

Change-Id: I824543338f98e06661276da0364dcb6d7496f9cc
Signed-off-by: Subbaraman Narayanamurthy <subbaram@codeaurora.org>
drivers/power/supply/qcom/fg-memif.c
drivers/power/supply/qcom/qpnp-fg-gen3.c

index 2dc7618..c00c72c 100644 (file)
@@ -175,6 +175,7 @@ int fg_clear_dma_errors_if_any(struct fg_chip *chip)
 {
        int rc;
        u8 dma_sts;
+       bool error_present;
 
        rc = fg_read(chip, MEM_IF_DMA_STS(chip), &dma_sts, 1);
        if (rc < 0) {
@@ -184,14 +185,13 @@ int fg_clear_dma_errors_if_any(struct fg_chip *chip)
        }
        fg_dbg(chip, FG_STATUS, "dma_sts: %x\n", dma_sts);
 
-       if (dma_sts & (DMA_WRITE_ERROR_BIT | DMA_READ_ERROR_BIT)) {
-               rc = fg_masked_write(chip, MEM_IF_DMA_CTL(chip),
-                               DMA_CLEAR_LOG_BIT, DMA_CLEAR_LOG_BIT);
-               if (rc < 0) {
-                       pr_err("failed to write addr=0x%04x, rc=%d\n",
-                               MEM_IF_DMA_CTL(chip), rc);
-                       return rc;
-               }
+       error_present = dma_sts & (DMA_WRITE_ERROR_BIT | DMA_READ_ERROR_BIT);
+       rc = fg_masked_write(chip, MEM_IF_DMA_CTL(chip), DMA_CLEAR_LOG_BIT,
+                       error_present ? DMA_CLEAR_LOG_BIT : 0);
+       if (rc < 0) {
+               pr_err("failed to write addr=0x%04x, rc=%d\n",
+                       MEM_IF_DMA_CTL(chip), rc);
+               return rc;
        }
 
        return 0;
index 6fdcc49..d0e1340 100644 (file)
@@ -3229,20 +3229,19 @@ static irqreturn_t fg_mem_xcp_irq_handler(int irq, void *data)
        }
 
        fg_dbg(chip, FG_IRQ, "irq %d triggered, status:%d\n", irq, status);
-       if (status & MEM_XCP_BIT) {
-               rc = fg_clear_dma_errors_if_any(chip);
-               if (rc < 0) {
-                       pr_err("Error in clearing DMA error, rc=%d\n", rc);
-                       return IRQ_HANDLED;
-               }
 
-               mutex_lock(&chip->sram_rw_lock);
+       mutex_lock(&chip->sram_rw_lock);
+       rc = fg_clear_dma_errors_if_any(chip);
+       if (rc < 0)
+               pr_err("Error in clearing DMA error, rc=%d\n", rc);
+
+       if (status & MEM_XCP_BIT) {
                rc = fg_clear_ima_errors_if_any(chip, true);
                if (rc < 0 && rc != -EAGAIN)
                        pr_err("Error in checking IMA errors rc:%d\n", rc);
-               mutex_unlock(&chip->sram_rw_lock);
        }
 
+       mutex_unlock(&chip->sram_rw_lock);
        return IRQ_HANDLED;
 }