aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2018-03-14 18:06:02 -0400
committerMarcel Holtmann <marcel@holtmann.org>2018-03-15 14:39:37 -0400
commitb09c61522c81886c34966825f9e5afcbfafac446 (patch)
tree00ad270695e9864c8d7eab63daed2b1bda513674
parentf44cb4b19ed40b655c2d422c9021ab2c2625adb6 (diff)
Revert "Bluetooth: hci_bcm: Streamline runtime PM code"
This reverts commit 43fff7683468 ("Bluetooth: hci_bcm: Streamline runtime PM code"). The commit msg for this commit states "No functional change intended.", but replacing: pm_runtime_get(); pm_runtime_mark_last_busy(); pm_runtime_put_autosuspend(); with: pm_request_resume(); Does result in a functional change, pm_request_resume() only calls pm_runtime_mark_last_busy() if the device was suspended before the call. This results in the following happening: 1) Device is runtime suspended 2) Device drives host_wake IRQ logically high as it starts receiving data 3) bcm_host_wake() gets called, causes the device to runtime-resume, current time gets marked as last_busy time 4) After 5 seconds the autosuspend timer expires and the dev autosuspends as no one has been calling pm_runtime_mark_last_busy(), the device was resumed during those 5 seconds, so all the pm_request_resume() calls while receiving data and/or bcm_host_wake() calls were nops 5) If 4) happens while the device has (just received) data in its buffer to be read by the host the IRQ line is *already* / still logically high when we autosuspend and since we use an edge triggered IRQ, the IRQ will never trigger, causing the device to get stuck in suspend Therefor this commit has to be reverted, so that we avoid the device getting stuck in suspend. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Acked-by: Lukas Wunner <lukas@wunner.de> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r--drivers/bluetooth/hci_bcm.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c
index 6314dfb02969..af5658121601 100644
--- a/drivers/bluetooth/hci_bcm.c
+++ b/drivers/bluetooth/hci_bcm.c
@@ -244,7 +244,9 @@ static irqreturn_t bcm_host_wake(int irq, void *data)
244 244
245 bt_dev_dbg(bdev, "Host wake IRQ"); 245 bt_dev_dbg(bdev, "Host wake IRQ");
246 246
247 pm_request_resume(bdev->dev); 247 pm_runtime_get(bdev->dev);
248 pm_runtime_mark_last_busy(bdev->dev);
249 pm_runtime_put_autosuspend(bdev->dev);
248 250
249 return IRQ_HANDLED; 251 return IRQ_HANDLED;
250} 252}
@@ -586,8 +588,11 @@ static int bcm_recv(struct hci_uart *hu, const void *data, int count)
586 } else if (!bcm->rx_skb) { 588 } else if (!bcm->rx_skb) {
587 /* Delay auto-suspend when receiving completed packet */ 589 /* Delay auto-suspend when receiving completed packet */
588 mutex_lock(&bcm_device_lock); 590 mutex_lock(&bcm_device_lock);
589 if (bcm->dev && bcm_device_exists(bcm->dev)) 591 if (bcm->dev && bcm_device_exists(bcm->dev)) {
590 pm_request_resume(bcm->dev->dev); 592 pm_runtime_get(bcm->dev->dev);
593 pm_runtime_mark_last_busy(bcm->dev->dev);
594 pm_runtime_put_autosuspend(bcm->dev->dev);
595 }
591 mutex_unlock(&bcm_device_lock); 596 mutex_unlock(&bcm_device_lock);
592 } 597 }
593 598