mtd: atmel_nand: add NFC status error check
authorWu, Josh <Josh.wu@atmel.com>
Tue, 10 Jun 2014 09:50:09 +0000 (17:50 +0800)
committerBrian Norris <computersforpeace@gmail.com>
Tue, 22 Jul 2014 03:02:01 +0000 (20:02 -0700)
Add a new function to read the NFC status. Meantime, this function will
check if there is any errors in NFC.

Signed-off-by: Josh Wu <josh.wu@atmel.com>
Tested-by: Matthieu Crapet <Matthieu.Crapet@ingenico.com>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
drivers/mtd/nand/atmel_nand.c
drivers/mtd/nand/atmel_nand_nfc.h

index 4f5348f..22e9137 100644 (file)
@@ -1572,6 +1572,25 @@ static int atmel_hw_nand_init_params(struct platform_device *pdev,
        return 0;
 }
 
+static inline u32 nfc_read_status(struct atmel_nand_host *host)
+{
+       u32 err_flags = NFC_SR_DTOE | NFC_SR_UNDEF | NFC_SR_AWB | NFC_SR_ASE;
+       u32 nfc_status = nfc_readl(host->nfc->hsmc_regs, SR);
+
+       if (unlikely(nfc_status & err_flags)) {
+               if (nfc_status & NFC_SR_DTOE)
+                       dev_err(host->dev, "NFC: Waiting Nand R/B Timeout Error\n");
+               else if (nfc_status & NFC_SR_UNDEF)
+                       dev_err(host->dev, "NFC: Access Undefined Area Error\n");
+               else if (nfc_status & NFC_SR_AWB)
+                       dev_err(host->dev, "NFC: Access memory While NFC is busy\n");
+               else if (nfc_status & NFC_SR_ASE)
+                       dev_err(host->dev, "NFC: Access memory Size Error\n");
+       }
+
+       return nfc_status;
+}
+
 /* SMC interrupt service routine */
 static irqreturn_t hsmc_interrupt(int irq, void *dev_id)
 {
@@ -1579,7 +1598,7 @@ static irqreturn_t hsmc_interrupt(int irq, void *dev_id)
        u32 status, mask, pending;
        irqreturn_t ret = IRQ_HANDLED;
 
-       status = nfc_readl(host->nfc->hsmc_regs, SR);
+       status = nfc_read_status(host);
        mask = nfc_readl(host->nfc->hsmc_regs, IMR);
        pending = status & mask;
 
@@ -2209,6 +2228,9 @@ static int atmel_nand_nfc_probe(struct platform_device *pdev)
                }
        }
 
+       nfc_writel(nfc->hsmc_regs, IDR, 0xffffffff);
+       nfc_readl(nfc->hsmc_regs, SR);  /* clear the NFC_SR */
+
        nfc->is_initialized = true;
        dev_info(&pdev->dev, "NFC is probed.\n");
        return 0;
index 4efd117..85b8ca6 100644 (file)
 #define ATMEL_HSMC_NFC_SR      0x08            /* NFC Status Register */
 #define                NFC_SR_XFR_DONE         (1 << 16)
 #define                NFC_SR_CMD_DONE         (1 << 17)
+#define                NFC_SR_DTOE             (1 << 20)
+#define                NFC_SR_UNDEF            (1 << 21)
+#define                NFC_SR_AWB              (1 << 22)
+#define                NFC_SR_ASE              (1 << 23)
 #define                NFC_SR_RB_EDGE          (1 << 24)
 
 #define ATMEL_HSMC_NFC_IER     0x0c