Commit cfe22345 authored by Linus Torvalds's avatar Linus Torvalds

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: (23 commits)
  regulator: Improve WM831x DVS VSEL selection algorithm
  regulator: Bootstrap wm831x DVS VSEL value from ON VSEL if not already set
  regulator: Set up GPIO for WM831x VSEL before enabling VSEL mode
  regulator: Add EPEs to the MODULE_ALIAS() for wm831x-dcdc
  regulator: Fix WM831x DCDC DVS VSEL bootstrapping
  regulator: Fix WM831x regulator ID lookups for multiple WM831xs
  regulator: Fix argument format type errors in error prints
  regulator: Fix memory leak in set_machine_constraints() error paths
  regulator: Make core more chatty about some errors
  regulator: tps65910: Fix array access out of bounds bug
  regulator: tps65910: Add missing breaks in switch/case
  regulator: tps65910: Fix a memory leak in tps65910_probe error path
  regulator: TWL: Remove entry of RES_ID for 6030 macros
  ASoC: tlv320aic3x: Add correct hw registers to Line1 cross connect muxes
  regulator: Add basic per consumer debugfs
  regulator: Add rdev_crit() macro
  regulator: Refactor supply implementation to work as regular consumers
  regulator: Include the device name in the microamps_requested_ file
  regulator: Increase the limit on sysfs file names
  regulator: Properly register dummy regulator driver
  ...
