public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] HID: asus: add support for T3304 keyboard
@ 2026-05-03  7:26 James Ye
  2026-05-03  7:26 ` [PATCH 1/6] HID: input: delete hid_battery on disconnect James Ye
                   ` (5 more replies)
  0 siblings, 6 replies; 12+ messages in thread
From: James Ye @ 2026-05-03  7:26 UTC (permalink / raw)
  To: jikos, bentiss, lee, pavel
  Cc: linux-input, linux-leds, linux-kernel, denis.benato, James Ye

This series adds support for the ASUS Vivobook Slate 13 OLED (T3304)
detachable keyboard. The keyboard is a USB device presenting two
interfaces: keyboard and touchpad. Basic functionality already works
with hid-generic and hid-multitouch, but Fn key chords including media
keys and LEDs do not work.

To add support, bind the keyboard interface to hid-asus. However, the
ASUS-specific report descriptors are on the touchpad interface, so fixup
the descriptor so that hid-asus knows about them. Media keys are also
sent via the touchpad interface, so add MT_CLS_ASUS to this device in
hid-multitouch.

Also included is a fix for a use-after-free in hid-input.c discovered
during development, but technically unrelated to the device.
("HID: input: delete hid_battery on disconnect")

James Ye (6):
  HID: input: delete hid_battery on disconnect
  HID: asus: check feature reports when determining is_vendor
  HID: asus: add support for T3304 detachable keyboard
  HID: multitouch: add support for ASUS T3304 media keys
  HID: asus: add microphone mute LED support for T3304
  leds: led-class: mark classdev as unregistering early

 drivers/hid/hid-asus.c       | 117 ++++++++++++++++++++++++++++++++---
 drivers/hid/hid-ids.h        |   1 +
 drivers/hid/hid-input.c      |   5 ++
 drivers/hid/hid-multitouch.c |  10 +++
 drivers/leds/led-class.c     |   4 +-
 5 files changed, 126 insertions(+), 11 deletions(-)

--
2.54.0

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/6] HID: input: delete hid_battery on disconnect
  2026-05-03  7:26 [PATCH 0/6] HID: asus: add support for T3304 keyboard James Ye
@ 2026-05-03  7:26 ` James Ye
  2026-05-03  7:26 ` [PATCH 2/6] HID: asus: check feature reports when determining is_vendor James Ye
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: James Ye @ 2026-05-03  7:26 UTC (permalink / raw)
  To: jikos, bentiss, lee, pavel
  Cc: linux-input, linux-leds, linux-kernel, denis.benato, James Ye

This fixes a use-after-free when an HID device containing a battery is
disconnected then reconnected, such as due to binding to a different
driver.

    BUG: KASAN: slab-use-after-free in hidinput_setup_battery.isra.0+0x15a/0x9db [hid]

