| From 9bdc30e35cbc1aa78ccf01040354209f1e11ca22 Mon Sep 17 00:00:00 2001 |
| From: Aditya Garg <gargaditya08@live.com> |
| Date: Mon, 30 Jun 2025 12:37:13 +0000 |
| Subject: HID: magicmouse: avoid setting up battery timer when not needed |
| |
| From: Aditya Garg <gargaditya08@live.com> |
| |
| commit 9bdc30e35cbc1aa78ccf01040354209f1e11ca22 upstream. |
| |
| 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> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| |
| --- |
| drivers/hid/hid-magicmouse.c | 58 ++++++++++++++++++++++++++++--------------- |
| 1 file changed, 38 insertions(+), 20 deletions(-) |
| |
| --- a/drivers/hid/hid-magicmouse.c |
| +++ b/drivers/hid/hid-magicmouse.c |
| @@ -772,16 +772,30 @@ static void magicmouse_enable_mt_work(st |
| 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; |
| +} |
| + |
| +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_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]; |
| @@ -843,16 +857,17 @@ static int magicmouse_probe(struct hid_d |
| 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_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) { |
| @@ -908,7 +923,10 @@ static int magicmouse_probe(struct hid_d |
| |
| return 0; |
| err_stop_hw: |
| - del_timer_sync(&msc->battery_timer); |
| + if (is_usb_magicmouse2(id->vendor, id->product) || |
| + is_usb_magictrackpad2(id->vendor, id->product)) |
| + del_timer_sync(&msc->battery_timer); |
| + |
| hid_hw_stop(hdev); |
| return ret; |
| } |
| @@ -919,7 +937,9 @@ static void magicmouse_remove(struct hid |
| |
| if (msc) { |
| cancel_delayed_work_sync(&msc->work); |
| - del_timer_sync(&msc->battery_timer); |
| + if (is_usb_magicmouse2(hdev->vendor, hdev->product) || |
| + is_usb_magictrackpad2(hdev->vendor, hdev->product)) |
| + del_timer_sync(&msc->battery_timer); |
| } |
| |
| hid_hw_stop(hdev); |
| @@ -936,10 +956,8 @@ static __u8 *magicmouse_report_fixup(str |
| * 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_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"); |