parents 60ad4466 424c3d4a
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/async.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/suspend.h> #include <linux/suspend.h>
...@@ -33,6 +34,8 @@ ...@@ -33,6 +34,8 @@
#include "dummy.h" #include "dummy.h"
#define rdev_crit(rdev, fmt, ...) \
pr_crit("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
#define rdev_err(rdev, fmt, ...) \ #define rdev_err(rdev, fmt, ...) \
pr_err("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__) pr_err("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
#define rdev_warn(rdev, fmt, ...) \ #define rdev_warn(rdev, fmt, ...) \
...@@ -78,11 +81,13 @@ struct regulator { ...@@ -78,11 +81,13 @@ struct regulator {
char *supply_name; char *supply_name;
struct device_attribute dev_attr; struct device_attribute dev_attr;
struct regulator_dev *rdev; struct regulator_dev *rdev;
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs;
#endif
}; };
static int _regulator_is_enabled(struct regulator_dev *rdev); static int _regulator_is_enabled(struct regulator_dev *rdev);
static int _regulator_disable(struct regulator_dev *rdev, static int _regulator_disable(struct regulator_dev *rdev);
struct regulator_dev **supply_rdev_ptr);
static int _regulator_get_voltage(struct regulator_dev *rdev); static int _regulator_get_voltage(struct regulator_dev *rdev);
static int _regulator_get_current_limit(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 unsigned int _regulator_get_mode(struct regulator_dev *rdev);
...@@ -90,6 +95,9 @@ static void _notifier_call_chain(struct regulator_dev *rdev, ...@@ -90,6 +95,9 @@ static void _notifier_call_chain(struct regulator_dev *rdev,
unsigned long event, void *data); unsigned long event, void *data);
static int _regulator_do_set_voltage(struct regulator_dev *rdev, static int _regulator_do_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV); 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) static const char *rdev_get_name(struct regulator_dev *rdev)
{ {
...@@ -143,8 +151,11 @@ static int regulator_check_voltage(struct regulator_dev *rdev, ...@@ -143,8 +151,11 @@ static int regulator_check_voltage(struct regulator_dev *rdev,
if (*min_uV < rdev->constraints->min_uV) if (*min_uV < rdev->constraints->min_uV)
*min_uV = rdev->constraints->min_uV; *min_uV = rdev->constraints->min_uV;
if (*min_uV > *max_uV) if (*min_uV > *max_uV) {
rdev_err(rdev, "unsupportable voltage range: %d-%duV\n",
*min_uV, *max_uV);
return -EINVAL; return -EINVAL;
}
return 0; return 0;
} }
...@@ -197,8 +208,11 @@ static int regulator_check_current_limit(struct regulator_dev *rdev, ...@@ -197,8 +208,11 @@ static int regulator_check_current_limit(struct regulator_dev *rdev,
if (*min_uA < rdev->constraints->min_uA) if (*min_uA < rdev->constraints->min_uA)
*min_uA = rdev->constraints->min_uA; *min_uA = rdev->constraints->min_uA;
if (*min_uA > *max_uA) if (*min_uA > *max_uA) {
rdev_err(rdev, "unsupportable current range: %d-%duA\n",
*min_uA, *max_uA);
return -EINVAL; return -EINVAL;
}
return 0; return 0;
} }
...@@ -213,6 +227,7 @@ static int regulator_mode_constrain(struct regulator_dev *rdev, int *mode) ...@@ -213,6 +227,7 @@ static int regulator_mode_constrain(struct regulator_dev *rdev, int *mode)
case REGULATOR_MODE_STANDBY: case REGULATOR_MODE_STANDBY:
break; break;
default: default:
rdev_err(rdev, "invalid mode %x specified\n", *mode);
return -EINVAL; return -EINVAL;
} }
...@@ -779,7 +794,6 @@ static int machine_constraints_voltage(struct regulator_dev *rdev, ...@@ -779,7 +794,6 @@ static int machine_constraints_voltage(struct regulator_dev *rdev,
if (ret < 0) { if (ret < 0) {
rdev_err(rdev, "failed to apply %duV constraint\n", rdev_err(rdev, "failed to apply %duV constraint\n",
rdev->constraints->min_uV); rdev->constraints->min_uV);
rdev->constraints = NULL;
return ret; return ret;
} }
} }
...@@ -882,7 +896,6 @@ static int set_machine_constraints(struct regulator_dev *rdev, ...@@ -882,7 +896,6 @@ static int set_machine_constraints(struct regulator_dev *rdev,
ret = suspend_prepare(rdev, rdev->constraints->initial_state); ret = suspend_prepare(rdev, rdev->constraints->initial_state);
if (ret < 0) { if (ret < 0) {
rdev_err(rdev, "failed to set suspend state\n"); rdev_err(rdev, "failed to set suspend state\n");
rdev->constraints = NULL;
goto out; goto out;
} }
} }
...@@ -909,13 +922,15 @@ static int set_machine_constraints(struct regulator_dev *rdev, ...@@ -909,13 +922,15 @@ static int set_machine_constraints(struct regulator_dev *rdev,
ret = ops->enable(rdev); ret = ops->enable(rdev);
if (ret < 0) { if (ret < 0) {
rdev_err(rdev, "failed to enable\n"); rdev_err(rdev, "failed to enable\n");
rdev->constraints = NULL;
goto out; goto out;
} }
} }
print_constraints(rdev); print_constraints(rdev);
return 0;
out: out:
kfree(rdev->constraints);
rdev->constraints = NULL;
return ret; return ret;
} }
...@@ -933,17 +948,16 @@ static int set_supply(struct regulator_dev *rdev, ...@@ -933,17 +948,16 @@ static int set_supply(struct regulator_dev *rdev,
{ {
int err; int err;
err = sysfs_create_link(&rdev->dev.kobj, &supply_rdev->dev.kobj, rdev_info(rdev, "supplied by %s\n", rdev_get_name(supply_rdev));
"supply");
if (err) { rdev->supply = create_regulator(supply_rdev, &rdev->dev, "SUPPLY");
rdev_err(rdev, "could not add device link %s err %d\n", if (IS_ERR(rdev->supply)) {
supply_rdev->dev.kobj.name, err); err = PTR_ERR(rdev->supply);
goto out; rdev->supply = NULL;
}
rdev->supply = supply_rdev;
list_add(&rdev->slist, &supply_rdev->supply_list);
out:
return err; return err;
}
return 0;
} }
/** /**
...@@ -1032,7 +1046,7 @@ static void unset_regulator_supplies(struct regulator_dev *rdev) ...@@ -1032,7 +1046,7 @@ static void unset_regulator_supplies(struct regulator_dev *rdev)
} }
} }
#define REG_STR_SIZE 32 #define REG_STR_SIZE 64
static struct regulator *create_regulator(struct regulator_dev *rdev, static struct regulator *create_regulator(struct regulator_dev *rdev,
struct device *dev, struct device *dev,
...@@ -1052,8 +1066,9 @@ static struct regulator *create_regulator(struct regulator_dev *rdev, ...@@ -1052,8 +1066,9 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
if (dev) { if (dev) {
/* create a 'requested_microamps_name' sysfs entry */ /* create a 'requested_microamps_name' sysfs entry */
size = scnprintf(buf, REG_STR_SIZE, "microamps_requested_%s", size = scnprintf(buf, REG_STR_SIZE,
supply_name); "microamps_requested_%s-%s",
dev_name(dev), supply_name);
if (size >= REG_STR_SIZE) if (size >= REG_STR_SIZE)
goto overflow_err; goto overflow_err;
...@@ -1088,7 +1103,28 @@ static struct regulator *create_regulator(struct regulator_dev *rdev, ...@@ -1088,7 +1103,28 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
dev->kobj.name, err); dev->kobj.name, err);
goto link_name_err; goto link_name_err;
} }
} else {
regulator->supply_name = kstrdup(supply_name, GFP_KERNEL);
if (regulator->supply_name == NULL)
goto attr_err;
}
#ifdef CONFIG_DEBUG_FS
regulator->debugfs = debugfs_create_dir(regulator->supply_name,
rdev->debugfs);
if (IS_ERR_OR_NULL(regulator->debugfs)) {
rdev_warn(rdev, "Failed to create debugfs directory\n");
regulator->debugfs = NULL;
} else {
debugfs_create_u32("uA_load", 0444, regulator->debugfs,
&regulator->uA_load);
debugfs_create_u32("min_uV", 0444, regulator->debugfs,
&regulator->min_uV);
debugfs_create_u32("max_uV", 0444, regulator->debugfs,
&regulator->max_uV);
} }
#endif
mutex_unlock(&rdev->mutex); mutex_unlock(&rdev->mutex);
return regulator; return regulator;
link_name_err: link_name_err:
...@@ -1267,13 +1303,17 @@ void regulator_put(struct regulator *regulator) ...@@ -1267,13 +1303,17 @@ void regulator_put(struct regulator *regulator)
mutex_lock(&regulator_list_mutex); mutex_lock(&regulator_list_mutex);
rdev = regulator->rdev; rdev = regulator->rdev;
#ifdef CONFIG_DEBUG_FS
debugfs_remove_recursive(regulator->debugfs);
#endif
/* remove any sysfs entries */ /* remove any sysfs entries */
if (regulator->dev) { if (regulator->dev) {
sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name); sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name);
kfree(regulator->supply_name);
device_remove_file(regulator->dev, &regulator->dev_attr); device_remove_file(regulator->dev, &regulator->dev_attr);
kfree(regulator->dev_attr.attr.name); kfree(regulator->dev_attr.attr.name);
} }
kfree(regulator->supply_name);
list_del(&regulator->list); list_del(&regulator->list);
kfree(regulator); kfree(regulator);
...@@ -1301,19 +1341,6 @@ static int _regulator_enable(struct regulator_dev *rdev) ...@@ -1301,19 +1341,6 @@ static int _regulator_enable(struct regulator_dev *rdev)
{ {
int ret, delay; int ret, delay;
if (rdev->use_count == 0) {
/* do we need to enable the supply regulator first */
if (rdev->supply) {
mutex_lock(&rdev->supply->mutex);
ret = _regulator_enable(rdev->supply);
mutex_unlock(&rdev->supply->mutex);
if (ret < 0) {
rdev_err(rdev, "failed to enable: %d\n", ret);
return ret;
}
}
}
/* check voltage and requested load before enabling */ /* check voltage and requested load before enabling */
if (rdev->constraints && if (rdev->constraints &&
(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS)) (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS))
...@@ -1388,19 +1415,27 @@ int regulator_enable(struct regulator *regulator) ...@@ -1388,19 +1415,27 @@ int regulator_enable(struct regulator *regulator)
struct regulator_dev *rdev = regulator->rdev; struct regulator_dev *rdev = regulator->rdev;
int ret = 0; int ret = 0;
if (rdev->supply) {
ret = regulator_enable(rdev->supply);
if (ret != 0)
return ret;
}
mutex_lock(&rdev->mutex); mutex_lock(&rdev->mutex);
ret = _regulator_enable(rdev); ret = _regulator_enable(rdev);
mutex_unlock(&rdev->mutex); mutex_unlock(&rdev->mutex);
if (ret != 0)
regulator_disable(rdev->supply);
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(regulator_enable); EXPORT_SYMBOL_GPL(regulator_enable);
/* locks held by regulator_disable() */ /* locks held by regulator_disable() */
static int _regulator_disable(struct regulator_dev *rdev, static int _regulator_disable(struct regulator_dev *rdev)
struct regulator_dev **supply_rdev_ptr)
{ {
int ret = 0; int ret = 0;
*supply_rdev_ptr = NULL;
if (WARN(rdev->use_count <= 0, if (WARN(rdev->use_count <= 0,
"unbalanced disables for %s\n", rdev_get_name(rdev))) "unbalanced disables for %s\n", rdev_get_name(rdev)))
...@@ -1427,9 +1462,6 @@ static int _regulator_disable(struct regulator_dev *rdev, ...@@ -1427,9 +1462,6 @@ static int _regulator_disable(struct regulator_dev *rdev,
NULL); NULL);
} }
/* decrease our supplies ref count and disable if required */
*supply_rdev_ptr = rdev->supply;
rdev->use_count = 0; rdev->use_count = 0;
} else if (rdev->use_count > 1) { } else if (rdev->use_count > 1) {
...@@ -1440,6 +1472,7 @@ static int _regulator_disable(struct regulator_dev *rdev, ...@@ -1440,6 +1472,7 @@ static int _regulator_disable(struct regulator_dev *rdev,
rdev->use_count--; rdev->use_count--;
} }
return ret; return ret;
} }
...@@ -1458,29 +1491,21 @@ static int _regulator_disable(struct regulator_dev *rdev, ...@@ -1458,29 +1491,21 @@ static int _regulator_disable(struct regulator_dev *rdev,
int regulator_disable(struct regulator *regulator) int regulator_disable(struct regulator *regulator)
{ {
struct regulator_dev *rdev = regulator->rdev; struct regulator_dev *rdev = regulator->rdev;
struct regulator_dev *supply_rdev = NULL;
int ret = 0; int ret = 0;
mutex_lock(&rdev->mutex); mutex_lock(&rdev->mutex);
ret = _regulator_disable(rdev, &supply_rdev); ret = _regulator_disable(rdev);
mutex_unlock(&rdev->mutex); mutex_unlock(&rdev->mutex);
/* decrease our supplies ref count and disable if required */ if (ret == 0 && rdev->supply)
while (supply_rdev != NULL) { regulator_disable(rdev->supply);
rdev = supply_rdev;
mutex_lock(&rdev->mutex);
_regulator_disable(rdev, &supply_rdev);
mutex_unlock(&rdev->mutex);
}
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(regulator_disable); EXPORT_SYMBOL_GPL(regulator_disable);
/* locks held by regulator_force_disable() */ /* locks held by regulator_force_disable() */
static int _regulator_force_disable(struct regulator_dev *rdev, static int _regulator_force_disable(struct regulator_dev *rdev)
struct regulator_dev **supply_rdev_ptr)
{ {
int ret = 0; int ret = 0;
...@@ -1497,10 +1522,6 @@ static int _regulator_force_disable(struct regulator_dev *rdev, ...@@ -1497,10 +1522,6 @@ static int _regulator_force_disable(struct regulator_dev *rdev,
REGULATOR_EVENT_DISABLE, NULL); REGULATOR_EVENT_DISABLE, NULL);
} }
/* decrease our supplies ref count and disable if required */
*supply_rdev_ptr = rdev->supply;
rdev->use_count = 0;
return ret; return ret;
} }
...@@ -1516,16 +1537,16 @@ static int _regulator_force_disable(struct regulator_dev *rdev, ...@@ -1516,16 +1537,16 @@ static int _regulator_force_disable(struct regulator_dev *rdev,
int regulator_force_disable(struct regulator *regulator) int regulator_force_disable(struct regulator *regulator)
{ {
struct regulator_dev *rdev = regulator->rdev; struct regulator_dev *rdev = regulator->rdev;
struct regulator_dev *supply_rdev = NULL;
int ret; int ret;
mutex_lock(&rdev->mutex); mutex_lock(&rdev->mutex);
regulator->uA_load = 0; regulator->uA_load = 0;
ret = _regulator_force_disable(rdev, &supply_rdev); ret = _regulator_force_disable(regulator->rdev);
mutex_unlock(&rdev->mutex); mutex_unlock(&rdev->mutex);
if (supply_rdev) if (rdev->supply)
regulator_disable(get_device_regulator(rdev_get_dev(supply_rdev))); while (rdev->open_count--)
regulator_disable(rdev->supply);
return ret; return ret;
} }
...@@ -2136,7 +2157,7 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) ...@@ -2136,7 +2157,7 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load)
/* get input voltage */ /* get input voltage */
input_uV = 0; input_uV = 0;
if (rdev->supply) if (rdev->supply)
input_uV = _regulator_get_voltage(rdev->supply); input_uV = regulator_get_voltage(rdev->supply);
if (input_uV <= 0) if (input_uV <= 0)
input_uV = rdev->constraints->input_uV; input_uV = rdev->constraints->input_uV;
if (input_uV <= 0) { if (input_uV <= 0) {
...@@ -2206,17 +2227,8 @@ EXPORT_SYMBOL_GPL(regulator_unregister_notifier); ...@@ -2206,17 +2227,8 @@ EXPORT_SYMBOL_GPL(regulator_unregister_notifier);
static void _notifier_call_chain(struct regulator_dev *rdev, static void _notifier_call_chain(struct regulator_dev *rdev,
unsigned long event, void *data) unsigned long event, void *data)
{ {
struct regulator_dev *_rdev;
/* call rdev chain first */ /* call rdev chain first */
blocking_notifier_call_chain(&rdev->notifier, event, NULL); blocking_notifier_call_chain(&rdev->notifier, event, NULL);
/* now notify regulator we supply */
list_for_each_entry(_rdev, &rdev->supply_list, slist) {
mutex_lock(&_rdev->mutex);
_notifier_call_chain(_rdev, event, data);
mutex_unlock(&_rdev->mutex);
}
} }
/** /**
...@@ -2264,6 +2276,13 @@ int regulator_bulk_get(struct device *dev, int num_consumers, ...@@ -2264,6 +2276,13 @@ int regulator_bulk_get(struct device *dev, int num_consumers,
} }
EXPORT_SYMBOL_GPL(regulator_bulk_get); EXPORT_SYMBOL_GPL(regulator_bulk_get);
static void regulator_bulk_enable_async(void *data, async_cookie_t cookie)
{
struct regulator_bulk_data *bulk = data;
bulk->ret = regulator_enable(bulk->consumer);
}
/** /**
* regulator_bulk_enable - enable multiple regulator consumers * regulator_bulk_enable - enable multiple regulator consumers
* *
...@@ -2279,21 +2298,33 @@ EXPORT_SYMBOL_GPL(regulator_bulk_get); ...@@ -2279,21 +2298,33 @@ EXPORT_SYMBOL_GPL(regulator_bulk_get);
int regulator_bulk_enable(int num_consumers, int regulator_bulk_enable(int num_consumers,
struct regulator_bulk_data *consumers) struct regulator_bulk_data *consumers)
{ {
LIST_HEAD(async_domain);
int i; int i;
int ret; int ret = 0;
for (i = 0; i < num_consumers; i++)
async_schedule_domain(regulator_bulk_enable_async,
&consumers[i], &async_domain);
async_synchronize_full_domain(&async_domain);
/* If any consumer failed we need to unwind any that succeeded */
for (i = 0; i < num_consumers; i++) { for (i = 0; i < num_consumers; i++) {
ret = regulator_enable(consumers[i].consumer); if (consumers[i].ret != 0) {
if (ret != 0) ret = consumers[i].ret;
goto err; goto err;
} }
}
return 0; return 0;
err: err:
pr_err("Failed to enable %s: %d\n", consumers[i].supply, ret); for (i = 0; i < num_consumers; i++)
for (--i; i >= 0; --i) if (consumers[i].ret == 0)
regulator_disable(consumers[i].consumer); regulator_disable(consumers[i].consumer);
else
pr_err("Failed to enable %s: %d\n",
consumers[i].supply, consumers[i].ret);
return ret; return ret;
} }
...@@ -2589,9 +2620,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, ...@@ -2589,9 +2620,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
rdev->owner = regulator_desc->owner; rdev->owner = regulator_desc->owner;
rdev->desc = regulator_desc; rdev->desc = regulator_desc;
INIT_LIST_HEAD(&rdev->consumer_list); INIT_LIST_HEAD(&rdev->consumer_list);
INIT_LIST_HEAD(&rdev->supply_list);
INIT_LIST_HEAD(&rdev->list); INIT_LIST_HEAD(&rdev->list);
INIT_LIST_HEAD(&rdev->slist);
BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier); BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier);
/* preform any regulator specific init */ /* preform any regulator specific init */
...@@ -2672,6 +2701,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, ...@@ -2672,6 +2701,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
unset_regulator_supplies(rdev); unset_regulator_supplies(rdev);
scrub: scrub:
kfree(rdev->constraints);
device_unregister(&rdev->dev); device_unregister(&rdev->dev);
/* device core frees rdev */ /* device core frees rdev */
rdev = ERR_PTR(ret); rdev = ERR_PTR(ret);
...@@ -2703,7 +2733,7 @@ void regulator_unregister(struct regulator_dev *rdev) ...@@ -2703,7 +2733,7 @@ void regulator_unregister(struct regulator_dev *rdev)
unset_regulator_supplies(rdev); unset_regulator_supplies(rdev);
list_del(&rdev->list); list_del(&rdev->list);
if (rdev->supply) if (rdev->supply)
sysfs_remove_link(&rdev->dev.kobj, "supply"); regulator_put(rdev->supply);
device_unregister(&rdev->dev); device_unregister(&rdev->dev);
kfree(rdev->constraints); kfree(rdev->constraints);
mutex_unlock(&regulator_list_mutex); mutex_unlock(&regulator_list_mutex);
......
...@@ -36,6 +36,29 @@ static struct regulator_desc dummy_desc = { ...@@ -36,6 +36,29 @@ static struct regulator_desc dummy_desc = {
.ops = &dummy_ops, .ops = &dummy_ops,
}; };
static int __devinit dummy_regulator_probe(struct platform_device *pdev)
{
int ret;
dummy_regulator_rdev = regulator_register(&dummy_desc, NULL,
&dummy_initdata, NULL);
if (IS_ERR(dummy_regulator_rdev)) {
ret = PTR_ERR(dummy_regulator_rdev);
pr_err("Failed to register regulator: %d\n", ret);
return ret;
}
return 0;
}
static struct platform_driver dummy_regulator_driver = {
.probe = dummy_regulator_probe,
.driver = {
.name = "reg-dummy",
.owner = THIS_MODULE,
},
};
static struct platform_device *dummy_pdev; static struct platform_device *dummy_pdev;
void __init regulator_dummy_init(void) void __init regulator_dummy_init(void)
...@@ -55,12 +78,9 @@ void __init regulator_dummy_init(void) ...@@ -55,12 +78,9 @@ void __init regulator_dummy_init(void)
return; return;
} }
dummy_regulator_rdev = regulator_register(&dummy_desc, NULL, ret = platform_driver_register(&dummy_regulator_driver);
&dummy_initdata, NULL); if (ret != 0) {
if (IS_ERR(dummy_regulator_rdev)) { pr_err("Failed to register dummy regulator driver: %d\n", ret);
ret = PTR_ERR(dummy_regulator_rdev);
pr_err("Failed to register regulator: %d\n", ret);
platform_device_unregister(dummy_pdev); platform_device_unregister(dummy_pdev);
return;
} }
} }
...@@ -49,7 +49,6 @@ ...@@ -49,7 +49,6 @@
#define TPS65911_REG_LDO7 11 #define TPS65911_REG_LDO7 11
#define TPS65911_REG_LDO8 12 #define TPS65911_REG_LDO8 12
#define TPS65910_NUM_REGULATOR 13
#define TPS65910_SUPPLY_STATE_ENABLED 0x1 #define TPS65910_SUPPLY_STATE_ENABLED 0x1
/* supported VIO voltages in milivolts */ /* supported VIO voltages in milivolts */
...@@ -264,11 +263,12 @@ static struct tps_info tps65911_regs[] = { ...@@ -264,11 +263,12 @@ static struct tps_info tps65911_regs[] = {
}; };
struct tps65910_reg { struct tps65910_reg {
struct regulator_desc desc[TPS65910_NUM_REGULATOR]; struct regulator_desc *desc;
struct tps65910 *mfd; struct tps65910 *mfd;
struct regulator_dev *rdev[TPS65910_NUM_REGULATOR]; struct regulator_dev **rdev;
struct tps_info *info[TPS65910_NUM_REGULATOR]; struct tps_info **info;
struct mutex mutex; struct mutex mutex;
int num_regulators;
int mode; int mode;
int (*get_ctrl_reg)(int); int (*get_ctrl_reg)(int);
}; };
...@@ -759,8 +759,13 @@ static int tps65910_list_voltage_dcdc(struct regulator_dev *dev, ...@@ -759,8 +759,13 @@ static int tps65910_list_voltage_dcdc(struct regulator_dev *dev,
mult = (selector / VDD1_2_NUM_VOLTS) + 1; mult = (selector / VDD1_2_NUM_VOLTS) + 1;
volt = VDD1_2_MIN_VOLT + volt = VDD1_2_MIN_VOLT +
(selector % VDD1_2_NUM_VOLTS) * VDD1_2_OFFSET; (selector % VDD1_2_NUM_VOLTS) * VDD1_2_OFFSET;
break;
case TPS65911_REG_VDDCTRL: case TPS65911_REG_VDDCTRL:
volt = VDDCTRL_MIN_VOLT + (selector * VDDCTRL_OFFSET); volt = VDDCTRL_MIN_VOLT + (selector * VDDCTRL_OFFSET);
break;
default:
BUG();
return -EINVAL;
} }
return volt * 100 * mult; return volt * 100 * mult;
...@@ -897,16 +902,42 @@ static __devinit int tps65910_probe(struct platform_device *pdev) ...@@ -897,16 +902,42 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
switch(tps65910_chip_id(tps65910)) { switch(tps65910_chip_id(tps65910)) {
case TPS65910: case TPS65910:
pmic->get_ctrl_reg = &tps65910_get_ctrl_register; pmic->get_ctrl_reg = &tps65910_get_ctrl_register;
pmic->num_regulators = ARRAY_SIZE(tps65910_regs);
info = tps65910_regs; info = tps65910_regs;
break;
case TPS65911: case TPS65911:
pmic->get_ctrl_reg = &tps65911_get_ctrl_register; pmic->get_ctrl_reg = &tps65911_get_ctrl_register;
pmic->num_regulators = ARRAY_SIZE(tps65911_regs);
info = tps65911_regs; info = tps65911_regs;
break;
default: default:
pr_err("Invalid tps chip version\n"); pr_err("Invalid tps chip version\n");
kfree(pmic);
return -ENODEV; return -ENODEV;
} }
for (i = 0; i < TPS65910_NUM_REGULATOR; i++, info++, reg_data++) { pmic->desc = kcalloc(pmic->num_regulators,
sizeof(struct regulator_desc), GFP_KERNEL);
if (!pmic->desc) {
err = -ENOMEM;
goto err_free_pmic;
}
pmic->info = kcalloc(pmic->num_regulators,
sizeof(struct tps_info *), GFP_KERNEL);
if (!pmic->info) {
err = -ENOMEM;
goto err_free_desc;
}
pmic->rdev = kcalloc(pmic->num_regulators,
sizeof(struct regulator_dev *), GFP_KERNEL);
if (!pmic->rdev) {
err = -ENOMEM;
goto err_free_info;
}
for (i = 0; i < pmic->num_regulators; i++, info++, reg_data++) {
/* Register the regulators */ /* Register the regulators */
pmic->info[i] = info; pmic->info[i] = info;
...@@ -938,7 +969,7 @@ static __devinit int tps65910_probe(struct platform_device *pdev) ...@@ -938,7 +969,7 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
"failed to register %s regulator\n", "failed to register %s regulator\n",
pdev->name); pdev->name);
err = PTR_ERR(rdev); err = PTR_ERR(rdev);
goto err; goto err_unregister_regulator;
} }
/* Save regulator for cleanup */ /* Save regulator for cleanup */
...@@ -946,23 +977,31 @@ static __devinit int tps65910_probe(struct platform_device *pdev) ...@@ -946,23 +977,31 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
} }
return 0; return 0;
err: err_unregister_regulator:
while (--i >= 0) while (--i >= 0)
regulator_unregister(pmic->rdev[i]); regulator_unregister(pmic->rdev[i]);
kfree(pmic->rdev);
err_free_info:
kfree(pmic->info);
err_free_desc:
kfree(pmic->desc);
err_free_pmic:
kfree(pmic); kfree(pmic);
return err; return err;
} }
static int __devexit tps65910_remove(struct platform_device *pdev) static int __devexit tps65910_remove(struct platform_device *pdev)
{ {
struct tps65910_reg *tps65910_reg = platform_get_drvdata(pdev); struct tps65910_reg *pmic = platform_get_drvdata(pdev);
int i; int i;
for (i = 0; i < TPS65910_NUM_REGULATOR; i++) for (i = 0; i < pmic->num_regulators; i++)
regulator_unregister(tps65910_reg->rdev[i]); regulator_unregister(pmic->rdev[i]);
kfree(tps65910_reg); kfree(pmic->rdev);
kfree(pmic->info);
kfree(pmic->desc);
kfree(pmic);
return 0; return 0;
} }
......
...@@ -835,8 +835,8 @@ static struct regulator_ops twlsmps_ops = { ...@@ -835,8 +835,8 @@ static struct regulator_ops twlsmps_ops = {
remap_conf) \ remap_conf) \
TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \
remap_conf, TWL4030, twl4030fixed_ops) remap_conf, TWL4030, twl4030fixed_ops)
#define TWL6030_FIXED_LDO(label, offset, mVolts, num, turnon_delay) \ #define TWL6030_FIXED_LDO(label, offset, mVolts, turnon_delay) \
TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ TWL_FIXED_LDO(label, offset, mVolts, 0x0, turnon_delay, \
0x0, TWL6030, twl6030fixed_ops) 0x0, TWL6030, twl6030fixed_ops)
#define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) { \ #define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) { \
...@@ -856,24 +856,22 @@ static struct regulator_ops twlsmps_ops = { ...@@ -856,24 +856,22 @@ static struct regulator_ops twlsmps_ops = {
}, \ }, \
} }
#define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts, num) { \ #define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) { \
.base = offset, \ .base = offset, \
.id = num, \
.min_mV = min_mVolts, \ .min_mV = min_mVolts, \
.max_mV = max_mVolts, \ .max_mV = max_mVolts, \
.desc = { \ .desc = { \
.name = #label, \ .name = #label, \
.id = TWL6030_REG_##label, \ .id = TWL6030_REG_##label, \
.n_voltages = (max_mVolts - min_mVolts)/100, \ .n_voltages = (max_mVolts - min_mVolts)/100 + 1, \
.ops = &twl6030ldo_ops, \ .ops = &twl6030ldo_ops, \
.type = REGULATOR_VOLTAGE, \ .type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \ .owner = THIS_MODULE, \
}, \ }, \
} }
#define TWL6025_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts, num) { \ #define TWL6025_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) { \
.base = offset, \ .base = offset, \
.id = num, \
.min_mV = min_mVolts, \ .min_mV = min_mVolts, \
.max_mV = max_mVolts, \ .max_mV = max_mVolts, \
.desc = { \ .desc = { \
...@@ -903,9 +901,8 @@ static struct regulator_ops twlsmps_ops = { ...@@ -903,9 +901,8 @@ static struct regulator_ops twlsmps_ops = {
}, \ }, \
} }
#define TWL6030_FIXED_RESOURCE(label, offset, num, turnon_delay) { \ #define TWL6030_FIXED_RESOURCE(label, offset, turnon_delay) { \
.base = offset, \ .base = offset, \
.id = num, \
.delay = turnon_delay, \ .delay = turnon_delay, \
.desc = { \ .desc = { \
.name = #label, \ .name = #label, \
...@@ -916,9 +913,8 @@ static struct regulator_ops twlsmps_ops = { ...@@ -916,9 +913,8 @@ static struct regulator_ops twlsmps_ops = {
}, \ }, \
} }
#define TWL6025_ADJUSTABLE_SMPS(label, offset, num) { \ #define TWL6025_ADJUSTABLE_SMPS(label, offset) { \
.base = offset, \ .base = offset, \
.id = num, \
.min_mV = 600, \ .min_mV = 600, \
.max_mV = 2100, \ .max_mV = 2100, \
.desc = { \ .desc = { \
...@@ -961,32 +957,32 @@ static struct twlreg_info twl_regs[] = { ...@@ -961,32 +957,32 @@ static struct twlreg_info twl_regs[] = {
/* 6030 REG with base as PMC Slave Misc : 0x0030 */ /* 6030 REG with base as PMC Slave Misc : 0x0030 */
/* Turnon-delay and remap configuration values for 6030 are not /* Turnon-delay and remap configuration values for 6030 are not
verified since the specification is not public */ verified since the specification is not public */
TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1000, 3300, 1), TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1000, 3300),
TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 1000, 3300, 2), TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 1000, 3300),
TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 1000, 3300, 3), TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 1000, 3300),
TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 1000, 3300, 4), TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 1000, 3300),
TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 1000, 3300, 5), TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 1000, 3300),
TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 1000, 3300, 7), TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 1000, 3300),
TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15, 0), TWL6030_FIXED_LDO(VANA, 0x50, 2100, 0),
TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16, 0), TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 0),
TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17, 0), TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 0),
TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 18, 0), TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 0),
TWL6030_FIXED_RESOURCE(CLK32KG, 0x8C, 48, 0), TWL6030_FIXED_RESOURCE(CLK32KG, 0x8C, 0),
/* 6025 are renamed compared to 6030 versions */ /* 6025 are renamed compared to 6030 versions */
TWL6025_ADJUSTABLE_LDO(LDO2, 0x54, 1000, 3300, 1), TWL6025_ADJUSTABLE_LDO(LDO2, 0x54, 1000, 3300),
TWL6025_ADJUSTABLE_LDO(LDO4, 0x58, 1000, 3300, 2), TWL6025_ADJUSTABLE_LDO(LDO4, 0x58, 1000, 3300),
TWL6025_ADJUSTABLE_LDO(LDO3, 0x5c, 1000, 3300, 3), TWL6025_ADJUSTABLE_LDO(LDO3, 0x5c, 1000, 3300),
TWL6025_ADJUSTABLE_LDO(LDO5, 0x68, 1000, 3300, 4), TWL6025_ADJUSTABLE_LDO(LDO5, 0x68, 1000, 3300),
TWL6025_ADJUSTABLE_LDO(LDO1, 0x6c, 1000, 3300, 5), TWL6025_ADJUSTABLE_LDO(LDO1, 0x6c, 1000, 3300),
TWL6025_ADJUSTABLE_LDO(LDO7, 0x74, 1000, 3300, 7), TWL6025_ADJUSTABLE_LDO(LDO7, 0x74, 1000, 3300),
TWL6025_ADJUSTABLE_LDO(LDO6, 0x60, 1000, 3300, 16), TWL6025_ADJUSTABLE_LDO(LDO6, 0x60, 1000, 3300),
TWL6025_ADJUSTABLE_LDO(LDOLN, 0x64, 1000, 3300, 17), TWL6025_ADJUSTABLE_LDO(LDOLN, 0x64, 1000, 3300),
TWL6025_ADJUSTABLE_LDO(LDOUSB, 0x70, 1000, 3300, 18), TWL6025_ADJUSTABLE_LDO(LDOUSB, 0x70, 1000, 3300),
TWL6025_ADJUSTABLE_SMPS(SMPS3, 0x34, 1), TWL6025_ADJUSTABLE_SMPS(SMPS3, 0x34),
TWL6025_ADJUSTABLE_SMPS(SMPS4, 0x10, 2), TWL6025_ADJUSTABLE_SMPS(SMPS4, 0x10),
TWL6025_ADJUSTABLE_SMPS(VIO, 0x16, 3), TWL6025_ADJUSTABLE_SMPS(VIO, 0x16),
}; };
static u8 twl_get_smps_offset(void) static u8 twl_get_smps_offset(void)
......
...@@ -267,23 +267,6 @@ static int wm831x_buckv_select_min_voltage(struct regulator_dev *rdev, ...@@ -267,23 +267,6 @@ static int wm831x_buckv_select_min_voltage(struct regulator_dev *rdev,
return vsel; return vsel;
} }
static int wm831x_buckv_select_max_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV)
{
u16 vsel;
if (max_uV < 600000 || max_uV > 1800000)
return -EINVAL;
vsel = ((max_uV - 600000) / 12500) + 8;
if (wm831x_buckv_list_voltage(rdev, vsel) < min_uV ||
wm831x_buckv_list_voltage(rdev, vsel) < max_uV)
return -EINVAL;
return vsel;
}
static int wm831x_buckv_set_dvs(struct regulator_dev *rdev, int state) static int wm831x_buckv_set_dvs(struct regulator_dev *rdev, int state)
{ {
struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
...@@ -338,27 +321,22 @@ static int wm831x_buckv_set_voltage(struct regulator_dev *rdev, ...@@ -338,27 +321,22 @@ static int wm831x_buckv_set_voltage(struct regulator_dev *rdev,
if (ret < 0) if (ret < 0)
return ret; return ret;
/* Set the high voltage as the DVS voltage. This is optimised /*
* for CPUfreq usage, most processors will keep the maximum * If this VSEL is higher than the last one we've seen then
* voltage constant and lower the minimum with the frequency. */ * remember it as the DVS VSEL. This is optimised for CPUfreq
vsel = wm831x_buckv_select_max_voltage(rdev, min_uV, max_uV); * usage where we want to get to the highest voltage very
if (vsel < 0) { * quickly.
/* This should never happen - at worst the same vsel */
* should be chosen */ if (vsel > dcdc->dvs_vsel) {
WARN_ON(vsel < 0); ret = wm831x_set_bits(wm831x, dvs_reg,
return 0; WM831X_DC1_DVS_VSEL_MASK,
} dcdc->dvs_vsel);
/* Don't bother if it's the same VSEL we're already using */
if (vsel == dcdc->on_vsel)
return 0;
ret = wm831x_set_bits(wm831x, dvs_reg, WM831X_DC1_DVS_VSEL_MASK, vsel);
if (ret == 0) if (ret == 0)
dcdc->dvs_vsel = vsel; dcdc->dvs_vsel = vsel;
else else
dev_warn(wm831x->dev, "Failed to set DCDC DVS VSEL: %d\n", dev_warn(wm831x->dev,
ret); "Failed to set DCDC DVS VSEL: %d\n", ret);
}
return 0; return 0;
} }
...@@ -456,27 +434,6 @@ static __devinit void wm831x_buckv_dvs_init(struct wm831x_dcdc *dcdc, ...@@ -456,27 +434,6 @@ static __devinit void wm831x_buckv_dvs_init(struct wm831x_dcdc *dcdc,
if (!pdata || !pdata->dvs_gpio) if (!pdata || !pdata->dvs_gpio)
return; return;
switch (pdata->dvs_control_src) {
case 1:
ctrl = 2 << WM831X_DC1_DVS_SRC_SHIFT;
break;
case 2:
ctrl = 3 << WM831X_DC1_DVS_SRC_SHIFT;
break;
default:
dev_err(wm831x->dev, "Invalid DVS control source %d for %s\n",
pdata->dvs_control_src, dcdc->name);
return;
}
ret = wm831x_set_bits(wm831x, dcdc->base + WM831X_DCDC_DVS_CONTROL,
WM831X_DC1_DVS_SRC_MASK, ctrl);
if (ret < 0) {
dev_err(wm831x->dev, "Failed to set %s DVS source: %d\n",
dcdc->name, ret);
return;
}
ret = gpio_request(pdata->dvs_gpio, "DCDC DVS"); ret = gpio_request(pdata->dvs_gpio, "DCDC DVS");
if (ret < 0) { if (ret < 0) {
dev_err(wm831x->dev, "Failed to get %s DVS GPIO: %d\n", dev_err(wm831x->dev, "Failed to get %s DVS GPIO: %d\n",
...@@ -498,17 +455,57 @@ static __devinit void wm831x_buckv_dvs_init(struct wm831x_dcdc *dcdc, ...@@ -498,17 +455,57 @@ static __devinit void wm831x_buckv_dvs_init(struct wm831x_dcdc *dcdc,
} }
dcdc->dvs_gpio = pdata->dvs_gpio; dcdc->dvs_gpio = pdata->dvs_gpio;
switch (pdata->dvs_control_src) {
case 1:
ctrl = 2 << WM831X_DC1_DVS_SRC_SHIFT;
break;
case 2:
ctrl = 3 << WM831X_DC1_DVS_SRC_SHIFT;
break;
default:
dev_err(wm831x->dev, "Invalid DVS control source %d for %s\n",
pdata->dvs_control_src, dcdc->name);
return;
}
/* If DVS_VSEL is set to the minimum value then raise it to ON_VSEL
* to make bootstrapping a bit smoother.
*/
if (!dcdc->dvs_vsel) {
ret = wm831x_set_bits(wm831x,
dcdc->base + WM831X_DCDC_DVS_CONTROL,
WM831X_DC1_DVS_VSEL_MASK, dcdc->on_vsel);
if (ret == 0)
dcdc->dvs_vsel = dcdc->on_vsel;
else
dev_warn(wm831x->dev, "Failed to set DVS_VSEL: %d\n",
ret);
}
ret = wm831x_set_bits(wm831x, dcdc->base + WM831X_DCDC_DVS_CONTROL,
WM831X_DC1_DVS_SRC_MASK, ctrl);
if (ret < 0) {
dev_err(wm831x->dev, "Failed to set %s DVS source: %d\n",
dcdc->name, ret);
}
} }
static __devinit int wm831x_buckv_probe(struct platform_device *pdev) static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
{ {
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
struct wm831x_pdata *pdata = wm831x->dev->platform_data; struct wm831x_pdata *pdata = wm831x->dev->platform_data;
int id = pdev->id % ARRAY_SIZE(pdata->dcdc); int id;
struct wm831x_dcdc *dcdc; struct wm831x_dcdc *dcdc;
struct resource *res; struct resource *res;
int ret, irq; int ret, irq;
if (pdata && pdata->wm831x_num)
id = (pdata->wm831x_num * 10) + 1;
else
id = 0;
id = pdev->id - id;
dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1); dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1);
if (pdata == NULL || pdata->dcdc[id] == NULL) if (pdata == NULL || pdata->dcdc[id] == NULL)
...@@ -545,7 +542,7 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev) ...@@ -545,7 +542,7 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
} }
dcdc->on_vsel = ret & WM831X_DC1_ON_VSEL_MASK; dcdc->on_vsel = ret & WM831X_DC1_ON_VSEL_MASK;
ret = wm831x_reg_read(wm831x, dcdc->base + WM831X_DCDC_ON_CONFIG); ret = wm831x_reg_read(wm831x, dcdc->base + WM831X_DCDC_DVS_CONTROL);
if (ret < 0) { if (ret < 0) {
dev_err(wm831x->dev, "Failed to read DVS VSEL: %d\n", ret); dev_err(wm831x->dev, "Failed to read DVS VSEL: %d\n", ret);
goto err; goto err;
...@@ -709,11 +706,17 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev) ...@@ -709,11 +706,17 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev)
{ {
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
struct wm831x_pdata *pdata = wm831x->dev->platform_data; struct wm831x_pdata *pdata = wm831x->dev->platform_data;
int id = pdev->id % ARRAY_SIZE(pdata->dcdc); int id;
struct wm831x_dcdc *dcdc; struct wm831x_dcdc *dcdc;
struct resource *res; struct resource *res;
int ret, irq; int ret, irq;
if (pdata && pdata->wm831x_num)
id = (pdata->wm831x_num * 10) + 1;
else
id = 0;
id = pdev->id - id;
dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1); dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1);
if (pdata == NULL || pdata->dcdc[id] == NULL) if (pdata == NULL || pdata->dcdc[id] == NULL)
...@@ -1046,3 +1049,4 @@ MODULE_DESCRIPTION("WM831x DC-DC convertor driver"); ...@@ -1046,3 +1049,4 @@ MODULE_DESCRIPTION("WM831x DC-DC convertor driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:wm831x-buckv"); MODULE_ALIAS("platform:wm831x-buckv");
MODULE_ALIAS("platform:wm831x-buckp"); MODULE_ALIAS("platform:wm831x-buckp");
MODULE_ALIAS("platform:wm831x-epe");
...@@ -310,11 +310,17 @@ static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev) ...@@ -310,11 +310,17 @@ static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev)
{ {
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
struct wm831x_pdata *pdata = wm831x->dev->platform_data; struct wm831x_pdata *pdata = wm831x->dev->platform_data;
int id = pdev->id % ARRAY_SIZE(pdata->ldo); int id;
struct wm831x_ldo *ldo; struct wm831x_ldo *ldo;
struct resource *res; struct resource *res;
int ret, irq; int ret, irq;
if (pdata && pdata->wm831x_num)
id = (pdata->wm831x_num * 10) + 1;
else
id = 0;
id = pdev->id - id;
dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1); dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1);
if (pdata == NULL || pdata->ldo[id] == NULL) if (pdata == NULL || pdata->ldo[id] == NULL)
...@@ -574,11 +580,17 @@ static __devinit int wm831x_aldo_probe(struct platform_device *pdev) ...@@ -574,11 +580,17 @@ static __devinit int wm831x_aldo_probe(struct platform_device *pdev)
{ {
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
struct wm831x_pdata *pdata = wm831x->dev->platform_data; struct wm831x_pdata *pdata = wm831x->dev->platform_data;
int id = pdev->id % ARRAY_SIZE(pdata->ldo); int id;
struct wm831x_ldo *ldo; struct wm831x_ldo *ldo;
struct resource *res; struct resource *res;
int ret, irq; int ret, irq;
if (pdata && pdata->wm831x_num)
id = (pdata->wm831x_num * 10) + 1;
else
id = 0;
id = pdev->id - id;
dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1); dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1);
if (pdata == NULL || pdata->ldo[id] == NULL) if (pdata == NULL || pdata->ldo[id] == NULL)
...@@ -764,11 +776,18 @@ static __devinit int wm831x_alive_ldo_probe(struct platform_device *pdev) ...@@ -764,11 +776,18 @@ static __devinit int wm831x_alive_ldo_probe(struct platform_device *pdev)
{ {
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
struct wm831x_pdata *pdata = wm831x->dev->platform_data; struct wm831x_pdata *pdata = wm831x->dev->platform_data;
int id = pdev->id % ARRAY_SIZE(pdata->ldo); int id;
struct wm831x_ldo *ldo; struct wm831x_ldo *ldo;
struct resource *res; struct resource *res;
int ret; int ret;
if (pdata && pdata->wm831x_num)
id = (pdata->wm831x_num * 10) + 1;
else
id = 0;
id = pdev->id - id;
dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1); dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1);
if (pdata == NULL || pdata->ldo[id] == NULL) if (pdata == NULL || pdata->ldo[id] == NULL)
......
...@@ -43,7 +43,7 @@ static int wm8994_ldo_enable(struct regulator_dev *rdev) ...@@ -43,7 +43,7 @@ static int wm8994_ldo_enable(struct regulator_dev *rdev)
if (!ldo->enable) if (!ldo->enable)
return 0; return 0;
gpio_set_value(ldo->enable, 1); gpio_set_value_cansleep(ldo->enable, 1);
ldo->is_enabled = true; ldo->is_enabled = true;
return 0; return 0;
...@@ -57,7 +57,7 @@ static int wm8994_ldo_disable(struct regulator_dev *rdev) ...@@ -57,7 +57,7 @@ static int wm8994_ldo_disable(struct regulator_dev *rdev)
if (!ldo->enable) if (!ldo->enable)
return -EINVAL; return -EINVAL;
gpio_set_value(ldo->enable, 0); gpio_set_value_cansleep(ldo->enable, 0);
ldo->is_enabled = false; ldo->is_enabled = false;
return 0; return 0;
......
...@@ -122,6 +122,9 @@ struct regulator; ...@@ -122,6 +122,9 @@ struct regulator;
struct regulator_bulk_data { struct regulator_bulk_data {
const char *supply; const char *supply;
struct regulator *consumer; struct regulator *consumer;
/* Internal use */
int ret;
}; };
#if defined(CONFIG_REGULATOR) #if defined(CONFIG_REGULATOR)
......
...@@ -188,18 +188,16 @@ struct regulator_dev { ...@@ -188,18 +188,16 @@ struct regulator_dev {
/* lists we belong to */ /* lists we belong to */
struct list_head list; /* list of all regulators */ struct list_head list; /* list of all regulators */
struct list_head slist; /* list of supplied regulators */
/* lists we own */ /* lists we own */
struct list_head consumer_list; /* consumers we supply */ struct list_head consumer_list; /* consumers we supply */
struct list_head supply_list; /* regulators we supply */
struct blocking_notifier_head notifier; struct blocking_notifier_head notifier;
struct mutex mutex; /* consumer lock */ struct mutex mutex; /* consumer lock */
struct module *owner; struct module *owner;
struct device dev; struct device dev;
struct regulation_constraints *constraints; struct regulation_constraints *constraints;
struct regulator_dev *supply; /* for tree */ struct regulator *supply; /* for tree */
void *reg_data; /* regulator_dev data */ void *reg_data; /* regulator_dev data */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment