From nobody Mon Jun 8 20:54:15 2026 Received: from sender4-op-o15.zoho.com (sender4-op-o15.zoho.com [136.143.188.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7D268274670; Tue, 26 May 2026 18:34:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=136.143.188.15 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779820443; cv=pass; b=kTrn+c5x8yJOzr+vyWJlYnb8kxJ8OxZTiX4ur3dw4ke0t3nmwOGB02uYunz4irguOdpvH+l6+FTX4X4NHnXv8JnQWB7ta98BTC1OxOO48eiEv7xQWe6MCMezJbQgNkQmrsT8NoEP0xW9/2SSHpvWI9bvKMJ9WSghNtuVqt5m97U= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779820443; c=relaxed/simple; bh=a42bEj4BPedTC4K4wJ7Psyc3lisaBUcp7A4pVwQ25HI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=W9T1IXl4R9XB9osxib++vimJ0BhOJGELCg98078wg6RLfesO5eymI+PFcjI3cfP3r38Lov8mcrmIDeiBF+HD6QDqm8tLtrSTGIrs0Cv7vcy6JN73HjBzfEZPxl7Ju4omQvlKmU6zsfjcJd/fsy8DOv5rGFOIwrKP2jqV0PdtwHU= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rong.moe; spf=pass smtp.mailfrom=rong.moe; dkim=pass (2048-bit key) header.d=rong.moe header.i=i@rong.moe header.b=GYOqmIBW; arc=pass smtp.client-ip=136.143.188.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rong.moe Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rong.moe Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=rong.moe header.i=i@rong.moe header.b="GYOqmIBW" ARC-Seal: i=1; a=rsa-sha256; t=1779820432; cv=none; d=zohomail.com; s=zohoarc; b=F6t5SVYemoTpG2bJyVr7uSO4VSRDToiYBFI4gLjInAuNtUQKq/zvaChUA9XSEyN2N45i05UgxOuXMAKz+jkRWkHrSALDxerFrVAEsHkqAjOPnbjT8GvykI9Xl66Lwe9JNfYm4xf4e3Q4jmhrX0pgK2Uz5BHJgT3HxUFimVgPY4c= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1779820432; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=eaikGadZPM1Qgx8PCRgB0wgBMW7yI8+qqFaAHygEo60=; b=kjWtOpuT6dstJa2AyQOFEezZhG+vObBup2WHvPFZoR5UgrFcSYfjwNWrzS7RJZZfUe30IeQ/ZaZZvbGTeRYfNDSZY+xOIs0sJNuBQ6jT2Zg+S986nAfbqMZ123rdqtRO3VI7VQbRpusNVknFO60fePyuWuFwqDCSqZmpTFe26GY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=rong.moe; spf=pass smtp.mailfrom=i@rong.moe; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1779820432; s=zmail2048; d=rong.moe; i=i@rong.moe; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:References:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=eaikGadZPM1Qgx8PCRgB0wgBMW7yI8+qqFaAHygEo60=; b=GYOqmIBWrJ9krmBttyDE1H/k5NRXyUVaeDHtjE/WRDoCc7PtAw+PRD/ZW+KqZW7q B45WvPsWdUfansrBgcVRk+duGOuiukczqQHHZAV7RWBJ2h4KIHD151CiR/K6LY/EISC Awgv7sY+l96dUv09ww3zE7Ujyaaf1xWPE2wxG90FsgRb1IMAW54z7teq862VTECTY0W 7BL+T726tFku/8M+6WnVoad7B2hGZNkf9f0K44wyyu74XY3qxS8gU/Mb9rJu8rgiB54 ik0l/Z/YlRai+dJ0jpp/VCFg0V/n23e6ZT/WrDXt/iiQIfEI16g/8VubQBLjHLyxtwo jfGH/pNcig== Received: by mx.zohomail.com with SMTPS id 1779820431845756.9517239776911; Tue, 26 May 2026 11:33:51 -0700 (PDT) From: Rong Zhang Date: Wed, 27 May 2026 02:31:31 +0800 Subject: [PATCH 1/2] ACPI: battery: Synchronize get_property() callback Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260527-b4-acpi-battery-notification-v1-1-2303bed8ec0b@rong.moe> References: <20260527-b4-acpi-battery-notification-v1-0-2303bed8ec0b@rong.moe> In-Reply-To: <20260527-b4-acpi-battery-notification-v1-0-2303bed8ec0b@rong.moe> To: "Rafael J. Wysocki" , Len Brown Cc: "Rafael J. Wysocki" , linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?Jeffrey_W=C3=A4lti?= , stable@vger.kernel.org, Rick , Rong Zhang X-Mailer: b4 0.16-dev-d5d98 X-ZohoMailClient: External The acpi_battery_get_property() callback calls acpi_battery_get_state() without battery->update_lock held, which could lead to race conditions, e.g., when multiple tasks read power supply properties simultaneously, or when other synchronized methods are called during its execution. Moreover, some devices' _BST method relies on a heavily shared ACPI mutex which protects EC accesses, so it cannot tolerate too much pressure or else other methods will time out. The lack of synchronization sometimes nullifies the cache mechanism of acpi_battery_get_state() when multiple processes read power supply properties simultaneously, which usually happens after a uevent. Normally, emitting a uevent implies that the cache must have been refreshed due to power_supply_uevent() reading all properties, so the mentioned processes should have seen cache hits. Unfortunately, these fragile devices' power_supply_ext properties are somehow slow to read after battery events, resulting in cache expiration before power_supply_uevent() finishes. Hence, once the uevent reaches userspace, the _BST method will be executed multiple times within a short period due to userspace processes reading all properties again. The coincidence causes lock starvation, resulting in a catastrophic situation that a lot of ACPI methods fail to acquire the shared ACPI mutex due to timeout and return garbage data thanks to the firmware's poorly designed error paths. Protect acpi_battery_get_property() with update_lock to synchronize it. The helper function acpi_battery_handle_discharging() for quirky devices has to be inlined due to the change, as the mutex must be unlocked before calling the expensive power_supply_is_system_supplied() helper function. Tested-by: Jeffrey W=C3=A4lti Fixes: 399dbcadc01e ("ACPI: battery: Add synchronization between interface = updates") Cc: stable@vger.kernel.org Reported-by: Rick Closes: https://bugzilla.kernel.org/show_bug.cgi?id=3D221065 Signed-off-by: Rong Zhang --- drivers/acpi/battery.c | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index b82dd67d98c9..5f06841b48a1 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -180,20 +180,6 @@ static bool acpi_battery_is_degraded(struct acpi_batte= ry *battery) battery->full_charge_capacity < battery->design_capacity; } =20 -static int acpi_battery_handle_discharging(struct acpi_battery *battery) -{ - /* - * Some devices wrongly report discharging if the battery's charge level - * was above the device's start charging threshold atm the AC adapter - * was plugged in and the device thus did not start a new charge cycle. - */ - if ((battery_ac_is_broken || power_supply_is_system_supplied()) && - battery->rate_now =3D=3D 0) - return POWER_SUPPLY_STATUS_NOT_CHARGING; - - return POWER_SUPPLY_STATUS_DISCHARGING; -} - static int acpi_battery_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) @@ -201,15 +187,35 @@ static int acpi_battery_get_property(struct power_sup= ply *psy, int full_capacity =3D ACPI_BATTERY_VALUE_UNKNOWN, ret =3D 0; struct acpi_battery *battery =3D to_acpi_battery(psy); =20 + mutex_lock(&battery->update_lock); + if (acpi_battery_present(battery)) { /* run battery update only if it is present */ acpi_battery_get_state(battery); - } else if (psp !=3D POWER_SUPPLY_PROP_PRESENT) + } else if (psp !=3D POWER_SUPPLY_PROP_PRESENT) { + mutex_unlock(&battery->update_lock); return -ENODEV; + } switch (psp) { case POWER_SUPPLY_PROP_STATUS: + /* + * Some devices wrongly report discharging if the battery's charge level + * was above the device's start charging threshold atm the AC adapter + * was plugged in and the device thus did not start a new charge cycle. + */ if (battery->state & ACPI_BATTERY_STATE_DISCHARGING) - val->intval =3D acpi_battery_handle_discharging(battery); + if (battery->rate_now !=3D 0) { + val->intval =3D POWER_SUPPLY_STATUS_DISCHARGING; + } else if (battery_ac_is_broken) { + val->intval =3D POWER_SUPPLY_STATUS_NOT_CHARGING; + } else { + mutex_unlock(&battery->update_lock); + + val->intval =3D power_supply_is_system_supplied() + ? POWER_SUPPLY_STATUS_NOT_CHARGING + : POWER_SUPPLY_STATUS_DISCHARGING; + return 0; + } else if (battery->state & ACPI_BATTERY_STATE_CHARGING) /* Validate the status by checking the current. */ if (battery->rate_now !=3D ACPI_BATTERY_VALUE_UNKNOWN && @@ -311,6 +317,8 @@ static int acpi_battery_get_property(struct power_suppl= y *psy, default: ret =3D -EINVAL; } + + mutex_unlock(&battery->update_lock); return ret; } =20 --=20 2.53.0 From nobody Mon Jun 8 20:54:15 2026 Received: from sender4-op-o12.zoho.com (sender4-op-o12.zoho.com [136.143.188.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 13FE9421EE6; Tue, 26 May 2026 18:34:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=136.143.188.12 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779820449; cv=pass; b=GHpwmIvYDf9Bec2h6ViCubHmzIkLuPo52qD520MgwWmVPnezwsE/JaMvyc+GFfW+KQDGS80p8rDOmRrg1C/BAjQ6IJi5kNKAsU8+F/F+M65D/6DQ3X2rWLMe+Uc5nGl1xPOPJtxvfQvSPOty/NONE5uTUgTCq+VzCVb2RbpXjAI= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779820449; c=relaxed/simple; bh=VuxzRL3waxV7wariDHQL7/MuXVxo1OsydyT36gX8NUo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=THoafPW3m4jy+R6T2TcuxUutuqVTIps58Fs2MFAtxKdXfnsoK9D7y4DDjP4+hpdXfQxmn1Mw5vIE8Z7udd+/5g/xJ4t4hX0JmVYCf7rhKulsfDSNnnKoJ3kphhYth4x/ue7LL3qkzhDFFOeF7sxVprFUEdZM8wGjLl99gDc4Pqk= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rong.moe; spf=pass smtp.mailfrom=rong.moe; dkim=pass (2048-bit key) header.d=rong.moe header.i=i@rong.moe header.b=H7uRJQIE; arc=pass smtp.client-ip=136.143.188.12 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rong.moe Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rong.moe Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=rong.moe header.i=i@rong.moe header.b="H7uRJQIE" ARC-Seal: i=1; a=rsa-sha256; t=1779820437; cv=none; d=zohomail.com; s=zohoarc; b=C/7uAFJTBijLMkYwoqqmh/fsrFzdj2gavWaueTmn0YvWtxYDUcePOSeE7Sx19UFVB9om2Od9fSjeB5J0R4LX/yHkMGvZqFC0z81YjVc8zS5QKObX/mufnyZJ2l4uRzWx5F67gTuwVTjK1Z+qIMVEe7kM3cDyjAOY/+fWey5HJ/c= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1779820437; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=ZAqx81ncxxdbkyglMNedqUT6QaWlryJv4v9cmskdtvw=; b=bQ+UIGJkQtvnj3WSItchb+f8ZndQ6xnrm1yEIOWeXglH7o3Jz8BnUvX08Po1HflAac8tEdMsLiFnY1wubR9LLx6RlgFdoLdd3QOrDipgKrWGwbGXb8vdtNgxkW6Qg9C3tcAe6RXhj1p2AdM9UfZATt5pxlQM/y6OTgCGoGyuiPg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=rong.moe; spf=pass smtp.mailfrom=i@rong.moe; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1779820437; s=zmail2048; d=rong.moe; i=i@rong.moe; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:References:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=ZAqx81ncxxdbkyglMNedqUT6QaWlryJv4v9cmskdtvw=; b=H7uRJQIEymgiKzrUecQP+3R/YGvNRc7+2pQkP/2pkYdehpRYrVgv9FWuF+wp+xbm zTKZLinmI1QnYA/1DM5ES9QOqFWrHUfP+Ov8osyW51W30oyDTCFRqaeGVJphhhbr4ct 5ldbMtqI4wbU44nzULpsmfN/T7Kdr8hJWKrEwfjMzH+ES8PISMl+yBNBRNHZJPqdRIO J7npA84p2f9MD8228u0xlxhKXcXi1RkMc5GQsTTUuXRGOpV8S/p+/c/XKmi5prHmqvt hPT1DNVO9dRVwXLm9fSIJwqqS/08n0Wu9jtJxWM1nHamehZQmLFvwjH1gv17bqbUmMK YKztESgdrA== Received: by mx.zohomail.com with SMTPS id 1779820434504677.2244680612367; Tue, 26 May 2026 11:33:54 -0700 (PDT) From: Rong Zhang Date: Wed, 27 May 2026 02:31:32 +0800 Subject: [PATCH 2/2] ACPI: battery: Merge consecutive battery notifications Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260527-b4-acpi-battery-notification-v1-2-2303bed8ec0b@rong.moe> References: <20260527-b4-acpi-battery-notification-v1-0-2303bed8ec0b@rong.moe> In-Reply-To: <20260527-b4-acpi-battery-notification-v1-0-2303bed8ec0b@rong.moe> To: "Rafael J. Wysocki" , Len Brown Cc: "Rafael J. Wysocki" , linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?Jeffrey_W=C3=A4lti?= , stable@vger.kernel.org, Rick , Rong Zhang X-Mailer: b4 0.16-dev-d5d98 X-ZohoMailClient: External It's a very common pattern to emit consecutive battery notifications, for example: Method (_Qxx, 0, NotSerialized) { Notify (BAT0, 0x80) // Status Change Notify (BAT0, 0x81) // Information Change } In this case, the current code path will update battery state twice within a short period, which is not optimal, as the same data are fetched twice. Moreover, both notifications are likely to call power_supply_changed(), causing power_supply_uevent() to read all battery properties in order to assemble uevents. Even worse, after the first uevent reaches userspace, some userspace processes start to read all battery properties in order to refresh their internal states, which competes with the second notification's handling and uevent assembling. This generates significant pressure on _STA, _BST and _BIX/_BIF methods. Not only that, power_supply_ext properties may also rely on some other ACPI methods, so both uevent assembling and userspace processes call them. It becomes a nightmare when all these methods share the same ACPI mutex protecting EC accesses and hence vulnerable to lock starvation. This is exactly the case of some Lenovo devices, where the mentioned EC query pattern eventually leads to a catastrophic situation that a bunch of ACPI methods (including but not limited to the mentioned ones) fail to acquire the same mutex due to timeout. These devices don't handle mutex acquisition failure gracefully and return garbage data, causing even more chaos. Improve battery notification handling by merging consecutive battery notifications within 10ms using a delayed work, so that they only refresh and/or update battery state once. ACPI netlink event and notifier call chain are still triggered multiple times in order not to break other components. Finally, call power_supply_changed() once and lead to a single uevent instead of a bunch, preventing userspace programs from causing too much pressure on power supply properties and underlying ACPI methods. Tested-by: Jeffrey W=C3=A4lti Cc: stable@vger.kernel.org Reported-by: Rick Closes: https://bugzilla.kernel.org/show_bug.cgi?id=3D221065 Signed-off-by: Rong Zhang --- drivers/acpi/battery.c | 73 +++++++++++++++++++++++++++++++++++++++++++---= ---- 1 file changed, 63 insertions(+), 10 deletions(-) diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 5f06841b48a1..f6e2b0d8e878 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -21,6 +22,7 @@ #include #include #include +#include =20 #include =20 @@ -43,6 +45,9 @@ =20 #define MAX_STRING_LENGTH 64 =20 +#define MAX_QUEUED_EVENTS 16 +#define NOTIF_MERGING_MS 10 + MODULE_AUTHOR("Paul Diefenbaugh"); MODULE_AUTHOR("Alexey Starikovskiy "); MODULE_DESCRIPTION("ACPI Battery Driver"); @@ -95,6 +100,8 @@ struct acpi_battery { struct power_supply_desc bat_desc; struct acpi_device *device; struct device *phys_dev; + struct kfifo acpi_notif_fifo; + struct delayed_work acpi_notif_dwork; struct notifier_block pm_nb; struct list_head list; unsigned long update_time; @@ -1067,14 +1074,22 @@ static void acpi_battery_refresh(struct acpi_batter= y *battery) } =20 /* Driver Interface */ -static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) +static void acpi_battery_notification_worker(struct work_struct *work) { - struct acpi_battery *battery =3D data; + struct acpi_battery *battery =3D container_of(work, struct acpi_battery, + acpi_notif_dwork.work); struct acpi_device *device =3D battery->device; + u32 events[MAX_QUEUED_EVENTS]; struct power_supply *old; + unsigned int count, i; =20 guard(mutex)(&battery->update_lock); =20 + count =3D kfifo_out(&battery->acpi_notif_fifo, events, sizeof(events)); + count /=3D sizeof(events[0]); + + pr_debug("merged %u battery notifications within %dms\n", count, NOTIF_ME= RGING_MS); + old =3D battery->bat; /* * On Acer Aspire V5-573G notifications are sometimes triggered too @@ -1084,19 +1099,45 @@ static void acpi_battery_notify(acpi_handle handle,= u32 event, void *data) */ if (battery_notification_delay_ms > 0) msleep(battery_notification_delay_ms); - if (event =3D=3D ACPI_BATTERY_NOTIFY_INFO) - acpi_battery_refresh(battery); + + for (i =3D 0; i < count; i++) { + if (events[i] =3D=3D ACPI_BATTERY_NOTIFY_INFO) { + acpi_battery_refresh(battery); + break; + } + } + acpi_battery_update(battery, false); - acpi_bus_generate_netlink_event(ACPI_BATTERY_CLASS, - dev_name(&device->dev), event, - acpi_battery_present(battery)); - acpi_notifier_call_chain(ACPI_BATTERY_CLASS, acpi_device_bid(device), - event, acpi_battery_present(battery)); + + for (i =3D 0; i < count; i++) { + acpi_bus_generate_netlink_event(ACPI_BATTERY_CLASS, + dev_name(&device->dev), events[i], + acpi_battery_present(battery)); + acpi_notifier_call_chain(ACPI_BATTERY_CLASS, acpi_device_bid(device), + events[i], acpi_battery_present(battery)); + } + /* acpi_battery_update could remove power_supply object */ if (old && battery->bat) power_supply_changed(battery->bat); } =20 +static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) +{ + struct acpi_battery *battery =3D data; + + guard(mutex)(&battery->update_lock); + + if (kfifo_avail(&battery->acpi_notif_fifo) < sizeof(event)) { + pr_err("too many battery notifications within %dms", NOTIF_MERGING_MS); + return; + } + + kfifo_in(&battery->acpi_notif_fifo, &event, sizeof(event)); + + schedule_delayed_work(&battery->acpi_notif_dwork, msecs_to_jiffies(NOTIF_= MERGING_MS)); +} + static int battery_notify(struct notifier_block *nb, unsigned long mode, void *_unused) { @@ -1264,13 +1305,22 @@ static int acpi_battery_probe(struct platform_devic= e *pdev) =20 device_init_wakeup(&pdev->dev, true); =20 + result =3D kfifo_alloc(&battery->acpi_notif_fifo, + MAX_QUEUED_EVENTS * sizeof(u32), GFP_KERNEL); + if (result) + goto fail_pm; + + INIT_DELAYED_WORK(&battery->acpi_notif_dwork, acpi_battery_notification_w= orker); + result =3D acpi_dev_install_notify_handler(device, ACPI_ALL_NOTIFY, acpi_battery_notify, battery); if (result) - goto fail_pm; + goto fail_kfifo; =20 return 0; =20 +fail_kfifo: + kfifo_free(&battery->acpi_notif_fifo); fail_pm: device_init_wakeup(&pdev->dev, false); unregister_pm_notifier(&battery->pm_nb); @@ -1287,6 +1337,9 @@ static void acpi_battery_remove(struct platform_devic= e *pdev) acpi_dev_remove_notify_handler(battery->device, ACPI_ALL_NOTIFY, acpi_battery_notify); =20 + cancel_delayed_work_sync(&battery->acpi_notif_dwork); + kfifo_free(&battery->acpi_notif_fifo); + device_init_wakeup(&pdev->dev, false); unregister_pm_notifier(&battery->pm_nb); =20 --=20 2.53.0