Signed-off-by: James Ye <jye836@gmail.com>
---
 drivers/hid/hid-input.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index d73cfa2e73d3..ae0e11c61eb8 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -2408,6 +2408,7 @@ EXPORT_SYMBOL_GPL(hidinput_connect);
 void hidinput_disconnect(struct hid_device *hid)
 {
 	struct hid_input *hidinput, *next;
+	struct hid_battery *bat, *bat_next;
 
 	list_for_each_entry_safe(hidinput, next, &hid->inputs, list) {
 		list_del(&hidinput->list);
@@ -2419,6 +2420,10 @@ void hidinput_disconnect(struct hid_device *hid)
 		kfree(hidinput);
 	}
 
+	list_for_each_entry_safe(bat, bat_next, &hid->batteries, list) {
+		list_del(&bat->list);
+	}
+
 	/* led_work is spawned by input_dev callbacks, but doesn't access the
 	 * parent input_dev at all. Once all input devices are removed, we
 	 * know that led_work will never get restarted, so we can cancel it
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 2/6] HID: asus: check feature reports when determining is_vendor
  2026-05-03  7:26 [PATCH 0/6] HID: asus: add support for T3304 keyboard James Ye
  2026-05-03  7:26 ` [PATCH 1/6] HID: input: delete hid_battery on disconnect James Ye
@ 2026-05-03  7:26 ` James Ye
  2026-05-03  7:26 ` [PATCH 3/6] HID: asus: add support for T3304 detachable keyboard James Ye
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: James Ye @ 2026-05-03  7:26 UTC (permalink / raw)
  To: jikos, bentiss, lee, pavel
  Cc: linux-input, linux-leds, linux-kernel, denis.benato, James Ye

ASUS T3304 Soft Keyboard has these reports on its touchpad interface,
which will be bound to hid_multitouch. To support a quirk allowing
hid_asus to configure the keyboard interface, feature reports should be
checked in addition to input reports, as is already the case in
asus_has_report_id.

Signed-off-by: James Ye <jye836@gmail.com>
---
 drivers/hid/hid-asus.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
index 3f5e96900b67..ef9d5eba4dc9 100644
--- a/drivers/hid/hid-asus.c
+++ b/drivers/hid/hid-asus.c
@@ -1282,10 +1282,12 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
 	}
 
 	/* Check for vendor for RGB init and handle generic devices properly. */
-	rep_enum = &hdev->report_enum[HID_INPUT_REPORT];
-	list_for_each_entry(rep, &rep_enum->report_list, list) {
-		if ((rep->application & HID_USAGE_PAGE) == HID_UP_ASUSVENDOR)
-			is_vendor = true;
+	for (int t = HID_INPUT_REPORT; t <= HID_FEATURE_REPORT; t++) {
+		rep_enum = &hdev->report_enum[t];
+		list_for_each_entry(rep, &rep_enum->report_list, list) {
+			if ((rep->application & HID_USAGE_PAGE) == HID_UP_ASUSVENDOR)
+				is_vendor = true;
+		}
 	}
 
 	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 3/6] HID: asus: add support for T3304 detachable keyboard
  2026-05-03  7:26 [PATCH 0/6] HID: asus: add support for T3304 keyboard James Ye
  2026-05-03  7:26 ` [PATCH 1/6] HID: input: delete hid_battery on disconnect James Ye
  2026-05-03  7:26 ` [PATCH 2/6] HID: asus: check feature reports when determining is_vendor James Ye
@ 2026-05-03  7:26 ` James Ye
  2026-05-03 22:23   ` Denis Benato
  2026-05-03  7:26 ` [PATCH 4/6] HID: multitouch: add support for ASUS T3304 media keys James Ye
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: James Ye @ 2026-05-03  7:26 UTC (permalink / raw)
  To: jikos, bentiss, lee, pavel
  Cc: linux-input, linux-leds, linux-kernel, denis.benato, James Ye

ASUSTek Computer, Inc. T3304 Soft Keyboard [0b05:1aad] is the detachable
keyboard of the ASUS Vivobook 13 Slate OLED (T3304). It presents as a
USB device with two interfaces: a keyboard and a pointing device
(touchpad).

Basic keyboard and full touchpad functionality work out-of-the-box with
hid-generic and hid-multitouch, but function key combos e.g. volume,
brightness control, home/end/pgup/pgdown require initialization.

Bind the keyboard interface to hid-asus for initialization. The
OEM-specific report descriptors required for this are present only on
the touchpad interface, not the keyboard, so a quirk is used to add the
required feature descriptor.

Signed-off-by: James Ye <jye836@gmail.com>
---
 drivers/hid/hid-asus.c | 58 +++++++++++++++++++++++++++++++++++++++---
 drivers/hid/hid-ids.h  |  1 +
 2 files changed, 56 insertions(+), 3 deletions(-)

diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
index ef9d5eba4dc9..e4c97fddfaf1 100644
--- a/drivers/hid/hid-asus.c
+++ b/drivers/hid/hid-asus.c
@@ -99,6 +99,7 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
 #define QUIRK_ROG_CLAYMORE_II_KEYBOARD	BIT(12)
 #define QUIRK_ROG_ALLY_XPAD		BIT(13)
 #define QUIRK_HID_FN_LOCK		BIT(14)
+#define QUIRK_T3304_KEYBOARD		BIT(15)

 #define I2C_KEYBOARD_QUIRKS			(QUIRK_FIX_NOTEBOOK_REPORT | \
 						 QUIRK_NO_INIT_REPORTS | \
@@ -494,6 +495,14 @@ static int asus_kbd_init(struct hid_device *hdev, u8 report_id)
 		return ret;
 	}

+	struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
+
+	/* T3304 keyboard always replies with 16 0xff bytes. Don't check for
+	 * acknowledgment.
+	 */
+	if (drvdata->quirks & QUIRK_T3304_KEYBOARD)
+		return 0;
+
 	u8 *readbuf __free(kfree) = kzalloc(FEATURE_KBD_REPORT_SIZE, GFP_KERNEL);
 	if (!readbuf)
 		return -ENOMEM;
@@ -1312,10 +1321,12 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
 		hid_warn(hdev, "Failed to initialize backlight.\n");

 	/*
-	 * For ROG keyboards, skip rename for consistency and ->input check as
-	 * some devices do not have inputs.
+	 * For ROG and T3304 keyboards, skip rename for consistency.
+	 * For ROG keyboards, skip ->input check as some devices do not have
+	 * inputs.
 	 */
-	if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD)
+	if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD ||
+	    drvdata->quirks & QUIRK_T3304_KEYBOARD)
 		return 0;

 	/*
@@ -1369,6 +1380,22 @@ static const __u8 asus_g752_fixed_rdesc[] = {
         0x2A, 0xFF, 0x00,		/*   Usage Maximum (0xFF)       */
 };

+static const __u8 asus_t3304_fixed_rdesc[] = {
+	0x06, 0x31, 0xff,              // Usage Page (Vendor Usage Page 0xff31)
+	0x09, 0x76,                    // Usage (Vendor Usage 0x76)
+	0xa1, 0x01,                    // Collection (Application)
+	0x05, 0xff,                    //  Usage Page (Vendor Usage Page 0xff)
+	0x85, 0x5a,                    //  Report ID (90)
+	0x19, 0x00,                    //  Usage Minimum (0)
+	0x2a, 0xff, 0x00,              //  Usage Maximum (255)
+	0x15, 0x00,                    //  Logical Minimum (0)
+	0x26, 0xff, 0x00,              //  Logical Maximum (255)
+	0x75, 0x08,                    //  Report Size (8)
+	0x95, 0x0f,                    //  Report Count (15)
+	0xb1, 0x02,                    //  Feature (Data,Var,Abs)
+	0xc0,                          // End Collection
+};
+
 static const __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc,
 		unsigned int *rsize)
 {
@@ -1473,6 +1500,28 @@ static const __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc,
 		}
 	}

+	/* T3304 keyboard's vendor descriptors are on the touchpad interface,
+	 * not the keyboard. But we need hid-multitouch to handle the touchpad,
+	 * Add a descriptor with only the config report so that this driver can
+	 * perform initialization.
+	 */
+	if (drvdata->quirks & QUIRK_T3304_KEYBOARD) {
+		__u8 *new_rdesc;
+		size_t new_size = *rsize + sizeof(asus_t3304_fixed_rdesc);
+
+		new_rdesc = devm_kzalloc(&hdev->dev, new_size, GFP_KERNEL);
+		if (new_rdesc == NULL)
+			return rdesc;
+
+		hid_info(hdev, "Fixing up Asus T3304 keyboard report descriptor\n");
+		memcpy(new_rdesc, rdesc, *rsize);
+		memcpy(new_rdesc + *rsize, asus_t3304_fixed_rdesc,
+		       sizeof(asus_t3304_fixed_rdesc));
+
+		*rsize = new_size;
+		rdesc = new_rdesc;
+	}
+
 	return rdesc;
 }

@@ -1536,6 +1585,9 @@ static const struct hid_device_id asus_devices[] = {
 	  QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
 	{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
 		USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_T101HA_KEYBOARD) },
+	{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
+		USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_T3304_KEYBOARD),
+	  QUIRK_T3304_KEYBOARD },
 	{ }
 };
 MODULE_DEVICE_TABLE(hid, asus_devices);
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 0cf63742315b..ecf30e36a99d 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -219,6 +219,7 @@
 #define USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD	0x8502
 #define USB_DEVICE_ID_ASUSTEK_T101HA_KEYBOARD	0x183d
 #define USB_DEVICE_ID_ASUSTEK_T304_KEYBOARD	0x184a
+#define USB_DEVICE_ID_ASUSTEK_T3304_KEYBOARD	0x1aad
 #define USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD	0x8585
 #define USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD	0x0101
 #define USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD1 0x1854
--
2.54.0

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 4/6] HID: multitouch: add support for ASUS T3304 media keys
  2026-05-03  7:26 [PATCH 0/6] HID: asus: add support for T3304 keyboard James Ye
                   ` (2 preceding siblings ...)
  2026-05-03  7:26 ` [PATCH 3/6] HID: asus: add support for T3304 detachable keyboard James Ye
@ 2026-05-03  7:26 ` James Ye
  2026-05-03  7:26 ` [PATCH 5/6] HID: asus: add microphone mute LED support for T3304 James Ye
  2026-05-03  7:26 ` [PATCH 6/6] leds: led-class: mark classdev as unregistering early James Ye
  5 siblings, 0 replies; 12+ messages in thread
From: James Ye @ 2026-05-03  7:26 UTC (permalink / raw)
  To: jikos, bentiss, lee, pavel
  Cc: linux-input, linux-leds, linux-kernel, denis.benato, James Ye

Touchpad functionality already works with hid-multitouch, but media key
events are emitted from the touchpad interface. Add MT_CLS_ASUS to
handle these, and also add missing key mappings.

Signed-off-by: James Ye <jye836@gmail.com>
---
 drivers/hid/hid-multitouch.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index e82a3c4e5b44..a49930496c5b 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -1510,6 +1510,10 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 		case 0x35: mt_map_key_clear(KEY_DISPLAY_OFF);		break;
 		case 0x6b: mt_map_key_clear(KEY_F21);			break;
 		case 0x6c: mt_map_key_clear(KEY_SLEEP);			break;
+		case 0x7c: mt_map_key_clear(KEY_MICMUTE);		break;
+		case 0x4e: mt_map_key_clear(KEY_FN_ESC);		break;
+
+		case 0x86: mt_map_key_clear(KEY_PROG1);		break; /* MyASUS key */
 		default:
 			return -1;
 		}
