X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=drivers%2Fregulator%2Fcore.c;h=d5f84c1b258b38e8d095934bcac5c6d05b013488;hb=1f9cc5f7716d664bfe32289ca61327be01a0a8e3;hp=5c4829cba6a62de6168c6bb3c4913812e5e8b4e1;hpb=18a022de47bc11ee20d7d0f4dd72d42d2cfdc51c;p=deliverable%2Flinux.git diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 5c4829cba6a6..d5f84c1b258b 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1381,22 +1381,14 @@ struct regulator *regulator_get_exclusive(struct device *dev, const char *id) } EXPORT_SYMBOL_GPL(regulator_get_exclusive); -/** - * regulator_put - "free" the regulator source - * @regulator: regulator source - * - * Note: drivers must ensure that all regulator_enable calls made on this - * regulator source are balanced by regulator_disable calls prior to calling - * this function. - */ -void regulator_put(struct regulator *regulator) +/* Locks held by regulator_put() */ +static void _regulator_put(struct regulator *regulator) { struct regulator_dev *rdev; if (regulator == NULL || IS_ERR(regulator)) return; - mutex_lock(®ulator_list_mutex); rdev = regulator->rdev; debugfs_remove_recursive(regulator->debugfs); @@ -1412,6 +1404,20 @@ void regulator_put(struct regulator *regulator) rdev->exclusive = 0; module_put(rdev->owner); +} + +/** + * regulator_put - "free" the regulator source + * @regulator: regulator source + * + * Note: drivers must ensure that all regulator_enable calls made on this + * regulator source are balanced by regulator_disable calls prior to calling + * this function. + */ +void regulator_put(struct regulator *regulator) +{ + mutex_lock(®ulator_list_mutex); + _regulator_put(regulator); mutex_unlock(®ulator_list_mutex); } EXPORT_SYMBOL_GPL(regulator_put); @@ -1860,6 +1866,28 @@ int regulator_is_enabled(struct regulator *regulator) } EXPORT_SYMBOL_GPL(regulator_is_enabled); +/** + * regulator_can_change_voltage - check if regulator can change voltage + * @regulator: regulator source + * + * Returns positive if the regulator driver backing the source/client + * can change its voltage, false otherwise. Usefull for detecting fixed + * or dummy regulators and disabling voltage change logic in the client + * driver. + */ +int regulator_can_change_voltage(struct regulator *regulator) +{ + struct regulator_dev *rdev = regulator->rdev; + + if (rdev->constraints && + rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE && + rdev->desc->n_voltages > 1) + return 1; + + return 0; +} +EXPORT_SYMBOL_GPL(regulator_can_change_voltage); + /** * regulator_count_voltages - count regulator_list_voltage() selectors * @regulator: regulator source @@ -1974,11 +2002,16 @@ int regulator_is_supported_voltage(struct regulator *regulator, if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) { ret = regulator_get_voltage(regulator); if (ret >= 0) - return (min_uV >= ret && ret <= max_uV); + return (min_uV <= ret && ret <= max_uV); else return ret; } + /* Any voltage within constrains range is fine? */ + if (rdev->desc->continuous_voltage_range) + return min_uV >= rdev->constraints->min_uV && + max_uV <= rdev->constraints->max_uV; + ret = regulator_count_voltages(regulator); if (ret < 0) return ret; @@ -3365,7 +3398,7 @@ regulator_register(const struct regulator_desc *regulator_desc, if (ret != 0) { rdev_err(rdev, "Failed to request enable GPIO%d: %d\n", config->ena_gpio, ret); - goto clean; + goto wash; } rdev->ena_gpio = config->ena_gpio; @@ -3445,10 +3478,11 @@ unset_supplies: scrub: if (rdev->supply) - regulator_put(rdev->supply); + _regulator_put(rdev->supply); if (rdev->ena_gpio) gpio_free(rdev->ena_gpio); kfree(rdev->constraints); +wash: device_unregister(&rdev->dev); /* device core frees rdev */ rdev = ERR_PTR(ret);