diff options
author | Zev Weiss <zev@bewilderbeest.net> | 2022-05-03 23:52:49 -0700 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2022-05-04 15:31:26 +0100 |
commit | 0f2d636e7d1fd76f704dd3ea5089ce29a8aee049 (patch) | |
tree | 61ed8b2cf833d1a131d0002bd93d250677541982 /drivers/regulator/core.c | |
parent | 20078e3bbe6e5adb1a88f03f9609d532d99c690c (diff) |
regulator: core: Add error flags to sysfs attributes
If a regulator provides a get_error_flags() operation, its sysfs
attributes will now include an entry for each defined
REGULATOR_ERROR_* flag.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Link: https://lore.kernel.org/r/20220504065252.6955-3-zev@bewilderbeest.net
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/regulator/core.c')
-rw-r--r-- | drivers/regulator/core.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index ce3786e966c3..d790f7b648b1 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -83,6 +83,7 @@ struct regulator_supply_alias { static int _regulator_is_enabled(struct regulator_dev *rdev); static int _regulator_disable(struct regulator *regulator); +static int _regulator_get_error_flags(struct regulator_dev *rdev, unsigned int *flags); static int _regulator_get_current_limit(struct regulator_dev *rdev); static unsigned int _regulator_get_mode(struct regulator_dev *rdev); static int _notifier_call_chain(struct regulator_dev *rdev, @@ -911,6 +912,30 @@ static ssize_t bypass_show(struct device *dev, } static DEVICE_ATTR_RO(bypass); +#define REGULATOR_ERROR_ATTR(name, bit) \ + static ssize_t name##_show(struct device *dev, struct device_attribute *attr, \ + char *buf) \ + { \ + int ret; \ + unsigned int flags; \ + struct regulator_dev *rdev = dev_get_drvdata(dev); \ + ret = _regulator_get_error_flags(rdev, &flags); \ + if (ret) \ + return ret; \ + return sysfs_emit(buf, "%d\n", !!(flags & (bit))); \ + } \ + static DEVICE_ATTR_RO(name) + +REGULATOR_ERROR_ATTR(under_voltage, REGULATOR_ERROR_UNDER_VOLTAGE); +REGULATOR_ERROR_ATTR(over_current, REGULATOR_ERROR_OVER_CURRENT); +REGULATOR_ERROR_ATTR(regulation_out, REGULATOR_ERROR_REGULATION_OUT); +REGULATOR_ERROR_ATTR(fail, REGULATOR_ERROR_FAIL); +REGULATOR_ERROR_ATTR(over_temp, REGULATOR_ERROR_OVER_TEMP); +REGULATOR_ERROR_ATTR(under_voltage_warn, REGULATOR_ERROR_UNDER_VOLTAGE_WARN); +REGULATOR_ERROR_ATTR(over_current_warn, REGULATOR_ERROR_OVER_CURRENT_WARN); +REGULATOR_ERROR_ATTR(over_voltage_warn, REGULATOR_ERROR_OVER_VOLTAGE_WARN); +REGULATOR_ERROR_ATTR(over_temp_warn, REGULATOR_ERROR_OVER_TEMP_WARN); + /* Calculate the new optimum regulator operating mode based on the new total * consumer load. All locks held by caller */ @@ -4984,6 +5009,15 @@ static struct attribute *regulator_dev_attrs[] = { &dev_attr_max_microvolts.attr, &dev_attr_min_microamps.attr, &dev_attr_max_microamps.attr, + &dev_attr_under_voltage.attr, + &dev_attr_over_current.attr, + &dev_attr_regulation_out.attr, + &dev_attr_fail.attr, + &dev_attr_over_temp.attr, + &dev_attr_under_voltage_warn.attr, + &dev_attr_over_current_warn.attr, + &dev_attr_over_voltage_warn.attr, + &dev_attr_over_temp_warn.attr, &dev_attr_suspend_standby_state.attr, &dev_attr_suspend_mem_state.attr, &dev_attr_suspend_disk_state.attr, @@ -5039,6 +5073,17 @@ static umode_t regulator_attr_is_visible(struct kobject *kobj, if (attr == &dev_attr_bypass.attr) return ops->get_bypass ? mode : 0; + if (attr == &dev_attr_under_voltage.attr || + attr == &dev_attr_over_current.attr || + attr == &dev_attr_regulation_out.attr || + attr == &dev_attr_fail.attr || + attr == &dev_attr_over_temp.attr || + attr == &dev_attr_under_voltage_warn.attr || + attr == &dev_attr_over_current_warn.attr || + attr == &dev_attr_over_voltage_warn.attr || + attr == &dev_attr_over_temp_warn.attr) + return ops->get_error_flags ? mode : 0; + /* constraints need specific supporting methods */ if (attr == &dev_attr_min_microvolts.attr || attr == &dev_attr_max_microvolts.attr) |