* [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