* [PATCH 00/10] regulator: Fix teardown races, reference counting, and error handling
@ 2026-11-04 18:20 Lee Jones
2026-11-04 18:20 ` [PATCH 01/10] regulator: irq_helpers: Clear caller handle in regulator_irq_helper_cancel() Lee Jones
` (9 more replies)
0 siblings, 10 replies; 11+ messages in thread
From: Lee Jones @ 2026-11-04 18:20 UTC (permalink / raw)
To: lee
Cc: linux-kernel, André Draszik, Andy Shevchenko,
Bartosz Golaszewski, Charles Keepax, ChiYuan Huang, Chris Morgan,
Douglas Anderson, Eduardo Candelaria, Esteban Blanc,
Graeme Gregory, Gyungoh Yoo, Jerome Neanne, Jiale Yao,
Kuninori Morimoto, Laxman Dewangan, Liam Girdwood, Linus Walleij,
Mal Nadar, Mark Brown, Matti Vaittinen, Stephen Warren,
Uday Khare, Wentao Liang, linux-gpio, patches
These issues were reported by Sashiko.
This series addresses ten bugs across the regulator core and regulator
drivers:
- Clear the caller's handle pointer (*handle = NULL) in
regulator_irq_helper_cancel() instead of assigning NULL to the local
variable.
- Remove the redundant arizona_ldo1_remove() callback that caused a
premature and double gpiod_put() on config.ena_gpiod (whose lifetime
is owned by the regulator core).
- Flush rdev->disable_work with flush_delayed_work() before releasing
rdev->supply in regulator_unregister().
- Cancel micsupp->check_cp_work on device teardown in arizona-micsupp
using devm_work_autocancel().
- Take a dedicated device reference for rdev->supply in set_supply() and
retain the local lookup reference throughout regulator_resolve_supply().
- Initialise rdev->last_off with ktime_get_boottime() in
set_machine_constraints() to match _regulator_do_enable() and
_regulator_do_disable().
- Propagate GPIO lookup errors (such as -EPROBE_DEFER) from
bq257xx_reg_dt_parse_gpio() instead of leaving an ERR_PTR in
pdata->otg_en_gpio.
- Fix the LDO4 n_voltages count in tps6594-regulator so selectors 0x3f
through 0x74 are reachable.
- Guard against a NULL idata pointer for BBAT, SDBY, and VRTC in
max8907_regulator_probe().
- Check the pm_runtime_resume_and_get() return value in
rt6190_out_enable().
Cc: "André Draszik" <andre.draszik@linaro.org>
Cc: Andy Shevchenko <andy.shevchenko@gmail.com>
Cc: Bartosz Golaszewski <brgl@kernel.org>
Cc: Charles Keepax <ckeepax@opensource.cirrus.com>
Cc: ChiYuan Huang <cy_huang@richtek.com>
Cc: Chris Morgan <macromorgan@hotmail.com>
Cc: Douglas Anderson <dianders@chromium.org>
Cc: Eduardo Candelaria <jedu@slimlogic.co.uk>
Cc: Esteban Blanc <eblanc@baylibre.com>
Cc: Graeme Gregory <gg@slimlogic.co.uk>
Cc: Gyungoh Yoo <jack.yoo@maxim-ic.com>
Cc: Jerome Neanne <jneanne@baylibre.com>
Cc: Jiale Yao <yaojiale02@163.com>
Cc: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Cc: Laxman Dewangan <ldewangan@nvidia.com>
Cc: Liam Girdwood <lgirdwood@gmail.com>
Cc: Linus Walleij <linusw@kernel.org>
Cc: Mal Nadar <m.nirmaladevi@ltts.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Matti Vaittinen <mazziesaccount@gmail.com>
Cc: Stephen Warren <swarren@nvidia.com>
Cc: Uday Khare <udaykhare77@gmail.com>
Cc: Wentao Liang <vulab@iscas.ac.cn>
Cc: linux-gpio@vger.kernel.org
Cc: patches@opensource.cirrus.com
Lee Jones (10):
regulator: irq_helpers: Clear caller handle in
regulator_irq_helper_cancel()
regulator: arizona-ldo1: Avoid double gpiod_put() on enable GPIO
regulator: core: Flush delayed disable_work before releasing supply in
regulator_unregister()
regulator: arizona-micsupp: Cancel check_cp_work on device teardown
regulator: core: Hold supply device reference until constraints are
resolved in regulator_resolve_supply()
regulator: core: Use ktime_get_boottime() in set_machine_constraints()
regulator: bq257xx: Propagate GPIO error in
bq257xx_reg_dt_parse_gpio()
regulator: tps6594-regulator: Fix LDO4 n_voltages in tps6594_ldo_regs
regulator: max8907: Avoid NULL idata dereference in
max8907_regulator_probe()
regulator: rt6190: Check pm_runtime_resume_and_get() return value in
rt6190_out_enable()
drivers/regulator/arizona-ldo1.c | 16 ----------------
drivers/regulator/arizona-micsupp.c | 6 +++++-
drivers/regulator/bq257xx-regulator.c | 20 ++++++++++++--------
drivers/regulator/core.c | 22 ++++++++++++----------
drivers/regulator/irq_helpers.c | 2 +-
drivers/regulator/max8907-regulator.c | 3 ++-
drivers/regulator/rt6190-regulator.c | 4 +++-
drivers/regulator/tps6594-regulator.c | 2 +-
8 files changed, 36 insertions(+), 39 deletions(-)
base-commit: 6628e7d4c6b25c8d18f1345e3a20d21829aae7e4
--
2.56.0.385.gac671c819a-goog
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 01/10] regulator: irq_helpers: Clear caller handle in regulator_irq_helper_cancel()
2026-11-04 18:20 [PATCH 00/10] regulator: Fix teardown races, reference counting, and error handling Lee Jones
@ 2026-11-04 18:20 ` Lee Jones
2026-11-04 18:20 ` [PATCH 02/10] regulator: arizona-ldo1: Avoid double gpiod_put() on enable GPIO Lee Jones
` (8 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Lee Jones @ 2026-11-04 18:20 UTC (permalink / raw)
To: lee, Matti Vaittinen, Liam Girdwood, Mark Brown, Jiale Yao,
Andy Shevchenko, linux-kernel
Cc: stable
regulator_irq_helper_cancel() is documented as clearing the caller's
handle pointer upon return, and takes a void **handle parameter for
that purpose. Instead, it assigns NULL to the local pointer h before
returning, leaving the caller with a dangling pointer to freed memory.
Dereference handle to clear the caller's pointer as intended.
Fixes: 7111c6d1b31b ("regulator: IRQ based event/error notification helpers")
Closes: https://sashiko.dev/#/bug/linux-5c3d3b21-3823-4654-bf5d-85407c5fd05f
Cc: stable@vger.kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
---
drivers/regulator/irq_helpers.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/regulator/irq_helpers.c b/drivers/regulator/irq_helpers.c
index cdbd170d2b15..7b25eae667e3 100644
--- a/drivers/regulator/irq_helpers.c
+++ b/drivers/regulator/irq_helpers.c
@@ -403,7 +403,7 @@ void regulator_irq_helper_cancel(void **handle)
destroy_workqueue(h->wq);
}
- h = NULL;
+ *handle = NULL;
}
}
EXPORT_SYMBOL_GPL(regulator_irq_helper_cancel);
--
2.56.0.385.gac671c819a-goog
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 02/10] regulator: arizona-ldo1: Avoid double gpiod_put() on enable GPIO
2026-11-04 18:20 [PATCH 00/10] regulator: Fix teardown races, reference counting, and error handling Lee Jones
2026-11-04 18:20 ` [PATCH 01/10] regulator: irq_helpers: Clear caller handle in regulator_irq_helper_cancel() Lee Jones
@ 2026-11-04 18:20 ` Lee Jones
2026-11-04 18:20 ` [PATCH 03/10] regulator: core: Flush delayed disable_work before releasing supply in regulator_unregister() Lee Jones
` (7 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Lee Jones @ 2026-11-04 18:20 UTC (permalink / raw)
To: lee, Liam Girdwood, Mark Brown, Linus Walleij,
Bartosz Golaszewski, Charles Keepax, patches, linux-kernel,
linux-gpio
Cc: stable
Passing config.ena_gpiod to devm_regulator_register() transfers ownership
of the GPIO descriptor to the regulator core, which releases it via
gpiod_put() in regulator_ena_gpio_free() upon registration failure or
when devres unregisters the regulator.
Calling gpiod_put(ldo1->ena_gpiod) in arizona_ldo1_remove() prematurely
frees the enable GPIO while the regulator is still registered and causes
a second gpiod_put() when devm_rdev_release() runs. Drop the redundant
remove callback and ena_gpiod field so the regulator core manages the
descriptor lifetime exclusively.
Fixes: a9191579ba10 ("regulator: arizona-ldo1: Use correct device to get enable GPIO")
Closes: https://sashiko.dev/#/bug/linux-7988402e-ca08-4bd3-9488-5779d6da0450
Cc: stable@vger.kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
---
drivers/regulator/arizona-ldo1.c | 16 ----------------
1 file changed, 16 deletions(-)
diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c
index 501843996faa..981e047167ea 100644
--- a/drivers/regulator/arizona-ldo1.c
+++ b/drivers/regulator/arizona-ldo1.c
@@ -35,8 +35,6 @@ struct arizona_ldo1 {
struct regulator_consumer_supply supply;
struct regulator_init_data init_data;
-
- struct gpio_desc *ena_gpiod;
};
static int arizona_ldo1_hc_set_voltage_sel(struct regulator_dev *rdev,
@@ -262,8 +260,6 @@ static int arizona_ldo1_common_init(struct platform_device *pdev,
if (IS_ERR(config.ena_gpiod))
return PTR_ERR(config.ena_gpiod);
- ldo1->ena_gpiod = config.ena_gpiod;
-
if (pdata->init_data)
config.init_data = pdata->init_data;
else
@@ -287,8 +283,6 @@ static int arizona_ldo1_common_init(struct platform_device *pdev,
return ret;
}
- platform_set_drvdata(pdev, ldo1);
-
return 0;
}
@@ -339,14 +333,6 @@ static int arizona_ldo1_probe(struct platform_device *pdev)
return ret;
}
-static void arizona_ldo1_remove(struct platform_device *pdev)
-{
- struct arizona_ldo1 *ldo1 = platform_get_drvdata(pdev);
-
- if (ldo1->ena_gpiod)
- gpiod_put(ldo1->ena_gpiod);
-}
-
static int madera_ldo1_probe(struct platform_device *pdev)
{
struct madera *madera = dev_get_drvdata(pdev->dev.parent);
@@ -375,7 +361,6 @@ static int madera_ldo1_probe(struct platform_device *pdev)
static struct platform_driver arizona_ldo1_driver = {
.probe = arizona_ldo1_probe,
- .remove = arizona_ldo1_remove,
.driver = {
.name = "arizona-ldo1",
.probe_type = PROBE_FORCE_SYNCHRONOUS,
@@ -384,7 +369,6 @@ static struct platform_driver arizona_ldo1_driver = {
static struct platform_driver madera_ldo1_driver = {
.probe = madera_ldo1_probe,
- .remove = arizona_ldo1_remove,
.driver = {
.name = "madera-ldo1",
.probe_type = PROBE_FORCE_SYNCHRONOUS,
--
2.56.0.385.gac671c819a-goog
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 03/10] regulator: core: Flush delayed disable_work before releasing supply in regulator_unregister()
2026-11-04 18:20 [PATCH 00/10] regulator: Fix teardown races, reference counting, and error handling Lee Jones
2026-11-04 18:20 ` [PATCH 01/10] regulator: irq_helpers: Clear caller handle in regulator_irq_helper_cancel() Lee Jones
2026-11-04 18:20 ` [PATCH 02/10] regulator: arizona-ldo1: Avoid double gpiod_put() on enable GPIO Lee Jones
@ 2026-11-04 18:20 ` Lee Jones
2026-11-04 18:20 ` [PATCH 04/10] regulator: arizona-micsupp: Cancel check_cp_work on device teardown Lee Jones
` (6 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Lee Jones @ 2026-11-04 18:20 UTC (permalink / raw)
To: lee, Liam Girdwood, Mark Brown, linux-kernel; +Cc: stable
regulator_unregister() currently calls flush_work() on
rdev->disable_work.work after tearing down and freeing rdev->supply.
This has two bugs:
1. Because rdev->disable_work is a delayed_work, flush_work() only waits
for work that has already been queued and ignores an armed timer,
allowing delayed_work_timer_fn() to fire after device_unregister()
has freed rdev.
2. regulator_disable_work() locks and disables rdev->supply via
regulator_lock_dependent() and _regulator_disable(), so releasing
rdev->supply before flushing disable_work races with any pending or
running deferred disable work item.
Use flush_delayed_work() at the start of regulator_unregister() so any
deferred disable work completes before rdev->supply is torn down.
Fixes: da07ecd93b19 ("regulator: Implement deferred disable support")
Fixes: e032b376551a ("regulator: Fix deadlock on removal of regulators with supplies")
Closes: https://sashiko.dev/#/bug/linux-6ee97926-52f2-4842-ba55-b554f9b39d53
Closes: https://sashiko.dev/#/bug/linux-aac296d1-789a-469b-8bde-8e110c4447ea
Cc: stable@vger.kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
---
drivers/regulator/core.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 14422cfe80e2..935fee27f126 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -6299,6 +6299,8 @@ void regulator_unregister(struct regulator_dev *rdev)
if (rdev == NULL)
return;
+ flush_delayed_work(&rdev->disable_work);
+
if (rdev->supply) {
regulator_unregister_notifier(rdev->supply,
&rdev->supply_fwd_nb);
@@ -6308,8 +6310,6 @@ void regulator_unregister(struct regulator_dev *rdev)
regulator_put(rdev->supply);
}
- flush_work(&rdev->disable_work.work);
-
mutex_lock(®ulator_list_mutex);
WARN_ON(rdev->open_count);
--
2.56.0.385.gac671c819a-goog
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 04/10] regulator: arizona-micsupp: Cancel check_cp_work on device teardown
2026-11-04 18:20 [PATCH 00/10] regulator: Fix teardown races, reference counting, and error handling Lee Jones
` (2 preceding siblings ...)
2026-11-04 18:20 ` [PATCH 03/10] regulator: core: Flush delayed disable_work before releasing supply in regulator_unregister() Lee Jones
@ 2026-11-04 18:20 ` Lee Jones
2026-11-04 18:20 ` [PATCH 05/10] regulator: core: Hold supply device reference until constraints are resolved in regulator_resolve_supply() Lee Jones
` (5 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Lee Jones @ 2026-11-04 18:20 UTC (permalink / raw)
To: lee, Liam Girdwood, Mark Brown, Kuninori Morimoto, patches, linux-kernel
Cc: stable
micsupp->check_cp_work is initialised with raw INIT_WORK() and is never
cancelled when the regulator device is unbound or when registration
fails after set_machine_constraints() has run, allowing a pending work
item to dereference micsupp after devres frees it.
Initialise check_cp_work with devm_work_autocancel() before registering
the regulator so the work item is cancelled after regulator teardown and
before micsupp is freed.
Fixes: e6ed90581bfa ("regulator: arizona-micsupp: Enable SYSCLK for charge pump")
Closes: https://sashiko.dev/#/bug/linux-3f85eadb-7493-4aea-9e4d-ce319b6e0688
Cc: stable@vger.kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
---
drivers/regulator/arizona-micsupp.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c
index be7208bc7409..70b939d3e704 100644
--- a/drivers/regulator/arizona-micsupp.c
+++ b/drivers/regulator/arizona-micsupp.c
@@ -10,6 +10,7 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/bitops.h>
+#include <linux/devm-helpers.h>
#include <linux/err.h>
#include <linux/of.h>
#include <linux/platform_device.h>
@@ -255,7 +256,10 @@ static int arizona_micsupp_common_init(struct platform_device *pdev,
struct regulator_config config = { };
int ret;
- INIT_WORK(&micsupp->check_cp_work, arizona_micsupp_check_cp);
+ ret = devm_work_autocancel(&pdev->dev, &micsupp->check_cp_work,
+ arizona_micsupp_check_cp);
+ if (ret)
+ return ret;
micsupp->init_data.consumer_supplies = &micsupp->supply;
micsupp->supply.dev_name = dev_name(micsupp->dev);
--
2.56.0.385.gac671c819a-goog
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 05/10] regulator: core: Hold supply device reference until constraints are resolved in regulator_resolve_supply()
2026-11-04 18:20 [PATCH 00/10] regulator: Fix teardown races, reference counting, and error handling Lee Jones
` (3 preceding siblings ...)
2026-11-04 18:20 ` [PATCH 04/10] regulator: arizona-micsupp: Cancel check_cp_work on device teardown Lee Jones
@ 2026-11-04 18:20 ` Lee Jones
2026-11-04 18:20 ` [PATCH 06/10] regulator: core: Use ktime_get_boottime() in set_machine_constraints() Lee Jones
` (4 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Lee Jones @ 2026-11-04 18:20 UTC (permalink / raw)
To: lee, Liam Girdwood, Mark Brown, André Draszik, linux-kernel; +Cc: stable
In regulator_resolve_supply(), set_supply() previously consumed the
caller's lookup reference on &r->dev without taking its own reference
for rdev->supply, while the concurrent path (when rdev->supply was
already set) dropped put_device(&r->dev) immediately after unlocking
and before retrying set_machine_constraints(). In both paths, if
set_machine_constraints() fails (which may drop rdev->supply inside
set_machine_constraints() or race with a concurrent task in
unset_supply), the error path subsequently passes r to
regulator_lock_two(rdev, r, &ww_ctx) without holding a guaranteed local
reference on &r->dev.
Take a dedicated device reference for rdev->supply in set_supply() to
match _regulator_put(), and retain the local lookup reference on &r->dev
throughout regulator_resolve_supply() until returning.
Fixes: 8d38423d9dea ("regulator: core: don't fail regulator_register() with missing required supply")
Closes: https://sashiko.dev/#/bug/linux-3a22ff58-1a66-4a6a-9e19-83135ef603e0
Cc: stable@vger.kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
---
drivers/regulator/core.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 935fee27f126..6d522731e4d9 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1842,6 +1842,7 @@ static int set_supply(struct regulator_dev *rdev,
err = -ENOMEM;
return err;
}
+ get_device(&supply_rdev->dev);
supply_rdev->open_count++;
return 0;
@@ -2290,22 +2291,20 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
supply = rdev->supply;
regulator_unlock_two(rdev, r, &ww_ctx);
- put_device(&r->dev);
/*
* Supply resolved by concurrent task, and constraints set as
* well (or not required): fast path.
*/
if (done)
- goto out;
+ goto out_put;
do_final_setup = false;
} else {
ret = set_supply(rdev, r);
if (ret < 0) {
regulator_unlock_two(rdev, r, &ww_ctx);
- put_device(&r->dev);
- goto out;
+ goto out_put;
}
supply = rdev->supply;
@@ -2342,7 +2341,7 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
*/
regulator_unlock_dependent(rdev, &ww_ctx);
ret = -EPROBE_DEFER;
- goto out;
+ goto out_put;
}
ret = set_machine_constraints(rdev, true);
@@ -2364,7 +2363,7 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
* that again via unset_supply.
*/
regulator_unlock_two(rdev, r, &ww_ctx);
- goto out;
+ goto out_put;
}
unregister_regulator_event_forwarding(rdev);
@@ -2376,11 +2375,13 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
regulator_unlock_dependent(rdev, &ww_ctx);
if (!do_final_setup)
- goto out;
+ goto out_put;
/* rdev->supply was created in set_supply() */
link_and_create_debugfs(rdev->supply, rdev->supply->rdev, &rdev->dev);
+out_put:
+ put_device(&r->dev);
out:
return ret;
@@ -2391,6 +2392,7 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
regulator_unlock_two(rdev, supply->rdev, &ww_ctx);
regulator_put(supply);
+ put_device(&r->dev);
return ret;
}
--
2.56.0.385.gac671c819a-goog
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 06/10] regulator: core: Use ktime_get_boottime() in set_machine_constraints()
2026-11-04 18:20 [PATCH 00/10] regulator: Fix teardown races, reference counting, and error handling Lee Jones
` (4 preceding siblings ...)
2026-11-04 18:20 ` [PATCH 05/10] regulator: core: Hold supply device reference until constraints are resolved in regulator_resolve_supply() Lee Jones
@ 2026-11-04 18:20 ` Lee Jones
2026-11-04 18:20 ` [PATCH 07/10] regulator: bq257xx: Propagate GPIO error in bq257xx_reg_dt_parse_gpio() Lee Jones
` (3 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Lee Jones @ 2026-11-04 18:20 UTC (permalink / raw)
To: lee, Liam Girdwood, Mark Brown, Douglas Anderson, linux-kernel; +Cc: stable
rdev->last_off is tracked against CLOCK_BOOTTIME in both
_regulator_do_enable() and _regulator_do_disable(), whereas
set_machine_constraints() initialises rdev->last_off using ktime_get()
(CLOCK_MONOTONIC). If the system suspends before a regulator with
off_on_delay is enabled, comparing a CLOCK_BOOTTIME timestamp against a
CLOCK_MONOTONIC timestamp produces an incorrect elapsed off-time.
Use ktime_get_boottime() in set_machine_constraints() so rdev->last_off
uses the same clock base everywhere.
Fixes: 691c1fcda535 ("regulator: core: Shorten off-on-delay-us for always-on/boot-on by time since booted")
Closes: https://sashiko.dev/#/bug/linux-4afd38c3-0589-4544-961d-4e3cc5ed8639
Cc: stable@vger.kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
---
drivers/regulator/core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 6d522731e4d9..6b5fae3cd486 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1698,7 +1698,7 @@ static int set_machine_constraints(struct regulator_dev *rdev,
if (rdev->constraints->always_on)
rdev->use_count++;
} else if (rdev->desc->off_on_delay) {
- rdev->last_off = ktime_get();
+ rdev->last_off = ktime_get_boottime();
}
if (!rdev->constraints->pw_budget_mW)
--
2.56.0.385.gac671c819a-goog
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 07/10] regulator: bq257xx: Propagate GPIO error in bq257xx_reg_dt_parse_gpio()
2026-11-04 18:20 [PATCH 00/10] regulator: Fix teardown races, reference counting, and error handling Lee Jones
` (5 preceding siblings ...)
2026-11-04 18:20 ` [PATCH 06/10] regulator: core: Use ktime_get_boottime() in set_machine_constraints() Lee Jones
@ 2026-11-04 18:20 ` Lee Jones
2026-11-04 18:20 ` [PATCH 08/10] regulator: tps6594-regulator: Fix LDO4 n_voltages in tps6594_ldo_regs Lee Jones
` (2 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Lee Jones @ 2026-11-04 18:20 UTC (permalink / raw)
To: lee, Liam Girdwood, Mark Brown, Chris Morgan, linux-kernel; +Cc: stable
When devm_fwnode_gpiod_get_index() fails with an error other than
-ENOENT (such as -EPROBE_DEFER), bq257xx_reg_dt_parse_gpio() logs the
error and returns void, leaving the error pointer stored in
pdata->otg_en_gpio. bq257xx_regulator_probe() then registers the
regulator and bq25703_vbus_enable() / bq25703_vbus_disable() pass the
ERR_PTR to gpiod_set_value_cansleep().
Return the error code from bq257xx_reg_dt_parse_gpio() via
dev_err_probe() and propagate it from bq257xx_regulator_probe().
Fixes: 981dd162b635 ("regulator: bq257xx: Add bq257xx boost regulator driver")
Closes: https://sashiko.dev/#/bug/linux-0d1fc150-1400-4ba5-ad27-3d7376fb2d7d
Cc: stable@vger.kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
---
drivers/regulator/bq257xx-regulator.c | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/drivers/regulator/bq257xx-regulator.c b/drivers/regulator/bq257xx-regulator.c
index 577b277efd7f..0db99a74e9e8 100644
--- a/drivers/regulator/bq257xx-regulator.c
+++ b/drivers/regulator/bq257xx-regulator.c
@@ -103,7 +103,7 @@ static const struct regulator_desc bq25703_vbus_desc = {
};
/* Get optional GPIO for OTG regulator enable. */
-static void bq257xx_reg_dt_parse_gpio(struct platform_device *pdev)
+static int bq257xx_reg_dt_parse_gpio(struct platform_device *pdev)
{
struct device_node *child, *subchild;
struct bq257xx_reg_data *pdata = platform_get_drvdata(pdev);
@@ -111,12 +111,12 @@ static void bq257xx_reg_dt_parse_gpio(struct platform_device *pdev)
child = of_get_child_by_name(pdev->dev.of_node,
pdata->desc.regulators_node);
if (!child)
- return;
+ return 0;
subchild = of_get_child_by_name(child, pdata->desc.of_match);
of_node_put(child);
if (!subchild)
- return;
+ return 0;
pdata->otg_en_gpio = devm_fwnode_gpiod_get_index(&pdev->dev,
of_fwnode_handle(subchild),
@@ -130,13 +130,14 @@ static void bq257xx_reg_dt_parse_gpio(struct platform_device *pdev)
if (PTR_ERR(pdata->otg_en_gpio) == -ENOENT) {
/* No GPIO, will only use register writes for OTG */
pdata->otg_en_gpio = NULL;
- return;
+ return 0;
}
- dev_err(&pdev->dev, "Error getting enable gpio: %ld\n",
- PTR_ERR(pdata->otg_en_gpio));
- return;
+ return dev_err_probe(&pdev->dev, PTR_ERR(pdata->otg_en_gpio),
+ "Error getting enable gpio\n");
}
+
+ return 0;
}
static int bq257xx_regulator_probe(struct platform_device *pdev)
@@ -144,6 +145,7 @@ static int bq257xx_regulator_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct bq257xx_reg_data *pdata;
struct regulator_config cfg = {};
+ int ret;
device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent);
@@ -154,7 +156,9 @@ static int bq257xx_regulator_probe(struct platform_device *pdev)
pdata->desc = bq25703_vbus_desc;
platform_set_drvdata(pdev, pdata);
- bq257xx_reg_dt_parse_gpio(pdev);
+ ret = bq257xx_reg_dt_parse_gpio(pdev);
+ if (ret)
+ return ret;
cfg.dev = &pdev->dev;
cfg.driver_data = pdata;
--
2.56.0.385.gac671c819a-goog
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 08/10] regulator: tps6594-regulator: Fix LDO4 n_voltages in tps6594_ldo_regs
2026-11-04 18:20 [PATCH 00/10] regulator: Fix teardown races, reference counting, and error handling Lee Jones
` (6 preceding siblings ...)
2026-11-04 18:20 ` [PATCH 07/10] regulator: bq257xx: Propagate GPIO error in bq257xx_reg_dt_parse_gpio() Lee Jones
@ 2026-11-04 18:20 ` Lee Jones
2026-11-04 18:20 ` [PATCH 09/10] regulator: max8907: Avoid NULL idata dereference in max8907_regulator_probe() Lee Jones
2026-11-04 18:21 ` [PATCH 10/10] regulator: rt6190: Check pm_runtime_resume_and_get() return value in rt6190_out_enable() Lee Jones
9 siblings, 0 replies; 11+ messages in thread
From: Lee Jones @ 2026-11-04 18:20 UTC (permalink / raw)
To: lee, Liam Girdwood, Mark Brown, Uday Khare, Jerome Neanne,
Mal Nadar, Esteban Blanc, linux-kernel
Cc: stable
Unlike TPS6594_MASK_LDO123_VSET (GENMASK(6, 1)), TPS6594_MASK_LDO4_VSET
is GENMASK(6, 0) (0x7f) and uses an unshifted 7-bit selector field,
with ldos_4_ranges defining valid voltage selectors from 0x20 up to
0x74 (116) in 25mV steps up to 3.3V. In tps6594_ldo_regs, LDO4
erroneously passes TPS6594_MASK_LDO4_VSET >> 1 (63) for n_voltages, so
the regulator core rejects any selector >= 63 and leaves selectors 0x3f
through 0x74 (1.975V to 3.3V) unreachable.
Pass TPS6594_MASK_LDO4_VSET for LDO4 n_voltages to allow the full LDO4
voltage range.
Fixes: f17ccc5deb4d ("regulator: tps6594-regulator: Add driver for TI TPS6594 regulators")
Closes: https://sashiko.dev/#/bug/linux-c680c361-7684-48a1-96f7-0eae5c8477d5
Cc: stable@vger.kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
---
drivers/regulator/tps6594-regulator.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/regulator/tps6594-regulator.c b/drivers/regulator/tps6594-regulator.c
index 503b89a2f5f8..fa4d700252e6 100644
--- a/drivers/regulator/tps6594-regulator.c
+++ b/drivers/regulator/tps6594-regulator.c
@@ -457,7 +457,7 @@ static const struct regulator_desc tps6594_ldo_regs[] = {
TPS6594_BIT_LDO_EN, 0, 0, ldos_1_2_3_ranges,
1, 0, 0, NULL, 0, TPS6594_BIT_LDO_BYPASS),
TPS6594_REGULATOR("LDO4", "ldo4", TPS6594_LDO_4,
- REGULATOR_VOLTAGE, tps6594_ldos_4_ops, TPS6594_MASK_LDO4_VSET >> 1,
+ REGULATOR_VOLTAGE, tps6594_ldos_4_ops, TPS6594_MASK_LDO4_VSET,
TPS6594_REG_LDOX_VOUT(3),
TPS6594_MASK_LDO4_VSET,
TPS6594_REG_LDOX_CTRL(3),
--
2.56.0.385.gac671c819a-goog
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 09/10] regulator: max8907: Avoid NULL idata dereference in max8907_regulator_probe()
2026-11-04 18:20 [PATCH 00/10] regulator: Fix teardown races, reference counting, and error handling Lee Jones
` (7 preceding siblings ...)
2026-11-04 18:20 ` [PATCH 08/10] regulator: tps6594-regulator: Fix LDO4 n_voltages in tps6594_ldo_regs Lee Jones
@ 2026-11-04 18:20 ` Lee Jones
2026-11-04 18:21 ` [PATCH 10/10] regulator: rt6190: Check pm_runtime_resume_and_get() return value in rt6190_out_enable() Lee Jones
9 siblings, 0 replies; 11+ messages in thread
From: Lee Jones @ 2026-11-04 18:20 UTC (permalink / raw)
To: lee, Liam Girdwood, Mark Brown, Gyungoh Yoo, Graeme Gregory,
Eduardo Candelaria, Laxman Dewangan, Stephen Warren,
linux-kernel
Cc: stable
When a board does not provide platform data or a Device Tree node for
BBAT, SDBY, or VRTC, idata is NULL in max8907_regulator_probe(). Unlike
the MAX8907_MBATT case above it, the BBAT/SDBY/VRTC case unconditionally
dereferences idata to assign idata->supply_regulator, causing a NULL
pointer dereference during probe.
Check that idata is non-NULL before dereferencing it.
Fixes: ffee19091a4e ("regulator: add MAX8907 driver")
Fixes: 5fc72f57e62e ("regulator: max8907: fix use of possibly NULL idata")
Closes: https://sashiko.dev/#/bug/linux-372cd4b4-65df-47bd-8b31-5a7b416b2f91
Cc: stable@vger.kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
---
drivers/regulator/max8907-regulator.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/regulator/max8907-regulator.c b/drivers/regulator/max8907-regulator.c
index e59aa7a3ee54..ee7d9b7ef7fc 100644
--- a/drivers/regulator/max8907-regulator.c
+++ b/drivers/regulator/max8907-regulator.c
@@ -331,7 +331,8 @@ static int max8907_regulator_probe(struct platform_device *pdev)
case MAX8907_BBAT:
case MAX8907_SDBY:
case MAX8907_VRTC:
- idata->supply_regulator = mbatt_rail_name;
+ if (idata)
+ idata->supply_regulator = mbatt_rail_name;
break;
}
--
2.56.0.385.gac671c819a-goog
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 10/10] regulator: rt6190: Check pm_runtime_resume_and_get() return value in rt6190_out_enable()
2026-11-04 18:20 [PATCH 00/10] regulator: Fix teardown races, reference counting, and error handling Lee Jones
` (8 preceding siblings ...)
2026-11-04 18:20 ` [PATCH 09/10] regulator: max8907: Avoid NULL idata dereference in max8907_regulator_probe() Lee Jones
@ 2026-11-04 18:21 ` Lee Jones
9 siblings, 0 replies; 11+ messages in thread
From: Lee Jones @ 2026-11-04 18:21 UTC (permalink / raw)
To: lee, Liam Girdwood, Mark Brown, Wentao Liang, ChiYuan Huang,
linux-kernel
Cc: stable
rt6190_out_enable() ignores the return value of pm_runtime_get_sync()
and proceeds with register accesses even if runtime resume fails.
Use pm_runtime_resume_and_get() and return the error code on failure so
the usage counter is not left elevated and registers are not accessed
while the device is suspended.
Fixes: e6999e7cca7e ("regulator: rt6190: Add support for Richtek RT6190 regulator")
Closes: https://sashiko.dev/#/bug/linux-dcfab9b2-550f-4319-87a5-682c3f6cef75
Cc: stable@vger.kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
---
drivers/regulator/rt6190-regulator.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/regulator/rt6190-regulator.c b/drivers/regulator/rt6190-regulator.c
index 21ced348a2cf..973335a9178d 100644
--- a/drivers/regulator/rt6190-regulator.c
+++ b/drivers/regulator/rt6190-regulator.c
@@ -99,7 +99,9 @@ static int rt6190_out_enable(struct regulator_dev *rdev)
u8 out_cfg[4];
int ret;
- pm_runtime_get_sync(data->dev);
+ ret = pm_runtime_resume_and_get(data->dev);
+ if (ret)
+ return ret;
/*
* From off to on, vout config will restore to IC default.
--
2.56.0.385.gac671c819a-goog
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-11-04 18:23 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-04 18:20 [PATCH 00/10] regulator: Fix teardown races, reference counting, and error handling Lee Jones
2026-11-04 18:20 ` [PATCH 01/10] regulator: irq_helpers: Clear caller handle in regulator_irq_helper_cancel() Lee Jones
2026-11-04 18:20 ` [PATCH 02/10] regulator: arizona-ldo1: Avoid double gpiod_put() on enable GPIO Lee Jones
2026-11-04 18:20 ` [PATCH 03/10] regulator: core: Flush delayed disable_work before releasing supply in regulator_unregister() Lee Jones
2026-11-04 18:20 ` [PATCH 04/10] regulator: arizona-micsupp: Cancel check_cp_work on device teardown Lee Jones
2026-11-04 18:20 ` [PATCH 05/10] regulator: core: Hold supply device reference until constraints are resolved in regulator_resolve_supply() Lee Jones
2026-11-04 18:20 ` [PATCH 06/10] regulator: core: Use ktime_get_boottime() in set_machine_constraints() Lee Jones
2026-11-04 18:20 ` [PATCH 07/10] regulator: bq257xx: Propagate GPIO error in bq257xx_reg_dt_parse_gpio() Lee Jones
2026-11-04 18:20 ` [PATCH 08/10] regulator: tps6594-regulator: Fix LDO4 n_voltages in tps6594_ldo_regs Lee Jones
2026-11-04 18:20 ` [PATCH 09/10] regulator: max8907: Avoid NULL idata dereference in max8907_regulator_probe() Lee Jones
2026-11-04 18:21 ` [PATCH 10/10] regulator: rt6190: Check pm_runtime_resume_and_get() return value in rt6190_out_enable() Lee Jones
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®