summaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth
diff options
context:
space:
mode:
authorChin-Ran Lo <crlo@marvell.com>2014-07-15 06:05:37 +0200
committerMarcel Holtmann <marcel@holtmann.org>2014-07-15 08:01:19 +0200
commit5bf8a7481d21a669dd9dd874c00f7815a878111a (patch)
tree7ed1828deea12066a24ed7516bf9509351c5a182 /drivers/bluetooth
parentBluetooth: cmtp: Remove unnecessary null test (diff)
downloadlinux-5bf8a7481d21a669dd9dd874c00f7815a878111a.tar.xz
linux-5bf8a7481d21a669dd9dd874c00f7815a878111a.zip
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: Chin-Ran Lo <crlo@marvell.com> Signed-off-by: Bing Zhao <bzhao@marvell.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r--drivers/bluetooth/btmrvl_sdio.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c
index efff06438b02..3e683b153259 100644
--- a/drivers/bluetooth/btmrvl_sdio.c
+++ b/drivers/bluetooth/btmrvl_sdio.c
@@ -1169,6 +1169,10 @@ static int btmrvl_sdio_suspend(struct device *dev)
}
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 (btmrvl_enable_hs(priv)) {
@@ -1176,10 +1180,6 @@ static int btmrvl_sdio_suspend(struct device *dev)
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;
@@ -1221,13 +1221,13 @@ static int btmrvl_sdio_resume(struct device *dev)
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->adapter->hs_state = HS_DEACTIVATED;
+ hcidev = priv->btmrvl_dev.hcidev;
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;
}