@@ -2145,6 +2149,12 @@ static const struct hid_device_id mt_devices[] = {
 			USB_VENDOR_ID_ASUSTEK,
 			USB_DEVICE_ID_ASUSTEK_T304_KEYBOARD) },
 
+	/* Asus T3304 */
+	{ .driver_data = MT_CLS_ASUS,
+		HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8,
+			USB_VENDOR_ID_ASUSTEK,
+			USB_DEVICE_ID_ASUSTEK_T3304_KEYBOARD) },
+
 	/* Atmel panels */
 	{ .driver_data = MT_CLS_SERIAL,
 		MT_USB_DEVICE(USB_VENDOR_ID_ATMEL,
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 5/6] HID: asus: add microphone mute LED support for T3304
  2026-05-03  7:26 [PATCH 0/6] HID: asus: add support for T3304 keyboard James Ye
                   ` (3 preceding siblings ...)
  2026-05-03  7:26 ` [PATCH 4/6] HID: multitouch: add support for ASUS T3304 media keys James Ye
@ 2026-05-03  7:26 ` James Ye
  2026-05-03 22:45   ` Denis Benato
  2026-05-03  7:26 ` [PATCH 6/6] leds: led-class: mark classdev as unregistering early James Ye
  5 siblings, 1 reply; 12+ messages in thread
From: James Ye @ 2026-05-03  7:26 UTC (permalink / raw)
  To: jikos, bentiss, lee, pavel
  Cc: linux-input, linux-leds, linux-kernel, denis.benato, James Ye

T3304 keyboard has a microphone mute LED indicator on the same key
(Fn+F9). Look this up with a led_classdev.

It does not have backlight LEDs, so return without failure from
asus_kbd_register_leds if backlight support is not present.

Signed-off-by: James Ye <jye836@gmail.com>
---
 drivers/hid/hid-asus.c | 51 +++++++++++++++++++++++++++++++++++++++---
 1 file changed, 48 insertions(+), 3 deletions(-)

diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
index e4c97fddfaf1..4f68bc40b8bf 100644
--- a/drivers/hid/hid-asus.c
+++ b/drivers/hid/hid-asus.c
@@ -100,6 +100,7 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
 #define QUIRK_ROG_ALLY_XPAD		BIT(13)
 #define QUIRK_HID_FN_LOCK		BIT(14)
 #define QUIRK_T3304_KEYBOARD		BIT(15)
+#define QUIRK_HID_MICMUTE		BIT(16)
 
 #define I2C_KEYBOARD_QUIRKS			(QUIRK_FIX_NOTEBOOK_REPORT | \
 						 QUIRK_NO_INIT_REPORTS | \
@@ -144,6 +145,7 @@ struct asus_drvdata {
 	unsigned long battery_next_query;
 	struct work_struct fn_lock_sync_work;
 	bool fn_lock;
+	struct led_classdev led_micmute;
 };
 
 static int asus_report_battery(struct asus_drvdata *, u8 *, int);
@@ -578,6 +580,26 @@ static int asus_kbd_disable_oobe(struct hid_device *hdev)
 	return 0;
 }
 
+static int asus_kbd_set_micmute_led(struct hid_device *hdev, bool enabled)
+{
+	u8 buf[] = { FEATURE_KBD_REPORT_ID, 0xd0, 0x7c, enabled };
+
+	return asus_kbd_set_report(hdev, buf, sizeof(buf));
+}
+
+static int asus_led_brightness_set(struct led_classdev *led_cdev,
+		enum led_brightness value)
+{
+	struct device *dev = led_cdev->dev->parent;
+	struct hid_device *hdev = to_hid_device(dev);
+	struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
+
+	if (led_cdev == &drvdata->led_micmute)
+		return asus_kbd_set_micmute_led(hdev, !!value);
+
+	return -ENODEV;
+}
+
 static int asus_kbd_set_fn_lock(struct hid_device *hdev, bool enabled)
 {
 	u8 buf[] = { FEATURE_KBD_REPORT_ID, 0xd0, 0x4e, !!enabled };
@@ -752,9 +774,31 @@ static int asus_kbd_register_leds(struct hid_device *hdev)
 	if (ret < 0)
 		return ret;
 
+	if (drvdata->quirks & QUIRK_HID_MICMUTE) {
+		char *name_micmute;
+		size_t name_sz = strlen(dev_name(&hdev->dev)) + 16;
+
+		name_micmute = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL);
+		if (name_micmute == NULL)
+			return -ENOMEM;
+
+		snprintf(name_micmute, name_sz, "%s::micmute", dev_name(&hdev->dev));
+		drvdata->led_micmute.name = name_micmute;
+		drvdata->led_micmute.default_trigger = "audio-micmute";
+		drvdata->led_micmute.brightness_set_blocking = asus_led_brightness_set;
+		drvdata->led_micmute.max_brightness = 1;
+		drvdata->led_micmute.flags = LED_CORE_SUSPENDRESUME | LED_HW_PLUGGABLE;
+		drvdata->led_micmute.dev = &hdev->dev;
+		ret = devm_led_classdev_register(&hdev->dev, &drvdata->led_micmute);
+		if (ret < 0) {
+			hid_err(hdev, "Failed to register LED: %d.\n", ret);
+			return ret;
+		}
+	}
+
 	/* Check for backlight support */
 	if (!(kbd_func & SUPPORT_KBD_BACKLIGHT))
-		return -ENODEV;
+		return 0;
 
 	if (dmi_match(DMI_PRODUCT_FAMILY, "ProArt P16")) {
 		ret = asus_kbd_disable_oobe(hdev);
@@ -1315,7 +1359,8 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
 	}
 
 	/* Laptops keyboard backlight is always at 0x5a */
-	if (is_vendor && (drvdata->quirks & QUIRK_USE_KBD_BACKLIGHT) &&
+	if (is_vendor &&
+	    (drvdata->quirks & (QUIRK_USE_KBD_BACKLIGHT | QUIRK_HID_MICMUTE)) &&
 	    (asus_has_report_id(hdev, FEATURE_KBD_REPORT_ID)) &&
 		(asus_kbd_register_leds(hdev)))
 		hid_warn(hdev, "Failed to initialize backlight.\n");
@@ -1587,7 +1632,7 @@ static const struct hid_device_id asus_devices[] = {
 		USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_T101HA_KEYBOARD) },
 	{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
 		USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_T3304_KEYBOARD),
-	  QUIRK_T3304_KEYBOARD },
+	  QUIRK_T3304_KEYBOARD | QUIRK_HID_MICMUTE },
 	{ }
 };
 MODULE_DEVICE_TABLE(hid, asus_devices);
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 6/6] leds: led-class: mark classdev as unregistering early
  2026-05-03  7:26 [PATCH 0/6] HID: asus: add support for T3304 keyboard James Ye
                   ` (4 preceding siblings ...)
  2026-05-03  7:26 ` [PATCH 5/6] HID: asus: add microphone mute LED support for T3304 James Ye
@ 2026-05-03  7:26 ` James Ye
  2026-05-04 21:49   ` kernel test robot
  2026-05-05  2:24   ` kernel test robot
  5 siblings, 2 replies; 12+ messages in thread
From: James Ye @ 2026-05-03  7:26 UTC (permalink / raw)
  To: jikos, bentiss, lee, pavel
  Cc: linux-input, linux-leds, linux-kernel, denis.benato, James Ye

The classdev was marked as unregistering after disabling the trigger.
Disabling the trigger attempts to turn the LED off, and the device may
already be inaccessible. This generates a "Setting an LED's brightness
failed" log, which is avoided by changing this order.

Signed-off-by: James Ye <jye836@gmail.com>
---
 drivers/leds/led-class.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
index 9e14ae588f78..a00986ffd9f6 100644
--- a/drivers/leds/led-class.c
+++ b/drivers/leds/led-class.c
@@ -601,6 +601,8 @@ void led_classdev_unregister(struct led_classdev *led_cdev)
 	if (IS_ERR_OR_NULL(led_cdev->dev))
 		return;
 
+	led_cdev->flags |= LED_UNREGISTERING;
+
 #ifdef CONFIG_LEDS_TRIGGERS
 	down_write(&led_cdev->trigger_lock);
 	if (led_cdev->trigger)
@@ -608,8 +610,6 @@ void led_classdev_unregister(struct led_classdev *led_cdev)
 	up_write(&led_cdev->trigger_lock);
 #endif
 
-	led_cdev->flags |= LED_UNREGISTERING;
-
 	/* Stop blinking */
 	led_stop_software_blink(led_cdev);
 
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/6] HID: asus: add support for T3304 detachable keyboard
  2026-05-03  7:26 ` [PATCH 3/6] HID: asus: add support for T3304 detachable keyboard James Ye
@ 2026-05-03 22:23   ` Denis Benato
  0 siblings, 0 replies; 12+ messages in thread
