X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=drivers%2Fregulator%2Fcore.c;h=ace4ecc6d7c23253aa9dff82324d8dde7c302442;hb=c5589c436d4646e0dc23f64264db8e04cf67c88f;hp=e8c00a884f1f13983e794459d3ce051290bd24dc;hpb=cf619f891971bfac659ac64968f8c35db605c884;p=linux-2.6-block.git diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index e8c00a884f1f..ace4ecc6d7c2 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1596,7 +1596,13 @@ static int set_machine_constraints(struct regulator_dev *rdev) if (rdev->supply_name && !rdev->supply) return -EPROBE_DEFER; - if (rdev->supply) { + /* If supplying regulator has already been enabled, + * it's not intended to have use_count increment + * when rdev is only boot-on. + */ + if (rdev->supply && + (rdev->constraints->always_on || + !regulator_is_enabled(rdev->supply))) { ret = regulator_enable(rdev->supply); if (ret < 0) { _regulator_put(rdev->supply); @@ -1640,6 +1646,7 @@ static int set_supply(struct regulator_dev *rdev, rdev->supply = create_regulator(supply_rdev, &rdev->dev, "SUPPLY"); if (rdev->supply == NULL) { + module_put(supply_rdev->owner); err = -ENOMEM; return err; } @@ -1813,7 +1820,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev, regulator = kzalloc(sizeof(*regulator), GFP_KERNEL); if (regulator == NULL) { - kfree(supply_name); + kfree_const(supply_name); return NULL; } @@ -1943,6 +1950,7 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev, node = of_get_regulator(dev, supply); if (node) { r = of_find_regulator_by_node(node); + of_node_put(node); if (r) return r; @@ -4778,22 +4786,8 @@ static int _notifier_call_chain(struct regulator_dev *rdev, return blocking_notifier_call_chain(&rdev->notifier, event, data); } -/** - * regulator_bulk_get - get multiple regulator consumers - * - * @dev: Device to supply - * @num_consumers: Number of consumers to register - * @consumers: Configuration of consumers; clients are stored here. - * - * @return 0 on success, an errno on failure. - * - * This helper function allows drivers to get several regulator - * consumers in one operation. If any of the regulators cannot be - * acquired then any regulators that were allocated will be freed - * before returning to the caller. - */ -int regulator_bulk_get(struct device *dev, int num_consumers, - struct regulator_bulk_data *consumers) +int _regulator_bulk_get(struct device *dev, int num_consumers, + struct regulator_bulk_data *consumers, enum regulator_get_type get_type) { int i; int ret; @@ -4802,8 +4796,8 @@ int regulator_bulk_get(struct device *dev, int num_consumers, consumers[i].consumer = NULL; for (i = 0; i < num_consumers; i++) { - consumers[i].consumer = regulator_get(dev, - consumers[i].supply); + consumers[i].consumer = _regulator_get(dev, + consumers[i].supply, get_type); if (IS_ERR(consumers[i].consumer)) { ret = dev_err_probe(dev, PTR_ERR(consumers[i].consumer), "Failed to get supply '%s'", @@ -4830,6 +4824,26 @@ err: return ret; } + +/** + * regulator_bulk_get - get multiple regulator consumers + * + * @dev: Device to supply + * @num_consumers: Number of consumers to register + * @consumers: Configuration of consumers; clients are stored here. + * + * @return 0 on success, an errno on failure. + * + * This helper function allows drivers to get several regulator + * consumers in one operation. If any of the regulators cannot be + * acquired then any regulators that were allocated will be freed + * before returning to the caller. + */ +int regulator_bulk_get(struct device *dev, int num_consumers, + struct regulator_bulk_data *consumers) +{ + return _regulator_bulk_get(dev, num_consumers, consumers, NORMAL_GET); +} EXPORT_SYMBOL_GPL(regulator_bulk_get); static void regulator_bulk_enable_async(void *data, async_cookie_t cookie) @@ -5396,6 +5410,7 @@ static struct regulator_coupler generic_regulator_coupler = { /** * regulator_register - register regulator + * @dev: the device that drive the regulator * @regulator_desc: regulator to register * @cfg: runtime configuration for regulator * @@ -5404,7 +5419,8 @@ static struct regulator_coupler generic_regulator_coupler = { * or an ERR_PTR() on error. */ struct regulator_dev * -regulator_register(const struct regulator_desc *regulator_desc, +regulator_register(struct device *dev, + const struct regulator_desc *regulator_desc, const struct regulator_config *cfg) { const struct regulator_init_data *init_data; @@ -5413,7 +5429,6 @@ regulator_register(const struct regulator_desc *regulator_desc, struct regulator_dev *rdev; bool dangling_cfg_gpiod = false; bool dangling_of_gpiod = false; - struct device *dev; int ret, i; bool resolved_early = false; @@ -5426,8 +5441,7 @@ regulator_register(const struct regulator_desc *regulator_desc, goto rinse; } - dev = cfg->dev; - WARN_ON(!dev); + WARN_ON(!dev || !cfg->dev); if (regulator_desc->name == NULL || regulator_desc->ops == NULL) { ret = -EINVAL; @@ -5641,6 +5655,7 @@ unset_supplies: regulator_remove_coupling(rdev); mutex_unlock(®ulator_list_mutex); wash: + regulator_put(rdev->supply); kfree(rdev->coupling_desc.coupled_rdevs); mutex_lock(®ulator_list_mutex); regulator_ena_gpio_free(rdev);