Commit fd8b327e authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/lrg/voltage-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/lrg/voltage-2.6: (41 commits)
  regulator: Add some brief design documentation
  regulator: fix voltage range in da9034 ldo12
  regulator/driver: be more specific in nanodoc for is_enabled
  regulator/lp3971: drop unnecessary initialization
  regulator: drop 'default n'
  regulator: fix typos
  regulator: fix calculation of voltage range in da9034_set_ldo12_voltage()
  regulator: update a filename in documentation
  drivers/regulator/Kconfig: fix typo (s/Usersapce/Userspace/) in REGULATOR_USERSPACE_CONSUMER description
  REGULATOR Handle positive returncode from enable
  regulator: tps650xx - build fixes for x86_64
  Fix some regulator documentation
  Regulator: Adding TPS65023 and TPS6507x in Kconfig and Makefile
  Regulator: Add TPS6507x regulator driver
  Regulator: Add TPS65023 regulator driver
  regulator: userspace: use sysfs_create_group
  regulator: Add GPIO enable control to fixed voltage regulator driver
  Regulator: Implement list_voltage for pcf50633 regulator driver.
  regulator: regulator_enable() permission checking
  regulator: Push locking for regulator_is_enabled() out
  ...
parents 0c9af280 63209a71
Regulator API design notes
==========================
This document provides a brief, partially structured, overview of some
of the design considerations which impact the regulator API design.
Safety
------
- Errors in regulator configuration can have very serious consequences
for the system, potentially including lasting hardware damage.
- It is not possible to automatically determine the power confugration
of the system - software-equivalent variants of the same chip may
have different power requirments, and not all components with power
requirements are visible to software.
=> The API should make no changes to the hardware state unless it has
specific knowledge that these changes are safe to do perform on
this particular system.
Consumer use cases
------------------
- The overwhelming majority of devices in a system will have no
requirement to do any runtime configuration of their power beyond
being able to turn it on or off.
- Many of the power supplies in the system will be shared between many
different consumers.
=> The consumer API should be structured so that these use cases are
very easy to handle and so that consumers will work with shared
supplies without any additional effort.
......@@ -87,7 +87,7 @@ static struct platform_device regulator_devices[] = {
},
};
/* register regulator 1 device */
platform_device_register(&wm8350_regulator_devices[0]);
platform_device_register(&regulator_devices[0]);
/* register regulator 2 device */
platform_device_register(&wm8350_regulator_devices[1]);
platform_device_register(&regulator_devices[1]);
......@@ -29,7 +29,7 @@ Some terms used in this document:-
o PMIC - Power Management IC. An IC that contains numerous regulators
and often contains other susbsystems.
and often contains other subsystems.
o Consumer - Electronic device that is supplied power by a regulator.
......@@ -168,4 +168,4 @@ relevant to non SoC devices and is split into the following four interfaces:-
userspace via sysfs. This could be used to help monitor device power
consumption and status.
See Documentation/ABI/testing/regulator-sysfs.txt
See Documentation/ABI/testing/sysfs-class-regulator
......@@ -10,8 +10,9 @@ Registration
Drivers can register a regulator by calling :-
struct regulator_dev *regulator_register(struct device *dev,
struct regulator_desc *regulator_desc);
struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
struct device *dev, struct regulator_init_data *init_data,
void *driver_data);
This will register the regulators capabilities and operations to the regulator
core.
......
menuconfig REGULATOR
bool "Voltage and Current Regulator Support"
default n
help
Generic Voltage and Current Regulator support.
......@@ -30,7 +29,6 @@ config REGULATOR_DEBUG
config REGULATOR_FIXED_VOLTAGE
tristate "Fixed voltage regulator support"
default n
help
This driver provides support for fixed voltage regulators,
useful for systems which use a combination of software
......@@ -38,7 +36,6 @@ config REGULATOR_FIXED_VOLTAGE
config REGULATOR_VIRTUAL_CONSUMER
tristate "Virtual regulator consumer support"
default n
help
This driver provides a virtual consumer for the voltage and
current regulator API which provides sysfs controls for
......@@ -49,17 +46,15 @@ config REGULATOR_VIRTUAL_CONSUMER
config REGULATOR_USERSPACE_CONSUMER
tristate "Userspace regulator consumer support"
default n
help
There are some classes of devices that are controlled entirely
from user space. Usersapce consumer driver provides ability to
from user space. Userspace consumer driver provides ability to
control power supplies for such devices.
If unsure, say no.
config REGULATOR_BQ24022
tristate "TI bq24022 Dual Input 1-Cell Li-Ion Charger IC"
default n
help
This driver controls a TI bq24022 Charger attached via
GPIOs. The provided current regulator can enable/disable
......@@ -69,7 +64,6 @@ config REGULATOR_BQ24022
config REGULATOR_MAX1586
tristate "Maxim 1586/1587 voltage regulator"
depends on I2C
default n
help
This driver controls a Maxim 1586 or 1587 voltage output
regulator via I2C bus. The provided regulator is suitable
......@@ -147,5 +141,21 @@ config REGULATOR_AB3100
AB3100 analog baseband dealing with power regulators
for the system.
config REGULATOR_TPS65023
tristate "TI TPS65023 Power regulators"
depends on I2C
help
This driver supports TPS65023 voltage regulator chips. TPS65023 provides
three step-down converters and two general-purpose LDO voltage regulators.
It supports TI's software based Class-2 SmartReflex implementation.
config REGULATOR_TPS6507X
tristate "TI TPS6507X Power regulators"
depends on I2C
help
This driver supports TPS6507X voltage regulator chips. TPS6507X provides
three step-down converters and two general-purpose LDO voltage regulators.
It supports TI's software based Class-2 SmartReflex implementation.
endif
......@@ -23,4 +23,7 @@ obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o
obj-$(CONFIG_REGULATOR_MC13783) += mc13783.o
obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o
obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o
obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o
ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
......@@ -37,7 +37,7 @@ static int has_full_constraints;
*/
struct regulator_map {
struct list_head list;
struct device *dev;
const char *dev_name; /* The dev_name() for the consumer */
const char *supply;
struct regulator_dev *regulator;
};
......@@ -232,7 +232,7 @@ static ssize_t regulator_name_show(struct device *dev,
struct regulator_dev *rdev = dev_get_drvdata(dev);
const char *name;
if (rdev->constraints->name)
if (rdev->constraints && rdev->constraints->name)
name = rdev->constraints->name;
else if (rdev->desc->name)
name = rdev->desc->name;
......@@ -280,8 +280,13 @@ 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 regulator_print_state(buf, _regulator_is_enabled(rdev));
return ret;
}
static DEVICE_ATTR(state, 0444, regulator_state_show, NULL);
......@@ -857,23 +862,39 @@ out:
* set_consumer_device_supply: Bind a regulator to a symbolic supply
* @rdev: regulator source
* @consumer_dev: device the supply applies to
* @consumer_dev_name: dev_name() string for device supply applies to
* @supply: symbolic name for supply
*
* Allows platform initialisation code to map physical regulator
* sources to symbolic names for supplies for use by devices. Devices
* should use these symbolic names to request regulators, avoiding the
* need to provide board-specific regulator names as platform data.
*
* Only one of consumer_dev and consumer_dev_name may be specified.
*/
static int set_consumer_device_supply(struct regulator_dev *rdev,
struct device *consumer_dev, const char *supply)
struct device *consumer_dev, const char *consumer_dev_name,
const char *supply)
{
struct regulator_map *node;
int has_dev;
if (consumer_dev && consumer_dev_name)
return -EINVAL;
if (!consumer_dev_name && consumer_dev)
consumer_dev_name = dev_name(consumer_dev);
if (supply == NULL)
return -EINVAL;
if (consumer_dev_name != NULL)
has_dev = 1;
else
has_dev = 0;
list_for_each_entry(node, &regulator_map_list, list) {
if (consumer_dev != node->dev)
if (consumer_dev_name != node->dev_name)
continue;
if (strcmp(node->supply, supply) != 0)
continue;
......@@ -886,30 +907,45 @@ static int set_consumer_device_supply(struct regulator_dev *rdev,
return -EBUSY;
}
node = kmalloc(sizeof(struct regulator_map), GFP_KERNEL);
node = kzalloc(sizeof(struct regulator_map), GFP_KERNEL);
if (node == NULL)
return -ENOMEM;
node->regulator = rdev;
node->dev = consumer_dev;
node->supply = supply;
if (has_dev) {
node->dev_name = kstrdup(consumer_dev_name, GFP_KERNEL);
if (node->dev_name == NULL) {
kfree(node);
return -ENOMEM;
}
}
list_add(&node->list, &regulator_map_list);
return 0;
}
static void unset_consumer_device_supply(struct regulator_dev *rdev,
struct device *consumer_dev)
const char *consumer_dev_name, struct device *consumer_dev)
{
struct regulator_map *node, *n;
if (consumer_dev && !consumer_dev_name)
consumer_dev_name = dev_name(consumer_dev);
list_for_each_entry_safe(node, n, &regulator_map_list, list) {
if (rdev == node->regulator &&
consumer_dev == node->dev) {
list_del(&node->list);
kfree(node);
return;
}
if (rdev != node->regulator)
continue;
if (consumer_dev_name && node->dev_name &&
strcmp(consumer_dev_name, node->dev_name))
continue;
list_del(&node->list);
kfree(node->dev_name);
kfree(node);
return;
}
}
......@@ -920,6 +956,7 @@ static void unset_regulator_supplies(struct regulator_dev *rdev)
list_for_each_entry_safe(node, n, &regulator_map_list, list) {
if (rdev == node->regulator) {
list_del(&node->list);
kfree(node->dev_name);
kfree(node);
return;
}
......@@ -1001,35 +1038,33 @@ overflow_err:
return NULL;
}
/**
* regulator_get - lookup and obtain a reference to a regulator.
* @dev: device for regulator "consumer"
* @id: Supply name or regulator ID.
*
* Returns a struct regulator corresponding to the regulator producer,
* or IS_ERR() condition containing errno.
*
* Use of supply names configured via regulator_set_device_supply() is
* strongly encouraged. It is recommended that the supply name used
* should match the name used for the supply and/or the relevant
* device pins in the datasheet.
*/
struct regulator *regulator_get(struct device *dev, const char *id)
/* Internal regulator request function */
static struct regulator *_regulator_get(struct device *dev, const char *id,
int exclusive)
{
struct regulator_dev *rdev;
struct regulator_map *map;
struct regulator *regulator = ERR_PTR(-ENODEV);
const char *devname = NULL;
int ret;
if (id == NULL) {
printk(KERN_ERR "regulator: get() with no identifier\n");
return regulator;
}
if (dev)
devname = dev_name(dev);
mutex_lock(&regulator_list_mutex);
list_for_each_entry(map, &regulator_map_list, list) {
if (dev == map->dev &&
strcmp(map->supply, id) == 0) {
/* If the mapping has a device set up it must match */
if (map->dev_name &&
(!devname || strcmp(map->dev_name, devname)))
continue;
if (strcmp(map->supply, id) == 0) {
rdev = map->regulator;
goto found;
}
......@@ -1038,6 +1073,16 @@ struct regulator *regulator_get(struct device *dev, const char *id)
return regulator;
found:
if (rdev->exclusive) {
regulator = ERR_PTR(-EPERM);
goto out;
}
if (exclusive && rdev->open_count) {
regulator = ERR_PTR(-EBUSY);
goto out;
}
if (!try_module_get(rdev->owner))
goto out;
......@@ -1047,12 +1092,69 @@ found:
module_put(rdev->owner);
}
rdev->open_count++;
if (exclusive) {
rdev->exclusive = 1;
ret = _regulator_is_enabled(rdev);
if (ret > 0)
rdev->use_count = 1;
else
rdev->use_count = 0;
}
out:
mutex_unlock(&regulator_list_mutex);
return regulator;
}
/**
* regulator_get - lookup and obtain a reference to a regulator.
* @dev: device for regulator "consumer"
* @id: Supply name or regulator ID.
*
* Returns a struct regulator corresponding to the regulator producer,
* or IS_ERR() condition containing errno.
*
* Use of supply names configured via regulator_set_device_supply() is
* strongly encouraged. It is recommended that the supply name used
* should match the name used for the supply and/or the relevant
* device pins in the datasheet.
*/
struct regulator *regulator_get(struct device *dev, const char *id)
{
return _regulator_get(dev, id, 0);
}
EXPORT_SYMBOL_GPL(regulator_get);
/**
* regulator_get_exclusive - obtain exclusive access to a regulator.
* @dev: device for regulator "consumer"
* @id: Supply name or regulator ID.
*
* Returns a struct regulator corresponding to the regulator producer,
* or IS_ERR() condition containing errno. Other consumers will be
* unable to obtain this reference is held and the use count for the
* regulator will be initialised to reflect the current state of the
* regulator.
*
* This is intended for use by consumers which cannot tolerate shared
* use of the regulator such as those which need to force the
* regulator off for correct operation of the hardware they are
* controlling.
*
* Use of supply names configured via regulator_set_device_supply() is
* strongly encouraged. It is recommended that the supply name used
* should match the name used for the supply and/or the relevant
* device pins in the datasheet.
*/
struct regulator *regulator_get_exclusive(struct device *dev, const char *id)
{
return _regulator_get(dev, id, 1);
}
EXPORT_SYMBOL_GPL(regulator_get_exclusive);
/**
* regulator_put - "free" the regulator source
* @regulator: regulator source
......@@ -1081,21 +1183,29 @@ void regulator_put(struct regulator *regulator)
list_del(&regulator->list);
kfree(regulator);
rdev->open_count--;
rdev->exclusive = 0;
module_put(rdev->owner);
mutex_unlock(&regulator_list_mutex);
}
EXPORT_SYMBOL_GPL(regulator_put);
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;
}
/* locks held by regulator_enable() */
static int _regulator_enable(struct regulator_dev *rdev)
{
int ret = -EINVAL;
if (!rdev->constraints) {
printk(KERN_ERR "%s: %s has no constraints\n",
__func__, rdev->desc->name);
return ret;
}
int ret;
/* do we need to enable the supply regulator first */
if (rdev->supply) {
......@@ -1108,24 +1218,35 @@ static int _regulator_enable(struct regulator_dev *rdev)
}
/* check voltage and requested load before enabling */
if (rdev->desc->ops->enable) {
if (rdev->constraints &&
(rdev->constraints->valid_ops_mask &
REGULATOR_CHANGE_DRMS))
drms_uA_update(rdev);
ret = rdev->desc->ops->enable(rdev);
if (ret < 0) {
printk(KERN_ERR "%s: failed to enable %s: %d\n",
if (rdev->constraints &&
(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS))
drms_uA_update(rdev);
if (rdev->use_count == 0) {
/* The regulator may on if it's not switchable or left on */
ret = _regulator_is_enabled(rdev);
if (ret == -EINVAL || ret == 0) {
if (!_regulator_can_change_status(rdev))
return -EPERM;
if (rdev->desc->ops->enable) {
ret = rdev->desc->ops->enable(rdev);
if (ret < 0)
return ret;
} else {
return -EINVAL;
}
} else if (ret < 0) {
printk(KERN_ERR "%s: is_enabled() failed for %s: %d\n",
__func__, rdev->desc->name, ret);
return ret;
}
rdev->use_count++;
return ret;
/* Fallthrough on positive return values - already enabled */
}
return ret;
rdev->use_count++;
return 0;
}
/**
......@@ -1165,7 +1286,8 @@ static int _regulator_disable(struct regulator_dev *rdev)
if (rdev->use_count == 1 && !rdev->constraints->always_on) {
/* we are last user */
if (rdev->desc->ops->disable) {
if (_regulator_can_change_status(rdev) &&
rdev->desc->ops->disable) {
ret = rdev->desc->ops->disable(rdev);
if (ret < 0) {
printk(KERN_ERR "%s: failed to disable %s\n",
......@@ -1265,20 +1387,11 @@ EXPORT_SYMBOL_GPL(regulator_force_disable);
static int _regulator_is_enabled(struct regulator_dev *rdev)
{
int ret;
mutex_lock(&rdev->mutex);
/* sanity check */
if (!rdev->desc->ops->is_enabled) {
ret = -EINVAL;
goto out;
}
if (!rdev->desc->ops->is_enabled)
return -EINVAL;
ret = rdev->desc->ops->is_enabled(rdev);
out:
mutex_unlock(&rdev->mutex);
return ret;
return rdev->desc->ops->is_enabled(rdev);
}
/**
......@@ -1295,7 +1408,13 @@ out:
*/
int regulator_is_enabled(struct regulator *regulator)
{
return _regulator_is_enabled(regulator->rdev);
int ret;
mutex_lock(&regulator->rdev->mutex);
ret = _regulator_is_enabled(regulator->rdev);
mutex_unlock(&regulator->rdev->mutex);
return ret;
}
EXPORT_SYMBOL_GPL(regulator_is_enabled);
......@@ -1349,6 +1468,35 @@ int regulator_list_voltage(struct regulator *regulator, unsigned selector)
}
EXPORT_SYMBOL_GPL(regulator_list_voltage);
/**
* regulator_is_supported_voltage - check if a voltage range can be supported
*
* @regulator: Regulator to check.
* @min_uV: Minimum required voltage in uV.
* @max_uV: Maximum required voltage in uV.
*
* Returns a boolean or a negative error code.
*/
int regulator_is_supported_voltage(struct regulator *regulator,
int min_uV, int max_uV)
{
int i, voltages, ret;
ret = regulator_count_voltages(regulator);
if (ret < 0)
return ret;
voltages = ret;
for (i = 0; i < voltages; i++) {
ret = regulator_list_voltage(regulator, i);
if (ret >= min_uV && ret <= max_uV)
return 1;
}
return 0;
}
/**
* regulator_set_voltage - set regulator output voltage
* @regulator: regulator source
......@@ -2091,11 +2239,13 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
for (i = 0; i < init_data->num_consumer_supplies; i++) {
ret = set_consumer_device_supply(rdev,
init_data->consumer_supplies[i].dev,
init_data->consumer_supplies[i].dev_name,
init_data->consumer_supplies[i].supply);
if (ret < 0) {
for (--i; i >= 0; i--)
unset_consumer_device_supply(rdev,
init_data->consumer_supplies[i].dev);
init_data->consumer_supplies[i].dev_name,
init_data->consumer_supplies[i].dev);
goto scrub;
}
}
......@@ -2130,6 +2280,7 @@ void regulator_unregister(struct regulator_dev *rdev)
return;
mutex_lock(&regulator_list_mutex);
WARN_ON(rdev->open_count);
unset_regulator_supplies(rdev);
list_del(&rdev->list);
if (rdev->supply)
......@@ -2277,14 +2428,14 @@ static int __init regulator_init_complete(void)
ops = rdev->desc->ops;
c = rdev->constraints;
if (c->name)
if (c && c->name)
name = c->name;
else if (rdev->desc->name)
name = rdev->desc->name;
else
name = "regulator";
if (!ops->disable || c->always_on)
if (!ops->disable || (c && c->always_on))
continue;
mutex_lock(&rdev->mutex);
......
......@@ -64,6 +64,14 @@
#define DA9034_MDTV2 (0x33)
#define DA9034_MVRC (0x34)