* [PATCH v2] Bluetooth: Properly disable remote wakeup for MT7922/MT7925 on Ryzen platform
@ 2026-07-01 15:43 Rong Zhang
2026-07-06 14:53 ` Rafael Passos
2026-07-13 15:06 ` John Rowley
0 siblings, 2 replies; 7+ messages in thread
From: Rong Zhang @ 2026-07-01 15:43 UTC (permalink / raw)
To: Marcel Holtmann, Luiz Augusto von Dentz, Matthias Brugger,
AngeloGioacchino Del Regno
Cc: Luiz Augusto von Dentz, Chris Lu (陸稚泓),
Will-CY Lee (李政穎),
SS Wu (巫憲欣), linux-bluetooth, linux-kernel,
linux-arm-kernel, linux-mediatek, Rong Zhang
It is reported that a remote wakeup could cause MT7922/MT7925's btusb
interface completely unresponsive. Resetting the xHCI root hub doesn't
help at all, and recovering from such a state needs a power cycle.
All reports seen to be relevant to Ryzen-based laptops. These NICs are
usually used as OEM components thanks to some sort of reference designs.
Their popularity on other platforms is unclear. While there is still a
chance that the quirk may exist on other platforms, be cautious and only
apply the quirk to direct children of Ryzen platforms's root hubs for
the time being. In most cases the root hub is on the SoC or PCH, which
needs the quirk. Unfortunately, this can't distinguish root hubs on PCIe
add-in cards. Such roughness should be acceptable, as PCIe USB
controller add-in cards are less commonly used nowadays. On the other
hand, applying the quirk doesn't hurt any functionalities either, as the
device can still be used as a wakeup source if desired. Theoretically,
we could retrieve the root hub's PCI vendor ID with some hierarchy
magic, but that's too intrusive...
Meanwhile, though device_set_wakeup_capable(false) is the correct fix
for other NICs with fake remote wakeup capabilities, doing so for
MT7922/MT7925 effectively prevents it from being used as wakeup
sources as per userspace requests. Hence, return -EBUSY on runtime
suspend to prevent the interface from being autosuspended while it's
still opened, which has the same effect as
device_set_wakeup_capable(false), since disabling remote wakeup simply
causes the USB core to gate runtime autosuspend as well due to
needs_remote_wakeup == 1. The interface can be safely autosuspended as
long as remote wakeup is disabled, i.e., after closing the HCI device.
Specifically, the interface may still take the advantage of remote
wakeup in order to wake up the system from sleep if userspace has
enabled it as a wakeup source.
Fixes: e31d761628ad ("Bluetooth: btmtk: Disable remote wakeup for MT7922/MT7925")
Signed-off-by: Rong Zhang <i@rong.moe>
---
Changes in v2:
- Only apply the quirk to to direct children of Ryzen platforms's root
hubs
- Theoretically, we could retrieve the root hub's PCI vendor ID with
some hierarchy magic to further limit the range down to only root
hubs on the SoC or PCH, but that's too intrusive -- the hierarchy
magic really made me nervous once I saw what I have wrote, so I gave
it up
- Link to v1: https://patch.msgid.link/20260629-btmtk-ryzen-remote-wakeup-v1-1-1d2f1cee6d22@rong.moe
---
drivers/bluetooth/btmtk.c | 10 -------
drivers/bluetooth/btusb.c | 73 ++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 69 insertions(+), 14 deletions(-)
diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
index 02a96342e964..4614434dd57b 100644
--- a/drivers/bluetooth/btmtk.c
+++ b/drivers/bluetooth/btmtk.c
@@ -1381,16 +1381,6 @@ int btmtk_usb_setup(struct hci_dev *hdev)
break;
case 0x7922:
case 0x7925:
- /*
- * A remote wakeup could cause the device completely unresponsive, and
- * recovering from such a state needs a power cycle.
- *
- * Since the remote wakeup capability is super broken, just disable it
- * to get rid of the troubles. The device can still be autosuspended
- * when the bluetooth interface is closed.
- */
- device_set_wakeup_capable(&btmtk_data->udev->dev, false);
- fallthrough;
case 0x7961:
case 0x7902:
case 0x6639:
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 08c0a99a62c5..eef6e3b43bf9 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -6,6 +6,7 @@
* Copyright (C) 2005-2008 Marcel Holtmann <marcel@holtmann.org>
*/
+#include <linux/cpufeature.h>
#include <linux/dmi.h>
#include <linux/module.h>
#include <linux/usb.h>
@@ -957,6 +958,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_WAKEUP_BROKEN 18
struct btusb_data {
struct hci_dev *hdev;
@@ -2936,10 +2938,25 @@ static int btusb_send_frame_mtk(struct hci_dev *hdev, struct sk_buff *skb)
}
}
+static inline bool platform_is_ryzen(void)
+{
+#ifdef CONFIG_X86
+ return boot_cpu_has(X86_FEATURE_ZEN);
+#else
+ return false;
+#endif
+}
+
+static inline bool is_direct_child_of_root_hub(struct usb_device *udev)
+{
+ return udev->parent == udev->bus->root_hub;
+}
+
static int btusb_mtk_setup(struct hci_dev *hdev)
{
struct btusb_data *data = hci_get_drvdata(hdev);
struct btmtk_data *btmtk_data = hci_get_priv(hdev);
+ int err;
/* MediaTek WMT vendor cmd requiring below USB resources to
* complete the handshake.
@@ -2956,7 +2973,40 @@ static int btusb_mtk_setup(struct hci_dev *hdev)
btusb_mtk_claim_iso_intf(data);
}
- return btmtk_usb_setup(hdev);
+ err = btmtk_usb_setup(hdev);
+ if (err)
+ return err;
+
+ switch (btmtk_data->dev_id) {
+ case 0x7922:
+ case 0x7925:
+ /*
+ * All reports seen to be relevant to Ryzen-based laptops. These
+ * NICs are usually used as OEM components thanks to some sort
+ * of reference designs.
+ *
+ * Their popularity on other platforms is unclear. While there
+ * is still a chance that the quirk may exist on other
+ * platforms, be cautious and only apply the quirk to direct
+ * children of Ryzen platforms's root hubs for the time being.
+ *
+ * In most cases the root hub is on the SoC or PCH, which needs
+ * the quirk. Unfortunately, this can't distinguish root hubs on
+ * PCIe add-in cards. Such roughness should be acceptable, as
+ * PCIe USB controller add-in cards are less commonly used
+ * nowadays. On the other hand, applying the quirk doesn't hurt
+ * any functionalities either, as the device can still be used
+ * as a wakeup source if desired.
+ *
+ * Theoretically, we could retrieve the root hub's PCI vendor ID
+ * with some hierarchy magic, but that's too intrusive...
+ */
+ if (platform_is_ryzen() && is_direct_child_of_root_hub(data->udev))
+ set_bit(BTUSB_WAKEUP_BROKEN, &data->flags);
+ break;
+ }
+
+ return 0;
}
static int btusb_mtk_shutdown(struct hci_dev *hdev)
@@ -4532,11 +4582,26 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
BT_DBG("intf %p", intf);
- /* Don't auto-suspend if there are connections or discovery in
- * progress; external suspend calls shall never fail.
+ /*
+ * It is reported that remote wakeup events could sometimes cause some
+ * adapters completely unresponsive. Resetting the xHCI root hub doesn't
+ * help at all, and recovering from such a state needs a power cycle.
+ * Since disabling remote wakeup simply causes the USB core to gate
+ * runtime autosuspend as well due to needs_remote_wakeup == 1, let's do
+ * this ourselves to make our life easier. The interface can be safely
+ * autosuspended as long as remote wakeup is disabled, i.e., after
+ * closing the HCI device.
+ *
+ * Don't auto-suspend if there are connections or discovery in progress.
+ *
+ * External suspend calls shall never fail. Specifically, a device with
+ * broken remote wakeup may still take the advantage of remote wakeup in
+ * order to wake up the system from sleep if userspace has enabled it as
+ * a wakeup source.
*/
if (PMSG_IS_AUTO(message) &&
- (hci_conn_count(data->hdev) || hci_discovery_active(data->hdev)))
+ ((test_bit(BTUSB_WAKEUP_BROKEN, &data->flags) && data->intf->needs_remote_wakeup) ||
+ hci_conn_count(data->hdev) || hci_discovery_active(data->hdev)))
return -EBUSY;
if (data->suspend_count++)
---
base-commit: dc59e4fea9d83f03bad6bddf3fa2e52491777482
change-id: 230ba8c9-btmtk-ryzen-remote-wakeup-055a407682ef
Thanks,
Rong
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH v2] Bluetooth: Properly disable remote wakeup for MT7922/MT7925 on Ryzen platform 2026-07-01 15:43 [PATCH v2] Bluetooth: Properly disable remote wakeup for MT7922/MT7925 on Ryzen platform Rong Zhang @ 2026-07-06 14:53 ` Rafael Passos 2026-07-06 15:08 ` Rong Zhang 2026-07-13 15:06 ` John Rowley 1 sibling, 1 reply; 7+ messages in thread From: Rafael Passos @ 2026-07-06 14:53 UTC (permalink / raw) To: Rong Zhang, Marcel Holtmann, Luiz Augusto von Dentz, Matthias Brugger, AngeloGioacchino Del Regno Cc: Luiz Augusto von Dentz, Chris Lu (陸稚泓), Will-CY Lee (李政穎), SS Wu (巫憲欣), linux-bluetooth, linux-kernel, linux-arm-kernel, linux-mediatek I was having issues with Bluetooth on the ASRock B850M with MT7925. I tested this and other patches in my investigation process. My issue was a platform bug causing a failure in USB enumeration before the driver path (unrelated to the patch). I can confirm this patch does not introduce regressions on this platform. I tested system power cycling and suspension, and also BT/Wifi adapter enable/disable. Patch applied on top of mailine (7.2 rc1). Tested-by: Rafael Passos <rafael@rcpassos.me> Thanks, Rafael Passos ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] Bluetooth: Properly disable remote wakeup for MT7922/MT7925 on Ryzen platform 2026-07-06 14:53 ` Rafael Passos @ 2026-07-06 15:08 ` Rong Zhang 2026-07-06 18:21 ` Rafael Passos 0 siblings, 1 reply; 7+ messages in thread From: Rong Zhang @ 2026-07-06 15:08 UTC (permalink / raw) To: Rafael Passos, Marcel Holtmann, Luiz Augusto von Dentz, Matthias Brugger, AngeloGioacchino Del Regno Cc: Luiz Augusto von Dentz, Chris Lu (陸稚泓), Will-CY Lee (李政穎), SS Wu (巫憲欣), linux-bluetooth, linux-kernel, linux-arm-kernel, linux-mediatek Hi Rafael, 于 2026年7月6日 GMT+08:00 22:53:17,Rafael Passos <rafael@rcpassos.me> 写道: >I was having issues with Bluetooth on the ASRock B850M with MT7925. >I tested this and other patches in my investigation process. >My issue was a platform bug causing a failure in USB enumeration >before the driver path (unrelated to the patch). > >I can confirm this patch does not introduce regressions on this platform. >I tested system power cycling and suspension, >and also BT/Wifi adapter enable/disable. >Patch applied on top of mailine (7.2 rc1). > >Tested-by: Rafael Passos <rafael@rcpassos.me> Thanks a lot for your testing! Your issue sounds related to the remote wakeup issue I am addressing. After triggering the remote wakeup bug, rebooting the platform without a power cycle [1] always causes a failure in USB enumeration before the driver path. [1]: power off, unplug AC, wait for a while, plug AC, power on. Thanks, Rong > >Thanks, >Rafael Passos ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] Bluetooth: Properly disable remote wakeup for MT7922/MT7925 on Ryzen platform 2026-07-06 15:08 ` Rong Zhang @ 2026-07-06 18:21 ` Rafael Passos 2026-07-06 19:39 ` Rong Zhang 0 siblings, 1 reply; 7+ messages in thread From: Rafael Passos @ 2026-07-06 18:21 UTC (permalink / raw) To: Rong Zhang, Rafael Passos, Marcel Holtmann, Luiz Augusto von Dentz, Matthias Brugger, AngeloGioacchino Del Regno Cc: Luiz Augusto von Dentz, Chris Lu (陸稚泓), Will-CY Lee (李政穎), SS Wu (巫憲欣), linux-bluetooth, linux-kernel, linux-arm-kernel, linux-mediatek On Mon Jul 6, 2026 at 12:08 PM -03, Rong Zhang wrote: > Hi Rafael, > > 于 2026年7月6日 GMT+08:00 22:53:17,Rafael Passos <rafael@rcpassos.me> 写道: >>Tested-by: Rafael Passos <rafael@rcpassos.me> > > Thanks a lot for your testing! > > Your issue sounds related to the remote wakeup issue I am addressing. After triggering the remote wakeup bug, rebooting the platform without a power cycle [1] always causes a failure in USB enumeration before the driver path. In my case, just the power cycle was not sufficient. I had to also change settings in BIOS [1], and only then it came back. Even after reverting all settings to the same state as before. I was hoping to fix this in Kernel, but I don't see a way forward. If you have any other ideas or patches to test, send them my way! I will gladly help. [1] I turned off sr-iov, resize-bar & disabled "Bluetooth On/Off". In a previous attempt, fast-boot and TPM were also disabled. Thanks, Rafael Passos ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] Bluetooth: Properly disable remote wakeup for MT7922/MT7925 on Ryzen platform 2026-07-06 18:21 ` Rafael Passos @ 2026-07-06 19:39 ` Rong Zhang 0 siblings, 0 replies; 7+ messages in thread From: Rong Zhang @ 2026-07-06 19:39 UTC (permalink / raw) To: Rafael Passos, Marcel Holtmann, Luiz Augusto von Dentz, Matthias Brugger, AngeloGioacchino Del Regno Cc: Luiz Augusto von Dentz, Chris Lu (陸稚泓), Will-CY Lee (李政穎), SS Wu (巫憲欣), linux-bluetooth, linux-kernel, linux-arm-kernel, linux-mediatek Hi Rafael, 于 2026年7月7日 GMT+08:00 02:21:57,Rafael Passos <rafael@rcpassos.me> 写道: >On Mon Jul 6, 2026 at 12:08 PM -03, Rong Zhang wrote: >> Hi Rafael, >> >> 于 2026年7月6日 GMT+08:00 22:53:17,Rafael Passos <rafael@rcpassos.me> 写道: >>>Tested-by: Rafael Passos <rafael@rcpassos.me> >> >> Thanks a lot for your testing! >> >> Your issue sounds related to the remote wakeup issue I am addressing. After triggering the remote wakeup bug, rebooting the platform without a power cycle [1] always causes a failure in USB enumeration before the driver path. > >In my case, just the power cycle was not sufficient. I had to also >change settings in BIOS [1], and only then it came back. >Even after reverting all settings to the same state as before. > >I was hoping to fix this in Kernel, but I don't see a way forward. >If you have any other ideas or patches to test, send them my way! >I will gladly help. > >[1] I turned off sr-iov, resize-bar & disabled "Bluetooth On/Off". >In a previous attempt, fast-boot and TPM were also disabled. Hmm, interesting. My speculation is that it doesn't matter which options are changed, but some changed options cause the BIOS to reinitialize something. Does resetting the BIOS settings to default help? Could you provide more details about your device's USB and PCI topology? Does the NIC's USB connect to one of the USB root hubs of the SoC (i.e., CPU) or the chipset? And I guess your device runs into the issue without any precursor? Once boot, try running the script below to capture more clues into dmesg, and wait for the issue to appear. #!/bin/sh ddcmd() { echo "$*" | sudo tee /proc/dynamic_debug/control; } ddcmd file drivers/usb/core/hub.c +p ddcmd file drivers/usb/core/driver.c +p ddcmd func handle_tx_event +p I would do the below experiments if I had a buggy device like that. Some extra hardware is required though. Connect another NIC (w/ Bluetooth interface) to the same M.2 port after triggering the enumeration failure, and see if the enumeration failure persists. Connect a passive M.2 (A+E key) to USB2.0 adapter card to the same M.2 port after triggering the enumeration failure, connect a USB2.0 device to the adapter card, and see if the enumeration failure persists. Connect the MTK NIC to a PCIe port using a passive PCIe to M.2 (A/E key) adapter card, such a card usually routes the USB signal from the M.2 interface to a 9-pin cable. Connect the 9-pin connector to the motherboard's USB expansion port, and try triggering the enumeration failure. Now connect the 9-pin connector to a dedicated PCIe USB controller card, and see if the enumeration failure persists. All mentioned extra hardware is cheap and easy to get in China. Though I guess it would be a completely different story in some other regions... Trying one of these experiments should be sufficient, so you can make your decision based on hardware availability. Thanks, Rong > >Thanks, >Rafael Passos ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] Bluetooth: Properly disable remote wakeup for MT7922/MT7925 on Ryzen platform 2026-07-01 15:43 [PATCH v2] Bluetooth: Properly disable remote wakeup for MT7922/MT7925 on Ryzen platform Rong Zhang 2026-07-06 14:53 ` Rafael Passos @ 2026-07-13 15:06 ` John Rowley 2026-07-13 17:32 ` Rong Zhang 1 sibling, 1 reply; 7+ messages in thread From: John Rowley @ 2026-07-13 15:06 UTC (permalink / raw) To: Rong Zhang Cc: Marcel Holtmann, Luiz Augusto von Dentz, Matthias Brugger, AngeloGioacchino Del Regno, Luiz Augusto von Dentz, Chris Lu (陸稚泓), Will-CY Lee (李政穎), SS Wu (巫憲欣), linux-bluetooth, linux-kernel, linux-arm-kernel, linux-mediatek On Wed, Jul 01, 2026 at 11:43:01PM +0800, Rong Zhang wrote: > It is reported that a remote wakeup could cause MT7922/MT7925's btusb > interface completely unresponsive. Resetting the xHCI root hub doesn't > help at all, and recovering from such a state needs a power cycle. > > All reports seen to be relevant to Ryzen-based laptops. These NICs are > usually used as OEM components thanks to some sort of reference designs. > Their popularity on other platforms is unclear. While there is still a > chance that the quirk may exist on other platforms, be cautious and only > apply the quirk to direct children of Ryzen platforms's root hubs for > the time being. In most cases the root hub is on the SoC or PCH, which > needs the quirk. Unfortunately, this can't distinguish root hubs on PCIe > add-in cards. Such roughness should be acceptable, as PCIe USB > controller add-in cards are less commonly used nowadays. On the other > hand, applying the quirk doesn't hurt any functionalities either, as the > device can still be used as a wakeup source if desired. Theoretically, > we could retrieve the root hub's PCI vendor ID with some hierarchy > magic, but that's too intrusive... > > Meanwhile, though device_set_wakeup_capable(false) is the correct fix > for other NICs with fake remote wakeup capabilities, doing so for > MT7922/MT7925 effectively prevents it from being used as wakeup > sources as per userspace requests. Hence, return -EBUSY on runtime > suspend to prevent the interface from being autosuspended while it's > still opened, which has the same effect as > device_set_wakeup_capable(false), since disabling remote wakeup simply > causes the USB core to gate runtime autosuspend as well due to > needs_remote_wakeup == 1. The interface can be safely autosuspended as > long as remote wakeup is disabled, i.e., after closing the HCI device. > > Specifically, the interface may still take the advantage of remote > wakeup in order to wake up the system from sleep if userspace has > enabled it as a wakeup source. Hi Rong, I'm experiencing xHCI hub freezing issues when bringing my AMD Framework 13 laptop out of suspend mode. Sometimes, the wifi controller will freeze up, and dmesg will show: [ 7238.147897] PM: suspend exit [ 7239.423823] usb 1-4: reset full-speed USB device number 3 using xhci_hcd [ 7239.692328] usb 1-4: reset full-speed USB device number 3 using xhci_hcd ...and so on... Any attempt to access the wireless interface, e.g. `ip addr show`, will hang the system. Only a power cycle fixes it. This has only started since 7.2-rc1. Here's my USB bus tree (1- only): /: Bus 001.Port 001: Dev 001, Class=root_hub, Driver=xhci_hcd/5p, 480M ID 1d6b:0002 Linux Foundation 2.0 root hub |__ Port 001: Dev 002, 12M ID 32ac:0002 |__ Port 004: Dev 003, If 0, Class=Vendor Specific Class, Driver=[none], 12M ID 27c6:609c Shenzhen Goodix Technology Co.,Ltd. |__ Port 005: Dev 004, If 0, Class=Wireless, Driver=[none], 480M ID 0e8d:e616 MediaTek Inc. |__ Port 005: Dev 004, If 1, Class=Wireless, Driver=[none], 480M ID 0e8d:e616 MediaTek Inc. |__ Port 005: Dev 004, If 2, Class=Wireless, Driver=[none], 480M ID 0e8d:e616 MediaTek Inc. Seeing as I have a MT7922 that is providing both wireless and Bluetooth functionality, I'm wondering if I'm hitting this bug also? Perhaps it's my fingerprint reader that's the problem, but your description above sounds very similar to what I'm seeing. I have applied your patch, which I thought had fixed the problem, but I had a freeze again earlier today after resuming my machine fron standby. I keep the bluetooth/btusb/bt* modules blacklisted, but that apparently hasn't made a difference. > > Fixes: e31d761628ad ("Bluetooth: btmtk: Disable remote wakeup for MT7922/MT7925") > Signed-off-by: Rong Zhang <i@rong.moe> > --- > Changes in v2: > - Only apply the quirk to to direct children of Ryzen platforms's root > hubs > - Theoretically, we could retrieve the root hub's PCI vendor ID with > some hierarchy magic to further limit the range down to only root > hubs on the SoC or PCH, but that's too intrusive -- the hierarchy > magic really made me nervous once I saw what I have wrote, so I gave > it up > - Link to v1: https://patch.msgid.link/20260629-btmtk-ryzen-remote-wakeup-v1-1-1d2f1cee6d22@rong.moe > --- > drivers/bluetooth/btmtk.c | 10 ------- > drivers/bluetooth/btusb.c | 73 ++++++++++++++++++++++++++++++++++++++++++++--- > 2 files changed, 69 insertions(+), 14 deletions(-) > > diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c > index 02a96342e964..4614434dd57b 100644 > --- a/drivers/bluetooth/btmtk.c > +++ b/drivers/bluetooth/btmtk.c > @@ -1381,16 +1381,6 @@ int btmtk_usb_setup(struct hci_dev *hdev) > break; > case 0x7922: > case 0x7925: > - /* > - * A remote wakeup could cause the device completely unresponsive, and > - * recovering from such a state needs a power cycle. > - * > - * Since the remote wakeup capability is super broken, just disable it > - * to get rid of the troubles. The device can still be autosuspended > - * when the bluetooth interface is closed. > - */ > - device_set_wakeup_capable(&btmtk_data->udev->dev, false); > - fallthrough; > case 0x7961: > case 0x7902: > case 0x6639: > diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c > index 08c0a99a62c5..eef6e3b43bf9 100644 > --- a/drivers/bluetooth/btusb.c > +++ b/drivers/bluetooth/btusb.c > @@ -6,6 +6,7 @@ > * Copyright (C) 2005-2008 Marcel Holtmann <marcel@holtmann.org> > */ > > +#include <linux/cpufeature.h> > #include <linux/dmi.h> > #include <linux/module.h> > #include <linux/usb.h> > @@ -957,6 +958,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_WAKEUP_BROKEN 18 > > struct btusb_data { > struct hci_dev *hdev; > @@ -2936,10 +2938,25 @@ static int btusb_send_frame_mtk(struct hci_dev *hdev, struct sk_buff *skb) > } > } > > +static inline bool platform_is_ryzen(void) > +{ > +#ifdef CONFIG_X86 > + return boot_cpu_has(X86_FEATURE_ZEN); > +#else > + return false; > +#endif > +} > + > +static inline bool is_direct_child_of_root_hub(struct usb_device *udev) > +{ > + return udev->parent == udev->bus->root_hub; > +} > + > static int btusb_mtk_setup(struct hci_dev *hdev) > { > struct btusb_data *data = hci_get_drvdata(hdev); > struct btmtk_data *btmtk_data = hci_get_priv(hdev); > + int err; > > /* MediaTek WMT vendor cmd requiring below USB resources to > * complete the handshake. > @@ -2956,7 +2973,40 @@ static int btusb_mtk_setup(struct hci_dev *hdev) > btusb_mtk_claim_iso_intf(data); > } > > - return btmtk_usb_setup(hdev); > + err = btmtk_usb_setup(hdev); > + if (err) > + return err; > + > + switch (btmtk_data->dev_id) { > + case 0x7922: > + case 0x7925: > + /* > + * All reports seen to be relevant to Ryzen-based laptops. These > + * NICs are usually used as OEM components thanks to some sort > + * of reference designs. > + * > + * Their popularity on other platforms is unclear. While there > + * is still a chance that the quirk may exist on other > + * platforms, be cautious and only apply the quirk to direct > + * children of Ryzen platforms's root hubs for the time being. > + * > + * In most cases the root hub is on the SoC or PCH, which needs > + * the quirk. Unfortunately, this can't distinguish root hubs on > + * PCIe add-in cards. Such roughness should be acceptable, as > + * PCIe USB controller add-in cards are less commonly used > + * nowadays. On the other hand, applying the quirk doesn't hurt > + * any functionalities either, as the device can still be used > + * as a wakeup source if desired. > + * > + * Theoretically, we could retrieve the root hub's PCI vendor ID > + * with some hierarchy magic, but that's too intrusive... > + */ > + if (platform_is_ryzen() && is_direct_child_of_root_hub(data->udev)) > + set_bit(BTUSB_WAKEUP_BROKEN, &data->flags); > + break; > + } > + > + return 0; > } > > static int btusb_mtk_shutdown(struct hci_dev *hdev) > @@ -4532,11 +4582,26 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message) > > BT_DBG("intf %p", intf); > > - /* Don't auto-suspend if there are connections or discovery in > - * progress; external suspend calls shall never fail. > + /* > + * It is reported that remote wakeup events could sometimes cause some > + * adapters completely unresponsive. Resetting the xHCI root hub doesn't > + * help at all, and recovering from such a state needs a power cycle. > + * Since disabling remote wakeup simply causes the USB core to gate > + * runtime autosuspend as well due to needs_remote_wakeup == 1, let's do > + * this ourselves to make our life easier. The interface can be safely > + * autosuspended as long as remote wakeup is disabled, i.e., after > + * closing the HCI device. > + * > + * Don't auto-suspend if there are connections or discovery in progress. > + * > + * External suspend calls shall never fail. Specifically, a device with > + * broken remote wakeup may still take the advantage of remote wakeup in > + * order to wake up the system from sleep if userspace has enabled it as > + * a wakeup source. > */ > if (PMSG_IS_AUTO(message) && > - (hci_conn_count(data->hdev) || hci_discovery_active(data->hdev))) > + ((test_bit(BTUSB_WAKEUP_BROKEN, &data->flags) && data->intf->needs_remote_wakeup) || > + hci_conn_count(data->hdev) || hci_discovery_active(data->hdev))) > return -EBUSY; > > if (data->suspend_count++) > > --- > base-commit: dc59e4fea9d83f03bad6bddf3fa2e52491777482 > change-id: 230ba8c9-btmtk-ryzen-remote-wakeup-055a407682ef > > Thanks, > Rong > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] Bluetooth: Properly disable remote wakeup for MT7922/MT7925 on Ryzen platform 2026-07-13 15:06 ` John Rowley @ 2026-07-13 17:32 ` Rong Zhang 0 siblings, 0 replies; 7+ messages in thread From: Rong Zhang @ 2026-07-13 17:32 UTC (permalink / raw) To: John Rowley Cc: Marcel Holtmann, Luiz Augusto von Dentz, Matthias Brugger, AngeloGioacchino Del Regno, Luiz Augusto von Dentz, Chris Lu (陸稚泓), Will-CY Lee (李政穎), SS Wu (巫憲欣), linux-bluetooth, linux-kernel, linux-arm-kernel, linux-mediatek Hi John, 于 2026年7月13日 GMT+08:00 23:06:56,John Rowley <hey@johnrowley.me> 写道: >On Wed, Jul 01, 2026 at 11:43:01PM +0800, Rong Zhang wrote: >> It is reported that a remote wakeup could cause MT7922/MT7925's btusb >> interface completely unresponsive. Resetting the xHCI root hub doesn't >> help at all, and recovering from such a state needs a power cycle. >> >> All reports seen to be relevant to Ryzen-based laptops. These NICs are >> usually used as OEM components thanks to some sort of reference designs. >> Their popularity on other platforms is unclear. While there is still a >> chance that the quirk may exist on other platforms, be cautious and only >> apply the quirk to direct children of Ryzen platforms's root hubs for >> the time being. In most cases the root hub is on the SoC or PCH, which >> needs the quirk. Unfortunately, this can't distinguish root hubs on PCIe >> add-in cards. Such roughness should be acceptable, as PCIe USB >> controller add-in cards are less commonly used nowadays. On the other >> hand, applying the quirk doesn't hurt any functionalities either, as the >> device can still be used as a wakeup source if desired. Theoretically, >> we could retrieve the root hub's PCI vendor ID with some hierarchy >> magic, but that's too intrusive... >> >> Meanwhile, though device_set_wakeup_capable(false) is the correct fix >> for other NICs with fake remote wakeup capabilities, doing so for >> MT7922/MT7925 effectively prevents it from being used as wakeup >> sources as per userspace requests. Hence, return -EBUSY on runtime >> suspend to prevent the interface from being autosuspended while it's >> still opened, which has the same effect as >> device_set_wakeup_capable(false), since disabling remote wakeup simply >> causes the USB core to gate runtime autosuspend as well due to >> needs_remote_wakeup == 1. The interface can be safely autosuspended as >> long as remote wakeup is disabled, i.e., after closing the HCI device. >> >> Specifically, the interface may still take the advantage of remote >> wakeup in order to wake up the system from sleep if userspace has >> enabled it as a wakeup source. > >Hi Rong, > >I'm experiencing xHCI hub freezing issues when bringing my AMD Framework >13 laptop out of suspend mode. Sometimes, the wifi controller will >freeze up, and dmesg will show: Hmm, it doesn't seem relevant to the issue here, because... > >[ 7238.147897] PM: suspend exit >[ 7239.423823] usb 1-4: reset full-speed USB device number 3 using xhci_hcd >[ 7239.692328] usb 1-4: reset full-speed USB device number 3 using xhci_hcd >...and so on... ...usb 1-4 means Bus 001 Port 004, which is... > >Any attempt to access the wireless interface, e.g. `ip addr show`, will >hang the system. Only a power cycle fixes it. > >This has only started since 7.2-rc1. Here's my USB bus tree (1- only): > >/: Bus 001.Port 001: Dev 001, Class=root_hub, Driver=xhci_hcd/5p, 480M > ID 1d6b:0002 Linux Foundation 2.0 root hub > |__ Port 001: Dev 002, 12M > ID 32ac:0002 > |__ Port 004: Dev 003, If 0, Class=Vendor Specific Class, Driver=[none], 12M > ID 27c6:609c Shenzhen Goodix Technology Co.,Ltd. ...probably a fingerprint reader module. A USB device reset is not necessarily caused by an xHCI hub failure. It's more commonly caused by the (buggy) device itself. And it's common to see a USB device reset after a USB autoresume. The USB core calls it "reset-resume". Sometimes userspace initiates USB reset via usbfs, so there was also a chance that fprintd initiated it. > |__ Port 005: Dev 004, If 0, Class=Wireless, Driver=[none], 480M > ID 0e8d:e616 MediaTek Inc. > |__ Port 005: Dev 004, If 1, Class=Wireless, Driver=[none], 480M > ID 0e8d:e616 MediaTek Inc. > |__ Port 005: Dev 004, If 2, Class=Wireless, Driver=[none], 480M > ID 0e8d:e616 MediaTek Inc. > >Seeing as I have a MT7922 that is providing both wireless and Bluetooth >functionality, I'm wondering if I'm hitting this bug also? Perhaps it's >my fingerprint reader that's the problem, but your description above >sounds very similar to what I'm seeing. It sounds like a different issue to me. The Bluetooth and WLAN interfaces, though provided by the same NIC, are connected to different buses. The Bluetooth interface connects to the USB bus while the WLAN one connects to the PCIe bus. The btusb issue here won't hang the system at all. It just renders the Bluetooth interface unusable until the next power cycle, but the WLAN one still works totally fine in all reports (as well as on my device). Based on the symptoms that "the wifi controller will freeze up" and that "any attempt to access the wireless interface will hang the system", it's more likely either a PCIe issue or an NIC one. > >I have applied your patch, which I thought had fixed the problem, but I >had a freeze again earlier today after resuming my machine fron standby. PCIe issues may be quite random. Perhaps you will encounter it after some more time. > >I keep the bluetooth/btusb/bt* modules blacklisted, but that apparently >hasn't made a difference. That really sounds like a PCIe issue to me. Could you try if executing `lspci' after triggering the bug freezes or resets the system? Additionally, there may be some helpful information: https://docs.kernel.org/arch/x86/amd-debugging.html Since it's likely unrelated to the btusb issue here, bugzilla.kernel.org may be a better place to post your follow-up experiment results. Thanks, Rong > >> >> Fixes: e31d761628ad ("Bluetooth: btmtk: Disable remote wakeup for MT7922/MT7925") >> Signed-off-by: Rong Zhang <i@rong.moe> >> --- >> Changes in v2: >> - Only apply the quirk to to direct children of Ryzen platforms's root >> hubs >> - Theoretically, we could retrieve the root hub's PCI vendor ID with >> some hierarchy magic to further limit the range down to only root >> hubs on the SoC or PCH, but that's too intrusive -- the hierarchy >> magic really made me nervous once I saw what I have wrote, so I gave >> it up >> - Link to v1: https://patch.msgid.link/20260629-btmtk-ryzen-remote-wakeup-v1-1-1d2f1cee6d22@rong.moe >> --- >> drivers/bluetooth/btmtk.c | 10 ------- >> drivers/bluetooth/btusb.c | 73 ++++++++++++++++++++++++++++++++++++++++++++--- >> 2 files changed, 69 insertions(+), 14 deletions(-) >> >> diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c >> index 02a96342e964..4614434dd57b 100644 >> --- a/drivers/bluetooth/btmtk.c >> +++ b/drivers/bluetooth/btmtk.c >> @@ -1381,16 +1381,6 @@ int btmtk_usb_setup(struct hci_dev *hdev) >> break; >> case 0x7922: >> case 0x7925: >> - /* >> - * A remote wakeup could cause the device completely unresponsive, and >> - * recovering from such a state needs a power cycle. >> - * >> - * Since the remote wakeup capability is super broken, just disable it >> - * to get rid of the troubles. The device can still be autosuspended >> - * when the bluetooth interface is closed. >> - */ >> - device_set_wakeup_capable(&btmtk_data->udev->dev, false); >> - fallthrough; >> case 0x7961: >> case 0x7902: >> case 0x6639: >> diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c >> index 08c0a99a62c5..eef6e3b43bf9 100644 >> --- a/drivers/bluetooth/btusb.c >> +++ b/drivers/bluetooth/btusb.c >> @@ -6,6 +6,7 @@ >> * Copyright (C) 2005-2008 Marcel Holtmann <marcel@holtmann.org> >> */ >> >> +#include <linux/cpufeature.h> >> #include <linux/dmi.h> >> #include <linux/module.h> >> #include <linux/usb.h> >> @@ -957,6 +958,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_WAKEUP_BROKEN 18 >> >> struct btusb_data { >> struct hci_dev *hdev; >> @@ -2936,10 +2938,25 @@ static int btusb_send_frame_mtk(struct hci_dev *hdev, struct sk_buff *skb) >> } >> } >> >> +static inline bool platform_is_ryzen(void) >> +{ >> +#ifdef CONFIG_X86 >> + return boot_cpu_has(X86_FEATURE_ZEN); >> +#else >> + return false; >> +#endif >> +} >> + >> +static inline bool is_direct_child_of_root_hub(struct usb_device *udev) >> +{ >> + return udev->parent == udev->bus->root_hub; >> +} >> + >> static int btusb_mtk_setup(struct hci_dev *hdev) >> { >> struct btusb_data *data = hci_get_drvdata(hdev); >> struct btmtk_data *btmtk_data = hci_get_priv(hdev); >> + int err; >> >> /* MediaTek WMT vendor cmd requiring below USB resources to >> * complete the handshake. >> @@ -2956,7 +2973,40 @@ static int btusb_mtk_setup(struct hci_dev *hdev) >> btusb_mtk_claim_iso_intf(data); >> } >> >> - return btmtk_usb_setup(hdev); >> + err = btmtk_usb_setup(hdev); >> + if (err) >> + return err; >> + >> + switch (btmtk_data->dev_id) { >> + case 0x7922: >> + case 0x7925: >> + /* >> + * All reports seen to be relevant to Ryzen-based laptops. These >> + * NICs are usually used as OEM components thanks to some sort >> + * of reference designs. >> + * >> + * Their popularity on other platforms is unclear. While there >> + * is still a chance that the quirk may exist on other >> + * platforms, be cautious and only apply the quirk to direct >> + * children of Ryzen platforms's root hubs for the time being. >> + * >> + * In most cases the root hub is on the SoC or PCH, which needs >> + * the quirk. Unfortunately, this can't distinguish root hubs on >> + * PCIe add-in cards. Such roughness should be acceptable, as >> + * PCIe USB controller add-in cards are less commonly used >> + * nowadays. On the other hand, applying the quirk doesn't hurt >> + * any functionalities either, as the device can still be used >> + * as a wakeup source if desired. >> + * >> + * Theoretically, we could retrieve the root hub's PCI vendor ID >> + * with some hierarchy magic, but that's too intrusive... >> + */ >> + if (platform_is_ryzen() && is_direct_child_of_root_hub(data->udev)) >> + set_bit(BTUSB_WAKEUP_BROKEN, &data->flags); >> + break; >> + } >> + >> + return 0; >> } >> >> static int btusb_mtk_shutdown(struct hci_dev *hdev) >> @@ -4532,11 +4582,26 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message) >> >> BT_DBG("intf %p", intf); >> >> - /* Don't auto-suspend if there are connections or discovery in >> - * progress; external suspend calls shall never fail. >> + /* >> + * It is reported that remote wakeup events could sometimes cause some >> + * adapters completely unresponsive. Resetting the xHCI root hub doesn't >> + * help at all, and recovering from such a state needs a power cycle. >> + * Since disabling remote wakeup simply causes the USB core to gate >> + * runtime autosuspend as well due to needs_remote_wakeup == 1, let's do >> + * this ourselves to make our life easier. The interface can be safely >> + * autosuspended as long as remote wakeup is disabled, i.e., after >> + * closing the HCI device. >> + * >> + * Don't auto-suspend if there are connections or discovery in progress. >> + * >> + * External suspend calls shall never fail. Specifically, a device with >> + * broken remote wakeup may still take the advantage of remote wakeup in >> + * order to wake up the system from sleep if userspace has enabled it as >> + * a wakeup source. >> */ >> if (PMSG_IS_AUTO(message) && >> - (hci_conn_count(data->hdev) || hci_discovery_active(data->hdev))) >> + ((test_bit(BTUSB_WAKEUP_BROKEN, &data->flags) && data->intf->needs_remote_wakeup) || >> + hci_conn_count(data->hdev) || hci_discovery_active(data->hdev))) >> return -EBUSY; >> >> if (data->suspend_count++) >> >> --- >> base-commit: dc59e4fea9d83f03bad6bddf3fa2e52491777482 >> change-id: 230ba8c9-btmtk-ryzen-remote-wakeup-055a407682ef >> >> Thanks, >> Rong >> ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-07-13 17:33 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-07-01 15:43 [PATCH v2] Bluetooth: Properly disable remote wakeup for MT7922/MT7925 on Ryzen platform Rong Zhang 2026-07-06 14:53 ` Rafael Passos 2026-07-06 15:08 ` Rong Zhang 2026-07-06 18:21 ` Rafael Passos 2026-07-06 19:39 ` Rong Zhang 2026-07-13 15:06 ` John Rowley 2026-07-13 17:32 ` Rong Zhang
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox