diff options
| author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2024-10-14 08:03:44 +0200 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2024-10-14 08:03:44 +0200 |
| commit | 64f3b5a6bc49adf77d58eddd72a4bfccd492fa24 (patch) | |
| tree | cdd6aa7a0d21482ae4d1e76d837f3712c8c6481d /drivers/bluetooth/btusb.c | |
| parent | USB: chaoskey: Fix possible deadlock chaoskey_list_lock (diff) | |
| parent | Linux 6.12-rc3 (diff) | |
| download | linux-64f3b5a6bc49adf77d58eddd72a4bfccd492fa24.tar.gz linux-64f3b5a6bc49adf77d58eddd72a4bfccd492fa24.zip | |
Merge 6.12-rc3 into usb-next
We need the USB fixes in here as well.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/bluetooth/btusb.c')
| -rw-r--r-- | drivers/bluetooth/btusb.c | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 6c9c761d5b93..a3e45b3060d1 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -17,7 +17,7 @@ #include <linux/suspend.h> #include <linux/gpio/consumer.h> #include <linux/debugfs.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> @@ -4038,16 +4038,29 @@ static void btusb_disconnect(struct usb_interface *intf) static int btusb_suspend(struct usb_interface *intf, pm_message_t message) { struct btusb_data *data = usb_get_intfdata(intf); + int err; BT_DBG("intf %p", intf); - /* Don't suspend if there are connections */ - if (hci_conn_count(data->hdev)) + /* Don't auto-suspend if there are connections; external suspend calls + * shall never fail. + */ + if (PMSG_IS_AUTO(message) && hci_conn_count(data->hdev)) return -EBUSY; if (data->suspend_count++) return 0; + /* Notify Host stack to suspend; this has to be done before stopping + * the traffic since the hci_suspend_dev itself may generate some + * traffic. + */ + err = hci_suspend_dev(data->hdev); + if (err) { + data->suspend_count--; + return err; + } + spin_lock_irq(&data->txlock); if (!(PMSG_IS_AUTO(message) && data->tx_in_flight)) { set_bit(BTUSB_SUSPENDING, &data->flags); @@ -4055,6 +4068,7 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message) } else { spin_unlock_irq(&data->txlock); data->suspend_count--; + hci_resume_dev(data->hdev); return -EBUSY; } @@ -4175,6 +4189,8 @@ static int btusb_resume(struct usb_interface *intf) spin_unlock_irq(&data->txlock); schedule_work(&data->work); + hci_resume_dev(data->hdev); + return 0; failed: |
