summaryrefslogtreecommitdiff
path: root/drivers/hid
AgeCommit message (Collapse)AuthorFilesLines
2026-08-14HID: thrustmaster: move FF initialization to .input_configured()Dmitry Torokhov1-33/+14
The driver currently initializes force-feedback in its probe() function after calling hid_hw_start(). This is racy as the input device is already registered and visible to userspace at that point. Move the FF initialization to the .input_configured() callback to ensure the device is fully prepared before registration. Assisted-by: Gemini:gemini-3.1-pro Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-14HID: pantherlord: move FF initialization to .input_configured()Dmitry Torokhov1-81/+61
The driver currently initializes force-feedback in its probe() function after calling hid_hw_start(). This is racy as the input device is already registered and visible to userspace at that point. Move the FF initialization to the .input_configured() callback to ensure the device is fully prepared before registration. Assisted-by: Gemini:gemini-3.1-pro Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-14HID: microsoft: move FF initialization to .input_configured()Dmitry Torokhov1-30/+8
The driver currently initializes force-feedback in its probe() function after calling hid_hw_start(). This is racy as the input device is already registered and visible to userspace at that point. Move the FF initialization to the .input_configured() callback to ensure the device is fully prepared before registration. Assisted-by: Gemini:gemini-3.1-pro Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-14HID: move generic FF initialization into hidinput_connect()Dmitry Torokhov2-21/+21
Generic force-feedback initialization (pidff) currently happens in hid_connect() after hidinput_connect() has already registered the input devices. This is racy as the device is live and visible to userspace before FF support is fully set up. Move the call to hdev->ff_init() into hidinput_connect(), ensuring it runs before input_register_device() is called. This closes the race window for standard PID-capable devices. The initialization now also checks (connect_mask & HID_CONNECT_FF) and !hid_has_ff_input() to avoid conflicts with custom FF implementations and respect driver opt-outs. Assisted-by: Gemini:gemini-3.1-pro Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-14HID: holtek: move FF initialization to .input_configured()Dmitry Torokhov1-37/+9
The driver currently initializes force-feedback in its probe() function after calling hid_hw_start() with HID_CONNECT_DEFAULT. This is racy as the input device is already registered and visible to userspace at that point. Move the FF initialization to the .input_configured() callback to ensure the device is fully prepared before registration. Assisted-by: Gemini:gemini-3.1-pro Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-14HID: stadia: move FF initialization to .input_configured()Dmitry Torokhov1-36/+5
The driver currently initializes force-feedback in its probe() function after calling hid_hw_start() with HID_CONNECT_DEFAULT. This is racy as the input device is already registered and visible to userspace at that point. Move the FF initialization to the .input_configured() callback to ensure the device is fully prepared before registration. Assisted-by: Gemini:gemini-3.1-pro Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-14HID: stadia: use open/close to manage workqueue lifecycleDmitry Torokhov1-33/+38
Override input device open() and close() callbacks to enable and disable the force-feedback workqueue item synchronously. When the input device is opened by userspace, call hid_hw_open() and enable_work(). When it is closed, disable_work_sync() ensures that any pending or running work item is cancelled/flushed and no further work items can be scheduled. In close(), zero out magnitudes and issue a final report to turn off the rumble motors on the physical controller before shutting down transport I/O. Pack strong and weak magnitudes into a single u32 integer using WRITE_ONCE() and READ_ONCE() for atomic, lockless updates. This allows eliminating the manual 'removed' boolean flag and spinlock completely. Assisted-by: Antigravity:gemini-3.6-flash Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-14HID: gaff: move FF initialization to .input_configured()Dmitry Torokhov1-43/+10
The driver currently initializes force-feedback in its probe() function after calling hid_hw_start() with HID_CONNECT_DEFAULT. This is racy as the input device is already registered and visible to userspace at that point. Move the FF initialization to the .input_configured() callback to ensure the device is fully prepared before registration. Assisted-by: Gemini:gemini-3.1-pro Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-14HID: emsff: move FF initialization to .input_configured()Dmitry Torokhov1-42/+8
The driver currently initializes force-feedback in its probe() function after calling hid_hw_start() with HID_CONNECT_DEFAULT. This is racy as the input device is already registered and visible to userspace at that point. Move the FF initialization to the .input_configured() callback to ensure the device is fully prepared before registration. Assisted-by: Gemini:gemini-3.1-pro Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-14HID: dragonrise: move FF initialization to .input_configured()Dmitry Torokhov1-51/+15
The driver currently initializes force-feedback in its probe() function after calling hid_hw_start() with HID_CONNECT_DEFAULT. This is racy as the input device is already registered and visible to userspace at that point. Move the FF initialization to the .input_configured() callback to ensure the device is fully prepared before registration. Assisted-by: Gemini:gemini-3.1-pro Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-14HID: bigben: move FF initialization to .input_configured()Dmitry Torokhov1-46/+43
The driver currently initializes force-feedback in its probe() function after calling hid_hw_start() with HID_CONNECT_DEFAULT. This is racy as the input device is already registered and visible to userspace at that point. Move the FF initialization to the .input_configured() callback to ensure the device is fully prepared before registration. Assisted-by: Gemini:gemini-3.1-pro Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-14HID: betop: move FF initialization to .input_configured()Dmitry Torokhov1-22/+11
The driver currently initializes force-feedback in its probe() function after calling hid_hw_start() with HID_CONNECT_DEFAULT. This is racy as the input device is already registered and visible to userspace at that point. Move the FF initialization to the .input_configured() callback to ensure the device is fully prepared before registration. Assisted-by: Gemini:gemini-3.1-pro Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-14HID: axff: move FF initialization to .input_configured()Dmitry Torokhov1-28/+12
The driver currently initializes force-feedback in its probe() function after calling hid_hw_start() with HID_CONNECT_DEFAULT. This is racy as the input device is already registered and visible to userspace at that point. Move the FF initialization to the .input_configured() callback to ensure the device is fully prepared before registration. Assisted-by: Gemini:gemini-3.1-pro Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-14HID: core: automatically initialize generic FF if no other FF is presentDmitry Torokhov1-1/+14
Some HID drivers initialize their own force-feedback support within their .input_configured() callback. In such cases, we should skip the generic PID force-feedback initialization to avoid conflicts and redundant setup. Add hid_has_ff_input() helper and use it to check for existing FF capabilities before calling hdev->ff_init(). Since we now have a dynamic way to detect if force-feedback is needed, the HID_CONNECT_FF flag is redundant for conflict resolution and can be ignored in the core initialization logic. Generic PID support will now be attempted by default for any claimed input device that doesn't already have FF capabilities. Assisted-by: Gemini:gemini-3.1-pro Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-14HID: amd_sfh: Register tablet-mode auxiliary deviceBasavaraj Natikar3-0/+53
Register an auxiliary device when the operating-mode sensor is present, so a dedicated input driver can bind to it and report the device posture. This keeps the input handling out of the sensor transport driver. Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-14HID: amd_sfh: Add accessor to read the operating-mode sensorBasavaraj Natikar5-1/+58
Allow other drivers to query the operating mode (laptop or tablet) reported by the Sensor Fusion Hub. This is the interface used by the tablet-mode switch driver to report the device posture to userspace. Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-14HID: amd_sfh: Serialize access to the shared emp2 pointerBasavaraj Natikar1-0/+6
The SFH accessors reach the device through a file-global emp2 pointer that is published at probe and cleared on remove. amd_get_sfh_info() is exported and called from other modules on unrelated threads, so a reader can observe a non-NULL emp2 and then race a concurrent unbind that clears it and frees the device. Serialize the emp2 publish/clear and all readers under a mutex, so a reader either sees a live device for the whole access or sees NULL. Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-14HID: amd_sfh: Track MP2 version explicitlyBasavaraj Natikar2-4/+11
The MP2 version is currently known only implicitly, from whether an ops pointer was stored in the PCI driver_data. Subsequent changes need to act on the MP2 version directly, for example to read the operating-mode register only on confirmed MP2 v2. Track the MP2 version explicitly so that version-specific behaviour can be gated on it, and leave it unset for generations that do not require such handling. Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-14HID: sony: fix UAF of ghl_poke_timer / ghl_urb at driver unbindDoruk Tan Ozturk1-1/+3
For GHL (Guitar Hero Live) dongles, sony_probe() arms a periodic timer: ghl_magic_poke() (the timer callback) submits sc->ghl_urb, and the URB completion ghl_magic_poke_cb() re-arms the timer with mod_timer(). sony_remove() drained the timer with timer_delete_sync() and then freed the URB with usb_free_urb(): timer_delete_sync(&sc->ghl_poke_timer); usb_free_urb(sc->ghl_urb); timer_delete_sync() does not block re-arming, and while the URB is in flight the timer is not pending, so the sync delete is a no-op. A URB completion that runs after the delete re-arms the timer, and usb_free_urb() only drops a reference -- it does not kill an in-flight URB. sc is allocated with devm_kzalloc() and freed once sony_remove() returns, so the re-armed ghl_poke_timer (embedded in sc) then fires on freed memory, a use-after-free from timer softirq. This is a disconnect/rmmod race. Poison the URB first, then shut the timer down, before freeing the URB. usb_poison_urb() kills any in-flight URB and permanently rejects further submissions, so a poke timer that is still pending cannot re-submit the URB from ghl_magic_poke() in the window before timer_shutdown_sync() runs. usb_kill_urb() would not suffice: it only cancels the in-flight URB and leaves it submittable once it returns, so the pending timer could re-submit it and put a fresh URB in flight over the freed sc. timer_shutdown_sync() then drains any last callback and blocks re-arming. The probe error path is unaffected: it is only reached before the timer is armed. Reproduced under KASAN on next-20260710 via dummy_hcd + raw-gadget emulation of the GHL PS4 dongle (VID 0x1430 / PID 0x07bb): hid-sony binds and arms the poke timer, the poke URB is held in flight, the driver is unbound (freeing sc), then the URB is released. The completion re-arms the timer on the freed sc, and the re-armed timer fires ~8 s later: BUG: KASAN: slab-use-after-free in ghl_magic_poke+0x98/0xb0 Read of size 8 at addr ffff88810b02fd50 by task swapper/0/0 ghl_magic_poke+0x98/0xb0 call_timer_fn+0x35/0x2b0 __run_timers+0x69c/0x9a0 run_timer_softirq+0x173/0x2a0 Allocated by task 169: sony_probe Freed by task 338: devres_release_group <- hid_device_remove (sony_remove) Found by 0sec (https://0sec.ai) using automated source analysis. Fixes: cc894ac55360 ("HID: sony: support for ghlive ps3/wii u dongles") Cc: stable@vger.kernel.org Assisted-by: 0sec:multi-model Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: uclogic: fix use-after-free of inrange_timer on removeIbrahim Hashimov1-1/+11
uclogic_remove() cancels the pen in-range timer and then stops the device: timer_delete_sync(&drvdata->inrange_timer); hid_hw_stop(hdev); timer_delete_sync() only guarantees the timer is idle at that instant. uclogic_raw_event_pen() keeps delivering pen reports until hid_hw_stop() stops the transport several lines later, and every report with pen->inrange == UCLOGIC_PARAMS_PEN_INRANGE_NONE re-arms the timer: mod_timer(&drvdata->inrange_timer, jiffies + msecs_to_jiffies(100)); A report landing between the timer_delete_sync() call and the transport teardown in hid_hw_stop() re-arms inrange_timer after it was cancelled. uclogic_remove() then returns and the devm drvdata is freed, while hid_hw_stop() has already freed the input device drvdata->pen_input points at, so when the timer fires ~100 ms later uclogic_inrange_timeout() dereferences freed memory -- a use-after-free in timer-softirq context. Swapping the two calls is not a fix: stopping the device first frees drvdata->pen_input via hidinput_disconnect() while the timer may still be pending, so a timer already armed before removal fires on the freed input device in the window before timer_delete_sync() runs. Use timer_shutdown_sync() before hid_hw_stop() instead. It cancels the timer, waits for a running callback while pen_input is still valid, and prevents any further re-arming -- a later mod_timer() from an in-flight report is silently ignored -- so the timer is provably dead before hid_hw_stop() frees the inputs. This is the ordering the timer core documents for this "timer re-armed from another path" teardown case. Fixes: 01309e29eb95 ("HID: uclogic: Support in-range reporting emulation") Cc: stable@vger.kernel.org Signed-off-by: Ibrahim Hashimov <security@auditcode.ai> Assisted-by: AuditCode-AI:2026.07 Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: picolcd: clamp eeprom debugfs read to bytes actually receivedIbrahim Hashimov1-0/+9
picolcd_debug_eeprom_read() trusts resp->raw_data[2] -- a length byte supplied by the device in its REPORT_EE_DATA reply -- clamped only to the caller's read() count: ret = resp->raw_data[2]; if (ret > s) ret = s; if (copy_to_user(u, resp->raw_data+3, ret)) It never checks resp->raw_size, the number of bytes picolcd_raw_event() actually copied into the 64-byte raw_data[] of the kmalloc'd struct picolcd_pending. A device (or a spoofed picoLCD) returning a length byte of 0xff, read with a count >= 255, makes copy_to_user() read past raw_data[] into adjacent slab memory and return it to userspace through the debugfs "eeprom" file: BUG: KASAN: slab-out-of-bounds in _copy_to_user Read of size 255 ... picolcd_debug_eeprom_read+0x214/0x2f0 [hid_picolcd] The debug-dump path in the same file already validates the device length byte against the received size before trusting it; this read does not. The file is created S_IRUSR (root-only) and a crafted device is needed, so it is neither unprivileged- nor remotely-triggerable. Clamp the copy length to resp->raw_size - 3 (the payload actually received, minus the 3-byte header), floored at 0 for short replies. Fixes: 9bbf2b98ba11 ("HID: add experimental access to PicoLCD device's EEPROM and FLASH") Cc: stable@vger.kernel.org Signed-off-by: Ibrahim Hashimov <security@auditcode.ai> Assisted-by: AuditCode-AI:2026.07 Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: apple: use the standard keyboard backlight LED nameAndre Eikmeyer1-1/+1
The T2-attached butterfly keyboard backlight is exposed as apple::kbd_backlight. This leaves the color field empty and gives userspace a model-specific name for the same white keyboard-backlight function exposed by Magic Keyboards. Magic Keyboard backlight support was added later and already follows the current LED naming convention. As a result, userspace has to handle two different names for the same function. We should use :white:kbd_backlight for both implementations. This follows the LED color and function naming convention and lets userspace discover either keyboard generation without a special case for the butterfly models. Signed-off-by: Andre Eikmeyer <dev@deq.rocks> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: apple: preserve keyboard backlight across T2 resumeAndre Eikmeyer1-2/+16
The T2 virtual USB host controller re-enumerates the internal keyboard after system resume. The butterfly keyboard backlight currently uses LED_CORE_SUSPENDRESUME, so the LED core sends a blocking request to the old HID device while it is disappearing. That request fails with -ENODEV and the newly probed device starts with its backlight off. To fix this, we cache the requested brightness when the old HID device is removed and restore it when the replacement is probed. We let re-enumeration handle restoration instead of issuing a request through the stale device. Fixes: 1f95a6cd5ad7 ("HID: apple: ensure the keyboard backlight is off if suspending") Cc: stable@vger.kernel.org Signed-off-by: Andre Eikmeyer <dev@deq.rocks> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: intel-ish-hid: ignore post-init ENUM_DEVICES from firmwareWahid Khan1-2/+3
Some ISH firmware versions (observed on Tiger Lake LP, 8086:a0fc, GUID {33AECD58-B679-4E54-9BD9-A04D34F0C226}) periodically re-send an unsolicited HOSTIF_DM_ENUM_DEVICES response roughly every 79 seconds. The current guard collapses two distinct cases into one condition: if (!(response_flag) || init_done) -> bad packet + ish_hw_reset This incorrectly treats a valid post-init firmware announcement as a corrupted packet, triggering an ISH soft-reset and a full ISHTP re-initialisation cycle on each occurrence (~1100 times per day on affected hardware). Split the check: reject messages with no response flag as before, but simply discard valid ENUM_DEVICES messages that arrive after init is complete. Signed-off-by: Wahid Khan <wahidzk0091@gmail.com> Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Tested-by: Zhang Lixu <lixu.zhang@intel.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: hid-msi: Add Rumble Intensity AttributesDerek J. Clark1-1/+201
Adds intensity adjustment for the left and right rumble motors. Claude was used during the reverse-engineering data gathering for this feature done by Zhouwang Huang. As the code had already been affected, I used Claude to create the initial framing for the feature, then did manual cleanup of the _show and _store functions afterwards to fix bugs and keep the coding style consistent. Claude was also used as an initial reviewer of this patch. Assisted-by: Claude:claude-sonnet-4-6 Co-developed-by: Zhouwang Huang <honjow311@gmail.com> Signed-off-by: Zhouwang Huang <honjow311@gmail.com> Link: https://patch.msgid.link/20260529072111.7565-5-derekjohn.clark@gmail.com Signed-off-by: Derek J. Clark <derekjohn.clark@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: hid-msi: Add RGB control interfaceDerek J. Clark1-15/+666
Adds RGB control interface for MSI Claw devices. The MSI Claw uses a fairly unique RGB interface. It has 9 total zones (4 per joystick ring and 1 for the ABXY buttons), and supports up to 8 sequential frames of RGB zone data. Each frame is written to a specific area of MCU memory by the profile command, the value of which changes based on the firmware of the device. Unlike other devices (such as the Legion Go or the OneXPlayer devices), there are no hard coded effects built into the MCU. Instead, the basic effects are provided as a series of frame data. I have mirrored the effects available in Windows in this driver, while keeping the effect names consistent with the Lenovo drivers for the effects that are similar. Initial reverse-engineering and implementation of this feature was done by Zhouwang Huang. I refactored the overall format to conform to kernel driver best practices and style guides. Claude was used as an initial reviewer of this patch. Assisted-by: Claude:claude-sonnet-4-6 Co-developed-by: Zhouwang Huang <honjow311@gmail.com> Signed-off-by: Zhouwang Huang <honjow311@gmail.com> Link: https://patch.msgid.link/20260529072111.7565-4-derekjohn.clark@gmail.com Signed-off-by: Derek J. Clark <derekjohn.clark@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: hid-msi: Add M-key mapping attributesDerek J. Clark1-1/+445
Adds attributes that allow for remapping the M-keys with up to 5 values when in macro mode. There are 2 mappable buttons on the rear of the device, M1 on the right and M2 on the left. When mapped, the events will fire from one of three event devices: gamepad buttons will fire from the device handled by xpad, while keyboard and mouse events will fire from respectively typed evdevs provided by the input core. Names of each mapping have been kept as close to the event that will fire from the evdev as possible, with context added to the ABS_ events on the direction of the movement. Initial reverse-engineering and implementation of this feature was done by Zhouwang Huang. I refactored the overall format to conform to kernel driver best practices and style guides. Claude was used as an initial reviewer of this patch. Assisted-by: Claude:claude-sonnet-4-6 Co-developed-by: Zhouwang Huang <honjow311@gmail.com> Signed-off-by: Zhouwang Huang <honjow311@gmail.com> Link: https://patch.msgid.link/20260529072111.7565-3-derekjohn.clark@gmail.com Signed-off-by: Derek J. Clark <derekjohn.clark@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: hid-msi: Add MSI Claw configuration driverDerek J. Clark4-0/+787
Adds configuration HID driver for the MSI Claw series of handheld PC's. In this initial patch add the initial driver outline and attributes for changing the gamepad mode, M-key behavior, and add a WO reset function. Sending the SWITCH_MODE and RESET commands causes a USB disconnect in the device. The completion will therefore never get hit and would trigger an -EIO. To avoid showing the user an error for every write to these attrs a bypass for the completion handling is introduced when timeout == 0. The initial version of this patch was written by Denis Benato, which contained the initial reverse-engineering and implementation for the gamepad mode switching. This work was later expanded by Zhouwang Huang to include more gamepad modes. Finally, I refactored the drivers data in/out flow and overall format to conform to kernel driver best practices and style guides. Claude was used as an initial reviewer of this patch. Assisted-by: Claude:claude-sonnet-4-6 Co-developed-by: Denis Benato <denis.benato@linux.dev> Signed-off-by: Denis Benato <denis.benato@linux.dev> Co-developed-by: Zhouwang Huang <honjow311@gmail.com> Signed-off-by: Zhouwang Huang <honjow311@gmail.com> Signed-off-by: Derek J. Clark <derekjohn.clark@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: Intel-thc-hid: Remove redundant dev_err()Pan Chuang2-8/+2
Since commit 55b48e23f5c4 ("genirq/devres: Add error handling in devm_request_*_irq()"), devm_request_threaded_irq() automatically logs detailed error messages on failure. Remove the now-redundant driver-specific dev_err() calls. Signed-off-by: Pan Chuang <panchuang@vivo.com> Reviewed-by: Even Xu <even.xu@intel.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: intel-ish-hid: ipc: Remove redundant dev_err()Pan Chuang1-3/+1
Since commit 55b48e23f5c4 ("genirq/devres: Add error handling in devm_request_*_irq()"), devm_request_irq() automatically logs detailed error messages on failure. Remove the now-redundant driver-specific dev_err() calls. Signed-off-by: Pan Chuang <panchuang@vivo.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com> Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: hid-goodix: Remove redundant dev_err()Pan Chuang1-4/+1
Since commit 55b48e23f5c4 ("genirq/devres: Add error handling in devm_request_*_irq()"), devm_request_threaded_irq() automatically logs detailed error messages on failure. Remove the now-redundant driver-specific dev_err() calls. Signed-off-by: Pan Chuang <panchuang@vivo.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: amd_sfh: Remove redundant dev_err()Pan Chuang1-11/+2
Since commit 55b48e23f5c4 ("genirq/devres: Add error handling in devm_request_*_irq()"), devm_request_irq() automatically logs detailed error messages on failure. Remove the now-redundant driver-specific dev_err() calls. Signed-off-by: Pan Chuang <panchuang@vivo.com> Acked-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: hyperx: add driver for the HyperX QuadCast 2 mute buttonBenjamin Blume4-0/+132
The tap-to-mute button of the HyperX QuadCast 2 (03f0:07b4) is handled entirely in the device firmware. The firmware gates the audio internally but never sends the Telephony "Phone Mute" usage (0x2f) that its own report descriptor advertises, and it does not touch the UAC feature unit either. Consequently neither an evdev key event nor an ALSA mixer change is ever generated, and userspace has no way to learn that the microphone was muted: desktops keep showing the microphone as live, and conferencing applications keep displaying an unmuted microphone while transmitting silence. The mute state is reported through a vendor-defined collection instead: 06 c0 ff Usage Page (Vendor-Defined 0xFFC0) a1 01 Collection (Application) 06 c1 ff Usage Page (Vendor-Defined 0xFFC1) 85 77 Report ID (0x77) 09 f0 Usage (0xF0) 75 08 95 3f Report Size (8), Report Count (63) 81 02 Input (Data,Var,Abs) Pressing the button emits a 64-byte report on that collection: 77 06 00 00 ... microphone unmuted 77 06 01 00 ... microphone muted where byte 1 identifies the mute event and byte 2 carries the resulting state. As the payload is an opaque vendor blob carrying no HID usages, hid-input cannot map it and a hwdb entry cannot express it either. Add a driver that decodes the report and emits KEY_MICMUTE, which makes the button behave like any other microphone mute key. Note that the device reports the resulting absolute state, whereas KEY_MICMUTE is a momentary key that userspace acts on as a toggle, so the driver emits one keypress per state change. Tested on a HyperX QuadCast 2 (03f0:07b4). Signed-off-by: Benjamin Blume <benjaminblume@posteo.de> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: steelseries: Add support for Arctis Nova 5X and Nova 7 familiesSriman Achanta3-0/+145
The Arctis Nova 5X, Nova 7 Gen2, and Nova 7 2026 refresh headsets answer status polls, but also send unsolicited battery and connection updates on a second HID interface (interface 5). Use that interface through async_interface so the driver does not have to poll. Add request and parse helpers for the Nova status format (0xb0/0xb7/0xb9/0xbb opcodes). The original (pre-Gen2) Arctis Nova 7 family answers the same status opcodes on the same interfaces, but reports battery capacity as a discrete 0-4 level instead of a raw percentage. Add a second parse function that maps that level through steelseries_map_capacity(), and a separate device_info so the two capacity encodings cannot get mixed up. Add the fourteen USB product IDs that share these protocols: 0x2253 Arctis Nova 5X 0x2202 Arctis Nova 7 0x2206 Arctis Nova 7X 0x22a4 Arctis Nova 7X (alternate PID) 0x223a Arctis Nova 7 Diablo 0x227a Arctis Nova 7 World of Warcraft Edition 0x22a1 Arctis Nova 7 2026 0x22a7 Arctis Nova 7P 2026 0x22a5 Arctis Nova 7X 2026 0x22a9 Arctis Nova 7 Diablo 2026 0x227e Arctis Nova 7 Gen 2 0x2258 Arctis Nova 7X Gen 2 0x229e Arctis Nova 7X Gen 2 (alternate PID) 0x22ad Arctis Nova 7X Gen 2 (alternate PID) Signed-off-by: Sriman Achanta <srimanachanta@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: steelseries: Add async status interface supportSriman Achanta1-25/+129
Some headsets expose a second HID interface that sends battery and connection updates on its own. Watching that interface lets the driver stop polling the sync interface. Add a steelseries_device_info::async_interface field and the code to handle it: - The driver binds both the sync and async interfaces. The async interface shares the steelseries_device created by the sync interface. It finds the sibling with usb_ifnum_to_if(), and before trusting its intfdata it rejects non-HID siblings by descriptor class and holds the sibling's device lock across the lookup, so a crafted device cannot cause a type-confused read and a concurrent unbind cannot free the hid_device from under it. It then takes a reference and returns -EPROBE_DEFER until the sync interface has probed. If the sync interface never binds, the async interface defers forever, which is fine here. - raw_event() now holds sd->lock and re-checks sd->removed so events on either interface are serialised against removal. - status_work runs once for async devices instead of rearming. A single status request is sent when the headset connects to get the initial battery level. No device sets async_interface yet. This is the infrastructure for the next commit. Signed-off-by: Sriman Achanta <srimanachanta@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: steelseries: Manage battery lifetime with refcountingSriman Achanta1-11/+36
The next change shares one steelseries_device between two HID interfaces, so the state can outlive either interface. Stop using devm for it. Reference count the struct with a kref and free it from steelseries_device_release(). Register and unregister the power supply explicitly, and clear sd->battery under sd->lock in remove() so it is not touched after it is unregistered. Drop the global atomic battery counter and name the power supply after the device (hdev->uniq, or dev_name() when empty), as hid-input and the other HID battery drivers do. No functional change for the current single-interface devices. Signed-off-by: Sriman Achanta <srimanachanta@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: steelseries: Correct Arctis 9 battery calibration rangeSriman Achanta1-1/+1
Map the Arctis 9 raw battery value over 0x64 (empty) to 0x9a (full) instead of 0x68 to 0x9d. These values match the HeadsetControl project [1] and fit the calibration points from an independent reverse engineering of the battery tray (about 25% at raw 112, 50% at raw 125) [2]. I do not have this headset. The values come from those references and were not measured directly. [1] https://github.com/Sapd/HeadsetControl/blob/master/lib/devices/steelseries_arctis_9.hpp [2] https://magnier.io/reverse-engineering-arctis-9-battery-tray/ Signed-off-by: Sriman Achanta <srimanachanta@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: steelseries: Report POWER_SUPPLY_STATUS_FULL when fullSriman Achanta1-1/+3
Report POWER_SUPPLY_STATUS_FULL when the headset is connected, charging, and at 100% capacity. It reported CHARGING in that case before. The charging flag doubles as a power-present signal: the headset keeps reporting charging while it sits docked at 100%, and clears the flag as soon as it runs on battery. Gating FULL on the charging flag therefore avoids reporting FULL for an unplugged headset that merely happens to be at 100%, which would otherwise hide the discharge state from userspace. Signed-off-by: Sriman Achanta <srimanachanta@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: steelseries: Refactor Arctis driver to use device_info frameworkSriman Achanta1-215/+259
Replace the per-product if/else quirk bitmap with a steelseries_device_info struct. Each model provides its capabilities, sync_interface, and request_status/parse_status callbacks. Report sending is folded into steelseries_send_report() and the feature and output wrappers, and the battery identifiers lose their per-model names. This is mostly a refactor, but it changes two things: - Battery status is polled from a periodic delayed work (status_work) instead of being requested from raw_event(). The interval stays at 3s. - Arctis 1 no longer clamps the reported capacity to 100% while disconnected. The connection state already controls how this is shown to userspace. ARCTIS_1_X and ARCTIS_9 keep working. No new devices are added. Signed-off-by: Sriman Achanta <srimanachanta@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: steelseries: Split Arctis headset driver into separate moduleSriman Achanta3-366/+428
Move all Arctis headset code (battery monitoring, wireless status, power supply registration, raw event handling) from hid-steelseries.c into the new hid-steelseries-arctis.c driver module. hid-steelseries.c keeps the SRWS1 racing wheel and the MSI RGB LED devices, while hid-steelseries-arctis.c handles the Arctis 1 (Xbox) and Arctis 9 wireless headsets with their own device table, probe, remove, and raw_event implementations. Signed-off-by: Sriman Achanta <srimanachanta@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: steelseries: Fix ARCTIS_1_X device mislabelingSriman Achanta3-10/+10
The SteelSeries Arctis 1 Wireless for Xbox (0x12b6) was labelled as the plain Arctis 1 Wireless. Rename USB_DEVICE_ID_STEELSERIES_ARCTIS_1 to USB_DEVICE_ID_STEELSERIES_ARCTIS_1_X, along with the matching quirk flag and device table entry. The device ID value is unchanged. Signed-off-by: Sriman Achanta <srimanachanta@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: magicmouse: re-enable multitouch after reset-resumeChristopher Kodama1-0/+19
When the Apple Magic Trackpad 2 (USB) is reset across a power transition (e.g. resume from hibernation) it drops out of multitouch mode: it keeps sending report ID 0x02 on its HID_TYPE_USBMOUSE interface, but the packet shrinks from 21 to 8 bytes and the trackpad2 handler drops it (size < 12). Clicks still work but pointer motion is lost until the device is re-plugged or the driver reloaded. Re-enable multitouch from .reset_resume via the workqueue. Only .reset_resume is needed; suspend-to-idle keeps the device powered and retains multitouch. Fixes: 87a2f10395c8 ("HID: magicmouse: Apple Magic Trackpad 2 USB-C driver support") Cc: stable@vger.kernel.org Assisted-by: Claude-Code:claude-opus-4-8 Signed-off-by: Christopher Kodama <ckhordiasma@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: lg4ff: validate report length before fixed offsetsJiancheng Huang1-0/+8
lg4ff_raw_event() rewrites fixed report offsets when combined pedals are enabled. It currently assumes that each product report contains every source and destination byte used by the rewrite. Return without rewriting a short report before each product-specific access. Apply the same bound to the computed offset path. Fixes: c832f86effbc ("HID: hid-logitech: Add combined pedal support Logitech wheels") Signed-off-by: Jiancheng Huang <jchuang@seu.edu.cn> Assisted-by: Codex:gpt-5.6-luna Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: corsair: cancel worker before unregistering LED to fix use-after-freeChen Changcheng1-2/+2
The cleanup functions k90_cleanup_backlight() and k90_cleanup_macro_functions() call led_classdev_unregister() before cancel_work_sync(): led_classdev_unregister() <-- may free led->cdev.dev cancel_work_sync() <-- wait for worker If the LED worker (k90_backlight_work / k90_record_led_work) is already running on another CPU, the following race can occur: CPU 1 (worker) CPU 2 (remove) --------------------- -------------------- if (led->removed) -> false (passed the guard, about to read led->cdev.dev) * preempted removed = true led_classdev_unregister() -> led->cdev.dev freed cancel_work_sync() -> waits for worker * resumes dev = led->cdev.dev->parent <-- UAF! Fix by swapping the order so that the worker is cancelled first: cancel_work_sync() <-- wait for worker first led_classdev_unregister() <-- then safe to unregister The removed flag is set before cancel_work_sync() so that if led_classdev_unregister() internally triggers another brightness update (which re-schedules the work), the worker will see the flag and return immediately. Signed-off-by: Chen Changcheng <chenchangcheng@kylinos.cn> Reported-by: sashiko-bot <sashiko-bot@kernel.org> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: corsair: fix use-after-free by reordering remove sequenceChen Changcheng1-2/+3
The corsair_remove() function currently frees the k90 driver data before calling hid_hw_stop(). Since hid_hw_stop() stops HID I/O, the event callback corsair_event() can still be invoked between the kfree() and hid_hw_stop(), and will dereference the freed drvdata->k90 pointer to write record_led.brightness. Reorder the remove sequence so that hid_hw_stop() is called first. Once hid_hw_stop() completes, the HID device is disconnected and no URBs are active, so corsair_event() cannot fire anymore. The driver data is freed only afterwards. Additionally, set drvdata->k90 to NULL after kfree() as a defensive measure, matching the existing pattern in the error path of k90_init_macro_functions(). Signed-off-by: Chen Changcheng <chenchangcheng@kylinos.cn> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: quirks: add ALWAYS_POLL quirk for AULA Mini 60 HE Pro DongleYuxiang Lin2-0/+3
The AULA Mini 60 HE Pro wireless keyboard dongle (USB ID 0c45:fefe) becomes unresponsive after roughly one minute of idle. No error appears in dmesg; the only recovery is physically replugging the dongle. This has been reproduced across kernels 6.8, 6.14 and 7.1.3. Testing shows HID_QUIRK_ALWAYS_POLL alone resolves the issue, verified via usbhid.quirks=0x0c45:0xfefe:0x400. Signed-off-by: Yuxiang Lin <mclyxfdw@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: i2c-hid: goodix: Disable VDD on VDDIO enable failureChao Huang1-1/+3
If enabling VDDIO fails after VDD has been enabled, the power-up path returns without disabling VDD. This leaves the regulator enabled and its enable count unbalanced. Disable VDD before returning the VDDIO error. Fixes: eb16f59e8e58 ("HID: i2c-hid: goodix: Add mainboard-vddio-supply") Signed-off-by: Chao Huang <huangchao@kylinos.cn> Reviewed-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: asus: support the Zenbook A16 (UX3607OA) keyboardKonrad Dybcio2-0/+19
The ASUS Zenbook A16 (UX3607OA), a Qualcomm Snapdragon X2 Elite Extreme (Glymur)-based laptop, carries its main keyboard on an I2C-HID device with the ID 0B05:4B42. Its Fn/media hotkeys are emitted as vendor-page (HID_UP_ASUSVENDOR) usages on report 0x5A. Match the device in hid-asus with the standard I2C keyboard quirks and add the three usage mappings observed on the hardware: 0x85 -> KEY_CAMERA (Fn+F11, camera toggle) 0x86 -> KEY_PROG1 (Fn+F12, MyASUS key) 0x5f -> KEY_PROG2 (extra programmable key) The camera-toggle key reports its usage (0x85) together with a companion state byte in the same array report ("5a 85 01" / "5a 85 10"). The 0x10 companion aliases the brightness-down vendor usage and spuriously dims the panel, so add QUIRK_FILTER_CAMERA_COMPANION to zero the companion slots for this device before input mapping. The quirk is device-gated so no other ASUS model is affected. Assisted-by: Claude Code:claude-opus-4-8 Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: quirks: Add ALWAYS_POLL quirk for Beitong BTP-KP20D dongleAaron Ma2-0/+4
The BTP-KP20D dongle in Direct/HID mode (20dd:5159) re-enumerates every few seconds because usbhid never submits its interrupt-IN URB: no HID driver binds to the vendor-specific report descriptor, so the device is never opened, and the firmware treats the idle endpoint as a lost link. Add HID_QUIRK_ALWAYS_POLL to keep the interrupt-IN URB submitted from probe time. Signed-off-by: Aaron Ma <mapengyu@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-08-03HID: hyperv: add KUnit coverage for device info boundsMichael Bommarito2-7/+120
Add KUnit coverage for Hyper-V synthetic HID initial device-info parsing. The tests cover zero bLength, a valid descriptor plus report descriptor, and a malformed report descriptor length that exceeds the received message. The same-translation-unit test uses a KUnit-only ACK bypass so parser coverage does not require a live VMBus channel. Assisted-by: Codex:gpt-5-5-xhigh Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>