Re: [PATCH v2] Bluetooth: Properly disable remote wakeup for MT7922/MT7925 on Ryzen platform

Rong Zhang <[email protected]>
Newsgroups org.infradead.lists.linux-mediatek,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-bluetooth,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
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 <[email protected]>
> > > ---
> > > 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/[email protected]__;!!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 <[email protected]>
> > >   */
> > > 
> > > +#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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.