Loading drivers/regulator/core.c +175 −37 Original line number Diff line number Diff line Loading @@ -1316,6 +1316,54 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev, return NULL; } static int regulator_resolve_supply(struct regulator_dev *rdev) { struct regulator_dev *r; struct device *dev = rdev->dev.parent; int ret; /* No supply to resovle? */ if (!rdev->supply_name) return 0; /* Supply already resolved? */ if (rdev->supply) return 0; r = regulator_dev_lookup(dev, rdev->supply_name, &ret); if (ret == -ENODEV) { /* * No supply was specified for this regulator and * there will never be one. */ return 0; } if (!r) { dev_err(dev, "Failed to resolve %s-supply for %s\n", rdev->supply_name, rdev->desc->name); return -EPROBE_DEFER; } /* Recursively resolve the supply of the supply */ ret = regulator_resolve_supply(r); if (ret < 0) return ret; ret = set_supply(rdev, r); if (ret < 0) return ret; /* Cascade always-on state to supply */ if (_regulator_is_enabled(rdev)) { ret = regulator_enable(rdev->supply); if (ret < 0) return ret; } return 0; } /* Internal regulator request function */ static struct regulator *_regulator_get(struct device *dev, const char *id, bool exclusive, bool allow_dummy) Loading Loading @@ -1385,6 +1433,12 @@ found: goto out; } ret = regulator_resolve_supply(rdev); if (ret < 0) { regulator = ERR_PTR(ret); goto out; } if (!try_module_get(rdev->owner)) goto out; Loading Loading @@ -3499,7 +3553,18 @@ static struct class regulator_class = { static void rdev_init_debugfs(struct regulator_dev *rdev) { rdev->debugfs = debugfs_create_dir(rdev_get_name(rdev), debugfs_root); struct device *parent = rdev->dev.parent; const char *rname = rdev_get_name(rdev); char name[NAME_MAX]; /* Avoid duplicate debugfs directory names */ if (parent && rname == rdev->desc->name) { snprintf(name, sizeof(name), "%s-%s", dev_name(parent), rname); rname = name; } rdev->debugfs = debugfs_create_dir(rname, debugfs_root); if (!rdev->debugfs) { rdev_warn(rdev, "Failed to create debugfs directory\n"); return; Loading Loading @@ -3533,7 +3598,6 @@ regulator_register(const struct regulator_desc *regulator_desc, struct regulator_dev *rdev; struct device *dev; int ret, i; const char *supply = NULL; if (regulator_desc == NULL || cfg == NULL) return ERR_PTR(-EINVAL); Loading Loading @@ -3641,41 +3705,10 @@ regulator_register(const struct regulator_desc *regulator_desc, goto scrub; if (init_data && init_data->supply_regulator) supply = init_data->supply_regulator; rdev->supply_name = init_data->supply_regulator; else if (regulator_desc->supply_name) supply = regulator_desc->supply_name; if (supply) { struct regulator_dev *r; r = regulator_dev_lookup(dev, supply, &ret); if (ret == -ENODEV) { /* * No supply was specified for this regulator and * there will never be one. */ ret = 0; goto add_dev; } else if (!r) { dev_err(dev, "Failed to find supply %s\n", supply); ret = -EPROBE_DEFER; goto scrub; } ret = set_supply(rdev, r); if (ret < 0) goto scrub; /* Enable supply if rail is enabled */ if (_regulator_is_enabled(rdev)) { ret = regulator_enable(rdev->supply); if (ret < 0) goto scrub; } } rdev->supply_name = regulator_desc->supply_name; add_dev: /* add consumers devices */ if (init_data) { for (i = 0; i < init_data->num_consumer_supplies; i++) { Loading @@ -3702,8 +3735,6 @@ unset_supplies: unset_regulator_supplies(rdev); scrub: if (rdev->supply) _regulator_put(rdev->supply); regulator_ena_gpio_free(rdev); kfree(rdev->constraints); wash: Loading Loading @@ -3936,6 +3967,110 @@ static const struct file_operations supply_map_fops = { #endif }; #ifdef CONFIG_DEBUG_FS static void regulator_summary_show_subtree(struct seq_file *s, struct regulator_dev *rdev, int level) { struct list_head *list = s->private; struct regulator_dev *child; struct regulation_constraints *c; struct regulator *consumer; if (!rdev) return; seq_printf(s, "%*s%-*s %3d %4d %6d ", level * 3 + 1, "", 30 - level * 3, rdev_get_name(rdev), rdev->use_count, rdev->open_count, rdev->bypass_count); seq_printf(s, "%5dmV ", _regulator_get_voltage(rdev) / 1000); seq_printf(s, "%5dmA ", _regulator_get_current_limit(rdev) / 1000); c = rdev->constraints; if (c) { switch (rdev->desc->type) { case REGULATOR_VOLTAGE: seq_printf(s, "%5dmV %5dmV ", c->min_uV / 1000, c->max_uV / 1000); break; case REGULATOR_CURRENT: seq_printf(s, "%5dmA %5dmA ", c->min_uA / 1000, c->max_uA / 1000); break; } } seq_puts(s, "\n"); list_for_each_entry(consumer, &rdev->consumer_list, list) { if (consumer->dev->class == ®ulator_class) continue; seq_printf(s, "%*s%-*s ", (level + 1) * 3 + 1, "", 30 - (level + 1) * 3, dev_name(consumer->dev)); switch (rdev->desc->type) { case REGULATOR_VOLTAGE: seq_printf(s, "%37dmV %5dmV", consumer->min_uV / 1000, consumer->max_uV / 1000); break; case REGULATOR_CURRENT: break; } seq_puts(s, "\n"); } list_for_each_entry(child, list, list) { /* handle only non-root regulators supplied by current rdev */ if (!child->supply || child->supply->rdev != rdev) continue; regulator_summary_show_subtree(s, child, level + 1); } } static int regulator_summary_show(struct seq_file *s, void *data) { struct list_head *list = s->private; struct regulator_dev *rdev; seq_puts(s, " regulator use open bypass voltage current min max\n"); seq_puts(s, "-------------------------------------------------------------------------------\n"); mutex_lock(®ulator_list_mutex); list_for_each_entry(rdev, list, list) { if (rdev->supply) continue; regulator_summary_show_subtree(s, rdev, 0); } mutex_unlock(®ulator_list_mutex); return 0; } static int regulator_summary_open(struct inode *inode, struct file *file) { return single_open(file, regulator_summary_show, inode->i_private); } #endif static const struct file_operations regulator_summary_fops = { #ifdef CONFIG_DEBUG_FS .open = regulator_summary_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, #endif }; static int __init regulator_init(void) { int ret; Loading @@ -3949,6 +4084,9 @@ static int __init regulator_init(void) debugfs_create_file("supply_map", 0444, debugfs_root, NULL, &supply_map_fops); debugfs_create_file("regulator_summary", 0444, debugfs_root, ®ulator_list, ®ulator_summary_fops); regulator_dummy_init(); return ret; Loading include/linux/regulator/driver.h +1 −0 Original line number Diff line number Diff line Loading @@ -367,6 +367,7 @@ struct regulator_dev { struct device dev; struct regulation_constraints *constraints; struct regulator *supply; /* for tree */ const char *supply_name; struct regmap *regmap; struct delayed_work disable_work; Loading include/linux/regulator/consumer.h +1 −1 File changed.Contains only whitespace changes. Show changes Loading
drivers/regulator/core.c +175 −37 Original line number Diff line number Diff line Loading @@ -1316,6 +1316,54 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev, return NULL; } static int regulator_resolve_supply(struct regulator_dev *rdev) { struct regulator_dev *r; struct device *dev = rdev->dev.parent; int ret; /* No supply to resovle? */ if (!rdev->supply_name) return 0; /* Supply already resolved? */ if (rdev->supply) return 0; r = regulator_dev_lookup(dev, rdev->supply_name, &ret); if (ret == -ENODEV) { /* * No supply was specified for this regulator and * there will never be one. */ return 0; } if (!r) { dev_err(dev, "Failed to resolve %s-supply for %s\n", rdev->supply_name, rdev->desc->name); return -EPROBE_DEFER; } /* Recursively resolve the supply of the supply */ ret = regulator_resolve_supply(r); if (ret < 0) return ret; ret = set_supply(rdev, r); if (ret < 0) return ret; /* Cascade always-on state to supply */ if (_regulator_is_enabled(rdev)) { ret = regulator_enable(rdev->supply); if (ret < 0) return ret; } return 0; } /* Internal regulator request function */ static struct regulator *_regulator_get(struct device *dev, const char *id, bool exclusive, bool allow_dummy) Loading Loading @@ -1385,6 +1433,12 @@ found: goto out; } ret = regulator_resolve_supply(rdev); if (ret < 0) { regulator = ERR_PTR(ret); goto out; } if (!try_module_get(rdev->owner)) goto out; Loading Loading @@ -3499,7 +3553,18 @@ static struct class regulator_class = { static void rdev_init_debugfs(struct regulator_dev *rdev) { rdev->debugfs = debugfs_create_dir(rdev_get_name(rdev), debugfs_root); struct device *parent = rdev->dev.parent; const char *rname = rdev_get_name(rdev); char name[NAME_MAX]; /* Avoid duplicate debugfs directory names */ if (parent && rname == rdev->desc->name) { snprintf(name, sizeof(name), "%s-%s", dev_name(parent), rname); rname = name; } rdev->debugfs = debugfs_create_dir(rname, debugfs_root); if (!rdev->debugfs) { rdev_warn(rdev, "Failed to create debugfs directory\n"); return; Loading Loading @@ -3533,7 +3598,6 @@ regulator_register(const struct regulator_desc *regulator_desc, struct regulator_dev *rdev; struct device *dev; int ret, i; const char *supply = NULL; if (regulator_desc == NULL || cfg == NULL) return ERR_PTR(-EINVAL); Loading Loading @@ -3641,41 +3705,10 @@ regulator_register(const struct regulator_desc *regulator_desc, goto scrub; if (init_data && init_data->supply_regulator) supply = init_data->supply_regulator; rdev->supply_name = init_data->supply_regulator; else if (regulator_desc->supply_name) supply = regulator_desc->supply_name; if (supply) { struct regulator_dev *r; r = regulator_dev_lookup(dev, supply, &ret); if (ret == -ENODEV) { /* * No supply was specified for this regulator and * there will never be one. */ ret = 0; goto add_dev; } else if (!r) { dev_err(dev, "Failed to find supply %s\n", supply); ret = -EPROBE_DEFER; goto scrub; } ret = set_supply(rdev, r); if (ret < 0) goto scrub; /* Enable supply if rail is enabled */ if (_regulator_is_enabled(rdev)) { ret = regulator_enable(rdev->supply); if (ret < 0) goto scrub; } } rdev->supply_name = regulator_desc->supply_name; add_dev: /* add consumers devices */ if (init_data) { for (i = 0; i < init_data->num_consumer_supplies; i++) { Loading @@ -3702,8 +3735,6 @@ unset_supplies: unset_regulator_supplies(rdev); scrub: if (rdev->supply) _regulator_put(rdev->supply); regulator_ena_gpio_free(rdev); kfree(rdev->constraints); wash: Loading Loading @@ -3936,6 +3967,110 @@ static const struct file_operations supply_map_fops = { #endif }; #ifdef CONFIG_DEBUG_FS static void regulator_summary_show_subtree(struct seq_file *s, struct regulator_dev *rdev, int level) { struct list_head *list = s->private; struct regulator_dev *child; struct regulation_constraints *c; struct regulator *consumer; if (!rdev) return; seq_printf(s, "%*s%-*s %3d %4d %6d ", level * 3 + 1, "", 30 - level * 3, rdev_get_name(rdev), rdev->use_count, rdev->open_count, rdev->bypass_count); seq_printf(s, "%5dmV ", _regulator_get_voltage(rdev) / 1000); seq_printf(s, "%5dmA ", _regulator_get_current_limit(rdev) / 1000); c = rdev->constraints; if (c) { switch (rdev->desc->type) { case REGULATOR_VOLTAGE: seq_printf(s, "%5dmV %5dmV ", c->min_uV / 1000, c->max_uV / 1000); break; case REGULATOR_CURRENT: seq_printf(s, "%5dmA %5dmA ", c->min_uA / 1000, c->max_uA / 1000); break; } } seq_puts(s, "\n"); list_for_each_entry(consumer, &rdev->consumer_list, list) { if (consumer->dev->class == ®ulator_class) continue; seq_printf(s, "%*s%-*s ", (level + 1) * 3 + 1, "", 30 - (level + 1) * 3, dev_name(consumer->dev)); switch (rdev->desc->type) { case REGULATOR_VOLTAGE: seq_printf(s, "%37dmV %5dmV", consumer->min_uV / 1000, consumer->max_uV / 1000); break; case REGULATOR_CURRENT: break; } seq_puts(s, "\n"); } list_for_each_entry(child, list, list) { /* handle only non-root regulators supplied by current rdev */ if (!child->supply || child->supply->rdev != rdev) continue; regulator_summary_show_subtree(s, child, level + 1); } } static int regulator_summary_show(struct seq_file *s, void *data) { struct list_head *list = s->private; struct regulator_dev *rdev; seq_puts(s, " regulator use open bypass voltage current min max\n"); seq_puts(s, "-------------------------------------------------------------------------------\n"); mutex_lock(®ulator_list_mutex); list_for_each_entry(rdev, list, list) { if (rdev->supply) continue; regulator_summary_show_subtree(s, rdev, 0); } mutex_unlock(®ulator_list_mutex); return 0; } static int regulator_summary_open(struct inode *inode, struct file *file) { return single_open(file, regulator_summary_show, inode->i_private); } #endif static const struct file_operations regulator_summary_fops = { #ifdef CONFIG_DEBUG_FS .open = regulator_summary_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, #endif }; static int __init regulator_init(void) { int ret; Loading @@ -3949,6 +4084,9 @@ static int __init regulator_init(void) debugfs_create_file("supply_map", 0444, debugfs_root, NULL, &supply_map_fops); debugfs_create_file("regulator_summary", 0444, debugfs_root, ®ulator_list, ®ulator_summary_fops); regulator_dummy_init(); return ret; Loading
include/linux/regulator/driver.h +1 −0 Original line number Diff line number Diff line Loading @@ -367,6 +367,7 @@ struct regulator_dev { struct device dev; struct regulation_constraints *constraints; struct regulator *supply; /* for tree */ const char *supply_name; struct regmap *regmap; struct delayed_work disable_work; Loading