From: Denis Benato @ 2026-05-03 22:23 UTC (permalink / raw)
  To: James Ye, jikos, bentiss, lee, pavel
  Cc: linux-input, linux-leds, linux-kernel


On 5/3/26 09:26, James Ye wrote:
> ASUSTek Computer, Inc. T3304 Soft Keyboard [0b05:1aad] is the detachable
> keyboard of the ASUS Vivobook 13 Slate OLED (T3304). It presents as a
> USB device with two interfaces: a keyboard and a pointing device
> (touchpad).
>
> Basic keyboard and full touchpad functionality work out-of-the-box with
> hid-generic and hid-multitouch, but function key combos e.g. volume,
> brightness control, home/end/pgup/pgdown require initialization.
>
> Bind the keyboard interface to hid-asus for initialization. The
> OEM-specific report descriptors required for this are present only on
> the touchpad interface, not the keyboard, so a quirk is used to add the
> required feature descriptor.
Reviewed-By: Denis Benato <denis.benato@linux.dev>
> Signed-off-by: James Ye <jye836@gmail.com>
> ---
>  drivers/hid/hid-asus.c | 58 +++++++++++++++++++++++++++++++++++++++---
>  drivers/hid/hid-ids.h  |  1 +
>  2 files changed, 56 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
> index ef9d5eba4dc9..e4c97fddfaf1 100644
> --- a/drivers/hid/hid-asus.c
> +++ b/drivers/hid/hid-asus.c
> @@ -99,6 +99,7 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
>  #define QUIRK_ROG_CLAYMORE_II_KEYBOARD	BIT(12)
>  #define QUIRK_ROG_ALLY_XPAD		BIT(13)
>  #define QUIRK_HID_FN_LOCK		BIT(14)
> +#define QUIRK_T3304_KEYBOARD		BIT(15)
>
>  #define I2C_KEYBOARD_QUIRKS			(QUIRK_FIX_NOTEBOOK_REPORT | \
>  						 QUIRK_NO_INIT_REPORTS | \
> @@ -494,6 +495,14 @@ static int asus_kbd_init(struct hid_device *hdev, u8 report_id)
>  		return ret;
>  	}
>
> +	struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
> +
> +	/* T3304 keyboard always replies with 16 0xff bytes. Don't check for
> +	 * acknowledgment.
> +	 */
> +	if (drvdata->quirks & QUIRK_T3304_KEYBOARD)
> +		return 0;
> +
>  	u8 *readbuf __free(kfree) = kzalloc(FEATURE_KBD_REPORT_SIZE, GFP_KERNEL);
>  	if (!readbuf)
>  		return -ENOMEM;
> @@ -1312,10 +1321,12 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
>  		hid_warn(hdev, "Failed to initialize backlight.\n");
>
>  	/*
> -	 * For ROG keyboards, skip rename for consistency and ->input check as
> -	 * some devices do not have inputs.
> +	 * For ROG and T3304 keyboards, skip rename for consistency.
> +	 * For ROG keyboards, skip ->input check as some devices do not have
> +	 * inputs.
>  	 */
> -	if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD)
> +	if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD ||
> +	    drvdata->quirks & QUIRK_T3304_KEYBOARD)
>  		return 0;
>
>  	/*
> @@ -1369,6 +1380,22 @@ static const __u8 asus_g752_fixed_rdesc[] = {
>          0x2A, 0xFF, 0x00,		/*   Usage Maximum (0xFF)       */
>  };
>
> +static const __u8 asus_t3304_fixed_rdesc[] = {
> +	0x06, 0x31, 0xff,              // Usage Page (Vendor Usage Page 0xff31)
> +	0x09, 0x76,                    // Usage (Vendor Usage 0x76)
> +	0xa1, 0x01,                    // Collection (Application)
> +	0x05, 0xff,                    //  Usage Page (Vendor Usage Page 0xff)
> +	0x85, 0x5a,                    //  Report ID (90)
> +	0x19, 0x00,                    //  Usage Minimum (0)
> +	0x2a, 0xff, 0x00,              //  Usage Maximum (255)
> +	0x15, 0x00,                    //  Logical Minimum (0)
> +	0x26, 0xff, 0x00,              //  Logical Maximum (255)
> +	0x75, 0x08,                    //  Report Size (8)
> +	0x95, 0x0f,                    //  Report Count (15)
> +	0xb1, 0x02,                    //  Feature (Data,Var,Abs)
> +	0xc0,                          // End Collection
> +};
> +
>  static const __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc,
>  		unsigned int *rsize)
>  {
> @@ -1473,6 +1500,28 @@ static const __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc,
>  		}
>  	}
>
> +	/* T3304 keyboard's vendor descriptors are on the touchpad interface,
> +	 * not the keyboard. But we need hid-multitouch to handle the touchpad,
> +	 * Add a descriptor with only the config report so that this driver can
> +	 * perform initialization.
> +	 */
> +	if (drvdata->quirks & QUIRK_T3304_KEYBOARD) {
> +		__u8 *new_rdesc;
> +		size_t new_size = *rsize + sizeof(asus_t3304_fixed_rdesc);
> +
> +		new_rdesc = devm_kzalloc(&hdev->dev, new_size, GFP_KERNEL);
> +		if (new_rdesc == NULL)
> +			return rdesc;
> +
> +		hid_info(hdev, "Fixing up Asus T3304 keyboard report descriptor\n");
> +		memcpy(new_rdesc, rdesc, *rsize);
> +		memcpy(new_rdesc + *rsize, asus_t3304_fixed_rdesc,
> +		       sizeof(asus_t3304_fixed_rdesc));
> +
> +		*rsize = new_size;
> +		rdesc = new_rdesc;
> +	}
> +
>  	return rdesc;
>  }
>
> @@ -1536,6 +1585,9 @@ static const struct hid_device_id asus_devices[] = {
>  	  QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
>  	{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
>  		USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_T101HA_KEYBOARD) },
> +	{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
> +		USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_T3304_KEYBOARD),
> +	  QUIRK_T3304_KEYBOARD },
>  	{ }
>  };
>  MODULE_DEVICE_TABLE(hid, asus_devices);
> diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
> index 0cf63742315b..ecf30e36a99d 100644
> --- a/drivers/hid/hid-ids.h
> +++ b/drivers/hid/hid-ids.h
> @@ -219,6 +219,7 @@
>  #define USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD	0x8502
>  #define USB_DEVICE_ID_ASUSTEK_T101HA_KEYBOARD	0x183d
>  #define USB_DEVICE_ID_ASUSTEK_T304_KEYBOARD	0x184a
> +#define USB_DEVICE_ID_ASUSTEK_T3304_KEYBOARD	0x1aad
>  #define USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD	0x8585
>  #define USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD	0x0101
>  #define USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD1 0x1854
> --
> 2.54.0

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 5/6] HID: asus: add microphone mute LED support for T3304
  2026-05-03  7:26 ` [PATCH 5/6] HID: asus: add microphone mute LED support for T3304 James Ye
@ 2026-05-03 22:45   ` Denis Benato
  2026-05-04  1:27     ` James Ye
  0 siblings, 1 reply; 12+ messages in thread
From: Denis Benato @ 2026-05-03 22:45 UTC (permalink / raw)
  To: James Ye, jikos, bentiss, lee, pavel
  Cc: linux-input, linux-leds, linux-kernel


On 5/3/26 09:26, James Ye wrote:
> T3304 keyboard has a microphone mute LED indicator on the same key
> (Fn+F9). Look this up with a led_classdev.
>
> It does not have backlight LEDs, so return without failure from
> asus_kbd_register_leds if backlight support is not present.
>
> Signed-off-by: James Ye <jye836@gmail.com>
> ---
>  drivers/hid/hid-asus.c | 51 +++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 48 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
> index e4c97fddfaf1..4f68bc40b8bf 100644
> --- a/drivers/hid/hid-asus.c
> +++ b/drivers/hid/hid-asus.c
> @@ -100,6 +100,7 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
>  #define QUIRK_ROG_ALLY_XPAD		BIT(13)
>  #define QUIRK_HID_FN_LOCK		BIT(14)
>  #define QUIRK_T3304_KEYBOARD		BIT(15)
> +#define QUIRK_HID_MICMUTE		BIT(16)
>  
Isn't QUIRK_T3304_KEYBOARD enough? Or are you saying you know there is more than one keyboard
model that requires this?
>  #define I2C_KEYBOARD_QUIRKS			(QUIRK_FIX_NOTEBOOK_REPORT | \
>  						 QUIRK_NO_INIT_REPORTS | \
> @@ -144,6 +145,7 @@ struct asus_drvdata {
>  	unsigned long battery_next_query;
>  	struct work_struct fn_lock_sync_work;
>  	bool fn_lock;
> +	struct led_classdev led_micmute;
>  };
>  
>  static int asus_report_battery(struct asus_drvdata *, u8 *, int);
> @@ -578,6 +580,26 @@ static int asus_kbd_disable_oobe(struct hid_device *hdev)
>  	return 0;
>  }
>  
> +static int asus_kbd_set_micmute_led(struct hid_device *hdev, bool enabled)
> +{
> +	u8 buf[] = { FEATURE_KBD_REPORT_ID, 0xd0, 0x7c, enabled };
> +
> +	return asus_kbd_set_report(hdev, buf, sizeof(buf));
> +}
> +
> +static int asus_led_brightness_set(struct led_classdev *led_cdev,
> +		enum led_brightness value)
> +{
> +	struct device *dev = led_cdev->dev->parent;
> +	struct hid_device *hdev = to_hid_device(dev);
> +	struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
> +
> +	if (led_cdev == &drvdata->led_micmute)
> +		return asus_kbd_set_micmute_led(hdev, !!value);
> +
> +	return -ENODEV;
> +}
> +
>  static int asus_kbd_set_fn_lock(struct hid_device *hdev, bool enabled)
>  {
>  	u8 buf[] = { FEATURE_KBD_REPORT_ID, 0xd0, 0x4e, !!enabled };
> @@ -752,9 +774,31 @@ static int asus_kbd_register_leds(struct hid_device *hdev)
>  	if (ret < 0)
>  		return ret;
>  
> +	if (drvdata->quirks & QUIRK_HID_MICMUTE) {
> +		char *name_micmute;
> +		size_t name_sz = strlen(dev_name(&hdev->dev)) + 16;
> +
Do we really want to use strlen?

Do we really want to use strlen on the result of a function without additional checks?
> +		name_micmute = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL);
> +		if (name_micmute == NULL)
> +			return -ENOMEM;
> +
> +		snprintf(name_micmute, name_sz, "%s::micmute", dev_name(&hdev->dev));
> +		drvdata->led_micmute.name = name_micmute;
> +		drvdata->led_micmute.default_trigger = "audio-micmute";
> +		drvdata->led_micmute.brightness_set_blocking = asus_led_brightness_set;
> +		drvdata->led_micmute.max_brightness = 1;
> +		drvdata->led_micmute.flags = LED_CORE_SUSPENDRESUME | LED_HW_PLUGGABLE;
> +		drvdata->led_micmute.dev = &hdev->dev;
> +		ret = devm_led_classdev_register(&hdev->dev, &drvdata->led_micmute);
> +		if (ret < 0) {
> +			hid_err(hdev, "Failed to register LED: %d.\n", ret);
> +			return ret;
> +		}
> +	}
> +
>  	/* Check for backlight support */
>  	if (!(kbd_func & SUPPORT_KBD_BACKLIGHT))
> -		return -ENODEV;
> +		return 0;
>  
This doesn't look like a good idea to change this for all laptops under the sun...


Perhaps might make sense to move this check before? Maybe not?

Denis
>  	if (dmi_match(DMI_PRODUCT_FAMILY, "ProArt P16")) {
>  		ret = asus_kbd_disable_oobe(hdev);
> @@ -1315,7 +1359,8 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
>  	}
>  
>  	/* Laptops keyboard backlight is always at 0x5a */
> -	if (is_vendor && (drvdata->quirks & QUIRK_USE_KBD_BACKLIGHT) &&
> +	if (is_vendor &&
> +	    (drvdata->quirks & (QUIRK_USE_KBD_BACKLIGHT | QUIRK_HID_MICMUTE)) &&
>  	    (asus_has_report_id(hdev, FEATURE_KBD_REPORT_ID)) &&
>  		(asus_kbd_register_leds(hdev)))
>  		hid_warn(hdev, "Failed to initialize backlight.\n");
> @@ -1587,7 +1632,7 @@ static const struct hid_device_id asus_devices[] = {
>  		USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_T101HA_KEYBOARD) },
>  	{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
>  		USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_T3304_KEYBOARD),
> -	  QUIRK_T3304_KEYBOARD },
> +	  QUIRK_T3304_KEYBOARD | QUIRK_HID_MICMUTE },
>  	{ }
>  };
>  MODULE_DEVICE_TABLE(hid, asus_devices);

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 5/6] HID: asus: add microphone mute LED support for T3304
  2026-05-03 22:45   ` Denis Benato
