[PATCH v2 1/2] Bluetooth: btusb: mediatek: Fix leaked runtime PM reference in reset

Luiz Augusto von Dentz luiz.dentz at gmail.com
Wed Aug 19 09:35:38 PDT 2026


Hi Jiajia,

On Wed, Aug 19, 2026 at 5:52 AM Jiajia Liu <liujiajia at kylinos.cn> wrote:
>
> MT7925 on HP Pro Mini 260 sometimes timed out during reloading driver
> and reset usb device. btusb_suspend is not called again after closing
> bluetooth interface.
>
>  usbcore: registered new interface driver btusb
>  Bluetooth: hci0: HW/SW Version: 0x00000000, Build Time: 20260605184935
>  Bluetooth: hci0: Execution of wmt command timed out
>  Bluetooth: hci0: Failed to send wmt patch dwnld (-110)
>  Bluetooth: hci0: Failed to set up firmware (-110)
>  usb 3-10: reset high-speed USB device number 4 using xhci_hcd
>  Bluetooth: hci0: HW/SW Version: 0x00000000, Build Time: 20260605184935
>  Bluetooth: hci0: Device setup in 1856545 usecs
>  Bluetooth: hci0: AOSP extensions version v1.00
>  Bluetooth: hci0: AOSP quality report is supported
>  Bluetooth: MGMT ver 1.23
>
> btusb_mtk_reset calls usb_autopm_get_interface to resume the device
> before driving the hardware reset, but never calls the matching
> usb_autopm_put_interface. Every hardware reset therefore leaks a PM
> usage reference of the interface, preventing the device from being
> runtime suspended again until it is unbound.
>
> Add BTUSB_USB_RESET_ACTIVE flag and set it before usb_queue_reset_device.
> Release the PM reference in btusb_disconnect if this flag is set.
>
> Fixes: 25b6d7593a3a ("Bluetooth: btmtk: introduce btmtk reset work")
> Assisted-by: Claude:qwen3.8-max
> Signed-off-by: Jiajia Liu <liujiajia at kylinos.cn>
> ---
>
> Changes in v2:
> - Fix the race window (sashiko)
>   Add and set BTUSB_USB_RESET_ACTIVE flag before usb_queue_reset_device.
>   Release PM reference in btusb_disconnect if this flag is set.
>
> Changes in v1:
> - add usb_autopm_put_interface after usb_queue_reset_device
>
> ---
>  drivers/bluetooth/btusb.c | 5 +++++
>  1 file changed, 5 insertions(+)
>
> diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
> index 184e95c1625e..45a726bed0dd 100644
> --- a/drivers/bluetooth/btusb.c
> +++ b/drivers/bluetooth/btusb.c
> @@ -957,6 +957,7 @@ struct qca_dump_info {
>  #define BTUSB_USE_ALT3_FOR_WBS 15
>  #define BTUSB_ALT6_CONTINUOUS_TX       16
>  #define BTUSB_HW_SSR_ACTIVE    17
> +#define BTUSB_USB_RESET_ACTIVE 18
>
>  struct btusb_data {
>         struct hci_dev       *hdev;
> @@ -2915,6 +2916,7 @@ static int btusb_mtk_reset(struct hci_dev *hdev, void *rst_data)
>
>         err = btmtk_usb_subsys_reset(hdev, btmtk_data->dev_id);
>
> +       set_bit(BTUSB_USB_RESET_ACTIVE, &data->flags);
>         usb_queue_reset_device(data->intf);
>         clear_bit(BTMTK_HW_RESET_ACTIVE, &btmtk_data->flags);
>
> @@ -4497,6 +4499,9 @@ static void btusb_disconnect(struct usb_interface *intf)
>         if (data->reset_gpio)
>                 gpiod_put(data->reset_gpio);
>
> +       if (test_bit(BTUSB_USB_RESET_ACTIVE, &data->flags))
> +               usb_autopm_put_interface_no_suspend(data->intf);

Should this be test_and_clear_bit rather then just test_bit, otherwise
it doesn't seem to be ever cleared? Sashiko also complains about the
handling of multiple resets (is that really possible though?):

https://sashiko.dev/#/patchset/ec23dae6c247005e8eccd312d326a626163ea491.1787132512.git.liujiajia%40kylinos.cn

Or perhaps we should check if BTUSB_USB_RESET_ACTIVE (Id rename it to
just BTUSB_RESET) and then don't queue a second time which perhaps is
what sashiko is talking about when it refers to reference.

>         if (intf == data->intf) {
>                 if (data->isoc)
>                         usb_driver_release_interface(&btusb_driver, data->isoc);
> --
> 2.55.0
>


-- 
Luiz Augusto von Dentz



More information about the Linux-mediatek mailing list