From 1961843ceeca0d3e55744bba7ae8d9e23d04cf6a Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Tue, 2 Sep 2014 15:12:44 -0700 Subject: [PATCH] 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 Signed-off-by: Samuel Ortiz --- drivers/nfc/trf7970a.c | 29 ++++++++++++++++++++++------- 1 file 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 @@ /* TX length is 3 nibbles long ==> 4KB - 1 bytes max */ #define TRF7970A_TX_MAX (4096 - 1) +#define TRF7970A_WAIT_FOR_TX_IRQ 20 #define TRF7970A_WAIT_FOR_RX_DATA_TIMEOUT 20 #define TRF7970A_WAIT_FOR_FIFO_DRAIN_TIMEOUT 20 #define TRF7970A_WAIT_TO_ISSUE_ISO15693_EOF 40 @@ -555,7 +556,11 @@ static int trf7970a_transmit(struct trf7970a *trf, struct sk_buff *skb, timeout = TRF7970A_WAIT_TO_ISSUE_ISO15693_EOF; } else { trf->state = TRF7970A_ST_WAIT_FOR_RX_DATA; - timeout = trf->timeout; + + if (!trf->timeout) + timeout = TRF7970A_WAIT_FOR_TX_IRQ; + else + timeout = trf->timeout; } } @@ -754,6 +759,14 @@ static irqreturn_t trf7970a_irq(int irq, void *dev_id) trf7970a_cmd(trf, TRF7970A_CMD_FIFO_RESET); } else if (status == TRF7970A_IRQ_STATUS_TX) { trf7970a_cmd(trf, TRF7970A_CMD_FIFO_RESET); + + if (!trf->timeout) { + trf->ignore_timeout = !cancel_delayed_work( + &trf->timeout_work); + trf->rx_skb = ERR_PTR(0); + trf7970a_send_upstream(trf); + break; + } } else { trf7970a_send_err_upstream(trf, -EIO); } @@ -1253,12 +1266,14 @@ static int trf7970a_in_send_cmd(struct nfc_digital_dev *ddev, goto out_err; } - trf->rx_skb = nfc_alloc_recv_skb(TRF7970A_RX_SKB_ALLOC_SIZE, - GFP_KERNEL); - if (!trf->rx_skb) { - dev_dbg(trf->dev, "Can't alloc rx_skb\n"); - ret = -ENOMEM; - goto out_err; + if (timeout) { + trf->rx_skb = nfc_alloc_recv_skb(TRF7970A_RX_SKB_ALLOC_SIZE, + GFP_KERNEL); + if (!trf->rx_skb) { + dev_dbg(trf->dev, "Can't alloc rx_skb\n"); + ret = -ENOMEM; + goto out_err; + } } if (trf->state == TRF7970A_ST_IDLE_RX_BLOCKED) { -- 2.20.1