From e312b7e3183d2d806609ee0e905da807ff5d891f Mon Sep 17 00:00:00 2001 From: Waqar Hameed Date: Sat, 20 Dec 2025 22:54:08 +0100 Subject: [PATCH 01/30] power: supply: bd99954: Remove unused gpio include header This header file is not used anywhere in the driver. Remove it. Signed-off-by: Waqar Hameed Acked-by: Matti Vaittinen Link: https://patch.msgid.link/ee74b461a8b8f02093e0beb519a1f0b8de7b64bc.1766266985.git.waqar.hameed@axis.com Signed-off-by: Sebastian Reichel --- drivers/power/supply/bd99954-charger.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/power/supply/bd99954-charger.c b/drivers/power/supply/bd99954-charger.c index d03a70cf8406..5c447b088223 100644 --- a/drivers/power/supply/bd99954-charger.c +++ b/drivers/power/supply/bd99954-charger.c @@ -56,7 +56,6 @@ */ #include -#include #include #include #include From 38673fd9d622318eed1e35cfad5998b4056edc1e Mon Sep 17 00:00:00 2001 From: Waqar Hameed Date: Sat, 20 Dec 2025 22:54:08 +0100 Subject: [PATCH 02/30] power: supply: bq256xx: Remove unused gpio include header This header file is not used anywhere in the driver. Remove it. Signed-off-by: Waqar Hameed Link: https://patch.msgid.link/730eb504f7ae9d3fcdfeebb544bfe115c32e1064.1766266985.git.waqar.hameed@axis.com Signed-off-by: Sebastian Reichel --- drivers/power/supply/bq256xx_charger.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/power/supply/bq256xx_charger.c b/drivers/power/supply/bq256xx_charger.c index ae14162f017a..3eb173394005 100644 --- a/drivers/power/supply/bq256xx_charger.c +++ b/drivers/power/supply/bq256xx_charger.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include From 3d74b6dfd703ba812c624c689451b0ae573b4f0b Mon Sep 17 00:00:00 2001 From: Waqar Hameed Date: Sat, 20 Dec 2025 22:54:08 +0100 Subject: [PATCH 03/30] power: supply: bq25980: Remove unused gpio include header This header file is not used anywhere in the driver. Remove it. Signed-off-by: Waqar Hameed Link: https://patch.msgid.link/94cf6d7dc464e20abea543983b24828e51c64f93.1766266985.git.waqar.hameed@axis.com Signed-off-by: Sebastian Reichel --- drivers/power/supply/bq25980_charger.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/power/supply/bq25980_charger.c b/drivers/power/supply/bq25980_charger.c index 723858d62d14..4f91fd1a3dec 100644 --- a/drivers/power/supply/bq25980_charger.c +++ b/drivers/power/supply/bq25980_charger.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include From 91a4f92de8454621e9d4e77a58c19c9d60a69581 Mon Sep 17 00:00:00 2001 From: Waqar Hameed Date: Sat, 20 Dec 2025 22:54:09 +0100 Subject: [PATCH 04/30] power: supply: cw2015: Remove unused gpio include header This header file is not used anywhere in the driver. Remove it. Signed-off-by: Waqar Hameed Link: https://patch.msgid.link/6c6ea228f39f3c01c0a89d8ba545be6f3ec13c2a.1766266985.git.waqar.hameed@axis.com Signed-off-by: Sebastian Reichel --- drivers/power/supply/cw2015_battery.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/power/supply/cw2015_battery.c b/drivers/power/supply/cw2015_battery.c index 0806abea2372..a05dcc4a48f2 100644 --- a/drivers/power/supply/cw2015_battery.c +++ b/drivers/power/supply/cw2015_battery.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include From ce3bc8469e4c387fd937e2ef96a6d45b7e22afc7 Mon Sep 17 00:00:00 2001 From: Waqar Hameed Date: Sat, 20 Dec 2025 22:54:09 +0100 Subject: [PATCH 05/30] power: supply: ucs1002: Remove unused gpio include header This header file is not used anywhere in the driver. Remove it. Signed-off-by: Waqar Hameed Link: https://patch.msgid.link/dcff57bfbf0510c8b5bfd9d39de021607567a6e8.1766266985.git.waqar.hameed@axis.com Signed-off-by: Sebastian Reichel --- drivers/power/supply/ucs1002_power.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/power/supply/ucs1002_power.c b/drivers/power/supply/ucs1002_power.c index fe94435340de..3f44cc902f84 100644 --- a/drivers/power/supply/ucs1002_power.c +++ b/drivers/power/supply/ucs1002_power.c @@ -6,7 +6,6 @@ */ #include #include -#include #include #include #include From c4af8a98bb52825a5331ae1d0604c0ea6956ba4b Mon Sep 17 00:00:00 2001 From: Waqar Hameed Date: Sat, 20 Dec 2025 23:35:58 +0100 Subject: [PATCH 06/30] power: supply: ab8500: Fix use-after-free in power_supply_changed() Using the `devm_` variant for requesting IRQ _before_ the `devm_` variant for allocating/registering the `power_supply` handle, means that the `power_supply` handle will be deallocated/unregistered _before_ the interrupt handler (since `devm_` naturally deallocates in reverse allocation order). This means that during removal, there is a race condition where an interrupt can fire just _after_ the `power_supply` handle has been freed, *but* just _before_ the corresponding unregistration of the IRQ handler has run. This will lead to the IRQ handler calling `power_supply_changed()` with a freed `power_supply` handle. Which usually crashes the system or otherwise silently corrupts the memory... Note that there is a similar situation which can also happen during `probe()`; the possibility of an interrupt firing _before_ registering the `power_supply` handle. This would then lead to the nasty situation of using the `power_supply` handle *uninitialized* in `power_supply_changed()`. Commit 1c1f13a006ed ("power: supply: ab8500: Move to componentized binding") introduced this issue during a refactorization. Fix this racy use-after-free by making sure the IRQ is requested _after_ the registration of the `power_supply` handle. Fixes: 1c1f13a006ed ("power: supply: ab8500: Move to componentized binding") Signed-off-by: Waqar Hameed Reviewed-by: Linus Walleij Link: https://patch.msgid.link/ccf83a09942cb8dda3dff70b2682f2c2e9cb97f2.1766268280.git.waqar.hameed@axis.com Signed-off-by: Sebastian Reichel --- drivers/power/supply/ab8500_charger.c | 40 +++++++++++++-------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/power/supply/ab8500_charger.c b/drivers/power/supply/ab8500_charger.c index 5f4537766e5b..1813fbdfa1c1 100644 --- a/drivers/power/supply/ab8500_charger.c +++ b/drivers/power/supply/ab8500_charger.c @@ -3466,26 +3466,6 @@ static int ab8500_charger_probe(struct platform_device *pdev) return ret; } - /* Request interrupts */ - for (i = 0; i < ARRAY_SIZE(ab8500_charger_irq); i++) { - irq = platform_get_irq_byname(pdev, ab8500_charger_irq[i].name); - if (irq < 0) - return irq; - - ret = devm_request_threaded_irq(dev, - irq, NULL, ab8500_charger_irq[i].isr, - IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_ONESHOT, - ab8500_charger_irq[i].name, di); - - if (ret != 0) { - dev_err(dev, "failed to request %s IRQ %d: %d\n" - , ab8500_charger_irq[i].name, irq, ret); - return ret; - } - dev_dbg(dev, "Requested %s IRQ %d: %d\n", - ab8500_charger_irq[i].name, irq, ret); - } - /* initialize lock */ spin_lock_init(&di->usb_state.usb_lock); mutex_init(&di->usb_ipt_crnt_lock); @@ -3614,6 +3594,26 @@ static int ab8500_charger_probe(struct platform_device *pdev) return PTR_ERR(di->usb_chg.psy); } + /* Request interrupts */ + for (i = 0; i < ARRAY_SIZE(ab8500_charger_irq); i++) { + irq = platform_get_irq_byname(pdev, ab8500_charger_irq[i].name); + if (irq < 0) + return irq; + + ret = devm_request_threaded_irq(dev, + irq, NULL, ab8500_charger_irq[i].isr, + IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_ONESHOT, + ab8500_charger_irq[i].name, di); + + if (ret != 0) { + dev_err(dev, "failed to request %s IRQ %d: %d\n" + , ab8500_charger_irq[i].name, irq, ret); + return ret; + } + dev_dbg(dev, "Requested %s IRQ %d: %d\n", + ab8500_charger_irq[i].name, irq, ret); + } + /* * Check what battery we have, since we always have the USB * psy, use that as a handle. From 3291c51d4684d048dd2eb91b5b65fcfdaf72141f Mon Sep 17 00:00:00 2001 From: Waqar Hameed Date: Sat, 20 Dec 2025 23:35:59 +0100 Subject: [PATCH 07/30] power: supply: act8945a: Fix use-after-free in power_supply_changed() Using the `devm_` variant for requesting IRQ _before_ the `devm_` variant for allocating/registering the `power_supply` handle, means that the `power_supply` handle will be deallocated/unregistered _before_ the interrupt handler (since `devm_` naturally deallocates in reverse allocation order). This means that during removal, there is a race condition where an interrupt can fire just _after_ the `power_supply` handle has been freed, *but* just _before_ the corresponding unregistration of the IRQ handler has run. This will lead to the IRQ handler calling `power_supply_changed()` with a freed `power_supply` handle. Which usually crashes the system or otherwise silently corrupts the memory... Note that there is a similar situation which can also happen during `probe()`; the possibility of an interrupt firing _before_ registering the `power_supply` handle. This would then lead to the nasty situation of using the `power_supply` handle *uninitialized* in `power_supply_changed()`. Fix this racy use-after-free by making sure the IRQ is requested _after_ the registration of the `power_supply` handle. Fixes: a09209acd6a8 ("power: supply: act8945a_charger: Add status change update support") Signed-off-by: Waqar Hameed Link: https://patch.msgid.link/bcf3a23b5187df0bba54a8c8fe09f8b8a0031dee.1766268280.git.waqar.hameed@axis.com Signed-off-by: Sebastian Reichel --- drivers/power/supply/act8945a_charger.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/power/supply/act8945a_charger.c b/drivers/power/supply/act8945a_charger.c index 3901a02f326a..9dec4486b143 100644 --- a/drivers/power/supply/act8945a_charger.c +++ b/drivers/power/supply/act8945a_charger.c @@ -597,14 +597,6 @@ static int act8945a_charger_probe(struct platform_device *pdev) return irq ?: -ENXIO; } - ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed, - IRQF_TRIGGER_FALLING, "act8945a_interrupt", - charger); - if (ret) { - dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n"); - return ret; - } - charger->desc.name = "act8945a-charger"; charger->desc.get_property = act8945a_charger_get_property; charger->desc.properties = act8945a_charger_props; @@ -625,6 +617,14 @@ static int act8945a_charger_probe(struct platform_device *pdev) return PTR_ERR(charger->psy); } + ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed, + IRQF_TRIGGER_FALLING, "act8945a_interrupt", + charger); + if (ret) { + dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n"); + return ret; + } + platform_set_drvdata(pdev, charger); INIT_WORK(&charger->work, act8945a_work); From 8005843369723d9c8975b7c4202d1b85d6125302 Mon Sep 17 00:00:00 2001 From: Waqar Hameed Date: Sat, 20 Dec 2025 23:35:59 +0100 Subject: [PATCH 08/30] power: supply: bq256xx: Fix use-after-free in power_supply_changed() Using the `devm_` variant for requesting IRQ _before_ the `devm_` variant for allocating/registering the `power_supply` handle, means that the `power_supply` handle will be deallocated/unregistered _before_ the interrupt handler (since `devm_` naturally deallocates in reverse allocation order). This means that during removal, there is a race condition where an interrupt can fire just _after_ the `power_supply` handle has been freed, *but* just _before_ the corresponding unregistration of the IRQ handler has run. This will lead to the IRQ handler calling `power_supply_changed()` with a freed `power_supply` handle. Which usually crashes the system or otherwise silently corrupts the memory... Note that there is a similar situation which can also happen during `probe()`; the possibility of an interrupt firing _before_ registering the `power_supply` handle. This would then lead to the nasty situation of using the `power_supply` handle *uninitialized* in `power_supply_changed()`. Fix this racy use-after-free by making sure the IRQ is requested _after_ the registration of the `power_supply` handle. Fixes: 32e4978bb920 ("power: supply: bq256xx: Introduce the BQ256XX charger driver") Signed-off-by: Waqar Hameed Link: https://patch.msgid.link/39da6da8cc060fa0382ca859f65071e791cb6119.1766268280.git.waqar.hameed@axis.com Signed-off-by: Sebastian Reichel --- drivers/power/supply/bq256xx_charger.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/power/supply/bq256xx_charger.c b/drivers/power/supply/bq256xx_charger.c index 3eb173394005..563f512709b3 100644 --- a/drivers/power/supply/bq256xx_charger.c +++ b/drivers/power/supply/bq256xx_charger.c @@ -1740,6 +1740,12 @@ static int bq256xx_probe(struct i2c_client *client) usb_register_notifier(bq->usb3_phy, &bq->usb_nb); } + ret = bq256xx_power_supply_init(bq, &psy_cfg, dev); + if (ret) { + dev_err(dev, "Failed to register power supply\n"); + return ret; + } + if (client->irq) { ret = devm_request_threaded_irq(dev, client->irq, NULL, bq256xx_irq_handler_thread, @@ -1752,12 +1758,6 @@ static int bq256xx_probe(struct i2c_client *client) } } - ret = bq256xx_power_supply_init(bq, &psy_cfg, dev); - if (ret) { - dev_err(dev, "Failed to register power supply\n"); - return ret; - } - ret = bq256xx_hw_init(bq); if (ret) { dev_err(dev, "Cannot initialize the chip.\n"); From 5f0b1cb41906e86b64bf69f5ededb83b0d757c27 Mon Sep 17 00:00:00 2001 From: Waqar Hameed Date: Sat, 20 Dec 2025 23:35:59 +0100 Subject: [PATCH 09/30] power: supply: bq25980: Fix use-after-free in power_supply_changed() Using the `devm_` variant for requesting IRQ _before_ the `devm_` variant for allocating/registering the `power_supply` handle, means that the `power_supply` handle will be deallocated/unregistered _before_ the interrupt handler (since `devm_` naturally deallocates in reverse allocation order). This means that during removal, there is a race condition where an interrupt can fire just _after_ the `power_supply` handle has been freed, *but* just _before_ the corresponding unregistration of the IRQ handler has run. This will lead to the IRQ handler calling `power_supply_changed()` with a freed `power_supply` handle. Which usually crashes the system or otherwise silently corrupts the memory... Note that there is a similar situation which can also happen during `probe()`; the possibility of an interrupt firing _before_ registering the `power_supply` handle. This would then lead to the nasty situation of using the `power_supply` handle *uninitialized* in `power_supply_changed()`. Fix this racy use-after-free by making sure the IRQ is requested _after_ the registration of the `power_supply` handle. Fixes: 5069185fc18e ("power: supply: bq25980: Add support for the BQ259xx family") Signed-off-by: Waqar Hameed Link: https://patch.msgid.link/8763035cadb959e14787b3837f2d3db61f6e1c34.1766268280.git.waqar.hameed@axis.com Signed-off-by: Sebastian Reichel --- drivers/power/supply/bq25980_charger.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/power/supply/bq25980_charger.c b/drivers/power/supply/bq25980_charger.c index 4f91fd1a3dec..44af3a0c92e5 100644 --- a/drivers/power/supply/bq25980_charger.c +++ b/drivers/power/supply/bq25980_charger.c @@ -1240,6 +1240,12 @@ static int bq25980_probe(struct i2c_client *client) return ret; } + ret = bq25980_power_supply_init(bq, dev); + if (ret) { + dev_err(dev, "Failed to register power supply\n"); + return ret; + } + if (client->irq) { ret = devm_request_threaded_irq(dev, client->irq, NULL, bq25980_irq_handler_thread, @@ -1250,12 +1256,6 @@ static int bq25980_probe(struct i2c_client *client) return ret; } - ret = bq25980_power_supply_init(bq, dev); - if (ret) { - dev_err(dev, "Failed to register power supply\n"); - return ret; - } - ret = bq25980_hw_init(bq); if (ret) { dev_err(dev, "Cannot initialize the chip.\n"); From 642f33e34b969eedec334738fd5df95d2dc42742 Mon Sep 17 00:00:00 2001 From: Waqar Hameed Date: Sat, 20 Dec 2025 23:36:00 +0100 Subject: [PATCH 10/30] power: supply: cpcap-battery: Fix use-after-free in power_supply_changed() Using the `devm_` variant for requesting IRQ _before_ the `devm_` variant for allocating/registering the `power_supply` handle, means that the `power_supply` handle will be deallocated/unregistered _before_ the interrupt handler (since `devm_` naturally deallocates in reverse allocation order). This means that during removal, there is a race condition where an interrupt can fire just _after_ the `power_supply` handle has been freed, *but* just _before_ the corresponding unregistration of the IRQ handler has run. This will lead to the IRQ handler calling `power_supply_changed()` with a freed `power_supply` handle. Which usually crashes the system or otherwise silently corrupts the memory... Note that there is a similar situation which can also happen during `probe()`; the possibility of an interrupt firing _before_ registering the `power_supply` handle. This would then lead to the nasty situation of using the `power_supply` handle *uninitialized* in `power_supply_changed()`. Fix this racy use-after-free by making sure the IRQ is requested _after_ the registration of the `power_supply` handle. Fixes: 874b2adbed12 ("power: supply: cpcap-battery: Add a battery driver") Signed-off-by: Waqar Hameed Link: https://patch.msgid.link/81db58d610c9a51a68184f856cd431a934cccee2.1766268280.git.waqar.hameed@axis.com Signed-off-by: Sebastian Reichel --- drivers/power/supply/cpcap-battery.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/power/supply/cpcap-battery.c b/drivers/power/supply/cpcap-battery.c index 8106d1edcbc2..507fdc1c866d 100644 --- a/drivers/power/supply/cpcap-battery.c +++ b/drivers/power/supply/cpcap-battery.c @@ -1122,10 +1122,6 @@ static int cpcap_battery_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ddata); - error = cpcap_battery_init_interrupts(pdev, ddata); - if (error) - return error; - error = cpcap_battery_init_iio(ddata); if (error) return error; @@ -1142,6 +1138,10 @@ static int cpcap_battery_probe(struct platform_device *pdev) return error; } + error = cpcap_battery_init_interrupts(pdev, ddata); + if (error) + return error; + atomic_set(&ddata->active, 1); error = cpcap_battery_calibrate(ddata); From b2ce982e2e0c888dc55c888ad0e20ea04daf2e6b Mon Sep 17 00:00:00 2001 From: Waqar Hameed Date: Sat, 20 Dec 2025 23:36:00 +0100 Subject: [PATCH 11/30] power: supply: goldfish: Fix use-after-free in power_supply_changed() Using the `devm_` variant for requesting IRQ _before_ the `devm_` variant for allocating/registering the `power_supply` handle, means that the `power_supply` handle will be deallocated/unregistered _before_ the interrupt handler (since `devm_` naturally deallocates in reverse allocation order). This means that during removal, there is a race condition where an interrupt can fire just _after_ the `power_supply` handle has been freed, *but* just _before_ the corresponding unregistration of the IRQ handler has run. This will lead to the IRQ handler calling `power_supply_changed()` with a freed `power_supply` handle. Which usually crashes the system or otherwise silently corrupts the memory... Note that there is a similar situation which can also happen during `probe()`; the possibility of an interrupt firing _before_ registering the `power_supply` handle. This would then lead to the nasty situation of using the `power_supply` handle *uninitialized* in `power_supply_changed()`. Fix this racy use-after-free by making sure the IRQ is requested _after_ the registration of the `power_supply` handle. Fixes: 84d7b7687489 ("power: Add battery driver for goldfish emulator") Signed-off-by: Waqar Hameed Link: https://patch.msgid.link/500a606bb6fb6f2bb8d797e19a00cea9dd7b03c1.1766268280.git.waqar.hameed@axis.com Signed-off-by: Sebastian Reichel --- drivers/power/supply/goldfish_battery.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/power/supply/goldfish_battery.c b/drivers/power/supply/goldfish_battery.c index 479195e35d73..5aa24e4dc445 100644 --- a/drivers/power/supply/goldfish_battery.c +++ b/drivers/power/supply/goldfish_battery.c @@ -224,12 +224,6 @@ static int goldfish_battery_probe(struct platform_device *pdev) if (data->irq < 0) return -ENODEV; - ret = devm_request_irq(&pdev->dev, data->irq, - goldfish_battery_interrupt, - IRQF_SHARED, pdev->name, data); - if (ret) - return ret; - psy_cfg.drv_data = data; data->ac = devm_power_supply_register(&pdev->dev, @@ -244,6 +238,12 @@ static int goldfish_battery_probe(struct platform_device *pdev) if (IS_ERR(data->battery)) return PTR_ERR(data->battery); + ret = devm_request_irq(&pdev->dev, data->irq, + goldfish_battery_interrupt, + IRQF_SHARED, pdev->name, data); + if (ret) + return ret; + GOLDFISH_BATTERY_WRITE(data, BATTERY_INT_ENABLE, BATTERY_INT_MASK); return 0; } From 838767f5074700552d3f006d867caed65edc7328 Mon Sep 17 00:00:00 2001 From: Waqar Hameed Date: Sat, 20 Dec 2025 23:36:01 +0100 Subject: [PATCH 12/30] power: supply: pf1550: Fix use-after-free in power_supply_changed() Using the `devm_` variant for requesting IRQ _before_ the `devm_` variant for allocating/registering the `power_supply` handle, means that the `power_supply` handle will be deallocated/unregistered _before_ the interrupt handler (since `devm_` naturally deallocates in reverse allocation order). This means that during removal, there is a race condition where an interrupt can fire just _after_ the `power_supply` handle has been freed, *but* just _before_ the corresponding unregistration of the IRQ handler has run. This will lead to the IRQ handler calling `power_supply_changed()` with a freed `power_supply` handle. Which usually crashes the system or otherwise silently corrupts the memory... Note that there is a similar situation which can also happen during `probe()`; the possibility of an interrupt firing _before_ registering the `power_supply` handle. This would then lead to the nasty situation of using the `power_supply` handle *uninitialized* in `power_supply_changed()`. Fix this racy use-after-free by making sure the IRQ is requested _after_ the registration of the `power_supply` handle. Fixes: 4b6b6433a97d ("power: supply: pf1550: add battery charger support") Signed-off-by: Waqar Hameed Reviewed-by: Samuel Kayode Link: https://patch.msgid.link/ae5a71b7e4dd2967d8fdcc531065cc71b17c86f5.1766268280.git.waqar.hameed@axis.com Signed-off-by: Sebastian Reichel --- drivers/power/supply/pf1550-charger.c | 32 +++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/power/supply/pf1550-charger.c b/drivers/power/supply/pf1550-charger.c index 98f1ee8eca3b..a457862ef461 100644 --- a/drivers/power/supply/pf1550-charger.c +++ b/drivers/power/supply/pf1550-charger.c @@ -584,22 +584,6 @@ static int pf1550_charger_probe(struct platform_device *pdev) return dev_err_probe(chg->dev, ret, "failed to add battery sense work\n"); - for (i = 0; i < PF1550_CHARGER_IRQ_NR; i++) { - irq = platform_get_irq(pdev, i); - if (irq < 0) - return irq; - - chg->virqs[i] = irq; - - ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, - pf1550_charger_irq_handler, - IRQF_NO_SUSPEND, - "pf1550-charger", chg); - if (ret) - return dev_err_probe(&pdev->dev, ret, - "failed irq request\n"); - } - psy_cfg.drv_data = chg; chg->charger = devm_power_supply_register(&pdev->dev, @@ -616,6 +600,22 @@ static int pf1550_charger_probe(struct platform_device *pdev) return dev_err_probe(&pdev->dev, PTR_ERR(chg->battery), "failed: power supply register\n"); + for (i = 0; i < PF1550_CHARGER_IRQ_NR; i++) { + irq = platform_get_irq(pdev, i); + if (irq < 0) + return irq; + + chg->virqs[i] = irq; + + ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, + pf1550_charger_irq_handler, + IRQF_NO_SUSPEND, + "pf1550-charger", chg); + if (ret) + return dev_err_probe(&pdev->dev, ret, + "failed irq request\n"); + } + pf1550_dt_parse_dev_info(chg); return pf1550_reg_init(chg); From 62914959b35e9a1e29cc0f64cb8cfc5075a5366f Mon Sep 17 00:00:00 2001 From: Waqar Hameed Date: Sat, 20 Dec 2025 23:36:01 +0100 Subject: [PATCH 13/30] power: supply: pm8916_bms_vm: Fix use-after-free in power_supply_changed() Using the `devm_` variant for requesting IRQ _before_ the `devm_` variant for allocating/registering the `power_supply` handle, means that the `power_supply` handle will be deallocated/unregistered _before_ the interrupt handler (since `devm_` naturally deallocates in reverse allocation order). This means that during removal, there is a race condition where an interrupt can fire just _after_ the `power_supply` handle has been freed, *but* just _before_ the corresponding unregistration of the IRQ handler has run. This will lead to the IRQ handler calling `power_supply_changed()` with a freed `power_supply` handle. Which usually crashes the system or otherwise silently corrupts the memory... Note that there is a similar situation which can also happen during `probe()`; the possibility of an interrupt firing _before_ registering the `power_supply` handle. This would then lead to the nasty situation of using the `power_supply` handle *uninitialized* in `power_supply_changed()`. Fix this racy use-after-free by making sure the IRQ is requested _after_ the registration of the `power_supply` handle. Fixes: 098bce1838e0 ("power: supply: Add pm8916 VM-BMS support") Signed-off-by: Waqar Hameed Reviewed-by: Nikita Travkin Link: https://patch.msgid.link/2749c09ff81fcac87ae48147e216135450d8c067.1766268280.git.waqar.hameed@axis.com Signed-off-by: Sebastian Reichel --- drivers/power/supply/pm8916_bms_vm.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/power/supply/pm8916_bms_vm.c b/drivers/power/supply/pm8916_bms_vm.c index 5120be086e6f..de5d571c03e2 100644 --- a/drivers/power/supply/pm8916_bms_vm.c +++ b/drivers/power/supply/pm8916_bms_vm.c @@ -167,15 +167,6 @@ static int pm8916_bms_vm_battery_probe(struct platform_device *pdev) if (ret < 0) return -EINVAL; - irq = platform_get_irq_byname(pdev, "fifo"); - if (irq < 0) - return irq; - - ret = devm_request_threaded_irq(dev, irq, NULL, pm8916_bms_vm_fifo_update_done_irq, - IRQF_ONESHOT, "pm8916_vm_bms", bat); - if (ret) - return ret; - ret = regmap_bulk_read(bat->regmap, bat->reg + PM8916_PERPH_TYPE, &tmp, 2); if (ret) goto comm_error; @@ -220,6 +211,15 @@ static int pm8916_bms_vm_battery_probe(struct platform_device *pdev) if (ret) return dev_err_probe(dev, ret, "Unable to get battery info\n"); + irq = platform_get_irq_byname(pdev, "fifo"); + if (irq < 0) + return irq; + + ret = devm_request_threaded_irq(dev, irq, NULL, pm8916_bms_vm_fifo_update_done_irq, + IRQF_ONESHOT, "pm8916_vm_bms", bat); + if (ret) + return ret; + platform_set_drvdata(pdev, bat); return 0; From b7508129978ae1e2ed9b0410396abc05def9c4eb Mon Sep 17 00:00:00 2001 From: Waqar Hameed Date: Sat, 20 Dec 2025 23:36:01 +0100 Subject: [PATCH 14/30] power: supply: pm8916_lbc: Fix use-after-free in power_supply_changed() Using the `devm_` variant for requesting IRQ _before_ the `devm_` variant for allocating/registering the `power_supply` handle, means that the `power_supply` handle will be deallocated/unregistered _before_ the interrupt handler (since `devm_` naturally deallocates in reverse allocation order). This means that during removal, there is a race condition where an interrupt can fire just _after_ the `power_supply` handle has been freed, *but* just _before_ the corresponding unregistration of the IRQ handler has run. This will lead to the IRQ handler calling `power_supply_changed()` with a freed `power_supply` handle. Which usually crashes the system or otherwise silently corrupts the memory... Note that there is a similar situation which can also happen during `probe()`; the possibility of an interrupt firing _before_ registering the `power_supply` handle. This would then lead to the nasty situation of using the `power_supply` handle *uninitialized* in `power_supply_changed()`. Fix this racy use-after-free by making sure the IRQ is requested _after_ the registration of the `power_supply` handle. Fixes: f8d7a3d21160 ("power: supply: Add driver for pm8916 lbc") Signed-off-by: Waqar Hameed Reviewed-by: Nikita Travkin Link: https://patch.msgid.link/64d8dd3675a4e59fa32c3e0ef451f12d1f7ed18f.1766268280.git.waqar.hameed@axis.com Signed-off-by: Sebastian Reichel --- drivers/power/supply/pm8916_lbc.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/power/supply/pm8916_lbc.c b/drivers/power/supply/pm8916_lbc.c index c74b75b1b267..3ca717d84aad 100644 --- a/drivers/power/supply/pm8916_lbc.c +++ b/drivers/power/supply/pm8916_lbc.c @@ -274,15 +274,6 @@ static int pm8916_lbc_charger_probe(struct platform_device *pdev) return dev_err_probe(dev, -EINVAL, "Wrong amount of reg values: %d (4 expected)\n", len); - irq = platform_get_irq_byname(pdev, "usb_vbus"); - if (irq < 0) - return irq; - - ret = devm_request_threaded_irq(dev, irq, NULL, pm8916_lbc_charger_state_changed_irq, - IRQF_ONESHOT, "pm8916_lbc", chg); - if (ret) - return ret; - ret = device_property_read_u32_array(dev, "reg", chg->reg, len); if (ret) return ret; @@ -332,6 +323,15 @@ static int pm8916_lbc_charger_probe(struct platform_device *pdev) if (ret) return dev_err_probe(dev, ret, "Unable to get battery info\n"); + irq = platform_get_irq_byname(pdev, "usb_vbus"); + if (irq < 0) + return irq; + + ret = devm_request_threaded_irq(dev, irq, NULL, pm8916_lbc_charger_state_changed_irq, + IRQF_ONESHOT, "pm8916_lbc", chg); + if (ret) + return ret; + chg->edev = devm_extcon_dev_allocate(dev, pm8916_lbc_charger_cable); if (IS_ERR(chg->edev)) return PTR_ERR(chg->edev); From e2febe375e5ea5afed92f4cd9711bde8f24ee6d2 Mon Sep 17 00:00:00 2001 From: Waqar Hameed Date: Sat, 20 Dec 2025 23:36:02 +0100 Subject: [PATCH 15/30] power: supply: rt9455: Fix use-after-free in power_supply_changed() Using the `devm_` variant for requesting IRQ _before_ the `devm_` variant for allocating/registering the `power_supply` handle, means that the `power_supply` handle will be deallocated/unregistered _before_ the interrupt handler (since `devm_` naturally deallocates in reverse allocation order). This means that during removal, there is a race condition where an interrupt can fire just _after_ the `power_supply` handle has been freed, *but* just _before_ the corresponding unregistration of the IRQ handler has run. This will lead to the IRQ handler calling `power_supply_changed()` with a freed `power_supply` handle. Which usually crashes the system or otherwise silently corrupts the memory... Note that there is a similar situation which can also happen during `probe()`; the possibility of an interrupt firing _before_ registering the `power_supply` handle. This would then lead to the nasty situation of using the `power_supply` handle *uninitialized* in `power_supply_changed()`. Fix this racy use-after-free by making sure the IRQ is requested _after_ the registration of the `power_supply` handle. Fixes: e86d69dd786e ("power_supply: Add support for Richtek RT9455 battery charger") Signed-off-by: Waqar Hameed Link: https://patch.msgid.link/1567d831e04c3e2fcb9e18dd36b7bcba4634581a.1766268280.git.waqar.hameed@axis.com Signed-off-by: Sebastian Reichel --- drivers/power/supply/rt9455_charger.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/power/supply/rt9455_charger.c b/drivers/power/supply/rt9455_charger.c index 1ffe7f02932f..5130d2395e88 100644 --- a/drivers/power/supply/rt9455_charger.c +++ b/drivers/power/supply/rt9455_charger.c @@ -1663,6 +1663,15 @@ static int rt9455_probe(struct i2c_client *client) rt9455_charger_config.supplied_to = rt9455_charger_supplied_to; rt9455_charger_config.num_supplicants = ARRAY_SIZE(rt9455_charger_supplied_to); + + info->charger = devm_power_supply_register(dev, &rt9455_charger_desc, + &rt9455_charger_config); + if (IS_ERR(info->charger)) { + dev_err(dev, "Failed to register charger\n"); + ret = PTR_ERR(info->charger); + goto put_usb_notifier; + } + ret = devm_request_threaded_irq(dev, client->irq, NULL, rt9455_irq_handler_thread, IRQF_TRIGGER_LOW | IRQF_ONESHOT, @@ -1678,14 +1687,6 @@ static int rt9455_probe(struct i2c_client *client) goto put_usb_notifier; } - info->charger = devm_power_supply_register(dev, &rt9455_charger_desc, - &rt9455_charger_config); - if (IS_ERR(info->charger)) { - dev_err(dev, "Failed to register charger\n"); - ret = PTR_ERR(info->charger); - goto put_usb_notifier; - } - return 0; put_usb_notifier: From 8d59cf3887fbabacef53bfba473e33e8a8d9d07b Mon Sep 17 00:00:00 2001 From: Waqar Hameed Date: Sat, 20 Dec 2025 23:36:02 +0100 Subject: [PATCH 16/30] power: supply: sbs-battery: Fix use-after-free in power_supply_changed() Using the `devm_` variant for requesting IRQ _before_ the `devm_` variant for allocating/registering the `power_supply` handle, means that the `power_supply` handle will be deallocated/unregistered _before_ the interrupt handler (since `devm_` naturally deallocates in reverse allocation order). This means that during removal, there is a race condition where an interrupt can fire just _after_ the `power_supply` handle has been freed, *but* just _before_ the corresponding unregistration of the IRQ handler has run. This will lead to the IRQ handler calling `power_supply_changed()` with a freed `power_supply` handle. Which usually crashes the system or otherwise silently corrupts the memory... Note that there is a similar situation which can also happen during `probe()`; the possibility of an interrupt firing _before_ registering the `power_supply` handle. This would then lead to the nasty situation of using the `power_supply` handle *uninitialized* in `power_supply_changed()`. Fix this racy use-after-free by making sure the IRQ is requested _after_ the registration of the `power_supply` handle. Keep the old behavior of just printing a warning in case of any failures during the IRQ request and finishing the probe successfully. Fixes: d2cec82c2880 ("power: sbs-battery: Request threaded irq and fix dev callback cookie") Signed-off-by: Waqar Hameed Reviewed-by: Phil Reid Link: https://patch.msgid.link/0ef896e002495e615157b482d18a437af19ddcd0.1766268280.git.waqar.hameed@axis.com Signed-off-by: Sebastian Reichel --- drivers/power/supply/sbs-battery.c | 36 +++++++++++++++--------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/power/supply/sbs-battery.c b/drivers/power/supply/sbs-battery.c index 943c82ee978f..43c48196c167 100644 --- a/drivers/power/supply/sbs-battery.c +++ b/drivers/power/supply/sbs-battery.c @@ -1174,24 +1174,6 @@ static int sbs_probe(struct i2c_client *client) i2c_set_clientdata(client, chip); - if (!chip->gpio_detect) - goto skip_gpio; - - irq = gpiod_to_irq(chip->gpio_detect); - if (irq <= 0) { - dev_warn(&client->dev, "Failed to get gpio as irq: %d\n", irq); - goto skip_gpio; - } - - rc = devm_request_threaded_irq(&client->dev, irq, NULL, sbs_irq, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - dev_name(&client->dev), chip); - if (rc) { - dev_warn(&client->dev, "Failed to request irq: %d\n", rc); - goto skip_gpio; - } - -skip_gpio: /* * Before we register, we might need to make sure we can actually talk * to the battery. @@ -1217,6 +1199,24 @@ skip_gpio: return dev_err_probe(&client->dev, PTR_ERR(chip->power_supply), "Failed to register power supply\n"); + if (!chip->gpio_detect) + goto out; + + irq = gpiod_to_irq(chip->gpio_detect); + if (irq <= 0) { + dev_warn(&client->dev, "Failed to get gpio as irq: %d\n", irq); + goto out; + } + + rc = devm_request_threaded_irq(&client->dev, irq, NULL, sbs_irq, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + dev_name(&client->dev), chip); + if (rc) { + dev_warn(&client->dev, "Failed to request irq: %d\n", rc); + goto out; + } + +out: dev_info(&client->dev, "%s: battery gas gauge device registered\n", client->name); From 36b05629226413836cfbb3fbe6689cd188bca156 Mon Sep 17 00:00:00 2001 From: Alexander Koskovich Date: Sun, 14 Dec 2025 19:16:18 +0000 Subject: [PATCH 17/30] power: reset: nvmem-reboot-mode: respect cell size for nvmem_cell_write Some platforms expose reboot mode cells that are smaller than an unsigned int, in which cases lead to write failures. Read the cell first to determine actual size and only write the number of bytes the cell can hold. Fixes: 7a78a7f7695b ("power: reset: nvmem-reboot-mode: use NVMEM as reboot mode write interface") Signed-off-by: Alexander Koskovich Link: https://patch.msgid.link/20251214191529.2470580-1-akoskovich@pm.me Signed-off-by: Sebastian Reichel --- drivers/power/reset/nvmem-reboot-mode.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/power/reset/nvmem-reboot-mode.c b/drivers/power/reset/nvmem-reboot-mode.c index 41530b70cfc4..d260715fccf6 100644 --- a/drivers/power/reset/nvmem-reboot-mode.c +++ b/drivers/power/reset/nvmem-reboot-mode.c @@ -10,6 +10,7 @@ #include #include #include +#include struct nvmem_reboot_mode { struct reboot_mode_driver reboot; @@ -19,12 +20,22 @@ struct nvmem_reboot_mode { static int nvmem_reboot_mode_write(struct reboot_mode_driver *reboot, unsigned int magic) { - int ret; struct nvmem_reboot_mode *nvmem_rbm; + size_t buf_len; + void *buf; + int ret; nvmem_rbm = container_of(reboot, struct nvmem_reboot_mode, reboot); - ret = nvmem_cell_write(nvmem_rbm->cell, &magic, sizeof(magic)); + buf = nvmem_cell_read(nvmem_rbm->cell, &buf_len); + if (IS_ERR(buf)) + return PTR_ERR(buf); + kfree(buf); + + if (buf_len > sizeof(magic)) + return -EINVAL; + + ret = nvmem_cell_write(nvmem_rbm->cell, &magic, buf_len); if (ret < 0) dev_err(reboot->dev, "update reboot mode bits failed\n"); From 688364a11647dc09ba1e4429313e0008066ec790 Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Thu, 4 Dec 2025 16:34:36 +0800 Subject: [PATCH 18/30] power: supply: bq27xxx: fix wrong errno when bus ops are unsupported bq27xxx_write(), bq27xxx_read_block(), and bq27xxx_write_block() return -EPERM when the bus callback pointer is NULL. A NULL callback indicates the operation is not supported by the bus/driver, not that permission is denied. Return -EOPNOTSUPP instead of -EPERM when di->bus.write/ read_bulk/write_bulk is NULL. Fixes: 14073f6614f6 ("power: supply: bq27xxx: Add bulk transfer bus methods") Signed-off-by: Haotian Zhang Reviewed-by: Matt Ranostay Link: https://patch.msgid.link/20251204083436.1367-1-vulab@iscas.ac.cn Signed-off-by: Sebastian Reichel --- drivers/power/supply/bq27xxx_battery.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c index 19445e39651c..45f0e39b8c2d 100644 --- a/drivers/power/supply/bq27xxx_battery.c +++ b/drivers/power/supply/bq27xxx_battery.c @@ -1172,7 +1172,7 @@ static inline int bq27xxx_write(struct bq27xxx_device_info *di, int reg_index, return -EINVAL; if (!di->bus.write) - return -EPERM; + return -EOPNOTSUPP; ret = di->bus.write(di, di->regs[reg_index], value, single); if (ret < 0) @@ -1191,7 +1191,7 @@ static inline int bq27xxx_read_block(struct bq27xxx_device_info *di, int reg_ind return -EINVAL; if (!di->bus.read_bulk) - return -EPERM; + return -EOPNOTSUPP; ret = di->bus.read_bulk(di, di->regs[reg_index], data, len); if (ret < 0) @@ -1210,7 +1210,7 @@ static inline int bq27xxx_write_block(struct bq27xxx_device_info *di, int reg_in return -EINVAL; if (!di->bus.write_bulk) - return -EPERM; + return -EOPNOTSUPP; ret = di->bus.write_bulk(di, di->regs[reg_index], data, len); if (ret < 0) From 2c7e46e1318d4fbf514f454d5a746a1b76d06ebe Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 26 Nov 2025 18:19:00 +0100 Subject: [PATCH 19/30] power: supply: sysfs: Constify pointer passed to dev_attr_psp() Memory pointer by pointer passed to dev_attr_psp() is not modified, so with help of container_of_const() (preferred than container_of()) can be made pointer to const for code safety. Signed-off-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20251126171859.72465-2-krzysztof.kozlowski@oss.qualcomm.com Signed-off-by: Sebastian Reichel --- drivers/power/supply/power_supply_sysfs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c index 198405f7126f..dd3a48d72d2b 100644 --- a/drivers/power/supply/power_supply_sysfs.c +++ b/drivers/power/supply/power_supply_sysfs.c @@ -235,12 +235,12 @@ static struct power_supply_attr power_supply_attrs[] __ro_after_init = { static struct attribute * __power_supply_attrs[POWER_SUPPLY_ATTR_CNT + 1] __ro_after_init; -static const struct power_supply_attr *to_ps_attr(struct device_attribute *attr) +static const struct power_supply_attr *to_ps_attr(const struct device_attribute *attr) { - return container_of(attr, struct power_supply_attr, dev_attr); + return container_of_const(attr, struct power_supply_attr, dev_attr); } -static enum power_supply_property dev_attr_psp(struct device_attribute *attr) +static enum power_supply_property dev_attr_psp(const struct device_attribute *attr) { return to_ps_attr(attr) - power_supply_attrs; } From 81963d1c5689168731dca0652093c73b90bed1d3 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 10 Nov 2025 22:00:09 -0800 Subject: [PATCH 20/30] power: supply: ab8500_chargalg: improve kernel-doc Correct "bad line" warnings and add descriptions for missing entries to avoid these warnings: ab8500_chargalg.c:173: warning: bad line: is set ab8500_chargalg.c:179: warning: bad line: increased ab8500_chargalg.c:247: warning: Function parameter or struct member 't_hyst_norm' not described in 'ab8500_chargalg' ab8500_chargalg.c:247: warning: Function parameter or struct member 't_hyst_lowhigh' not described in 'ab8500_chargalg' ab8500_chargalg.c:247: warning: Function parameter or struct member 'ccm' not described in 'ab8500_chargalg' ab8500_chargalg.c:247: warning: Function parameter or struct member 'ac_chg' not described in 'ab8500_chargalg' ab8500_chargalg.c:247: warning: Function parameter or struct member 'usb_chg' not described in 'ab8500_chargalg' ab8500_chargalg.c:308: warning: Function parameter or struct member 'state' not described in 'ab8500_chargalg_state_to' ab8500_chargalg.c:773: warning: Function parameter or struct member 'di' not described in 'ab8500_chargalg_chg_curr_maxim' Signed-off-by: Randy Dunlap Reviewed-by: Linus Walleij Link: https://patch.msgid.link/20251111060009.1959425-1-rdunlap@infradead.org Signed-off-by: Sebastian Reichel --- drivers/power/supply/ab8500_chargalg.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/power/supply/ab8500_chargalg.c b/drivers/power/supply/ab8500_chargalg.c index dc6c8b0dd1cf..d2b9880b0770 100644 --- a/drivers/power/supply/ab8500_chargalg.c +++ b/drivers/power/supply/ab8500_chargalg.c @@ -170,13 +170,13 @@ struct ab8500_chargalg_events { * @original_iset_ua: the non optimized/maximised charger current * @current_iset_ua: the charging current used at this moment * @condition_cnt: number of iterations needed before a new charger current - is set + * is set * @max_current_ua: maximum charger current * @wait_cnt: to avoid too fast current step down in case of charger * voltage collapse, we insert this delay between step * down * @level: tells in how many steps the charging current has been - increased + * increased */ struct ab8500_charge_curr_maximization { int original_iset_ua; @@ -199,18 +199,20 @@ enum maxim_ret { * @charge_status: battery operating status * @eoc_cnt: counter used to determine end-of_charge * @maintenance_chg: indicate if maintenance charge is active - * @t_hyst_norm temperature hysteresis when the temperature has been + * @t_hyst_norm: temperature hysteresis when the temperature has been * over or under normal limits - * @t_hyst_lowhigh temperature hysteresis when the temperature has been + * @t_hyst_lowhigh: temperature hysteresis when the temperature has been * over or under the high or low limits * @charge_state: current state of the charging algorithm - * @ccm charging current maximization parameters + * @ccm: charging current maximization parameters * @chg_info: information about connected charger types * @batt_data: data of the battery * @bm: Platform specific battery management information * @parent: pointer to the struct ab8500 * @chargalg_psy: structure that holds the battery properties exposed by * the charging algorithm + * @ac_chg: AC charger power supply + * @usb_chg: USB charger power supply * @events: structure for information about events triggered * @chargalg_wq: work queue for running the charging algorithm * @chargalg_periodic_work: work to run the charging algorithm periodically @@ -300,6 +302,7 @@ ab8500_chargalg_maintenance_timer_expired(struct hrtimer *timer) /** * ab8500_chargalg_state_to() - Change charge state * @di: pointer to the ab8500_chargalg structure + * @state: new charge algorithm state * * This function gets called when a charge state change should occur */ @@ -763,7 +766,7 @@ static void init_maxim_chg_curr(struct ab8500_chargalg *di) /** * ab8500_chargalg_chg_curr_maxim - increases the charger current to * compensate for the system load - * @di pointer to the ab8500_chargalg structure + * @di: pointer to the ab8500_chargalg structure * * This maximization function is used to raise the charger current to get the * battery current as close to the optimal value as possible. The battery From 04aa3d6dddaf39ecc9735d0b62f46899db71d35e Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn Date: Fri, 7 Nov 2025 13:36:21 +0100 Subject: [PATCH 21/30] MAINTAINERS: adjust file entry in ROHM BD71828 CHARGER Commit 5bff79dad20a ("power: supply: Add bd718(15/28/78) charger driver") adds the file bd71828-power.c in drivers/power/supply/, whereas commit b838cecc2291 ("MAINTAINERS: Add entry for BD71828 charger") from the same patch series, adds a section referring to the non-existing file bd71828-charger.c in the directory above. Adjust the file entry to refer to the intended existing file. Signed-off-by: Lukas Bulwahn Reviewed-by: Matti Vaittinen Link: https://patch.msgid.link/20251107123621.425633-1-lukas.bulwahn@redhat.com Signed-off-by: Sebastian Reichel --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 5b11839cba9d..31cc0cae1415 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -22685,7 +22685,7 @@ ROHM BD71828 CHARGER M: Andreas Kemnade M: Matti Vaittinen S: Maintained -F: drivers/power/supply/bd71828-charger.c +F: drivers/power/supply/bd71828-power.c ROHM BD79703 DAC M: Matti Vaittinen From 39fe0eac6d755ef215026518985fcf8de9360e9e Mon Sep 17 00:00:00 2001 From: Waqar Hameed Date: Sat, 20 Dec 2025 23:46:24 +0100 Subject: [PATCH 22/30] power: supply: wm97xx: Fix NULL pointer dereference in power_supply_changed() In `probe()`, `request_irq()` is called before allocating/registering a `power_supply` handle. If an interrupt is fired between the call to `request_irq()` and `power_supply_register()`, the `power_supply` handle will be used uninitialized in `power_supply_changed()` in `wm97xx_bat_update()` (triggered from the interrupt handler). This will lead to a `NULL` pointer dereference since Fix this racy `NULL` pointer dereference by making sure the IRQ is requested _after_ the registration of the `power_supply` handle. Since the IRQ is the last thing requests in the `probe()` now, remove the error path for freeing it. Instead add one for unregistering the `power_supply` handle when IRQ request fails. Fixes: 7c87942aef52 ("wm97xx_battery: Use irq to detect charger state") Signed-off-by: Waqar Hameed Link: https://patch.msgid.link/97b55f0479a932eea7213844bf66f28a974e27a2.1766270196.git.waqar.hameed@axis.com Signed-off-by: Sebastian Reichel --- drivers/power/supply/wm97xx_battery.c | 34 +++++++++++++++------------ 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/drivers/power/supply/wm97xx_battery.c b/drivers/power/supply/wm97xx_battery.c index b3b0c37a9dd2..f00722c88c6f 100644 --- a/drivers/power/supply/wm97xx_battery.c +++ b/drivers/power/supply/wm97xx_battery.c @@ -178,12 +178,6 @@ static int wm97xx_bat_probe(struct platform_device *dev) "failed to get charge GPIO\n"); if (charge_gpiod) { gpiod_set_consumer_name(charge_gpiod, "BATT CHRG"); - ret = request_irq(gpiod_to_irq(charge_gpiod), - wm97xx_chrg_irq, 0, - "AC Detect", dev); - if (ret) - return dev_err_probe(&dev->dev, ret, - "failed to request GPIO irq\n"); props++; /* POWER_SUPPLY_PROP_STATUS */ } @@ -199,10 +193,8 @@ static int wm97xx_bat_probe(struct platform_device *dev) props++; /* POWER_SUPPLY_PROP_VOLTAGE_MIN */ prop = kcalloc(props, sizeof(*prop), GFP_KERNEL); - if (!prop) { - ret = -ENOMEM; - goto err3; - } + if (!prop) + return -ENOMEM; prop[i++] = POWER_SUPPLY_PROP_PRESENT; if (charge_gpiod) @@ -236,15 +228,27 @@ static int wm97xx_bat_probe(struct platform_device *dev) schedule_work(&bat_work); } else { ret = PTR_ERR(bat_psy); - goto err4; + goto free; + } + + if (charge_gpiod) { + ret = request_irq(gpiod_to_irq(charge_gpiod), wm97xx_chrg_irq, + 0, "AC Detect", dev); + if (ret) { + dev_err_probe(&dev->dev, ret, + "failed to request GPIO irq\n"); + goto unregister; + } } return 0; -err4: + +unregister: + power_supply_unregister(bat_psy); + +free: kfree(prop); -err3: - if (charge_gpiod) - free_irq(gpiod_to_irq(charge_gpiod), dev); + return ret; } From 432b119ab8d8bf1f550c247f7fbe960e87ba6c92 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 4 Jan 2026 18:16:44 +0100 Subject: [PATCH 23/30] docs: power: update documentation about removed function The function cm_notify_event() was removed in commit 9584051f3cf3 ("power: supply: charger-manager: Remove cm_notify_event function"). Remove the documentation that suggests how it can be used. Signed-off-by: Julia Lawall Link: https://patch.msgid.link/20260104171644.292437-1-Julia.Lawall@inria.fr Signed-off-by: Sebastian Reichel --- Documentation/power/charger-manager.rst | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/Documentation/power/charger-manager.rst b/Documentation/power/charger-manager.rst index 84fab9376792..b29c962cacdc 100644 --- a/Documentation/power/charger-manager.rst +++ b/Documentation/power/charger-manager.rst @@ -183,17 +183,7 @@ struct charger_desc elements: the value of measure_battery_temp. -5. Notify Charger-Manager of charger events: cm_notify_event() -============================================================== -If there is an charger event is required to notify -Charger Manager, a charger device driver that triggers the event can call -cm_notify_event(psy, type, msg) to notify the corresponding Charger Manager. -In the function, psy is the charger driver's power_supply pointer, which is -associated with Charger-Manager. The parameter "type" -is the same as irq's type (enum cm_event_types). The event message "msg" is -optional and is effective only if the event type is "UNDESCRIBED" or "OTHERS". - -6. Other Considerations +5. Other Considerations ======================= At the charger/battery-related events such as battery-pulled-out, From 562357a6310f79e45844c3e980d410a1e8e02ce6 Mon Sep 17 00:00:00 2001 From: Emanuele Ghidoli Date: Fri, 30 Jan 2026 08:11:35 +0100 Subject: [PATCH 24/30] power: reset: tdx-ec-poweroff: fix restart During testing, restart occasionally failed on Toradex modules. The issue was traced to an interaction between the EC-based reset/poweroff handler and the PSCI restart handler. While the embedded controller is resetting or powering off the module, the PSCI code may still be invoked, triggering an I2C transaction to the PMIC. This can leave the PMIC I2C in a frozen state. Add a delay after issuing the EC reset or power-off command to give the controller time to complete the operation and avoid falling back to another restart/poweroff provider. Also print an error message if sending the command to the embedded controller fails. Fixes: 18672fe12367 ("power: reset: add Toradex Embedded Controller") Cc: stable@vger.kernel.org Signed-off-by: Emanuele Ghidoli Reviewed-by: Francesco Dolcini Link: https://patch.msgid.link/20260130071208.1184239-1-ghidoliemanuele@gmail.com Signed-off-by: Sebastian Reichel --- drivers/power/reset/tdx-ec-poweroff.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/power/reset/tdx-ec-poweroff.c b/drivers/power/reset/tdx-ec-poweroff.c index 3302a127fce5..8040aa03d74d 100644 --- a/drivers/power/reset/tdx-ec-poweroff.c +++ b/drivers/power/reset/tdx-ec-poweroff.c @@ -8,7 +8,10 @@ */ #include +#include +#include #include +#include #include #include #include @@ -31,6 +34,8 @@ #define EC_REG_MAX 0xD0 +#define EC_CMD_TIMEOUT_MS 1000 + static const struct regmap_range volatile_ranges[] = { regmap_reg_range(EC_CMD_REG, EC_CMD_REG), }; @@ -75,6 +80,13 @@ static int tdx_ec_power_off(struct sys_off_data *data) err = tdx_ec_cmd(regmap, EC_CMD_POWEROFF); + if (err) { + dev_err(data->dev, "Failed to send power off command\n"); + } else { + mdelay(EC_CMD_TIMEOUT_MS); + WARN_ONCE(1, "Unable to power off system\n"); + } + return err ? NOTIFY_BAD : NOTIFY_DONE; } @@ -85,6 +97,13 @@ static int tdx_ec_restart(struct sys_off_data *data) err = tdx_ec_cmd(regmap, EC_CMD_RESET); + if (err) { + dev_err(data->dev, "Failed to send restart command\n"); + } else { + mdelay(EC_CMD_TIMEOUT_MS); + WARN_ONCE(1, "Unable to restart system\n"); + } + return err ? NOTIFY_BAD : NOTIFY_DONE; } From 23067259919663580c6f81801847cfc7bd54fd1f Mon Sep 17 00:00:00 2001 From: Waqar Hameed Date: Fri, 23 Jan 2026 11:24:20 +0100 Subject: [PATCH 25/30] power: supply: pm8916_lbc: Fix use-after-free for extcon in IRQ handler Using the `devm_` variant for requesting IRQ _before_ the `devm_` variant for allocating/registering the `extcon` handle, means that the `extcon` handle will be deallocated/unregistered _before_ the interrupt handler (since `devm_` naturally deallocates in reverse allocation order). This means that during removal, there is a race condition where an interrupt can fire just _after_ the `extcon` handle has been freed, *but* just _before_ the corresponding unregistration of the IRQ handler has run. This will lead to the IRQ handler calling `extcon_set_state_sync()` with a freed `extcon` handle. Which usually crashes the system or otherwise silently corrupts the memory... Fix this racy use-after-free by making sure the IRQ is requested _after_ the registration of the `extcon` handle. Fixes: f8d7a3d21160 ("power: supply: Add driver for pm8916 lbc") Signed-off-by: Waqar Hameed Reviewed-by: Nikita Travkin Link: https://patch.msgid.link/e2a4cd2fcd42b6cd97d856c17c097289a2aed393.1769163273.git.waqar.hameed@axis.com Signed-off-by: Sebastian Reichel --- drivers/power/supply/pm8916_lbc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/power/supply/pm8916_lbc.c b/drivers/power/supply/pm8916_lbc.c index 3ca717d84aad..6b631012a795 100644 --- a/drivers/power/supply/pm8916_lbc.c +++ b/drivers/power/supply/pm8916_lbc.c @@ -327,11 +327,6 @@ static int pm8916_lbc_charger_probe(struct platform_device *pdev) if (irq < 0) return irq; - ret = devm_request_threaded_irq(dev, irq, NULL, pm8916_lbc_charger_state_changed_irq, - IRQF_ONESHOT, "pm8916_lbc", chg); - if (ret) - return ret; - chg->edev = devm_extcon_dev_allocate(dev, pm8916_lbc_charger_cable); if (IS_ERR(chg->edev)) return PTR_ERR(chg->edev); @@ -340,6 +335,11 @@ static int pm8916_lbc_charger_probe(struct platform_device *pdev) if (ret < 0) return dev_err_probe(dev, ret, "failed to register extcon device\n"); + ret = devm_request_threaded_irq(dev, irq, NULL, pm8916_lbc_charger_state_changed_irq, + IRQF_ONESHOT, "pm8916_lbc", chg); + if (ret) + return ret; + ret = regmap_read(chg->regmap, chg->reg[LBC_USB] + PM8916_INT_RT_STS, &tmp); if (ret) goto comm_error; From 72db889394d89ffde61e7438f0cdfc0135c9da48 Mon Sep 17 00:00:00 2001 From: Waqar Hameed Date: Fri, 23 Jan 2026 09:55:43 +0100 Subject: [PATCH 26/30] power: supply: wm97xx: Use devm_kcalloc() Instead of handling the memory allocation manually, use the automatic `devres` variant `devm_kcalloc()`. This is less error prone and eliminates the `goto`-path. Signed-off-by: Waqar Hameed Link: https://patch.msgid.link/5ac93f5b0fa417bb5d9e93b9302a18f2c04d4077.1769158280.git.waqar.hameed@axis.com Signed-off-by: Sebastian Reichel --- drivers/power/supply/wm97xx_battery.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/power/supply/wm97xx_battery.c b/drivers/power/supply/wm97xx_battery.c index f00722c88c6f..c30c347b48f9 100644 --- a/drivers/power/supply/wm97xx_battery.c +++ b/drivers/power/supply/wm97xx_battery.c @@ -192,7 +192,7 @@ static int wm97xx_bat_probe(struct platform_device *dev) if (pdata->min_voltage >= 0) props++; /* POWER_SUPPLY_PROP_VOLTAGE_MIN */ - prop = kcalloc(props, sizeof(*prop), GFP_KERNEL); + prop = devm_kcalloc(&dev->dev, props, sizeof(*prop), GFP_KERNEL); if (!prop) return -ENOMEM; @@ -224,12 +224,10 @@ static int wm97xx_bat_probe(struct platform_device *dev) bat_psy_desc.num_properties = props; bat_psy = power_supply_register(&dev->dev, &bat_psy_desc, &cfg); - if (!IS_ERR(bat_psy)) { - schedule_work(&bat_work); - } else { - ret = PTR_ERR(bat_psy); - goto free; - } + if (IS_ERR(bat_psy)) + return PTR_ERR(bat_psy); + + schedule_work(&bat_work); if (charge_gpiod) { ret = request_irq(gpiod_to_irq(charge_gpiod), wm97xx_chrg_irq, @@ -246,9 +244,6 @@ static int wm97xx_bat_probe(struct platform_device *dev) unregister: power_supply_unregister(bat_psy); -free: - kfree(prop); - return ret; } @@ -258,7 +253,6 @@ static void wm97xx_bat_remove(struct platform_device *dev) free_irq(gpiod_to_irq(charge_gpiod), dev); cancel_work_sync(&bat_work); power_supply_unregister(bat_psy); - kfree(prop); } static struct platform_driver wm97xx_bat_driver = { From 3db37475d78ed0c2857f289a535dd44b045a904a Mon Sep 17 00:00:00 2001 From: Waqar Hameed Date: Fri, 23 Jan 2026 09:55:43 +0100 Subject: [PATCH 27/30] power: supply: wm97xx: Use devm_power_supply_register() Instead of handling the registration manually, use the automatic `devres` variant `devm_power_supply_register()`. This is less error prone and cleaner. Signed-off-by: Waqar Hameed Link: https://patch.msgid.link/b0b366d302f0605c8555dd68ed32973959f133bb.1769158280.git.waqar.hameed@axis.com Signed-off-by: Sebastian Reichel --- drivers/power/supply/wm97xx_battery.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/power/supply/wm97xx_battery.c b/drivers/power/supply/wm97xx_battery.c index c30c347b48f9..a6c55b1e0286 100644 --- a/drivers/power/supply/wm97xx_battery.c +++ b/drivers/power/supply/wm97xx_battery.c @@ -223,7 +223,7 @@ static int wm97xx_bat_probe(struct platform_device *dev) bat_psy_desc.properties = prop; bat_psy_desc.num_properties = props; - bat_psy = power_supply_register(&dev->dev, &bat_psy_desc, &cfg); + bat_psy = devm_power_supply_register(&dev->dev, &bat_psy_desc, &cfg); if (IS_ERR(bat_psy)) return PTR_ERR(bat_psy); @@ -232,19 +232,12 @@ static int wm97xx_bat_probe(struct platform_device *dev) if (charge_gpiod) { ret = request_irq(gpiod_to_irq(charge_gpiod), wm97xx_chrg_irq, 0, "AC Detect", dev); - if (ret) { - dev_err_probe(&dev->dev, ret, - "failed to request GPIO irq\n"); - goto unregister; - } + if (ret) + return dev_err_probe(&dev->dev, ret, + "failed to request GPIO irq\n"); } return 0; - -unregister: - power_supply_unregister(bat_psy); - - return ret; } static void wm97xx_bat_remove(struct platform_device *dev) @@ -252,7 +245,6 @@ static void wm97xx_bat_remove(struct platform_device *dev) if (charge_gpiod) free_irq(gpiod_to_irq(charge_gpiod), dev); cancel_work_sync(&bat_work); - power_supply_unregister(bat_psy); } static struct platform_driver wm97xx_bat_driver = { From c655f45480637aee326b5bd96488d35ab90db2b0 Mon Sep 17 00:00:00 2001 From: Val Packett Date: Tue, 20 Jan 2026 20:57:58 -0300 Subject: [PATCH 28/30] power: supply: qcom_battmgr: Recognize "LiP" as lithium-polymer On the Dell Latitude 7455, the firmware uses "LiP" with a lowercase 'i' for the battery chemistry type, but only all-uppercase "LIP" was being recognized. Add the CamelCase variant to the check to fix the "Unknown battery technology" warning. Fixes: 202ac22b8e2e ("power: supply: qcom_battmgr: Add lithium-polymer entry") Signed-off-by: Val Packett Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Link: https://patch.msgid.link/20260120235831.479038-1-val@packett.cool Signed-off-by: Sebastian Reichel --- drivers/power/supply/qcom_battmgr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/power/supply/qcom_battmgr.c b/drivers/power/supply/qcom_battmgr.c index c8028606bba0..80572ee945b4 100644 --- a/drivers/power/supply/qcom_battmgr.c +++ b/drivers/power/supply/qcom_battmgr.c @@ -1240,7 +1240,8 @@ static unsigned int qcom_battmgr_sc8280xp_parse_technology(const char *chemistry if ((!strncmp(chemistry, "LIO", BATTMGR_CHEMISTRY_LEN)) || (!strncmp(chemistry, "OOI", BATTMGR_CHEMISTRY_LEN))) return POWER_SUPPLY_TECHNOLOGY_LION; - if (!strncmp(chemistry, "LIP", BATTMGR_CHEMISTRY_LEN)) + if (!strncmp(chemistry, "LIP", BATTMGR_CHEMISTRY_LEN) || + !strncmp(chemistry, "LiP", BATTMGR_CHEMISTRY_LEN)) return POWER_SUPPLY_TECHNOLOGY_LIPO; pr_err("Unknown battery technology '%s'\n", chemistry); From 4c3f02f843999a590f4481791f59a2f9a7f34fe4 Mon Sep 17 00:00:00 2001 From: Kuan-Wei Chiu Date: Tue, 13 Jan 2026 09:26:00 +0000 Subject: [PATCH 29/30] dt-bindings: power: supply: google,goldfish-battery: Convert to DT schema Convert the Android Goldfish Battery binding to DT schema format. Move the file to the power/supply directory to match the subsystem. Update the example node name to 'battery' to comply with generic node naming standards. Signed-off-by: Kuan-Wei Chiu Reviewed-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20260113092602.3197681-5-visitorckw@gmail.com Signed-off-by: Sebastian Reichel --- .../devicetree/bindings/goldfish/battery.txt | 17 -------- .../power/supply/google,goldfish-battery.yaml | 41 +++++++++++++++++++ 2 files changed, 41 insertions(+), 17 deletions(-) delete mode 100644 Documentation/devicetree/bindings/goldfish/battery.txt create mode 100644 Documentation/devicetree/bindings/power/supply/google,goldfish-battery.yaml diff --git a/Documentation/devicetree/bindings/goldfish/battery.txt b/Documentation/devicetree/bindings/goldfish/battery.txt deleted file mode 100644 index 4fb613933214..000000000000 --- a/Documentation/devicetree/bindings/goldfish/battery.txt +++ /dev/null @@ -1,17 +0,0 @@ -Android Goldfish Battery - -Android goldfish battery device generated by android emulator. - -Required properties: - -- compatible : should contain "google,goldfish-battery" to match emulator -- reg : -- interrupts : - -Example: - - goldfish_battery@9020000 { - compatible = "google,goldfish-battery"; - reg = <0x9020000 0x1000>; - interrupts = <0x3>; - }; diff --git a/Documentation/devicetree/bindings/power/supply/google,goldfish-battery.yaml b/Documentation/devicetree/bindings/power/supply/google,goldfish-battery.yaml new file mode 100644 index 000000000000..634327c89c88 --- /dev/null +++ b/Documentation/devicetree/bindings/power/supply/google,goldfish-battery.yaml @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/power/supply/google,goldfish-battery.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Android Goldfish Battery + +maintainers: + - Kuan-Wei Chiu + +allOf: + - $ref: power-supply.yaml# + +description: + Android goldfish battery device generated by Android emulator. + +properties: + compatible: + const: google,goldfish-battery + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + +unevaluatedProperties: false + +examples: + - | + battery@9020000 { + compatible = "google,goldfish-battery"; + reg = <0x9020000 0x1000>; + interrupts = <3>; + }; From 12bdf471e374b34cb0e48b29bb9eb9127ed26fc5 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Thu, 15 Jan 2026 12:19:04 +0200 Subject: [PATCH 30/30] power: supply: bd71828: Use dev_err_probe() The driver uses separate error printing and error returning at probe() for locations where the error value is hard-coded and can't be EPROBE_DEFER. This helps to omit the extra return value check which is done in dev_err_probe(). Using the dev_err_probe() has some other benefits besides handling the -EPROBE_DEFER though, like standardizing the print for error numbers. Some believe thes outweigh the benefit of skipping the extra check. Use dev_err_probe() consistently in the bd71828 power-supply probe. Signed-off-by: Matti Vaittinen Link: https://patch.msgid.link/aWi_GG74sZRfajA_@mva-rohm Signed-off-by: Sebastian Reichel --- drivers/power/supply/bd71828-power.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/power/supply/bd71828-power.c b/drivers/power/supply/bd71828-power.c index 438e220a9cb7..0e00acb58993 100644 --- a/drivers/power/supply/bd71828-power.c +++ b/drivers/power/supply/bd71828-power.c @@ -1058,10 +1058,8 @@ static int bd71828_power_probe(struct platform_device *pdev) pwr->regmap = dev_get_regmap(pdev->dev.parent, NULL); else pwr->regmap = dev_get_regmap(pdev->dev.parent, "wrap-map"); - if (!pwr->regmap) { - dev_err(&pdev->dev, "No parent regmap\n"); - return -EINVAL; - } + if (!pwr->regmap) + return dev_err_probe(&pdev->dev, -EINVAL, "No parent regmap\n"); pwr->dev = &pdev->dev; @@ -1083,8 +1081,7 @@ static int bd71828_power_probe(struct platform_device *pdev) dev_dbg(pwr->dev, "Found ROHM BD72720\n"); break; default: - dev_err(pwr->dev, "Unknown PMIC\n"); - return -EINVAL; + return dev_err_probe(pwr->dev, -EINVAL, "Unknown PMIC\n"); } ret = bd7182x_get_rsens(pwr);