]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
HID: magicmouse: avoid setting up battery timer when not needed
authorAditya Garg <gargaditya08@live.com>
Mon, 30 Jun 2025 12:37:13 +0000 (12:37 +0000)
committerJiri Kosina <jkosina@suse.com>
Thu, 3 Jul 2025 07:41:40 +0000 (09:41 +0200)
Currently, the battery timer is set up for all devices using
hid-magicmouse, irrespective of whether they actually need it or not.

The current implementation requires the battery timer for Magic Mouse 2
and Magic Trackpad 2 when connected via USB only. Add checks to ensure
that the battery timer is only set up when they are connected via USB.

Fixes: 0b91b4e4dae6 ("HID: magicmouse: Report battery level over USB")
Cc: stable@vger.kernel.org
Signed-off-by: Aditya Garg <gargaditya08@live.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
drivers/hid/hid-magicmouse.c

index 36f034ac605dcb6039d890a1db07904ab83a1e7b..226682762db365088c0ac30df2a785fe6e966edb 100644 (file)
@@ -791,17 +791,31 @@ static void magicmouse_enable_mt_work(struct work_struct *work)
                hid_err(msc->hdev, "unable to request touch data (%d)\n", ret);
 }
 
+static bool is_usb_magicmouse2(__u32 vendor, __u32 product)
+{
+       if (vendor != USB_VENDOR_ID_APPLE)
+               return false;
+       return product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ||
+              product == USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC;
+}
+
+static bool is_usb_magictrackpad2(__u32 vendor, __u32 product)
+{
+       if (vendor != USB_VENDOR_ID_APPLE)
+               return false;
+       return product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ||
+              product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC;
+}
+
 static int magicmouse_fetch_battery(struct hid_device *hdev)
 {
 #ifdef CONFIG_HID_BATTERY_STRENGTH
        struct hid_report_enum *report_enum;
        struct hid_report *report;
 
-       if (!hdev->battery || hdev->vendor != USB_VENDOR_ID_APPLE ||
-           (hdev->product != USB_DEVICE_ID_APPLE_MAGICMOUSE2 &&
-            hdev->product != USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC &&
-            hdev->product != USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 &&
-            hdev->product != USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC))
+       if (!hdev->battery ||
+           (!is_usb_magicmouse2(hdev->vendor, hdev->product) &&
+            !is_usb_magictrackpad2(hdev->vendor, hdev->product)))
                return -1;
 
        report_enum = &hdev->report_enum[hdev->battery_report_type];
@@ -863,17 +877,17 @@ static int magicmouse_probe(struct hid_device *hdev,
                return ret;
        }
 
-       timer_setup(&msc->battery_timer, magicmouse_battery_timer_tick, 0);
-       mod_timer(&msc->battery_timer,
-                 jiffies + msecs_to_jiffies(USB_BATTERY_TIMEOUT_MS));
-       magicmouse_fetch_battery(hdev);
-
-       if (id->vendor == USB_VENDOR_ID_APPLE &&
-           (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ||
-            id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC ||
-            ((id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ||
-              id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) &&
-             hdev->type != HID_TYPE_USBMOUSE)))
+       if (is_usb_magicmouse2(id->vendor, id->product) ||
+           is_usb_magictrackpad2(id->vendor, id->product)) {
+               timer_setup(&msc->battery_timer, magicmouse_battery_timer_tick, 0);
+               mod_timer(&msc->battery_timer,
+                         jiffies + msecs_to_jiffies(USB_BATTERY_TIMEOUT_MS));
+               magicmouse_fetch_battery(hdev);
+       }
+
+       if (is_usb_magicmouse2(id->vendor, id->product) ||
+           (is_usb_magictrackpad2(id->vendor, id->product) &&
+            hdev->type != HID_TYPE_USBMOUSE))
                return 0;
 
        if (!msc->input) {
@@ -936,7 +950,10 @@ static int magicmouse_probe(struct hid_device *hdev,
 
        return 0;
 err_stop_hw:
-       timer_delete_sync(&msc->battery_timer);
+       if (is_usb_magicmouse2(id->vendor, id->product) ||
+           is_usb_magictrackpad2(id->vendor, id->product))
+               timer_delete_sync(&msc->battery_timer);
+
        hid_hw_stop(hdev);
        return ret;
 }
@@ -947,7 +964,9 @@ static void magicmouse_remove(struct hid_device *hdev)
 
        if (msc) {
                cancel_delayed_work_sync(&msc->work);
-               timer_delete_sync(&msc->battery_timer);
+               if (is_usb_magicmouse2(hdev->vendor, hdev->product) ||
+                   is_usb_magictrackpad2(hdev->vendor, hdev->product))
+                       timer_delete_sync(&msc->battery_timer);
        }
 
        hid_hw_stop(hdev);
@@ -964,11 +983,8 @@ static const __u8 *magicmouse_report_fixup(struct hid_device *hdev, __u8 *rdesc,
         *   0x05, 0x01,       // Usage Page (Generic Desktop)        0
         *   0x09, 0x02,       // Usage (Mouse)                       2
         */
-       if (hdev->vendor == USB_VENDOR_ID_APPLE &&
-           (hdev->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ||
-            hdev->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC ||
-            hdev->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ||
-            hdev->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) &&
+       if ((is_usb_magicmouse2(hdev->vendor, hdev->product) ||
+            is_usb_magictrackpad2(hdev->vendor, hdev->product)) &&
            *rsize == 83 && rdesc[46] == 0x84 && rdesc[58] == 0x85) {
                hid_info(hdev,
                         "fixing up magicmouse battery report descriptor\n");