diff options
Diffstat (limited to 'drivers/regulator/core.c')
| -rw-r--r-- | drivers/regulator/core.c | 461 | 
1 files changed, 345 insertions, 116 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index e70dd382a00..7584a74eec8 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -24,6 +24,7 @@  #include <linux/suspend.h>  #include <linux/delay.h>  #include <linux/of.h> +#include <linux/regmap.h>  #include <linux/regulator/of_regulator.h>  #include <linux/regulator/consumer.h>  #include <linux/regulator/driver.h> @@ -74,6 +75,7 @@ struct regulator_map {  struct regulator {  	struct device *dev;  	struct list_head list; +	unsigned int always_on:1;  	int uA_load;  	int min_uV;  	int max_uV; @@ -155,6 +157,17 @@ static struct device_node *of_get_regulator(struct device *dev, const char *supp  	return regnode;  } +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; +} +  /* Platform voltage constraint check */  static int regulator_check_voltage(struct regulator_dev *rdev,  				   int *min_uV, int *max_uV) @@ -649,7 +662,7 @@ static void drms_uA_update(struct regulator_dev *rdev)  	/* get input voltage */  	input_uV = 0;  	if (rdev->supply) -		input_uV = _regulator_get_voltage(rdev); +		input_uV = regulator_get_voltage(rdev->supply);  	if (input_uV <= 0)  		input_uV = rdev->constraints->input_uV;  	if (input_uV <= 0) @@ -673,17 +686,14 @@ static int suspend_set_state(struct regulator_dev *rdev,  	struct regulator_state *rstate)  {  	int ret = 0; -	bool can_set_state; - -	can_set_state = rdev->desc->ops->set_suspend_enable && -		rdev->desc->ops->set_suspend_disable;  	/* If we have no suspend mode configration don't set anything; -	 * only warn if the driver actually makes the suspend mode -	 * configurable. +	 * only warn if the driver implements set_suspend_voltage or +	 * set_suspend_mode callback.  	 */  	if (!rstate->enabled && !rstate->disabled) { -		if (can_set_state) +		if (rdev->desc->ops->set_suspend_voltage || +		    rdev->desc->ops->set_suspend_mode)  			rdev_warn(rdev, "No configuration\n");  		return 0;  	} @@ -693,15 +703,13 @@ static int suspend_set_state(struct regulator_dev *rdev,  		return -EINVAL;  	} -	if (!can_set_state) { -		rdev_err(rdev, "no way to set suspend state\n"); -		return -EINVAL; -	} - -	if (rstate->enabled) +	if (rstate->enabled && rdev->desc->ops->set_suspend_enable)  		ret = rdev->desc->ops->set_suspend_enable(rdev); -	else +	else if (rstate->disabled && rdev->desc->ops->set_suspend_disable)  		ret = rdev->desc->ops->set_suspend_disable(rdev); +	else /* OK if set_suspend_enable or set_suspend_disable is NULL */ +		ret = 0; +  	if (ret < 0) {  		rdev_err(rdev, "failed to enabled/disable\n");  		return ret; @@ -1146,6 +1154,15 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,  				   ®ulator->max_uV);  	} +	/* +	 * Check now if the regulator is an always on regulator - if +	 * it is then we don't need to do nearly so much work for +	 * enable/disable calls. +	 */ +	if (!_regulator_can_change_status(rdev) && +	    _regulator_is_enabled(rdev)) +		regulator->always_on = true; +  	mutex_unlock(&rdev->mutex);  	return regulator;  link_name_err: @@ -1169,26 +1186,52 @@ static int _regulator_get_enable_time(struct regulator_dev *rdev)  }  static struct regulator_dev *regulator_dev_lookup(struct device *dev, -							 const char *supply) +						  const char *supply, +						  int *ret)  {  	struct regulator_dev *r;  	struct device_node *node; +	struct regulator_map *map; +	const char *devname = NULL;  	/* first do a dt based lookup */  	if (dev && dev->of_node) {  		node = of_get_regulator(dev, supply); -		if (node) +		if (node) {  			list_for_each_entry(r, ®ulator_list, list)  				if (r->dev.parent &&  					node == r->dev.of_node)  					return r; +		} else { +			/* +			 * If we couldn't even get the node then it's +			 * not just that the device didn't register +			 * yet, there's no node and we'll never +			 * succeed. +			 */ +			*ret = -ENODEV; +		}  	}  	/* if not found, try doing it non-dt way */ +	if (dev) +		devname = dev_name(dev); +  	list_for_each_entry(r, ®ulator_list, list)  		if (strcmp(rdev_get_name(r), supply) == 0)  			return r; +	list_for_each_entry(map, ®ulator_map_list, list) { +		/* 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, supply) == 0) +			return map->regulator; +	} + +  	return NULL;  } @@ -1197,7 +1240,6 @@ 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(-EPROBE_DEFER);  	const char *devname = NULL;  	int ret; @@ -1212,22 +1254,10 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,  	mutex_lock(®ulator_list_mutex); -	rdev = regulator_dev_lookup(dev, id); +	rdev = regulator_dev_lookup(dev, id, &ret);  	if (rdev)  		goto found; -	list_for_each_entry(map, ®ulator_map_list, list) { -		/* 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; -		} -	} -  	if (board_wants_dummy_regulator) {  		rdev = dummy_regulator_rdev;  		goto found; @@ -1431,20 +1461,12 @@ void devm_regulator_put(struct regulator *regulator)  	rc = devres_destroy(regulator->dev, devm_regulator_release,  			    devm_regulator_match, regulator); -	WARN_ON(rc); -} -EXPORT_SYMBOL_GPL(devm_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; +	if (rc == 0) +		regulator_put(regulator);  	else -		return 0; +		WARN_ON(rc);  } +EXPORT_SYMBOL_GPL(devm_regulator_put);  /* locks held by regulator_enable() */  static int _regulator_enable(struct regulator_dev *rdev) @@ -1525,6 +1547,9 @@ int regulator_enable(struct regulator *regulator)  	struct regulator_dev *rdev = regulator->rdev;  	int ret = 0; +	if (regulator->always_on) +		return 0; +  	if (rdev->supply) {  		ret = regulator_enable(rdev->supply);  		if (ret != 0) @@ -1603,6 +1628,9 @@ int regulator_disable(struct regulator *regulator)  	struct regulator_dev *rdev = regulator->rdev;  	int ret = 0; +	if (regulator->always_on) +		return 0; +  	mutex_lock(&rdev->mutex);  	ret = _regulator_disable(rdev);  	mutex_unlock(&rdev->mutex); @@ -1711,6 +1739,9 @@ int regulator_disable_deferred(struct regulator *regulator, int ms)  	struct regulator_dev *rdev = regulator->rdev;  	int ret; +	if (regulator->always_on) +		return 0; +  	mutex_lock(&rdev->mutex);  	rdev->deferred_disables++;  	mutex_unlock(&rdev->mutex); @@ -1724,6 +1755,61 @@ int regulator_disable_deferred(struct regulator *regulator, int ms)  }  EXPORT_SYMBOL_GPL(regulator_disable_deferred); +/** + * regulator_is_enabled_regmap - standard is_enabled() for regmap users + * + * @rdev: regulator to operate on + * + * Regulators that use regmap for their register I/O can set the + * enable_reg and enable_mask fields in their descriptor and then use + * this as their is_enabled operation, saving some code. + */ +int regulator_is_enabled_regmap(struct regulator_dev *rdev) +{ +	unsigned int val; +	int ret; + +	ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val); +	if (ret != 0) +		return ret; + +	return (val & rdev->desc->enable_mask) != 0; +} +EXPORT_SYMBOL_GPL(regulator_is_enabled_regmap); + +/** + * regulator_enable_regmap - standard enable() for regmap users + * + * @rdev: regulator to operate on + * + * Regulators that use regmap for their register I/O can set the + * enable_reg and enable_mask fields in their descriptor and then use + * this as their enable() operation, saving some code. + */ +int regulator_enable_regmap(struct regulator_dev *rdev) +{ +	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, +				  rdev->desc->enable_mask, +				  rdev->desc->enable_mask); +} +EXPORT_SYMBOL_GPL(regulator_enable_regmap); + +/** + * regulator_disable_regmap - standard disable() for regmap users + * + * @rdev: regulator to operate on + * + * Regulators that use regmap for their register I/O can set the + * enable_reg and enable_mask fields in their descriptor and then use + * this as their disable() operation, saving some code. + */ +int regulator_disable_regmap(struct regulator_dev *rdev) +{ +	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, +				  rdev->desc->enable_mask, 0); +} +EXPORT_SYMBOL_GPL(regulator_disable_regmap); +  static int _regulator_is_enabled(struct regulator_dev *rdev)  {  	/* If we don't know then assume that the regulator is always on */ @@ -1749,6 +1835,9 @@ int regulator_is_enabled(struct regulator *regulator)  {  	int ret; +	if (regulator->always_on) +		return 1; +  	mutex_lock(®ulator->rdev->mutex);  	ret = _regulator_is_enabled(regulator->rdev);  	mutex_unlock(®ulator->rdev->mutex); @@ -1774,6 +1863,26 @@ int regulator_count_voltages(struct regulator *regulator)  EXPORT_SYMBOL_GPL(regulator_count_voltages);  /** + * regulator_list_voltage_linear - List voltages with simple calculation + * + * @rdev: Regulator device + * @selector: Selector to convert into a voltage + * + * Regulators with a simple linear mapping between voltages and + * selectors can set min_uV and uV_step in the regulator descriptor + * and then use this function as their list_voltage() operation, + */ +int regulator_list_voltage_linear(struct regulator_dev *rdev, +				  unsigned int selector) +{ +	if (selector >= rdev->desc->n_voltages) +		return -EINVAL; + +	return rdev->desc->min_uV + (rdev->desc->uV_step * selector); +} +EXPORT_SYMBOL_GPL(regulator_list_voltage_linear); + +/**   * regulator_list_voltage - enumerate supported voltages   * @regulator: regulator source   * @selector: identify voltage to list @@ -1837,75 +1946,183 @@ int regulator_is_supported_voltage(struct regulator *regulator,  }  EXPORT_SYMBOL_GPL(regulator_is_supported_voltage); +/** + * regulator_get_voltage_sel_regmap - standard get_voltage_sel for regmap users + * + * @rdev: regulator to operate on + * + * Regulators that use regmap for their register I/O can set the + * vsel_reg and vsel_mask fields in their descriptor and then use this + * as their get_voltage_vsel operation, saving some code. + */ +int regulator_get_voltage_sel_regmap(struct regulator_dev *rdev) +{ +	unsigned int val; +	int ret; + +	ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val); +	if (ret != 0) +		return ret; + +	val &= rdev->desc->vsel_mask; +	val >>= ffs(rdev->desc->vsel_mask) - 1; + +	return val; +} +EXPORT_SYMBOL_GPL(regulator_get_voltage_sel_regmap); + +/** + * regulator_set_voltage_sel_regmap - standard set_voltage_sel for regmap users + * + * @rdev: regulator to operate on + * @sel: Selector to set + * + * Regulators that use regmap for their register I/O can set the + * vsel_reg and vsel_mask fields in their descriptor and then use this + * as their set_voltage_vsel operation, saving some code. + */ +int regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel) +{ +	sel <<= ffs(rdev->desc->vsel_mask) - 1; + +	return regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg, +				  rdev->desc->vsel_mask, sel); +} +EXPORT_SYMBOL_GPL(regulator_set_voltage_sel_regmap); + +/** + * regulator_map_voltage_iterate - map_voltage() based on list_voltage() + * + * @rdev: Regulator to operate on + * @min_uV: Lower bound for voltage + * @max_uV: Upper bound for voltage + * + * Drivers implementing set_voltage_sel() and list_voltage() can use + * this as their map_voltage() operation.  It will find a suitable + * voltage by calling list_voltage() until it gets something in bounds + * for the requested voltages. + */ +int regulator_map_voltage_iterate(struct regulator_dev *rdev, +				  int min_uV, int max_uV) +{ +	int best_val = INT_MAX; +	int selector = 0; +	int i, ret; + +	/* Find the smallest voltage that falls within the specified +	 * range. +	 */ +	for (i = 0; i < rdev->desc->n_voltages; i++) { +		ret = rdev->desc->ops->list_voltage(rdev, i); +		if (ret < 0) +			continue; + +		if (ret < best_val && ret >= min_uV && ret <= max_uV) { +			best_val = ret; +			selector = i; +		} +	} + +	if (best_val != INT_MAX) +		return selector; +	else +		return -EINVAL; +} +EXPORT_SYMBOL_GPL(regulator_map_voltage_iterate); + +/** + * regulator_map_voltage_linear - map_voltage() for simple linear mappings + * + * @rdev: Regulator to operate on + * @min_uV: Lower bound for voltage + * @max_uV: Upper bound for voltage + * + * Drivers providing min_uV and uV_step in their regulator_desc can + * use this as their map_voltage() operation. + */ +int regulator_map_voltage_linear(struct regulator_dev *rdev, +				 int min_uV, int max_uV) +{ +	int ret, voltage; + +	if (!rdev->desc->uV_step) { +		BUG_ON(!rdev->desc->uV_step); +		return -EINVAL; +	} + +	ret = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step); +	if (ret < 0) +		return ret; + +	/* Map back into a voltage to verify we're still in bounds */ +	voltage = rdev->desc->ops->list_voltage(rdev, ret); +	if (voltage < min_uV || voltage > max_uV) +		return -EINVAL; + +	return ret; +} +EXPORT_SYMBOL_GPL(regulator_map_voltage_linear); +  static int _regulator_do_set_voltage(struct regulator_dev *rdev,  				     int min_uV, int max_uV)  {  	int ret;  	int delay = 0; +	int best_val;  	unsigned int selector; +	int old_selector = -1;  	trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV);  	min_uV += rdev->constraints->uV_offset;  	max_uV += rdev->constraints->uV_offset; +	/* +	 * If we can't obtain the old selector there is not enough +	 * info to call set_voltage_time_sel(). +	 */ +	if (rdev->desc->ops->set_voltage_time_sel && +	    rdev->desc->ops->get_voltage_sel) { +		old_selector = rdev->desc->ops->get_voltage_sel(rdev); +		if (old_selector < 0) +			return old_selector; +	} +  	if (rdev->desc->ops->set_voltage) {  		ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV,  						   &selector); - -		if (rdev->desc->ops->list_voltage) -			selector = rdev->desc->ops->list_voltage(rdev, -								 selector); -		else -			selector = -1;  	} else if (rdev->desc->ops->set_voltage_sel) { -		int best_val = INT_MAX; -		int i; - -		selector = 0; - -		/* Find the smallest voltage that falls within the specified -		 * range. -		 */ -		for (i = 0; i < rdev->desc->n_voltages; i++) { -			ret = rdev->desc->ops->list_voltage(rdev, i); -			if (ret < 0) -				continue; +		if (rdev->desc->ops->map_voltage) +			ret = rdev->desc->ops->map_voltage(rdev, min_uV, +							   max_uV); +		else +			ret = regulator_map_voltage_iterate(rdev, min_uV, +							    max_uV); -			if (ret < best_val && ret >= min_uV && ret <= max_uV) { -				best_val = ret; -				selector = i; -			} +		if (ret >= 0) { +			selector = ret; +			ret = rdev->desc->ops->set_voltage_sel(rdev, ret);  		} +	} else { +		ret = -EINVAL; +	} -		/* -		 * If we can't obtain the old selector there is not enough -		 * info to call set_voltage_time_sel(). -		 */ -		if (rdev->desc->ops->set_voltage_time_sel && -		    rdev->desc->ops->get_voltage_sel) { -			unsigned int old_selector = 0; +	if (rdev->desc->ops->list_voltage) +		best_val = rdev->desc->ops->list_voltage(rdev, selector); +	else +		best_val = -1; -			ret = rdev->desc->ops->get_voltage_sel(rdev); -			if (ret < 0) -				return ret; -			old_selector = ret; -			ret = rdev->desc->ops->set_voltage_time_sel(rdev, -						old_selector, selector); -			if (ret < 0) -				rdev_warn(rdev, "set_voltage_time_sel() failed: %d\n", ret); -			else -				delay = ret; -		} +	/* Call set_voltage_time_sel if successfully obtained old_selector */ +	if (ret == 0 && old_selector >= 0 && +	    rdev->desc->ops->set_voltage_time_sel) { -		if (best_val != INT_MAX) { -			ret = rdev->desc->ops->set_voltage_sel(rdev, selector); -			selector = best_val; -		} else { -			ret = -EINVAL; +		delay = rdev->desc->ops->set_voltage_time_sel(rdev, +						old_selector, selector); +		if (delay < 0) { +			rdev_warn(rdev, "set_voltage_time_sel() failed: %d\n", +				  delay); +			delay = 0;  		} -	} else { -		ret = -EINVAL;  	}  	/* Insert any necessary delays */ @@ -1920,7 +2137,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,  		_notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE,  				     NULL); -	trace_regulator_set_voltage_complete(rdev_get_name(rdev), selector); +	trace_regulator_set_voltage_complete(rdev_get_name(rdev), best_val);  	return ret;  } @@ -2324,6 +2541,9 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load)  	 */  	ret = -EINVAL; +	if (!rdev->desc->ops->set_mode) +		goto out; +  	/* get output voltage */  	output_uV = _regulator_get_voltage(rdev);  	if (output_uV <= 0) { @@ -2525,9 +2745,13 @@ int regulator_bulk_enable(int num_consumers,  	int i;  	int ret = 0; -	for (i = 0; i < num_consumers; i++) -		async_schedule_domain(regulator_bulk_enable_async, -				      &consumers[i], &async_domain); +	for (i = 0; i < num_consumers; i++) { +		if (consumers[i].consumer->always_on) +			consumers[i].ret = 0; +		else +			async_schedule_domain(regulator_bulk_enable_async, +					      &consumers[i], &async_domain); +	}  	async_synchronize_full_domain(&async_domain); @@ -2566,7 +2790,7 @@ int regulator_bulk_disable(int num_consumers,  			   struct regulator_bulk_data *consumers)  {  	int i; -	int ret; +	int ret, r;  	for (i = num_consumers - 1; i >= 0; --i) {  		ret = regulator_disable(consumers[i].consumer); @@ -2578,8 +2802,12 @@ int regulator_bulk_disable(int num_consumers,  err:  	pr_err("Failed to disable %s: %d\n", consumers[i].supply, ret); -	for (++i; i < num_consumers; ++i) -		regulator_enable(consumers[i].consumer); +	for (++i; i < num_consumers; ++i) { +		r = regulator_enable(consumers[i].consumer); +		if (r != 0) +			pr_err("Failed to reename %s: %d\n", +			       consumers[i].supply, r); +	}  	return ret;  } @@ -2756,10 +2984,6 @@ static int add_regulator_attributes(struct regulator_dev *rdev)  			return status;  	} -	/* suspend mode constraints need multiple supporting methods */ -	if (!(ops->set_suspend_enable && ops->set_suspend_disable)) -		return status; -  	status = device_create_file(dev, &dev_attr_suspend_standby_state);  	if (status < 0)  		return status; @@ -2820,28 +3044,29 @@ static void rdev_init_debugfs(struct regulator_dev *rdev)  /**   * regulator_register - register regulator   * @regulator_desc: regulator to register - * @dev: struct device for the regulator - * @init_data: platform provided init data, passed through by driver - * @driver_data: private regulator data - * @of_node: OpenFirmware node to parse for device tree bindings (may be - *           NULL). + * @config: runtime configuration for regulator   *   * Called by regulator drivers to register a regulator.   * Returns 0 on success.   */ -struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, -	struct device *dev, const struct regulator_init_data *init_data, -	void *driver_data, struct device_node *of_node) +struct regulator_dev * +regulator_register(const struct regulator_desc *regulator_desc, +		   const struct regulator_config *config)  {  	const struct regulation_constraints *constraints = NULL; +	const struct regulator_init_data *init_data;  	static atomic_t regulator_no = ATOMIC_INIT(0);  	struct regulator_dev *rdev; +	struct device *dev;  	int ret, i;  	const char *supply = NULL; -	if (regulator_desc == NULL) +	if (regulator_desc == NULL || config == NULL)  		return ERR_PTR(-EINVAL); +	dev = config->dev; +	WARN_ON(!dev); +  	if (regulator_desc->name == NULL || regulator_desc->ops == NULL)  		return ERR_PTR(-EINVAL); @@ -2865,6 +3090,8 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,  		return ERR_PTR(-EINVAL);  	} +	init_data = config->init_data; +  	rdev = kzalloc(sizeof(struct regulator_dev), GFP_KERNEL);  	if (rdev == NULL)  		return ERR_PTR(-ENOMEM); @@ -2872,9 +3099,10 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,  	mutex_lock(®ulator_list_mutex);  	mutex_init(&rdev->mutex); -	rdev->reg_data = driver_data; +	rdev->reg_data = config->driver_data;  	rdev->owner = regulator_desc->owner;  	rdev->desc = regulator_desc; +	rdev->regmap = config->regmap;  	INIT_LIST_HEAD(&rdev->consumer_list);  	INIT_LIST_HEAD(&rdev->list);  	BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier); @@ -2889,7 +3117,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,  	/* register with sysfs */  	rdev->dev.class = ®ulator_class; -	rdev->dev.of_node = of_node; +	rdev->dev.of_node = config->of_node;  	rdev->dev.parent = dev;  	dev_set_name(&rdev->dev, "regulator.%d",  		     atomic_inc_return(®ulator_no) - 1); @@ -2922,7 +3150,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,  	if (supply) {  		struct regulator_dev *r; -		r = regulator_dev_lookup(dev, supply); +		r = regulator_dev_lookup(dev, supply, &ret);  		if (!r) {  			dev_err(dev, "Failed to find supply %s\n", supply); @@ -2935,8 +3163,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,  			goto scrub;  		/* Enable supply if rail is enabled */ -		if (rdev->desc->ops->is_enabled && -				rdev->desc->ops->is_enabled(rdev)) { +		if (_regulator_is_enabled(rdev)) {  			ret = regulator_enable(rdev->supply);  			if (ret < 0)  				goto scrub; @@ -2968,6 +3195,8 @@ unset_supplies:  	unset_regulator_supplies(rdev);  scrub: +	if (rdev->supply) +		regulator_put(rdev->supply);  	kfree(rdev->constraints);  	device_unregister(&rdev->dev);  	/* device core frees rdev */ @@ -3066,7 +3295,7 @@ int regulator_suspend_finish(void)  				goto unlock;  			if (!ops->disable)  				goto unlock; -			if (ops->is_enabled && !ops->is_enabled(rdev)) +			if (!_regulator_is_enabled(rdev))  				goto unlock;  			error = ops->disable(rdev);  |