From nobody Fri Sep 25 06:46:14 2026 Received: from mta0.migadu.com (out-52.mta0.migadu.com [91.218.175.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 11B004BE439 for ; Tue, 15 Sep 2026 18:12:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789495934; cv=none; b=dt6+07pi0Rmy3QGZnp6d8rRfKMBPPUeyWEGutmKEYSN13LcbTp/DEM6xAgsOuCew9eT+kreJcazu8634OCLHNrvvNojhDOvD33cYyUxEhD8/H51I2FyFR9zEIUZ7ZT0m+KXoD959JptevXi88ufJ8GeB/FIEpuBkAJwfKLiw/p4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789495934; c=relaxed/simple; bh=E7RbFhHLJt+DOrkD7WYgzOURJt/v0VVzoD4303hHwYo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Vu3PrE66zGrBPJautnkj6taLP3jT/knlNsI3tmzpfjpubM89I4EhFy2YMVTVKSSV56BvYsgNXn4DlqCNDIh2YIP4P9TanSWb2W/8XxW9frRPmyZYHYgMm1MogoutJvCqzIu5nUH2d5NZiH3rU2NtuEXSfCYEtyAjdTH3t9gqPXs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=PxzM4MGz; arc=none smtp.client-ip=91.218.175.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="PxzM4MGz" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=E7RbFhHLJt+DOrkD7WYgzOURJt/v0VVzoD4303hHwYo=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1789495930; v=1; x=1790100730; b=PxzM4MGzjHjvvhO5mDwekHbqCR7bspr9IJuM+TqTu8M/HTF1CT6yu2Rk4xRp9KOmI7wO0zm5 KtoNXqE/e5dWMlI3x5KgjuV3Y/TZlyv564uwwx5BZAdDiss2zv8FghPrFof/ULfdtMVsbNSc82J s0ofPH55dtXeIi0e5czFEjPg= X-Envelope-To: linux-kernel@vger.kernel.org Received: by smtp.migadu.com with ESMTPS id a5ce936d8455cf12; Tue, 15 Sep 2026 18:12:10 +0000 X-Mizu-Trace-ID: a5ce936d8455cf12 X-Migadu-Flow: FLOW_OUT From: Denis Benato To: linux-kernel@vger.kernel.org Cc: linux-input@vger.kernel.org, "Benjamin Tissoires" , "Jiri Kosina" , "Luke D . Jones" , "Mateusz Schyboll" , "Denis Benato" , Denis Benato Subject: [PATCH 1/3] HID: asus: document and harden the worker teardown Date: Tue, 15 Sep 2026 18:11:58 +0000 Message-ID: <20260915181200.18086-2-denis.benato@linux.dev> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260915181200.18086-1-denis.benato@linux.dev> References: <20260915181200.18086-1-denis.benato@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" asus_work() executes actions against the device: they send feature reports with hid_hw_raw_request() and, for the Fn+F5 fan key fallback, re-inject the raw report into the HID core with hid_report_raw_event(). For this reason the worker must be quiesced before hid_hw_stop(): after the low level driver has stopped, the transport is gone (usbhid_stop() frees the URBs and the I/O buffers) and re-injected reports would race against the input devices being unregistered by hid_disconnect(). Make so that the teardown cannot race to a use-after-free: every site queueing an action holds worker->lock across the .removed check, the list insertion and schedule_work(), and asus_worker_stop() sets .removed and drains the queue under that same lock before calling cancel_work_sync(). An action that passed the check is caught by the latter while any later attempt is discarded by asus_worker_schedule(). Closes: https://lore.kernel.org/all/20260908180032.34C2D1F00A3A@smtp.kernel= .org/ Fixes: 47669bec44fe ("HID: asus: refactor the two workqueues and init seque= nce") Assisted-by: zcode:glm-5.3-flash Signed-off-by: Denis Benato --- drivers/hid/hid-asus.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index bd46aba6622a..3a8b8b7e90f7 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c @@ -765,9 +765,14 @@ static void asus_work(struct work_struct *work) struct asus_work_action *action =3D NULL; unsigned long flags; =20 - /* Save the action to be performed and clear the flag */ + /* + * Dequeue the next action, if any. Once teardown has begun .removed + * is set and asus_worker_stop() drains the queue: leave the queued + * actions alone, they are dropped instead of being executed against + * a device that is being removed. + */ spin_lock_irqsave(&worker->lock, flags); - if (!list_empty(&worker->actions)) { + if (!worker->removed && !list_empty(&worker->actions)) { action =3D list_first_entry(&worker->actions, struct asus_work_action, node); list_del(&action->node); @@ -817,6 +822,25 @@ static int asus_worker_create(struct hid_device *hdev,= struct asus_drvdata *drvd return 0; } =20 +/** + * asus_worker_stop - quiesce the worker + * @worker: the worker to quiesce + * + * Once this function returns no more actions can be queued and no instance + * of asus_work() is running or pending. + * + * Callers must do this before hid_hw_stop(): actions are executed while t= he + * device is fully operational, since they send raw requests to it and, in + * the fan-key fallback path, re-inject raw reports into the HID core. Aft= er + * hid_hw_stop() the transport is gone (usbhid_stop() frees the URBs and t= he + * I/O buffers) and the input devices have been unregistered. + * + * The quiescing is race free because every site that queues an action hol= ds + * worker->lock across the .removed check, the list insertion and + * schedule_work(): anything scheduled before .removed is set here is caug= ht + * by the cancel_work_sync() below, anything after it is discarded by + * asus_worker_schedule(). + */ static void asus_worker_stop(struct asus_worker *worker) { struct asus_work_action *action, *tmp; --=20 2.47.3 From nobody Fri Sep 25 06:46:14 2026 Received: from mta0.migadu.com (out-59.mta0.migadu.com [91.218.175.59]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 92A6C4BE43F for ; Tue, 15 Sep 2026 18:12:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.59 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789495939; cv=none; b=HAx6Z/JCprYSz8JZv+fzsgqAOud04l8aZ5Q7uGbreqOYOq84BRtH5mnkA3ZaSHgzG54GHYeGgJ1tP2QpcTx8QERnI0XY0L9JEvz+8VuXD1KTmBNPrORGNZm1/nTTvIUzjRWAgfiTInVijYh6tQ3CErc3Ul5SQRmtV7JkdY9L5Tk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789495939; c=relaxed/simple; bh=kSldjP/LJAFNxvSitEbFvA30E6J1HGiVZNJXHPDdUoQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rIYmvBKQwJqlyEDNxLg7xNFwwvxldMVznBAuJUjt6m6II02xQd5SwMzHOza3ZU21nZndyyk/UqLUfSjQnvm1vCwYTtr+d7wnJnqv6sa3y4dFGtSshw6O7LtMzkW1ga7JyJ55Ro1s7rGjmoAF3GOhpYbRRiMkDNfELsS3O2+BxO8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=smIUwk6B; arc=none smtp.client-ip=91.218.175.59 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="smIUwk6B" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=kSldjP/LJAFNxvSitEbFvA30E6J1HGiVZNJXHPDdUoQ=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1789495935; v=1; x=1790100735; b=smIUwk6Bvv0fulpl06BFLHJRtTJE4qVzTRVEuXvG1ICyhozCw09fOUfB/Wy/6azhZ/YtfUpY PSAtb9AMBte7vdMR83VBPUE8t/ggSWSV2WSZ9Rkz+nHedwUks6+MguDLihv3tn5KJfEBdQePslN LGvRWOudzF9dizptIVB6m1Sc= X-Envelope-To: linux-kernel@vger.kernel.org Received: by smtp.migadu.com with ESMTPS id 8438823b630f5064; Tue, 15 Sep 2026 18:12:15 +0000 X-Mizu-Trace-ID: 8438823b630f5064 X-Migadu-Flow: FLOW_OUT From: Denis Benato To: linux-kernel@vger.kernel.org Cc: linux-input@vger.kernel.org, "Benjamin Tissoires" , "Jiri Kosina" , "Luke D . Jones" , "Mateusz Schyboll" , "Denis Benato" , Denis Benato Subject: [PATCH 2/3] HID: asus: reinitialize the device after exiting a sleep state Date: Tue, 15 Sep 2026 18:11:59 +0000 Message-ID: <20260915181200.18086-3-denis.benato@linux.dev> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260915181200.18086-1-denis.benato@linux.dev> References: <20260915181200.18086-1-denis.benato@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The ROG ally needs to have the EC string sent back after resuming from s2idle since the USB device can be turned completely off by the firmware when mcu_powersave firmware-attribute is set to 1. This may also be true for other laptops and certain features might stop working after the device exit from sleep. Assisted-by: opencode:glm-5.2 Signed-off-by: Denis Benato --- drivers/hid/hid-asus.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index 3a8b8b7e90f7..03150d29eec5 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c @@ -1384,6 +1384,28 @@ static int asus_start_multitouch(struct hid_device *= hdev) return 0; } =20 +/* + * Initialize the reports of the device. + * + * Failures are intentionally not fatal: asus_kbd_init() tolerates a wrong + * handshake until this is verified to work for all devices, so a failure + * is only reported and the initialization of the remaining reports is + * still attempted. + */ +static void asus_initialize_reports(struct hid_device *hdev) +{ + int ret; + + for (int r =3D 0; r < ARRAY_SIZE(asus_report_id_init); r++) { + if (asus_has_report_id(hdev, asus_report_id_init[r])) { + ret =3D asus_kbd_init(hdev, asus_report_id_init[r]); + if (ret < 0) + hid_warn(hdev, "Failed to initialize 0x%x: %d.\n", + asus_report_id_init[r], ret); + } + } +} + static int __maybe_unused asus_resume(struct hid_device *hdev) { struct asus_drvdata *drvdata =3D hid_get_drvdata(hdev); @@ -1403,6 +1425,9 @@ static int __maybe_unused asus_reset_resume(struct hi= d_device *hdev) { struct asus_drvdata *drvdata =3D hid_get_drvdata(hdev); =20 + if (!drvdata->tp) + asus_initialize_reports(hdev); + if (drvdata->tp) return asus_start_multitouch(hdev); =20 @@ -1517,16 +1542,8 @@ static int asus_probe(struct hid_device *hdev, const= struct hid_device_id *id) return ret; } =20 - if (!drvdata->tp) { - for (int r =3D 0; r < ARRAY_SIZE(asus_report_id_init); r++) { - if (asus_has_report_id(hdev, asus_report_id_init[r])) { - ret =3D asus_kbd_init(hdev, asus_report_id_init[r]); - if (ret < 0) - hid_warn(hdev, "Failed to initialize 0x%x: %d.\n", - asus_report_id_init[r], ret); - } - } - } + if (!drvdata->tp) + asus_initialize_reports(hdev); =20 /* Laptops keyboard backlight is always at 0x5a */ if (is_vendor && (drvdata->quirks & QUIRK_USE_KBD_BACKLIGHT) && --=20 2.47.3 From nobody Fri Sep 25 06:46:14 2026 Received: from mta0.migadu.com (out-65.mta0.migadu.com [91.218.175.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BDA7F40A927 for ; Tue, 15 Sep 2026 18:12:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.65 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789495946; cv=none; b=XGQpnskMdVEsMiTsO85srh8qK2GeiNSCDBgII9daNmwodC4mQCFlLBCE8c7To7iR3nOGZl3g0pZSbJUDgVm/7LJk3Cey6RPcEab1xcrh58g9JWsQshRAYd/36PQ7lJgp7+14bF65pjGAqCatlO+UAmaYOkHOzd+9eb8d5PvK784= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789495946; c=relaxed/simple; bh=mWSonoI8Rf6kLGtR+hZdBol7nOHVUi5oG8LK3DaGXl4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=j62t+FcY6CenWECfP/nwrg77pWyp3viXLgWU5Balrim0EwjqCeKIz+CTulZosRtA5WjQVItLn7XhIuH2P2YQwrrD/aj7q+e4yAMcPdSLRFLPaF2oBAu0+6M0dvMoY+za+1IIh743nqwRH/C5nqo1/ivhtNiVus7QNEeEzuXmnws= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=NyFVnitE; arc=none smtp.client-ip=91.218.175.65 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="NyFVnitE" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=mWSonoI8Rf6kLGtR+hZdBol7nOHVUi5oG8LK3DaGXl4=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1789495940; v=1; x=1790100740; b=NyFVnitEIgFYzpY04Pn3i2mvuDpaW3qXFJ/vdi4uymMhvCND7dA9BozLKVw2wdnMyNOhD2qW kW4L2F6Fl1rhT8vLd4bNiYCcu4io1xWwVM8POquHqmlLhcxB7m0KDR7DXLiiiw2Gfq3d1oX2WwX Ue5Jx422uvxv3RoDcOUj7bDw= X-Envelope-To: linux-kernel@vger.kernel.org Received: by smtp.migadu.com with ESMTPS id 58d4f4e72a68db37; Tue, 15 Sep 2026 18:12:20 +0000 X-Mizu-Trace-ID: 58d4f4e72a68db37 X-Migadu-Flow: FLOW_OUT From: Denis Benato To: linux-kernel@vger.kernel.org Cc: linux-input@vger.kernel.org, "Benjamin Tissoires" , "Jiri Kosina" , "Luke D . Jones" , "Mateusz Schyboll" , "Denis Benato" , Denis Benato , Antheas Kapenekakis Subject: [PATCH 3/3] HID: asus: add support for xgm led Date: Tue, 15 Sep 2026 18:12:00 +0000 Message-ID: <20260915181200.18086-4-denis.benato@linux.dev> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260915181200.18086-1-denis.benato@linux.dev> References: <20260915181200.18086-1-denis.benato@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" XG mobile stations have very bright leds behind the fan that can be turned either ON or OFF: add a cled interface to allow controlling the brightness of those red leds. Let the led core manage the power transitions: the classdev is flagged with LED_CORE_SUSPENDRESUME, so it is switched off at suspend and its last brightness is restored at resume. The EC drives its own blinking pattern during s2idle anyway, so the led state while the machine is asleep is not meaningful. Cc: Antheas Kapenekakis Signed-off-by: Denis Benato --- drivers/hid/hid-asus.c | 84 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index 03150d29eec5..a427e272563d 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c @@ -51,6 +51,8 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad"); #define FEATURE_KBD_LED_REPORT_ID1 0x5d #define FEATURE_KBD_LED_REPORT_ID2 0x5e =20 +#define ROG_XGM_REPORT_SIZE 300 + #define ROG_ALLY_REPORT_SIZE 64 #define ROG_ALLY_X_MIN_MCU 313 #define ROG_ALLY_MIN_MCU 319 @@ -144,6 +146,11 @@ struct asus_worker { bool removed; }; =20 +struct asus_xgm_led { + struct led_classdev cdev; + struct hid_device *hdev; +}; + struct asus_touchpad_info { int max_x; int max_y; @@ -170,6 +177,7 @@ struct asus_drvdata { unsigned long battery_next_query; struct asus_hid_listener listener; bool fn_lock; + struct asus_xgm_led *xgm_led; }; =20 static int asus_report_battery(struct asus_drvdata *, u8 *, int); @@ -1161,6 +1169,26 @@ static int asus_battery_probe(struct hid_device *hde= v) return ret; } =20 +static int asus_xgm_led_set(struct led_classdev *led_cdev, enum led_bright= ness value) +{ + const u8 buf[ROG_XGM_REPORT_SIZE] =3D { + FEATURE_KBD_LED_REPORT_ID2, 0xC5, (value) ? 0x50 : 0x00 + }; + struct asus_xgm_led *xgm =3D container_of(led_cdev, struct asus_xgm_led, = cdev); + int ret; + + ret =3D asus_kbd_set_report(xgm->hdev, buf, ROG_XGM_REPORT_SIZE); + if (ret < 0) { + hid_err(xgm->hdev, "Unable to set XG mobile led state: %d\n", ret); + return ret; + } else if (ret !=3D ROG_XGM_REPORT_SIZE) { + hid_err(xgm->hdev, "Unexpected partial transfer to XG mobile: %d\n", ret= ); + return -EIO; + } + + return 0; +} + static int asus_input_configured(struct hid_device *hdev, struct hid_input= *hi) { struct input_dev *input =3D hi->input; @@ -1406,6 +1434,49 @@ static void asus_initialize_reports(struct hid_devic= e *hdev) } } =20 +static int asus_xgm_init(struct hid_device *hdev, struct asus_drvdata *drv= data) +{ + const char *name; + int ret; + + drvdata->xgm_led =3D devm_kzalloc(&hdev->dev, sizeof(*drvdata->xgm_led), = GFP_KERNEL); + if (drvdata->xgm_led =3D=3D NULL) + return -ENOMEM; + + name =3D devm_kasprintf(&hdev->dev, GFP_KERNEL, "asus:xgm-%s:led", + strlen(hdev->uniq) ? hdev->uniq : dev_name(&hdev->dev)); + + if (name =3D=3D NULL) { + ret =3D -ENOMEM; + goto asus_xgm_init_err; + } + + drvdata->xgm_led->hdev =3D hdev; + drvdata->xgm_led->cdev.name =3D name; + drvdata->xgm_led->cdev.brightness =3D 1; + drvdata->xgm_led->cdev.max_brightness =3D 1; + drvdata->xgm_led->cdev.brightness_set_blocking =3D asus_xgm_led_set; + drvdata->xgm_led->cdev.flags =3D LED_CORE_SUSPENDRESUME; + + /* LED state is arbitrary on boot, set a default */ + ret =3D asus_xgm_led_set(&drvdata->xgm_led->cdev, drvdata->xgm_led->cdev.= brightness); + if (ret) { + hid_err(hdev, "Asus failed to set xgm led: %d\n", ret); + goto asus_xgm_init_err; + } + + ret =3D devm_led_classdev_register(&hdev->dev, &drvdata->xgm_led->cdev); + if (ret) { + hid_err(hdev, "Asus failed to register xgm led: %d\n", ret); + goto asus_xgm_init_err; + } + + return 0; +asus_xgm_init_err: + drvdata->xgm_led =3D NULL; + return ret; +} + static int __maybe_unused asus_resume(struct hid_device *hdev) { struct asus_drvdata *drvdata =3D hid_get_drvdata(hdev); @@ -1545,6 +1616,16 @@ static int asus_probe(struct hid_device *hdev, const= struct hid_device_id *id) if (!drvdata->tp) asus_initialize_reports(hdev); =20 + if (asus_has_report_id(hdev, FEATURE_KBD_REPORT_ID) && + ((hdev->product =3D=3D USB_DEVICE_ID_ASUSTEK_XGM_2022) || + (hdev->product =3D=3D USB_DEVICE_ID_ASUSTEK_XGM_2023))) { + ret =3D asus_xgm_init(hdev, drvdata); + if (ret) { + hid_err(hdev, "Failed to initialize xg mobile: %d\n", ret); + goto err_stop_hw; + } + } + /* Laptops keyboard backlight is always at 0x5a */ if (is_vendor && (drvdata->quirks & QUIRK_USE_KBD_BACKLIGHT) && (asus_has_report_id(hdev, FEATURE_KBD_REPORT_ID)) && @@ -1594,6 +1675,9 @@ static void asus_remove(struct hid_device *hdev) if (drvdata->listener.brightness_set) asus_hid_unregister_listener(&drvdata->listener); =20 + if (drvdata->xgm_led) + devm_led_classdev_unregister(&hdev->dev, &drvdata->xgm_led->cdev); + asus_worker_stop(drvdata->worker); hid_hw_stop(hdev); } --=20 2.47.3