aboutsummaryrefslogtreecommitdiff
path: root/drivers/bluetooth/btmrvl_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/bluetooth/btmrvl_main.c')
-rw-r--r--drivers/bluetooth/btmrvl_main.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c
index 1e0320af00c6..49d20989b45a 100644
--- a/drivers/bluetooth/btmrvl_main.c
+++ b/drivers/bluetooth/btmrvl_main.c
@@ -112,6 +112,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
adapter->hs_state = HS_ACTIVATED;
if (adapter->psmode)
adapter->ps_state = PS_SLEEP;
+ wake_up_interruptible(&adapter->event_hs_wait_q);
BT_DBG("HS ACTIVATED!");
} else {
BT_DBG("HS Enable failed");
@@ -251,11 +252,31 @@ EXPORT_SYMBOL_GPL(btmrvl_enable_ps);
int btmrvl_enable_hs(struct btmrvl_private *priv)
{
+ struct btmrvl_adapter *adapter = priv->adapter;
int ret;
ret = btmrvl_send_sync_cmd(priv, BT_CMD_HOST_SLEEP_ENABLE, NULL, 0);
- if (ret)
+ if (ret) {
BT_ERR("Host sleep enable command failed\n");
+ return ret;
+ }
+
+ ret = wait_event_interruptible_timeout(adapter->event_hs_wait_q,
+ adapter->hs_state,
+ msecs_to_jiffies(WAIT_UNTIL_HS_STATE_CHANGED));
+ if (ret < 0) {
+ BT_ERR("event_hs_wait_q terminated (%d): %d,%d,%d",
+ ret, adapter->hs_state, adapter->ps_state,
+ adapter->wakeup_tries);
+ } else if (!ret) {
+ BT_ERR("hs_enable timeout: %d,%d,%d", adapter->hs_state,
+ adapter->ps_state, adapter->wakeup_tries);
+ ret = -ETIMEDOUT;
+ } else {
+ BT_DBG("host sleep enabled: %d,%d,%d", adapter->hs_state,
+ adapter->ps_state, adapter->wakeup_tries);
+ ret = 0;
+ }
return ret;
}
@@ -341,6 +362,7 @@ static void btmrvl_init_adapter(struct btmrvl_private *priv)
priv->adapter->ps_state = PS_AWAKE;
init_waitqueue_head(&priv->adapter->cmd_wait_q);
+ init_waitqueue_head(&priv->adapter->event_hs_wait_q);
}
static void btmrvl_free_adapter(struct btmrvl_private *priv)
@@ -648,6 +670,7 @@ int btmrvl_remove_card(struct btmrvl_private *priv)
hdev = priv->btmrvl_dev.hcidev;
wake_up_interruptible(&priv->adapter->cmd_wait_q);
+ wake_up_interruptible(&priv->adapter->event_hs_wait_q);
kthread_stop(priv->main_thread.task);