NFC: nfcmrvl: avoid being stuck on FW dnld timeout
authorVincent Cuissard <cuissard@marvell.com>
Tue, 3 Nov 2015 18:19:36 +0000 (19:19 +0100)
committerSamuel Ortiz <sameo@linux.intel.com>
Wed, 4 Nov 2015 23:32:25 +0000 (00:32 +0100)
FW Download procedure can block on del_timer_sync because the
timer is not running. This patch check that timer is scheduled
before cancelling it.

Signed-off-by: Vincent Cuissard <cuissard@marvell.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
drivers/nfc/nfcmrvl/fw_dnld.c

index bfa771392b1fb47669b914f9000a8f2be6fd9133..f8dcdf4b24f6ff8b63a1a70e9e5249b997209780 100644 (file)
@@ -113,9 +113,12 @@ static void fw_dnld_over(struct nfcmrvl_private *priv, u32 error)
        }
 
        atomic_set(&priv->ndev->cmd_cnt, 0);
-       del_timer_sync(&priv->ndev->cmd_timer);
 
-       del_timer_sync(&priv->fw_dnld.timer);
+       if (timer_pending(&priv->ndev->cmd_timer))
+               del_timer_sync(&priv->ndev->cmd_timer);
+
+       if (timer_pending(&priv->fw_dnld.timer))
+               del_timer_sync(&priv->fw_dnld.timer);
 
        nfc_info(priv->dev, "FW loading over (%d)]\n", error);
 
@@ -472,9 +475,12 @@ void       nfcmrvl_fw_dnld_deinit(struct nfcmrvl_private *priv)
 void   nfcmrvl_fw_dnld_recv_frame(struct nfcmrvl_private *priv,
                                   struct sk_buff *skb)
 {
+       /* Discard command timer */
+       if (timer_pending(&priv->ndev->cmd_timer))
+               del_timer_sync(&priv->ndev->cmd_timer);
+
        /* Allow next command */
        atomic_set(&priv->ndev->cmd_cnt, 1);
-       del_timer_sync(&priv->ndev->cmd_timer);
 
        /* Queue and trigger rx work */
        skb_queue_tail(&priv->fw_dnld.rx_q, skb);