xref: /openbmc/linux/drivers/regulator/core.c (revision 215b8b05)
1414c70cbSLiam Girdwood /*
2414c70cbSLiam Girdwood  * core.c  --  Voltage/Current Regulator framework.
3414c70cbSLiam Girdwood  *
4414c70cbSLiam Girdwood  * Copyright 2007, 2008 Wolfson Microelectronics PLC.
5a5766f11SLiam Girdwood  * Copyright 2008 SlimLogic Ltd.
6414c70cbSLiam Girdwood  *
7a5766f11SLiam Girdwood  * Author: Liam Girdwood <lrg@slimlogic.co.uk>
8414c70cbSLiam Girdwood  *
9414c70cbSLiam Girdwood  *  This program is free software; you can redistribute  it and/or modify it
10414c70cbSLiam Girdwood  *  under  the terms of  the GNU General  Public License as published by the
11414c70cbSLiam Girdwood  *  Free Software Foundation;  either version 2 of the  License, or (at your
12414c70cbSLiam Girdwood  *  option) any later version.
13414c70cbSLiam Girdwood  *
14414c70cbSLiam Girdwood  */
15414c70cbSLiam Girdwood 
16414c70cbSLiam Girdwood #include <linux/kernel.h>
17414c70cbSLiam Girdwood #include <linux/init.h>
181130e5b3SMark Brown #include <linux/debugfs.h>
19414c70cbSLiam Girdwood #include <linux/device.h>
205a0e3ad6STejun Heo #include <linux/slab.h>
21f21e0e81SMark Brown #include <linux/async.h>
22414c70cbSLiam Girdwood #include <linux/err.h>
23414c70cbSLiam Girdwood #include <linux/mutex.h>
24414c70cbSLiam Girdwood #include <linux/suspend.h>
2531aae2beSMark Brown #include <linux/delay.h>
2665f73508SMark Brown #include <linux/gpio.h>
2769511a45SRajendra Nayak #include <linux/of.h>
2865b19ce6SMark Brown #include <linux/regmap.h>
2969511a45SRajendra Nayak #include <linux/regulator/of_regulator.h>
30414c70cbSLiam Girdwood #include <linux/regulator/consumer.h>
31414c70cbSLiam Girdwood #include <linux/regulator/driver.h>
32414c70cbSLiam Girdwood #include <linux/regulator/machine.h>
3365602c32SPaul Gortmaker #include <linux/module.h>
34414c70cbSLiam Girdwood 
3502fa3ec0SMark Brown #define CREATE_TRACE_POINTS
3602fa3ec0SMark Brown #include <trace/events/regulator.h>
3702fa3ec0SMark Brown 
3834abbd68SMark Brown #include "dummy.h"
3934abbd68SMark Brown 
407d51a0dbSMark Brown #define rdev_crit(rdev, fmt, ...)					\
417d51a0dbSMark Brown 	pr_crit("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
425da84fd9SJoe Perches #define rdev_err(rdev, fmt, ...)					\
435da84fd9SJoe Perches 	pr_err("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
445da84fd9SJoe Perches #define rdev_warn(rdev, fmt, ...)					\
455da84fd9SJoe Perches 	pr_warn("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
465da84fd9SJoe Perches #define rdev_info(rdev, fmt, ...)					\
475da84fd9SJoe Perches 	pr_info("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
485da84fd9SJoe Perches #define rdev_dbg(rdev, fmt, ...)					\
495da84fd9SJoe Perches 	pr_debug("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
505da84fd9SJoe Perches 
51414c70cbSLiam Girdwood static DEFINE_MUTEX(regulator_list_mutex);
52414c70cbSLiam Girdwood static LIST_HEAD(regulator_list);
53414c70cbSLiam Girdwood static LIST_HEAD(regulator_map_list);
5421cf891aSMark Brown static bool has_full_constraints;
55688fe99aSMark Brown static bool board_wants_dummy_regulator;
56414c70cbSLiam Girdwood 
571130e5b3SMark Brown static struct dentry *debugfs_root;
581130e5b3SMark Brown 
598dc5390dSMark Brown /*
60414c70cbSLiam Girdwood  * struct regulator_map
61414c70cbSLiam Girdwood  *
62414c70cbSLiam Girdwood  * Used to provide symbolic supply names to devices.
63414c70cbSLiam Girdwood  */
64414c70cbSLiam Girdwood struct regulator_map {
65414c70cbSLiam Girdwood 	struct list_head list;
6640f9244fSMark Brown 	const char *dev_name;   /* The dev_name() for the consumer */
67414c70cbSLiam Girdwood 	const char *supply;
68a5766f11SLiam Girdwood 	struct regulator_dev *regulator;
69414c70cbSLiam Girdwood };
70414c70cbSLiam Girdwood 
71414c70cbSLiam Girdwood /*
72414c70cbSLiam Girdwood  * struct regulator
73414c70cbSLiam Girdwood  *
74414c70cbSLiam Girdwood  * One for each consumer device.
75414c70cbSLiam Girdwood  */
76414c70cbSLiam Girdwood struct regulator {
77414c70cbSLiam Girdwood 	struct device *dev;
78414c70cbSLiam Girdwood 	struct list_head list;
796492bc1bSMark Brown 	unsigned int always_on:1;
80414c70cbSLiam Girdwood 	int uA_load;
81414c70cbSLiam Girdwood 	int min_uV;
82414c70cbSLiam Girdwood 	int max_uV;
83414c70cbSLiam Girdwood 	char *supply_name;
84414c70cbSLiam Girdwood 	struct device_attribute dev_attr;
85414c70cbSLiam Girdwood 	struct regulator_dev *rdev;
865de70519SMark Brown 	struct dentry *debugfs;
87414c70cbSLiam Girdwood };
88414c70cbSLiam Girdwood 
89414c70cbSLiam Girdwood static int _regulator_is_enabled(struct regulator_dev *rdev);
903801b86aSMark Brown static int _regulator_disable(struct regulator_dev *rdev);
91414c70cbSLiam Girdwood static int _regulator_get_voltage(struct regulator_dev *rdev);
92414c70cbSLiam Girdwood static int _regulator_get_current_limit(struct regulator_dev *rdev);
93414c70cbSLiam Girdwood static unsigned int _regulator_get_mode(struct regulator_dev *rdev);
94414c70cbSLiam Girdwood static void _notifier_call_chain(struct regulator_dev *rdev,
95414c70cbSLiam Girdwood 				  unsigned long event, void *data);
9675790251SMark Brown static int _regulator_do_set_voltage(struct regulator_dev *rdev,
9775790251SMark Brown 				     int min_uV, int max_uV);
983801b86aSMark Brown static struct regulator *create_regulator(struct regulator_dev *rdev,
993801b86aSMark Brown 					  struct device *dev,
1003801b86aSMark Brown 					  const char *supply_name);
101414c70cbSLiam Girdwood 
1021083c393SMark Brown static const char *rdev_get_name(struct regulator_dev *rdev)
1031083c393SMark Brown {
1041083c393SMark Brown 	if (rdev->constraints && rdev->constraints->name)
1051083c393SMark Brown 		return rdev->constraints->name;
1061083c393SMark Brown 	else if (rdev->desc->name)
1071083c393SMark Brown 		return rdev->desc->name;
1081083c393SMark Brown 	else
1091083c393SMark Brown 		return "";
1101083c393SMark Brown }
1111083c393SMark Brown 
11269511a45SRajendra Nayak /**
11369511a45SRajendra Nayak  * of_get_regulator - get a regulator device node based on supply name
11469511a45SRajendra Nayak  * @dev: Device pointer for the consumer (of regulator) device
11569511a45SRajendra Nayak  * @supply: regulator supply name
11669511a45SRajendra Nayak  *
11769511a45SRajendra Nayak  * Extract the regulator device node corresponding to the supply name.
11869511a45SRajendra Nayak  * retruns the device node corresponding to the regulator if found, else
11969511a45SRajendra Nayak  * returns NULL.
12069511a45SRajendra Nayak  */
12169511a45SRajendra Nayak static struct device_node *of_get_regulator(struct device *dev, const char *supply)
12269511a45SRajendra Nayak {
12369511a45SRajendra Nayak 	struct device_node *regnode = NULL;
12469511a45SRajendra Nayak 	char prop_name[32]; /* 32 is max size of property name */
12569511a45SRajendra Nayak 
12669511a45SRajendra Nayak 	dev_dbg(dev, "Looking up %s-supply from device tree\n", supply);
12769511a45SRajendra Nayak 
12869511a45SRajendra Nayak 	snprintf(prop_name, 32, "%s-supply", supply);
12969511a45SRajendra Nayak 	regnode = of_parse_phandle(dev->of_node, prop_name, 0);
13069511a45SRajendra Nayak 
13169511a45SRajendra Nayak 	if (!regnode) {
13216fbcc3bSRajendra Nayak 		dev_dbg(dev, "Looking up %s property in node %s failed",
13369511a45SRajendra Nayak 				prop_name, dev->of_node->full_name);
13469511a45SRajendra Nayak 		return NULL;
13569511a45SRajendra Nayak 	}
13669511a45SRajendra Nayak 	return regnode;
13769511a45SRajendra Nayak }
13869511a45SRajendra Nayak 
1396492bc1bSMark Brown static int _regulator_can_change_status(struct regulator_dev *rdev)
1406492bc1bSMark Brown {
1416492bc1bSMark Brown 	if (!rdev->constraints)
1426492bc1bSMark Brown 		return 0;
1436492bc1bSMark Brown 
1446492bc1bSMark Brown 	if (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_STATUS)
1456492bc1bSMark Brown 		return 1;
1466492bc1bSMark Brown 	else
1476492bc1bSMark Brown 		return 0;
1486492bc1bSMark Brown }
1496492bc1bSMark Brown 
150414c70cbSLiam Girdwood /* Platform voltage constraint check */
151414c70cbSLiam Girdwood static int regulator_check_voltage(struct regulator_dev *rdev,
152414c70cbSLiam Girdwood 				   int *min_uV, int *max_uV)
153414c70cbSLiam Girdwood {
154414c70cbSLiam Girdwood 	BUG_ON(*min_uV > *max_uV);
155414c70cbSLiam Girdwood 
156414c70cbSLiam Girdwood 	if (!rdev->constraints) {
1575da84fd9SJoe Perches 		rdev_err(rdev, "no constraints\n");
158414c70cbSLiam Girdwood 		return -ENODEV;
159414c70cbSLiam Girdwood 	}
160414c70cbSLiam Girdwood 	if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) {
1615da84fd9SJoe Perches 		rdev_err(rdev, "operation not allowed\n");
162414c70cbSLiam Girdwood 		return -EPERM;
163414c70cbSLiam Girdwood 	}
164414c70cbSLiam Girdwood 
165414c70cbSLiam Girdwood 	if (*max_uV > rdev->constraints->max_uV)
166414c70cbSLiam Girdwood 		*max_uV = rdev->constraints->max_uV;
167414c70cbSLiam Girdwood 	if (*min_uV < rdev->constraints->min_uV)
168414c70cbSLiam Girdwood 		*min_uV = rdev->constraints->min_uV;
169414c70cbSLiam Girdwood 
17089f425edSMark Brown 	if (*min_uV > *max_uV) {
17189f425edSMark Brown 		rdev_err(rdev, "unsupportable voltage range: %d-%duV\n",
17254abd335SMark Brown 			 *min_uV, *max_uV);
173414c70cbSLiam Girdwood 		return -EINVAL;
17489f425edSMark Brown 	}
175414c70cbSLiam Girdwood 
176414c70cbSLiam Girdwood 	return 0;
177414c70cbSLiam Girdwood }
178414c70cbSLiam Girdwood 
17905fda3b1SThomas Petazzoni /* Make sure we select a voltage that suits the needs of all
18005fda3b1SThomas Petazzoni  * regulator consumers
18105fda3b1SThomas Petazzoni  */
18205fda3b1SThomas Petazzoni static int regulator_check_consumers(struct regulator_dev *rdev,
18305fda3b1SThomas Petazzoni 				     int *min_uV, int *max_uV)
18405fda3b1SThomas Petazzoni {
18505fda3b1SThomas Petazzoni 	struct regulator *regulator;
18605fda3b1SThomas Petazzoni 
18705fda3b1SThomas Petazzoni 	list_for_each_entry(regulator, &rdev->consumer_list, list) {
1884aa922c0SMark Brown 		/*
1894aa922c0SMark Brown 		 * Assume consumers that didn't say anything are OK
1904aa922c0SMark Brown 		 * with anything in the constraint range.
1914aa922c0SMark Brown 		 */
1924aa922c0SMark Brown 		if (!regulator->min_uV && !regulator->max_uV)
1934aa922c0SMark Brown 			continue;
1944aa922c0SMark Brown 
19505fda3b1SThomas Petazzoni 		if (*max_uV > regulator->max_uV)
19605fda3b1SThomas Petazzoni 			*max_uV = regulator->max_uV;
19705fda3b1SThomas Petazzoni 		if (*min_uV < regulator->min_uV)
19805fda3b1SThomas Petazzoni 			*min_uV = regulator->min_uV;
19905fda3b1SThomas Petazzoni 	}
20005fda3b1SThomas Petazzoni 
20105fda3b1SThomas Petazzoni 	if (*min_uV > *max_uV)
20205fda3b1SThomas Petazzoni 		return -EINVAL;
20305fda3b1SThomas Petazzoni 
20405fda3b1SThomas Petazzoni 	return 0;
20505fda3b1SThomas Petazzoni }
20605fda3b1SThomas Petazzoni 
207414c70cbSLiam Girdwood /* current constraint check */
208414c70cbSLiam Girdwood static int regulator_check_current_limit(struct regulator_dev *rdev,
209414c70cbSLiam Girdwood 					int *min_uA, int *max_uA)
210414c70cbSLiam Girdwood {
211414c70cbSLiam Girdwood 	BUG_ON(*min_uA > *max_uA);
212414c70cbSLiam Girdwood 
213414c70cbSLiam Girdwood 	if (!rdev->constraints) {
2145da84fd9SJoe Perches 		rdev_err(rdev, "no constraints\n");
215414c70cbSLiam Girdwood 		return -ENODEV;
216414c70cbSLiam Girdwood 	}
217414c70cbSLiam Girdwood 	if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_CURRENT)) {
2185da84fd9SJoe Perches 		rdev_err(rdev, "operation not allowed\n");
219414c70cbSLiam Girdwood 		return -EPERM;
220414c70cbSLiam Girdwood 	}
221414c70cbSLiam Girdwood 
222414c70cbSLiam Girdwood 	if (*max_uA > rdev->constraints->max_uA)
223414c70cbSLiam Girdwood 		*max_uA = rdev->constraints->max_uA;
224414c70cbSLiam Girdwood 	if (*min_uA < rdev->constraints->min_uA)
225414c70cbSLiam Girdwood 		*min_uA = rdev->constraints->min_uA;
226414c70cbSLiam Girdwood 
22789f425edSMark Brown 	if (*min_uA > *max_uA) {
22889f425edSMark Brown 		rdev_err(rdev, "unsupportable current range: %d-%duA\n",
22954abd335SMark Brown 			 *min_uA, *max_uA);
230414c70cbSLiam Girdwood 		return -EINVAL;
23189f425edSMark Brown 	}
232414c70cbSLiam Girdwood 
233414c70cbSLiam Girdwood 	return 0;
234414c70cbSLiam Girdwood }
235414c70cbSLiam Girdwood 
236414c70cbSLiam Girdwood /* operating mode constraint check */
2372c608234SMark Brown static int regulator_mode_constrain(struct regulator_dev *rdev, int *mode)
238414c70cbSLiam Girdwood {
2392c608234SMark Brown 	switch (*mode) {
240e573520bSDavid Brownell 	case REGULATOR_MODE_FAST:
241e573520bSDavid Brownell 	case REGULATOR_MODE_NORMAL:
242e573520bSDavid Brownell 	case REGULATOR_MODE_IDLE:
243e573520bSDavid Brownell 	case REGULATOR_MODE_STANDBY:
244e573520bSDavid Brownell 		break;
245e573520bSDavid Brownell 	default:
24689f425edSMark Brown 		rdev_err(rdev, "invalid mode %x specified\n", *mode);
247e573520bSDavid Brownell 		return -EINVAL;
248e573520bSDavid Brownell 	}
249e573520bSDavid Brownell 
250414c70cbSLiam Girdwood 	if (!rdev->constraints) {
2515da84fd9SJoe Perches 		rdev_err(rdev, "no constraints\n");
252414c70cbSLiam Girdwood 		return -ENODEV;
253414c70cbSLiam Girdwood 	}
254414c70cbSLiam Girdwood 	if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_MODE)) {
2555da84fd9SJoe Perches 		rdev_err(rdev, "operation not allowed\n");
256414c70cbSLiam Girdwood 		return -EPERM;
257414c70cbSLiam Girdwood 	}
2582c608234SMark Brown 
2592c608234SMark Brown 	/* The modes are bitmasks, the most power hungry modes having
2602c608234SMark Brown 	 * the lowest values. If the requested mode isn't supported
2612c608234SMark Brown 	 * try higher modes. */
2622c608234SMark Brown 	while (*mode) {
2632c608234SMark Brown 		if (rdev->constraints->valid_modes_mask & *mode)
264414c70cbSLiam Girdwood 			return 0;
2652c608234SMark Brown 		*mode /= 2;
2662c608234SMark Brown 	}
2672c608234SMark Brown 
2682c608234SMark Brown 	return -EINVAL;
269414c70cbSLiam Girdwood }
270414c70cbSLiam Girdwood 
271414c70cbSLiam Girdwood /* dynamic regulator mode switching constraint check */
272414c70cbSLiam Girdwood static int regulator_check_drms(struct regulator_dev *rdev)
273414c70cbSLiam Girdwood {
274414c70cbSLiam Girdwood 	if (!rdev->constraints) {
2755da84fd9SJoe Perches 		rdev_err(rdev, "no constraints\n");
276414c70cbSLiam Girdwood 		return -ENODEV;
277414c70cbSLiam Girdwood 	}
278414c70cbSLiam Girdwood 	if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS)) {
2795da84fd9SJoe Perches 		rdev_err(rdev, "operation not allowed\n");
280414c70cbSLiam Girdwood 		return -EPERM;
281414c70cbSLiam Girdwood 	}
282414c70cbSLiam Girdwood 	return 0;
283414c70cbSLiam Girdwood }
284414c70cbSLiam Girdwood 
285414c70cbSLiam Girdwood static ssize_t regulator_uV_show(struct device *dev,
286414c70cbSLiam Girdwood 				struct device_attribute *attr, char *buf)
287414c70cbSLiam Girdwood {
288a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
289414c70cbSLiam Girdwood 	ssize_t ret;
290414c70cbSLiam Girdwood 
291414c70cbSLiam Girdwood 	mutex_lock(&rdev->mutex);
292414c70cbSLiam Girdwood 	ret = sprintf(buf, "%d\n", _regulator_get_voltage(rdev));
293414c70cbSLiam Girdwood 	mutex_unlock(&rdev->mutex);
294414c70cbSLiam Girdwood 
295414c70cbSLiam Girdwood 	return ret;
296414c70cbSLiam Girdwood }
2977ad68e2fSDavid Brownell static DEVICE_ATTR(microvolts, 0444, regulator_uV_show, NULL);
298414c70cbSLiam Girdwood 
299414c70cbSLiam Girdwood static ssize_t regulator_uA_show(struct device *dev,
300414c70cbSLiam Girdwood 				struct device_attribute *attr, char *buf)
301414c70cbSLiam Girdwood {
302a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
303414c70cbSLiam Girdwood 
304414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", _regulator_get_current_limit(rdev));
305414c70cbSLiam Girdwood }
3067ad68e2fSDavid Brownell static DEVICE_ATTR(microamps, 0444, regulator_uA_show, NULL);
307414c70cbSLiam Girdwood 
308bc558a60SMark Brown static ssize_t regulator_name_show(struct device *dev,
309bc558a60SMark Brown 			     struct device_attribute *attr, char *buf)
310bc558a60SMark Brown {
311bc558a60SMark Brown 	struct regulator_dev *rdev = dev_get_drvdata(dev);
312bc558a60SMark Brown 
3131083c393SMark Brown 	return sprintf(buf, "%s\n", rdev_get_name(rdev));
314bc558a60SMark Brown }
315bc558a60SMark Brown 
3164fca9545SDavid Brownell static ssize_t regulator_print_opmode(char *buf, int mode)
317414c70cbSLiam Girdwood {
318414c70cbSLiam Girdwood 	switch (mode) {
319414c70cbSLiam Girdwood 	case REGULATOR_MODE_FAST:
320414c70cbSLiam Girdwood 		return sprintf(buf, "fast\n");
321414c70cbSLiam Girdwood 	case REGULATOR_MODE_NORMAL:
322414c70cbSLiam Girdwood 		return sprintf(buf, "normal\n");
323414c70cbSLiam Girdwood 	case REGULATOR_MODE_IDLE:
324414c70cbSLiam Girdwood 		return sprintf(buf, "idle\n");
325414c70cbSLiam Girdwood 	case REGULATOR_MODE_STANDBY:
326414c70cbSLiam Girdwood 		return sprintf(buf, "standby\n");
327414c70cbSLiam Girdwood 	}
328414c70cbSLiam Girdwood 	return sprintf(buf, "unknown\n");
329414c70cbSLiam Girdwood }
330414c70cbSLiam Girdwood 
3314fca9545SDavid Brownell static ssize_t regulator_opmode_show(struct device *dev,
332414c70cbSLiam Girdwood 				    struct device_attribute *attr, char *buf)
333414c70cbSLiam Girdwood {
334a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
335414c70cbSLiam Girdwood 
3364fca9545SDavid Brownell 	return regulator_print_opmode(buf, _regulator_get_mode(rdev));
3374fca9545SDavid Brownell }
3387ad68e2fSDavid Brownell static DEVICE_ATTR(opmode, 0444, regulator_opmode_show, NULL);
3394fca9545SDavid Brownell 
3404fca9545SDavid Brownell static ssize_t regulator_print_state(char *buf, int state)
3414fca9545SDavid Brownell {
342414c70cbSLiam Girdwood 	if (state > 0)
343414c70cbSLiam Girdwood 		return sprintf(buf, "enabled\n");
344414c70cbSLiam Girdwood 	else if (state == 0)
345414c70cbSLiam Girdwood 		return sprintf(buf, "disabled\n");
346414c70cbSLiam Girdwood 	else
347414c70cbSLiam Girdwood 		return sprintf(buf, "unknown\n");
348414c70cbSLiam Girdwood }
349414c70cbSLiam Girdwood 
3504fca9545SDavid Brownell static ssize_t regulator_state_show(struct device *dev,
3514fca9545SDavid Brownell 				   struct device_attribute *attr, char *buf)
3524fca9545SDavid Brownell {
3534fca9545SDavid Brownell 	struct regulator_dev *rdev = dev_get_drvdata(dev);
3549332546fSMark Brown 	ssize_t ret;
3554fca9545SDavid Brownell 
3569332546fSMark Brown 	mutex_lock(&rdev->mutex);
3579332546fSMark Brown 	ret = regulator_print_state(buf, _regulator_is_enabled(rdev));
3589332546fSMark Brown 	mutex_unlock(&rdev->mutex);
3599332546fSMark Brown 
3609332546fSMark Brown 	return ret;
3614fca9545SDavid Brownell }
3627ad68e2fSDavid Brownell static DEVICE_ATTR(state, 0444, regulator_state_show, NULL);
3634fca9545SDavid Brownell 
364853116a1SDavid Brownell static ssize_t regulator_status_show(struct device *dev,
365853116a1SDavid Brownell 				   struct device_attribute *attr, char *buf)
366853116a1SDavid Brownell {
367853116a1SDavid Brownell 	struct regulator_dev *rdev = dev_get_drvdata(dev);
368853116a1SDavid Brownell 	int status;
369853116a1SDavid Brownell 	char *label;
370853116a1SDavid Brownell 
371853116a1SDavid Brownell 	status = rdev->desc->ops->get_status(rdev);
372853116a1SDavid Brownell 	if (status < 0)
373853116a1SDavid Brownell 		return status;
374853116a1SDavid Brownell 
375853116a1SDavid Brownell 	switch (status) {
376853116a1SDavid Brownell 	case REGULATOR_STATUS_OFF:
377853116a1SDavid Brownell 		label = "off";
378853116a1SDavid Brownell 		break;
379853116a1SDavid Brownell 	case REGULATOR_STATUS_ON:
380853116a1SDavid Brownell 		label = "on";
381853116a1SDavid Brownell 		break;
382853116a1SDavid Brownell 	case REGULATOR_STATUS_ERROR:
383853116a1SDavid Brownell 		label = "error";
384853116a1SDavid Brownell 		break;
385853116a1SDavid Brownell 	case REGULATOR_STATUS_FAST:
386853116a1SDavid Brownell 		label = "fast";
387853116a1SDavid Brownell 		break;
388853116a1SDavid Brownell 	case REGULATOR_STATUS_NORMAL:
389853116a1SDavid Brownell 		label = "normal";
390853116a1SDavid Brownell 		break;
391853116a1SDavid Brownell 	case REGULATOR_STATUS_IDLE:
392853116a1SDavid Brownell 		label = "idle";
393853116a1SDavid Brownell 		break;
394853116a1SDavid Brownell 	case REGULATOR_STATUS_STANDBY:
395853116a1SDavid Brownell 		label = "standby";
396853116a1SDavid Brownell 		break;
3971beaf762SKrystian Garbaciak 	case REGULATOR_STATUS_UNDEFINED:
3981beaf762SKrystian Garbaciak 		label = "undefined";
3991beaf762SKrystian Garbaciak 		break;
400853116a1SDavid Brownell 	default:
401853116a1SDavid Brownell 		return -ERANGE;
402853116a1SDavid Brownell 	}
403853116a1SDavid Brownell 
404853116a1SDavid Brownell 	return sprintf(buf, "%s\n", label);
405853116a1SDavid Brownell }
406853116a1SDavid Brownell static DEVICE_ATTR(status, 0444, regulator_status_show, NULL);
407853116a1SDavid Brownell 
408414c70cbSLiam Girdwood static ssize_t regulator_min_uA_show(struct device *dev,
409414c70cbSLiam Girdwood 				    struct device_attribute *attr, char *buf)
410414c70cbSLiam Girdwood {
411a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
412414c70cbSLiam Girdwood 
413414c70cbSLiam Girdwood 	if (!rdev->constraints)
414414c70cbSLiam Girdwood 		return sprintf(buf, "constraint not defined\n");
415414c70cbSLiam Girdwood 
416414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", rdev->constraints->min_uA);
417414c70cbSLiam Girdwood }
4187ad68e2fSDavid Brownell static DEVICE_ATTR(min_microamps, 0444, regulator_min_uA_show, NULL);
419414c70cbSLiam Girdwood 
420414c70cbSLiam Girdwood static ssize_t regulator_max_uA_show(struct device *dev,
421414c70cbSLiam Girdwood 				    struct device_attribute *attr, char *buf)
422414c70cbSLiam Girdwood {
423a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
424414c70cbSLiam Girdwood 
425414c70cbSLiam Girdwood 	if (!rdev->constraints)
426414c70cbSLiam Girdwood 		return sprintf(buf, "constraint not defined\n");
427414c70cbSLiam Girdwood 
428414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", rdev->constraints->max_uA);
429414c70cbSLiam Girdwood }
4307ad68e2fSDavid Brownell static DEVICE_ATTR(max_microamps, 0444, regulator_max_uA_show, NULL);
431414c70cbSLiam Girdwood 
432414c70cbSLiam Girdwood static ssize_t regulator_min_uV_show(struct device *dev,
433414c70cbSLiam Girdwood 				    struct device_attribute *attr, char *buf)
434414c70cbSLiam Girdwood {
435a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
436414c70cbSLiam Girdwood 
437414c70cbSLiam Girdwood 	if (!rdev->constraints)
438414c70cbSLiam Girdwood 		return sprintf(buf, "constraint not defined\n");
439414c70cbSLiam Girdwood 
440414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", rdev->constraints->min_uV);
441414c70cbSLiam Girdwood }
4427ad68e2fSDavid Brownell static DEVICE_ATTR(min_microvolts, 0444, regulator_min_uV_show, NULL);
443414c70cbSLiam Girdwood 
444414c70cbSLiam Girdwood static ssize_t regulator_max_uV_show(struct device *dev,
445414c70cbSLiam Girdwood 				    struct device_attribute *attr, char *buf)
446414c70cbSLiam Girdwood {
447a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
448414c70cbSLiam Girdwood 
449414c70cbSLiam Girdwood 	if (!rdev->constraints)
450414c70cbSLiam Girdwood 		return sprintf(buf, "constraint not defined\n");
451414c70cbSLiam Girdwood 
452414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", rdev->constraints->max_uV);
453414c70cbSLiam Girdwood }
4547ad68e2fSDavid Brownell static DEVICE_ATTR(max_microvolts, 0444, regulator_max_uV_show, NULL);
455414c70cbSLiam Girdwood 
456414c70cbSLiam Girdwood static ssize_t regulator_total_uA_show(struct device *dev,
457414c70cbSLiam Girdwood 				      struct device_attribute *attr, char *buf)
458414c70cbSLiam Girdwood {
459a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
460414c70cbSLiam Girdwood 	struct regulator *regulator;
461414c70cbSLiam Girdwood 	int uA = 0;
462414c70cbSLiam Girdwood 
463414c70cbSLiam Girdwood 	mutex_lock(&rdev->mutex);
464414c70cbSLiam Girdwood 	list_for_each_entry(regulator, &rdev->consumer_list, list)
465414c70cbSLiam Girdwood 		uA += regulator->uA_load;
466414c70cbSLiam Girdwood 	mutex_unlock(&rdev->mutex);
467414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", uA);
468414c70cbSLiam Girdwood }
4697ad68e2fSDavid Brownell static DEVICE_ATTR(requested_microamps, 0444, regulator_total_uA_show, NULL);
470414c70cbSLiam Girdwood 
471414c70cbSLiam Girdwood static ssize_t regulator_num_users_show(struct device *dev,
472414c70cbSLiam Girdwood 				      struct device_attribute *attr, char *buf)
473414c70cbSLiam Girdwood {
474a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
475414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", rdev->use_count);
476414c70cbSLiam Girdwood }
477414c70cbSLiam Girdwood 
478414c70cbSLiam Girdwood static ssize_t regulator_type_show(struct device *dev,
479414c70cbSLiam Girdwood 				  struct device_attribute *attr, char *buf)
480414c70cbSLiam Girdwood {
481a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
482414c70cbSLiam Girdwood 
483414c70cbSLiam Girdwood 	switch (rdev->desc->type) {
484414c70cbSLiam Girdwood 	case REGULATOR_VOLTAGE:
485414c70cbSLiam Girdwood 		return sprintf(buf, "voltage\n");
486414c70cbSLiam Girdwood 	case REGULATOR_CURRENT:
487414c70cbSLiam Girdwood 		return sprintf(buf, "current\n");
488414c70cbSLiam Girdwood 	}
489414c70cbSLiam Girdwood 	return sprintf(buf, "unknown\n");
490414c70cbSLiam Girdwood }
491414c70cbSLiam Girdwood 
492414c70cbSLiam Girdwood static ssize_t regulator_suspend_mem_uV_show(struct device *dev,
493414c70cbSLiam Girdwood 				struct device_attribute *attr, char *buf)
494414c70cbSLiam Girdwood {
495a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
496414c70cbSLiam Girdwood 
497414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", rdev->constraints->state_mem.uV);
498414c70cbSLiam Girdwood }
4997ad68e2fSDavid Brownell static DEVICE_ATTR(suspend_mem_microvolts, 0444,
5007ad68e2fSDavid Brownell 		regulator_suspend_mem_uV_show, NULL);
501414c70cbSLiam Girdwood 
502414c70cbSLiam Girdwood static ssize_t regulator_suspend_disk_uV_show(struct device *dev,
503414c70cbSLiam Girdwood 				struct device_attribute *attr, char *buf)
504414c70cbSLiam Girdwood {
505a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
506414c70cbSLiam Girdwood 
507414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", rdev->constraints->state_disk.uV);
508414c70cbSLiam Girdwood }
5097ad68e2fSDavid Brownell static DEVICE_ATTR(suspend_disk_microvolts, 0444,
5107ad68e2fSDavid Brownell 		regulator_suspend_disk_uV_show, NULL);
511414c70cbSLiam Girdwood 
512414c70cbSLiam Girdwood static ssize_t regulator_suspend_standby_uV_show(struct device *dev,
513414c70cbSLiam Girdwood 				struct device_attribute *attr, char *buf)
514414c70cbSLiam Girdwood {
515a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
516414c70cbSLiam Girdwood 
517414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", rdev->constraints->state_standby.uV);
518414c70cbSLiam Girdwood }
5197ad68e2fSDavid Brownell static DEVICE_ATTR(suspend_standby_microvolts, 0444,
5207ad68e2fSDavid Brownell 		regulator_suspend_standby_uV_show, NULL);
521414c70cbSLiam Girdwood 
522414c70cbSLiam Girdwood static ssize_t regulator_suspend_mem_mode_show(struct device *dev,
523414c70cbSLiam Girdwood 				struct device_attribute *attr, char *buf)
524414c70cbSLiam Girdwood {
525a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
526414c70cbSLiam Girdwood 
5274fca9545SDavid Brownell 	return regulator_print_opmode(buf,
5284fca9545SDavid Brownell 		rdev->constraints->state_mem.mode);
529414c70cbSLiam Girdwood }
5307ad68e2fSDavid Brownell static DEVICE_ATTR(suspend_mem_mode, 0444,
5317ad68e2fSDavid Brownell 		regulator_suspend_mem_mode_show, NULL);
532414c70cbSLiam Girdwood 
533414c70cbSLiam Girdwood static ssize_t regulator_suspend_disk_mode_show(struct device *dev,
534414c70cbSLiam Girdwood 				struct device_attribute *attr, char *buf)
535414c70cbSLiam Girdwood {
536a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
537414c70cbSLiam Girdwood 
5384fca9545SDavid Brownell 	return regulator_print_opmode(buf,
5394fca9545SDavid Brownell 		rdev->constraints->state_disk.mode);
540414c70cbSLiam Girdwood }
5417ad68e2fSDavid Brownell static DEVICE_ATTR(suspend_disk_mode, 0444,
5427ad68e2fSDavid Brownell 		regulator_suspend_disk_mode_show, NULL);
543414c70cbSLiam Girdwood 
544414c70cbSLiam Girdwood static ssize_t regulator_suspend_standby_mode_show(struct device *dev,
545414c70cbSLiam Girdwood 				struct device_attribute *attr, char *buf)
546414c70cbSLiam Girdwood {
547a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
548414c70cbSLiam Girdwood 
5494fca9545SDavid Brownell 	return regulator_print_opmode(buf,
5504fca9545SDavid Brownell 		rdev->constraints->state_standby.mode);
551414c70cbSLiam Girdwood }
5527ad68e2fSDavid Brownell static DEVICE_ATTR(suspend_standby_mode, 0444,
5537ad68e2fSDavid Brownell 		regulator_suspend_standby_mode_show, NULL);
554414c70cbSLiam Girdwood 
555414c70cbSLiam Girdwood static ssize_t regulator_suspend_mem_state_show(struct device *dev,
556414c70cbSLiam Girdwood 				   struct device_attribute *attr, char *buf)
557414c70cbSLiam Girdwood {
558a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
559414c70cbSLiam Girdwood 
5604fca9545SDavid Brownell 	return regulator_print_state(buf,
5614fca9545SDavid Brownell 			rdev->constraints->state_mem.enabled);
562414c70cbSLiam Girdwood }
5637ad68e2fSDavid Brownell static DEVICE_ATTR(suspend_mem_state, 0444,
5647ad68e2fSDavid Brownell 		regulator_suspend_mem_state_show, NULL);
565414c70cbSLiam Girdwood 
566414c70cbSLiam Girdwood static ssize_t regulator_suspend_disk_state_show(struct device *dev,
567414c70cbSLiam Girdwood 				   struct device_attribute *attr, char *buf)
568414c70cbSLiam Girdwood {
569a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
570414c70cbSLiam Girdwood 
5714fca9545SDavid Brownell 	return regulator_print_state(buf,
5724fca9545SDavid Brownell 			rdev->constraints->state_disk.enabled);
573414c70cbSLiam Girdwood }
5747ad68e2fSDavid Brownell static DEVICE_ATTR(suspend_disk_state, 0444,
5757ad68e2fSDavid Brownell 		regulator_suspend_disk_state_show, NULL);
576414c70cbSLiam Girdwood 
577414c70cbSLiam Girdwood static ssize_t regulator_suspend_standby_state_show(struct device *dev,
578414c70cbSLiam Girdwood 				   struct device_attribute *attr, char *buf)
579414c70cbSLiam Girdwood {
580a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
581414c70cbSLiam Girdwood 
5824fca9545SDavid Brownell 	return regulator_print_state(buf,
5834fca9545SDavid Brownell 			rdev->constraints->state_standby.enabled);
584414c70cbSLiam Girdwood }
5857ad68e2fSDavid Brownell static DEVICE_ATTR(suspend_standby_state, 0444,
5867ad68e2fSDavid Brownell 		regulator_suspend_standby_state_show, NULL);
587bc558a60SMark Brown 
5887ad68e2fSDavid Brownell 
5897ad68e2fSDavid Brownell /*
5907ad68e2fSDavid Brownell  * These are the only attributes are present for all regulators.
5917ad68e2fSDavid Brownell  * Other attributes are a function of regulator functionality.
5927ad68e2fSDavid Brownell  */
593414c70cbSLiam Girdwood static struct device_attribute regulator_dev_attrs[] = {
594bc558a60SMark Brown 	__ATTR(name, 0444, regulator_name_show, NULL),
595414c70cbSLiam Girdwood 	__ATTR(num_users, 0444, regulator_num_users_show, NULL),
596414c70cbSLiam Girdwood 	__ATTR(type, 0444, regulator_type_show, NULL),
597414c70cbSLiam Girdwood 	__ATTR_NULL,
598414c70cbSLiam Girdwood };
599414c70cbSLiam Girdwood 
600414c70cbSLiam Girdwood static void regulator_dev_release(struct device *dev)
601414c70cbSLiam Girdwood {
602a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
603414c70cbSLiam Girdwood 	kfree(rdev);
604414c70cbSLiam Girdwood }
605414c70cbSLiam Girdwood 
606414c70cbSLiam Girdwood static struct class regulator_class = {
607414c70cbSLiam Girdwood 	.name = "regulator",
608414c70cbSLiam Girdwood 	.dev_release = regulator_dev_release,
609414c70cbSLiam Girdwood 	.dev_attrs = regulator_dev_attrs,
610414c70cbSLiam Girdwood };
611414c70cbSLiam Girdwood 
612414c70cbSLiam Girdwood /* Calculate the new optimum regulator operating mode based on the new total
613414c70cbSLiam Girdwood  * consumer load. All locks held by caller */
614414c70cbSLiam Girdwood static void drms_uA_update(struct regulator_dev *rdev)
615414c70cbSLiam Girdwood {
616414c70cbSLiam Girdwood 	struct regulator *sibling;
617414c70cbSLiam Girdwood 	int current_uA = 0, output_uV, input_uV, err;
618414c70cbSLiam Girdwood 	unsigned int mode;
619414c70cbSLiam Girdwood 
620414c70cbSLiam Girdwood 	err = regulator_check_drms(rdev);
621414c70cbSLiam Girdwood 	if (err < 0 || !rdev->desc->ops->get_optimum_mode ||
622476c2d83SMark Brown 	    (!rdev->desc->ops->get_voltage &&
623476c2d83SMark Brown 	     !rdev->desc->ops->get_voltage_sel) ||
624476c2d83SMark Brown 	    !rdev->desc->ops->set_mode)
625414c70cbSLiam Girdwood 		return;
626414c70cbSLiam Girdwood 
627414c70cbSLiam Girdwood 	/* get output voltage */
6281bf5a1f8SMark Brown 	output_uV = _regulator_get_voltage(rdev);
629414c70cbSLiam Girdwood 	if (output_uV <= 0)
630414c70cbSLiam Girdwood 		return;
631414c70cbSLiam Girdwood 
632414c70cbSLiam Girdwood 	/* get input voltage */
6331bf5a1f8SMark Brown 	input_uV = 0;
6341bf5a1f8SMark Brown 	if (rdev->supply)
6353f24f5adSAxel Lin 		input_uV = regulator_get_voltage(rdev->supply);
6361bf5a1f8SMark Brown 	if (input_uV <= 0)
637414c70cbSLiam Girdwood 		input_uV = rdev->constraints->input_uV;
638414c70cbSLiam Girdwood 	if (input_uV <= 0)
639414c70cbSLiam Girdwood 		return;
640414c70cbSLiam Girdwood 
641414c70cbSLiam Girdwood 	/* calc total requested load */
642414c70cbSLiam Girdwood 	list_for_each_entry(sibling, &rdev->consumer_list, list)
643414c70cbSLiam Girdwood 		current_uA += sibling->uA_load;
644414c70cbSLiam Girdwood 
645414c70cbSLiam Girdwood 	/* now get the optimum mode for our new total regulator load */
646414c70cbSLiam Girdwood 	mode = rdev->desc->ops->get_optimum_mode(rdev, input_uV,
647414c70cbSLiam Girdwood 						  output_uV, current_uA);
648414c70cbSLiam Girdwood 
649414c70cbSLiam Girdwood 	/* check the new mode is allowed */
6502c608234SMark Brown 	err = regulator_mode_constrain(rdev, &mode);
651414c70cbSLiam Girdwood 	if (err == 0)
652414c70cbSLiam Girdwood 		rdev->desc->ops->set_mode(rdev, mode);
653414c70cbSLiam Girdwood }
654414c70cbSLiam Girdwood 
655414c70cbSLiam Girdwood static int suspend_set_state(struct regulator_dev *rdev,
656414c70cbSLiam Girdwood 	struct regulator_state *rstate)
657414c70cbSLiam Girdwood {
658414c70cbSLiam Girdwood 	int ret = 0;
659638f85c5SMark Brown 
660638f85c5SMark Brown 	/* If we have no suspend mode configration don't set anything;
6618ac0e95dSAxel Lin 	 * only warn if the driver implements set_suspend_voltage or
6628ac0e95dSAxel Lin 	 * set_suspend_mode callback.
663638f85c5SMark Brown 	 */
664638f85c5SMark Brown 	if (!rstate->enabled && !rstate->disabled) {
6658ac0e95dSAxel Lin 		if (rdev->desc->ops->set_suspend_voltage ||
6668ac0e95dSAxel Lin 		    rdev->desc->ops->set_suspend_mode)
6675da84fd9SJoe Perches 			rdev_warn(rdev, "No configuration\n");
668638f85c5SMark Brown 		return 0;
669638f85c5SMark Brown 	}
670638f85c5SMark Brown 
671638f85c5SMark Brown 	if (rstate->enabled && rstate->disabled) {
6725da84fd9SJoe Perches 		rdev_err(rdev, "invalid configuration\n");
673638f85c5SMark Brown 		return -EINVAL;
674638f85c5SMark Brown 	}
675638f85c5SMark Brown 
6768ac0e95dSAxel Lin 	if (rstate->enabled && rdev->desc->ops->set_suspend_enable)
677414c70cbSLiam Girdwood 		ret = rdev->desc->ops->set_suspend_enable(rdev);
6788ac0e95dSAxel Lin 	else if (rstate->disabled && rdev->desc->ops->set_suspend_disable)
679414c70cbSLiam Girdwood 		ret = rdev->desc->ops->set_suspend_disable(rdev);
6808ac0e95dSAxel Lin 	else /* OK if set_suspend_enable or set_suspend_disable is NULL */
6818ac0e95dSAxel Lin 		ret = 0;
6828ac0e95dSAxel Lin 
683414c70cbSLiam Girdwood 	if (ret < 0) {
6845da84fd9SJoe Perches 		rdev_err(rdev, "failed to enabled/disable\n");
685414c70cbSLiam Girdwood 		return ret;
686414c70cbSLiam Girdwood 	}
687414c70cbSLiam Girdwood 
688414c70cbSLiam Girdwood 	if (rdev->desc->ops->set_suspend_voltage && rstate->uV > 0) {
689414c70cbSLiam Girdwood 		ret = rdev->desc->ops->set_suspend_voltage(rdev, rstate->uV);
690414c70cbSLiam Girdwood 		if (ret < 0) {
6915da84fd9SJoe Perches 			rdev_err(rdev, "failed to set voltage\n");
692414c70cbSLiam Girdwood 			return ret;
693414c70cbSLiam Girdwood 		}
694414c70cbSLiam Girdwood 	}
695414c70cbSLiam Girdwood 
696414c70cbSLiam Girdwood 	if (rdev->desc->ops->set_suspend_mode && rstate->mode > 0) {
697414c70cbSLiam Girdwood 		ret = rdev->desc->ops->set_suspend_mode(rdev, rstate->mode);
698414c70cbSLiam Girdwood 		if (ret < 0) {
6995da84fd9SJoe Perches 			rdev_err(rdev, "failed to set mode\n");
700414c70cbSLiam Girdwood 			return ret;
701414c70cbSLiam Girdwood 		}
702414c70cbSLiam Girdwood 	}
703414c70cbSLiam Girdwood 	return ret;
704414c70cbSLiam Girdwood }
705414c70cbSLiam Girdwood 
706414c70cbSLiam Girdwood /* locks held by caller */
707414c70cbSLiam Girdwood static int suspend_prepare(struct regulator_dev *rdev, suspend_state_t state)
708414c70cbSLiam Girdwood {
709414c70cbSLiam Girdwood 	if (!rdev->constraints)
710414c70cbSLiam Girdwood 		return -EINVAL;
711414c70cbSLiam Girdwood 
712414c70cbSLiam Girdwood 	switch (state) {
713414c70cbSLiam Girdwood 	case PM_SUSPEND_STANDBY:
714414c70cbSLiam Girdwood 		return suspend_set_state(rdev,
715414c70cbSLiam Girdwood 			&rdev->constraints->state_standby);
716414c70cbSLiam Girdwood 	case PM_SUSPEND_MEM:
717414c70cbSLiam Girdwood 		return suspend_set_state(rdev,
718414c70cbSLiam Girdwood 			&rdev->constraints->state_mem);
719414c70cbSLiam Girdwood 	case PM_SUSPEND_MAX:
720414c70cbSLiam Girdwood 		return suspend_set_state(rdev,
721414c70cbSLiam Girdwood 			&rdev->constraints->state_disk);
722414c70cbSLiam Girdwood 	default:
723414c70cbSLiam Girdwood 		return -EINVAL;
724414c70cbSLiam Girdwood 	}
725414c70cbSLiam Girdwood }
726414c70cbSLiam Girdwood 
727414c70cbSLiam Girdwood static void print_constraints(struct regulator_dev *rdev)
728414c70cbSLiam Girdwood {
729414c70cbSLiam Girdwood 	struct regulation_constraints *constraints = rdev->constraints;
730973e9a27SMark Brown 	char buf[80] = "";
7318f031b48SMark Brown 	int count = 0;
7328f031b48SMark Brown 	int ret;
733414c70cbSLiam Girdwood 
7348f031b48SMark Brown 	if (constraints->min_uV && constraints->max_uV) {
735414c70cbSLiam Girdwood 		if (constraints->min_uV == constraints->max_uV)
7368f031b48SMark Brown 			count += sprintf(buf + count, "%d mV ",
737414c70cbSLiam Girdwood 					 constraints->min_uV / 1000);
738414c70cbSLiam Girdwood 		else
7398f031b48SMark Brown 			count += sprintf(buf + count, "%d <--> %d mV ",
740414c70cbSLiam Girdwood 					 constraints->min_uV / 1000,
741414c70cbSLiam Girdwood 					 constraints->max_uV / 1000);
7428f031b48SMark Brown 	}
7438f031b48SMark Brown 
7448f031b48SMark Brown 	if (!constraints->min_uV ||
7458f031b48SMark Brown 	    constraints->min_uV != constraints->max_uV) {
7468f031b48SMark Brown 		ret = _regulator_get_voltage(rdev);
7478f031b48SMark Brown 		if (ret > 0)
7488f031b48SMark Brown 			count += sprintf(buf + count, "at %d mV ", ret / 1000);
7498f031b48SMark Brown 	}
7508f031b48SMark Brown 
751bf5892a8SMark Brown 	if (constraints->uV_offset)
752bf5892a8SMark Brown 		count += sprintf(buf, "%dmV offset ",
753bf5892a8SMark Brown 				 constraints->uV_offset / 1000);
754bf5892a8SMark Brown 
7558f031b48SMark Brown 	if (constraints->min_uA && constraints->max_uA) {
756414c70cbSLiam Girdwood 		if (constraints->min_uA == constraints->max_uA)
7578f031b48SMark Brown 			count += sprintf(buf + count, "%d mA ",
758414c70cbSLiam Girdwood 					 constraints->min_uA / 1000);
759414c70cbSLiam Girdwood 		else
7608f031b48SMark Brown 			count += sprintf(buf + count, "%d <--> %d mA ",
761414c70cbSLiam Girdwood 					 constraints->min_uA / 1000,
762414c70cbSLiam Girdwood 					 constraints->max_uA / 1000);
763414c70cbSLiam Girdwood 	}
7648f031b48SMark Brown 
7658f031b48SMark Brown 	if (!constraints->min_uA ||
7668f031b48SMark Brown 	    constraints->min_uA != constraints->max_uA) {
7678f031b48SMark Brown 		ret = _regulator_get_current_limit(rdev);
7688f031b48SMark Brown 		if (ret > 0)
769e4a6376bSCyril Chemparathy 			count += sprintf(buf + count, "at %d mA ", ret / 1000);
7708f031b48SMark Brown 	}
7718f031b48SMark Brown 
772414c70cbSLiam Girdwood 	if (constraints->valid_modes_mask & REGULATOR_MODE_FAST)
773414c70cbSLiam Girdwood 		count += sprintf(buf + count, "fast ");
774414c70cbSLiam Girdwood 	if (constraints->valid_modes_mask & REGULATOR_MODE_NORMAL)
775414c70cbSLiam Girdwood 		count += sprintf(buf + count, "normal ");
776414c70cbSLiam Girdwood 	if (constraints->valid_modes_mask & REGULATOR_MODE_IDLE)
777414c70cbSLiam Girdwood 		count += sprintf(buf + count, "idle ");
778414c70cbSLiam Girdwood 	if (constraints->valid_modes_mask & REGULATOR_MODE_STANDBY)
779414c70cbSLiam Girdwood 		count += sprintf(buf + count, "standby");
780414c70cbSLiam Girdwood 
781215b8b05SUwe Kleine-König 	if (!count)
782215b8b05SUwe Kleine-König 		sprintf(buf, "no parameters");
783215b8b05SUwe Kleine-König 
78413ce29f8SMark Brown 	rdev_info(rdev, "%s\n", buf);
7854a682922SMark Brown 
7864a682922SMark Brown 	if ((constraints->min_uV != constraints->max_uV) &&
7874a682922SMark Brown 	    !(constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE))
7884a682922SMark Brown 		rdev_warn(rdev,
7894a682922SMark Brown 			  "Voltage range but no REGULATOR_CHANGE_VOLTAGE\n");
790414c70cbSLiam Girdwood }
791414c70cbSLiam Girdwood 
792e79055d6SMark Brown static int machine_constraints_voltage(struct regulator_dev *rdev,
7931083c393SMark Brown 	struct regulation_constraints *constraints)
794e79055d6SMark Brown {
795e79055d6SMark Brown 	struct regulator_ops *ops = rdev->desc->ops;
796af5866c9SMark Brown 	int ret;
797af5866c9SMark Brown 
798af5866c9SMark Brown 	/* do we need to apply the constraint voltage */
799af5866c9SMark Brown 	if (rdev->constraints->apply_uV &&
80075790251SMark Brown 	    rdev->constraints->min_uV == rdev->constraints->max_uV) {
80175790251SMark Brown 		ret = _regulator_do_set_voltage(rdev,
8023a93f2a9SMark Brown 						rdev->constraints->min_uV,
80375790251SMark Brown 						rdev->constraints->max_uV);
804af5866c9SMark Brown 		if (ret < 0) {
8055da84fd9SJoe Perches 			rdev_err(rdev, "failed to apply %duV constraint\n",
8065da84fd9SJoe Perches 				 rdev->constraints->min_uV);
807af5866c9SMark Brown 			return ret;
808af5866c9SMark Brown 		}
809af5866c9SMark Brown 	}
810e79055d6SMark Brown 
811e79055d6SMark Brown 	/* constrain machine-level voltage specs to fit
812e79055d6SMark Brown 	 * the actual range supported by this regulator.
813e79055d6SMark Brown 	 */
814e79055d6SMark Brown 	if (ops->list_voltage && rdev->desc->n_voltages) {
815e79055d6SMark Brown 		int	count = rdev->desc->n_voltages;
816e79055d6SMark Brown 		int	i;
817e79055d6SMark Brown 		int	min_uV = INT_MAX;
818e79055d6SMark Brown 		int	max_uV = INT_MIN;
819e79055d6SMark Brown 		int	cmin = constraints->min_uV;
820e79055d6SMark Brown 		int	cmax = constraints->max_uV;
821e79055d6SMark Brown 
822e79055d6SMark Brown 		/* it's safe to autoconfigure fixed-voltage supplies
823e79055d6SMark Brown 		   and the constraints are used by list_voltage. */
824e79055d6SMark Brown 		if (count == 1 && !cmin) {
825e79055d6SMark Brown 			cmin = 1;
826e79055d6SMark Brown 			cmax = INT_MAX;
827e79055d6SMark Brown 			constraints->min_uV = cmin;
828e79055d6SMark Brown 			constraints->max_uV = cmax;
829e79055d6SMark Brown 		}
830e79055d6SMark Brown 
831e79055d6SMark Brown 		/* voltage constraints are optional */
832e79055d6SMark Brown 		if ((cmin == 0) && (cmax == 0))
833e79055d6SMark Brown 			return 0;
834e79055d6SMark Brown 
835e79055d6SMark Brown 		/* else require explicit machine-level constraints */
836e79055d6SMark Brown 		if (cmin <= 0 || cmax <= 0 || cmax < cmin) {
8375da84fd9SJoe Perches 			rdev_err(rdev, "invalid voltage constraints\n");
838e79055d6SMark Brown 			return -EINVAL;
839e79055d6SMark Brown 		}
840e79055d6SMark Brown 
841e79055d6SMark Brown 		/* initial: [cmin..cmax] valid, [min_uV..max_uV] not */
842e79055d6SMark Brown 		for (i = 0; i < count; i++) {
843e79055d6SMark Brown 			int	value;
844e79055d6SMark Brown 
845e79055d6SMark Brown 			value = ops->list_voltage(rdev, i);
846e79055d6SMark Brown 			if (value <= 0)
847e79055d6SMark Brown 				continue;
848e79055d6SMark Brown 
849e79055d6SMark Brown 			/* maybe adjust [min_uV..max_uV] */
850e79055d6SMark Brown 			if (value >= cmin && value < min_uV)
851e79055d6SMark Brown 				min_uV = value;
852e79055d6SMark Brown 			if (value <= cmax && value > max_uV)
853e79055d6SMark Brown 				max_uV = value;
854e79055d6SMark Brown 		}
855e79055d6SMark Brown 
856e79055d6SMark Brown 		/* final: [min_uV..max_uV] valid iff constraints valid */
857e79055d6SMark Brown 		if (max_uV < min_uV) {
8585da84fd9SJoe Perches 			rdev_err(rdev, "unsupportable voltage constraints\n");
859e79055d6SMark Brown 			return -EINVAL;
860e79055d6SMark Brown 		}
861e79055d6SMark Brown 
862e79055d6SMark Brown 		/* use regulator's subset of machine constraints */
863e79055d6SMark Brown 		if (constraints->min_uV < min_uV) {
8645da84fd9SJoe Perches 			rdev_dbg(rdev, "override min_uV, %d -> %d\n",
8655da84fd9SJoe Perches 				 constraints->min_uV, min_uV);
866e79055d6SMark Brown 			constraints->min_uV = min_uV;
867e79055d6SMark Brown 		}
868e79055d6SMark Brown 		if (constraints->max_uV > max_uV) {
8695da84fd9SJoe Perches 			rdev_dbg(rdev, "override max_uV, %d -> %d\n",
8705da84fd9SJoe Perches 				 constraints->max_uV, max_uV);
871e79055d6SMark Brown 			constraints->max_uV = max_uV;
872e79055d6SMark Brown 		}
873e79055d6SMark Brown 	}
874e79055d6SMark Brown 
875e79055d6SMark Brown 	return 0;
876e79055d6SMark Brown }
877e79055d6SMark Brown 
878a5766f11SLiam Girdwood /**
879a5766f11SLiam Girdwood  * set_machine_constraints - sets regulator constraints
88069279fb9SMark Brown  * @rdev: regulator source
881c8e7e464SMark Brown  * @constraints: constraints to apply
882a5766f11SLiam Girdwood  *
883a5766f11SLiam Girdwood  * Allows platform initialisation code to define and constrain
884a5766f11SLiam Girdwood  * regulator circuits e.g. valid voltage/current ranges, etc.  NOTE:
885a5766f11SLiam Girdwood  * Constraints *must* be set by platform code in order for some
886a5766f11SLiam Girdwood  * regulator operations to proceed i.e. set_voltage, set_current_limit,
887a5766f11SLiam Girdwood  * set_mode.
888a5766f11SLiam Girdwood  */
889a5766f11SLiam Girdwood static int set_machine_constraints(struct regulator_dev *rdev,
890f8c12fe3SMark Brown 	const struct regulation_constraints *constraints)
891a5766f11SLiam Girdwood {
892a5766f11SLiam Girdwood 	int ret = 0;
893e5fda26cSMark Brown 	struct regulator_ops *ops = rdev->desc->ops;
894e06f5b4fSMark Brown 
8959a8f5e07SMark Brown 	if (constraints)
896f8c12fe3SMark Brown 		rdev->constraints = kmemdup(constraints, sizeof(*constraints),
897f8c12fe3SMark Brown 					    GFP_KERNEL);
8989a8f5e07SMark Brown 	else
8999a8f5e07SMark Brown 		rdev->constraints = kzalloc(sizeof(*constraints),
9009a8f5e07SMark Brown 					    GFP_KERNEL);
901f8c12fe3SMark Brown 	if (!rdev->constraints)
902f8c12fe3SMark Brown 		return -ENOMEM;
903af5866c9SMark Brown 
904f8c12fe3SMark Brown 	ret = machine_constraints_voltage(rdev, rdev->constraints);
905e79055d6SMark Brown 	if (ret != 0)
9063e2b9abdSMark Brown 		goto out;
9073e2b9abdSMark Brown 
908a5766f11SLiam Girdwood 	/* do we need to setup our suspend state */
9099a8f5e07SMark Brown 	if (rdev->constraints->initial_state) {
910f8c12fe3SMark Brown 		ret = suspend_prepare(rdev, rdev->constraints->initial_state);
911e06f5b4fSMark Brown 		if (ret < 0) {
9125da84fd9SJoe Perches 			rdev_err(rdev, "failed to set suspend state\n");
913e06f5b4fSMark Brown 			goto out;
914e06f5b4fSMark Brown 		}
915e06f5b4fSMark Brown 	}
916a5766f11SLiam Girdwood 
9179a8f5e07SMark Brown 	if (rdev->constraints->initial_mode) {
918a308466cSMark Brown 		if (!ops->set_mode) {
9195da84fd9SJoe Perches 			rdev_err(rdev, "no set_mode operation\n");
920a308466cSMark Brown 			ret = -EINVAL;
921a308466cSMark Brown 			goto out;
922a308466cSMark Brown 		}
923a308466cSMark Brown 
924f8c12fe3SMark Brown 		ret = ops->set_mode(rdev, rdev->constraints->initial_mode);
925a308466cSMark Brown 		if (ret < 0) {
9265da84fd9SJoe Perches 			rdev_err(rdev, "failed to set initial mode: %d\n", ret);
927a308466cSMark Brown 			goto out;
928a308466cSMark Brown 		}
929a308466cSMark Brown 	}
930a308466cSMark Brown 
931cacf90f2SMark Brown 	/* If the constraints say the regulator should be on at this point
932cacf90f2SMark Brown 	 * and we have control then make sure it is enabled.
933cacf90f2SMark Brown 	 */
934f8c12fe3SMark Brown 	if ((rdev->constraints->always_on || rdev->constraints->boot_on) &&
935f8c12fe3SMark Brown 	    ops->enable) {
936e5fda26cSMark Brown 		ret = ops->enable(rdev);
937e5fda26cSMark Brown 		if (ret < 0) {
9385da84fd9SJoe Perches 			rdev_err(rdev, "failed to enable\n");
939e5fda26cSMark Brown 			goto out;
940e5fda26cSMark Brown 		}
941e5fda26cSMark Brown 	}
942e5fda26cSMark Brown 
9436f0b2c69SYadwinder Singh Brar 	if (rdev->constraints->ramp_delay && ops->set_ramp_delay) {
9446f0b2c69SYadwinder Singh Brar 		ret = ops->set_ramp_delay(rdev, rdev->constraints->ramp_delay);
9456f0b2c69SYadwinder Singh Brar 		if (ret < 0) {
9466f0b2c69SYadwinder Singh Brar 			rdev_err(rdev, "failed to set ramp_delay\n");
9476f0b2c69SYadwinder Singh Brar 			goto out;
9486f0b2c69SYadwinder Singh Brar 		}
9496f0b2c69SYadwinder Singh Brar 	}
9506f0b2c69SYadwinder Singh Brar 
951a5766f11SLiam Girdwood 	print_constraints(rdev);
9521a6958e7SAxel Lin 	return 0;
953a5766f11SLiam Girdwood out:
9541a6958e7SAxel Lin 	kfree(rdev->constraints);
9551a6958e7SAxel Lin 	rdev->constraints = NULL;
956a5766f11SLiam Girdwood 	return ret;
957a5766f11SLiam Girdwood }
958a5766f11SLiam Girdwood 
959a5766f11SLiam Girdwood /**
960a5766f11SLiam Girdwood  * set_supply - set regulator supply regulator
96169279fb9SMark Brown  * @rdev: regulator name
96269279fb9SMark Brown  * @supply_rdev: supply regulator name
963a5766f11SLiam Girdwood  *
964a5766f11SLiam Girdwood  * Called by platform initialisation code to set the supply regulator for this
965a5766f11SLiam Girdwood  * regulator. This ensures that a regulators supply will also be enabled by the
966a5766f11SLiam Girdwood  * core if it's child is enabled.
967a5766f11SLiam Girdwood  */
968a5766f11SLiam Girdwood static int set_supply(struct regulator_dev *rdev,
969a5766f11SLiam Girdwood 		      struct regulator_dev *supply_rdev)
970a5766f11SLiam Girdwood {
971a5766f11SLiam Girdwood 	int err;
972a5766f11SLiam Girdwood 
9733801b86aSMark Brown 	rdev_info(rdev, "supplied by %s\n", rdev_get_name(supply_rdev));
9743801b86aSMark Brown 
9753801b86aSMark Brown 	rdev->supply = create_regulator(supply_rdev, &rdev->dev, "SUPPLY");
97632c78de8SAxel Lin 	if (rdev->supply == NULL) {
97732c78de8SAxel Lin 		err = -ENOMEM;
978a5766f11SLiam Girdwood 		return err;
979a5766f11SLiam Girdwood 	}
98057ad526aSLaxman Dewangan 	supply_rdev->open_count++;
981a5766f11SLiam Girdwood 
9823801b86aSMark Brown 	return 0;
9833801b86aSMark Brown }
9843801b86aSMark Brown 
985a5766f11SLiam Girdwood /**
98606c63f93SRandy Dunlap  * set_consumer_device_supply - Bind a regulator to a symbolic supply
98769279fb9SMark Brown  * @rdev:         regulator source
98840f9244fSMark Brown  * @consumer_dev_name: dev_name() string for device supply applies to
989a5766f11SLiam Girdwood  * @supply:       symbolic name for supply
990a5766f11SLiam Girdwood  *
991a5766f11SLiam Girdwood  * Allows platform initialisation code to map physical regulator
992a5766f11SLiam Girdwood  * sources to symbolic names for supplies for use by devices.  Devices
993a5766f11SLiam Girdwood  * should use these symbolic names to request regulators, avoiding the
994a5766f11SLiam Girdwood  * need to provide board-specific regulator names as platform data.
995a5766f11SLiam Girdwood  */
996a5766f11SLiam Girdwood static int set_consumer_device_supply(struct regulator_dev *rdev,
997737f360dSMark Brown 				      const char *consumer_dev_name,
99840f9244fSMark Brown 				      const char *supply)
999a5766f11SLiam Girdwood {
1000a5766f11SLiam Girdwood 	struct regulator_map *node;
10019ed2099eSMark Brown 	int has_dev;
1002a5766f11SLiam Girdwood 
1003a5766f11SLiam Girdwood 	if (supply == NULL)
1004a5766f11SLiam Girdwood 		return -EINVAL;
1005a5766f11SLiam Girdwood 
10069ed2099eSMark Brown 	if (consumer_dev_name != NULL)
10079ed2099eSMark Brown 		has_dev = 1;
10089ed2099eSMark Brown 	else
10099ed2099eSMark Brown 		has_dev = 0;
10109ed2099eSMark Brown 
10116001e13cSDavid Brownell 	list_for_each_entry(node, &regulator_map_list, list) {
101223b5cc2aSJani Nikula 		if (node->dev_name && consumer_dev_name) {
101323b5cc2aSJani Nikula 			if (strcmp(node->dev_name, consumer_dev_name) != 0)
10146001e13cSDavid Brownell 				continue;
101523b5cc2aSJani Nikula 		} else if (node->dev_name || consumer_dev_name) {
101623b5cc2aSJani Nikula 			continue;
101723b5cc2aSJani Nikula 		}
101823b5cc2aSJani Nikula 
10196001e13cSDavid Brownell 		if (strcmp(node->supply, supply) != 0)
10206001e13cSDavid Brownell 			continue;
10216001e13cSDavid Brownell 
1022737f360dSMark Brown 		pr_debug("%s: %s/%s is '%s' supply; fail %s/%s\n",
1023737f360dSMark Brown 			 consumer_dev_name,
10246001e13cSDavid Brownell 			 dev_name(&node->regulator->dev),
10256001e13cSDavid Brownell 			 node->regulator->desc->name,
10266001e13cSDavid Brownell 			 supply,
10271083c393SMark Brown 			 dev_name(&rdev->dev), rdev_get_name(rdev));
10286001e13cSDavid Brownell 		return -EBUSY;
10296001e13cSDavid Brownell 	}
10306001e13cSDavid Brownell 
10319ed2099eSMark Brown 	node = kzalloc(sizeof(struct regulator_map), GFP_KERNEL);
1032a5766f11SLiam Girdwood 	if (node == NULL)
1033a5766f11SLiam Girdwood 		return -ENOMEM;
1034a5766f11SLiam Girdwood 
1035a5766f11SLiam Girdwood 	node->regulator = rdev;
1036a5766f11SLiam Girdwood 	node->supply = supply;
1037a5766f11SLiam Girdwood 
10389ed2099eSMark Brown 	if (has_dev) {
10399ed2099eSMark Brown 		node->dev_name = kstrdup(consumer_dev_name, GFP_KERNEL);
104040f9244fSMark Brown 		if (node->dev_name == NULL) {
104140f9244fSMark Brown 			kfree(node);
104240f9244fSMark Brown 			return -ENOMEM;
104340f9244fSMark Brown 		}
10449ed2099eSMark Brown 	}
104540f9244fSMark Brown 
1046a5766f11SLiam Girdwood 	list_add(&node->list, &regulator_map_list);
1047a5766f11SLiam Girdwood 	return 0;
1048a5766f11SLiam Girdwood }
1049a5766f11SLiam Girdwood 
10500f1d747bSMike Rapoport static void unset_regulator_supplies(struct regulator_dev *rdev)
10510f1d747bSMike Rapoport {
10520f1d747bSMike Rapoport 	struct regulator_map *node, *n;
10530f1d747bSMike Rapoport 
10540f1d747bSMike Rapoport 	list_for_each_entry_safe(node, n, &regulator_map_list, list) {
10550f1d747bSMike Rapoport 		if (rdev == node->regulator) {
10560f1d747bSMike Rapoport 			list_del(&node->list);
105740f9244fSMark Brown 			kfree(node->dev_name);
10580f1d747bSMike Rapoport 			kfree(node);
10590f1d747bSMike Rapoport 		}
10600f1d747bSMike Rapoport 	}
10610f1d747bSMike Rapoport }
10620f1d747bSMike Rapoport 
1063f5726ae3SMark Brown #define REG_STR_SIZE	64
1064414c70cbSLiam Girdwood 
1065414c70cbSLiam Girdwood static struct regulator *create_regulator(struct regulator_dev *rdev,
1066414c70cbSLiam Girdwood 					  struct device *dev,
1067414c70cbSLiam Girdwood 					  const char *supply_name)
1068414c70cbSLiam Girdwood {
1069414c70cbSLiam Girdwood 	struct regulator *regulator;
1070414c70cbSLiam Girdwood 	char buf[REG_STR_SIZE];
1071414c70cbSLiam Girdwood 	int err, size;
1072414c70cbSLiam Girdwood 
1073414c70cbSLiam Girdwood 	regulator = kzalloc(sizeof(*regulator), GFP_KERNEL);
1074414c70cbSLiam Girdwood 	if (regulator == NULL)
1075414c70cbSLiam Girdwood 		return NULL;
1076414c70cbSLiam Girdwood 
1077414c70cbSLiam Girdwood 	mutex_lock(&rdev->mutex);
1078414c70cbSLiam Girdwood 	regulator->rdev = rdev;
1079414c70cbSLiam Girdwood 	list_add(&regulator->list, &rdev->consumer_list);
1080414c70cbSLiam Girdwood 
1081414c70cbSLiam Girdwood 	if (dev) {
1082e2c98eafSShawn Guo 		regulator->dev = dev;
1083e2c98eafSShawn Guo 
1084222cc7b1SMark Brown 		/* Add a link to the device sysfs entry */
1085414c70cbSLiam Girdwood 		size = scnprintf(buf, REG_STR_SIZE, "%s-%s",
1086414c70cbSLiam Girdwood 				 dev->kobj.name, supply_name);
1087414c70cbSLiam Girdwood 		if (size >= REG_STR_SIZE)
1088222cc7b1SMark Brown 			goto overflow_err;
1089414c70cbSLiam Girdwood 
1090414c70cbSLiam Girdwood 		regulator->supply_name = kstrdup(buf, GFP_KERNEL);
1091414c70cbSLiam Girdwood 		if (regulator->supply_name == NULL)
1092222cc7b1SMark Brown 			goto overflow_err;
1093414c70cbSLiam Girdwood 
1094414c70cbSLiam Girdwood 		err = sysfs_create_link(&rdev->dev.kobj, &dev->kobj,
1095414c70cbSLiam Girdwood 					buf);
1096414c70cbSLiam Girdwood 		if (err) {
10975da84fd9SJoe Perches 			rdev_warn(rdev, "could not add device link %s err %d\n",
10981d7372e1SDaniel Walker 				  dev->kobj.name, err);
1099222cc7b1SMark Brown 			/* non-fatal */
1100414c70cbSLiam Girdwood 		}
11015de70519SMark Brown 	} else {
11025de70519SMark Brown 		regulator->supply_name = kstrdup(supply_name, GFP_KERNEL);
11035de70519SMark Brown 		if (regulator->supply_name == NULL)
1104222cc7b1SMark Brown 			goto overflow_err;
1105414c70cbSLiam Girdwood 	}
11065de70519SMark Brown 
11075de70519SMark Brown 	regulator->debugfs = debugfs_create_dir(regulator->supply_name,
11085de70519SMark Brown 						rdev->debugfs);
110924751434SStephen Boyd 	if (!regulator->debugfs) {
11105de70519SMark Brown 		rdev_warn(rdev, "Failed to create debugfs directory\n");
11115de70519SMark Brown 	} else {
11125de70519SMark Brown 		debugfs_create_u32("uA_load", 0444, regulator->debugfs,
11135de70519SMark Brown 				   &regulator->uA_load);
11145de70519SMark Brown 		debugfs_create_u32("min_uV", 0444, regulator->debugfs,
11155de70519SMark Brown 				   &regulator->min_uV);
11165de70519SMark Brown 		debugfs_create_u32("max_uV", 0444, regulator->debugfs,
11175de70519SMark Brown 				   &regulator->max_uV);
11185de70519SMark Brown 	}
11195de70519SMark Brown 
11206492bc1bSMark Brown 	/*
11216492bc1bSMark Brown 	 * Check now if the regulator is an always on regulator - if
11226492bc1bSMark Brown 	 * it is then we don't need to do nearly so much work for
11236492bc1bSMark Brown 	 * enable/disable calls.
11246492bc1bSMark Brown 	 */
11256492bc1bSMark Brown 	if (!_regulator_can_change_status(rdev) &&
11266492bc1bSMark Brown 	    _regulator_is_enabled(rdev))
11276492bc1bSMark Brown 		regulator->always_on = true;
11286492bc1bSMark Brown 
1129414c70cbSLiam Girdwood 	mutex_unlock(&rdev->mutex);
1130414c70cbSLiam Girdwood 	return regulator;
1131414c70cbSLiam Girdwood overflow_err:
1132414c70cbSLiam Girdwood 	list_del(&regulator->list);
1133414c70cbSLiam Girdwood 	kfree(regulator);
1134414c70cbSLiam Girdwood 	mutex_unlock(&rdev->mutex);
1135414c70cbSLiam Girdwood 	return NULL;
1136414c70cbSLiam Girdwood }
1137414c70cbSLiam Girdwood 
113831aae2beSMark Brown static int _regulator_get_enable_time(struct regulator_dev *rdev)
113931aae2beSMark Brown {
114031aae2beSMark Brown 	if (!rdev->desc->ops->enable_time)
114179511ed3SMark Brown 		return rdev->desc->enable_time;
114231aae2beSMark Brown 	return rdev->desc->ops->enable_time(rdev);
114331aae2beSMark Brown }
114431aae2beSMark Brown 
114569511a45SRajendra Nayak static struct regulator_dev *regulator_dev_lookup(struct device *dev,
11466d191a5fSMark Brown 						  const char *supply,
11476d191a5fSMark Brown 						  int *ret)
114869511a45SRajendra Nayak {
114969511a45SRajendra Nayak 	struct regulator_dev *r;
115069511a45SRajendra Nayak 	struct device_node *node;
1151576ca436SMark Brown 	struct regulator_map *map;
1152576ca436SMark Brown 	const char *devname = NULL;
115369511a45SRajendra Nayak 
115469511a45SRajendra Nayak 	/* first do a dt based lookup */
115569511a45SRajendra Nayak 	if (dev && dev->of_node) {
115669511a45SRajendra Nayak 		node = of_get_regulator(dev, supply);
11576d191a5fSMark Brown 		if (node) {
115869511a45SRajendra Nayak 			list_for_each_entry(r, &regulator_list, list)
115969511a45SRajendra Nayak 				if (r->dev.parent &&
116069511a45SRajendra Nayak 					node == r->dev.of_node)
116169511a45SRajendra Nayak 					return r;
11626d191a5fSMark Brown 		} else {
11636d191a5fSMark Brown 			/*
11646d191a5fSMark Brown 			 * If we couldn't even get the node then it's
11656d191a5fSMark Brown 			 * not just that the device didn't register
11666d191a5fSMark Brown 			 * yet, there's no node and we'll never
11676d191a5fSMark Brown 			 * succeed.
11686d191a5fSMark Brown 			 */
11696d191a5fSMark Brown 			*ret = -ENODEV;
11706d191a5fSMark Brown 		}
117169511a45SRajendra Nayak 	}
117269511a45SRajendra Nayak 
117369511a45SRajendra Nayak 	/* if not found, try doing it non-dt way */
1174576ca436SMark Brown 	if (dev)
1175576ca436SMark Brown 		devname = dev_name(dev);
1176576ca436SMark Brown 
117769511a45SRajendra Nayak 	list_for_each_entry(r, &regulator_list, list)
117869511a45SRajendra Nayak 		if (strcmp(rdev_get_name(r), supply) == 0)
117969511a45SRajendra Nayak 			return r;
118069511a45SRajendra Nayak 
1181576ca436SMark Brown 	list_for_each_entry(map, &regulator_map_list, list) {
1182576ca436SMark Brown 		/* If the mapping has a device set up it must match */
1183576ca436SMark Brown 		if (map->dev_name &&
1184576ca436SMark Brown 		    (!devname || strcmp(map->dev_name, devname)))
1185576ca436SMark Brown 			continue;
1186576ca436SMark Brown 
1187576ca436SMark Brown 		if (strcmp(map->supply, supply) == 0)
1188576ca436SMark Brown 			return map->regulator;
1189576ca436SMark Brown 	}
1190576ca436SMark Brown 
1191576ca436SMark Brown 
119269511a45SRajendra Nayak 	return NULL;
119369511a45SRajendra Nayak }
119469511a45SRajendra Nayak 
11955ffbd136SMark Brown /* Internal regulator request function */
11965ffbd136SMark Brown static struct regulator *_regulator_get(struct device *dev, const char *id,
11975ffbd136SMark Brown 					int exclusive)
1198414c70cbSLiam Girdwood {
1199414c70cbSLiam Girdwood 	struct regulator_dev *rdev;
120004bf3011SMark Brown 	struct regulator *regulator = ERR_PTR(-EPROBE_DEFER);
120140f9244fSMark Brown 	const char *devname = NULL;
12025ffbd136SMark Brown 	int ret;
1203414c70cbSLiam Girdwood 
1204414c70cbSLiam Girdwood 	if (id == NULL) {
12055da84fd9SJoe Perches 		pr_err("get() with no identifier\n");
1206414c70cbSLiam Girdwood 		return regulator;
1207414c70cbSLiam Girdwood 	}
1208414c70cbSLiam Girdwood 
120940f9244fSMark Brown 	if (dev)
121040f9244fSMark Brown 		devname = dev_name(dev);
121140f9244fSMark Brown 
1212414c70cbSLiam Girdwood 	mutex_lock(&regulator_list_mutex);
1213414c70cbSLiam Girdwood 
12146d191a5fSMark Brown 	rdev = regulator_dev_lookup(dev, id, &ret);
121569511a45SRajendra Nayak 	if (rdev)
121669511a45SRajendra Nayak 		goto found;
121769511a45SRajendra Nayak 
1218688fe99aSMark Brown 	if (board_wants_dummy_regulator) {
1219688fe99aSMark Brown 		rdev = dummy_regulator_rdev;
1220688fe99aSMark Brown 		goto found;
1221688fe99aSMark Brown 	}
1222688fe99aSMark Brown 
122334abbd68SMark Brown #ifdef CONFIG_REGULATOR_DUMMY
122434abbd68SMark Brown 	if (!devname)
122534abbd68SMark Brown 		devname = "deviceless";
122634abbd68SMark Brown 
122734abbd68SMark Brown 	/* If the board didn't flag that it was fully constrained then
122834abbd68SMark Brown 	 * substitute in a dummy regulator so consumers can continue.
122934abbd68SMark Brown 	 */
123034abbd68SMark Brown 	if (!has_full_constraints) {
12315da84fd9SJoe Perches 		pr_warn("%s supply %s not found, using dummy regulator\n",
123234abbd68SMark Brown 			devname, id);
123334abbd68SMark Brown 		rdev = dummy_regulator_rdev;
123434abbd68SMark Brown 		goto found;
123534abbd68SMark Brown 	}
123634abbd68SMark Brown #endif
123734abbd68SMark Brown 
1238414c70cbSLiam Girdwood 	mutex_unlock(&regulator_list_mutex);
1239414c70cbSLiam Girdwood 	return regulator;
1240414c70cbSLiam Girdwood 
1241414c70cbSLiam Girdwood found:
12425ffbd136SMark Brown 	if (rdev->exclusive) {
12435ffbd136SMark Brown 		regulator = ERR_PTR(-EPERM);
12445ffbd136SMark Brown 		goto out;
12455ffbd136SMark Brown 	}
12465ffbd136SMark Brown 
12475ffbd136SMark Brown 	if (exclusive && rdev->open_count) {
12485ffbd136SMark Brown 		regulator = ERR_PTR(-EBUSY);
12495ffbd136SMark Brown 		goto out;
12505ffbd136SMark Brown 	}
12515ffbd136SMark Brown 
1252a5766f11SLiam Girdwood 	if (!try_module_get(rdev->owner))
1253a5766f11SLiam Girdwood 		goto out;
1254a5766f11SLiam Girdwood 
1255414c70cbSLiam Girdwood 	regulator = create_regulator(rdev, dev, id);
1256414c70cbSLiam Girdwood 	if (regulator == NULL) {
1257414c70cbSLiam Girdwood 		regulator = ERR_PTR(-ENOMEM);
1258414c70cbSLiam Girdwood 		module_put(rdev->owner);
1259bcda4321SAxel Lin 		goto out;
1260414c70cbSLiam Girdwood 	}
1261414c70cbSLiam Girdwood 
12625ffbd136SMark Brown 	rdev->open_count++;
12635ffbd136SMark Brown 	if (exclusive) {
12645ffbd136SMark Brown 		rdev->exclusive = 1;
12655ffbd136SMark Brown 
12665ffbd136SMark Brown 		ret = _regulator_is_enabled(rdev);
12675ffbd136SMark Brown 		if (ret > 0)
12685ffbd136SMark Brown 			rdev->use_count = 1;
12695ffbd136SMark Brown 		else
12705ffbd136SMark Brown 			rdev->use_count = 0;
12715ffbd136SMark Brown 	}
12725ffbd136SMark Brown 
1273a5766f11SLiam Girdwood out:
1274414c70cbSLiam Girdwood 	mutex_unlock(&regulator_list_mutex);
12755ffbd136SMark Brown 
1276414c70cbSLiam Girdwood 	return regulator;
1277414c70cbSLiam Girdwood }
12785ffbd136SMark Brown 
12795ffbd136SMark Brown /**
12805ffbd136SMark Brown  * regulator_get - lookup and obtain a reference to a regulator.
12815ffbd136SMark Brown  * @dev: device for regulator "consumer"
12825ffbd136SMark Brown  * @id: Supply name or regulator ID.
12835ffbd136SMark Brown  *
12845ffbd136SMark Brown  * Returns a struct regulator corresponding to the regulator producer,
12855ffbd136SMark Brown  * or IS_ERR() condition containing errno.
12865ffbd136SMark Brown  *
12875ffbd136SMark Brown  * Use of supply names configured via regulator_set_device_supply() is
12885ffbd136SMark Brown  * strongly encouraged.  It is recommended that the supply name used
12895ffbd136SMark Brown  * should match the name used for the supply and/or the relevant
12905ffbd136SMark Brown  * device pins in the datasheet.
12915ffbd136SMark Brown  */
12925ffbd136SMark Brown struct regulator *regulator_get(struct device *dev, const char *id)
12935ffbd136SMark Brown {
12945ffbd136SMark Brown 	return _regulator_get(dev, id, 0);
12955ffbd136SMark Brown }
1296414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_get);
1297414c70cbSLiam Girdwood 
1298070b9079SStephen Boyd static void devm_regulator_release(struct device *dev, void *res)
1299070b9079SStephen Boyd {
1300070b9079SStephen Boyd 	regulator_put(*(struct regulator **)res);
1301070b9079SStephen Boyd }
1302070b9079SStephen Boyd 
1303070b9079SStephen Boyd /**
1304070b9079SStephen Boyd  * devm_regulator_get - Resource managed regulator_get()
1305070b9079SStephen Boyd  * @dev: device for regulator "consumer"
1306070b9079SStephen Boyd  * @id: Supply name or regulator ID.
1307070b9079SStephen Boyd  *
1308070b9079SStephen Boyd  * Managed regulator_get(). Regulators returned from this function are
1309070b9079SStephen Boyd  * automatically regulator_put() on driver detach. See regulator_get() for more
1310070b9079SStephen Boyd  * information.
1311070b9079SStephen Boyd  */
1312070b9079SStephen Boyd struct regulator *devm_regulator_get(struct device *dev, const char *id)
1313070b9079SStephen Boyd {
1314070b9079SStephen Boyd 	struct regulator **ptr, *regulator;
1315070b9079SStephen Boyd 
1316070b9079SStephen Boyd 	ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL);
1317070b9079SStephen Boyd 	if (!ptr)
1318070b9079SStephen Boyd 		return ERR_PTR(-ENOMEM);
1319070b9079SStephen Boyd 
1320070b9079SStephen Boyd 	regulator = regulator_get(dev, id);
1321070b9079SStephen Boyd 	if (!IS_ERR(regulator)) {
1322070b9079SStephen Boyd 		*ptr = regulator;
1323070b9079SStephen Boyd 		devres_add(dev, ptr);
1324070b9079SStephen Boyd 	} else {
1325070b9079SStephen Boyd 		devres_free(ptr);
1326070b9079SStephen Boyd 	}
1327070b9079SStephen Boyd 
1328070b9079SStephen Boyd 	return regulator;
1329070b9079SStephen Boyd }
1330070b9079SStephen Boyd EXPORT_SYMBOL_GPL(devm_regulator_get);
1331070b9079SStephen Boyd 
1332414c70cbSLiam Girdwood /**
13335ffbd136SMark Brown  * regulator_get_exclusive - obtain exclusive access to a regulator.
13345ffbd136SMark Brown  * @dev: device for regulator "consumer"
13355ffbd136SMark Brown  * @id: Supply name or regulator ID.
13365ffbd136SMark Brown  *
13375ffbd136SMark Brown  * Returns a struct regulator corresponding to the regulator producer,
13385ffbd136SMark Brown  * or IS_ERR() condition containing errno.  Other consumers will be
13395ffbd136SMark Brown  * unable to obtain this reference is held and the use count for the
13405ffbd136SMark Brown  * regulator will be initialised to reflect the current state of the
13415ffbd136SMark Brown  * regulator.
13425ffbd136SMark Brown  *
13435ffbd136SMark Brown  * This is intended for use by consumers which cannot tolerate shared
13445ffbd136SMark Brown  * use of the regulator such as those which need to force the
13455ffbd136SMark Brown  * regulator off for correct operation of the hardware they are
13465ffbd136SMark Brown  * controlling.
13475ffbd136SMark Brown  *
13485ffbd136SMark Brown  * Use of supply names configured via regulator_set_device_supply() is
13495ffbd136SMark Brown  * strongly encouraged.  It is recommended that the supply name used
13505ffbd136SMark Brown  * should match the name used for the supply and/or the relevant
13515ffbd136SMark Brown  * device pins in the datasheet.
13525ffbd136SMark Brown  */
13535ffbd136SMark Brown struct regulator *regulator_get_exclusive(struct device *dev, const char *id)
13545ffbd136SMark Brown {
13555ffbd136SMark Brown 	return _regulator_get(dev, id, 1);
13565ffbd136SMark Brown }
13575ffbd136SMark Brown EXPORT_SYMBOL_GPL(regulator_get_exclusive);
13585ffbd136SMark Brown 
13595ffbd136SMark Brown /**
1360414c70cbSLiam Girdwood  * regulator_put - "free" the regulator source
1361414c70cbSLiam Girdwood  * @regulator: regulator source
1362414c70cbSLiam Girdwood  *
1363414c70cbSLiam Girdwood  * Note: drivers must ensure that all regulator_enable calls made on this
1364414c70cbSLiam Girdwood  * regulator source are balanced by regulator_disable calls prior to calling
1365414c70cbSLiam Girdwood  * this function.
1366414c70cbSLiam Girdwood  */
1367414c70cbSLiam Girdwood void regulator_put(struct regulator *regulator)
1368414c70cbSLiam Girdwood {
1369414c70cbSLiam Girdwood 	struct regulator_dev *rdev;
1370414c70cbSLiam Girdwood 
1371414c70cbSLiam Girdwood 	if (regulator == NULL || IS_ERR(regulator))
1372414c70cbSLiam Girdwood 		return;
1373414c70cbSLiam Girdwood 
1374414c70cbSLiam Girdwood 	mutex_lock(&regulator_list_mutex);
1375414c70cbSLiam Girdwood 	rdev = regulator->rdev;
1376414c70cbSLiam Girdwood 
13775de70519SMark Brown 	debugfs_remove_recursive(regulator->debugfs);
13785de70519SMark Brown 
1379414c70cbSLiam Girdwood 	/* remove any sysfs entries */
1380e2c98eafSShawn Guo 	if (regulator->dev)
1381414c70cbSLiam Girdwood 		sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name);
13825de70519SMark Brown 	kfree(regulator->supply_name);
1383414c70cbSLiam Girdwood 	list_del(&regulator->list);
1384414c70cbSLiam Girdwood 	kfree(regulator);
1385414c70cbSLiam Girdwood 
13865ffbd136SMark Brown 	rdev->open_count--;
13875ffbd136SMark Brown 	rdev->exclusive = 0;
13885ffbd136SMark Brown 
1389414c70cbSLiam Girdwood 	module_put(rdev->owner);
1390414c70cbSLiam Girdwood 	mutex_unlock(&regulator_list_mutex);
1391414c70cbSLiam Girdwood }
1392414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_put);
1393414c70cbSLiam Girdwood 
1394d5ad34f7SMark Brown static int devm_regulator_match(struct device *dev, void *res, void *data)
1395d5ad34f7SMark Brown {
1396d5ad34f7SMark Brown 	struct regulator **r = res;
1397d5ad34f7SMark Brown 	if (!r || !*r) {
1398d5ad34f7SMark Brown 		WARN_ON(!r || !*r);
1399d5ad34f7SMark Brown 		return 0;
1400d5ad34f7SMark Brown 	}
1401d5ad34f7SMark Brown 	return *r == data;
1402d5ad34f7SMark Brown }
1403d5ad34f7SMark Brown 
1404d5ad34f7SMark Brown /**
1405d5ad34f7SMark Brown  * devm_regulator_put - Resource managed regulator_put()
1406d5ad34f7SMark Brown  * @regulator: regulator to free
1407d5ad34f7SMark Brown  *
1408d5ad34f7SMark Brown  * Deallocate a regulator allocated with devm_regulator_get(). Normally
1409d5ad34f7SMark Brown  * this function will not need to be called and the resource management
1410d5ad34f7SMark Brown  * code will ensure that the resource is freed.
1411d5ad34f7SMark Brown  */
1412d5ad34f7SMark Brown void devm_regulator_put(struct regulator *regulator)
1413d5ad34f7SMark Brown {
1414d5ad34f7SMark Brown 	int rc;
1415d5ad34f7SMark Brown 
1416361ff501SMark Brown 	rc = devres_release(regulator->dev, devm_regulator_release,
1417d5ad34f7SMark Brown 			    devm_regulator_match, regulator);
1418230a5a1cSMark Brown 	if (rc != 0)
1419d5ad34f7SMark Brown 		WARN_ON(rc);
1420d5ad34f7SMark Brown }
1421d5ad34f7SMark Brown EXPORT_SYMBOL_GPL(devm_regulator_put);
1422d5ad34f7SMark Brown 
14235c5659d0SMark Brown static int _regulator_do_enable(struct regulator_dev *rdev)
14245c5659d0SMark Brown {
14255c5659d0SMark Brown 	int ret, delay;
14265c5659d0SMark Brown 
14275c5659d0SMark Brown 	/* Query before enabling in case configuration dependent.  */
14285c5659d0SMark Brown 	ret = _regulator_get_enable_time(rdev);
14295c5659d0SMark Brown 	if (ret >= 0) {
14305c5659d0SMark Brown 		delay = ret;
14315c5659d0SMark Brown 	} else {
14325c5659d0SMark Brown 		rdev_warn(rdev, "enable_time() failed: %d\n", ret);
14335c5659d0SMark Brown 		delay = 0;
14345c5659d0SMark Brown 	}
14355c5659d0SMark Brown 
14365c5659d0SMark Brown 	trace_regulator_enable(rdev_get_name(rdev));
14375c5659d0SMark Brown 
143865f73508SMark Brown 	if (rdev->ena_gpio) {
143965f73508SMark Brown 		gpio_set_value_cansleep(rdev->ena_gpio,
144065f73508SMark Brown 					!rdev->ena_gpio_invert);
144165f73508SMark Brown 		rdev->ena_gpio_state = 1;
144265f73508SMark Brown 	} else if (rdev->desc->ops->enable) {
14435c5659d0SMark Brown 		ret = rdev->desc->ops->enable(rdev);
14445c5659d0SMark Brown 		if (ret < 0)
14455c5659d0SMark Brown 			return ret;
14465c5659d0SMark Brown 	} else {
14475c5659d0SMark Brown 		return -EINVAL;
14485c5659d0SMark Brown 	}
14495c5659d0SMark Brown 
14505c5659d0SMark Brown 	/* Allow the regulator to ramp; it would be useful to extend
14515c5659d0SMark Brown 	 * this for bulk operations so that the regulators can ramp
14525c5659d0SMark Brown 	 * together.  */
14535c5659d0SMark Brown 	trace_regulator_enable_delay(rdev_get_name(rdev));
14545c5659d0SMark Brown 
14555c5659d0SMark Brown 	if (delay >= 1000) {
14565c5659d0SMark Brown 		mdelay(delay / 1000);
14575c5659d0SMark Brown 		udelay(delay % 1000);
14585c5659d0SMark Brown 	} else if (delay) {
14595c5659d0SMark Brown 		udelay(delay);
14605c5659d0SMark Brown 	}
14615c5659d0SMark Brown 
14625c5659d0SMark Brown 	trace_regulator_enable_complete(rdev_get_name(rdev));
14635c5659d0SMark Brown 
14645c5659d0SMark Brown 	return 0;
14655c5659d0SMark Brown }
14665c5659d0SMark Brown 
1467414c70cbSLiam Girdwood /* locks held by regulator_enable() */
1468414c70cbSLiam Girdwood static int _regulator_enable(struct regulator_dev *rdev)
1469414c70cbSLiam Girdwood {
14705c5659d0SMark Brown 	int ret;
1471414c70cbSLiam Girdwood 
1472414c70cbSLiam Girdwood 	/* check voltage and requested load before enabling */
1473414c70cbSLiam Girdwood 	if (rdev->constraints &&
14749a2372faSMark Brown 	    (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS))
1475414c70cbSLiam Girdwood 		drms_uA_update(rdev);
1476414c70cbSLiam Girdwood 
14779a2372faSMark Brown 	if (rdev->use_count == 0) {
14789a2372faSMark Brown 		/* The regulator may on if it's not switchable or left on */
14799a2372faSMark Brown 		ret = _regulator_is_enabled(rdev);
14809a2372faSMark Brown 		if (ret == -EINVAL || ret == 0) {
14819a2372faSMark Brown 			if (!_regulator_can_change_status(rdev))
14829a2372faSMark Brown 				return -EPERM;
14839a2372faSMark Brown 
14845c5659d0SMark Brown 			ret = _regulator_do_enable(rdev);
14859a2372faSMark Brown 			if (ret < 0)
14869a2372faSMark Brown 				return ret;
148731aae2beSMark Brown 
1488a7433cffSLinus Walleij 		} else if (ret < 0) {
14895da84fd9SJoe Perches 			rdev_err(rdev, "is_enabled() failed: %d\n", ret);
1490414c70cbSLiam Girdwood 			return ret;
1491414c70cbSLiam Girdwood 		}
1492a7433cffSLinus Walleij 		/* Fallthrough on positive return values - already enabled */
1493414c70cbSLiam Girdwood 	}
1494414c70cbSLiam Girdwood 
14959a2372faSMark Brown 	rdev->use_count++;
14969a2372faSMark Brown 
14979a2372faSMark Brown 	return 0;
1498414c70cbSLiam Girdwood }
1499414c70cbSLiam Girdwood 
1500414c70cbSLiam Girdwood /**
1501414c70cbSLiam Girdwood  * regulator_enable - enable regulator output
1502414c70cbSLiam Girdwood  * @regulator: regulator source
1503414c70cbSLiam Girdwood  *
1504cf7bbcdfSMark Brown  * Request that the regulator be enabled with the regulator output at
1505cf7bbcdfSMark Brown  * the predefined voltage or current value.  Calls to regulator_enable()
1506cf7bbcdfSMark Brown  * must be balanced with calls to regulator_disable().
1507cf7bbcdfSMark Brown  *
1508414c70cbSLiam Girdwood  * NOTE: the output value can be set by other drivers, boot loader or may be
1509cf7bbcdfSMark Brown  * hardwired in the regulator.
1510414c70cbSLiam Girdwood  */
1511414c70cbSLiam Girdwood int regulator_enable(struct regulator *regulator)
1512414c70cbSLiam Girdwood {
1513412aec61SDavid Brownell 	struct regulator_dev *rdev = regulator->rdev;
1514412aec61SDavid Brownell 	int ret = 0;
1515414c70cbSLiam Girdwood 
15166492bc1bSMark Brown 	if (regulator->always_on)
15176492bc1bSMark Brown 		return 0;
15186492bc1bSMark Brown 
15193801b86aSMark Brown 	if (rdev->supply) {
15203801b86aSMark Brown 		ret = regulator_enable(rdev->supply);
15213801b86aSMark Brown 		if (ret != 0)
15223801b86aSMark Brown 			return ret;
15233801b86aSMark Brown 	}
15243801b86aSMark Brown 
1525412aec61SDavid Brownell 	mutex_lock(&rdev->mutex);
1526412aec61SDavid Brownell 	ret = _regulator_enable(rdev);
1527412aec61SDavid Brownell 	mutex_unlock(&rdev->mutex);
15283801b86aSMark Brown 
1529d1685e4eSHeiko Stübner 	if (ret != 0 && rdev->supply)
15303801b86aSMark Brown 		regulator_disable(rdev->supply);
15313801b86aSMark Brown 
1532414c70cbSLiam Girdwood 	return ret;
1533414c70cbSLiam Girdwood }
1534414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_enable);
1535414c70cbSLiam Girdwood 
15365c5659d0SMark Brown static int _regulator_do_disable(struct regulator_dev *rdev)
15375c5659d0SMark Brown {
15385c5659d0SMark Brown 	int ret;
15395c5659d0SMark Brown 
15405c5659d0SMark Brown 	trace_regulator_disable(rdev_get_name(rdev));
15415c5659d0SMark Brown 
15425c5659d0SMark Brown 	if (rdev->ena_gpio) {
15435c5659d0SMark Brown 		gpio_set_value_cansleep(rdev->ena_gpio,
15445c5659d0SMark Brown 					rdev->ena_gpio_invert);
15455c5659d0SMark Brown 		rdev->ena_gpio_state = 0;
15465c5659d0SMark Brown 
15475c5659d0SMark Brown 	} else if (rdev->desc->ops->disable) {
15485c5659d0SMark Brown 		ret = rdev->desc->ops->disable(rdev);
15495c5659d0SMark Brown 		if (ret != 0)
15505c5659d0SMark Brown 			return ret;
15515c5659d0SMark Brown 	}
15525c5659d0SMark Brown 
15535c5659d0SMark Brown 	trace_regulator_disable_complete(rdev_get_name(rdev));
15545c5659d0SMark Brown 
15555c5659d0SMark Brown 	_notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE,
15565c5659d0SMark Brown 			     NULL);
15575c5659d0SMark Brown 	return 0;
15585c5659d0SMark Brown }
15595c5659d0SMark Brown 
1560414c70cbSLiam Girdwood /* locks held by regulator_disable() */
15613801b86aSMark Brown static int _regulator_disable(struct regulator_dev *rdev)
1562414c70cbSLiam Girdwood {
1563414c70cbSLiam Girdwood 	int ret = 0;
1564414c70cbSLiam Girdwood 
1565cd94b505SDavid Brownell 	if (WARN(rdev->use_count <= 0,
156643e7ee33SJoe Perches 		 "unbalanced disables for %s\n", rdev_get_name(rdev)))
1567cd94b505SDavid Brownell 		return -EIO;
1568cd94b505SDavid Brownell 
1569414c70cbSLiam Girdwood 	/* are we the last user and permitted to disable ? */
157060ef66fcSMark Brown 	if (rdev->use_count == 1 &&
157160ef66fcSMark Brown 	    (rdev->constraints && !rdev->constraints->always_on)) {
1572414c70cbSLiam Girdwood 
1573414c70cbSLiam Girdwood 		/* we are last user */
15745c5659d0SMark Brown 		if (_regulator_can_change_status(rdev)) {
15755c5659d0SMark Brown 			ret = _regulator_do_disable(rdev);
1576414c70cbSLiam Girdwood 			if (ret < 0) {
15775da84fd9SJoe Perches 				rdev_err(rdev, "failed to disable\n");
1578414c70cbSLiam Girdwood 				return ret;
1579414c70cbSLiam Girdwood 			}
1580414c70cbSLiam Girdwood 		}
1581414c70cbSLiam Girdwood 
1582414c70cbSLiam Girdwood 		rdev->use_count = 0;
1583414c70cbSLiam Girdwood 	} else if (rdev->use_count > 1) {
1584414c70cbSLiam Girdwood 
1585414c70cbSLiam Girdwood 		if (rdev->constraints &&
1586414c70cbSLiam Girdwood 			(rdev->constraints->valid_ops_mask &
1587414c70cbSLiam Girdwood 			REGULATOR_CHANGE_DRMS))
1588414c70cbSLiam Girdwood 			drms_uA_update(rdev);
1589414c70cbSLiam Girdwood 
1590414c70cbSLiam Girdwood 		rdev->use_count--;
1591414c70cbSLiam Girdwood 	}
15923801b86aSMark Brown 
1593414c70cbSLiam Girdwood 	return ret;
1594414c70cbSLiam Girdwood }
1595414c70cbSLiam Girdwood 
1596414c70cbSLiam Girdwood /**
1597414c70cbSLiam Girdwood  * regulator_disable - disable regulator output
1598414c70cbSLiam Girdwood  * @regulator: regulator source
1599414c70cbSLiam Girdwood  *
1600cf7bbcdfSMark Brown  * Disable the regulator output voltage or current.  Calls to
1601cf7bbcdfSMark Brown  * regulator_enable() must be balanced with calls to
1602cf7bbcdfSMark Brown  * regulator_disable().
160369279fb9SMark Brown  *
1604414c70cbSLiam Girdwood  * NOTE: this will only disable the regulator output if no other consumer
1605cf7bbcdfSMark Brown  * devices have it enabled, the regulator device supports disabling and
1606cf7bbcdfSMark Brown  * machine constraints permit this operation.
1607414c70cbSLiam Girdwood  */
1608414c70cbSLiam Girdwood int regulator_disable(struct regulator *regulator)
1609414c70cbSLiam Girdwood {
1610412aec61SDavid Brownell 	struct regulator_dev *rdev = regulator->rdev;
1611412aec61SDavid Brownell 	int ret = 0;
1612414c70cbSLiam Girdwood 
16136492bc1bSMark Brown 	if (regulator->always_on)
16146492bc1bSMark Brown 		return 0;
16156492bc1bSMark Brown 
1616412aec61SDavid Brownell 	mutex_lock(&rdev->mutex);
16173801b86aSMark Brown 	ret = _regulator_disable(rdev);
1618412aec61SDavid Brownell 	mutex_unlock(&rdev->mutex);
16198cbf811dSJeffrey Carlyle 
16203801b86aSMark Brown 	if (ret == 0 && rdev->supply)
16213801b86aSMark Brown 		regulator_disable(rdev->supply);
16228cbf811dSJeffrey Carlyle 
1623414c70cbSLiam Girdwood 	return ret;
1624414c70cbSLiam Girdwood }
1625414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_disable);
1626414c70cbSLiam Girdwood 
1627414c70cbSLiam Girdwood /* locks held by regulator_force_disable() */
16283801b86aSMark Brown static int _regulator_force_disable(struct regulator_dev *rdev)
1629414c70cbSLiam Girdwood {
1630414c70cbSLiam Girdwood 	int ret = 0;
1631414c70cbSLiam Girdwood 
1632414c70cbSLiam Girdwood 	/* force disable */
1633414c70cbSLiam Girdwood 	if (rdev->desc->ops->disable) {
1634414c70cbSLiam Girdwood 		/* ah well, who wants to live forever... */
1635414c70cbSLiam Girdwood 		ret = rdev->desc->ops->disable(rdev);
1636414c70cbSLiam Girdwood 		if (ret < 0) {
16375da84fd9SJoe Perches 			rdev_err(rdev, "failed to force disable\n");
1638414c70cbSLiam Girdwood 			return ret;
1639414c70cbSLiam Girdwood 		}
1640414c70cbSLiam Girdwood 		/* notify other consumers that power has been forced off */
164184b68263SMark Brown 		_notifier_call_chain(rdev, REGULATOR_EVENT_FORCE_DISABLE |
164284b68263SMark Brown 			REGULATOR_EVENT_DISABLE, NULL);
1643414c70cbSLiam Girdwood 	}
1644414c70cbSLiam Girdwood 
1645414c70cbSLiam Girdwood 	return ret;
1646414c70cbSLiam Girdwood }
1647414c70cbSLiam Girdwood 
1648414c70cbSLiam Girdwood /**
1649414c70cbSLiam Girdwood  * regulator_force_disable - force disable regulator output
1650414c70cbSLiam Girdwood  * @regulator: regulator source
1651414c70cbSLiam Girdwood  *
1652414c70cbSLiam Girdwood  * Forcibly disable the regulator output voltage or current.
1653414c70cbSLiam Girdwood  * NOTE: this *will* disable the regulator output even if other consumer
1654414c70cbSLiam Girdwood  * devices have it enabled. This should be used for situations when device
1655414c70cbSLiam Girdwood  * damage will likely occur if the regulator is not disabled (e.g. over temp).
1656414c70cbSLiam Girdwood  */
1657414c70cbSLiam Girdwood int regulator_force_disable(struct regulator *regulator)
1658414c70cbSLiam Girdwood {
165982d15839SMark Brown 	struct regulator_dev *rdev = regulator->rdev;
1660414c70cbSLiam Girdwood 	int ret;
1661414c70cbSLiam Girdwood 
166282d15839SMark Brown 	mutex_lock(&rdev->mutex);
1663414c70cbSLiam Girdwood 	regulator->uA_load = 0;
16643801b86aSMark Brown 	ret = _regulator_force_disable(regulator->rdev);
166582d15839SMark Brown 	mutex_unlock(&rdev->mutex);
16668cbf811dSJeffrey Carlyle 
16673801b86aSMark Brown 	if (rdev->supply)
16683801b86aSMark Brown 		while (rdev->open_count--)
16693801b86aSMark Brown 			regulator_disable(rdev->supply);
16708cbf811dSJeffrey Carlyle 
1671414c70cbSLiam Girdwood 	return ret;
1672414c70cbSLiam Girdwood }
1673414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_force_disable);
1674414c70cbSLiam Girdwood 
1675da07ecd9SMark Brown static void regulator_disable_work(struct work_struct *work)
1676da07ecd9SMark Brown {
1677da07ecd9SMark Brown 	struct regulator_dev *rdev = container_of(work, struct regulator_dev,
1678da07ecd9SMark Brown 						  disable_work.work);
1679da07ecd9SMark Brown 	int count, i, ret;
1680da07ecd9SMark Brown 
1681da07ecd9SMark Brown 	mutex_lock(&rdev->mutex);
1682da07ecd9SMark Brown 
1683da07ecd9SMark Brown 	BUG_ON(!rdev->deferred_disables);
1684da07ecd9SMark Brown 
1685da07ecd9SMark Brown 	count = rdev->deferred_disables;
1686da07ecd9SMark Brown 	rdev->deferred_disables = 0;
1687da07ecd9SMark Brown 
1688da07ecd9SMark Brown 	for (i = 0; i < count; i++) {
1689da07ecd9SMark Brown 		ret = _regulator_disable(rdev);
1690da07ecd9SMark Brown 		if (ret != 0)
1691da07ecd9SMark Brown 			rdev_err(rdev, "Deferred disable failed: %d\n", ret);
1692da07ecd9SMark Brown 	}
1693da07ecd9SMark Brown 
1694da07ecd9SMark Brown 	mutex_unlock(&rdev->mutex);
1695da07ecd9SMark Brown 
1696da07ecd9SMark Brown 	if (rdev->supply) {
1697da07ecd9SMark Brown 		for (i = 0; i < count; i++) {
1698da07ecd9SMark Brown 			ret = regulator_disable(rdev->supply);
1699da07ecd9SMark Brown 			if (ret != 0) {
1700da07ecd9SMark Brown 				rdev_err(rdev,
1701da07ecd9SMark Brown 					 "Supply disable failed: %d\n", ret);
1702da07ecd9SMark Brown 			}
1703da07ecd9SMark Brown 		}
1704da07ecd9SMark Brown 	}
1705da07ecd9SMark Brown }
1706da07ecd9SMark Brown 
1707da07ecd9SMark Brown /**
1708da07ecd9SMark Brown  * regulator_disable_deferred - disable regulator output with delay
1709da07ecd9SMark Brown  * @regulator: regulator source
1710da07ecd9SMark Brown  * @ms: miliseconds until the regulator is disabled
1711da07ecd9SMark Brown  *
1712da07ecd9SMark Brown  * Execute regulator_disable() on the regulator after a delay.  This
1713da07ecd9SMark Brown  * is intended for use with devices that require some time to quiesce.
1714da07ecd9SMark Brown  *
1715da07ecd9SMark Brown  * NOTE: this will only disable the regulator output if no other consumer
1716da07ecd9SMark Brown  * devices have it enabled, the regulator device supports disabling and
1717da07ecd9SMark Brown  * machine constraints permit this operation.
1718da07ecd9SMark Brown  */
1719da07ecd9SMark Brown int regulator_disable_deferred(struct regulator *regulator, int ms)
1720da07ecd9SMark Brown {
1721da07ecd9SMark Brown 	struct regulator_dev *rdev = regulator->rdev;
1722aa59802dSMark Brown 	int ret;
1723da07ecd9SMark Brown 
17246492bc1bSMark Brown 	if (regulator->always_on)
17256492bc1bSMark Brown 		return 0;
17266492bc1bSMark Brown 
1727da07ecd9SMark Brown 	mutex_lock(&rdev->mutex);
1728da07ecd9SMark Brown 	rdev->deferred_disables++;
1729da07ecd9SMark Brown 	mutex_unlock(&rdev->mutex);
1730da07ecd9SMark Brown 
1731aa59802dSMark Brown 	ret = schedule_delayed_work(&rdev->disable_work,
1732da07ecd9SMark Brown 				    msecs_to_jiffies(ms));
1733aa59802dSMark Brown 	if (ret < 0)
1734aa59802dSMark Brown 		return ret;
1735aa59802dSMark Brown 	else
1736aa59802dSMark Brown 		return 0;
1737da07ecd9SMark Brown }
1738da07ecd9SMark Brown EXPORT_SYMBOL_GPL(regulator_disable_deferred);
1739da07ecd9SMark Brown 
1740cd6dffb4SMark Brown /**
1741cd6dffb4SMark Brown  * regulator_is_enabled_regmap - standard is_enabled() for regmap users
1742cd6dffb4SMark Brown  *
1743cd6dffb4SMark Brown  * @rdev: regulator to operate on
1744cd6dffb4SMark Brown  *
1745cd6dffb4SMark Brown  * Regulators that use regmap for their register I/O can set the
1746cd6dffb4SMark Brown  * enable_reg and enable_mask fields in their descriptor and then use
1747cd6dffb4SMark Brown  * this as their is_enabled operation, saving some code.
1748cd6dffb4SMark Brown  */
1749cd6dffb4SMark Brown int regulator_is_enabled_regmap(struct regulator_dev *rdev)
1750cd6dffb4SMark Brown {
1751cd6dffb4SMark Brown 	unsigned int val;
1752cd6dffb4SMark Brown 	int ret;
1753cd6dffb4SMark Brown 
1754cd6dffb4SMark Brown 	ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val);
1755cd6dffb4SMark Brown 	if (ret != 0)
1756cd6dffb4SMark Brown 		return ret;
1757cd6dffb4SMark Brown 
1758cd6dffb4SMark Brown 	return (val & rdev->desc->enable_mask) != 0;
1759cd6dffb4SMark Brown }
1760cd6dffb4SMark Brown EXPORT_SYMBOL_GPL(regulator_is_enabled_regmap);
1761cd6dffb4SMark Brown 
1762cd6dffb4SMark Brown /**
1763cd6dffb4SMark Brown  * regulator_enable_regmap - standard enable() for regmap users
1764cd6dffb4SMark Brown  *
1765cd6dffb4SMark Brown  * @rdev: regulator to operate on
1766cd6dffb4SMark Brown  *
1767cd6dffb4SMark Brown  * Regulators that use regmap for their register I/O can set the
1768cd6dffb4SMark Brown  * enable_reg and enable_mask fields in their descriptor and then use
1769cd6dffb4SMark Brown  * this as their enable() operation, saving some code.
1770cd6dffb4SMark Brown  */
1771cd6dffb4SMark Brown int regulator_enable_regmap(struct regulator_dev *rdev)
1772cd6dffb4SMark Brown {
1773cd6dffb4SMark Brown 	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
1774cd6dffb4SMark Brown 				  rdev->desc->enable_mask,
1775cd6dffb4SMark Brown 				  rdev->desc->enable_mask);
1776cd6dffb4SMark Brown }
1777cd6dffb4SMark Brown EXPORT_SYMBOL_GPL(regulator_enable_regmap);
1778cd6dffb4SMark Brown 
1779cd6dffb4SMark Brown /**
1780cd6dffb4SMark Brown  * regulator_disable_regmap - standard disable() for regmap users
1781cd6dffb4SMark Brown  *
1782cd6dffb4SMark Brown  * @rdev: regulator to operate on
1783cd6dffb4SMark Brown  *
1784cd6dffb4SMark Brown  * Regulators that use regmap for their register I/O can set the
1785cd6dffb4SMark Brown  * enable_reg and enable_mask fields in their descriptor and then use
1786cd6dffb4SMark Brown  * this as their disable() operation, saving some code.
1787cd6dffb4SMark Brown  */
1788cd6dffb4SMark Brown int regulator_disable_regmap(struct regulator_dev *rdev)
1789cd6dffb4SMark Brown {
1790cd6dffb4SMark Brown 	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
1791cd6dffb4SMark Brown 				  rdev->desc->enable_mask, 0);
1792cd6dffb4SMark Brown }
1793cd6dffb4SMark Brown EXPORT_SYMBOL_GPL(regulator_disable_regmap);
1794cd6dffb4SMark Brown 
1795414c70cbSLiam Girdwood static int _regulator_is_enabled(struct regulator_dev *rdev)
1796414c70cbSLiam Girdwood {
179765f73508SMark Brown 	/* A GPIO control always takes precedence */
179865f73508SMark Brown 	if (rdev->ena_gpio)
179965f73508SMark Brown 		return rdev->ena_gpio_state;
180065f73508SMark Brown 
18019a7f6a4cSMark Brown 	/* If we don't know then assume that the regulator is always on */
18029332546fSMark Brown 	if (!rdev->desc->ops->is_enabled)
18039a7f6a4cSMark Brown 		return 1;
1804414c70cbSLiam Girdwood 
18059332546fSMark Brown 	return rdev->desc->ops->is_enabled(rdev);
1806414c70cbSLiam Girdwood }
1807414c70cbSLiam Girdwood 
1808414c70cbSLiam Girdwood /**
1809414c70cbSLiam Girdwood  * regulator_is_enabled - is the regulator output enabled
1810414c70cbSLiam Girdwood  * @regulator: regulator source
1811414c70cbSLiam Girdwood  *
1812412aec61SDavid Brownell  * Returns positive if the regulator driver backing the source/client
1813412aec61SDavid Brownell  * has requested that the device be enabled, zero if it hasn't, else a
1814412aec61SDavid Brownell  * negative errno code.
1815412aec61SDavid Brownell  *
1816412aec61SDavid Brownell  * Note that the device backing this regulator handle can have multiple
1817412aec61SDavid Brownell  * users, so it might be enabled even if regulator_enable() was never
1818412aec61SDavid Brownell  * called for this particular source.
1819414c70cbSLiam Girdwood  */
1820414c70cbSLiam Girdwood int regulator_is_enabled(struct regulator *regulator)
1821414c70cbSLiam Girdwood {
18229332546fSMark Brown 	int ret;
18239332546fSMark Brown 
18246492bc1bSMark Brown 	if (regulator->always_on)
18256492bc1bSMark Brown 		return 1;
18266492bc1bSMark Brown 
18279332546fSMark Brown 	mutex_lock(&regulator->rdev->mutex);
18289332546fSMark Brown 	ret = _regulator_is_enabled(regulator->rdev);
18299332546fSMark Brown 	mutex_unlock(&regulator->rdev->mutex);
18309332546fSMark Brown 
18319332546fSMark Brown 	return ret;
1832414c70cbSLiam Girdwood }
1833414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_is_enabled);
1834414c70cbSLiam Girdwood 
1835414c70cbSLiam Girdwood /**
18364367cfdcSDavid Brownell  * regulator_count_voltages - count regulator_list_voltage() selectors
18374367cfdcSDavid Brownell  * @regulator: regulator source
18384367cfdcSDavid Brownell  *
18394367cfdcSDavid Brownell  * Returns number of selectors, or negative errno.  Selectors are
18404367cfdcSDavid Brownell  * numbered starting at zero, and typically correspond to bitfields
18414367cfdcSDavid Brownell  * in hardware registers.
18424367cfdcSDavid Brownell  */
18434367cfdcSDavid Brownell int regulator_count_voltages(struct regulator *regulator)
18444367cfdcSDavid Brownell {
18454367cfdcSDavid Brownell 	struct regulator_dev	*rdev = regulator->rdev;
18464367cfdcSDavid Brownell 
18474367cfdcSDavid Brownell 	return rdev->desc->n_voltages ? : -EINVAL;
18484367cfdcSDavid Brownell }
18494367cfdcSDavid Brownell EXPORT_SYMBOL_GPL(regulator_count_voltages);
18504367cfdcSDavid Brownell 
18514367cfdcSDavid Brownell /**
1852bca7bbffSMark Brown  * regulator_list_voltage_linear - List voltages with simple calculation
1853bca7bbffSMark Brown  *
1854bca7bbffSMark Brown  * @rdev: Regulator device
1855bca7bbffSMark Brown  * @selector: Selector to convert into a voltage
1856bca7bbffSMark Brown  *
1857bca7bbffSMark Brown  * Regulators with a simple linear mapping between voltages and
1858bca7bbffSMark Brown  * selectors can set min_uV and uV_step in the regulator descriptor
1859bca7bbffSMark Brown  * and then use this function as their list_voltage() operation,
1860bca7bbffSMark Brown  */
1861bca7bbffSMark Brown int regulator_list_voltage_linear(struct regulator_dev *rdev,
1862bca7bbffSMark Brown 				  unsigned int selector)
1863bca7bbffSMark Brown {
1864bca7bbffSMark Brown 	if (selector >= rdev->desc->n_voltages)
1865bca7bbffSMark Brown 		return -EINVAL;
1866bca7bbffSMark Brown 
1867bca7bbffSMark Brown 	return rdev->desc->min_uV + (rdev->desc->uV_step * selector);
1868bca7bbffSMark Brown }
1869bca7bbffSMark Brown EXPORT_SYMBOL_GPL(regulator_list_voltage_linear);
1870bca7bbffSMark Brown 
1871bca7bbffSMark Brown /**
1872cffc9592SAxel Lin  * regulator_list_voltage_table - List voltages with table based mapping
1873cffc9592SAxel Lin  *
1874cffc9592SAxel Lin  * @rdev: Regulator device
1875cffc9592SAxel Lin  * @selector: Selector to convert into a voltage
1876cffc9592SAxel Lin  *
1877cffc9592SAxel Lin  * Regulators with table based mapping between voltages and
1878cffc9592SAxel Lin  * selectors can set volt_table in the regulator descriptor
1879cffc9592SAxel Lin  * and then use this function as their list_voltage() operation.
1880cffc9592SAxel Lin  */
1881cffc9592SAxel Lin int regulator_list_voltage_table(struct regulator_dev *rdev,
1882cffc9592SAxel Lin 				 unsigned int selector)
1883cffc9592SAxel Lin {
1884cffc9592SAxel Lin 	if (!rdev->desc->volt_table) {
1885cffc9592SAxel Lin 		BUG_ON(!rdev->desc->volt_table);
1886cffc9592SAxel Lin 		return -EINVAL;
1887cffc9592SAxel Lin 	}
1888cffc9592SAxel Lin 
1889cffc9592SAxel Lin 	if (selector >= rdev->desc->n_voltages)
1890cffc9592SAxel Lin 		return -EINVAL;
1891cffc9592SAxel Lin 
1892cffc9592SAxel Lin 	return rdev->desc->volt_table[selector];
1893cffc9592SAxel Lin }
1894cffc9592SAxel Lin EXPORT_SYMBOL_GPL(regulator_list_voltage_table);
1895cffc9592SAxel Lin 
1896cffc9592SAxel Lin /**
18974367cfdcSDavid Brownell  * regulator_list_voltage - enumerate supported voltages
18984367cfdcSDavid Brownell  * @regulator: regulator source
18994367cfdcSDavid Brownell  * @selector: identify voltage to list
19004367cfdcSDavid Brownell  * Context: can sleep
19014367cfdcSDavid Brownell  *
19024367cfdcSDavid Brownell  * Returns a voltage that can be passed to @regulator_set_voltage(),
190388393161SThomas Weber  * zero if this selector code can't be used on this system, or a
19044367cfdcSDavid Brownell  * negative errno.
19054367cfdcSDavid Brownell  */
19064367cfdcSDavid Brownell int regulator_list_voltage(struct regulator *regulator, unsigned selector)
19074367cfdcSDavid Brownell {
19084367cfdcSDavid Brownell 	struct regulator_dev	*rdev = regulator->rdev;
19094367cfdcSDavid Brownell 	struct regulator_ops	*ops = rdev->desc->ops;
19104367cfdcSDavid Brownell 	int			ret;
19114367cfdcSDavid Brownell 
19124367cfdcSDavid Brownell 	if (!ops->list_voltage || selector >= rdev->desc->n_voltages)
19134367cfdcSDavid Brownell 		return -EINVAL;
19144367cfdcSDavid Brownell 
19154367cfdcSDavid Brownell 	mutex_lock(&rdev->mutex);
19164367cfdcSDavid Brownell 	ret = ops->list_voltage(rdev, selector);
19174367cfdcSDavid Brownell 	mutex_unlock(&rdev->mutex);
19184367cfdcSDavid Brownell 
19194367cfdcSDavid Brownell 	if (ret > 0) {
19204367cfdcSDavid Brownell 		if (ret < rdev->constraints->min_uV)
19214367cfdcSDavid Brownell 			ret = 0;
19224367cfdcSDavid Brownell 		else if (ret > rdev->constraints->max_uV)
19234367cfdcSDavid Brownell 			ret = 0;
19244367cfdcSDavid Brownell 	}
19254367cfdcSDavid Brownell 
19264367cfdcSDavid Brownell 	return ret;
19274367cfdcSDavid Brownell }
19284367cfdcSDavid Brownell EXPORT_SYMBOL_GPL(regulator_list_voltage);
19294367cfdcSDavid Brownell 
19304367cfdcSDavid Brownell /**
1931a7a1ad90SMark Brown  * regulator_is_supported_voltage - check if a voltage range can be supported
1932a7a1ad90SMark Brown  *
1933a7a1ad90SMark Brown  * @regulator: Regulator to check.
1934a7a1ad90SMark Brown  * @min_uV: Minimum required voltage in uV.
1935a7a1ad90SMark Brown  * @max_uV: Maximum required voltage in uV.
1936a7a1ad90SMark Brown  *
1937a7a1ad90SMark Brown  * Returns a boolean or a negative error code.
1938a7a1ad90SMark Brown  */
1939a7a1ad90SMark Brown int regulator_is_supported_voltage(struct regulator *regulator,
1940a7a1ad90SMark Brown 				   int min_uV, int max_uV)
1941a7a1ad90SMark Brown {
1942c5f3939bSMark Brown 	struct regulator_dev *rdev = regulator->rdev;
1943a7a1ad90SMark Brown 	int i, voltages, ret;
1944a7a1ad90SMark Brown 
1945c5f3939bSMark Brown 	/* If we can't change voltage check the current voltage */
1946c5f3939bSMark Brown 	if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) {
1947c5f3939bSMark Brown 		ret = regulator_get_voltage(regulator);
1948c5f3939bSMark Brown 		if (ret >= 0)
1949c5f3939bSMark Brown 			return (min_uV >= ret && ret <= max_uV);
1950c5f3939bSMark Brown 		else
1951c5f3939bSMark Brown 			return ret;
1952c5f3939bSMark Brown 	}
1953c5f3939bSMark Brown 
1954a7a1ad90SMark Brown 	ret = regulator_count_voltages(regulator);
1955a7a1ad90SMark Brown 	if (ret < 0)
1956a7a1ad90SMark Brown 		return ret;
1957a7a1ad90SMark Brown 	voltages = ret;
1958a7a1ad90SMark Brown 
1959a7a1ad90SMark Brown 	for (i = 0; i < voltages; i++) {
1960a7a1ad90SMark Brown 		ret = regulator_list_voltage(regulator, i);
1961a7a1ad90SMark Brown 
1962a7a1ad90SMark Brown 		if (ret >= min_uV && ret <= max_uV)
1963a7a1ad90SMark Brown 			return 1;
1964a7a1ad90SMark Brown 	}
1965a7a1ad90SMark Brown 
1966a7a1ad90SMark Brown 	return 0;
1967a7a1ad90SMark Brown }
1968a398eaa2SMark Brown EXPORT_SYMBOL_GPL(regulator_is_supported_voltage);
1969a7a1ad90SMark Brown 
19704ab5b3d9SMark Brown /**
19714ab5b3d9SMark Brown  * regulator_get_voltage_sel_regmap - standard get_voltage_sel for regmap users
19724ab5b3d9SMark Brown  *
19734ab5b3d9SMark Brown  * @rdev: regulator to operate on
19744ab5b3d9SMark Brown  *
19754ab5b3d9SMark Brown  * Regulators that use regmap for their register I/O can set the
19764ab5b3d9SMark Brown  * vsel_reg and vsel_mask fields in their descriptor and then use this
19774ab5b3d9SMark Brown  * as their get_voltage_vsel operation, saving some code.
19784ab5b3d9SMark Brown  */
19794ab5b3d9SMark Brown int regulator_get_voltage_sel_regmap(struct regulator_dev *rdev)
19804ab5b3d9SMark Brown {
19814ab5b3d9SMark Brown 	unsigned int val;
19824ab5b3d9SMark Brown 	int ret;
19834ab5b3d9SMark Brown 
19844ab5b3d9SMark Brown 	ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val);
19854ab5b3d9SMark Brown 	if (ret != 0)
19864ab5b3d9SMark Brown 		return ret;
19874ab5b3d9SMark Brown 
19884ab5b3d9SMark Brown 	val &= rdev->desc->vsel_mask;
19894ab5b3d9SMark Brown 	val >>= ffs(rdev->desc->vsel_mask) - 1;
19904ab5b3d9SMark Brown 
19914ab5b3d9SMark Brown 	return val;
19924ab5b3d9SMark Brown }
19934ab5b3d9SMark Brown EXPORT_SYMBOL_GPL(regulator_get_voltage_sel_regmap);
19944ab5b3d9SMark Brown 
19954ab5b3d9SMark Brown /**
19964ab5b3d9SMark Brown  * regulator_set_voltage_sel_regmap - standard set_voltage_sel for regmap users
19974ab5b3d9SMark Brown  *
19984ab5b3d9SMark Brown  * @rdev: regulator to operate on
19994ab5b3d9SMark Brown  * @sel: Selector to set
20004ab5b3d9SMark Brown  *
20014ab5b3d9SMark Brown  * Regulators that use regmap for their register I/O can set the
20024ab5b3d9SMark Brown  * vsel_reg and vsel_mask fields in their descriptor and then use this
20034ab5b3d9SMark Brown  * as their set_voltage_vsel operation, saving some code.
20044ab5b3d9SMark Brown  */
20054ab5b3d9SMark Brown int regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel)
20064ab5b3d9SMark Brown {
20074ab5b3d9SMark Brown 	sel <<= ffs(rdev->desc->vsel_mask) - 1;
20084ab5b3d9SMark Brown 
20094ab5b3d9SMark Brown 	return regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
20104ab5b3d9SMark Brown 				  rdev->desc->vsel_mask, sel);
20114ab5b3d9SMark Brown }
20124ab5b3d9SMark Brown EXPORT_SYMBOL_GPL(regulator_set_voltage_sel_regmap);
20134ab5b3d9SMark Brown 
2014e843fc46SMark Brown /**
2015e843fc46SMark Brown  * regulator_map_voltage_iterate - map_voltage() based on list_voltage()
2016e843fc46SMark Brown  *
2017e843fc46SMark Brown  * @rdev: Regulator to operate on
2018e843fc46SMark Brown  * @min_uV: Lower bound for voltage
2019e843fc46SMark Brown  * @max_uV: Upper bound for voltage
2020e843fc46SMark Brown  *
2021e843fc46SMark Brown  * Drivers implementing set_voltage_sel() and list_voltage() can use
2022e843fc46SMark Brown  * this as their map_voltage() operation.  It will find a suitable
2023e843fc46SMark Brown  * voltage by calling list_voltage() until it gets something in bounds
2024e843fc46SMark Brown  * for the requested voltages.
2025e843fc46SMark Brown  */
2026e843fc46SMark Brown int regulator_map_voltage_iterate(struct regulator_dev *rdev,
202775790251SMark Brown 				  int min_uV, int max_uV)
202875790251SMark Brown {
2029e8eef82bSMark Brown 	int best_val = INT_MAX;
2030e843fc46SMark Brown 	int selector = 0;
2031e843fc46SMark Brown 	int i, ret;
2032e8eef82bSMark Brown 
2033e8eef82bSMark Brown 	/* Find the smallest voltage that falls within the specified
2034e8eef82bSMark Brown 	 * range.
2035e8eef82bSMark Brown 	 */
2036e8eef82bSMark Brown 	for (i = 0; i < rdev->desc->n_voltages; i++) {
2037e8eef82bSMark Brown 		ret = rdev->desc->ops->list_voltage(rdev, i);
2038e8eef82bSMark Brown 		if (ret < 0)
2039e8eef82bSMark Brown 			continue;
2040e8eef82bSMark Brown 
2041e8eef82bSMark Brown 		if (ret < best_val && ret >= min_uV && ret <= max_uV) {
2042e8eef82bSMark Brown 			best_val = ret;
2043e8eef82bSMark Brown 			selector = i;
2044e8eef82bSMark Brown 		}
2045e8eef82bSMark Brown 	}
2046e8eef82bSMark Brown 
2047e843fc46SMark Brown 	if (best_val != INT_MAX)
2048e843fc46SMark Brown 		return selector;
2049e843fc46SMark Brown 	else
2050e843fc46SMark Brown 		return -EINVAL;
2051e843fc46SMark Brown }
2052e843fc46SMark Brown EXPORT_SYMBOL_GPL(regulator_map_voltage_iterate);
2053e843fc46SMark Brown 
2054bca7bbffSMark Brown /**
2055bca7bbffSMark Brown  * regulator_map_voltage_linear - map_voltage() for simple linear mappings
2056bca7bbffSMark Brown  *
2057bca7bbffSMark Brown  * @rdev: Regulator to operate on
2058bca7bbffSMark Brown  * @min_uV: Lower bound for voltage
2059bca7bbffSMark Brown  * @max_uV: Upper bound for voltage
2060bca7bbffSMark Brown  *
2061bca7bbffSMark Brown  * Drivers providing min_uV and uV_step in their regulator_desc can
2062bca7bbffSMark Brown  * use this as their map_voltage() operation.
2063bca7bbffSMark Brown  */
2064bca7bbffSMark Brown int regulator_map_voltage_linear(struct regulator_dev *rdev,
2065bca7bbffSMark Brown 				 int min_uV, int max_uV)
2066bca7bbffSMark Brown {
2067bca7bbffSMark Brown 	int ret, voltage;
2068bca7bbffSMark Brown 
20695a6881e8SAxel Lin 	/* Allow uV_step to be 0 for fixed voltage */
20705a6881e8SAxel Lin 	if (rdev->desc->n_voltages == 1 && rdev->desc->uV_step == 0) {
20715a6881e8SAxel Lin 		if (min_uV <= rdev->desc->min_uV && rdev->desc->min_uV <= max_uV)
20725a6881e8SAxel Lin 			return 0;
20735a6881e8SAxel Lin 		else
20745a6881e8SAxel Lin 			return -EINVAL;
20755a6881e8SAxel Lin 	}
20765a6881e8SAxel Lin 
2077bca7bbffSMark Brown 	if (!rdev->desc->uV_step) {
2078bca7bbffSMark Brown 		BUG_ON(!rdev->desc->uV_step);
2079bca7bbffSMark Brown 		return -EINVAL;
2080bca7bbffSMark Brown 	}
2081bca7bbffSMark Brown 
20820bdc81e4SAxel Lin 	if (min_uV < rdev->desc->min_uV)
20830bdc81e4SAxel Lin 		min_uV = rdev->desc->min_uV;
20840bdc81e4SAxel Lin 
2085ccfcb1c3SAxel Lin 	ret = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step);
2086bca7bbffSMark Brown 	if (ret < 0)
2087bca7bbffSMark Brown 		return ret;
2088bca7bbffSMark Brown 
2089bca7bbffSMark Brown 	/* Map back into a voltage to verify we're still in bounds */
2090bca7bbffSMark Brown 	voltage = rdev->desc->ops->list_voltage(rdev, ret);
2091bca7bbffSMark Brown 	if (voltage < min_uV || voltage > max_uV)
2092bca7bbffSMark Brown 		return -EINVAL;
2093bca7bbffSMark Brown 
2094bca7bbffSMark Brown 	return ret;
2095bca7bbffSMark Brown }
2096bca7bbffSMark Brown EXPORT_SYMBOL_GPL(regulator_map_voltage_linear);
2097bca7bbffSMark Brown 
2098a7a1ad90SMark Brown static int _regulator_do_set_voltage(struct regulator_dev *rdev,
2099a7a1ad90SMark Brown 				     int min_uV, int max_uV)
2100a7a1ad90SMark Brown {
2101a7a1ad90SMark Brown 	int ret;
210275790251SMark Brown 	int delay = 0;
2103e113d792SMark Brown 	int best_val = 0;
210475790251SMark Brown 	unsigned int selector;
2105eba41a5eSAxel Lin 	int old_selector = -1;
210675790251SMark Brown 
210775790251SMark Brown 	trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV);
210875790251SMark Brown 
210975790251SMark Brown 	min_uV += rdev->constraints->uV_offset;
211075790251SMark Brown 	max_uV += rdev->constraints->uV_offset;
211175790251SMark Brown 
211277af1b26SLinus Walleij 	/*
211377af1b26SLinus Walleij 	 * If we can't obtain the old selector there is not enough
211477af1b26SLinus Walleij 	 * info to call set_voltage_time_sel().
211577af1b26SLinus Walleij 	 */
21168b7485efSAxel Lin 	if (_regulator_is_enabled(rdev) &&
21178b7485efSAxel Lin 	    rdev->desc->ops->set_voltage_time_sel &&
211877af1b26SLinus Walleij 	    rdev->desc->ops->get_voltage_sel) {
2119eba41a5eSAxel Lin 		old_selector = rdev->desc->ops->get_voltage_sel(rdev);
2120eba41a5eSAxel Lin 		if (old_selector < 0)
2121eba41a5eSAxel Lin 			return old_selector;
2122eba41a5eSAxel Lin 	}
212377af1b26SLinus Walleij 
212475790251SMark Brown 	if (rdev->desc->ops->set_voltage) {
212575790251SMark Brown 		ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV,
212675790251SMark Brown 						   &selector);
2127e113d792SMark Brown 
2128e113d792SMark Brown 		if (ret >= 0) {
2129e113d792SMark Brown 			if (rdev->desc->ops->list_voltage)
2130e113d792SMark Brown 				best_val = rdev->desc->ops->list_voltage(rdev,
2131e113d792SMark Brown 									 selector);
2132e113d792SMark Brown 			else
2133e113d792SMark Brown 				best_val = _regulator_get_voltage(rdev);
2134e113d792SMark Brown 		}
2135e113d792SMark Brown 
2136e8eef82bSMark Brown 	} else if (rdev->desc->ops->set_voltage_sel) {
21379152c36aSAxel Lin 		if (rdev->desc->ops->map_voltage) {
2138e843fc46SMark Brown 			ret = rdev->desc->ops->map_voltage(rdev, min_uV,
2139e843fc46SMark Brown 							   max_uV);
21409152c36aSAxel Lin 		} else {
21419152c36aSAxel Lin 			if (rdev->desc->ops->list_voltage ==
21429152c36aSAxel Lin 			    regulator_list_voltage_linear)
21439152c36aSAxel Lin 				ret = regulator_map_voltage_linear(rdev,
21449152c36aSAxel Lin 								min_uV, max_uV);
214507351233SAxel Lin 			else
21469152c36aSAxel Lin 				ret = regulator_map_voltage_iterate(rdev,
21479152c36aSAxel Lin 								min_uV, max_uV);
21489152c36aSAxel Lin 		}
2149e843fc46SMark Brown 
2150e843fc46SMark Brown 		if (ret >= 0) {
2151e113d792SMark Brown 			best_val = rdev->desc->ops->list_voltage(rdev, ret);
2152e113d792SMark Brown 			if (min_uV <= best_val && max_uV >= best_val) {
2153e843fc46SMark Brown 				selector = ret;
2154e113d792SMark Brown 				ret = rdev->desc->ops->set_voltage_sel(rdev,
2155e113d792SMark Brown 								       ret);
2156e113d792SMark Brown 			} else {
2157e113d792SMark Brown 				ret = -EINVAL;
2158e113d792SMark Brown 			}
2159e843fc46SMark Brown 		}
2160e8eef82bSMark Brown 	} else {
2161e8eef82bSMark Brown 		ret = -EINVAL;
2162e8eef82bSMark Brown 	}
2163e8eef82bSMark Brown 
2164eba41a5eSAxel Lin 	/* Call set_voltage_time_sel if successfully obtained old_selector */
21655aff3a8bSMark Brown 	if (ret == 0 && _regulator_is_enabled(rdev) && old_selector >= 0 &&
2166eba41a5eSAxel Lin 	    rdev->desc->ops->set_voltage_time_sel) {
2167eba41a5eSAxel Lin 
2168eba41a5eSAxel Lin 		delay = rdev->desc->ops->set_voltage_time_sel(rdev,
2169eba41a5eSAxel Lin 						old_selector, selector);
2170eba41a5eSAxel Lin 		if (delay < 0) {
2171eba41a5eSAxel Lin 			rdev_warn(rdev, "set_voltage_time_sel() failed: %d\n",
2172eba41a5eSAxel Lin 				  delay);
2173eba41a5eSAxel Lin 			delay = 0;
2174e8eef82bSMark Brown 		}
217575790251SMark Brown 
217677af1b26SLinus Walleij 		/* Insert any necessary delays */
217777af1b26SLinus Walleij 		if (delay >= 1000) {
217877af1b26SLinus Walleij 			mdelay(delay / 1000);
217977af1b26SLinus Walleij 			udelay(delay % 1000);
218077af1b26SLinus Walleij 		} else if (delay) {
218177af1b26SLinus Walleij 			udelay(delay);
218277af1b26SLinus Walleij 		}
21838b96de31SPhilip Rakity 	}
218477af1b26SLinus Walleij 
21852f6c797fSAxel Lin 	if (ret == 0 && best_val >= 0) {
21862f6c797fSAxel Lin 		unsigned long data = best_val;
21872f6c797fSAxel Lin 
2188ded06a52SMark Brown 		_notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE,
21892f6c797fSAxel Lin 				     (void *)data);
21902f6c797fSAxel Lin 	}
2191ded06a52SMark Brown 
2192eba41a5eSAxel Lin 	trace_regulator_set_voltage_complete(rdev_get_name(rdev), best_val);
219375790251SMark Brown 
219475790251SMark Brown 	return ret;
219575790251SMark Brown }
219675790251SMark Brown 
2197a7a1ad90SMark Brown /**
2198414c70cbSLiam Girdwood  * regulator_set_voltage - set regulator output voltage
2199414c70cbSLiam Girdwood  * @regulator: regulator source
2200414c70cbSLiam Girdwood  * @min_uV: Minimum required voltage in uV
2201414c70cbSLiam Girdwood  * @max_uV: Maximum acceptable voltage in uV
2202414c70cbSLiam Girdwood  *
2203414c70cbSLiam Girdwood  * Sets a voltage regulator to the desired output voltage. This can be set
2204414c70cbSLiam Girdwood  * during any regulator state. IOW, regulator can be disabled or enabled.
2205414c70cbSLiam Girdwood  *
2206414c70cbSLiam Girdwood  * If the regulator is enabled then the voltage will change to the new value
2207414c70cbSLiam Girdwood  * immediately otherwise if the regulator is disabled the regulator will
2208414c70cbSLiam Girdwood  * output at the new voltage when enabled.
2209414c70cbSLiam Girdwood  *
2210414c70cbSLiam Girdwood  * NOTE: If the regulator is shared between several devices then the lowest
2211414c70cbSLiam Girdwood  * request voltage that meets the system constraints will be used.
221269279fb9SMark Brown  * Regulator system constraints must be set for this regulator before
2213414c70cbSLiam Girdwood  * calling this function otherwise this call will fail.
2214414c70cbSLiam Girdwood  */
2215414c70cbSLiam Girdwood int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
2216414c70cbSLiam Girdwood {
2217414c70cbSLiam Girdwood 	struct regulator_dev *rdev = regulator->rdev;
221895a3c23aSMark Brown 	int ret = 0;
2219414c70cbSLiam Girdwood 
2220414c70cbSLiam Girdwood 	mutex_lock(&rdev->mutex);
2221414c70cbSLiam Girdwood 
222295a3c23aSMark Brown 	/* If we're setting the same range as last time the change
222395a3c23aSMark Brown 	 * should be a noop (some cpufreq implementations use the same
222495a3c23aSMark Brown 	 * voltage for multiple frequencies, for example).
222595a3c23aSMark Brown 	 */
222695a3c23aSMark Brown 	if (regulator->min_uV == min_uV && regulator->max_uV == max_uV)
222795a3c23aSMark Brown 		goto out;
222895a3c23aSMark Brown 
2229414c70cbSLiam Girdwood 	/* sanity check */
2230e8eef82bSMark Brown 	if (!rdev->desc->ops->set_voltage &&
2231e8eef82bSMark Brown 	    !rdev->desc->ops->set_voltage_sel) {
2232414c70cbSLiam Girdwood 		ret = -EINVAL;
2233414c70cbSLiam Girdwood 		goto out;
2234414c70cbSLiam Girdwood 	}
2235414c70cbSLiam Girdwood 
2236414c70cbSLiam Girdwood 	/* constraints check */
2237414c70cbSLiam Girdwood 	ret = regulator_check_voltage(rdev, &min_uV, &max_uV);
2238414c70cbSLiam Girdwood 	if (ret < 0)
2239414c70cbSLiam Girdwood 		goto out;
2240414c70cbSLiam Girdwood 	regulator->min_uV = min_uV;
2241414c70cbSLiam Girdwood 	regulator->max_uV = max_uV;
22423a93f2a9SMark Brown 
224305fda3b1SThomas Petazzoni 	ret = regulator_check_consumers(rdev, &min_uV, &max_uV);
224405fda3b1SThomas Petazzoni 	if (ret < 0)
224505fda3b1SThomas Petazzoni 		goto out;
224605fda3b1SThomas Petazzoni 
224775790251SMark Brown 	ret = _regulator_do_set_voltage(rdev, min_uV, max_uV);
224802fa3ec0SMark Brown 
2249414c70cbSLiam Girdwood out:
2250414c70cbSLiam Girdwood 	mutex_unlock(&rdev->mutex);
2251414c70cbSLiam Girdwood 	return ret;
2252414c70cbSLiam Girdwood }
2253414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_set_voltage);
2254414c70cbSLiam Girdwood 
2255606a2562SMark Brown /**
225688cd222bSLinus Walleij  * regulator_set_voltage_time - get raise/fall time
225788cd222bSLinus Walleij  * @regulator: regulator source
225888cd222bSLinus Walleij  * @old_uV: starting voltage in microvolts
225988cd222bSLinus Walleij  * @new_uV: target voltage in microvolts
226088cd222bSLinus Walleij  *
226188cd222bSLinus Walleij  * Provided with the starting and ending voltage, this function attempts to
226288cd222bSLinus Walleij  * calculate the time in microseconds required to rise or fall to this new
226388cd222bSLinus Walleij  * voltage.
226488cd222bSLinus Walleij  */
226588cd222bSLinus Walleij int regulator_set_voltage_time(struct regulator *regulator,
226688cd222bSLinus Walleij 			       int old_uV, int new_uV)
226788cd222bSLinus Walleij {
226888cd222bSLinus Walleij 	struct regulator_dev	*rdev = regulator->rdev;
226988cd222bSLinus Walleij 	struct regulator_ops	*ops = rdev->desc->ops;
227088cd222bSLinus Walleij 	int old_sel = -1;
227188cd222bSLinus Walleij 	int new_sel = -1;
227288cd222bSLinus Walleij 	int voltage;
227388cd222bSLinus Walleij 	int i;
227488cd222bSLinus Walleij 
227588cd222bSLinus Walleij 	/* Currently requires operations to do this */
227688cd222bSLinus Walleij 	if (!ops->list_voltage || !ops->set_voltage_time_sel
227788cd222bSLinus Walleij 	    || !rdev->desc->n_voltages)
227888cd222bSLinus Walleij 		return -EINVAL;
227988cd222bSLinus Walleij 
228088cd222bSLinus Walleij 	for (i = 0; i < rdev->desc->n_voltages; i++) {
228188cd222bSLinus Walleij 		/* We only look for exact voltage matches here */
228288cd222bSLinus Walleij 		voltage = regulator_list_voltage(regulator, i);
228388cd222bSLinus Walleij 		if (voltage < 0)
228488cd222bSLinus Walleij 			return -EINVAL;
228588cd222bSLinus Walleij 		if (voltage == 0)
228688cd222bSLinus Walleij 			continue;
228788cd222bSLinus Walleij 		if (voltage == old_uV)
228888cd222bSLinus Walleij 			old_sel = i;
228988cd222bSLinus Walleij 		if (voltage == new_uV)
229088cd222bSLinus Walleij 			new_sel = i;
229188cd222bSLinus Walleij 	}
229288cd222bSLinus Walleij 
229388cd222bSLinus Walleij 	if (old_sel < 0 || new_sel < 0)
229488cd222bSLinus Walleij 		return -EINVAL;
229588cd222bSLinus Walleij 
229688cd222bSLinus Walleij 	return ops->set_voltage_time_sel(rdev, old_sel, new_sel);
229788cd222bSLinus Walleij }
229888cd222bSLinus Walleij EXPORT_SYMBOL_GPL(regulator_set_voltage_time);
229988cd222bSLinus Walleij 
230088cd222bSLinus Walleij /**
230198a175b6SYadwinder Singh Brar  *regulator_set_voltage_time_sel - get raise/fall time
230298a175b6SYadwinder Singh Brar  * @regulator: regulator source
230398a175b6SYadwinder Singh Brar  * @old_selector: selector for starting voltage
230498a175b6SYadwinder Singh Brar  * @new_selector: selector for target voltage
230598a175b6SYadwinder Singh Brar  *
230698a175b6SYadwinder Singh Brar  * Provided with the starting and target voltage selectors, this function
230798a175b6SYadwinder Singh Brar  * returns time in microseconds required to rise or fall to this new voltage
230898a175b6SYadwinder Singh Brar  *
2309f11d08c3SAxel Lin  * Drivers providing ramp_delay in regulation_constraints can use this as their
2310398715abSAxel Lin  * set_voltage_time_sel() operation.
231198a175b6SYadwinder Singh Brar  */
231298a175b6SYadwinder Singh Brar int regulator_set_voltage_time_sel(struct regulator_dev *rdev,
231398a175b6SYadwinder Singh Brar 				   unsigned int old_selector,
231498a175b6SYadwinder Singh Brar 				   unsigned int new_selector)
231598a175b6SYadwinder Singh Brar {
2316398715abSAxel Lin 	unsigned int ramp_delay = 0;
2317f11d08c3SAxel Lin 	int old_volt, new_volt;
2318398715abSAxel Lin 
23196f0b2c69SYadwinder Singh Brar 	if (rdev->constraints->ramp_delay)
2320398715abSAxel Lin 		ramp_delay = rdev->constraints->ramp_delay;
2321398715abSAxel Lin 	else if (rdev->desc->ramp_delay)
2322398715abSAxel Lin 		ramp_delay = rdev->desc->ramp_delay;
2323398715abSAxel Lin 
2324398715abSAxel Lin 	if (ramp_delay == 0) {
23256f0b2c69SYadwinder Singh Brar 		rdev_warn(rdev, "ramp_delay not set\n");
2326398715abSAxel Lin 		return 0;
23276f0b2c69SYadwinder Singh Brar 	}
2328398715abSAxel Lin 
2329f11d08c3SAxel Lin 	/* sanity check */
2330f11d08c3SAxel Lin 	if (!rdev->desc->ops->list_voltage)
2331f11d08c3SAxel Lin 		return -EINVAL;
2332398715abSAxel Lin 
2333f11d08c3SAxel Lin 	old_volt = rdev->desc->ops->list_voltage(rdev, old_selector);
2334f11d08c3SAxel Lin 	new_volt = rdev->desc->ops->list_voltage(rdev, new_selector);
2335f11d08c3SAxel Lin 
2336f11d08c3SAxel Lin 	return DIV_ROUND_UP(abs(new_volt - old_volt), ramp_delay);
233798a175b6SYadwinder Singh Brar }
2338b19dbf71SMark Brown EXPORT_SYMBOL_GPL(regulator_set_voltage_time_sel);
233998a175b6SYadwinder Singh Brar 
234098a175b6SYadwinder Singh Brar /**
2341606a2562SMark Brown  * regulator_sync_voltage - re-apply last regulator output voltage
2342606a2562SMark Brown  * @regulator: regulator source
2343606a2562SMark Brown  *
2344606a2562SMark Brown  * Re-apply the last configured voltage.  This is intended to be used
2345606a2562SMark Brown  * where some external control source the consumer is cooperating with
2346606a2562SMark Brown  * has caused the configured voltage to change.
2347606a2562SMark Brown  */
2348606a2562SMark Brown int regulator_sync_voltage(struct regulator *regulator)
2349606a2562SMark Brown {
2350606a2562SMark Brown 	struct regulator_dev *rdev = regulator->rdev;
2351606a2562SMark Brown 	int ret, min_uV, max_uV;
2352606a2562SMark Brown 
2353606a2562SMark Brown 	mutex_lock(&rdev->mutex);
2354606a2562SMark Brown 
2355606a2562SMark Brown 	if (!rdev->desc->ops->set_voltage &&
2356606a2562SMark Brown 	    !rdev->desc->ops->set_voltage_sel) {
2357606a2562SMark Brown 		ret = -EINVAL;
2358606a2562SMark Brown 		goto out;
2359606a2562SMark Brown 	}
2360606a2562SMark Brown 
2361606a2562SMark Brown 	/* This is only going to work if we've had a voltage configured. */
2362606a2562SMark Brown 	if (!regulator->min_uV && !regulator->max_uV) {
2363606a2562SMark Brown 		ret = -EINVAL;
2364606a2562SMark Brown 		goto out;
2365606a2562SMark Brown 	}
2366606a2562SMark Brown 
2367606a2562SMark Brown 	min_uV = regulator->min_uV;
2368606a2562SMark Brown 	max_uV = regulator->max_uV;
2369606a2562SMark Brown 
2370606a2562SMark Brown 	/* This should be a paranoia check... */
2371606a2562SMark Brown 	ret = regulator_check_voltage(rdev, &min_uV, &max_uV);
2372606a2562SMark Brown 	if (ret < 0)
2373606a2562SMark Brown 		goto out;
2374606a2562SMark Brown 
2375606a2562SMark Brown 	ret = regulator_check_consumers(rdev, &min_uV, &max_uV);
2376606a2562SMark Brown 	if (ret < 0)
2377606a2562SMark Brown 		goto out;
2378606a2562SMark Brown 
2379606a2562SMark Brown 	ret = _regulator_do_set_voltage(rdev, min_uV, max_uV);
2380606a2562SMark Brown 
2381606a2562SMark Brown out:
2382606a2562SMark Brown 	mutex_unlock(&rdev->mutex);
2383606a2562SMark Brown 	return ret;
2384606a2562SMark Brown }
2385606a2562SMark Brown EXPORT_SYMBOL_GPL(regulator_sync_voltage);
2386606a2562SMark Brown 
2387414c70cbSLiam Girdwood static int _regulator_get_voltage(struct regulator_dev *rdev)
2388414c70cbSLiam Girdwood {
2389bf5892a8SMark Brown 	int sel, ret;
2390476c2d83SMark Brown 
2391476c2d83SMark Brown 	if (rdev->desc->ops->get_voltage_sel) {
2392476c2d83SMark Brown 		sel = rdev->desc->ops->get_voltage_sel(rdev);
2393476c2d83SMark Brown 		if (sel < 0)
2394476c2d83SMark Brown 			return sel;
2395bf5892a8SMark Brown 		ret = rdev->desc->ops->list_voltage(rdev, sel);
2396cb220d16SAxel Lin 	} else if (rdev->desc->ops->get_voltage) {
2397bf5892a8SMark Brown 		ret = rdev->desc->ops->get_voltage(rdev);
2398cb220d16SAxel Lin 	} else {
2399414c70cbSLiam Girdwood 		return -EINVAL;
2400cb220d16SAxel Lin 	}
2401bf5892a8SMark Brown 
2402cb220d16SAxel Lin 	if (ret < 0)
2403cb220d16SAxel Lin 		return ret;
2404bf5892a8SMark Brown 	return ret - rdev->constraints->uV_offset;
2405414c70cbSLiam Girdwood }
2406414c70cbSLiam Girdwood 
2407414c70cbSLiam Girdwood /**
2408414c70cbSLiam Girdwood  * regulator_get_voltage - get regulator output voltage
2409414c70cbSLiam Girdwood  * @regulator: regulator source
2410414c70cbSLiam Girdwood  *
2411414c70cbSLiam Girdwood  * This returns the current regulator voltage in uV.
2412414c70cbSLiam Girdwood  *
2413414c70cbSLiam Girdwood  * NOTE: If the regulator is disabled it will return the voltage value. This
2414414c70cbSLiam Girdwood  * function should not be used to determine regulator state.
2415414c70cbSLiam Girdwood  */
2416414c70cbSLiam Girdwood int regulator_get_voltage(struct regulator *regulator)
2417414c70cbSLiam Girdwood {
2418414c70cbSLiam Girdwood 	int ret;
2419414c70cbSLiam Girdwood 
2420414c70cbSLiam Girdwood 	mutex_lock(&regulator->rdev->mutex);
2421414c70cbSLiam Girdwood 
2422414c70cbSLiam Girdwood 	ret = _regulator_get_voltage(regulator->rdev);
2423414c70cbSLiam Girdwood 
2424414c70cbSLiam Girdwood 	mutex_unlock(&regulator->rdev->mutex);
2425414c70cbSLiam Girdwood 
2426414c70cbSLiam Girdwood 	return ret;
2427414c70cbSLiam Girdwood }
2428414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_get_voltage);
2429414c70cbSLiam Girdwood 
2430414c70cbSLiam Girdwood /**
2431414c70cbSLiam Girdwood  * regulator_set_current_limit - set regulator output current limit
2432414c70cbSLiam Girdwood  * @regulator: regulator source
2433414c70cbSLiam Girdwood  * @min_uA: Minimuum supported current in uA
2434414c70cbSLiam Girdwood  * @max_uA: Maximum supported current in uA
2435414c70cbSLiam Girdwood  *
2436414c70cbSLiam Girdwood  * Sets current sink to the desired output current. This can be set during
2437414c70cbSLiam Girdwood  * any regulator state. IOW, regulator can be disabled or enabled.
2438414c70cbSLiam Girdwood  *
2439414c70cbSLiam Girdwood  * If the regulator is enabled then the current will change to the new value
2440414c70cbSLiam Girdwood  * immediately otherwise if the regulator is disabled the regulator will
2441414c70cbSLiam Girdwood  * output at the new current when enabled.
2442414c70cbSLiam Girdwood  *
2443414c70cbSLiam Girdwood  * NOTE: Regulator system constraints must be set for this regulator before
2444414c70cbSLiam Girdwood  * calling this function otherwise this call will fail.
2445414c70cbSLiam Girdwood  */
2446414c70cbSLiam Girdwood int regulator_set_current_limit(struct regulator *regulator,
2447414c70cbSLiam Girdwood 			       int min_uA, int max_uA)
2448414c70cbSLiam Girdwood {
2449414c70cbSLiam Girdwood 	struct regulator_dev *rdev = regulator->rdev;
2450414c70cbSLiam Girdwood 	int ret;
2451414c70cbSLiam Girdwood 
2452414c70cbSLiam Girdwood 	mutex_lock(&rdev->mutex);
2453414c70cbSLiam Girdwood 
2454414c70cbSLiam Girdwood 	/* sanity check */
2455414c70cbSLiam Girdwood 	if (!rdev->desc->ops->set_current_limit) {
2456414c70cbSLiam Girdwood 		ret = -EINVAL;
2457414c70cbSLiam Girdwood 		goto out;
2458414c70cbSLiam Girdwood 	}
2459414c70cbSLiam Girdwood 
2460414c70cbSLiam Girdwood 	/* constraints check */
2461414c70cbSLiam Girdwood 	ret = regulator_check_current_limit(rdev, &min_uA, &max_uA);
2462414c70cbSLiam Girdwood 	if (ret < 0)
2463414c70cbSLiam Girdwood 		goto out;
2464414c70cbSLiam Girdwood 
2465414c70cbSLiam Girdwood 	ret = rdev->desc->ops->set_current_limit(rdev, min_uA, max_uA);
2466414c70cbSLiam Girdwood out:
2467414c70cbSLiam Girdwood 	mutex_unlock(&rdev->mutex);
2468414c70cbSLiam Girdwood 	return ret;
2469414c70cbSLiam Girdwood }
2470414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_set_current_limit);
2471414c70cbSLiam Girdwood 
2472414c70cbSLiam Girdwood static int _regulator_get_current_limit(struct regulator_dev *rdev)
2473414c70cbSLiam Girdwood {
2474414c70cbSLiam Girdwood 	int ret;
2475414c70cbSLiam Girdwood 
2476414c70cbSLiam Girdwood 	mutex_lock(&rdev->mutex);
2477414c70cbSLiam Girdwood 
2478414c70cbSLiam Girdwood 	/* sanity check */
2479414c70cbSLiam Girdwood 	if (!rdev->desc->ops->get_current_limit) {
2480414c70cbSLiam Girdwood 		ret = -EINVAL;
2481414c70cbSLiam Girdwood 		goto out;
2482414c70cbSLiam Girdwood 	}
2483414c70cbSLiam Girdwood 
2484414c70cbSLiam Girdwood 	ret = rdev->desc->ops->get_current_limit(rdev);
2485414c70cbSLiam Girdwood out:
2486414c70cbSLiam Girdwood 	mutex_unlock(&rdev->mutex);
2487414c70cbSLiam Girdwood 	return ret;
2488414c70cbSLiam Girdwood }
2489414c70cbSLiam Girdwood 
2490414c70cbSLiam Girdwood /**
2491414c70cbSLiam Girdwood  * regulator_get_current_limit - get regulator output current
2492414c70cbSLiam Girdwood  * @regulator: regulator source
2493414c70cbSLiam Girdwood  *
2494414c70cbSLiam Girdwood  * This returns the current supplied by the specified current sink in uA.
2495414c70cbSLiam Girdwood  *
2496414c70cbSLiam Girdwood  * NOTE: If the regulator is disabled it will return the current value. This
2497414c70cbSLiam Girdwood  * function should not be used to determine regulator state.
2498414c70cbSLiam Girdwood  */
2499414c70cbSLiam Girdwood int regulator_get_current_limit(struct regulator *regulator)
2500414c70cbSLiam Girdwood {
2501414c70cbSLiam Girdwood 	return _regulator_get_current_limit(regulator->rdev);
2502414c70cbSLiam Girdwood }
2503414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_get_current_limit);
2504414c70cbSLiam Girdwood 
2505414c70cbSLiam Girdwood /**
2506414c70cbSLiam Girdwood  * regulator_set_mode - set regulator operating mode
2507414c70cbSLiam Girdwood  * @regulator: regulator source
2508414c70cbSLiam Girdwood  * @mode: operating mode - one of the REGULATOR_MODE constants
2509414c70cbSLiam Girdwood  *
2510414c70cbSLiam Girdwood  * Set regulator operating mode to increase regulator efficiency or improve
2511414c70cbSLiam Girdwood  * regulation performance.
2512414c70cbSLiam Girdwood  *
2513414c70cbSLiam Girdwood  * NOTE: Regulator system constraints must be set for this regulator before
2514414c70cbSLiam Girdwood  * calling this function otherwise this call will fail.
2515414c70cbSLiam Girdwood  */
2516414c70cbSLiam Girdwood int regulator_set_mode(struct regulator *regulator, unsigned int mode)
2517414c70cbSLiam Girdwood {
2518414c70cbSLiam Girdwood 	struct regulator_dev *rdev = regulator->rdev;
2519414c70cbSLiam Girdwood 	int ret;
2520500b4ac9SSundar R Iyer 	int regulator_curr_mode;
2521414c70cbSLiam Girdwood 
2522414c70cbSLiam Girdwood 	mutex_lock(&rdev->mutex);
2523414c70cbSLiam Girdwood 
2524414c70cbSLiam Girdwood 	/* sanity check */
2525414c70cbSLiam Girdwood 	if (!rdev->desc->ops->set_mode) {
2526414c70cbSLiam Girdwood 		ret = -EINVAL;
2527414c70cbSLiam Girdwood 		goto out;
2528414c70cbSLiam Girdwood 	}
2529414c70cbSLiam Girdwood 
2530500b4ac9SSundar R Iyer 	/* return if the same mode is requested */
2531500b4ac9SSundar R Iyer 	if (rdev->desc->ops->get_mode) {
2532500b4ac9SSundar R Iyer 		regulator_curr_mode = rdev->desc->ops->get_mode(rdev);
2533500b4ac9SSundar R Iyer 		if (regulator_curr_mode == mode) {
2534500b4ac9SSundar R Iyer 			ret = 0;
2535500b4ac9SSundar R Iyer 			goto out;
2536500b4ac9SSundar R Iyer 		}
2537500b4ac9SSundar R Iyer 	}
2538500b4ac9SSundar R Iyer 
2539414c70cbSLiam Girdwood 	/* constraints check */
254022c51b47SAxel Lin 	ret = regulator_mode_constrain(rdev, &mode);
2541414c70cbSLiam Girdwood 	if (ret < 0)
2542414c70cbSLiam Girdwood 		goto out;
2543414c70cbSLiam Girdwood 
2544414c70cbSLiam Girdwood 	ret = rdev->desc->ops->set_mode(rdev, mode);
2545414c70cbSLiam Girdwood out:
2546414c70cbSLiam Girdwood 	mutex_unlock(&rdev->mutex);
2547414c70cbSLiam Girdwood 	return ret;
2548414c70cbSLiam Girdwood }
2549414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_set_mode);
2550414c70cbSLiam Girdwood 
2551414c70cbSLiam Girdwood static unsigned int _regulator_get_mode(struct regulator_dev *rdev)
2552414c70cbSLiam Girdwood {
2553414c70cbSLiam Girdwood 	int ret;
2554414c70cbSLiam Girdwood 
2555414c70cbSLiam Girdwood 	mutex_lock(&rdev->mutex);
2556414c70cbSLiam Girdwood 
2557414c70cbSLiam Girdwood 	/* sanity check */
2558414c70cbSLiam Girdwood 	if (!rdev->desc->ops->get_mode) {
2559414c70cbSLiam Girdwood 		ret = -EINVAL;
2560414c70cbSLiam Girdwood 		goto out;
2561414c70cbSLiam Girdwood 	}
2562414c70cbSLiam Girdwood 
2563414c70cbSLiam Girdwood 	ret = rdev->desc->ops->get_mode(rdev);
2564414c70cbSLiam Girdwood out:
2565414c70cbSLiam Girdwood 	mutex_unlock(&rdev->mutex);
2566414c70cbSLiam Girdwood 	return ret;
2567414c70cbSLiam Girdwood }
2568414c70cbSLiam Girdwood 
2569414c70cbSLiam Girdwood /**
2570414c70cbSLiam Girdwood  * regulator_get_mode - get regulator operating mode
2571414c70cbSLiam Girdwood  * @regulator: regulator source
2572414c70cbSLiam Girdwood  *
2573414c70cbSLiam Girdwood  * Get the current regulator operating mode.
2574414c70cbSLiam Girdwood  */
2575414c70cbSLiam Girdwood unsigned int regulator_get_mode(struct regulator *regulator)
2576414c70cbSLiam Girdwood {
2577414c70cbSLiam Girdwood 	return _regulator_get_mode(regulator->rdev);
2578414c70cbSLiam Girdwood }
2579414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_get_mode);
2580414c70cbSLiam Girdwood 
2581414c70cbSLiam Girdwood /**
2582414c70cbSLiam Girdwood  * regulator_set_optimum_mode - set regulator optimum operating mode
2583414c70cbSLiam Girdwood  * @regulator: regulator source
2584414c70cbSLiam Girdwood  * @uA_load: load current
2585414c70cbSLiam Girdwood  *
2586414c70cbSLiam Girdwood  * Notifies the regulator core of a new device load. This is then used by
2587414c70cbSLiam Girdwood  * DRMS (if enabled by constraints) to set the most efficient regulator
2588414c70cbSLiam Girdwood  * operating mode for the new regulator loading.
2589414c70cbSLiam Girdwood  *
2590414c70cbSLiam Girdwood  * Consumer devices notify their supply regulator of the maximum power
2591414c70cbSLiam Girdwood  * they will require (can be taken from device datasheet in the power
2592414c70cbSLiam Girdwood  * consumption tables) when they change operational status and hence power
2593414c70cbSLiam Girdwood  * state. Examples of operational state changes that can affect power
2594414c70cbSLiam Girdwood  * consumption are :-
2595414c70cbSLiam Girdwood  *
2596414c70cbSLiam Girdwood  *    o Device is opened / closed.
2597414c70cbSLiam Girdwood  *    o Device I/O is about to begin or has just finished.
2598414c70cbSLiam Girdwood  *    o Device is idling in between work.
2599414c70cbSLiam Girdwood  *
2600414c70cbSLiam Girdwood  * This information is also exported via sysfs to userspace.
2601414c70cbSLiam Girdwood  *
2602414c70cbSLiam Girdwood  * DRMS will sum the total requested load on the regulator and change
2603414c70cbSLiam Girdwood  * to the most efficient operating mode if platform constraints allow.
2604414c70cbSLiam Girdwood  *
2605414c70cbSLiam Girdwood  * Returns the new regulator mode or error.
2606414c70cbSLiam Girdwood  */
2607414c70cbSLiam Girdwood int regulator_set_optimum_mode(struct regulator *regulator, int uA_load)
2608414c70cbSLiam Girdwood {
2609414c70cbSLiam Girdwood 	struct regulator_dev *rdev = regulator->rdev;
2610414c70cbSLiam Girdwood 	struct regulator *consumer;
2611d92d95b6SStephen Boyd 	int ret, output_uV, input_uV = 0, total_uA_load = 0;
2612414c70cbSLiam Girdwood 	unsigned int mode;
2613414c70cbSLiam Girdwood 
2614d92d95b6SStephen Boyd 	if (rdev->supply)
2615d92d95b6SStephen Boyd 		input_uV = regulator_get_voltage(rdev->supply);
2616d92d95b6SStephen Boyd 
2617414c70cbSLiam Girdwood 	mutex_lock(&rdev->mutex);
2618414c70cbSLiam Girdwood 
2619a4b41483SMark Brown 	/*
2620a4b41483SMark Brown 	 * first check to see if we can set modes at all, otherwise just
2621a4b41483SMark Brown 	 * tell the consumer everything is OK.
2622a4b41483SMark Brown 	 */
2623414c70cbSLiam Girdwood 	regulator->uA_load = uA_load;
2624414c70cbSLiam Girdwood 	ret = regulator_check_drms(rdev);
2625a4b41483SMark Brown 	if (ret < 0) {
2626a4b41483SMark Brown 		ret = 0;
2627414c70cbSLiam Girdwood 		goto out;
2628a4b41483SMark Brown 	}
2629414c70cbSLiam Girdwood 
2630414c70cbSLiam Girdwood 	if (!rdev->desc->ops->get_optimum_mode)
2631414c70cbSLiam Girdwood 		goto out;
2632414c70cbSLiam Girdwood 
2633a4b41483SMark Brown 	/*
2634a4b41483SMark Brown 	 * we can actually do this so any errors are indicators of
2635a4b41483SMark Brown 	 * potential real failure.
2636a4b41483SMark Brown 	 */
2637a4b41483SMark Brown 	ret = -EINVAL;
2638a4b41483SMark Brown 
2639854ccbaeSAxel Lin 	if (!rdev->desc->ops->set_mode)
2640854ccbaeSAxel Lin 		goto out;
2641854ccbaeSAxel Lin 
2642414c70cbSLiam Girdwood 	/* get output voltage */
26431bf5a1f8SMark Brown 	output_uV = _regulator_get_voltage(rdev);
2644414c70cbSLiam Girdwood 	if (output_uV <= 0) {
26455da84fd9SJoe Perches 		rdev_err(rdev, "invalid output voltage found\n");
2646414c70cbSLiam Girdwood 		goto out;
2647414c70cbSLiam Girdwood 	}
2648414c70cbSLiam Girdwood 
2649d92d95b6SStephen Boyd 	/* No supply? Use constraint voltage */
26501bf5a1f8SMark Brown 	if (input_uV <= 0)
2651414c70cbSLiam Girdwood 		input_uV = rdev->constraints->input_uV;
2652414c70cbSLiam Girdwood 	if (input_uV <= 0) {
26535da84fd9SJoe Perches 		rdev_err(rdev, "invalid input voltage found\n");
2654414c70cbSLiam Girdwood 		goto out;
2655414c70cbSLiam Girdwood 	}
2656414c70cbSLiam Girdwood 
2657414c70cbSLiam Girdwood 	/* calc total requested load for this regulator */
2658414c70cbSLiam Girdwood 	list_for_each_entry(consumer, &rdev->consumer_list, list)
2659414c70cbSLiam Girdwood 		total_uA_load += consumer->uA_load;
2660414c70cbSLiam Girdwood 
2661414c70cbSLiam Girdwood 	mode = rdev->desc->ops->get_optimum_mode(rdev,
2662414c70cbSLiam Girdwood 						 input_uV, output_uV,
2663414c70cbSLiam Girdwood 						 total_uA_load);
26642c608234SMark Brown 	ret = regulator_mode_constrain(rdev, &mode);
2665e573520bSDavid Brownell 	if (ret < 0) {
26665da84fd9SJoe Perches 		rdev_err(rdev, "failed to get optimum mode @ %d uA %d -> %d uV\n",
2667414c70cbSLiam Girdwood 			 total_uA_load, input_uV, output_uV);
2668414c70cbSLiam Girdwood 		goto out;
2669414c70cbSLiam Girdwood 	}
2670414c70cbSLiam Girdwood 
2671414c70cbSLiam Girdwood 	ret = rdev->desc->ops->set_mode(rdev, mode);
2672e573520bSDavid Brownell 	if (ret < 0) {
26735da84fd9SJoe Perches 		rdev_err(rdev, "failed to set optimum mode %x\n", mode);
2674414c70cbSLiam Girdwood 		goto out;
2675414c70cbSLiam Girdwood 	}
2676414c70cbSLiam Girdwood 	ret = mode;
2677414c70cbSLiam Girdwood out:
2678414c70cbSLiam Girdwood 	mutex_unlock(&rdev->mutex);
2679414c70cbSLiam Girdwood 	return ret;
2680414c70cbSLiam Girdwood }
2681414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_set_optimum_mode);
2682414c70cbSLiam Girdwood 
2683414c70cbSLiam Girdwood /**
2684414c70cbSLiam Girdwood  * regulator_register_notifier - register regulator event notifier
2685414c70cbSLiam Girdwood  * @regulator: regulator source
268669279fb9SMark Brown  * @nb: notifier block
2687414c70cbSLiam Girdwood  *
2688414c70cbSLiam Girdwood  * Register notifier block to receive regulator events.
2689414c70cbSLiam Girdwood  */
2690414c70cbSLiam Girdwood int regulator_register_notifier(struct regulator *regulator,
2691414c70cbSLiam Girdwood 			      struct notifier_block *nb)
2692414c70cbSLiam Girdwood {
2693414c70cbSLiam Girdwood 	return blocking_notifier_chain_register(&regulator->rdev->notifier,
2694414c70cbSLiam Girdwood 						nb);
2695414c70cbSLiam Girdwood }
2696414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_register_notifier);
2697414c70cbSLiam Girdwood 
2698414c70cbSLiam Girdwood /**
2699414c70cbSLiam Girdwood  * regulator_unregister_notifier - unregister regulator event notifier
2700414c70cbSLiam Girdwood  * @regulator: regulator source
270169279fb9SMark Brown  * @nb: notifier block
2702414c70cbSLiam Girdwood  *
2703414c70cbSLiam Girdwood  * Unregister regulator event notifier block.
2704414c70cbSLiam Girdwood  */
2705414c70cbSLiam Girdwood int regulator_unregister_notifier(struct regulator *regulator,
2706414c70cbSLiam Girdwood 				struct notifier_block *nb)
2707414c70cbSLiam Girdwood {
2708414c70cbSLiam Girdwood 	return blocking_notifier_chain_unregister(&regulator->rdev->notifier,
2709414c70cbSLiam Girdwood 						  nb);
2710414c70cbSLiam Girdwood }
2711414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_unregister_notifier);
2712414c70cbSLiam Girdwood 
2713b136fb44SJonathan Cameron /* notify regulator consumers and downstream regulator consumers.
2714b136fb44SJonathan Cameron  * Note mutex must be held by caller.
2715b136fb44SJonathan Cameron  */
2716414c70cbSLiam Girdwood static void _notifier_call_chain(struct regulator_dev *rdev,
2717414c70cbSLiam Girdwood 				  unsigned long event, void *data)
2718414c70cbSLiam Girdwood {
2719414c70cbSLiam Girdwood 	/* call rdev chain first */
2720d8493d21SMark Brown 	blocking_notifier_call_chain(&rdev->notifier, event, data);
2721414c70cbSLiam Girdwood }
2722414c70cbSLiam Girdwood 
2723414c70cbSLiam Girdwood /**
2724414c70cbSLiam Girdwood  * regulator_bulk_get - get multiple regulator consumers
2725414c70cbSLiam Girdwood  *
2726414c70cbSLiam Girdwood  * @dev:           Device to supply
2727414c70cbSLiam Girdwood  * @num_consumers: Number of consumers to register
2728414c70cbSLiam Girdwood  * @consumers:     Configuration of consumers; clients are stored here.
2729414c70cbSLiam Girdwood  *
2730414c70cbSLiam Girdwood  * @return 0 on success, an errno on failure.
2731414c70cbSLiam Girdwood  *
2732414c70cbSLiam Girdwood  * This helper function allows drivers to get several regulator
2733414c70cbSLiam Girdwood  * consumers in one operation.  If any of the regulators cannot be
2734414c70cbSLiam Girdwood  * acquired then any regulators that were allocated will be freed
2735414c70cbSLiam Girdwood  * before returning to the caller.
2736414c70cbSLiam Girdwood  */
2737414c70cbSLiam Girdwood int regulator_bulk_get(struct device *dev, int num_consumers,
2738414c70cbSLiam Girdwood 		       struct regulator_bulk_data *consumers)
2739414c70cbSLiam Girdwood {
2740414c70cbSLiam Girdwood 	int i;
2741414c70cbSLiam Girdwood 	int ret;
2742414c70cbSLiam Girdwood 
2743414c70cbSLiam Girdwood 	for (i = 0; i < num_consumers; i++)
2744414c70cbSLiam Girdwood 		consumers[i].consumer = NULL;
2745414c70cbSLiam Girdwood 
2746414c70cbSLiam Girdwood 	for (i = 0; i < num_consumers; i++) {
2747414c70cbSLiam Girdwood 		consumers[i].consumer = regulator_get(dev,
2748414c70cbSLiam Girdwood 						      consumers[i].supply);
2749414c70cbSLiam Girdwood 		if (IS_ERR(consumers[i].consumer)) {
2750414c70cbSLiam Girdwood 			ret = PTR_ERR(consumers[i].consumer);
27515b307627SMark Brown 			dev_err(dev, "Failed to get supply '%s': %d\n",
27525b307627SMark Brown 				consumers[i].supply, ret);
2753414c70cbSLiam Girdwood 			consumers[i].consumer = NULL;
2754414c70cbSLiam Girdwood 			goto err;
2755414c70cbSLiam Girdwood 		}
2756414c70cbSLiam Girdwood 	}
2757414c70cbSLiam Girdwood 
2758414c70cbSLiam Girdwood 	return 0;
2759414c70cbSLiam Girdwood 
2760414c70cbSLiam Girdwood err:
2761b29c7690SAxel Lin 	while (--i >= 0)
2762414c70cbSLiam Girdwood 		regulator_put(consumers[i].consumer);
2763414c70cbSLiam Girdwood 
2764414c70cbSLiam Girdwood 	return ret;
2765414c70cbSLiam Girdwood }
2766414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_bulk_get);
2767414c70cbSLiam Girdwood 
2768e6e74030SMark Brown /**
2769e6e74030SMark Brown  * devm_regulator_bulk_get - managed get multiple regulator consumers
2770e6e74030SMark Brown  *
2771e6e74030SMark Brown  * @dev:           Device to supply
2772e6e74030SMark Brown  * @num_consumers: Number of consumers to register
2773e6e74030SMark Brown  * @consumers:     Configuration of consumers; clients are stored here.
2774e6e74030SMark Brown  *
2775e6e74030SMark Brown  * @return 0 on success, an errno on failure.
2776e6e74030SMark Brown  *
2777e6e74030SMark Brown  * This helper function allows drivers to get several regulator
2778e6e74030SMark Brown  * consumers in one operation with management, the regulators will
2779e6e74030SMark Brown  * automatically be freed when the device is unbound.  If any of the
2780e6e74030SMark Brown  * regulators cannot be acquired then any regulators that were
2781e6e74030SMark Brown  * allocated will be freed before returning to the caller.
2782e6e74030SMark Brown  */
2783e6e74030SMark Brown int devm_regulator_bulk_get(struct device *dev, int num_consumers,
2784e6e74030SMark Brown 			    struct regulator_bulk_data *consumers)
2785e6e74030SMark Brown {
2786e6e74030SMark Brown 	int i;
2787e6e74030SMark Brown 	int ret;
2788e6e74030SMark Brown 
2789e6e74030SMark Brown 	for (i = 0; i < num_consumers; i++)
2790e6e74030SMark Brown 		consumers[i].consumer = NULL;
2791e6e74030SMark Brown 
2792e6e74030SMark Brown 	for (i = 0; i < num_consumers; i++) {
2793e6e74030SMark Brown 		consumers[i].consumer = devm_regulator_get(dev,
2794e6e74030SMark Brown 							   consumers[i].supply);
2795e6e74030SMark Brown 		if (IS_ERR(consumers[i].consumer)) {
2796e6e74030SMark Brown 			ret = PTR_ERR(consumers[i].consumer);
2797e6e74030SMark Brown 			dev_err(dev, "Failed to get supply '%s': %d\n",
2798e6e74030SMark Brown 				consumers[i].supply, ret);
2799e6e74030SMark Brown 			consumers[i].consumer = NULL;
2800e6e74030SMark Brown 			goto err;
2801e6e74030SMark Brown 		}
2802e6e74030SMark Brown 	}
2803e6e74030SMark Brown 
2804e6e74030SMark Brown 	return 0;
2805e6e74030SMark Brown 
2806e6e74030SMark Brown err:
2807e6e74030SMark Brown 	for (i = 0; i < num_consumers && consumers[i].consumer; i++)
2808e6e74030SMark Brown 		devm_regulator_put(consumers[i].consumer);
2809e6e74030SMark Brown 
2810e6e74030SMark Brown 	return ret;
2811e6e74030SMark Brown }
2812e6e74030SMark Brown EXPORT_SYMBOL_GPL(devm_regulator_bulk_get);
2813e6e74030SMark Brown 
2814f21e0e81SMark Brown static void regulator_bulk_enable_async(void *data, async_cookie_t cookie)
2815f21e0e81SMark Brown {
2816f21e0e81SMark Brown 	struct regulator_bulk_data *bulk = data;
2817f21e0e81SMark Brown 
2818f21e0e81SMark Brown 	bulk->ret = regulator_enable(bulk->consumer);
2819f21e0e81SMark Brown }
2820f21e0e81SMark Brown 
2821414c70cbSLiam Girdwood /**
2822414c70cbSLiam Girdwood  * regulator_bulk_enable - enable multiple regulator consumers
2823414c70cbSLiam Girdwood  *
2824414c70cbSLiam Girdwood  * @num_consumers: Number of consumers
2825414c70cbSLiam Girdwood  * @consumers:     Consumer data; clients are stored here.
2826414c70cbSLiam Girdwood  * @return         0 on success, an errno on failure
2827414c70cbSLiam Girdwood  *
2828414c70cbSLiam Girdwood  * This convenience API allows consumers to enable multiple regulator
2829414c70cbSLiam Girdwood  * clients in a single API call.  If any consumers cannot be enabled
2830414c70cbSLiam Girdwood  * then any others that were enabled will be disabled again prior to
2831414c70cbSLiam Girdwood  * return.
2832414c70cbSLiam Girdwood  */
2833414c70cbSLiam Girdwood int regulator_bulk_enable(int num_consumers,
2834414c70cbSLiam Girdwood 			  struct regulator_bulk_data *consumers)
2835414c70cbSLiam Girdwood {
28362955b47dSDan Williams 	ASYNC_DOMAIN_EXCLUSIVE(async_domain);
2837414c70cbSLiam Girdwood 	int i;
2838f21e0e81SMark Brown 	int ret = 0;
2839414c70cbSLiam Girdwood 
28406492bc1bSMark Brown 	for (i = 0; i < num_consumers; i++) {
28416492bc1bSMark Brown 		if (consumers[i].consumer->always_on)
28426492bc1bSMark Brown 			consumers[i].ret = 0;
28436492bc1bSMark Brown 		else
2844f21e0e81SMark Brown 			async_schedule_domain(regulator_bulk_enable_async,
2845f21e0e81SMark Brown 					      &consumers[i], &async_domain);
28466492bc1bSMark Brown 	}
2847f21e0e81SMark Brown 
2848f21e0e81SMark Brown 	async_synchronize_full_domain(&async_domain);
2849f21e0e81SMark Brown 
2850f21e0e81SMark Brown 	/* If any consumer failed we need to unwind any that succeeded */
2851414c70cbSLiam Girdwood 	for (i = 0; i < num_consumers; i++) {
2852f21e0e81SMark Brown 		if (consumers[i].ret != 0) {
2853f21e0e81SMark Brown 			ret = consumers[i].ret;
2854414c70cbSLiam Girdwood 			goto err;
2855414c70cbSLiam Girdwood 		}
2856f21e0e81SMark Brown 	}
2857414c70cbSLiam Girdwood 
2858414c70cbSLiam Girdwood 	return 0;
2859414c70cbSLiam Girdwood 
2860414c70cbSLiam Girdwood err:
2861b29c7690SAxel Lin 	pr_err("Failed to enable %s: %d\n", consumers[i].supply, ret);
2862b29c7690SAxel Lin 	while (--i >= 0)
2863414c70cbSLiam Girdwood 		regulator_disable(consumers[i].consumer);
2864414c70cbSLiam Girdwood 
2865414c70cbSLiam Girdwood 	return ret;
2866414c70cbSLiam Girdwood }
2867414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_bulk_enable);
2868414c70cbSLiam Girdwood 
2869414c70cbSLiam Girdwood /**
2870414c70cbSLiam Girdwood  * regulator_bulk_disable - disable multiple regulator consumers
2871414c70cbSLiam Girdwood  *
2872414c70cbSLiam Girdwood  * @num_consumers: Number of consumers
2873414c70cbSLiam Girdwood  * @consumers:     Consumer data; clients are stored here.
2874414c70cbSLiam Girdwood  * @return         0 on success, an errno on failure
2875414c70cbSLiam Girdwood  *
2876414c70cbSLiam Girdwood  * This convenience API allows consumers to disable multiple regulator
287749e22632SSylwester Nawrocki  * clients in a single API call.  If any consumers cannot be disabled
287849e22632SSylwester Nawrocki  * then any others that were disabled will be enabled again prior to
2879414c70cbSLiam Girdwood  * return.
2880414c70cbSLiam Girdwood  */
2881414c70cbSLiam Girdwood int regulator_bulk_disable(int num_consumers,
2882414c70cbSLiam Girdwood 			   struct regulator_bulk_data *consumers)
2883414c70cbSLiam Girdwood {
2884414c70cbSLiam Girdwood 	int i;
288501e86f49SMark Brown 	int ret, r;
2886414c70cbSLiam Girdwood 
288749e22632SSylwester Nawrocki 	for (i = num_consumers - 1; i >= 0; --i) {
2888414c70cbSLiam Girdwood 		ret = regulator_disable(consumers[i].consumer);
2889414c70cbSLiam Girdwood 		if (ret != 0)
2890414c70cbSLiam Girdwood 			goto err;
2891414c70cbSLiam Girdwood 	}
2892414c70cbSLiam Girdwood 
2893414c70cbSLiam Girdwood 	return 0;
2894414c70cbSLiam Girdwood 
2895414c70cbSLiam Girdwood err:
28965da84fd9SJoe Perches 	pr_err("Failed to disable %s: %d\n", consumers[i].supply, ret);
289701e86f49SMark Brown 	for (++i; i < num_consumers; ++i) {
289801e86f49SMark Brown 		r = regulator_enable(consumers[i].consumer);
289901e86f49SMark Brown 		if (r != 0)
290001e86f49SMark Brown 			pr_err("Failed to reename %s: %d\n",
290101e86f49SMark Brown 			       consumers[i].supply, r);
290201e86f49SMark Brown 	}
2903414c70cbSLiam Girdwood 
2904414c70cbSLiam Girdwood 	return ret;
2905414c70cbSLiam Girdwood }
2906414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_bulk_disable);
2907414c70cbSLiam Girdwood 
2908414c70cbSLiam Girdwood /**
2909e1de2f42SDonggeun Kim  * regulator_bulk_force_disable - force disable multiple regulator consumers
2910e1de2f42SDonggeun Kim  *
2911e1de2f42SDonggeun Kim  * @num_consumers: Number of consumers
2912e1de2f42SDonggeun Kim  * @consumers:     Consumer data; clients are stored here.
2913e1de2f42SDonggeun Kim  * @return         0 on success, an errno on failure
2914e1de2f42SDonggeun Kim  *
2915e1de2f42SDonggeun Kim  * This convenience API allows consumers to forcibly disable multiple regulator
2916e1de2f42SDonggeun Kim  * clients in a single API call.
2917e1de2f42SDonggeun Kim  * NOTE: This should be used for situations when device damage will
2918e1de2f42SDonggeun Kim  * likely occur if the regulators are not disabled (e.g. over temp).
2919e1de2f42SDonggeun Kim  * Although regulator_force_disable function call for some consumers can
2920e1de2f42SDonggeun Kim  * return error numbers, the function is called for all consumers.
2921e1de2f42SDonggeun Kim  */
2922e1de2f42SDonggeun Kim int regulator_bulk_force_disable(int num_consumers,
2923e1de2f42SDonggeun Kim 			   struct regulator_bulk_data *consumers)
2924e1de2f42SDonggeun Kim {
2925e1de2f42SDonggeun Kim 	int i;
2926e1de2f42SDonggeun Kim 	int ret;
2927e1de2f42SDonggeun Kim 
2928e1de2f42SDonggeun Kim 	for (i = 0; i < num_consumers; i++)
2929e1de2f42SDonggeun Kim 		consumers[i].ret =
2930e1de2f42SDonggeun Kim 			    regulator_force_disable(consumers[i].consumer);
2931e1de2f42SDonggeun Kim 
2932e1de2f42SDonggeun Kim 	for (i = 0; i < num_consumers; i++) {
2933e1de2f42SDonggeun Kim 		if (consumers[i].ret != 0) {
2934e1de2f42SDonggeun Kim 			ret = consumers[i].ret;
2935e1de2f42SDonggeun Kim 			goto out;
2936e1de2f42SDonggeun Kim 		}
2937e1de2f42SDonggeun Kim 	}
2938e1de2f42SDonggeun Kim 
2939e1de2f42SDonggeun Kim 	return 0;
2940e1de2f42SDonggeun Kim out:
2941e1de2f42SDonggeun Kim 	return ret;
2942e1de2f42SDonggeun Kim }
2943e1de2f42SDonggeun Kim EXPORT_SYMBOL_GPL(regulator_bulk_force_disable);
2944e1de2f42SDonggeun Kim 
2945e1de2f42SDonggeun Kim /**
2946414c70cbSLiam Girdwood  * regulator_bulk_free - free multiple regulator consumers
2947414c70cbSLiam Girdwood  *
2948414c70cbSLiam Girdwood  * @num_consumers: Number of consumers
2949414c70cbSLiam Girdwood  * @consumers:     Consumer data; clients are stored here.
2950414c70cbSLiam Girdwood  *
2951414c70cbSLiam Girdwood  * This convenience API allows consumers to free multiple regulator
2952414c70cbSLiam Girdwood  * clients in a single API call.
2953414c70cbSLiam Girdwood  */
2954414c70cbSLiam Girdwood void regulator_bulk_free(int num_consumers,
2955414c70cbSLiam Girdwood 			 struct regulator_bulk_data *consumers)
2956414c70cbSLiam Girdwood {
2957414c70cbSLiam Girdwood 	int i;
2958414c70cbSLiam Girdwood 
2959414c70cbSLiam Girdwood 	for (i = 0; i < num_consumers; i++) {
2960414c70cbSLiam Girdwood 		regulator_put(consumers[i].consumer);
2961414c70cbSLiam Girdwood 		consumers[i].consumer = NULL;
2962414c70cbSLiam Girdwood 	}
2963414c70cbSLiam Girdwood }
2964414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_bulk_free);
2965414c70cbSLiam Girdwood 
2966414c70cbSLiam Girdwood /**
2967414c70cbSLiam Girdwood  * regulator_notifier_call_chain - call regulator event notifier
296869279fb9SMark Brown  * @rdev: regulator source
2969414c70cbSLiam Girdwood  * @event: notifier block
297069279fb9SMark Brown  * @data: callback-specific data.
2971414c70cbSLiam Girdwood  *
2972414c70cbSLiam Girdwood  * Called by regulator drivers to notify clients a regulator event has
2973414c70cbSLiam Girdwood  * occurred. We also notify regulator clients downstream.
2974b136fb44SJonathan Cameron  * Note lock must be held by caller.
2975414c70cbSLiam Girdwood  */
2976414c70cbSLiam Girdwood int regulator_notifier_call_chain(struct regulator_dev *rdev,
2977414c70cbSLiam Girdwood 				  unsigned long event, void *data)
2978414c70cbSLiam Girdwood {
2979414c70cbSLiam Girdwood 	_notifier_call_chain(rdev, event, data);
2980414c70cbSLiam Girdwood 	return NOTIFY_DONE;
2981414c70cbSLiam Girdwood 
2982414c70cbSLiam Girdwood }
2983414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_notifier_call_chain);
2984414c70cbSLiam Girdwood 
2985be721979SMark Brown /**
2986be721979SMark Brown  * regulator_mode_to_status - convert a regulator mode into a status
2987be721979SMark Brown  *
2988be721979SMark Brown  * @mode: Mode to convert
2989be721979SMark Brown  *
2990be721979SMark Brown  * Convert a regulator mode into a status.
2991be721979SMark Brown  */
2992be721979SMark Brown int regulator_mode_to_status(unsigned int mode)
2993be721979SMark Brown {
2994be721979SMark Brown 	switch (mode) {
2995be721979SMark Brown 	case REGULATOR_MODE_FAST:
2996be721979SMark Brown 		return REGULATOR_STATUS_FAST;
2997be721979SMark Brown 	case REGULATOR_MODE_NORMAL:
2998be721979SMark Brown 		return REGULATOR_STATUS_NORMAL;
2999be721979SMark Brown 	case REGULATOR_MODE_IDLE:
3000be721979SMark Brown 		return REGULATOR_STATUS_IDLE;
300103ffcf3dSKrystian Garbaciak 	case REGULATOR_MODE_STANDBY:
3002be721979SMark Brown 		return REGULATOR_STATUS_STANDBY;
3003be721979SMark Brown 	default:
30041beaf762SKrystian Garbaciak 		return REGULATOR_STATUS_UNDEFINED;
3005be721979SMark Brown 	}
3006be721979SMark Brown }
3007be721979SMark Brown EXPORT_SYMBOL_GPL(regulator_mode_to_status);
3008be721979SMark Brown 
30097ad68e2fSDavid Brownell /*
30107ad68e2fSDavid Brownell  * To avoid cluttering sysfs (and memory) with useless state, only
30117ad68e2fSDavid Brownell  * create attributes that can be meaningfully displayed.
30127ad68e2fSDavid Brownell  */
30137ad68e2fSDavid Brownell static int add_regulator_attributes(struct regulator_dev *rdev)
30147ad68e2fSDavid Brownell {
30157ad68e2fSDavid Brownell 	struct device		*dev = &rdev->dev;
30167ad68e2fSDavid Brownell 	struct regulator_ops	*ops = rdev->desc->ops;
30177ad68e2fSDavid Brownell 	int			status = 0;
30187ad68e2fSDavid Brownell 
30197ad68e2fSDavid Brownell 	/* some attributes need specific methods to be displayed */
30204c78899bSMark Brown 	if ((ops->get_voltage && ops->get_voltage(rdev) >= 0) ||
30214c78899bSMark Brown 	    (ops->get_voltage_sel && ops->get_voltage_sel(rdev) >= 0)) {
30227ad68e2fSDavid Brownell 		status = device_create_file(dev, &dev_attr_microvolts);
30237ad68e2fSDavid Brownell 		if (status < 0)
30247ad68e2fSDavid Brownell 			return status;
30257ad68e2fSDavid Brownell 	}
30267ad68e2fSDavid Brownell 	if (ops->get_current_limit) {
30277ad68e2fSDavid Brownell 		status = device_create_file(dev, &dev_attr_microamps);
30287ad68e2fSDavid Brownell 		if (status < 0)
30297ad68e2fSDavid Brownell 			return status;
30307ad68e2fSDavid Brownell 	}
30317ad68e2fSDavid Brownell 	if (ops->get_mode) {
30327ad68e2fSDavid Brownell 		status = device_create_file(dev, &dev_attr_opmode);
30337ad68e2fSDavid Brownell 		if (status < 0)
30347ad68e2fSDavid Brownell 			return status;
30357ad68e2fSDavid Brownell 	}
30367ad68e2fSDavid Brownell 	if (ops->is_enabled) {
30377ad68e2fSDavid Brownell 		status = device_create_file(dev, &dev_attr_state);
30387ad68e2fSDavid Brownell 		if (status < 0)
30397ad68e2fSDavid Brownell 			return status;
30407ad68e2fSDavid Brownell 	}
3041853116a1SDavid Brownell 	if (ops->get_status) {
3042853116a1SDavid Brownell 		status = device_create_file(dev, &dev_attr_status);
3043853116a1SDavid Brownell 		if (status < 0)
3044853116a1SDavid Brownell 			return status;
3045853116a1SDavid Brownell 	}
30467ad68e2fSDavid Brownell 
30477ad68e2fSDavid Brownell 	/* some attributes are type-specific */
30487ad68e2fSDavid Brownell 	if (rdev->desc->type == REGULATOR_CURRENT) {
30497ad68e2fSDavid Brownell 		status = device_create_file(dev, &dev_attr_requested_microamps);
30507ad68e2fSDavid Brownell 		if (status < 0)
30517ad68e2fSDavid Brownell 			return status;
30527ad68e2fSDavid Brownell 	}
30537ad68e2fSDavid Brownell 
30547ad68e2fSDavid Brownell 	/* all the other attributes exist to support constraints;
30557ad68e2fSDavid Brownell 	 * don't show them if there are no constraints, or if the
30567ad68e2fSDavid Brownell 	 * relevant supporting methods are missing.
30577ad68e2fSDavid Brownell 	 */
30587ad68e2fSDavid Brownell 	if (!rdev->constraints)
30597ad68e2fSDavid Brownell 		return status;
30607ad68e2fSDavid Brownell 
30617ad68e2fSDavid Brownell 	/* constraints need specific supporting methods */
3062e8eef82bSMark Brown 	if (ops->set_voltage || ops->set_voltage_sel) {
30637ad68e2fSDavid Brownell 		status = device_create_file(dev, &dev_attr_min_microvolts);
30647ad68e2fSDavid Brownell 		if (status < 0)
30657ad68e2fSDavid Brownell 			return status;
30667ad68e2fSDavid Brownell 		status = device_create_file(dev, &dev_attr_max_microvolts);
30677ad68e2fSDavid Brownell 		if (status < 0)
30687ad68e2fSDavid Brownell 			return status;
30697ad68e2fSDavid Brownell 	}
30707ad68e2fSDavid Brownell 	if (ops->set_current_limit) {
30717ad68e2fSDavid Brownell 		status = device_create_file(dev, &dev_attr_min_microamps);
30727ad68e2fSDavid Brownell 		if (status < 0)
30737ad68e2fSDavid Brownell 			return status;
30747ad68e2fSDavid Brownell 		status = device_create_file(dev, &dev_attr_max_microamps);
30757ad68e2fSDavid Brownell 		if (status < 0)
30767ad68e2fSDavid Brownell 			return status;
30777ad68e2fSDavid Brownell 	}
30787ad68e2fSDavid Brownell 
30797ad68e2fSDavid Brownell 	status = device_create_file(dev, &dev_attr_suspend_standby_state);
30807ad68e2fSDavid Brownell 	if (status < 0)
30817ad68e2fSDavid Brownell 		return status;
30827ad68e2fSDavid Brownell 	status = device_create_file(dev, &dev_attr_suspend_mem_state);
30837ad68e2fSDavid Brownell 	if (status < 0)
30847ad68e2fSDavid Brownell 		return status;
30857ad68e2fSDavid Brownell 	status = device_create_file(dev, &dev_attr_suspend_disk_state);
30867ad68e2fSDavid Brownell 	if (status < 0)
30877ad68e2fSDavid Brownell 		return status;
30887ad68e2fSDavid Brownell 
30897ad68e2fSDavid Brownell 	if (ops->set_suspend_voltage) {
30907ad68e2fSDavid Brownell 		status = device_create_file(dev,
30917ad68e2fSDavid Brownell 				&dev_attr_suspend_standby_microvolts);
30927ad68e2fSDavid Brownell 		if (status < 0)
30937ad68e2fSDavid Brownell 			return status;
30947ad68e2fSDavid Brownell 		status = device_create_file(dev,
30957ad68e2fSDavid Brownell 				&dev_attr_suspend_mem_microvolts);
30967ad68e2fSDavid Brownell 		if (status < 0)
30977ad68e2fSDavid Brownell 			return status;
30987ad68e2fSDavid Brownell 		status = device_create_file(dev,
30997ad68e2fSDavid Brownell 				&dev_attr_suspend_disk_microvolts);
31007ad68e2fSDavid Brownell 		if (status < 0)
31017ad68e2fSDavid Brownell 			return status;
31027ad68e2fSDavid Brownell 	}
31037ad68e2fSDavid Brownell 
31047ad68e2fSDavid Brownell 	if (ops->set_suspend_mode) {
31057ad68e2fSDavid Brownell 		status = device_create_file(dev,
31067ad68e2fSDavid Brownell 				&dev_attr_suspend_standby_mode);
31077ad68e2fSDavid Brownell 		if (status < 0)
31087ad68e2fSDavid Brownell 			return status;
31097ad68e2fSDavid Brownell 		status = device_create_file(dev,
31107ad68e2fSDavid Brownell 				&dev_attr_suspend_mem_mode);
31117ad68e2fSDavid Brownell 		if (status < 0)
31127ad68e2fSDavid Brownell 			return status;
31137ad68e2fSDavid Brownell 		status = device_create_file(dev,
31147ad68e2fSDavid Brownell 				&dev_attr_suspend_disk_mode);
31157ad68e2fSDavid Brownell 		if (status < 0)
31167ad68e2fSDavid Brownell 			return status;
31177ad68e2fSDavid Brownell 	}
31187ad68e2fSDavid Brownell 
31197ad68e2fSDavid Brownell 	return status;
31207ad68e2fSDavid Brownell }
31217ad68e2fSDavid Brownell 
31221130e5b3SMark Brown static void rdev_init_debugfs(struct regulator_dev *rdev)
31231130e5b3SMark Brown {
31241130e5b3SMark Brown 	rdev->debugfs = debugfs_create_dir(rdev_get_name(rdev), debugfs_root);
312524751434SStephen Boyd 	if (!rdev->debugfs) {
31261130e5b3SMark Brown 		rdev_warn(rdev, "Failed to create debugfs directory\n");
31271130e5b3SMark Brown 		return;
31281130e5b3SMark Brown 	}
31291130e5b3SMark Brown 
31301130e5b3SMark Brown 	debugfs_create_u32("use_count", 0444, rdev->debugfs,
31311130e5b3SMark Brown 			   &rdev->use_count);
31321130e5b3SMark Brown 	debugfs_create_u32("open_count", 0444, rdev->debugfs,
31331130e5b3SMark Brown 			   &rdev->open_count);
31341130e5b3SMark Brown }
31351130e5b3SMark Brown 
3136414c70cbSLiam Girdwood /**
3137414c70cbSLiam Girdwood  * regulator_register - register regulator
313869279fb9SMark Brown  * @regulator_desc: regulator to register
3139c172708dSMark Brown  * @config: runtime configuration for regulator
3140414c70cbSLiam Girdwood  *
3141414c70cbSLiam Girdwood  * Called by regulator drivers to register a regulator.
3142414c70cbSLiam Girdwood  * Returns 0 on success.
3143414c70cbSLiam Girdwood  */
314465f26846SMark Brown struct regulator_dev *
314565f26846SMark Brown regulator_register(const struct regulator_desc *regulator_desc,
3146c172708dSMark Brown 		   const struct regulator_config *config)
3147414c70cbSLiam Girdwood {
31489a8f5e07SMark Brown 	const struct regulation_constraints *constraints = NULL;
3149c172708dSMark Brown 	const struct regulator_init_data *init_data;
3150414c70cbSLiam Girdwood 	static atomic_t regulator_no = ATOMIC_INIT(0);
3151414c70cbSLiam Girdwood 	struct regulator_dev *rdev;
315232c8fad4SMark Brown 	struct device *dev;
3153a5766f11SLiam Girdwood 	int ret, i;
315469511a45SRajendra Nayak 	const char *supply = NULL;
3155414c70cbSLiam Girdwood 
3156c172708dSMark Brown 	if (regulator_desc == NULL || config == NULL)
3157414c70cbSLiam Girdwood 		return ERR_PTR(-EINVAL);
3158414c70cbSLiam Girdwood 
315932c8fad4SMark Brown 	dev = config->dev;
3160dcf70112SMark Brown 	WARN_ON(!dev);
316132c8fad4SMark Brown 
3162414c70cbSLiam Girdwood 	if (regulator_desc->name == NULL || regulator_desc->ops == NULL)
3163414c70cbSLiam Girdwood 		return ERR_PTR(-EINVAL);
3164414c70cbSLiam Girdwood 
3165cd78dfc6SDiego Liziero 	if (regulator_desc->type != REGULATOR_VOLTAGE &&
3166cd78dfc6SDiego Liziero 	    regulator_desc->type != REGULATOR_CURRENT)
3167414c70cbSLiam Girdwood 		return ERR_PTR(-EINVAL);
3168414c70cbSLiam Girdwood 
3169476c2d83SMark Brown 	/* Only one of each should be implemented */
3170476c2d83SMark Brown 	WARN_ON(regulator_desc->ops->get_voltage &&
3171476c2d83SMark Brown 		regulator_desc->ops->get_voltage_sel);
3172e8eef82bSMark Brown 	WARN_ON(regulator_desc->ops->set_voltage &&
3173e8eef82bSMark Brown 		regulator_desc->ops->set_voltage_sel);
3174476c2d83SMark Brown 
3175476c2d83SMark Brown 	/* If we're using selectors we must implement list_voltage. */
3176476c2d83SMark Brown 	if (regulator_desc->ops->get_voltage_sel &&
3177476c2d83SMark Brown 	    !regulator_desc->ops->list_voltage) {
3178476c2d83SMark Brown 		return ERR_PTR(-EINVAL);
3179476c2d83SMark Brown 	}
3180e8eef82bSMark Brown 	if (regulator_desc->ops->set_voltage_sel &&
3181e8eef82bSMark Brown 	    !regulator_desc->ops->list_voltage) {
3182e8eef82bSMark Brown 		return ERR_PTR(-EINVAL);
3183e8eef82bSMark Brown 	}
3184476c2d83SMark Brown 
3185c172708dSMark Brown 	init_data = config->init_data;
3186c172708dSMark Brown 
3187414c70cbSLiam Girdwood 	rdev = kzalloc(sizeof(struct regulator_dev), GFP_KERNEL);
3188414c70cbSLiam Girdwood 	if (rdev == NULL)
3189414c70cbSLiam Girdwood 		return ERR_PTR(-ENOMEM);
3190414c70cbSLiam Girdwood 
3191414c70cbSLiam Girdwood 	mutex_lock(&regulator_list_mutex);
3192414c70cbSLiam Girdwood 
3193414c70cbSLiam Girdwood 	mutex_init(&rdev->mutex);
3194c172708dSMark Brown 	rdev->reg_data = config->driver_data;
3195414c70cbSLiam Girdwood 	rdev->owner = regulator_desc->owner;
3196414c70cbSLiam Girdwood 	rdev->desc = regulator_desc;
31973a4b0a07SMark Brown 	if (config->regmap)
319865b19ce6SMark Brown 		rdev->regmap = config->regmap;
31993a4b0a07SMark Brown 	else
32003a4b0a07SMark Brown 		rdev->regmap = dev_get_regmap(dev, NULL);
3201414c70cbSLiam Girdwood 	INIT_LIST_HEAD(&rdev->consumer_list);
3202414c70cbSLiam Girdwood 	INIT_LIST_HEAD(&rdev->list);
3203414c70cbSLiam Girdwood 	BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier);
3204da07ecd9SMark Brown 	INIT_DELAYED_WORK(&rdev->disable_work, regulator_disable_work);
3205414c70cbSLiam Girdwood 
3206a5766f11SLiam Girdwood 	/* preform any regulator specific init */
32079a8f5e07SMark Brown 	if (init_data && init_data->regulator_init) {
3208a5766f11SLiam Girdwood 		ret = init_data->regulator_init(rdev->reg_data);
32094fca9545SDavid Brownell 		if (ret < 0)
32104fca9545SDavid Brownell 			goto clean;
3211a5766f11SLiam Girdwood 	}
3212a5766f11SLiam Girdwood 
3213a5766f11SLiam Girdwood 	/* register with sysfs */
3214a5766f11SLiam Girdwood 	rdev->dev.class = &regulator_class;
3215c172708dSMark Brown 	rdev->dev.of_node = config->of_node;
3216a5766f11SLiam Girdwood 	rdev->dev.parent = dev;
3217812460a9SKay Sievers 	dev_set_name(&rdev->dev, "regulator.%d",
3218812460a9SKay Sievers 		     atomic_inc_return(&regulator_no) - 1);
3219a5766f11SLiam Girdwood 	ret = device_register(&rdev->dev);
3220ad7725cbSVasiliy Kulikov 	if (ret != 0) {
3221ad7725cbSVasiliy Kulikov 		put_device(&rdev->dev);
32224fca9545SDavid Brownell 		goto clean;
3223ad7725cbSVasiliy Kulikov 	}
3224a5766f11SLiam Girdwood 
3225a5766f11SLiam Girdwood 	dev_set_drvdata(&rdev->dev, rdev);
3226a5766f11SLiam Girdwood 
322765f73508SMark Brown 	if (config->ena_gpio) {
322865f73508SMark Brown 		ret = gpio_request_one(config->ena_gpio,
322965f73508SMark Brown 				       GPIOF_DIR_OUT | config->ena_gpio_flags,
323065f73508SMark Brown 				       rdev_get_name(rdev));
323165f73508SMark Brown 		if (ret != 0) {
323265f73508SMark Brown 			rdev_err(rdev, "Failed to request enable GPIO%d: %d\n",
323365f73508SMark Brown 				 config->ena_gpio, ret);
323465f73508SMark Brown 			goto clean;
323565f73508SMark Brown 		}
323665f73508SMark Brown 
323765f73508SMark Brown 		rdev->ena_gpio = config->ena_gpio;
323865f73508SMark Brown 		rdev->ena_gpio_invert = config->ena_gpio_invert;
323965f73508SMark Brown 
324065f73508SMark Brown 		if (config->ena_gpio_flags & GPIOF_OUT_INIT_HIGH)
324165f73508SMark Brown 			rdev->ena_gpio_state = 1;
324265f73508SMark Brown 
324365f73508SMark Brown 		if (rdev->ena_gpio_invert)
324465f73508SMark Brown 			rdev->ena_gpio_state = !rdev->ena_gpio_state;
324565f73508SMark Brown 	}
324665f73508SMark Brown 
324774f544c1SMike Rapoport 	/* set regulator constraints */
32489a8f5e07SMark Brown 	if (init_data)
32499a8f5e07SMark Brown 		constraints = &init_data->constraints;
32509a8f5e07SMark Brown 
32519a8f5e07SMark Brown 	ret = set_machine_constraints(rdev, constraints);
325274f544c1SMike Rapoport 	if (ret < 0)
325374f544c1SMike Rapoport 		goto scrub;
325474f544c1SMike Rapoport 
32557ad68e2fSDavid Brownell 	/* add attributes supported by this regulator */
32567ad68e2fSDavid Brownell 	ret = add_regulator_attributes(rdev);
32577ad68e2fSDavid Brownell 	if (ret < 0)
32587ad68e2fSDavid Brownell 		goto scrub;
32597ad68e2fSDavid Brownell 
32609a8f5e07SMark Brown 	if (init_data && init_data->supply_regulator)
326169511a45SRajendra Nayak 		supply = init_data->supply_regulator;
326269511a45SRajendra Nayak 	else if (regulator_desc->supply_name)
326369511a45SRajendra Nayak 		supply = regulator_desc->supply_name;
326469511a45SRajendra Nayak 
326569511a45SRajendra Nayak 	if (supply) {
32660178f3e2SMark Brown 		struct regulator_dev *r;
32670178f3e2SMark Brown 
32686d191a5fSMark Brown 		r = regulator_dev_lookup(dev, supply, &ret);
32690178f3e2SMark Brown 
327069511a45SRajendra Nayak 		if (!r) {
327169511a45SRajendra Nayak 			dev_err(dev, "Failed to find supply %s\n", supply);
327204bf3011SMark Brown 			ret = -EPROBE_DEFER;
32730178f3e2SMark Brown 			goto scrub;
32740178f3e2SMark Brown 		}
32750178f3e2SMark Brown 
32760178f3e2SMark Brown 		ret = set_supply(rdev, r);
32770178f3e2SMark Brown 		if (ret < 0)
32780178f3e2SMark Brown 			goto scrub;
3279b2296bd4SLaxman Dewangan 
3280b2296bd4SLaxman Dewangan 		/* Enable supply if rail is enabled */
3281b1a86831SMark Brown 		if (_regulator_is_enabled(rdev)) {
3282b2296bd4SLaxman Dewangan 			ret = regulator_enable(rdev->supply);
3283b2296bd4SLaxman Dewangan 			if (ret < 0)
3284b2296bd4SLaxman Dewangan 				goto scrub;
3285b2296bd4SLaxman Dewangan 		}
32860178f3e2SMark Brown 	}
32870178f3e2SMark Brown 
3288a5766f11SLiam Girdwood 	/* add consumers devices */
32899a8f5e07SMark Brown 	if (init_data) {
3290a5766f11SLiam Girdwood 		for (i = 0; i < init_data->num_consumer_supplies; i++) {
3291a5766f11SLiam Girdwood 			ret = set_consumer_device_supply(rdev,
329240f9244fSMark Brown 				init_data->consumer_supplies[i].dev_name,
3293a5766f11SLiam Girdwood 				init_data->consumer_supplies[i].supply);
329423c2f041SMark Brown 			if (ret < 0) {
329523c2f041SMark Brown 				dev_err(dev, "Failed to set supply %s\n",
329623c2f041SMark Brown 					init_data->consumer_supplies[i].supply);
3297d4033b54SJani Nikula 				goto unset_supplies;
3298a5766f11SLiam Girdwood 			}
329923c2f041SMark Brown 		}
33009a8f5e07SMark Brown 	}
3301a5766f11SLiam Girdwood 
3302a5766f11SLiam Girdwood 	list_add(&rdev->list, &regulator_list);
33031130e5b3SMark Brown 
33041130e5b3SMark Brown 	rdev_init_debugfs(rdev);
3305a5766f11SLiam Girdwood out:
3306414c70cbSLiam Girdwood 	mutex_unlock(&regulator_list_mutex);
3307414c70cbSLiam Girdwood 	return rdev;
33084fca9545SDavid Brownell 
3309d4033b54SJani Nikula unset_supplies:
3310d4033b54SJani Nikula 	unset_regulator_supplies(rdev);
3311d4033b54SJani Nikula 
33124fca9545SDavid Brownell scrub:
3313e81dba85SMark Brown 	if (rdev->supply)
3314e81dba85SMark Brown 		regulator_put(rdev->supply);
331565f73508SMark Brown 	if (rdev->ena_gpio)
331665f73508SMark Brown 		gpio_free(rdev->ena_gpio);
33171a6958e7SAxel Lin 	kfree(rdev->constraints);
33184fca9545SDavid Brownell 	device_unregister(&rdev->dev);
331953032dafSPaul Walmsley 	/* device core frees rdev */
332053032dafSPaul Walmsley 	rdev = ERR_PTR(ret);
332153032dafSPaul Walmsley 	goto out;
332253032dafSPaul Walmsley 
33234fca9545SDavid Brownell clean:
33244fca9545SDavid Brownell 	kfree(rdev);
33254fca9545SDavid Brownell 	rdev = ERR_PTR(ret);
33264fca9545SDavid Brownell 	goto out;
3327414c70cbSLiam Girdwood }
3328414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_register);
3329414c70cbSLiam Girdwood 
3330414c70cbSLiam Girdwood /**
3331414c70cbSLiam Girdwood  * regulator_unregister - unregister regulator
333269279fb9SMark Brown  * @rdev: regulator to unregister
3333414c70cbSLiam Girdwood  *
3334414c70cbSLiam Girdwood  * Called by regulator drivers to unregister a regulator.
3335414c70cbSLiam Girdwood  */
3336414c70cbSLiam Girdwood void regulator_unregister(struct regulator_dev *rdev)
3337414c70cbSLiam Girdwood {
3338414c70cbSLiam Girdwood 	if (rdev == NULL)
3339414c70cbSLiam Girdwood 		return;
3340414c70cbSLiam Girdwood 
3341e032b376SMark Brown 	if (rdev->supply)
3342e032b376SMark Brown 		regulator_put(rdev->supply);
3343414c70cbSLiam Girdwood 	mutex_lock(&regulator_list_mutex);
33441130e5b3SMark Brown 	debugfs_remove_recursive(rdev->debugfs);
3345da07ecd9SMark Brown 	flush_work_sync(&rdev->disable_work.work);
33466bf87d17SMark Brown 	WARN_ON(rdev->open_count);
33470f1d747bSMike Rapoport 	unset_regulator_supplies(rdev);
3348414c70cbSLiam Girdwood 	list_del(&rdev->list);
3349f8c12fe3SMark Brown 	kfree(rdev->constraints);
335065f73508SMark Brown 	if (rdev->ena_gpio)
335165f73508SMark Brown 		gpio_free(rdev->ena_gpio);
335258fb5cf5SLothar Waßmann 	device_unregister(&rdev->dev);
3353414c70cbSLiam Girdwood 	mutex_unlock(&regulator_list_mutex);
3354414c70cbSLiam Girdwood }
3355414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_unregister);
3356414c70cbSLiam Girdwood 
3357414c70cbSLiam Girdwood /**
3358cf7bbcdfSMark Brown  * regulator_suspend_prepare - prepare regulators for system wide suspend
3359414c70cbSLiam Girdwood  * @state: system suspend state
3360414c70cbSLiam Girdwood  *
3361414c70cbSLiam Girdwood  * Configure each regulator with it's suspend operating parameters for state.
3362414c70cbSLiam Girdwood  * This will usually be called by machine suspend code prior to supending.
3363414c70cbSLiam Girdwood  */
3364414c70cbSLiam Girdwood int regulator_suspend_prepare(suspend_state_t state)
3365414c70cbSLiam Girdwood {
3366414c70cbSLiam Girdwood 	struct regulator_dev *rdev;
3367414c70cbSLiam Girdwood 	int ret = 0;
3368414c70cbSLiam Girdwood 
3369414c70cbSLiam Girdwood 	/* ON is handled by regulator active state */
3370414c70cbSLiam Girdwood 	if (state == PM_SUSPEND_ON)
3371414c70cbSLiam Girdwood 		return -EINVAL;
3372414c70cbSLiam Girdwood 
3373414c70cbSLiam Girdwood 	mutex_lock(&regulator_list_mutex);
3374414c70cbSLiam Girdwood 	list_for_each_entry(rdev, &regulator_list, list) {
3375414c70cbSLiam Girdwood 
3376414c70cbSLiam Girdwood 		mutex_lock(&rdev->mutex);
3377414c70cbSLiam Girdwood 		ret = suspend_prepare(rdev, state);
3378414c70cbSLiam Girdwood 		mutex_unlock(&rdev->mutex);
3379414c70cbSLiam Girdwood 
3380414c70cbSLiam Girdwood 		if (ret < 0) {
33815da84fd9SJoe Perches 			rdev_err(rdev, "failed to prepare\n");
3382414c70cbSLiam Girdwood 			goto out;
3383414c70cbSLiam Girdwood 		}
3384414c70cbSLiam Girdwood 	}
3385414c70cbSLiam Girdwood out:
3386414c70cbSLiam Girdwood 	mutex_unlock(&regulator_list_mutex);
3387414c70cbSLiam Girdwood 	return ret;
3388414c70cbSLiam Girdwood }
3389414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_suspend_prepare);
3390414c70cbSLiam Girdwood 
3391414c70cbSLiam Girdwood /**
33927a32b589SMyungJoo Ham  * regulator_suspend_finish - resume regulators from system wide suspend
33937a32b589SMyungJoo Ham  *
33947a32b589SMyungJoo Ham  * Turn on regulators that might be turned off by regulator_suspend_prepare
33957a32b589SMyungJoo Ham  * and that should be turned on according to the regulators properties.
33967a32b589SMyungJoo Ham  */
33977a32b589SMyungJoo Ham int regulator_suspend_finish(void)
33987a32b589SMyungJoo Ham {
33997a32b589SMyungJoo Ham 	struct regulator_dev *rdev;
34007a32b589SMyungJoo Ham 	int ret = 0, error;
34017a32b589SMyungJoo Ham 
34027a32b589SMyungJoo Ham 	mutex_lock(&regulator_list_mutex);
34037a32b589SMyungJoo Ham 	list_for_each_entry(rdev, &regulator_list, list) {
34047a32b589SMyungJoo Ham 		struct regulator_ops *ops = rdev->desc->ops;
34057a32b589SMyungJoo Ham 
34067a32b589SMyungJoo Ham 		mutex_lock(&rdev->mutex);
34077a32b589SMyungJoo Ham 		if ((rdev->use_count > 0  || rdev->constraints->always_on) &&
34087a32b589SMyungJoo Ham 				ops->enable) {
34097a32b589SMyungJoo Ham 			error = ops->enable(rdev);
34107a32b589SMyungJoo Ham 			if (error)
34117a32b589SMyungJoo Ham 				ret = error;
34127a32b589SMyungJoo Ham 		} else {
34137a32b589SMyungJoo Ham 			if (!has_full_constraints)
34147a32b589SMyungJoo Ham 				goto unlock;
34157a32b589SMyungJoo Ham 			if (!ops->disable)
34167a32b589SMyungJoo Ham 				goto unlock;
3417b1a86831SMark Brown 			if (!_regulator_is_enabled(rdev))
34187a32b589SMyungJoo Ham 				goto unlock;
34197a32b589SMyungJoo Ham 
34207a32b589SMyungJoo Ham 			error = ops->disable(rdev);
34217a32b589SMyungJoo Ham 			if (error)
34227a32b589SMyungJoo Ham 				ret = error;
34237a32b589SMyungJoo Ham 		}
34247a32b589SMyungJoo Ham unlock:
34257a32b589SMyungJoo Ham 		mutex_unlock(&rdev->mutex);
34267a32b589SMyungJoo Ham 	}
34277a32b589SMyungJoo Ham 	mutex_unlock(&regulator_list_mutex);
34287a32b589SMyungJoo Ham 	return ret;
34297a32b589SMyungJoo Ham }
34307a32b589SMyungJoo Ham EXPORT_SYMBOL_GPL(regulator_suspend_finish);
34317a32b589SMyungJoo Ham 
34327a32b589SMyungJoo Ham /**
3433ca725561SMark Brown  * regulator_has_full_constraints - the system has fully specified constraints
3434ca725561SMark Brown  *
3435ca725561SMark Brown  * Calling this function will cause the regulator API to disable all
3436ca725561SMark Brown  * regulators which have a zero use count and don't have an always_on
3437ca725561SMark Brown  * constraint in a late_initcall.
3438ca725561SMark Brown  *
3439ca725561SMark Brown  * The intention is that this will become the default behaviour in a
3440ca725561SMark Brown  * future kernel release so users are encouraged to use this facility
3441ca725561SMark Brown  * now.
3442ca725561SMark Brown  */
3443ca725561SMark Brown void regulator_has_full_constraints(void)
3444ca725561SMark Brown {
3445ca725561SMark Brown 	has_full_constraints = 1;
3446ca725561SMark Brown }
3447ca725561SMark Brown EXPORT_SYMBOL_GPL(regulator_has_full_constraints);
3448ca725561SMark Brown 
3449ca725561SMark Brown /**
3450688fe99aSMark Brown  * regulator_use_dummy_regulator - Provide a dummy regulator when none is found
3451688fe99aSMark Brown  *
3452688fe99aSMark Brown  * Calling this function will cause the regulator API to provide a
3453688fe99aSMark Brown  * dummy regulator to consumers if no physical regulator is found,
3454688fe99aSMark Brown  * allowing most consumers to proceed as though a regulator were
3455688fe99aSMark Brown  * configured.  This allows systems such as those with software
3456688fe99aSMark Brown  * controllable regulators for the CPU core only to be brought up more
3457688fe99aSMark Brown  * readily.
3458688fe99aSMark Brown  */
3459688fe99aSMark Brown void regulator_use_dummy_regulator(void)
3460688fe99aSMark Brown {
3461688fe99aSMark Brown 	board_wants_dummy_regulator = true;
3462688fe99aSMark Brown }
3463688fe99aSMark Brown EXPORT_SYMBOL_GPL(regulator_use_dummy_regulator);
3464688fe99aSMark Brown 
3465688fe99aSMark Brown /**
3466414c70cbSLiam Girdwood  * rdev_get_drvdata - get rdev regulator driver data
346769279fb9SMark Brown  * @rdev: regulator
3468414c70cbSLiam Girdwood  *
3469414c70cbSLiam Girdwood  * Get rdev regulator driver private data. This call can be used in the
3470414c70cbSLiam Girdwood  * regulator driver context.
3471414c70cbSLiam Girdwood  */
3472414c70cbSLiam Girdwood void *rdev_get_drvdata(struct regulator_dev *rdev)
3473414c70cbSLiam Girdwood {
3474414c70cbSLiam Girdwood 	return rdev->reg_data;
3475414c70cbSLiam Girdwood }
3476414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(rdev_get_drvdata);
3477414c70cbSLiam Girdwood 
3478414c70cbSLiam Girdwood /**
3479414c70cbSLiam Girdwood  * regulator_get_drvdata - get regulator driver data
3480414c70cbSLiam Girdwood  * @regulator: regulator
3481414c70cbSLiam Girdwood  *
3482414c70cbSLiam Girdwood  * Get regulator driver private data. This call can be used in the consumer
3483414c70cbSLiam Girdwood  * driver context when non API regulator specific functions need to be called.
3484414c70cbSLiam Girdwood  */
3485414c70cbSLiam Girdwood void *regulator_get_drvdata(struct regulator *regulator)
3486414c70cbSLiam Girdwood {
3487414c70cbSLiam Girdwood 	return regulator->rdev->reg_data;
3488414c70cbSLiam Girdwood }
3489414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_get_drvdata);
3490414c70cbSLiam Girdwood 
3491414c70cbSLiam Girdwood /**
3492414c70cbSLiam Girdwood  * regulator_set_drvdata - set regulator driver data
3493414c70cbSLiam Girdwood  * @regulator: regulator
3494414c70cbSLiam Girdwood  * @data: data
3495414c70cbSLiam Girdwood  */
3496414c70cbSLiam Girdwood void regulator_set_drvdata(struct regulator *regulator, void *data)
3497414c70cbSLiam Girdwood {
3498414c70cbSLiam Girdwood 	regulator->rdev->reg_data = data;
3499414c70cbSLiam Girdwood }
3500414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_set_drvdata);
3501414c70cbSLiam Girdwood 
3502414c70cbSLiam Girdwood /**
3503414c70cbSLiam Girdwood  * regulator_get_id - get regulator ID
350469279fb9SMark Brown  * @rdev: regulator
3505414c70cbSLiam Girdwood  */
3506414c70cbSLiam Girdwood int rdev_get_id(struct regulator_dev *rdev)
3507414c70cbSLiam Girdwood {
3508414c70cbSLiam Girdwood 	return rdev->desc->id;
3509414c70cbSLiam Girdwood }
3510414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(rdev_get_id);
3511414c70cbSLiam Girdwood 
3512a5766f11SLiam Girdwood struct device *rdev_get_dev(struct regulator_dev *rdev)
3513a5766f11SLiam Girdwood {
3514a5766f11SLiam Girdwood 	return &rdev->dev;
3515a5766f11SLiam Girdwood }
3516a5766f11SLiam Girdwood EXPORT_SYMBOL_GPL(rdev_get_dev);
3517a5766f11SLiam Girdwood 
3518a5766f11SLiam Girdwood void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data)
3519a5766f11SLiam Girdwood {
3520a5766f11SLiam Girdwood 	return reg_init_data->driver_data;
3521a5766f11SLiam Girdwood }
3522a5766f11SLiam Girdwood EXPORT_SYMBOL_GPL(regulator_get_init_drvdata);
3523a5766f11SLiam Girdwood 
3524ba55a974SMark Brown #ifdef CONFIG_DEBUG_FS
3525ba55a974SMark Brown static ssize_t supply_map_read_file(struct file *file, char __user *user_buf,
3526ba55a974SMark Brown 				    size_t count, loff_t *ppos)
3527ba55a974SMark Brown {
3528ba55a974SMark Brown 	char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
3529ba55a974SMark Brown 	ssize_t len, ret = 0;
3530ba55a974SMark Brown 	struct regulator_map *map;
3531ba55a974SMark Brown 
3532ba55a974SMark Brown 	if (!buf)
3533ba55a974SMark Brown 		return -ENOMEM;
3534ba55a974SMark Brown 
3535ba55a974SMark Brown 	list_for_each_entry(map, &regulator_map_list, list) {
3536ba55a974SMark Brown 		len = snprintf(buf + ret, PAGE_SIZE - ret,
3537ba55a974SMark Brown 			       "%s -> %s.%s\n",
3538ba55a974SMark Brown 			       rdev_get_name(map->regulator), map->dev_name,
3539ba55a974SMark Brown 			       map->supply);
3540ba55a974SMark Brown 		if (len >= 0)
3541ba55a974SMark Brown 			ret += len;
3542ba55a974SMark Brown 		if (ret > PAGE_SIZE) {
3543ba55a974SMark Brown 			ret = PAGE_SIZE;
3544ba55a974SMark Brown 			break;
3545ba55a974SMark Brown 		}
3546ba55a974SMark Brown 	}
3547ba55a974SMark Brown 
3548ba55a974SMark Brown 	ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
3549ba55a974SMark Brown 
3550ba55a974SMark Brown 	kfree(buf);
3551ba55a974SMark Brown 
3552ba55a974SMark Brown 	return ret;
3553ba55a974SMark Brown }
355424751434SStephen Boyd #endif
3555ba55a974SMark Brown 
3556ba55a974SMark Brown static const struct file_operations supply_map_fops = {
355724751434SStephen Boyd #ifdef CONFIG_DEBUG_FS
3558ba55a974SMark Brown 	.read = supply_map_read_file,
3559ba55a974SMark Brown 	.llseek = default_llseek,
3560ba55a974SMark Brown #endif
356124751434SStephen Boyd };
3562ba55a974SMark Brown 
3563414c70cbSLiam Girdwood static int __init regulator_init(void)
3564414c70cbSLiam Girdwood {
356534abbd68SMark Brown 	int ret;
356634abbd68SMark Brown 
356734abbd68SMark Brown 	ret = class_register(&regulator_class);
356834abbd68SMark Brown 
35691130e5b3SMark Brown 	debugfs_root = debugfs_create_dir("regulator", NULL);
357024751434SStephen Boyd 	if (!debugfs_root)
35711130e5b3SMark Brown 		pr_warn("regulator: Failed to create debugfs directory\n");
3572ba55a974SMark Brown 
3573f4d562c6SMark Brown 	debugfs_create_file("supply_map", 0444, debugfs_root, NULL,
3574f4d562c6SMark Brown 			    &supply_map_fops);
35751130e5b3SMark Brown 
357634abbd68SMark Brown 	regulator_dummy_init();
357734abbd68SMark Brown 
357834abbd68SMark Brown 	return ret;
3579414c70cbSLiam Girdwood }
3580414c70cbSLiam Girdwood 
3581414c70cbSLiam Girdwood /* init early to allow our consumers to complete system booting */
3582414c70cbSLiam Girdwood core_initcall(regulator_init);
3583ca725561SMark Brown 
3584ca725561SMark Brown static int __init regulator_init_complete(void)
3585ca725561SMark Brown {
3586ca725561SMark Brown 	struct regulator_dev *rdev;
3587ca725561SMark Brown 	struct regulator_ops *ops;
3588ca725561SMark Brown 	struct regulation_constraints *c;
3589ca725561SMark Brown 	int enabled, ret;
3590ca725561SMark Brown 
359186f5fcfcSMark Brown 	/*
359286f5fcfcSMark Brown 	 * Since DT doesn't provide an idiomatic mechanism for
359386f5fcfcSMark Brown 	 * enabling full constraints and since it's much more natural
359486f5fcfcSMark Brown 	 * with DT to provide them just assume that a DT enabled
359586f5fcfcSMark Brown 	 * system has full constraints.
359686f5fcfcSMark Brown 	 */
359786f5fcfcSMark Brown 	if (of_have_populated_dt())
359886f5fcfcSMark Brown 		has_full_constraints = true;
359986f5fcfcSMark Brown 
3600ca725561SMark Brown 	mutex_lock(&regulator_list_mutex);
3601ca725561SMark Brown 
3602ca725561SMark Brown 	/* If we have a full configuration then disable any regulators
3603ca725561SMark Brown 	 * which are not in use or always_on.  This will become the
3604ca725561SMark Brown 	 * default behaviour in the future.
3605ca725561SMark Brown 	 */
3606ca725561SMark Brown 	list_for_each_entry(rdev, &regulator_list, list) {
3607ca725561SMark Brown 		ops = rdev->desc->ops;
3608ca725561SMark Brown 		c = rdev->constraints;
3609ca725561SMark Brown 
3610f25e0b4fSMark Brown 		if (!ops->disable || (c && c->always_on))
3611ca725561SMark Brown 			continue;
3612ca725561SMark Brown 
3613ca725561SMark Brown 		mutex_lock(&rdev->mutex);
3614ca725561SMark Brown 
3615ca725561SMark Brown 		if (rdev->use_count)
3616ca725561SMark Brown 			goto unlock;
3617ca725561SMark Brown 
3618ca725561SMark Brown 		/* If we can't read the status assume it's on. */
3619ca725561SMark Brown 		if (ops->is_enabled)
3620ca725561SMark Brown 			enabled = ops->is_enabled(rdev);
3621ca725561SMark Brown 		else
3622ca725561SMark Brown 			enabled = 1;
3623ca725561SMark Brown 
3624ca725561SMark Brown 		if (!enabled)
3625ca725561SMark Brown 			goto unlock;
3626ca725561SMark Brown 
3627ca725561SMark Brown 		if (has_full_constraints) {
3628ca725561SMark Brown 			/* We log since this may kill the system if it
3629ca725561SMark Brown 			 * goes wrong. */
36305da84fd9SJoe Perches 			rdev_info(rdev, "disabling\n");
3631ca725561SMark Brown 			ret = ops->disable(rdev);
3632ca725561SMark Brown 			if (ret != 0) {
36335da84fd9SJoe Perches 				rdev_err(rdev, "couldn't disable: %d\n", ret);
3634ca725561SMark Brown 			}
3635ca725561SMark Brown 		} else {
3636ca725561SMark Brown 			/* The intention is that in future we will
3637ca725561SMark Brown 			 * assume that full constraints are provided
3638ca725561SMark Brown 			 * so warn even if we aren't going to do
3639ca725561SMark Brown 			 * anything here.
3640ca725561SMark Brown 			 */
36415da84fd9SJoe Perches 			rdev_warn(rdev, "incomplete constraints, leaving on\n");
3642ca725561SMark Brown 		}
3643ca725561SMark Brown 
3644ca725561SMark Brown unlock:
3645ca725561SMark Brown 		mutex_unlock(&rdev->mutex);
3646ca725561SMark Brown 	}
3647ca725561SMark Brown 
3648ca725561SMark Brown 	mutex_unlock(&regulator_list_mutex);
3649ca725561SMark Brown 
3650ca725561SMark Brown 	return 0;
3651ca725561SMark Brown }
3652ca725561SMark Brown late_initcall(regulator_init_complete);
3653