From: sashiko-bot@kernel.org
To: "Torstein Eide" <torsteine+linux@gmail.com>
Cc: linux-input@vger.kernel.org, dmitry.torokhov@gmail.com
Subject: Re: [PATCH 3/4] HID: lg-g15: report Super-key-lock state on G15 v2's keyboard interface
Date: Mon, 09 Nov 2026 10:36:16 +0000 [thread overview]
Message-ID: <sashiko-outbox-204828@kernel.org> (raw)
In-Reply-To: <20261109094426.1432465-4-torsteine+linux@gmail.com>
Thank you for your contribution! Sashiko AI review found 3 potential
issues to consider:
- [Medium] HID: lg-g15: missing HID_QUIRK_INPUT_PER_APP in
lg_g15_v2_kbd_probe()
- [Medium] HID: lg-g15: initial lock state read after LED registration
in lg_g15_v2_kbd_probe()
- [Low] HID: lg-g15: race updating super_lock between lg_g15_resume()
and raw_event
--
commit 429a4d981b469fb0f361faf62d0245c19b75257d
Author: Torstein Eide <torsteine+linux@gmail.com>
HID: lg-g15: report Super-key-lock state on G15 v2's keyboard interface
This commit binds the Logitech G15 v2 keyboard USB device (046D:C226) to
hid-lg-g15 and exposes the Super-key lock state from report 3 as a
read-only g15::game_mode LED while keeping default hid-input handling.
> diff --git a/drivers/hid/hid-lg-g15.c b/drivers/hid/hid-lg-g15.c
> index 35d183787383a..592c9747738e2 100644
> --- a/drivers/hid/hid-lg-g15.c
> +++ b/drivers/hid/hid-lg-g15.c
[ ... ]
> @@ -981,11 +995,138 @@ static int lg_g510_leds_event(struct lg_g15_data *g15, u8 *data)
[ ... ]
> +static void lg_g15_v2_kbd_set_super_lock(struct lg_g15_kbd_data *kbd, bool super_lock)
> +{
> + if (super_lock == kbd->super_lock)
> + return;
> +
> + kbd->super_lock = super_lock;
> + led_classdev_notify_brightness_hw_changed(&kbd->led, super_lock);
> +}
> +
> +/* Fetches the current lock state, which may already be on at probe/resume. */
> +static void lg_g15_v2_kbd_read_super_lock(struct hid_device *hdev,
> + struct lg_g15_kbd_data *kbd)
> +{
> + u8 *buf;
> + int ret;
> +
> + buf = kzalloc(2, GFP_KERNEL); /* DMA-able, not on the stack */
> + if (!buf)
> + return;
> +
> + ret = hid_hw_raw_request(hdev, LG_G15_V2_KBD_GAME_MODE_REPORT, buf, 2,
> + HID_INPUT_REPORT, HID_REQ_GET_REPORT);
> + if (ret == 2 && buf[0] == LG_G15_V2_KBD_GAME_MODE_REPORT)
> + lg_g15_v2_kbd_set_super_lock(kbd, buf[1] & 0x01);
> + else
> + hid_dbg(hdev, "Error reading Super-key-lock state: %d\n", ret);
> +
> + kfree(buf);
> +}
[ ... ]
> + kbd->led.name = "g15::game_mode";
> + kbd->led.max_brightness = 1;
> + kbd->led.brightness_get = lg_g15_v2_kbd_super_lock_get;
> + kbd->led.flags = LED_BRIGHT_HW_CHANGED; /* Enables the hw_changed notify below */
> +
> + ret = devm_led_classdev_register(&hdev->dev, &kbd->led);
> + if (ret)
> + return 0; /* Non-fatal, keyboard input still works without the LED */
> +
> + /*
> + * Only set drvdata once the LED is registered: raw_event may run as
> + * soon as hid_hw_start() returns, and notifying a brightness change
> + * on an unregistered LED triggers a WARN.
> + */
> + hid_set_drvdata(hdev, kbd);
> + lg_g15_v2_kbd_read_super_lock(hdev, kbd);
[Severity: Medium]
Does registering kbd->led before reading the initial hardware lock state
publish a stale brightness of 0 and emit a spurious brightness_hw_changed
notification when the Super-key lock switch is already on at probe?
Inside devm_led_classdev_register(), led_classdev_register_ext() calls
kbd->led.brightness_get while kbd->super_lock is still false, caches
kbd->led.brightness = 0, initializes kbd->led.brightness_hw_changed to -1
(-ENODATA), and emits KOBJ_ADD. Userspace readers reacting to the uevent
can observe 0 while the GET_REPORT transfer is in flight, and
lg_g15_v2_kbd_read_super_lock() -> lg_g15_v2_kbd_set_super_lock() then fires
led_classdev_notify_brightness_hw_changed() and sets brightness_hw_changed
to 1 even though no hardware change occurred after registration.
Reading the initial report into kbd->super_lock before calling
devm_led_classdev_register() (similar to lg_g15_get_initial_led_brightness()
in lg_g15_probe()) would register the LED with the actual hardware state.
[ ... ]
> @@ -1492,6 +1638,12 @@ static int lg_g15_probe(struct hid_device *hdev, const struct hid_device_id *id)
> struct hid_report *rep;
> int ret, i, gkeys = 0;
>
> + if (lg_g15_is_v2_kbd(hdev)) /* Not the GamePanel LCD interface */
> + return lg_g15_v2_kbd_probe(hdev);
> +
> + if (id->driver_data == LG_G15_V2_KBD) /* e.g. a mismatching new_id */
> + return -ENODEV;
> +
> hdev->quirks |= HID_QUIRK_INPUT_PER_APP;
[Severity: Medium]
Should lg_g15_v2_kbd_probe() also set HID_QUIRK_INPUT_PER_APP on
hdev->quirks before calling hid_parse() and hid_hw_start()?
Previously 046D:C226 was bound by hid-generic, where hid_generic_probe()
sets HID_QUIRK_INPUT_PER_APP:
drivers/hid/hid-generic.c:hid_generic_probe() {
hdev->quirks |= HID_QUIRK_INPUT_PER_APP;
ret = hid_parse(hdev);
if (ret)
return ret;
return hid_hw_start(hdev, HID_CONNECT_DEFAULT);
}
Because lg_g15_probe() dispatches to lg_g15_v2_kbd_probe() before setting
HID_QUIRK_INPUT_PER_APP, any interface on 046D:C226 with multiple
application collections (such as the consumer-control/extra-report
interface) has all application collections merged into a single input_dev
and loses the per-application input device name suffix, which is a
regression relative to hid-generic.
[ ... ]
> @@ -1772,9 +1947,18 @@ static void lg_g15_remove(struct hid_device *hdev)
> */
> static int lg_g15_resume(struct hid_device *hdev)
> {
> - struct lg_g15_data *g15 = hid_get_drvdata(hdev);
> + struct lg_g15_data *g15;
> struct lg_g15_led *contrast;
>
> + if (lg_g15_is_v2_kbd(hdev)) {
> + struct lg_g15_kbd_data *kbd = hid_get_drvdata(hdev);
> +
> + if (kbd)
> + lg_g15_v2_kbd_read_super_lock(hdev, kbd);
> + return 0;
> + }
[Severity: Low]
Can lg_g15_resume() race with lg_g15_v2_kbd_raw_event() when updating
kbd->super_lock and kbd->led.brightness_hw_changed?
In usbhid, hid_resume_common() and hid_post_reset() call hid_restart_io() to
restart the interrupt IN URB before invoking the HID driver's resume or
reset_resume callback. If the Super-key lock switch is toggled during
resume, the GET_REPORT control transfer and an interrupt IN report can run
concurrently:
CPU0 (resume) CPU1 (URB completion)
lg_g15_resume()
lg_g15_v2_kbd_read_super_lock()
hid_hw_raw_request()
-> reads old state (0)
lg_g15_raw_event()
lg_g15_v2_kbd_raw_event()
lg_g15_v2_kbd_set_super_lock(kbd, 1)
kbd->super_lock = 1;
..._hw_changed(&kbd->led, 1);
lg_g15_v2_kbd_set_super_lock(kbd, 0)
kbd->super_lock = 0; <-- overwrites newer interrupt state
The two paths can also interleave between assigning kbd->super_lock and
calling led_classdev_notify_brightness_hw_changed(), leaving kbd->super_lock
and kbd->led.brightness_hw_changed with opposite values.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261109094426.1432465-1-torsteine+linux@gmail.com?part=3
next prev parent reply other threads:[~2026-11-09 10:36 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-09 9:44 [PATCH 0/4] HID: lg-g15: G15 v2 LCD and game-mode support Torstein Eide
2026-11-09 9:44 ` [PATCH 1/4] HID: lg-g15: add LCD contrast LED Torstein Eide
2026-11-09 10:00 ` sashiko-bot
2026-11-09 9:44 ` [PATCH 2/4] HID: lg-g15: add LCD pixel-content framebuffer Torstein Eide
2026-11-09 10:21 ` sashiko-bot
2026-11-09 9:44 ` [PATCH 3/4] HID: lg-g15: report Super-key-lock state on G15 v2's keyboard interface Torstein Eide
2026-11-09 10:36 ` sashiko-bot [this message]
2026-11-09 9:44 ` [PATCH 4/4] HID: lg-g15: cancel LED work only after stopping the hardware Torstein Eide
2026-11-09 14:01 ` Hans de Goede
2026-11-09 13:49 ` [PATCH 0/4] HID: lg-g15: G15 v2 LCD and game-mode support Hans de Goede
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=sashiko-outbox-204828@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=dmitry.torokhov@gmail.com \
--cc=linux-input@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=torsteine+linux@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox