NFC: trf7970a: Handle low-watermark IRQ when transmitting
authorMark A. Greer <mgreer@animalcreek.com>
Tue, 2 Sep 2014 22:12:30 +0000 (15:12 -0700)
committerSamuel Ortiz <sameo@linux.intel.com>
Sun, 7 Sep 2014 21:13:44 +0000 (23:13 +0200)
Commit 4dd836e46c3d ("NFC: trf7970a: Reset FIFO when
'End of TX' Interrupt Occurs") fixes the issue that
it was meant to fix but adds the unfortunate side
effect of causing the driver to report an error
when the TX low-watermark level is passed during
transmits.  This can be fixed by checking whether
the IRQ status indicates that the low-watermark
has been passed when transmitting.  If it has been
passed and the FIFO is empty, then its safe to reset
the FIFO.  Otherwise, silently continue since another
TX interrupt will be generated and the FIFO will be
reset then.

Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
drivers/nfc/trf7970a.c

index e9e961fe67561cd6aa56d24d450f5a658edc1d97..6d2b06ddf191998712d2c1ee8b1cbe255e42a0c5 100644 (file)
@@ -667,7 +667,7 @@ static irqreturn_t trf7970a_irq(int irq, void *dev_id)
 {
        struct trf7970a *trf = dev_id;
        int ret;
-       u8 status;
+       u8 status, fifo_bytes;
 
        mutex_lock(&trf->lock);
 
@@ -720,6 +720,16 @@ static irqreturn_t trf7970a_irq(int irq, void *dev_id)
                        trf->ignore_timeout =
                                !cancel_delayed_work(&trf->timeout_work);
                        trf7970a_drain_fifo(trf, status);
+               } else if (status & TRF7970A_IRQ_STATUS_FIFO) {
+                       ret = trf7970a_read(trf, TRF7970A_FIFO_STATUS,
+                                       &fifo_bytes);
+
+                       fifo_bytes &= ~TRF7970A_FIFO_STATUS_OVERFLOW;
+
+                       if (ret)
+                               trf7970a_send_err_upstream(trf, ret);
+                       else if (!fifo_bytes)
+                               trf7970a_cmd(trf, TRF7970A_CMD_FIFO_RESET);
                } else if (status == TRF7970A_IRQ_STATUS_TX) {
                        trf7970a_cmd(trf, TRF7970A_CMD_FIFO_RESET);
                } else {