Commit b09c6152 authored by Hans de Goede's avatar Hans de Goede Committed by Marcel Holtmann

Revert "Bluetooth: hci_bcm: Streamline runtime PM code"

This reverts commit 43fff768 ("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: default avatarHans de Goede <hdegoede@redhat.com>
Acked-by: default avatarLukas Wunner <lukas@wunner.de>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent f44cb4b1
...@@ -244,7 +244,9 @@ static irqreturn_t bcm_host_wake(int irq, void *data) ...@@ -244,7 +244,9 @@ static irqreturn_t bcm_host_wake(int irq, void *data)
bt_dev_dbg(bdev, "Host wake IRQ"); bt_dev_dbg(bdev, "Host wake IRQ");
pm_request_resume(bdev->dev); pm_runtime_get(bdev->dev);
pm_runtime_mark_last_busy(bdev->dev);
pm_runtime_put_autosuspend(bdev->dev);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -586,8 +588,11 @@ static int bcm_recv(struct hci_uart *hu, const void *data, int count) ...@@ -586,8 +588,11 @@ static int bcm_recv(struct hci_uart *hu, const void *data, int count)
} else if (!bcm->rx_skb) { } else if (!bcm->rx_skb) {
/* Delay auto-suspend when receiving completed packet */ /* Delay auto-suspend when receiving completed packet */
mutex_lock(&bcm_device_lock); mutex_lock(&bcm_device_lock);
if (bcm->dev && bcm_device_exists(bcm->dev)) if (bcm->dev && bcm_device_exists(bcm->dev)) {
pm_request_resume(bcm->dev->dev); pm_runtime_get(bcm->dev->dev);
pm_runtime_mark_last_busy(bcm->dev->dev);
pm_runtime_put_autosuspend(bcm->dev->dev);
}
mutex_unlock(&bcm_device_lock); mutex_unlock(&bcm_device_lock);
} }
......
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