/* * core.c -- Voltage/Current Regulator framework. * * Copyright 2007, 2008 Wolfson Microelectronics PLC. * Copyright 2008 SlimLogic Ltd. * * Author: Liam Girdwood <lrg@slimlogic.co.uk> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * */ #include <linux/kernel.h>#include <linux/init.h>#include <linux/debugfs.h>#include <linux/device.h>#include <linux/slab.h>#include <linux/async.h>#include <linux/err.h>#include <linux/mutex.h>#include <linux/suspend.h>#include <linux/delay.h>#include <linux/gpio.h>#include <linux/of.h>#include <linux/regmap.h>#include <linux/regulator/of_regulator.h>#include <linux/regulator/consumer.h>#include <linux/regulator/driver.h>#include <linux/regulator/machine.h>#include <linux/module.h> #define CREATE_TRACE_POINTS#include <trace/events/regulator.h> #include "dummy.h"#include "internal.h" #define rdev_crit(rdev, fmt, ...) \ pr_crit("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)#define rdev_err(rdev, fmt, ...) \ pr_err("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)#define rdev_warn(rdev, fmt, ...) \ pr_warn("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)#define rdev_info(rdev, fmt, ...) \ pr_info("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)#define rdev_dbg(rdev, fmt, ...) \ pr_debug("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__) static DEFINE_MUTEX(regulator_list_mutex);static LIST_HEAD(regulator_list);static LIST_HEAD(regulator_map_list);static LIST_HEAD(regulator_ena_gpio_list);static LIST_HEAD(regulator_supply_alias_list);static bool has_full_constraints; static struct dentry *debugfs_root; /* * struct regulator_map * * Used to provide symbolic supply names to devices. */struct regulator_map { struct list_head list; const char *dev_name; /* The dev_name() for the consumer */ const char *supply; struct regulator_dev *regulator;}; /* * struct regulator_enable_gpio * * Management for shared enable GPIO pin */struct regulator_enable_gpio { struct list_head list; int gpio; u32 enable_count; /* a number of enabled shared GPIO */ u32 request_count; /* a number of requested shared GPIO */ unsigned int ena_gpio_invert:1;}; /* * struct regulator_supply_alias * * Used to map lookups for a supply onto an alternative device. */struct regulator_supply_alias { struct list_head list; struct device *src_dev; const char *src_supply; struct device *alias_dev; const char *alias_supply;}; static int _regulator_is_enabled(struct regulator_dev *rdev);static int _regulator_disable(struct regulator_dev *rdev);static int _regulator_get_voltage(struct regulator_dev *rdev);static int _regulator_get_current_limit(struct regulator_dev *rdev);static unsigned int _regulator_get_mode(struct regulator_dev *rdev);static void _notifier_call_chain(struct regulator_dev *rdev, unsigned long event, void *data);static int _regulator_do_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV);static struct regulator *create_regulator(struct regulator_dev *rdev, struct device *dev, const char *supply_name); static const char *rdev_get_name(struct regulator_dev *rdev){ if (rdev->constraints && rdev->constraints->name) return rdev->constraints->name; else if (rdev->desc->name) return rdev->desc->name; else return "";} static bool have_full_constraints(void){ return has_full_constraints || of_have_populated_dt();} /** * of_get_regulator - get a regulator device node based on supply name * @dev: Device pointer for the consumer (of regulator) device * @supply: regulator supply name * * Extract the regulator device node corresponding to the supply name. * returns the device node corresponding to the regulator if found, else * returns NULL. */static struct device_node *of_get_regulator(struct device *dev, const char *supply){ struct device_node *regnode = NULL; char prop_name[32]; /* 32 is max size of property name */ dev_dbg(dev, "Looking up %s-supply from device tree\n", supply); snprintf(prop_name, 32, "%s-supply", supply); regnode = of_parse_phandle(dev->of_node, prop_name, 0); if (!regnode) { dev_dbg(dev, "Looking up %s property in node %s failed", prop_name, dev->of_node->full_name); return NULL; } return regnode;} static int _regulator_can_change_status(struct regulator_dev *rdev){ if (!rdev->constraints) return 0; if (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_STATUS) return 1; else return 0;} /* Platform voltage constraint check */static int regulator_check_voltage(struct regulator_dev *rdev, int *min_uV, int *max_uV){ BUG_ON(*min_uV > *max_uV); if (!rdev->constraints) { rdev_err(rdev, "no constraints\n"); return -ENODEV; } if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) { rdev_err(rdev, "operation not allowed\n"); return -EPERM; } if (*max_uV > rdev->constraints->max_uV) *max_uV = rdev->constraints->max_uV; if (*min_uV < rdev->constraints->min_uV) *min_uV = rdev->constraints->min_uV; if (*min_uV > *max_uV) { rdev_err(rdev, "unsupportable voltage range: %d-%duV\n", *min_uV, *max_uV); return -EINVAL; } return 0;} /* Make sure we select a voltage that suits the needs of all * regulator consumers */static int regulator_check_consumers(struct regulator_dev *rdev, int *min_uV, int *max_uV){ struct regulator *regulator; list_for_each_entry(regulator, &rdev->consumer_list, list) { /* * Assume consumers that didn't say anything are OK * with anything in the constraint range. */ if (!regulator->min_uV && !regulator->max_uV) continue; if (*max_uV > regulator->max_uV) *max_uV = regulator->max_uV; if (*min_uV < regulator->min_uV) *min_uV = regulator->min_uV; } if (*min_uV > *max_uV) { rdev_err(rdev, "Restricting voltage, %u-%uuV\n", *min_uV, *max_uV); return -EINVAL; } return 0;} /* current constraint check */static int regulator_check_current_limit(struct regulator_dev *rdev, int *min_uA, int *max_uA){ BUG_ON(*min_uA > *max_uA); if (!rdev->constraints) { rdev_err(rdev, "no constraints\n"); return -ENODEV; } if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_CURRENT)) { rdev_err(rdev, "operation not allowed\n"); return -EPERM; } if (*max_uA > rdev->constraints->max_uA) *max_uA = rdev->constraints->max_uA; if (*min_uA < rdev->constraints->min_uA) *min_uA = rdev->constraints->min_uA; if (*min_uA > *max_uA) { rdev_err(rdev, "unsupportable current range: %d-%duA\n", *min_uA, *max_uA); return -EINVAL; } return 0;} /* operating mode constraint check */static int regulator_mode_constrain(struct regulator_dev *rdev, int *mode){ switch (*mode) { case REGULATOR_MODE_FAST: case REGULATOR_MODE_NORMAL: case REGULATOR_MODE_IDLE: case REGULATOR_MODE_STANDBY: break; default: rdev_err(rdev, "invalid mode %x specified\n", *mode); return -EINVAL; } if (!rdev->constraints) { rdev_err(rdev, "no constraints\n"); return -ENODEV; } if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_MODE)) { rdev_err(rdev, "operation not allowed\n"); return -EPERM; } /* The modes are bitmasks, the most power hungry modes having * the lowest values. If the requested mode isn't supported * try higher modes. */ while (*mode) { if (rdev->constraints->valid_modes_mask & *mode) return 0; *mode /= 2; } return -EINVAL;} /* dynamic regulator mode switching constraint check */static int regulator_check_drms(struct regulator_dev *rdev){ if (!rdev->constraints) { rdev_err(rdev, "no constraints\n"); return -ENODEV; } if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS)) { rdev_err(rdev, "operation not allowed\n"); return -EPERM; } return 0;} static ssize_t regulator_uV_show(struct device *dev, struct device_attribute *attr, char *buf){ struct regulator_dev *rdev = dev_get_drvdata(dev); ssize_t ret; mutex_lock(&rdev->mutex); ret = sprintf(buf, "%d\n", _regulator_get_voltage(rdev)); mutex_unlock(&rdev->mutex); return ret;}static DEVICE_ATTR(microvolts, 0444, regulator_uV_show, NULL); static ssize_t regulator_uA_show(struct device *dev, struct device_attribute *attr, char *buf){ struct regulator_dev *rdev = dev_get_drvdata(dev); return sprintf(buf, "%d\n", _regulator_get_current_limit(rdev));}static DEVICE_ATTR(microamps, 0444, regulator_uA_show, NULL); static ssize_t name_show(struct device *dev, struct device_attribute *attr, char *buf){ struct regulator_dev *rdev = dev_get_drvdata(dev); return sprintf(buf, "%s\n", rdev_get_name(rdev));}static DEVICE_ATTR_RO(name); static ssize_t regulator_print_opmode(char *buf, int mode){ switch (mode) { case REGULATOR_MODE_FAST: return sprintf(buf, "fast\n"); case REGULATOR_MODE_NORMAL: return sprintf(buf, "normal\n"); case REGULATOR_MODE_IDLE: return sprintf(buf, "idle\n"); case REGULATOR_MODE_STANDBY: return sprintf(buf, "standby\n"); } return sprintf(buf, "unknown\n");} static ssize_t regulator_opmode_show(struct device *dev, struct device_attribute *attr, char *buf){ struct regulator_dev *rdev = dev_get_drvdata(dev); return regulator_print_opmode(buf, _regulator_get_mode(rdev));}static DEVICE_ATTR(opmode, 0444, regulator_opmode_show, NULL); static ssize_t regulator_print_state(char *buf, int state){ if (state > 0) return sprintf(buf, "enabled\n"); else if (state == 0) return sprintf(buf, "disabled\n"); else return sprintf(buf, "unknown\n");} static ssize_t regulator_state_show(struct device *dev, struct device_attribute *attr, char *buf){ struct regulator_dev *rdev = dev_get_drvdata(dev); ssize_t ret; mutex_lock(&rdev->mutex); ret = regulator_print_state(buf, _regulator_is_enabled(rdev)); mutex_unlock(&rdev->mutex); return ret;}static DEVICE_ATTR(state, 0444, regulator_state_show, NULL); static ssize_t regulator_status_show(struct device *dev, struct device_attribute *attr, char *buf){ struct regulator_dev *rdev = dev_get_drvdata(dev); int status; char *label; status = rdev->desc->ops->get_status(rdev); if (status < 0) return status; switch (status) { case REGULATOR_STATUS_OFF: label = "off"; break; case REGULATOR_STATUS_ON: label = "on"; break; case REGULATOR_STATUS_ERROR: label = "error"; break; case REGULATOR_STATUS_FAST: label = "fast"; break; case REGULATOR_STATUS_NORMAL: label = "normal"; break; case REGULATOR_STATUS_IDLE: label = "idle"; break; case REGULATOR_STATUS_STANDBY: label = "standby"; break; case REGULATOR_STATUS_BYPASS: label = "bypass"; break; case REGULATOR_STATUS_UNDEFINED: label = "undefined"; break; default: return -ERANGE; } return sprintf(buf, "%s\n", label);}static DEVICE_ATTR(status, 0444, regulator_status_show, NULL); static ssize_t regulator_min_uA_show(struct device *dev, struct device_attribute *attr, char *buf){ struct regulator_dev *rdev = dev_get_drvdata(dev); if (!rdev->constraints) return sprintf(buf, "constraint not defined\n"); return sprintf(buf, "%d\n", rdev->constraints->min_uA);}static DEVICE_ATTR(min_microamps, 0444, regulator_min_uA_show, NULL); static ssize_t regulator_max_uA_show(struct device *dev, struct device_attribute *attr, char *buf){ struct regulator_dev *rdev = dev_get_drvdata(dev); if (!rdev->constraints) return sprintf(buf, "constraint not defined\n"); return sprintf(buf, "%d\n", rdev->constraints->max_uA);}static DEVICE_ATTR(max_microamps, 0444, regulator_max_uA_show, NULL); static ssize_t regulator_min_uV_show(struct device *dev, struct device_attribute *attr, char *buf){ struct regulator_dev *rdev = dev_get_drvdata(dev); if (!rdev->constraints) return sprintf(buf, "constraint not defined\n"); return sprintf(buf, "%d\n", rdev->constraints->min_uV);}static DEVICE_ATTR(min_microvolts, 0444, regulator_min_uV_show, NULL); static ssize_t regulator_max_uV_show(struct device *dev, struct device_attribute *attr, char *buf){ struct regulator_dev *rdev = dev_get_drvdata(dev); if (!rdev->constraints) return sprintf(buf, "constraint not defined\n"); return sprintf(buf, "%d\n", rdev->constraints->max_uV);}static DEVICE_ATTR(max_microvolts, 0444, regulator_max_uV_show, NULL); static ssize_t regulator_total_uA_show(struct device *dev, struct device_attribute *attr, char *buf){ struct regulator_dev *rdev = dev_get_drvdata(dev); struct regulator *regulator; int uA = 0; mutex_lock(&rdev->mutex); list_for_each_entry(regulator, &rdev->consumer_list, list) uA += regulator->uA_load; mutex_unlock(&rdev->mutex); return sprintf(buf, "%d\n", uA);}static DEVICE_ATTR(requested_microamps, 0444, regulator_total_uA_show, NULL); static ssize_t num_users_show(struct device *dev, struct device_attribute *attr, char *buf){ struct regulator_dev *rdev = dev_get_drvdata(dev); return sprintf(buf, "%d\n", rdev->use_count);}static DEVICE_ATTR_RO(num_users); Lines 1–500 of 3858. Load more
/* * core.c -- Voltage/Current Regulator framework. * * Copyright 2007, 2008 Wolfson Microelectronics PLC. * Copyright 2008 SlimLogic Ltd. * * Author: Liam Girdwood <lrg@slimlogic.co.uk> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * */ #include <linux/kernel.h> #include <linux/init.h> #include <linux/debugfs.h> #include <linux/device.h> #include <linux/slab.h> #include <linux/async.h> #include <linux/err.h> #include <linux/mutex.h> #include <linux/suspend.h> #include <linux/delay.h> #include <linux/gpio.h> #include <linux/of.h> #include <linux/regmap.h> #include <linux/regulator/of_regulator.h> #include <linux/regulator/consumer.h> #include <linux/regulator/driver.h> #include <linux/regulator/machine.h> #include <linux/module.h> #define CREATE_TRACE_POINTS #include <trace/events/regulator.h> #include "dummy.h" #include "internal.h" #define rdev_crit(rdev, fmt, ...) \ pr_crit("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__) #define rdev_err(rdev, fmt, ...) \ pr_err("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__) #define rdev_warn(rdev, fmt, ...) \ pr_warn("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__) #define rdev_info(rdev, fmt, ...) \ pr_info("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__) #define rdev_dbg(rdev, fmt, ...) \ pr_debug("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__) static DEFINE_MUTEX(regulator_list_mutex); static LIST_HEAD(regulator_list); static LIST_HEAD(regulator_map_list); static LIST_HEAD(regulator_ena_gpio_list); static LIST_HEAD(regulator_supply_alias_list); static bool has_full_constraints; static struct dentry *debugfs_root; /* * struct regulator_map * * Used to provide symbolic supply names to devices. */ struct regulator_map { struct list_head list; const char *dev_name; /* The dev_name() for the consumer */ const char *supply; struct regulator_dev *regulator; }; /* * struct regulator_enable_gpio * * Management for shared enable GPIO pin */ struct regulator_enable_gpio { struct list_head list; int gpio; u32 enable_count; /* a number of enabled shared GPIO */ u32 request_count; /* a number of requested shared GPIO */ unsigned int ena_gpio_invert:1; }; /* * struct regulator_supply_alias * * Used to map lookups for a supply onto an alternative device. */ struct regulator_supply_alias { struct list_head list; struct device *src_dev; const char *src_supply; struct device *alias_dev; const char *alias_supply; }; static int _regulator_is_enabled(struct regulator_dev *rdev); static int _regulator_disable(struct regulator_dev *rdev); static int _regulator_get_voltage(struct regulator_dev *rdev); static int _regulator_get_current_limit(struct regulator_dev *rdev); static unsigned int _regulator_get_mode(struct regulator_dev *rdev); static void _notifier_call_chain(struct regulator_dev *rdev, unsigned long event, void *data); static int _regulator_do_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV); static struct regulator *create_regulator(struct regulator_dev *rdev, struct device *dev, const char *supply_name); static const char *rdev_get_name(struct regulator_dev *rdev) { if (rdev->constraints && rdev->constraints->name) return rdev->constraints->name; else if (rdev->desc->name) return rdev->desc->name; else return ""; } static bool have_full_constraints(void) { return has_full_constraints || of_have_populated_dt(); } /** * of_get_regulator - get a regulator device node based on supply name * @dev: Device pointer for the consumer (of regulator) device * @supply: regulator supply name * * Extract the regulator device node corresponding to the supply name. * returns the device node corresponding to the regulator if found, else * returns NULL. */ static struct device_node *of_get_regulator(struct device *dev, const char *supply) { struct device_node *regnode = NULL; char prop_name[32]; /* 32 is max size of property name */ dev_dbg(dev, "Looking up %s-supply from device tree\n", supply); snprintf(prop_name, 32, "%s-supply", supply); regnode = of_parse_phandle(dev->of_node, prop_name, 0); if (!regnode) { dev_dbg(dev, "Looking up %s property in node %s failed", prop_name, dev->of_node->full_name); return NULL; } return regnode; } static int _regulator_can_change_status(struct regulator_dev *rdev) { if (!rdev->constraints) return 0; if (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_STATUS) return 1; else return 0; } /* Platform voltage constraint check */ static int regulator_check_voltage(struct regulator_dev *rdev, int *min_uV, int *max_uV) { BUG_ON(*min_uV > *max_uV); if (!rdev->constraints) { rdev_err(rdev, "no constraints\n"); return -ENODEV; } if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) { rdev_err(rdev, "operation not allowed\n"); return -EPERM; } if (*max_uV > rdev->constraints->max_uV) *max_uV = rdev->constraints->max_uV; if (*min_uV < rdev->constraints->min_uV) *min_uV = rdev->constraints->min_uV; if (*min_uV > *max_uV) { rdev_err(rdev, "unsupportable voltage range: %d-%duV\n", *min_uV, *max_uV); return -EINVAL; } return 0; } /* Make sure we select a voltage that suits the needs of all * regulator consumers */ static int regulator_check_consumers(struct regulator_dev *rdev, int *min_uV, int *max_uV) { struct regulator *regulator; list_for_each_entry(regulator, &rdev->consumer_list, list) { /* * Assume consumers that didn't say anything are OK * with anything in the constraint range. */ if (!regulator->min_uV && !regulator->max_uV) continue; if (*max_uV > regulator->max_uV) *max_uV = regulator->max_uV; if (*min_uV < regulator->min_uV) *min_uV = regulator->min_uV; } if (*min_uV > *max_uV) { rdev_err(rdev, "Restricting voltage, %u-%uuV\n", *min_uV, *max_uV); return -EINVAL; } return 0; } /* current constraint check */ static int regulator_check_current_limit(struct regulator_dev *rdev, int *min_uA, int *max_uA) { BUG_ON(*min_uA > *max_uA); if (!rdev->constraints) { rdev_err(rdev, "no constraints\n"); return -ENODEV; } if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_CURRENT)) { rdev_err(rdev, "operation not allowed\n"); return -EPERM; } if (*max_uA > rdev->constraints->max_uA) *max_uA = rdev->constraints->max_uA; if (*min_uA < rdev->constraints->min_uA) *min_uA = rdev->constraints->min_uA; if (*min_uA > *max_uA) { rdev_err(rdev, "unsupportable current range: %d-%duA\n", *min_uA, *max_uA); return -EINVAL; } return 0; } /* operating mode constraint check */ static int regulator_mode_constrain(struct regulator_dev *rdev, int *mode) { switch (*mode) { case REGULATOR_MODE_FAST: case REGULATOR_MODE_NORMAL: case REGULATOR_MODE_IDLE: case REGULATOR_MODE_STANDBY: break; default: rdev_err(rdev, "invalid mode %x specified\n", *mode); return -EINVAL; } if (!rdev->constraints) { rdev_err(rdev, "no constraints\n"); return -ENODEV; } if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_MODE)) { rdev_err(rdev, "operation not allowed\n"); return -EPERM; } /* The modes are bitmasks, the most power hungry modes having * the lowest values. If the requested mode isn't supported * try higher modes. */ while (*mode) { if (rdev->constraints->valid_modes_mask & *mode) return 0; *mode /= 2; } return -EINVAL; } /* dynamic regulator mode switching constraint check */ static int regulator_check_drms(struct regulator_dev *rdev) { if (!rdev->constraints) { rdev_err(rdev, "no constraints\n"); return -ENODEV; } if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS)) { rdev_err(rdev, "operation not allowed\n"); return -EPERM; } return 0; } static ssize_t regulator_uV_show(struct device *dev, struct device_attribute *attr, char *buf) { struct regulator_dev *rdev = dev_get_drvdata(dev); ssize_t ret; mutex_lock(&rdev->mutex); ret = sprintf(buf, "%d\n", _regulator_get_voltage(rdev)); mutex_unlock(&rdev->mutex); return ret; } static DEVICE_ATTR(microvolts, 0444, regulator_uV_show, NULL); static ssize_t regulator_uA_show(struct device *dev, struct device_attribute *attr, char *buf) { struct regulator_dev *rdev = dev_get_drvdata(dev); return sprintf(buf, "%d\n", _regulator_get_current_limit(rdev)); } static DEVICE_ATTR(microamps, 0444, regulator_uA_show, NULL); static ssize_t name_show(struct device *dev, struct device_attribute *attr, char *buf) { struct regulator_dev *rdev = dev_get_drvdata(dev); return sprintf(buf, "%s\n", rdev_get_name(rdev)); } static DEVICE_ATTR_RO(name); static ssize_t regulator_print_opmode(char *buf, int mode) { switch (mode) { case REGULATOR_MODE_FAST: return sprintf(buf, "fast\n"); case REGULATOR_MODE_NORMAL: return sprintf(buf, "normal\n"); case REGULATOR_MODE_IDLE: return sprintf(buf, "idle\n"); case REGULATOR_MODE_STANDBY: return sprintf(buf, "standby\n"); } return sprintf(buf, "unknown\n"); } static ssize_t regulator_opmode_show(struct device *dev, struct device_attribute *attr, char *buf) { struct regulator_dev *rdev = dev_get_drvdata(dev); return regulator_print_opmode(buf, _regulator_get_mode(rdev)); } static DEVICE_ATTR(opmode, 0444, regulator_opmode_show, NULL); static ssize_t regulator_print_state(char *buf, int state) { if (state > 0) return sprintf(buf, "enabled\n"); else if (state == 0) return sprintf(buf, "disabled\n"); else return sprintf(buf, "unknown\n"); } static ssize_t regulator_state_show(struct device *dev, struct device_attribute *attr, char *buf) { struct regulator_dev *rdev = dev_get_drvdata(dev); ssize_t ret; mutex_lock(&rdev->mutex); ret = regulator_print_state(buf, _regulator_is_enabled(rdev)); mutex_unlock(&rdev->mutex); return ret; } static DEVICE_ATTR(state, 0444, regulator_state_show, NULL); static ssize_t regulator_status_show(struct device *dev, struct device_attribute *attr, char *buf) { struct regulator_dev *rdev = dev_get_drvdata(dev); int status; char *label; status = rdev->desc->ops->get_status(rdev); if (status < 0) return status; switch (status) { case REGULATOR_STATUS_OFF: label = "off"; break; case REGULATOR_STATUS_ON: label = "on"; break; case REGULATOR_STATUS_ERROR: label = "error"; break; case REGULATOR_STATUS_FAST: label = "fast"; break; case REGULATOR_STATUS_NORMAL: label = "normal"; break; case REGULATOR_STATUS_IDLE: label = "idle"; break; case REGULATOR_STATUS_STANDBY: label = "standby"; break; case REGULATOR_STATUS_BYPASS: label = "bypass"; break; case REGULATOR_STATUS_UNDEFINED: label = "undefined"; break; default: return -ERANGE; } return sprintf(buf, "%s\n", label); } static DEVICE_ATTR(status, 0444, regulator_status_show, NULL); static ssize_t regulator_min_uA_show(struct device *dev, struct device_attribute *attr, char *buf) { struct regulator_dev *rdev = dev_get_drvdata(dev); if (!rdev->constraints) return sprintf(buf, "constraint not defined\n"); return sprintf(buf, "%d\n", rdev->constraints->min_uA); } static DEVICE_ATTR(min_microamps, 0444, regulator_min_uA_show, NULL); static ssize_t regulator_max_uA_show(struct device *dev, struct device_attribute *attr, char *buf) { struct regulator_dev *rdev = dev_get_drvdata(dev); if (!rdev->constraints) return sprintf(buf, "constraint not defined\n"); return sprintf(buf, "%d\n", rdev->constraints->max_uA); } static DEVICE_ATTR(max_microamps, 0444, regulator_max_uA_show, NULL); static ssize_t regulator_min_uV_show(struct device *dev, struct device_attribute *attr, char *buf) { struct regulator_dev *rdev = dev_get_drvdata(dev); if (!rdev->constraints) return sprintf(buf, "constraint not defined\n"); return sprintf(buf, "%d\n", rdev->constraints->min_uV); } static DEVICE_ATTR(min_microvolts, 0444, regulator_min_uV_show, NULL); static ssize_t regulator_max_uV_show(struct device *dev, struct device_attribute *attr, char *buf) { struct regulator_dev *rdev = dev_get_drvdata(dev); if (!rdev->constraints) return sprintf(buf, "constraint not defined\n"); return sprintf(buf, "%d\n", rdev->constraints->max_uV); } static DEVICE_ATTR(max_microvolts, 0444, regulator_max_uV_show, NULL); static ssize_t regulator_total_uA_show(struct device *dev, struct device_attribute *attr, char *buf) { struct regulator_dev *rdev = dev_get_drvdata(dev); struct regulator *regulator; int uA = 0; mutex_lock(&rdev->mutex); list_for_each_entry(regulator, &rdev->consumer_list, list) uA += regulator->uA_load; mutex_unlock(&rdev->mutex); return sprintf(buf, "%d\n", uA); } static DEVICE_ATTR(requested_microamps, 0444, regulator_total_uA_show, NULL); static ssize_t num_users_show(struct device *dev, struct device_attribute *attr, char *buf) { struct regulator_dev *rdev = dev_get_drvdata(dev); return sprintf(buf, "%d\n", rdev->use_count); } static DEVICE_ATTR_RO(num_users);