Commit 5bf8a748 authored by Chin-Ran Lo's avatar Chin-Ran Lo Committed by Marcel Holtmann

Bluetooth: btmrvl: avoid sending data to firmware after hs_activated

We should suspend hci device and purge remaining data in tx queue
before enabling host sleep in firmware. If any data is sent to
firmware after host sleep is activated, firmware may end up
sending a TX_DONE interrupt to driver. If this interrupt gets
delivered to host while the SDIO host controller is suspending,
it may crash the system.

Conversely, in resume handler, we should resume hci device after
host sleep is de-activated.
Signed-off-by: default avatarChin-Ran Lo <crlo@marvell.com>
Signed-off-by: default avatarBing Zhao <bzhao@marvell.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent 4d042654
...@@ -1169,6 +1169,10 @@ static int btmrvl_sdio_suspend(struct device *dev) ...@@ -1169,6 +1169,10 @@ static int btmrvl_sdio_suspend(struct device *dev)
} }
priv = card->priv; priv = card->priv;
hcidev = priv->btmrvl_dev.hcidev;
BT_DBG("%s: SDIO suspend", hcidev->name);
hci_suspend_dev(hcidev);
skb_queue_purge(&priv->adapter->tx_queue);
if (priv->adapter->hs_state != HS_ACTIVATED) { if (priv->adapter->hs_state != HS_ACTIVATED) {
if (btmrvl_enable_hs(priv)) { if (btmrvl_enable_hs(priv)) {
...@@ -1176,10 +1180,6 @@ static int btmrvl_sdio_suspend(struct device *dev) ...@@ -1176,10 +1180,6 @@ static int btmrvl_sdio_suspend(struct device *dev)
return -EBUSY; return -EBUSY;
} }
} }
hcidev = priv->btmrvl_dev.hcidev;
BT_DBG("%s: SDIO suspend", hcidev->name);
hci_suspend_dev(hcidev);
skb_queue_purge(&priv->adapter->tx_queue);
priv->adapter->is_suspended = true; priv->adapter->is_suspended = true;
...@@ -1221,13 +1221,13 @@ static int btmrvl_sdio_resume(struct device *dev) ...@@ -1221,13 +1221,13 @@ static int btmrvl_sdio_resume(struct device *dev)
return 0; return 0;
} }
priv->adapter->is_suspended = false;
hcidev = priv->btmrvl_dev.hcidev;
BT_DBG("%s: SDIO resume", hcidev->name);
hci_resume_dev(hcidev);
priv->hw_wakeup_firmware(priv); priv->hw_wakeup_firmware(priv);
priv->adapter->hs_state = HS_DEACTIVATED; priv->adapter->hs_state = HS_DEACTIVATED;
hcidev = priv->btmrvl_dev.hcidev;
BT_DBG("%s: HS DEACTIVATED in resume!", hcidev->name); BT_DBG("%s: HS DEACTIVATED in resume!", hcidev->name);
priv->adapter->is_suspended = false;
BT_DBG("%s: SDIO resume", hcidev->name);
hci_resume_dev(hcidev);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment