Re: [PATCH v2] Bluetooth: Properly disable remote wakeup for MT7922/MT7925 on Ryzen platform
From: Rong Zhang
Date: Fri Jul 24 2026 - 10:12:28 EST
Hi Chris,
Thanks for your reply.
On Fri, 2026-07-24 at 09:54 +0000, Chris Lu (陸稚泓) wrote:
> Hi Rong,
>
> Sorry for not getting back you sooner,
> MediaTek BT team is currently looking for an AMD platform that can
> reproduce this issue, but we haven't found a environment which has
> similar problem.
FYI, the buggy devices I have are
- ThinkBook 14 G7+ ASP
- SoC: AMD Ryzen AI 9 H 365 w/ Radeon 880M
- PCI: 62:00.0 Network controller [0280]: MEDIATEK Corp. MT7925 802.11be 160MHz 2x2 PCIe Wireless Network Adapter [Filogic 360] [14c3:7925] Subsystem: Lenovo Device [17aa:e0ff]
- USB: Bus 003 Device 004: ID 0489:e111 Foxconn / Hon Hai Wireless_Device
- Beelink GTR 9 Pro
- SoC: AMD RYZEN AI MAX+ 395 w/ Radeon 8060S
- PCI: c1:00.0 Network controller [0280]: MEDIATEK Corp. MT7925 802.11be 160MHz 2x2 PCIe Wireless Network Adapter [Filogic 360] [14c3:7925] Subsystem: AzureWave Device [1a3b:6002]
- USB: Bus 003 Device 004: ID 13d3:3604 IMC Networks Wireless_Device
I can easily reproduce the issue in the office, but rarely at home. So I
guess it must be some sort of Bluetooth device triggering the issue. I
can't determine what device it is as many colleagues in the office have
their Bluetooth devices.
>
> About the patch, LGTM.
Could you kindly reply with a Reviewed-by: or Acked-by: tag? It's the
standard way to say "LGTM" and helps the review process.
> Your change can limit setting wakeup up capable to false to platform
> with X86_FEATURE_ZEN. I also tried this patch locally with Arm-based
> platform and it successfully avoids the issue of incorrectly disable BT
> wakeup.
Thanks for testing. I would also appreciate a Tested-by: tag indicating
that it correctly fixes the wakeup issue introduced in my previous patch.
Thanks a lot,
Rong
>
> Thanks,
> Chris Lu
>
> On Thu, 2026-07-23 at 21:38 +0800, Rong Zhang wrote:
> >
> > External email : Please do not click links or open attachments until
> > you have verified the sender or the content.
> >
> >
> > Hi Luiz, Chris,
> >
> > Could you kindly take a look at the patch?
> >
> > Thanks,
> > Rong
> >
> > On Wed, 2026-07-01 at 23:43 +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.
> > >
> > > Fixes: e31d761628ad ("Bluetooth: btmtk: Disable remote wakeup for
> > > MT7922/MT7925")
> > > Signed-off-by: Rong Zhang <i@xxxxxxxx>
> > > ---
> > > 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://urldefense.com/v3/__https://patch.msgid.link/20260629-btmtk-ryzen-remote-wakeup-v1-1-1d2f1cee6d22@rong.moe__;!!CTRNKA9wMg0ARbw!iS1xt56hol42azIYmHUZP_NI-N6WX6yn7_A1lf72MMvo1ZG_CNJRRSLgAbMx_AWK4kGyC2yBMQ$
> > > ---
> > > 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@xxxxxxxxxxxx>
> > > */
> > >
> > > +#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