Skip to content

Commit

Permalink
Merge tag 'regulator-fix-v6.14-rc7' of git://git.kernel.org/pub/scm/l…
Browse files Browse the repository at this point in the history
…inux/kernel/git/broonie/regulator

Pull regulator fixes from Mark Brown:
 "More fixes than I'd like at this point, some of which is due to me
  cooking things in -next for a bit and resetting that cooking time as
  more fixes came in.

   - Christian Eggers fixed some race conditions with the dummy
     regulator not being available very early in boot due to the use of
     asynchronous probing, both the provider side (ensuring that it's
     availalbe) and consumer side (handling things if that goes wrong)
     are fixed

   - Ludvig Pärsson fixed some lockdep issues with the debugfs
     registration for regulators holding more locks than it really needs
     causing issues later when looking at the resulting debugfs.boot

   - Some device specific fixes for incorrect descriptions of the
     RTQ2208 from ChiYuan Huang"

* tag 'regulator-fix-v6.14-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator:
  regulator: rtq2208: Fix the LDO DVS capability
  regulator: rtq2208: Fix incorrect buck converter phase mapping
  regulator: check that dummy regulator has been probed before using it
  regulator: dummy: force synchronous probing
  regulator: core: Fix deadlock in create_regulator()
  • Loading branch information
Linus Torvalds committed Mar 21, 2025
2 parents 3e49db0 + b65439d commit 21d1ccf
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 128 deletions.
88 changes: 54 additions & 34 deletions drivers/regulator/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1830,12 +1830,49 @@ static const struct file_operations constraint_flags_fops = {

#define REG_STR_SIZE 64

static void link_and_create_debugfs(struct regulator *regulator, struct regulator_dev *rdev,
struct device *dev)
{
int err = 0;

if (dev) {
regulator->dev = dev;

/* Add a link to the device sysfs entry */
err = sysfs_create_link_nowarn(&rdev->dev.kobj, &dev->kobj,
regulator->supply_name);
if (err) {
rdev_dbg(rdev, "could not add device link %s: %pe\n",
dev->kobj.name, ERR_PTR(err));
/* non-fatal */
}
}

if (err != -EEXIST) {
regulator->debugfs = debugfs_create_dir(regulator->supply_name, rdev->debugfs);
if (IS_ERR(regulator->debugfs)) {
rdev_dbg(rdev, "Failed to create debugfs directory\n");
regulator->debugfs = NULL;
}
}

if (regulator->debugfs) {
debugfs_create_u32("uA_load", 0444, regulator->debugfs,
&regulator->uA_load);
debugfs_create_u32("min_uV", 0444, regulator->debugfs,
&regulator->voltage[PM_SUSPEND_ON].min_uV);
debugfs_create_u32("max_uV", 0444, regulator->debugfs,
&regulator->voltage[PM_SUSPEND_ON].max_uV);
debugfs_create_file("constraint_flags", 0444, regulator->debugfs,
regulator, &constraint_flags_fops);
}
}

static struct regulator *create_regulator(struct regulator_dev *rdev,
struct device *dev,
const char *supply_name)
{
struct regulator *regulator;
int err = 0;

lockdep_assert_held_once(&rdev->mutex.base);

Expand Down Expand Up @@ -1868,38 +1905,6 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,

list_add(&regulator->list, &rdev->consumer_list);

if (dev) {
regulator->dev = dev;

/* Add a link to the device sysfs entry */
err = sysfs_create_link_nowarn(&rdev->dev.kobj, &dev->kobj,
supply_name);
if (err) {
rdev_dbg(rdev, "could not add device link %s: %pe\n",
dev->kobj.name, ERR_PTR(err));
/* non-fatal */
}
}

if (err != -EEXIST) {
regulator->debugfs = debugfs_create_dir(supply_name, rdev->debugfs);
if (IS_ERR(regulator->debugfs)) {
rdev_dbg(rdev, "Failed to create debugfs directory\n");
regulator->debugfs = NULL;
}
}

if (regulator->debugfs) {
debugfs_create_u32("uA_load", 0444, regulator->debugfs,
&regulator->uA_load);
debugfs_create_u32("min_uV", 0444, regulator->debugfs,
&regulator->voltage[PM_SUSPEND_ON].min_uV);
debugfs_create_u32("max_uV", 0444, regulator->debugfs,
&regulator->voltage[PM_SUSPEND_ON].max_uV);
debugfs_create_file("constraint_flags", 0444, regulator->debugfs,
regulator, &constraint_flags_fops);
}

/*
* Check now if the regulator is an always on regulator - if
* it is then we don't need to do nearly so much work for
Expand Down Expand Up @@ -2069,6 +2074,10 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)

if (have_full_constraints()) {
r = dummy_regulator_rdev;
if (!r) {
ret = -EPROBE_DEFER;
goto out;
}
get_device(&r->dev);
} else {
dev_err(dev, "Failed to resolve %s-supply for %s\n",
Expand All @@ -2086,6 +2095,10 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
goto out;
}
r = dummy_regulator_rdev;
if (!r) {
ret = -EPROBE_DEFER;
goto out;
}
get_device(&r->dev);
}

Expand Down Expand Up @@ -2133,6 +2146,9 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)

regulator_unlock_two(rdev, r, &ww_ctx);

/* rdev->supply was created in set_supply() */
link_and_create_debugfs(rdev->supply, r, &rdev->dev);

/*
* In set_machine_constraints() we may have turned this regulator on
* but we couldn't propagate to the supply if it hadn't been resolved
Expand Down Expand Up @@ -2211,8 +2227,10 @@ struct regulator *_regulator_get_common(struct regulator_dev *rdev, struct devic
* enabled, even if it isn't hooked up, and just
* provide a dummy.
*/
dev_warn(dev, "supply %s not found, using dummy regulator\n", id);
rdev = dummy_regulator_rdev;
if (!rdev)
return ERR_PTR(-EPROBE_DEFER);
dev_warn(dev, "supply %s not found, using dummy regulator\n", id);
get_device(&rdev->dev);
break;

Expand Down Expand Up @@ -2271,6 +2289,8 @@ struct regulator *_regulator_get_common(struct regulator_dev *rdev, struct devic
return regulator;
}

link_and_create_debugfs(regulator, rdev, dev);

rdev->open_count++;
if (get_type == EXCLUSIVE_GET) {
rdev->exclusive = 1;
Expand Down
2 changes: 1 addition & 1 deletion drivers/regulator/dummy.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ static struct platform_driver dummy_regulator_driver = {
.probe = dummy_regulator_probe,
.driver = {
.name = "reg-dummy",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
.probe_type = PROBE_FORCE_SYNCHRONOUS,
},
};

Expand Down
Loading

0 comments on commit 21d1ccf

Please sign in to comment.