diff options
| -rw-r--r-- | drivers/regulator/core.c | 120 |
1 files changed, 119 insertions, 1 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index a291a6b9cd44..cd0ca0768eed 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
| @@ -3556,7 +3556,18 @@ static struct class regulator_class = { | |||
| 3556 | 3556 | ||
| 3557 | static void rdev_init_debugfs(struct regulator_dev *rdev) | 3557 | static void rdev_init_debugfs(struct regulator_dev *rdev) |
| 3558 | { | 3558 | { |
| 3559 | rdev->debugfs = debugfs_create_dir(rdev_get_name(rdev), debugfs_root); | 3559 | struct device *parent = rdev->dev.parent; |
| 3560 | const char *rname = rdev_get_name(rdev); | ||
| 3561 | char name[NAME_MAX]; | ||
| 3562 | |||
| 3563 | /* Avoid duplicate debugfs directory names */ | ||
| 3564 | if (parent && rname == rdev->desc->name) { | ||
| 3565 | snprintf(name, sizeof(name), "%s-%s", dev_name(parent), | ||
| 3566 | rname); | ||
| 3567 | rname = name; | ||
| 3568 | } | ||
| 3569 | |||
| 3570 | rdev->debugfs = debugfs_create_dir(rname, debugfs_root); | ||
| 3560 | if (!rdev->debugfs) { | 3571 | if (!rdev->debugfs) { |
| 3561 | rdev_warn(rdev, "Failed to create debugfs directory\n"); | 3572 | rdev_warn(rdev, "Failed to create debugfs directory\n"); |
| 3562 | return; | 3573 | return; |
| @@ -3963,6 +3974,110 @@ static const struct file_operations supply_map_fops = { | |||
| 3963 | #endif | 3974 | #endif |
| 3964 | }; | 3975 | }; |
| 3965 | 3976 | ||
| 3977 | #ifdef CONFIG_DEBUG_FS | ||
| 3978 | static void regulator_summary_show_subtree(struct seq_file *s, | ||
| 3979 | struct regulator_dev *rdev, | ||
| 3980 | int level) | ||
| 3981 | { | ||
| 3982 | struct list_head *list = s->private; | ||
| 3983 | struct regulator_dev *child; | ||
| 3984 | struct regulation_constraints *c; | ||
| 3985 | struct regulator *consumer; | ||
| 3986 | |||
| 3987 | if (!rdev) | ||
| 3988 | return; | ||
| 3989 | |||
| 3990 | seq_printf(s, "%*s%-*s %3d %4d %6d ", | ||
| 3991 | level * 3 + 1, "", | ||
| 3992 | 30 - level * 3, rdev_get_name(rdev), | ||
| 3993 | rdev->use_count, rdev->open_count, rdev->bypass_count); | ||
| 3994 | |||
| 3995 | seq_printf(s, "%5dmV ", _regulator_get_voltage(rdev) / 1000); | ||
| 3996 | seq_printf(s, "%5dmA ", _regulator_get_current_limit(rdev) / 1000); | ||
| 3997 | |||
| 3998 | c = rdev->constraints; | ||
| 3999 | if (c) { | ||
| 4000 | switch (rdev->desc->type) { | ||
| 4001 | case REGULATOR_VOLTAGE: | ||
| 4002 | seq_printf(s, "%5dmV %5dmV ", | ||
| 4003 | c->min_uV / 1000, c->max_uV / 1000); | ||
| 4004 | break; | ||
| 4005 | case REGULATOR_CURRENT: | ||
| 4006 | seq_printf(s, "%5dmA %5dmA ", | ||
| 4007 | c->min_uA / 1000, c->max_uA / 1000); | ||
| 4008 | break; | ||
| 4009 | } | ||
| 4010 | } | ||
| 4011 | |||
| 4012 | seq_puts(s, "\n"); | ||
| 4013 | |||
| 4014 | list_for_each_entry(consumer, &rdev->consumer_list, list) { | ||
| 4015 | if (consumer->dev->class == ®ulator_class) | ||
| 4016 | continue; | ||
| 4017 | |||
| 4018 | seq_printf(s, "%*s%-*s ", | ||
| 4019 | (level + 1) * 3 + 1, "", | ||
| 4020 | 30 - (level + 1) * 3, dev_name(consumer->dev)); | ||
| 4021 | |||
| 4022 | switch (rdev->desc->type) { | ||
| 4023 | case REGULATOR_VOLTAGE: | ||
| 4024 | seq_printf(s, "%37dmV %5dmV", | ||
| 4025 | consumer->min_uV / 1000, | ||
| 4026 | consumer->max_uV / 1000); | ||
| 4027 | break; | ||
| 4028 | case REGULATOR_CURRENT: | ||
| 4029 | break; | ||
| 4030 | } | ||
| 4031 | |||
| 4032 | seq_puts(s, "\n"); | ||
| 4033 | } | ||
| 4034 | |||
| 4035 | list_for_each_entry(child, list, list) { | ||
| 4036 | /* handle only non-root regulators supplied by current rdev */ | ||
| 4037 | if (!child->supply || child->supply->rdev != rdev) | ||
| 4038 | continue; | ||
| 4039 | |||
| 4040 | regulator_summary_show_subtree(s, child, level + 1); | ||
| 4041 | } | ||
| 4042 | } | ||
| 4043 | |||
| 4044 | static int regulator_summary_show(struct seq_file *s, void *data) | ||
| 4045 | { | ||
| 4046 | struct list_head *list = s->private; | ||
| 4047 | struct regulator_dev *rdev; | ||
| 4048 | |||
| 4049 | seq_puts(s, " regulator use open bypass voltage current min max\n"); | ||
| 4050 | seq_puts(s, "-------------------------------------------------------------------------------\n"); | ||
| 4051 | |||
| 4052 | mutex_lock(®ulator_list_mutex); | ||
| 4053 | |||
| 4054 | list_for_each_entry(rdev, list, list) { | ||
| 4055 | if (rdev->supply) | ||
| 4056 | continue; | ||
| 4057 | |||
| 4058 | regulator_summary_show_subtree(s, rdev, 0); | ||
| 4059 | } | ||
| 4060 | |||
| 4061 | mutex_unlock(®ulator_list_mutex); | ||
| 4062 | |||
| 4063 | return 0; | ||
| 4064 | } | ||
| 4065 | |||
| 4066 | static int regulator_summary_open(struct inode *inode, struct file *file) | ||
| 4067 | { | ||
| 4068 | return single_open(file, regulator_summary_show, inode->i_private); | ||
| 4069 | } | ||
| 4070 | #endif | ||
| 4071 | |||
| 4072 | static const struct file_operations regulator_summary_fops = { | ||
| 4073 | #ifdef CONFIG_DEBUG_FS | ||
| 4074 | .open = regulator_summary_open, | ||
| 4075 | .read = seq_read, | ||
| 4076 | .llseek = seq_lseek, | ||
| 4077 | .release = single_release, | ||
| 4078 | #endif | ||
| 4079 | }; | ||
| 4080 | |||
| 3966 | static int __init regulator_init(void) | 4081 | static int __init regulator_init(void) |
| 3967 | { | 4082 | { |
| 3968 | int ret; | 4083 | int ret; |
| @@ -3976,6 +4091,9 @@ static int __init regulator_init(void) | |||
| 3976 | debugfs_create_file("supply_map", 0444, debugfs_root, NULL, | 4091 | debugfs_create_file("supply_map", 0444, debugfs_root, NULL, |
| 3977 | &supply_map_fops); | 4092 | &supply_map_fops); |
| 3978 | 4093 | ||
| 4094 | debugfs_create_file("regulator_summary", 0444, debugfs_root, | ||
| 4095 | ®ulator_list, ®ulator_summary_fops); | ||
| 4096 | |||
| 3979 | regulator_dummy_init(); | 4097 | regulator_dummy_init(); |
| 3980 | 4098 | ||
| 3981 | return ret; | 4099 | return ret; |