@ 2026-05-04  1:27     ` James Ye
  0 siblings, 0 replies; 12+ messages in thread
From: James Ye @ 2026-05-04  1:27 UTC (permalink / raw)
  To: Denis Benato
  Cc: jikos, bentiss, lee, pavel, linux-input, linux-leds, linux-kernel

On Mon, 4 May 2026 at 08:45, Denis Benato <denis.benato@linux.dev> wrote:
> Isn't QUIRK_T3304_KEYBOARD enough? Or are you saying you know there is more than one keyboard
> model that requires this?

I don't know for certain if there are any other such keyboards with
LEDs that need to be handled like this, but I can imagine that there
are.

I decided to introduce an additional quirk because:
- I don't know how to detect if a micmute LED is present.
- The quirk could be used to implement support in other devices.
- asus_kbd_register_leds is also gated by QUIRK_USE_KBD_BACKLIGHT,
adding a device-specific quirk didn't feel appropriate.

If there turns out to be a widely-supported detection method and T330
doesn't support this, then just QUIRK_T3304_KEYBOARD would be better.

If you would prefer then I shall remove QUIRK_HID_MICMUTE. This can be
revisited when more than one device uses this code.

>
> Do we really want to use strlen?
>
> Do we really want to use strlen on the result of a function without additional checks?

My understanding is that this is safe, as this name is set by the
kernel. Existing use of dev_name appears to not involve additional
checks.

> This doesn't look like a good idea to change this for all laptops under the sun...
>
>
> Perhaps might make sense to move this check before? Maybe not?

Returning an error from asus_kbd_register_leds is currently non-fatal,
so the only difference in behaviour is that devices with
QUIRK_USE_KBD_BACKLIGHT that do not report supporting a backlight will
no longer log a warning.

T3304 indeed lacks a backlight, so we can't proceed with the backlight
setup code, but asus_kbd_get_functions() is still a prerequisite for
the micmute LED.

I think the alternative is:
- Move the asus_kbd_get_functions() call site from
asus_kbd_register_leds() to asus_probe(), and
- Separate asus_kbd_register_leds() into two functions for backlight
and micmute LEDs respectively, keeping the current behaviour for
backlight registration.

Your thoughts?

Cheers,
James

>
> Denis

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 6/6] leds: led-class: mark classdev as unregistering early
  2026-05-03  7:26 ` [PATCH 6/6] leds: led-class: mark classdev as unregistering early James Ye
