From e0e09f71900ba7d43aa5ce29a2d616482b0dfe58 Mon Sep 17 00:00:00 2001 From: Subbaraman Narayanamurthy Date: Tue, 14 Mar 2017 20:30:47 -0700 Subject: qpnp-fg-gen3: fg-memif: Clear CLEAR_LOG bit in DMA_CTL after handling error 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 --- drivers/power/supply/qcom/fg-memif.c | 16 ++++++++-------- drivers/power/supply/qcom/qpnp-fg-gen3.c | 15 +++++++-------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/drivers/power/supply/qcom/fg-memif.c b/drivers/power/supply/qcom/fg-memif.c index 2dc76182ed15..c00c72c5884c 100644 --- a/drivers/power/supply/qcom/fg-memif.c +++ b/drivers/power/supply/qcom/fg-memif.c @@ -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; diff --git a/drivers/power/supply/qcom/qpnp-fg-gen3.c b/drivers/power/supply/qcom/qpnp-fg-gen3.c index 6fdcc494cdc5..d0e1340456a0 100644 --- a/drivers/power/supply/qcom/qpnp-fg-gen3.c +++ b/drivers/power/supply/qcom/qpnp-fg-gen3.c @@ -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; } -- cgit v1.2.3