OSDN Git Service

Bluetooth: btusb: Remove WAKEUP_DISABLE and add WAKEUP_AUTOSUSPEND for Realtek devices
authorMax Chou <max.chou@realtek.com>
Tue, 17 Aug 2021 03:03:12 +0000 (11:03 +0800)
committerMarcel Holtmann <marcel@holtmann.org>
Thu, 19 Aug 2021 15:08:31 +0000 (17:08 +0200)
For the commit of 9e45524a011107a73bc2cdde8370c61e82e93a4d, wakeup is
always disabled for Realtek devices. However, there's the capability
for Realtek devices to apply USB wakeup.

In this commit, remove WAKEUP_DISABLE feature for Realtek devices.
If users would switch wakeup, they should access
"/sys/bus/usb/.../power/wakeup"

In this commit, it also adds the feature as WAKEUP_AUTOSUSPEND
for Realtek devices because it should set do_remote_wakeup on autosuspend.

Signed-off-by: Max Chou <max.chou@realtek.com>
Tested-by: Hilda Wu <hildawu@realtek.com>
Reviewed-by: Archie Pusaka <apusaka@chromium.org>
Reviewed-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
drivers/bluetooth/btusb.c

index 2336f73..60d2fce 100644 (file)
@@ -527,7 +527,7 @@ static const struct dmi_system_id btusb_needs_reset_resume_table[] = {
 #define BTUSB_OOB_WAKE_ENABLED 11
 #define BTUSB_HW_RESET_ACTIVE  12
 #define BTUSB_TX_WAIT_VND_EVT  13
-#define BTUSB_WAKEUP_DISABLE   14
+#define BTUSB_WAKEUP_AUTOSUSPEND       14
 #define BTUSB_USE_ALT3_FOR_WBS 15
 
 struct btusb_data {
@@ -1350,13 +1350,6 @@ static int btusb_open(struct hci_dev *hdev)
 
        data->intf->needs_remote_wakeup = 1;
 
-       /* Disable device remote wakeup when host is suspended
-        * For Realtek chips, global suspend without
-        * SET_FEATURE (DEVICE_REMOTE_WAKEUP) can save more power in device.
-        */
-       if (test_bit(BTUSB_WAKEUP_DISABLE, &data->flags))
-               device_wakeup_disable(&data->udev->dev);
-
        if (test_and_set_bit(BTUSB_INTR_RUNNING, &data->flags))
                goto done;
 
@@ -1423,7 +1416,7 @@ static int btusb_close(struct hci_dev *hdev)
        data->intf->needs_remote_wakeup = 0;
 
        /* Enable remote wake up for auto-suspend */
-       if (test_bit(BTUSB_WAKEUP_DISABLE, &data->flags))
+       if (test_bit(BTUSB_WAKEUP_AUTOSUSPEND, &data->flags))
                data->intf->needs_remote_wakeup = 1;
 
        usb_autopm_put_interface(data->intf);
@@ -3602,9 +3595,6 @@ static bool btusb_prevent_wake(struct hci_dev *hdev)
 {
        struct btusb_data *data = hci_get_drvdata(hdev);
 
-       if (test_bit(BTUSB_WAKEUP_DISABLE, &data->flags))
-               return true;
-
        return !device_may_wakeup(&data->udev->dev);
 }
 
@@ -3882,11 +3872,8 @@ static int btusb_probe(struct usb_interface *intf,
                hdev->shutdown = btrtl_shutdown_realtek;
                hdev->cmd_timeout = btusb_rtl_cmd_timeout;
 
-               /* Realtek devices lose their updated firmware over global
-                * suspend that means host doesn't send SET_FEATURE
-                * (DEVICE_REMOTE_WAKEUP)
-                */
-               set_bit(BTUSB_WAKEUP_DISABLE, &data->flags);
+               /* Realtek devices need to set remote wakeup on auto-suspend */
+               set_bit(BTUSB_WAKEUP_AUTOSUSPEND, &data->flags);
                set_bit(BTUSB_USE_ALT3_FOR_WBS, &data->flags);
        }
 
@@ -4062,12 +4049,15 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
         * Actually, it depends on whether the usb host sends
         * set feature (enable wakeup) or not.
         */
-       if (test_bit(BTUSB_WAKEUP_DISABLE, &data->flags)) {
+       if (test_bit(BTUSB_WAKEUP_AUTOSUSPEND, &data->flags)) {
                if (PMSG_IS_AUTO(message) &&
                    device_can_wakeup(&data->udev->dev))
                        data->udev->do_remote_wakeup = 1;
-               else if (!PMSG_IS_AUTO(message))
+               else if (!PMSG_IS_AUTO(message) &&
+                        !device_may_wakeup(&data->udev->dev)) {
+                       data->udev->do_remote_wakeup = 0;
                        data->udev->reset_resume = 1;
+               }
        }
 
        return 0;