From: Sean Wang sean.wang@mediatek.com
stable inclusion from stable-v5.10.150 commit ea1b6b54098ce4e6203d806c1f5a526db6e42f68 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I6D0XA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
[ Upstream commit fd3f106677bac70437dc12e76c827294ed495a44 ]
WMT cmd/event doesn't follow up the generic HCI cmd/event handling, it needs constantly polling control pipe until the host received the WMT event, thus, we should require to specifically acquire PM counter on the USB to prevent the interface from entering auto suspended while WMT cmd/event in progress.
Fixes: a1c49c434e15 ("Bluetooth: btusb: Add protocol support for MediaTek MT7668U USB devices") Co-developed-by: Jing Cai jing.cai@mediatek.com Signed-off-by: Jing Cai jing.cai@mediatek.com Signed-off-by: Sean Wang sean.wang@mediatek.com Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Jialin Zhang zhangjialin11@huawei.com --- drivers/bluetooth/btusb.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 80a3d5019950..6efd981979bd 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -3033,15 +3033,29 @@ static int btusb_mtk_hci_wmt_sync(struct hci_dev *hdev,
set_bit(BTUSB_TX_WAIT_VND_EVT, &data->flags);
+ /* WMT cmd/event doesn't follow up the generic HCI cmd/event handling, + * it needs constantly polling control pipe until the host received the + * WMT event, thus, we should require to specifically acquire PM counter + * on the USB to prevent the interface from entering auto suspended + * while WMT cmd/event in progress. + */ + err = usb_autopm_get_interface(data->intf); + if (err < 0) + goto err_free_wc; + err = __hci_cmd_send(hdev, 0xfc6f, hlen, wc);
if (err < 0) { clear_bit(BTUSB_TX_WAIT_VND_EVT, &data->flags); + usb_autopm_put_interface(data->intf); goto err_free_wc; }
/* Submit control IN URB on demand to process the WMT event */ err = btusb_mtk_submit_wmt_recv_urb(hdev); + + usb_autopm_put_interface(data->intf); + if (err < 0) return err;