aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/nfc
diff options
context:
space:
mode:
authorMark A. Greer <mgreer@animalcreek.com>2014-09-02 18:12:44 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2014-09-07 17:13:45 -0400
commit1961843ceeca0d3e55744bba7ae8d9e23d04cf6a (patch)
treed515e99992c63e9063d613fabd6375ef6ac28f15 /drivers/nfc
parent6fb9edcb43d0b1bf0ac2aaf6ba488d105c45f477 (diff)
NFC: trf7970a: Handle timeout values of zero
The digital layer can try to send a command with a timeout value of zero (e.g., digital_tg_send_psl_res(). The zero value is used as a flag to indicate that the driver should not expect a response. To handle this, the driver sets an internal timer because it should still get an interrupt with the TX bit set in the IRQ Status Register. When it gets that interrupt, it returns a return value of '0'. If it doesn't get the interrupt before timing out, it returns ETIMEDOUT as usual. Signed-off-by: Mark A. Greer <mgreer@animalcreek.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/nfc')
-rw-r--r--drivers/nfc/trf7970a.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c
index 00fb2cee6790..8b109e15687f 100644
--- a/drivers/nfc/trf7970a.c
+++ b/drivers/nfc/trf7970a.c
@@ -132,6 +132,7 @@
132/* TX length is 3 nibbles long ==> 4KB - 1 bytes max */ 132/* TX length is 3 nibbles long ==> 4KB - 1 bytes max */
133#define TRF7970A_TX_MAX (4096 - 1) 133#define TRF7970A_TX_MAX (4096 - 1)
134 134
135#define TRF7970A_WAIT_FOR_TX_IRQ 20
135#define TRF7970A_WAIT_FOR_RX_DATA_TIMEOUT 20 136#define TRF7970A_WAIT_FOR_RX_DATA_TIMEOUT 20
136#define TRF7970A_WAIT_FOR_FIFO_DRAIN_TIMEOUT 20 137#define TRF7970A_WAIT_FOR_FIFO_DRAIN_TIMEOUT 20
137#define TRF7970A_WAIT_TO_ISSUE_ISO15693_EOF 40 138#define TRF7970A_WAIT_TO_ISSUE_ISO15693_EOF 40
@@ -555,7 +556,11 @@ static int trf7970a_transmit(struct trf7970a *trf, struct sk_buff *skb,
555 timeout = TRF7970A_WAIT_TO_ISSUE_ISO15693_EOF; 556 timeout = TRF7970A_WAIT_TO_ISSUE_ISO15693_EOF;
556 } else { 557 } else {
557 trf->state = TRF7970A_ST_WAIT_FOR_RX_DATA; 558 trf->state = TRF7970A_ST_WAIT_FOR_RX_DATA;
558 timeout = trf->timeout; 559
560 if (!trf->timeout)
561 timeout = TRF7970A_WAIT_FOR_TX_IRQ;
562 else
563 timeout = trf->timeout;
559 } 564 }
560 } 565 }
561 566
@@ -754,6 +759,14 @@ static irqreturn_t trf7970a_irq(int irq, void *dev_id)
754 trf7970a_cmd(trf, TRF7970A_CMD_FIFO_RESET); 759 trf7970a_cmd(trf, TRF7970A_CMD_FIFO_RESET);
755 } else if (status == TRF7970A_IRQ_STATUS_TX) { 760 } else if (status == TRF7970A_IRQ_STATUS_TX) {
756 trf7970a_cmd(trf, TRF7970A_CMD_FIFO_RESET); 761 trf7970a_cmd(trf, TRF7970A_CMD_FIFO_RESET);
762
763 if (!trf->timeout) {
764 trf->ignore_timeout = !cancel_delayed_work(
765 &trf->timeout_work);
766 trf->rx_skb = ERR_PTR(0);
767 trf7970a_send_upstream(trf);
768 break;
769 }
757 } else { 770 } else {
758 trf7970a_send_err_upstream(trf, -EIO); 771 trf7970a_send_err_upstream(trf, -EIO);
759 } 772 }
@@ -1253,12 +1266,14 @@ static int trf7970a_in_send_cmd(struct nfc_digital_dev *ddev,
1253 goto out_err; 1266 goto out_err;
1254 } 1267 }
1255 1268
1256 trf->rx_skb = nfc_alloc_recv_skb(TRF7970A_RX_SKB_ALLOC_SIZE, 1269 if (timeout) {
1257 GFP_KERNEL); 1270 trf->rx_skb = nfc_alloc_recv_skb(TRF7970A_RX_SKB_ALLOC_SIZE,
1258 if (!trf->rx_skb) { 1271 GFP_KERNEL);
1259 dev_dbg(trf->dev, "Can't alloc rx_skb\n"); 1272 if (!trf->rx_skb) {
1260 ret = -ENOMEM; 1273 dev_dbg(trf->dev, "Can't alloc rx_skb\n");
1261 goto out_err; 1274 ret = -ENOMEM;
1275 goto out_err;
1276 }
1262 } 1277 }
1263 1278
1264 if (trf->state == TRF7970A_ST_IDLE_RX_BLOCKED) { 1279 if (trf->state == TRF7970A_ST_IDLE_RX_BLOCKED) {