@ 2026-05-04 21:49   ` kernel test robot
  2026-05-05  2:24   ` kernel test robot
  1 sibling, 0 replies; 12+ messages in thread
From: kernel test robot @ 2026-05-04 21:49 UTC (permalink / raw)
  To: James Ye, jikos, bentiss, lee, pavel
  Cc: llvm, oe-kbuild-all, linux-input, linux-leds, linux-kernel,
	denis.benato, James Ye

Hi James,

kernel test robot noticed the following build errors:

[auto build test ERROR on hid/for-next]
[also build test ERROR on lee-leds/for-leds-next linus/master v6.16-rc1 next-20260430]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/James-Ye/HID-input-delete-hid_battery-on-disconnect/20260504-013406
base:   https://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git for-next
patch link:    https://lore.kernel.org/r/20260503072643.2774762-7-jye836%40gmail.com
patch subject: [PATCH 6/6] leds: led-class: mark classdev as unregistering early
config: x86_64-kexec (https://download.01.org/0day-ci/archive/20260504/202605042355.hVEd8jjX-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260504/202605042355.hVEd8jjX-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202605042355.hVEd8jjX-lkp@intel.com/

All errors (new ones prefixed by >>):

>> drivers/hid/hid-input.c:2423:48: error: no member named 'batteries' in 'struct hid_device'
    2423 |         list_for_each_entry_safe(bat, bat_next, &hid->batteries, list) {
         |                                                  ~~~  ^
   include/linux/list.h:869:30: note: expanded from macro 'list_for_each_entry_safe'
     869 |         for (pos = list_first_entry(head, typeof(*pos), member),        \
         |                                     ^~~~
   include/linux/list.h:620:14: note: expanded from macro 'list_first_entry'
     620 |         list_entry((ptr)->next, type, member)
         |                     ^~~
   include/linux/list.h:609:15: note: expanded from macro 'list_entry'
     609 |         container_of(ptr, type, member)
         |                      ^~~
   include/linux/container_of.h:20:26: note: expanded from macro 'container_of'
      20 |         void *__mptr = (void *)(ptr);                                   \
         |                                 ^~~
>> drivers/hid/hid-input.c:2423:48: error: no member named 'batteries' in 'struct hid_device'
    2423 |         list_for_each_entry_safe(bat, bat_next, &hid->batteries, list) {
         |                                                  ~~~  ^
   include/linux/list.h:869:30: note: expanded from macro 'list_for_each_entry_safe'
     869 |         for (pos = list_first_entry(head, typeof(*pos), member),        \
         |                                     ^~~~
   include/linux/list.h:620:14: note: expanded from macro 'list_first_entry'
     620 |         list_entry((ptr)->next, type, member)
         |                     ^~~
   include/linux/list.h:609:15: note: expanded from macro 'list_entry'
     609 |         container_of(ptr, type, member)
         |                      ^~~
   note: (skipping 1 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
   include/linux/compiler_types.h:610:63: note: expanded from macro '__same_type'
     610 | #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
         |                                                               ^
   include/linux/build_bug.h:79:50: note: expanded from macro 'static_assert'
      79 | #define static_assert(expr, ...) __static_assert(expr, ##__VA_ARGS__, #expr)
         |                                                  ^~~~
   include/linux/build_bug.h:80:56: note: expanded from macro '__static_assert'
      80 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
>> drivers/hid/hid-input.c:2423:48: error: no member named 'batteries' in 'struct hid_device'
    2423 |         list_for_each_entry_safe(bat, bat_next, &hid->batteries, list) {
         |                                                  ~~~  ^
   include/linux/list.h:869:30: note: expanded from macro 'list_for_each_entry_safe'
     869 |         for (pos = list_first_entry(head, typeof(*pos), member),        \
         |                                     ^~~~
   include/linux/list.h:620:14: note: expanded from macro 'list_first_entry'
     620 |         list_entry((ptr)->next, type, member)
         |                     ^~~
   include/linux/list.h:609:15: note: expanded from macro 'list_entry'
     609 |         container_of(ptr, type, member)
         |                      ^~~
   note: (skipping 1 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
   include/linux/compiler_types.h:610:63: note: expanded from macro '__same_type'
     610 | #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
         |                                                               ^
   include/linux/build_bug.h:79:50: note: expanded from macro 'static_assert'
      79 | #define static_assert(expr, ...) __static_assert(expr, ##__VA_ARGS__, #expr)
         |                                                  ^~~~
   include/linux/build_bug.h:80:56: note: expanded from macro '__static_assert'
      80 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
>> drivers/hid/hid-input.c:2423:48: error: no member named 'batteries' in 'struct hid_device'
    2423 |         list_for_each_entry_safe(bat, bat_next, &hid->batteries, list) {
         |                                                  ~~~  ^
   include/linux/list.h:871:32: note: expanded from macro 'list_for_each_entry_safe'
     871 |              !list_entry_is_head(pos, head, member);                    \
         |                                       ^~~~
   include/linux/list.h:773:30: note: expanded from macro 'list_entry_is_head'
     773 |         list_is_head(&pos->member, (head))
         |                                     ^~~~
   4 errors generated.


vim +2423 drivers/hid/hid-input.c

  2407	
  2408	void hidinput_disconnect(struct hid_device *hid)
  2409	{
  2410		struct hid_input *hidinput, *next;
  2411		struct hid_battery *bat, *bat_next;
  2412	
  2413		list_for_each_entry_safe(hidinput, next, &hid->inputs, list) {
  2414			list_del(&hidinput->list);
  2415			if (hidinput->registered)
  2416				input_unregister_device(hidinput->input);
  2417			else
  2418				input_free_device(hidinput->input);
  2419			kfree(hidinput->name);
  2420			kfree(hidinput);
  2421		}
  2422	
> 2423		list_for_each_entry_safe(bat, bat_next, &hid->batteries, list) {
  2424			list_del(&bat->list);
  2425		}
  2426	
  2427		/* led_work is spawned by input_dev callbacks, but doesn't access the
  2428		 * parent input_dev at all. Once all input devices are removed, we
  2429		 * know that led_work will never get restarted, so we can cancel it
  2430		 * synchronously and are safe. */
  2431		cancel_work_sync(&hid->led_work);
  2432	}
  2433	EXPORT_SYMBOL_GPL(hidinput_disconnect);
  2434	

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 6/6] leds: led-class: mark classdev as unregistering early
  2026-05-03  7:26 ` [PATCH 6/6] leds: led-class: mark classdev as unregistering early James Ye
  2026-05-04 21:49   ` kernel test robot
@ 2026-05-05  2:24   ` kernel test robot
  1 sibling, 0 replies; 12+ messages in thread
From: kernel test robot @ 2026-05-05  2:24 UTC (permalink / raw)
  To: James Ye, jikos, bentiss, lee, pavel
  Cc: oe-kbuild-all, linux-input, linux-leds, linux-kernel,
	denis.benato, James Ye

Hi James,

kernel test robot noticed the following build errors:

[auto build test ERROR on hid/for-next]
[also build test ERROR on lee-leds/for-leds-next linus/master v7.1-rc2 next-20260504]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/James-Ye/HID-input-delete-hid_battery-on-disconnect/20260504-013406
base:   https://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git for-next
patch link:    https://lore.kernel.org/r/20260503072643.2774762-7-jye836%40gmail.com
patch subject: [PATCH 6/6] leds: led-class: mark classdev as unregistering early
config: x86_64-randconfig-2005-20250721 (https://download.01.org/0day-ci/archive/20260505/202605050414.YJmW3t4y-lkp@intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260505/202605050414.YJmW3t4y-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202605050414.YJmW3t4y-lkp@intel.com/

All errors (new ones prefixed by >>):

   In file included from include/linux/list.h:5,
                    from include/linux/module.h:12,
                    from drivers/hid/hid-input.c:16:
   drivers/hid/hid-input.c: In function 'hidinput_disconnect':
>> drivers/hid/hid-input.c:2423:53: error: 'struct hid_device' has no member named 'batteries'
    2423 |         list_for_each_entry_safe(bat, bat_next, &hid->batteries, list) {
         |                                                     ^~
   include/linux/container_of.h:20:33: note: in definition of macro 'container_of'
      20 |         void *__mptr = (void *)(ptr);                                   \
         |                                 ^~~
   include/linux/list.h:620:9: note: in expansion of macro 'list_entry'
     620 |         list_entry((ptr)->next, type, member)
         |         ^~~~~~~~~~
   include/linux/list.h:869:20: note: in expansion of macro 'list_first_entry'
     869 |         for (pos = list_first_entry(head, typeof(*pos), member),        \
         |                    ^~~~~~~~~~~~~~~~
   drivers/hid/hid-input.c:2423:9: note: in expansion of macro 'list_for_each_entry_safe'
    2423 |         list_for_each_entry_safe(bat, bat_next, &hid->batteries, list) {
         |         ^~~~~~~~~~~~~~~~~~~~~~~~
   In file included from include/linux/container_of.h:5:
>> drivers/hid/hid-input.c:2423:53: error: 'struct hid_device' has no member named 'batteries'
    2423 |         list_for_each_entry_safe(bat, bat_next, &hid->batteries, list) {
         |                                                     ^~
   include/linux/build_bug.h:80:56: note: in definition of macro '__static_assert'
      80 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:21:9: note: in expansion of macro 'static_assert'
      21 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:21:23: note: in expansion of macro '__same_type'
      21 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                       ^~~~~~~~~~~
   include/linux/list.h:609:9: note: in expansion of macro 'container_of'
     609 |         container_of(ptr, type, member)
         |         ^~~~~~~~~~~~
   include/linux/list.h:620:9: note: in expansion of macro 'list_entry'
     620 |         list_entry((ptr)->next, type, member)
         |         ^~~~~~~~~~
   include/linux/list.h:869:20: note: in expansion of macro 'list_first_entry'
     869 |         for (pos = list_first_entry(head, typeof(*pos), member),        \
         |                    ^~~~~~~~~~~~~~~~
   drivers/hid/hid-input.c:2423:9: note: in expansion of macro 'list_for_each_entry_safe'
    2423 |         list_for_each_entry_safe(bat, bat_next, &hid->batteries, list) {
         |         ^~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/hid/hid-input.c:2423:53: error: 'struct hid_device' has no member named 'batteries'
    2423 |         list_for_each_entry_safe(bat, bat_next, &hid->batteries, list) {
         |                                                     ^~
   include/linux/build_bug.h:80:56: note: in definition of macro '__static_assert'
      80 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:21:9: note: in expansion of macro 'static_assert'
      21 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:22:23: note: in expansion of macro '__same_type'
      22 |                       __same_type(*(ptr), void),                        \
         |                       ^~~~~~~~~~~
   include/linux/list.h:609:9: note: in expansion of macro 'container_of'
     609 |         container_of(ptr, type, member)
         |         ^~~~~~~~~~~~
   include/linux/list.h:620:9: note: in expansion of macro 'list_entry'
     620 |         list_entry((ptr)->next, type, member)
         |         ^~~~~~~~~~
   include/linux/list.h:869:20: note: in expansion of macro 'list_first_entry'
     869 |         for (pos = list_first_entry(head, typeof(*pos), member),        \
         |                    ^~~~~~~~~~~~~~~~
   drivers/hid/hid-input.c:2423:9: note: in expansion of macro 'list_for_each_entry_safe'
    2423 |         list_for_each_entry_safe(bat, bat_next, &hid->batteries, list) {
         |         ^~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/compiler_types.h:610:27: error: expression in static assertion is not an integer
     610 | #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/build_bug.h:80:56: note: in definition of macro '__static_assert'
      80 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:21:9: note: in expansion of macro 'static_assert'
      21 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:21:23: note: in expansion of macro '__same_type'
      21 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                       ^~~~~~~~~~~
   include/linux/list.h:609:9: note: in expansion of macro 'container_of'
     609 |         container_of(ptr, type, member)
         |         ^~~~~~~~~~~~
   include/linux/list.h:620:9: note: in expansion of macro 'list_entry'
     620 |         list_entry((ptr)->next, type, member)
         |         ^~~~~~~~~~
   include/linux/list.h:869:20: note: in expansion of macro 'list_first_entry'
     869 |         for (pos = list_first_entry(head, typeof(*pos), member),        \
         |                    ^~~~~~~~~~~~~~~~
   drivers/hid/hid-input.c:2423:9: note: in expansion of macro 'list_for_each_entry_safe'
    2423 |         list_for_each_entry_safe(bat, bat_next, &hid->batteries, list) {
         |         ^~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/hid/hid-input.c:2423:53: error: 'struct hid_device' has no member named 'batteries'
    2423 |         list_for_each_entry_safe(bat, bat_next, &hid->batteries, list) {
         |                                                     ^~
   include/linux/list.h:773:37: note: in definition of macro 'list_entry_is_head'
     773 |         list_is_head(&pos->member, (head))
         |                                     ^~~~
   drivers/hid/hid-input.c:2423:9: note: in expansion of macro 'list_for_each_entry_safe'
    2423 |         list_for_each_entry_safe(bat, bat_next, &hid->batteries, list) {
         |         ^~~~~~~~~~~~~~~~~~~~~~~~


vim +2423 drivers/hid/hid-input.c

  2407	
  2408	void hidinput_disconnect(struct hid_device *hid)
  2409	{
  2410		struct hid_input *hidinput, *next;
  2411		struct hid_battery *bat, *bat_next;
  2412	
  2413		list_for_each_entry_safe(hidinput, next, &hid->inputs, list) {
  2414			list_del(&hidinput->list);
  2415			if (hidinput->registered)
  2416				input_unregister_device(hidinput->input);
  2417			else
  2418				input_free_device(hidinput->input);
  2419			kfree(hidinput->name);
  2420			kfree(hidinput);
  2421		}
  2422	
> 2423		list_for_each_entry_safe(bat, bat_next, &hid->batteries, list) {
  2424			list_del(&bat->list);
  2425		}
  2426	
  2427		/* led_work is spawned by input_dev callbacks, but doesn't access the
  2428		 * parent input_dev at all. Once all input devices are removed, we
  2429		 * know that led_work will never get restarted, so we can cancel it
  2430		 * synchronously and are safe. */
  2431		cancel_work_sync(&hid->led_work);
  2432	}
  2433	EXPORT_SYMBOL_GPL(hidinput_disconnect);
  2434	

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2026-05-05  2:24 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-03  7:26 [PATCH 0/6] HID: asus: add support for T3304 keyboard James Ye
2026-05-03  7:26 ` [PATCH 1/6] HID: input: delete hid_battery on disconnect James Ye
2026-05-03  7:26 ` [PATCH 2/6] HID: asus: check feature reports when determining is_vendor James Ye
2026-05-03  7:26 ` [PATCH 3/6] HID: asus: add support for T3304 detachable keyboard James Ye
2026-05-03 22:23   ` Denis Benato
2026-05-03  7:26 ` [PATCH 4/6] HID: multitouch: add support for ASUS T3304 media keys James Ye
2026-05-03  7:26 ` [PATCH 5/6] HID: asus: add microphone mute LED support for T3304 James Ye
2026-05-03 22:45   ` Denis Benato
2026-05-04  1:27     ` James Ye
2026-05-03  7:26 ` [PATCH 6/6] leds: led-class: mark classdev as unregistering early James Ye
2026-05-04 21:49   ` kernel test robot
2026-05-05  2:24   ` kernel test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox