2010/10/5 Alan Cox <alan@xxxxxxxxxxxxxxxxxxx>: > I actually see two ways of attacking that, one is that the dummy > regulator *and* the compiled in regulator system have a standard > regulator value that can be passed which means "report success, move > along nothing to see" that could be passed into drivers, Something like this patch series? If people like it I'll test it a bit more and submit this 2-patch series. From: Linus Walleij <linus.walleij@xxxxxxxxxxxxxx> Date: Tue, 5 Oct 2010 23:23:47 +0200 Subject: [PATCH 1/2] regulator: add a relaxed regulor_try_get() This wrapper function will accept non-existing regulators and not treat them as errors. Consumers will have to NULL-check their regulators. Signed-off-by: Linus Walleij <linus.walleij@xxxxxxxxxxxxxx> --- include/linux/regulator/consumer.h | 20 ++++++++++++++++++++ 1 files changed, 20 insertions(+), 0 deletions(-) diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index ebd7472..6ee7fdc 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -36,6 +36,7 @@ #define __LINUX_REGULATOR_CONSUMER_H_ #include <linux/device.h> +#include <linux/err.h> /* * Regulator operating modes. @@ -297,4 +298,23 @@ static inline void regulator_set_drvdata(struct regulator *regulator, #endif +/* + * Try to get a regulator, if it fails, no big deal. + * This wrapper function is intended to be used for code + * where regulator control is optional for the particular + * consumer, but still the regulator framework may be in + * use for other things in the platform. + */ +static inline struct regulator *regulator_try_get(struct device *dev, + const char *id) +{ + struct regulator *reg = regulator_get(dev, id); + + /* It's just that this regulator is not (yet) defined */ + if (IS_ERR(reg) && PTR_ERR(reg) == -ENODEV) + return NULL; + + return reg; +} + #endif -- 1.7.2.3 From: Linus Walleij <linus.walleij@xxxxxxxxxxxxxx> Date: Wed, 6 Oct 2010 00:04:25 +0200 Subject: [PATCH 2/2] regulator: handle NULL regulators in core If the user has selected to use regulator_try_get() to fetch regulators, we bail out of consumer operations if the regulator happens to be NULL. Signed-off-by: Linus Walleij <linus.walleij@xxxxxxxxxxxxxx> --- drivers/regulator/core.c | 64 +++++++++++++++++++++++++++++++++++++++------ 1 files changed, 55 insertions(+), 9 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index cc8b337..989e4e4 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1337,9 +1337,12 @@ static int _regulator_enable(struct regulator_dev *rdev) */ int regulator_enable(struct regulator *regulator) { - struct regulator_dev *rdev = regulator->rdev; + struct regulator_dev *rdev; int ret = 0; + if (regulator == NULL) + return 0; + rdev = regulator->rdev; mutex_lock(&rdev->mutex); ret = _regulator_enable(rdev); mutex_unlock(&rdev->mutex); @@ -1406,9 +1409,12 @@ static int _regulator_disable(struct regulator_dev *rdev) */ int regulator_disable(struct regulator *regulator) { - struct regulator_dev *rdev = regulator->rdev; + struct regulator_dev *rdev; int ret = 0; + if (regulator == NULL) + return 0; + rdev = regulator->rdev; mutex_lock(&rdev->mutex); ret = _regulator_disable(rdev); mutex_unlock(&rdev->mutex); @@ -1456,6 +1462,8 @@ int regulator_force_disable(struct regulator *regulator) { int ret; + if (regulator == NULL) + return 0; mutex_lock(®ulator->rdev->mutex); regulator->uA_load = 0; ret = _regulator_force_disable(regulator->rdev); @@ -1489,6 +1497,8 @@ int regulator_is_enabled(struct regulator *regulator) { int ret; + if (regulator == NULL) + return 1; mutex_lock(®ulator->rdev->mutex); ret = _regulator_is_enabled(regulator->rdev); mutex_unlock(®ulator->rdev->mutex); @@ -1507,8 +1517,11 @@ EXPORT_SYMBOL_GPL(regulator_is_enabled); */ int regulator_count_voltages(struct regulator *regulator) { - struct regulator_dev *rdev = regulator->rdev; + struct regulator_dev *rdev; + if (regulator == NULL) + return 0; + rdev = regulator->rdev; return rdev->desc->n_voltages ? : -EINVAL; } EXPORT_SYMBOL_GPL(regulator_count_voltages); @@ -1525,10 +1538,15 @@ EXPORT_SYMBOL_GPL(regulator_count_voltages); */ int regulator_list_voltage(struct regulator *regulator, unsigned selector) { - struct regulator_dev *rdev = regulator->rdev; - struct regulator_ops *ops = rdev->desc->ops; + struct regulator_dev *rdev; + struct regulator_ops *ops; int ret; + if (regulator == NULL) + return 0; + rdev = regulator->rdev; + ops = rdev->desc->ops; + if (!ops->list_voltage || selector >= rdev->desc->n_voltages) return -EINVAL; @@ -1561,6 +1579,8 @@ int regulator_is_supported_voltage(struct regulator *regulator, { int i, voltages, ret; + if (regulator == NULL) + return 0; ret = regulator_count_voltages(regulator); if (ret < 0) return ret; @@ -1596,9 +1616,12 @@ int regulator_is_supported_voltage(struct regulator *regulator, */ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV) { - struct regulator_dev *rdev = regulator->rdev; + struct regulator_dev *rdev; int ret; + if (regulator == NULL) + return 0; + rdev = regulator->rdev; mutex_lock(&rdev->mutex); /* sanity check */ @@ -1644,6 +1667,9 @@ int regulator_get_voltage(struct regulator *regulator) { int ret; + if (regulator == NULL) + return 0; + mutex_lock(®ulator->rdev->mutex); ret = _regulator_get_voltage(regulator->rdev); @@ -1673,9 +1699,13 @@ EXPORT_SYMBOL_GPL(regulator_get_voltage); int regulator_set_current_limit(struct regulator *regulator, int min_uA, int max_uA) { - struct regulator_dev *rdev = regulator->rdev; + struct regulator_dev *rdev; int ret; + if (regulator == NULL) + return 0; + rdev = regulator->rdev; + mutex_lock(&rdev->mutex); /* sanity check */ @@ -1725,6 +1755,8 @@ out: */ int regulator_get_current_limit(struct regulator *regulator) { + if (regulator == NULL) + return 0; return _regulator_get_current_limit(regulator->rdev); } EXPORT_SYMBOL_GPL(regulator_get_current_limit); @@ -1742,10 +1774,14 @@ EXPORT_SYMBOL_GPL(regulator_get_current_limit); */ int regulator_set_mode(struct regulator *regulator, unsigned int mode) { - struct regulator_dev *rdev = regulator->rdev; + struct regulator_dev *rdev; int ret; int regulator_curr_mode; + if (regulator == NULL) + return 0; + rdev = regulator->rdev; + mutex_lock(&rdev->mutex); /* sanity check */ @@ -1801,6 +1837,8 @@ out: */ unsigned int regulator_get_mode(struct regulator *regulator) { + if (regulator == NULL) + return REGULATOR_MODE_NORMAL; return _regulator_get_mode(regulator->rdev); } EXPORT_SYMBOL_GPL(regulator_get_mode); @@ -1833,11 +1871,15 @@ EXPORT_SYMBOL_GPL(regulator_get_mode); */ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) { - struct regulator_dev *rdev = regulator->rdev; + struct regulator_dev *rdev; struct regulator *consumer; int ret, output_uV, input_uV, total_uA_load = 0; unsigned int mode; + if (regulator == NULL) + return REGULATOR_MODE_NORMAL; + rdev = regulator->rdev; + mutex_lock(&rdev->mutex); regulator->uA_load = uA_load; @@ -1907,6 +1949,8 @@ EXPORT_SYMBOL_GPL(regulator_set_optimum_mode); int regulator_register_notifier(struct regulator *regulator, struct notifier_block *nb) { + if (regulator == NULL) + return 0; return blocking_notifier_chain_register(®ulator->rdev->notifier, nb); } @@ -1922,6 +1966,8 @@ EXPORT_SYMBOL_GPL(regulator_register_notifier); int regulator_unregister_notifier(struct regulator *regulator, struct notifier_block *nb) { + if (regulator == NULL) + return 0; return blocking_notifier_chain_unregister(®ulator->rdev->notifier, nb); } -- 1.7.2.3 Yours, Linus Walleij -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html