xref: /openbmc/linux/drivers/regulator/core.c (revision cd6dffb4)
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>
2669511a45SRajendra Nayak #include <linux/of.h>
2765b19ce6SMark Brown #include <linux/regmap.h>
2869511a45SRajendra Nayak #include <linux/regulator/of_regulator.h>
29414c70cbSLiam Girdwood #include <linux/regulator/consumer.h>
30414c70cbSLiam Girdwood #include <linux/regulator/driver.h>
31414c70cbSLiam Girdwood #include <linux/regulator/machine.h>
3265602c32SPaul Gortmaker #include <linux/module.h>
33414c70cbSLiam Girdwood 
3402fa3ec0SMark Brown #define CREATE_TRACE_POINTS
3502fa3ec0SMark Brown #include <trace/events/regulator.h>
3602fa3ec0SMark Brown 
3734abbd68SMark Brown #include "dummy.h"
3834abbd68SMark Brown 
397d51a0dbSMark Brown #define rdev_crit(rdev, fmt, ...)					\
407d51a0dbSMark Brown 	pr_crit("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
415da84fd9SJoe Perches #define rdev_err(rdev, fmt, ...)					\
425da84fd9SJoe Perches 	pr_err("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
435da84fd9SJoe Perches #define rdev_warn(rdev, fmt, ...)					\
445da84fd9SJoe Perches 	pr_warn("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
455da84fd9SJoe Perches #define rdev_info(rdev, fmt, ...)					\
465da84fd9SJoe Perches 	pr_info("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
475da84fd9SJoe Perches #define rdev_dbg(rdev, fmt, ...)					\
485da84fd9SJoe Perches 	pr_debug("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
495da84fd9SJoe Perches 
50414c70cbSLiam Girdwood static DEFINE_MUTEX(regulator_list_mutex);
51414c70cbSLiam Girdwood static LIST_HEAD(regulator_list);
52414c70cbSLiam Girdwood static LIST_HEAD(regulator_map_list);
5321cf891aSMark Brown static bool has_full_constraints;
54688fe99aSMark Brown static bool board_wants_dummy_regulator;
55414c70cbSLiam Girdwood 
561130e5b3SMark Brown static struct dentry *debugfs_root;
571130e5b3SMark Brown 
588dc5390dSMark Brown /*
59414c70cbSLiam Girdwood  * struct regulator_map
60414c70cbSLiam Girdwood  *
61414c70cbSLiam Girdwood  * Used to provide symbolic supply names to devices.
62414c70cbSLiam Girdwood  */
63414c70cbSLiam Girdwood struct regulator_map {
64414c70cbSLiam Girdwood 	struct list_head list;
6540f9244fSMark Brown 	const char *dev_name;   /* The dev_name() for the consumer */
66414c70cbSLiam Girdwood 	const char *supply;
67a5766f11SLiam Girdwood 	struct regulator_dev *regulator;
68414c70cbSLiam Girdwood };
69414c70cbSLiam Girdwood 
70414c70cbSLiam Girdwood /*
71414c70cbSLiam Girdwood  * struct regulator
72414c70cbSLiam Girdwood  *
73414c70cbSLiam Girdwood  * One for each consumer device.
74414c70cbSLiam Girdwood  */
75414c70cbSLiam Girdwood struct regulator {
76414c70cbSLiam Girdwood 	struct device *dev;
77414c70cbSLiam Girdwood 	struct list_head list;
78414c70cbSLiam Girdwood 	int uA_load;
79414c70cbSLiam Girdwood 	int min_uV;
80414c70cbSLiam Girdwood 	int max_uV;
81414c70cbSLiam Girdwood 	char *supply_name;
82414c70cbSLiam Girdwood 	struct device_attribute dev_attr;
83414c70cbSLiam Girdwood 	struct regulator_dev *rdev;
845de70519SMark Brown 	struct dentry *debugfs;
85414c70cbSLiam Girdwood };
86414c70cbSLiam Girdwood 
87414c70cbSLiam Girdwood static int _regulator_is_enabled(struct regulator_dev *rdev);
883801b86aSMark Brown static int _regulator_disable(struct regulator_dev *rdev);
89414c70cbSLiam Girdwood static int _regulator_get_voltage(struct regulator_dev *rdev);
90414c70cbSLiam Girdwood static int _regulator_get_current_limit(struct regulator_dev *rdev);
91414c70cbSLiam Girdwood static unsigned int _regulator_get_mode(struct regulator_dev *rdev);
92414c70cbSLiam Girdwood static void _notifier_call_chain(struct regulator_dev *rdev,
93414c70cbSLiam Girdwood 				  unsigned long event, void *data);
9475790251SMark Brown static int _regulator_do_set_voltage(struct regulator_dev *rdev,
9575790251SMark Brown 				     int min_uV, int max_uV);
963801b86aSMark Brown static struct regulator *create_regulator(struct regulator_dev *rdev,
973801b86aSMark Brown 					  struct device *dev,
983801b86aSMark Brown 					  const char *supply_name);
99414c70cbSLiam Girdwood 
1001083c393SMark Brown static const char *rdev_get_name(struct regulator_dev *rdev)
1011083c393SMark Brown {
1021083c393SMark Brown 	if (rdev->constraints && rdev->constraints->name)
1031083c393SMark Brown 		return rdev->constraints->name;
1041083c393SMark Brown 	else if (rdev->desc->name)
1051083c393SMark Brown 		return rdev->desc->name;
1061083c393SMark Brown 	else
1071083c393SMark Brown 		return "";
1081083c393SMark Brown }
1091083c393SMark Brown 
110414c70cbSLiam Girdwood /* gets the regulator for a given consumer device */
111414c70cbSLiam Girdwood static struct regulator *get_device_regulator(struct device *dev)
112414c70cbSLiam Girdwood {
113414c70cbSLiam Girdwood 	struct regulator *regulator = NULL;
114414c70cbSLiam Girdwood 	struct regulator_dev *rdev;
115414c70cbSLiam Girdwood 
116414c70cbSLiam Girdwood 	mutex_lock(&regulator_list_mutex);
117414c70cbSLiam Girdwood 	list_for_each_entry(rdev, &regulator_list, list) {
118414c70cbSLiam Girdwood 		mutex_lock(&rdev->mutex);
119414c70cbSLiam Girdwood 		list_for_each_entry(regulator, &rdev->consumer_list, list) {
120414c70cbSLiam Girdwood 			if (regulator->dev == dev) {
121414c70cbSLiam Girdwood 				mutex_unlock(&rdev->mutex);
122414c70cbSLiam Girdwood 				mutex_unlock(&regulator_list_mutex);
123414c70cbSLiam Girdwood 				return regulator;
124414c70cbSLiam Girdwood 			}
125414c70cbSLiam Girdwood 		}
126414c70cbSLiam Girdwood 		mutex_unlock(&rdev->mutex);
127414c70cbSLiam Girdwood 	}
128414c70cbSLiam Girdwood 	mutex_unlock(&regulator_list_mutex);
129414c70cbSLiam Girdwood 	return NULL;
130414c70cbSLiam Girdwood }
131414c70cbSLiam Girdwood 
13269511a45SRajendra Nayak /**
13369511a45SRajendra Nayak  * of_get_regulator - get a regulator device node based on supply name
13469511a45SRajendra Nayak  * @dev: Device pointer for the consumer (of regulator) device
13569511a45SRajendra Nayak  * @supply: regulator supply name
13669511a45SRajendra Nayak  *
13769511a45SRajendra Nayak  * Extract the regulator device node corresponding to the supply name.
13869511a45SRajendra Nayak  * retruns the device node corresponding to the regulator if found, else
13969511a45SRajendra Nayak  * returns NULL.
14069511a45SRajendra Nayak  */
14169511a45SRajendra Nayak static struct device_node *of_get_regulator(struct device *dev, const char *supply)
14269511a45SRajendra Nayak {
14369511a45SRajendra Nayak 	struct device_node *regnode = NULL;
14469511a45SRajendra Nayak 	char prop_name[32]; /* 32 is max size of property name */
14569511a45SRajendra Nayak 
14669511a45SRajendra Nayak 	dev_dbg(dev, "Looking up %s-supply from device tree\n", supply);
14769511a45SRajendra Nayak 
14869511a45SRajendra Nayak 	snprintf(prop_name, 32, "%s-supply", supply);
14969511a45SRajendra Nayak 	regnode = of_parse_phandle(dev->of_node, prop_name, 0);
15069511a45SRajendra Nayak 
15169511a45SRajendra Nayak 	if (!regnode) {
15216fbcc3bSRajendra Nayak 		dev_dbg(dev, "Looking up %s property in node %s failed",
15369511a45SRajendra Nayak 				prop_name, dev->of_node->full_name);
15469511a45SRajendra Nayak 		return NULL;
15569511a45SRajendra Nayak 	}
15669511a45SRajendra Nayak 	return regnode;
15769511a45SRajendra Nayak }
15869511a45SRajendra Nayak 
159414c70cbSLiam Girdwood /* Platform voltage constraint check */
160414c70cbSLiam Girdwood static int regulator_check_voltage(struct regulator_dev *rdev,
161414c70cbSLiam Girdwood 				   int *min_uV, int *max_uV)
162414c70cbSLiam Girdwood {
163414c70cbSLiam Girdwood 	BUG_ON(*min_uV > *max_uV);
164414c70cbSLiam Girdwood 
165414c70cbSLiam Girdwood 	if (!rdev->constraints) {
1665da84fd9SJoe Perches 		rdev_err(rdev, "no constraints\n");
167414c70cbSLiam Girdwood 		return -ENODEV;
168414c70cbSLiam Girdwood 	}
169414c70cbSLiam Girdwood 	if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) {
1705da84fd9SJoe Perches 		rdev_err(rdev, "operation not allowed\n");
171414c70cbSLiam Girdwood 		return -EPERM;
172414c70cbSLiam Girdwood 	}
173414c70cbSLiam Girdwood 
174414c70cbSLiam Girdwood 	if (*max_uV > rdev->constraints->max_uV)
175414c70cbSLiam Girdwood 		*max_uV = rdev->constraints->max_uV;
176414c70cbSLiam Girdwood 	if (*min_uV < rdev->constraints->min_uV)
177414c70cbSLiam Girdwood 		*min_uV = rdev->constraints->min_uV;
178414c70cbSLiam Girdwood 
17989f425edSMark Brown 	if (*min_uV > *max_uV) {
18089f425edSMark Brown 		rdev_err(rdev, "unsupportable voltage range: %d-%duV\n",
18154abd335SMark Brown 			 *min_uV, *max_uV);
182414c70cbSLiam Girdwood 		return -EINVAL;
18389f425edSMark Brown 	}
184414c70cbSLiam Girdwood 
185414c70cbSLiam Girdwood 	return 0;
186414c70cbSLiam Girdwood }
187414c70cbSLiam Girdwood 
18805fda3b1SThomas Petazzoni /* Make sure we select a voltage that suits the needs of all
18905fda3b1SThomas Petazzoni  * regulator consumers
19005fda3b1SThomas Petazzoni  */
19105fda3b1SThomas Petazzoni static int regulator_check_consumers(struct regulator_dev *rdev,
19205fda3b1SThomas Petazzoni 				     int *min_uV, int *max_uV)
19305fda3b1SThomas Petazzoni {
19405fda3b1SThomas Petazzoni 	struct regulator *regulator;
19505fda3b1SThomas Petazzoni 
19605fda3b1SThomas Petazzoni 	list_for_each_entry(regulator, &rdev->consumer_list, list) {
1974aa922c0SMark Brown 		/*
1984aa922c0SMark Brown 		 * Assume consumers that didn't say anything are OK
1994aa922c0SMark Brown 		 * with anything in the constraint range.
2004aa922c0SMark Brown 		 */
2014aa922c0SMark Brown 		if (!regulator->min_uV && !regulator->max_uV)
2024aa922c0SMark Brown 			continue;
2034aa922c0SMark Brown 
20405fda3b1SThomas Petazzoni 		if (*max_uV > regulator->max_uV)
20505fda3b1SThomas Petazzoni 			*max_uV = regulator->max_uV;
20605fda3b1SThomas Petazzoni 		if (*min_uV < regulator->min_uV)
20705fda3b1SThomas Petazzoni 			*min_uV = regulator->min_uV;
20805fda3b1SThomas Petazzoni 	}
20905fda3b1SThomas Petazzoni 
21005fda3b1SThomas Petazzoni 	if (*min_uV > *max_uV)
21105fda3b1SThomas Petazzoni 		return -EINVAL;
21205fda3b1SThomas Petazzoni 
21305fda3b1SThomas Petazzoni 	return 0;
21405fda3b1SThomas Petazzoni }
21505fda3b1SThomas Petazzoni 
216414c70cbSLiam Girdwood /* current constraint check */
217414c70cbSLiam Girdwood static int regulator_check_current_limit(struct regulator_dev *rdev,
218414c70cbSLiam Girdwood 					int *min_uA, int *max_uA)
219414c70cbSLiam Girdwood {
220414c70cbSLiam Girdwood 	BUG_ON(*min_uA > *max_uA);
221414c70cbSLiam Girdwood 
222414c70cbSLiam Girdwood 	if (!rdev->constraints) {
2235da84fd9SJoe Perches 		rdev_err(rdev, "no constraints\n");
224414c70cbSLiam Girdwood 		return -ENODEV;
225414c70cbSLiam Girdwood 	}
226414c70cbSLiam Girdwood 	if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_CURRENT)) {
2275da84fd9SJoe Perches 		rdev_err(rdev, "operation not allowed\n");
228414c70cbSLiam Girdwood 		return -EPERM;
229414c70cbSLiam Girdwood 	}
230414c70cbSLiam Girdwood 
231414c70cbSLiam Girdwood 	if (*max_uA > rdev->constraints->max_uA)
232414c70cbSLiam Girdwood 		*max_uA = rdev->constraints->max_uA;
233414c70cbSLiam Girdwood 	if (*min_uA < rdev->constraints->min_uA)
234414c70cbSLiam Girdwood 		*min_uA = rdev->constraints->min_uA;
235414c70cbSLiam Girdwood 
23689f425edSMark Brown 	if (*min_uA > *max_uA) {
23789f425edSMark Brown 		rdev_err(rdev, "unsupportable current range: %d-%duA\n",
23854abd335SMark Brown 			 *min_uA, *max_uA);
239414c70cbSLiam Girdwood 		return -EINVAL;
24089f425edSMark Brown 	}
241414c70cbSLiam Girdwood 
242414c70cbSLiam Girdwood 	return 0;
243414c70cbSLiam Girdwood }
244414c70cbSLiam Girdwood 
245414c70cbSLiam Girdwood /* operating mode constraint check */
2462c608234SMark Brown static int regulator_mode_constrain(struct regulator_dev *rdev, int *mode)
247414c70cbSLiam Girdwood {
2482c608234SMark Brown 	switch (*mode) {
249e573520bSDavid Brownell 	case REGULATOR_MODE_FAST:
250e573520bSDavid Brownell 	case REGULATOR_MODE_NORMAL:
251e573520bSDavid Brownell 	case REGULATOR_MODE_IDLE:
252e573520bSDavid Brownell 	case REGULATOR_MODE_STANDBY:
253e573520bSDavid Brownell 		break;
254e573520bSDavid Brownell 	default:
25589f425edSMark Brown 		rdev_err(rdev, "invalid mode %x specified\n", *mode);
256e573520bSDavid Brownell 		return -EINVAL;
257e573520bSDavid Brownell 	}
258e573520bSDavid Brownell 
259414c70cbSLiam Girdwood 	if (!rdev->constraints) {
2605da84fd9SJoe Perches 		rdev_err(rdev, "no constraints\n");
261414c70cbSLiam Girdwood 		return -ENODEV;
262414c70cbSLiam Girdwood 	}
263414c70cbSLiam Girdwood 	if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_MODE)) {
2645da84fd9SJoe Perches 		rdev_err(rdev, "operation not allowed\n");
265414c70cbSLiam Girdwood 		return -EPERM;
266414c70cbSLiam Girdwood 	}
2672c608234SMark Brown 
2682c608234SMark Brown 	/* The modes are bitmasks, the most power hungry modes having
2692c608234SMark Brown 	 * the lowest values. If the requested mode isn't supported
2702c608234SMark Brown 	 * try higher modes. */
2712c608234SMark Brown 	while (*mode) {
2722c608234SMark Brown 		if (rdev->constraints->valid_modes_mask & *mode)
273414c70cbSLiam Girdwood 			return 0;
2742c608234SMark Brown 		*mode /= 2;
2752c608234SMark Brown 	}
2762c608234SMark Brown 
2772c608234SMark Brown 	return -EINVAL;
278414c70cbSLiam Girdwood }
279414c70cbSLiam Girdwood 
280414c70cbSLiam Girdwood /* dynamic regulator mode switching constraint check */
281414c70cbSLiam Girdwood static int regulator_check_drms(struct regulator_dev *rdev)
282414c70cbSLiam Girdwood {
283414c70cbSLiam Girdwood 	if (!rdev->constraints) {
2845da84fd9SJoe Perches 		rdev_err(rdev, "no constraints\n");
285414c70cbSLiam Girdwood 		return -ENODEV;
286414c70cbSLiam Girdwood 	}
287414c70cbSLiam Girdwood 	if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS)) {
2885da84fd9SJoe Perches 		rdev_err(rdev, "operation not allowed\n");
289414c70cbSLiam Girdwood 		return -EPERM;
290414c70cbSLiam Girdwood 	}
291414c70cbSLiam Girdwood 	return 0;
292414c70cbSLiam Girdwood }
293414c70cbSLiam Girdwood 
294414c70cbSLiam Girdwood static ssize_t device_requested_uA_show(struct device *dev,
295414c70cbSLiam Girdwood 			     struct device_attribute *attr, char *buf)
296414c70cbSLiam Girdwood {
297414c70cbSLiam Girdwood 	struct regulator *regulator;
298414c70cbSLiam Girdwood 
299414c70cbSLiam Girdwood 	regulator = get_device_regulator(dev);
300414c70cbSLiam Girdwood 	if (regulator == NULL)
301414c70cbSLiam Girdwood 		return 0;
302414c70cbSLiam Girdwood 
303414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", regulator->uA_load);
304414c70cbSLiam Girdwood }
305414c70cbSLiam Girdwood 
306414c70cbSLiam Girdwood static ssize_t regulator_uV_show(struct device *dev,
307414c70cbSLiam Girdwood 				struct device_attribute *attr, char *buf)
308414c70cbSLiam Girdwood {
309a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
310414c70cbSLiam Girdwood 	ssize_t ret;
311414c70cbSLiam Girdwood 
312414c70cbSLiam Girdwood 	mutex_lock(&rdev->mutex);
313414c70cbSLiam Girdwood 	ret = sprintf(buf, "%d\n", _regulator_get_voltage(rdev));
314414c70cbSLiam Girdwood 	mutex_unlock(&rdev->mutex);
315414c70cbSLiam Girdwood 
316414c70cbSLiam Girdwood 	return ret;
317414c70cbSLiam Girdwood }
3187ad68e2fSDavid Brownell static DEVICE_ATTR(microvolts, 0444, regulator_uV_show, NULL);
319414c70cbSLiam Girdwood 
320414c70cbSLiam Girdwood static ssize_t regulator_uA_show(struct device *dev,
321414c70cbSLiam Girdwood 				struct device_attribute *attr, char *buf)
322414c70cbSLiam Girdwood {
323a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
324414c70cbSLiam Girdwood 
325414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", _regulator_get_current_limit(rdev));
326414c70cbSLiam Girdwood }
3277ad68e2fSDavid Brownell static DEVICE_ATTR(microamps, 0444, regulator_uA_show, NULL);
328414c70cbSLiam Girdwood 
329bc558a60SMark Brown static ssize_t regulator_name_show(struct device *dev,
330bc558a60SMark Brown 			     struct device_attribute *attr, char *buf)
331bc558a60SMark Brown {
332bc558a60SMark Brown 	struct regulator_dev *rdev = dev_get_drvdata(dev);
333bc558a60SMark Brown 
3341083c393SMark Brown 	return sprintf(buf, "%s\n", rdev_get_name(rdev));
335bc558a60SMark Brown }
336bc558a60SMark Brown 
3374fca9545SDavid Brownell static ssize_t regulator_print_opmode(char *buf, int mode)
338414c70cbSLiam Girdwood {
339414c70cbSLiam Girdwood 	switch (mode) {
340414c70cbSLiam Girdwood 	case REGULATOR_MODE_FAST:
341414c70cbSLiam Girdwood 		return sprintf(buf, "fast\n");
342414c70cbSLiam Girdwood 	case REGULATOR_MODE_NORMAL:
343414c70cbSLiam Girdwood 		return sprintf(buf, "normal\n");
344414c70cbSLiam Girdwood 	case REGULATOR_MODE_IDLE:
345414c70cbSLiam Girdwood 		return sprintf(buf, "idle\n");
346414c70cbSLiam Girdwood 	case REGULATOR_MODE_STANDBY:
347414c70cbSLiam Girdwood 		return sprintf(buf, "standby\n");
348414c70cbSLiam Girdwood 	}
349414c70cbSLiam Girdwood 	return sprintf(buf, "unknown\n");
350414c70cbSLiam Girdwood }
351414c70cbSLiam Girdwood 
3524fca9545SDavid Brownell static ssize_t regulator_opmode_show(struct device *dev,
353414c70cbSLiam Girdwood 				    struct device_attribute *attr, char *buf)
354414c70cbSLiam Girdwood {
355a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
356414c70cbSLiam Girdwood 
3574fca9545SDavid Brownell 	return regulator_print_opmode(buf, _regulator_get_mode(rdev));
3584fca9545SDavid Brownell }
3597ad68e2fSDavid Brownell static DEVICE_ATTR(opmode, 0444, regulator_opmode_show, NULL);
3604fca9545SDavid Brownell 
3614fca9545SDavid Brownell static ssize_t regulator_print_state(char *buf, int state)
3624fca9545SDavid Brownell {
363414c70cbSLiam Girdwood 	if (state > 0)
364414c70cbSLiam Girdwood 		return sprintf(buf, "enabled\n");
365414c70cbSLiam Girdwood 	else if (state == 0)
366414c70cbSLiam Girdwood 		return sprintf(buf, "disabled\n");
367414c70cbSLiam Girdwood 	else
368414c70cbSLiam Girdwood 		return sprintf(buf, "unknown\n");
369414c70cbSLiam Girdwood }
370414c70cbSLiam Girdwood 
3714fca9545SDavid Brownell static ssize_t regulator_state_show(struct device *dev,
3724fca9545SDavid Brownell 				   struct device_attribute *attr, char *buf)
3734fca9545SDavid Brownell {
3744fca9545SDavid Brownell 	struct regulator_dev *rdev = dev_get_drvdata(dev);
3759332546fSMark Brown 	ssize_t ret;
3764fca9545SDavid Brownell 
3779332546fSMark Brown 	mutex_lock(&rdev->mutex);
3789332546fSMark Brown 	ret = regulator_print_state(buf, _regulator_is_enabled(rdev));
3799332546fSMark Brown 	mutex_unlock(&rdev->mutex);
3809332546fSMark Brown 
3819332546fSMark Brown 	return ret;
3824fca9545SDavid Brownell }
3837ad68e2fSDavid Brownell static DEVICE_ATTR(state, 0444, regulator_state_show, NULL);
3844fca9545SDavid Brownell 
385853116a1SDavid Brownell static ssize_t regulator_status_show(struct device *dev,
386853116a1SDavid Brownell 				   struct device_attribute *attr, char *buf)
387853116a1SDavid Brownell {
388853116a1SDavid Brownell 	struct regulator_dev *rdev = dev_get_drvdata(dev);
389853116a1SDavid Brownell 	int status;
390853116a1SDavid Brownell 	char *label;
391853116a1SDavid Brownell 
392853116a1SDavid Brownell 	status = rdev->desc->ops->get_status(rdev);
393853116a1SDavid Brownell 	if (status < 0)
394853116a1SDavid Brownell 		return status;
395853116a1SDavid Brownell 
396853116a1SDavid Brownell 	switch (status) {
397853116a1SDavid Brownell 	case REGULATOR_STATUS_OFF:
398853116a1SDavid Brownell 		label = "off";
399853116a1SDavid Brownell 		break;
400853116a1SDavid Brownell 	case REGULATOR_STATUS_ON:
401853116a1SDavid Brownell 		label = "on";
402853116a1SDavid Brownell 		break;
403853116a1SDavid Brownell 	case REGULATOR_STATUS_ERROR:
404853116a1SDavid Brownell 		label = "error";
405853116a1SDavid Brownell 		break;
406853116a1SDavid Brownell 	case REGULATOR_STATUS_FAST:
407853116a1SDavid Brownell 		label = "fast";
408853116a1SDavid Brownell 		break;
409853116a1SDavid Brownell 	case REGULATOR_STATUS_NORMAL:
410853116a1SDavid Brownell 		label = "normal";
411853116a1SDavid Brownell 		break;
412853116a1SDavid Brownell 	case REGULATOR_STATUS_IDLE:
413853116a1SDavid Brownell 		label = "idle";
414853116a1SDavid Brownell 		break;
415853116a1SDavid Brownell 	case REGULATOR_STATUS_STANDBY:
416853116a1SDavid Brownell 		label = "standby";
417853116a1SDavid Brownell 		break;
418853116a1SDavid Brownell 	default:
419853116a1SDavid Brownell 		return -ERANGE;
420853116a1SDavid Brownell 	}
421853116a1SDavid Brownell 
422853116a1SDavid Brownell 	return sprintf(buf, "%s\n", label);
423853116a1SDavid Brownell }
424853116a1SDavid Brownell static DEVICE_ATTR(status, 0444, regulator_status_show, NULL);
425853116a1SDavid Brownell 
426414c70cbSLiam Girdwood static ssize_t regulator_min_uA_show(struct device *dev,
427414c70cbSLiam Girdwood 				    struct device_attribute *attr, char *buf)
428414c70cbSLiam Girdwood {
429a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
430414c70cbSLiam Girdwood 
431414c70cbSLiam Girdwood 	if (!rdev->constraints)
432414c70cbSLiam Girdwood 		return sprintf(buf, "constraint not defined\n");
433414c70cbSLiam Girdwood 
434414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", rdev->constraints->min_uA);
435414c70cbSLiam Girdwood }
4367ad68e2fSDavid Brownell static DEVICE_ATTR(min_microamps, 0444, regulator_min_uA_show, NULL);
437414c70cbSLiam Girdwood 
438414c70cbSLiam Girdwood static ssize_t regulator_max_uA_show(struct device *dev,
439414c70cbSLiam Girdwood 				    struct device_attribute *attr, char *buf)
440414c70cbSLiam Girdwood {
441a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
442414c70cbSLiam Girdwood 
443414c70cbSLiam Girdwood 	if (!rdev->constraints)
444414c70cbSLiam Girdwood 		return sprintf(buf, "constraint not defined\n");
445414c70cbSLiam Girdwood 
446414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", rdev->constraints->max_uA);
447414c70cbSLiam Girdwood }
4487ad68e2fSDavid Brownell static DEVICE_ATTR(max_microamps, 0444, regulator_max_uA_show, NULL);
449414c70cbSLiam Girdwood 
450414c70cbSLiam Girdwood static ssize_t regulator_min_uV_show(struct device *dev,
451414c70cbSLiam Girdwood 				    struct device_attribute *attr, char *buf)
452414c70cbSLiam Girdwood {
453a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
454414c70cbSLiam Girdwood 
455414c70cbSLiam Girdwood 	if (!rdev->constraints)
456414c70cbSLiam Girdwood 		return sprintf(buf, "constraint not defined\n");
457414c70cbSLiam Girdwood 
458414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", rdev->constraints->min_uV);
459414c70cbSLiam Girdwood }
4607ad68e2fSDavid Brownell static DEVICE_ATTR(min_microvolts, 0444, regulator_min_uV_show, NULL);
461414c70cbSLiam Girdwood 
462414c70cbSLiam Girdwood static ssize_t regulator_max_uV_show(struct device *dev,
463414c70cbSLiam Girdwood 				    struct device_attribute *attr, char *buf)
464414c70cbSLiam Girdwood {
465a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
466414c70cbSLiam Girdwood 
467414c70cbSLiam Girdwood 	if (!rdev->constraints)
468414c70cbSLiam Girdwood 		return sprintf(buf, "constraint not defined\n");
469414c70cbSLiam Girdwood 
470414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", rdev->constraints->max_uV);
471414c70cbSLiam Girdwood }
4727ad68e2fSDavid Brownell static DEVICE_ATTR(max_microvolts, 0444, regulator_max_uV_show, NULL);
473414c70cbSLiam Girdwood 
474414c70cbSLiam Girdwood static ssize_t regulator_total_uA_show(struct device *dev,
475414c70cbSLiam Girdwood 				      struct device_attribute *attr, char *buf)
476414c70cbSLiam Girdwood {
477a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
478414c70cbSLiam Girdwood 	struct regulator *regulator;
479414c70cbSLiam Girdwood 	int uA = 0;
480414c70cbSLiam Girdwood 
481414c70cbSLiam Girdwood 	mutex_lock(&rdev->mutex);
482414c70cbSLiam Girdwood 	list_for_each_entry(regulator, &rdev->consumer_list, list)
483414c70cbSLiam Girdwood 		uA += regulator->uA_load;
484414c70cbSLiam Girdwood 	mutex_unlock(&rdev->mutex);
485414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", uA);
486414c70cbSLiam Girdwood }
4877ad68e2fSDavid Brownell static DEVICE_ATTR(requested_microamps, 0444, regulator_total_uA_show, NULL);
488414c70cbSLiam Girdwood 
489414c70cbSLiam Girdwood static ssize_t regulator_num_users_show(struct device *dev,
490414c70cbSLiam Girdwood 				      struct device_attribute *attr, char *buf)
491414c70cbSLiam Girdwood {
492a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
493414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", rdev->use_count);
494414c70cbSLiam Girdwood }
495414c70cbSLiam Girdwood 
496414c70cbSLiam Girdwood static ssize_t regulator_type_show(struct device *dev,
497414c70cbSLiam Girdwood 				  struct device_attribute *attr, char *buf)
498414c70cbSLiam Girdwood {
499a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
500414c70cbSLiam Girdwood 
501414c70cbSLiam Girdwood 	switch (rdev->desc->type) {
502414c70cbSLiam Girdwood 	case REGULATOR_VOLTAGE:
503414c70cbSLiam Girdwood 		return sprintf(buf, "voltage\n");
504414c70cbSLiam Girdwood 	case REGULATOR_CURRENT:
505414c70cbSLiam Girdwood 		return sprintf(buf, "current\n");
506414c70cbSLiam Girdwood 	}
507414c70cbSLiam Girdwood 	return sprintf(buf, "unknown\n");
508414c70cbSLiam Girdwood }
509414c70cbSLiam Girdwood 
510414c70cbSLiam Girdwood static ssize_t regulator_suspend_mem_uV_show(struct device *dev,
511414c70cbSLiam Girdwood 				struct device_attribute *attr, char *buf)
512414c70cbSLiam Girdwood {
513a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
514414c70cbSLiam Girdwood 
515414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", rdev->constraints->state_mem.uV);
516414c70cbSLiam Girdwood }
5177ad68e2fSDavid Brownell static DEVICE_ATTR(suspend_mem_microvolts, 0444,
5187ad68e2fSDavid Brownell 		regulator_suspend_mem_uV_show, NULL);
519414c70cbSLiam Girdwood 
520414c70cbSLiam Girdwood static ssize_t regulator_suspend_disk_uV_show(struct device *dev,
521414c70cbSLiam Girdwood 				struct device_attribute *attr, char *buf)
522414c70cbSLiam Girdwood {
523a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
524414c70cbSLiam Girdwood 
525414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", rdev->constraints->state_disk.uV);
526414c70cbSLiam Girdwood }
5277ad68e2fSDavid Brownell static DEVICE_ATTR(suspend_disk_microvolts, 0444,
5287ad68e2fSDavid Brownell 		regulator_suspend_disk_uV_show, NULL);
529414c70cbSLiam Girdwood 
530414c70cbSLiam Girdwood static ssize_t regulator_suspend_standby_uV_show(struct device *dev,
531414c70cbSLiam Girdwood 				struct device_attribute *attr, char *buf)
532414c70cbSLiam Girdwood {
533a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
534414c70cbSLiam Girdwood 
535414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", rdev->constraints->state_standby.uV);
536414c70cbSLiam Girdwood }
5377ad68e2fSDavid Brownell static DEVICE_ATTR(suspend_standby_microvolts, 0444,
5387ad68e2fSDavid Brownell 		regulator_suspend_standby_uV_show, NULL);
539414c70cbSLiam Girdwood 
540414c70cbSLiam Girdwood static ssize_t regulator_suspend_mem_mode_show(struct device *dev,
541414c70cbSLiam Girdwood 				struct device_attribute *attr, char *buf)
542414c70cbSLiam Girdwood {
543a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
544414c70cbSLiam Girdwood 
5454fca9545SDavid Brownell 	return regulator_print_opmode(buf,
5464fca9545SDavid Brownell 		rdev->constraints->state_mem.mode);
547414c70cbSLiam Girdwood }
5487ad68e2fSDavid Brownell static DEVICE_ATTR(suspend_mem_mode, 0444,
5497ad68e2fSDavid Brownell 		regulator_suspend_mem_mode_show, NULL);
550414c70cbSLiam Girdwood 
551414c70cbSLiam Girdwood static ssize_t regulator_suspend_disk_mode_show(struct device *dev,
552414c70cbSLiam Girdwood 				struct device_attribute *attr, char *buf)
553414c70cbSLiam Girdwood {
554a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
555414c70cbSLiam Girdwood 
5564fca9545SDavid Brownell 	return regulator_print_opmode(buf,
5574fca9545SDavid Brownell 		rdev->constraints->state_disk.mode);
558414c70cbSLiam Girdwood }
5597ad68e2fSDavid Brownell static DEVICE_ATTR(suspend_disk_mode, 0444,
5607ad68e2fSDavid Brownell 		regulator_suspend_disk_mode_show, NULL);
561414c70cbSLiam Girdwood 
562414c70cbSLiam Girdwood static ssize_t regulator_suspend_standby_mode_show(struct device *dev,
563414c70cbSLiam Girdwood 				struct device_attribute *attr, char *buf)
564414c70cbSLiam Girdwood {
565a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
566414c70cbSLiam Girdwood 
5674fca9545SDavid Brownell 	return regulator_print_opmode(buf,
5684fca9545SDavid Brownell 		rdev->constraints->state_standby.mode);
569414c70cbSLiam Girdwood }
5707ad68e2fSDavid Brownell static DEVICE_ATTR(suspend_standby_mode, 0444,
5717ad68e2fSDavid Brownell 		regulator_suspend_standby_mode_show, NULL);
572414c70cbSLiam Girdwood 
573414c70cbSLiam Girdwood static ssize_t regulator_suspend_mem_state_show(struct device *dev,
574414c70cbSLiam Girdwood 				   struct device_attribute *attr, char *buf)
575414c70cbSLiam Girdwood {
576a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
577414c70cbSLiam Girdwood 
5784fca9545SDavid Brownell 	return regulator_print_state(buf,
5794fca9545SDavid Brownell 			rdev->constraints->state_mem.enabled);
580414c70cbSLiam Girdwood }
5817ad68e2fSDavid Brownell static DEVICE_ATTR(suspend_mem_state, 0444,
5827ad68e2fSDavid Brownell 		regulator_suspend_mem_state_show, NULL);
583414c70cbSLiam Girdwood 
584414c70cbSLiam Girdwood static ssize_t regulator_suspend_disk_state_show(struct device *dev,
585414c70cbSLiam Girdwood 				   struct device_attribute *attr, char *buf)
586414c70cbSLiam Girdwood {
587a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
588414c70cbSLiam Girdwood 
5894fca9545SDavid Brownell 	return regulator_print_state(buf,
5904fca9545SDavid Brownell 			rdev->constraints->state_disk.enabled);
591414c70cbSLiam Girdwood }
5927ad68e2fSDavid Brownell static DEVICE_ATTR(suspend_disk_state, 0444,
5937ad68e2fSDavid Brownell 		regulator_suspend_disk_state_show, NULL);
594414c70cbSLiam Girdwood 
595414c70cbSLiam Girdwood static ssize_t regulator_suspend_standby_state_show(struct device *dev,
596414c70cbSLiam Girdwood 				   struct device_attribute *attr, char *buf)
597414c70cbSLiam Girdwood {
598a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
599414c70cbSLiam Girdwood 
6004fca9545SDavid Brownell 	return regulator_print_state(buf,
6014fca9545SDavid Brownell 			rdev->constraints->state_standby.enabled);
602414c70cbSLiam Girdwood }
6037ad68e2fSDavid Brownell static DEVICE_ATTR(suspend_standby_state, 0444,
6047ad68e2fSDavid Brownell 		regulator_suspend_standby_state_show, NULL);
605bc558a60SMark Brown 
6067ad68e2fSDavid Brownell 
6077ad68e2fSDavid Brownell /*
6087ad68e2fSDavid Brownell  * These are the only attributes are present for all regulators.
6097ad68e2fSDavid Brownell  * Other attributes are a function of regulator functionality.
6107ad68e2fSDavid Brownell  */
611414c70cbSLiam Girdwood static struct device_attribute regulator_dev_attrs[] = {
612bc558a60SMark Brown 	__ATTR(name, 0444, regulator_name_show, NULL),
613414c70cbSLiam Girdwood 	__ATTR(num_users, 0444, regulator_num_users_show, NULL),
614414c70cbSLiam Girdwood 	__ATTR(type, 0444, regulator_type_show, NULL),
615414c70cbSLiam Girdwood 	__ATTR_NULL,
616414c70cbSLiam Girdwood };
617414c70cbSLiam Girdwood 
618414c70cbSLiam Girdwood static void regulator_dev_release(struct device *dev)
619414c70cbSLiam Girdwood {
620a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
621414c70cbSLiam Girdwood 	kfree(rdev);
622414c70cbSLiam Girdwood }
623414c70cbSLiam Girdwood 
624414c70cbSLiam Girdwood static struct class regulator_class = {
625414c70cbSLiam Girdwood 	.name = "regulator",
626414c70cbSLiam Girdwood 	.dev_release = regulator_dev_release,
627414c70cbSLiam Girdwood 	.dev_attrs = regulator_dev_attrs,
628414c70cbSLiam Girdwood };
629414c70cbSLiam Girdwood 
630414c70cbSLiam Girdwood /* Calculate the new optimum regulator operating mode based on the new total
631414c70cbSLiam Girdwood  * consumer load. All locks held by caller */
632414c70cbSLiam Girdwood static void drms_uA_update(struct regulator_dev *rdev)
633414c70cbSLiam Girdwood {
634414c70cbSLiam Girdwood 	struct regulator *sibling;
635414c70cbSLiam Girdwood 	int current_uA = 0, output_uV, input_uV, err;
636414c70cbSLiam Girdwood 	unsigned int mode;
637414c70cbSLiam Girdwood 
638414c70cbSLiam Girdwood 	err = regulator_check_drms(rdev);
639414c70cbSLiam Girdwood 	if (err < 0 || !rdev->desc->ops->get_optimum_mode ||
640476c2d83SMark Brown 	    (!rdev->desc->ops->get_voltage &&
641476c2d83SMark Brown 	     !rdev->desc->ops->get_voltage_sel) ||
642476c2d83SMark Brown 	    !rdev->desc->ops->set_mode)
643414c70cbSLiam Girdwood 		return;
644414c70cbSLiam Girdwood 
645414c70cbSLiam Girdwood 	/* get output voltage */
6461bf5a1f8SMark Brown 	output_uV = _regulator_get_voltage(rdev);
647414c70cbSLiam Girdwood 	if (output_uV <= 0)
648414c70cbSLiam Girdwood 		return;
649414c70cbSLiam Girdwood 
650414c70cbSLiam Girdwood 	/* get input voltage */
6511bf5a1f8SMark Brown 	input_uV = 0;
6521bf5a1f8SMark Brown 	if (rdev->supply)
6531bf5a1f8SMark Brown 		input_uV = _regulator_get_voltage(rdev);
6541bf5a1f8SMark Brown 	if (input_uV <= 0)
655414c70cbSLiam Girdwood 		input_uV = rdev->constraints->input_uV;
656414c70cbSLiam Girdwood 	if (input_uV <= 0)
657414c70cbSLiam Girdwood 		return;
658414c70cbSLiam Girdwood 
659414c70cbSLiam Girdwood 	/* calc total requested load */
660414c70cbSLiam Girdwood 	list_for_each_entry(sibling, &rdev->consumer_list, list)
661414c70cbSLiam Girdwood 		current_uA += sibling->uA_load;
662414c70cbSLiam Girdwood 
663414c70cbSLiam Girdwood 	/* now get the optimum mode for our new total regulator load */
664414c70cbSLiam Girdwood 	mode = rdev->desc->ops->get_optimum_mode(rdev, input_uV,
665414c70cbSLiam Girdwood 						  output_uV, current_uA);
666414c70cbSLiam Girdwood 
667414c70cbSLiam Girdwood 	/* check the new mode is allowed */
6682c608234SMark Brown 	err = regulator_mode_constrain(rdev, &mode);
669414c70cbSLiam Girdwood 	if (err == 0)
670414c70cbSLiam Girdwood 		rdev->desc->ops->set_mode(rdev, mode);
671414c70cbSLiam Girdwood }
672414c70cbSLiam Girdwood 
673414c70cbSLiam Girdwood static int suspend_set_state(struct regulator_dev *rdev,
674414c70cbSLiam Girdwood 	struct regulator_state *rstate)
675414c70cbSLiam Girdwood {
676414c70cbSLiam Girdwood 	int ret = 0;
677638f85c5SMark Brown 	bool can_set_state;
678414c70cbSLiam Girdwood 
679638f85c5SMark Brown 	can_set_state = rdev->desc->ops->set_suspend_enable &&
680638f85c5SMark Brown 		rdev->desc->ops->set_suspend_disable;
681638f85c5SMark Brown 
682638f85c5SMark Brown 	/* If we have no suspend mode configration don't set anything;
683638f85c5SMark Brown 	 * only warn if the driver actually makes the suspend mode
684638f85c5SMark Brown 	 * configurable.
685638f85c5SMark Brown 	 */
686638f85c5SMark Brown 	if (!rstate->enabled && !rstate->disabled) {
687638f85c5SMark Brown 		if (can_set_state)
6885da84fd9SJoe Perches 			rdev_warn(rdev, "No configuration\n");
689638f85c5SMark Brown 		return 0;
690638f85c5SMark Brown 	}
691638f85c5SMark Brown 
692638f85c5SMark Brown 	if (rstate->enabled && rstate->disabled) {
6935da84fd9SJoe Perches 		rdev_err(rdev, "invalid configuration\n");
694638f85c5SMark Brown 		return -EINVAL;
695638f85c5SMark Brown 	}
696638f85c5SMark Brown 
697638f85c5SMark Brown 	if (!can_set_state) {
6985da84fd9SJoe Perches 		rdev_err(rdev, "no way to set suspend state\n");
699414c70cbSLiam Girdwood 		return -EINVAL;
700a5766f11SLiam Girdwood 	}
701414c70cbSLiam Girdwood 
702414c70cbSLiam Girdwood 	if (rstate->enabled)
703414c70cbSLiam Girdwood 		ret = rdev->desc->ops->set_suspend_enable(rdev);
704414c70cbSLiam Girdwood 	else
705414c70cbSLiam Girdwood 		ret = rdev->desc->ops->set_suspend_disable(rdev);
706414c70cbSLiam Girdwood 	if (ret < 0) {
7075da84fd9SJoe Perches 		rdev_err(rdev, "failed to enabled/disable\n");
708414c70cbSLiam Girdwood 		return ret;
709414c70cbSLiam Girdwood 	}
710414c70cbSLiam Girdwood 
711414c70cbSLiam Girdwood 	if (rdev->desc->ops->set_suspend_voltage && rstate->uV > 0) {
712414c70cbSLiam Girdwood 		ret = rdev->desc->ops->set_suspend_voltage(rdev, rstate->uV);
713414c70cbSLiam Girdwood 		if (ret < 0) {
7145da84fd9SJoe Perches 			rdev_err(rdev, "failed to set voltage\n");
715414c70cbSLiam Girdwood 			return ret;
716414c70cbSLiam Girdwood 		}
717414c70cbSLiam Girdwood 	}
718414c70cbSLiam Girdwood 
719414c70cbSLiam Girdwood 	if (rdev->desc->ops->set_suspend_mode && rstate->mode > 0) {
720414c70cbSLiam Girdwood 		ret = rdev->desc->ops->set_suspend_mode(rdev, rstate->mode);
721414c70cbSLiam Girdwood 		if (ret < 0) {
7225da84fd9SJoe Perches 			rdev_err(rdev, "failed to set mode\n");
723414c70cbSLiam Girdwood 			return ret;
724414c70cbSLiam Girdwood 		}
725414c70cbSLiam Girdwood 	}
726414c70cbSLiam Girdwood 	return ret;
727414c70cbSLiam Girdwood }
728414c70cbSLiam Girdwood 
729414c70cbSLiam Girdwood /* locks held by caller */
730414c70cbSLiam Girdwood static int suspend_prepare(struct regulator_dev *rdev, suspend_state_t state)
731414c70cbSLiam Girdwood {
732414c70cbSLiam Girdwood 	if (!rdev->constraints)
733414c70cbSLiam Girdwood 		return -EINVAL;
734414c70cbSLiam Girdwood 
735414c70cbSLiam Girdwood 	switch (state) {
736414c70cbSLiam Girdwood 	case PM_SUSPEND_STANDBY:
737414c70cbSLiam Girdwood 		return suspend_set_state(rdev,
738414c70cbSLiam Girdwood 			&rdev->constraints->state_standby);
739414c70cbSLiam Girdwood 	case PM_SUSPEND_MEM:
740414c70cbSLiam Girdwood 		return suspend_set_state(rdev,
741414c70cbSLiam Girdwood 			&rdev->constraints->state_mem);
742414c70cbSLiam Girdwood 	case PM_SUSPEND_MAX:
743414c70cbSLiam Girdwood 		return suspend_set_state(rdev,
744414c70cbSLiam Girdwood 			&rdev->constraints->state_disk);
745414c70cbSLiam Girdwood 	default:
746414c70cbSLiam Girdwood 		return -EINVAL;
747414c70cbSLiam Girdwood 	}
748414c70cbSLiam Girdwood }
749414c70cbSLiam Girdwood 
750414c70cbSLiam Girdwood static void print_constraints(struct regulator_dev *rdev)
751414c70cbSLiam Girdwood {
752414c70cbSLiam Girdwood 	struct regulation_constraints *constraints = rdev->constraints;
753973e9a27SMark Brown 	char buf[80] = "";
7548f031b48SMark Brown 	int count = 0;
7558f031b48SMark Brown 	int ret;
756414c70cbSLiam Girdwood 
7578f031b48SMark Brown 	if (constraints->min_uV && constraints->max_uV) {
758414c70cbSLiam Girdwood 		if (constraints->min_uV == constraints->max_uV)
7598f031b48SMark Brown 			count += sprintf(buf + count, "%d mV ",
760414c70cbSLiam Girdwood 					 constraints->min_uV / 1000);
761414c70cbSLiam Girdwood 		else
7628f031b48SMark Brown 			count += sprintf(buf + count, "%d <--> %d mV ",
763414c70cbSLiam Girdwood 					 constraints->min_uV / 1000,
764414c70cbSLiam Girdwood 					 constraints->max_uV / 1000);
7658f031b48SMark Brown 	}
7668f031b48SMark Brown 
7678f031b48SMark Brown 	if (!constraints->min_uV ||
7688f031b48SMark Brown 	    constraints->min_uV != constraints->max_uV) {
7698f031b48SMark Brown 		ret = _regulator_get_voltage(rdev);
7708f031b48SMark Brown 		if (ret > 0)
7718f031b48SMark Brown 			count += sprintf(buf + count, "at %d mV ", ret / 1000);
7728f031b48SMark Brown 	}
7738f031b48SMark Brown 
774bf5892a8SMark Brown 	if (constraints->uV_offset)
775bf5892a8SMark Brown 		count += sprintf(buf, "%dmV offset ",
776bf5892a8SMark Brown 				 constraints->uV_offset / 1000);
777bf5892a8SMark Brown 
7788f031b48SMark Brown 	if (constraints->min_uA && constraints->max_uA) {
779414c70cbSLiam Girdwood 		if (constraints->min_uA == constraints->max_uA)
7808f031b48SMark Brown 			count += sprintf(buf + count, "%d mA ",
781414c70cbSLiam Girdwood 					 constraints->min_uA / 1000);
782414c70cbSLiam Girdwood 		else
7838f031b48SMark Brown 			count += sprintf(buf + count, "%d <--> %d mA ",
784414c70cbSLiam Girdwood 					 constraints->min_uA / 1000,
785414c70cbSLiam Girdwood 					 constraints->max_uA / 1000);
786414c70cbSLiam Girdwood 	}
7878f031b48SMark Brown 
7888f031b48SMark Brown 	if (!constraints->min_uA ||
7898f031b48SMark Brown 	    constraints->min_uA != constraints->max_uA) {
7908f031b48SMark Brown 		ret = _regulator_get_current_limit(rdev);
7918f031b48SMark Brown 		if (ret > 0)
792e4a6376bSCyril Chemparathy 			count += sprintf(buf + count, "at %d mA ", ret / 1000);
7938f031b48SMark Brown 	}
7948f031b48SMark Brown 
795414c70cbSLiam Girdwood 	if (constraints->valid_modes_mask & REGULATOR_MODE_FAST)
796414c70cbSLiam Girdwood 		count += sprintf(buf + count, "fast ");
797414c70cbSLiam Girdwood 	if (constraints->valid_modes_mask & REGULATOR_MODE_NORMAL)
798414c70cbSLiam Girdwood 		count += sprintf(buf + count, "normal ");
799414c70cbSLiam Girdwood 	if (constraints->valid_modes_mask & REGULATOR_MODE_IDLE)
800414c70cbSLiam Girdwood 		count += sprintf(buf + count, "idle ");
801414c70cbSLiam Girdwood 	if (constraints->valid_modes_mask & REGULATOR_MODE_STANDBY)
802414c70cbSLiam Girdwood 		count += sprintf(buf + count, "standby");
803414c70cbSLiam Girdwood 
80413ce29f8SMark Brown 	rdev_info(rdev, "%s\n", buf);
8054a682922SMark Brown 
8064a682922SMark Brown 	if ((constraints->min_uV != constraints->max_uV) &&
8074a682922SMark Brown 	    !(constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE))
8084a682922SMark Brown 		rdev_warn(rdev,
8094a682922SMark Brown 			  "Voltage range but no REGULATOR_CHANGE_VOLTAGE\n");
810414c70cbSLiam Girdwood }
811414c70cbSLiam Girdwood 
812e79055d6SMark Brown static int machine_constraints_voltage(struct regulator_dev *rdev,
8131083c393SMark Brown 	struct regulation_constraints *constraints)
814e79055d6SMark Brown {
815e79055d6SMark Brown 	struct regulator_ops *ops = rdev->desc->ops;
816af5866c9SMark Brown 	int ret;
817af5866c9SMark Brown 
818af5866c9SMark Brown 	/* do we need to apply the constraint voltage */
819af5866c9SMark Brown 	if (rdev->constraints->apply_uV &&
82075790251SMark Brown 	    rdev->constraints->min_uV == rdev->constraints->max_uV) {
82175790251SMark Brown 		ret = _regulator_do_set_voltage(rdev,
8223a93f2a9SMark Brown 						rdev->constraints->min_uV,
82375790251SMark Brown 						rdev->constraints->max_uV);
824af5866c9SMark Brown 		if (ret < 0) {
8255da84fd9SJoe Perches 			rdev_err(rdev, "failed to apply %duV constraint\n",
8265da84fd9SJoe Perches 				 rdev->constraints->min_uV);
827af5866c9SMark Brown 			return ret;
828af5866c9SMark Brown 		}
829af5866c9SMark Brown 	}
830e79055d6SMark Brown 
831e79055d6SMark Brown 	/* constrain machine-level voltage specs to fit
832e79055d6SMark Brown 	 * the actual range supported by this regulator.
833e79055d6SMark Brown 	 */
834e79055d6SMark Brown 	if (ops->list_voltage && rdev->desc->n_voltages) {
835e79055d6SMark Brown 		int	count = rdev->desc->n_voltages;
836e79055d6SMark Brown 		int	i;
837e79055d6SMark Brown 		int	min_uV = INT_MAX;
838e79055d6SMark Brown 		int	max_uV = INT_MIN;
839e79055d6SMark Brown 		int	cmin = constraints->min_uV;
840e79055d6SMark Brown 		int	cmax = constraints->max_uV;
841e79055d6SMark Brown 
842e79055d6SMark Brown 		/* it's safe to autoconfigure fixed-voltage supplies
843e79055d6SMark Brown 		   and the constraints are used by list_voltage. */
844e79055d6SMark Brown 		if (count == 1 && !cmin) {
845e79055d6SMark Brown 			cmin = 1;
846e79055d6SMark Brown 			cmax = INT_MAX;
847e79055d6SMark Brown 			constraints->min_uV = cmin;
848e79055d6SMark Brown 			constraints->max_uV = cmax;
849e79055d6SMark Brown 		}
850e79055d6SMark Brown 
851e79055d6SMark Brown 		/* voltage constraints are optional */
852e79055d6SMark Brown 		if ((cmin == 0) && (cmax == 0))
853e79055d6SMark Brown 			return 0;
854e79055d6SMark Brown 
855e79055d6SMark Brown 		/* else require explicit machine-level constraints */
856e79055d6SMark Brown 		if (cmin <= 0 || cmax <= 0 || cmax < cmin) {
8575da84fd9SJoe Perches 			rdev_err(rdev, "invalid voltage constraints\n");
858e79055d6SMark Brown 			return -EINVAL;
859e79055d6SMark Brown 		}
860e79055d6SMark Brown 
861e79055d6SMark Brown 		/* initial: [cmin..cmax] valid, [min_uV..max_uV] not */
862e79055d6SMark Brown 		for (i = 0; i < count; i++) {
863e79055d6SMark Brown 			int	value;
864e79055d6SMark Brown 
865e79055d6SMark Brown 			value = ops->list_voltage(rdev, i);
866e79055d6SMark Brown 			if (value <= 0)
867e79055d6SMark Brown 				continue;
868e79055d6SMark Brown 
869e79055d6SMark Brown 			/* maybe adjust [min_uV..max_uV] */
870e79055d6SMark Brown 			if (value >= cmin && value < min_uV)
871e79055d6SMark Brown 				min_uV = value;
872e79055d6SMark Brown 			if (value <= cmax && value > max_uV)
873e79055d6SMark Brown 				max_uV = value;
874e79055d6SMark Brown 		}
875e79055d6SMark Brown 
876e79055d6SMark Brown 		/* final: [min_uV..max_uV] valid iff constraints valid */
877e79055d6SMark Brown 		if (max_uV < min_uV) {
8785da84fd9SJoe Perches 			rdev_err(rdev, "unsupportable voltage constraints\n");
879e79055d6SMark Brown 			return -EINVAL;
880e79055d6SMark Brown 		}
881e79055d6SMark Brown 
882e79055d6SMark Brown 		/* use regulator's subset of machine constraints */
883e79055d6SMark Brown 		if (constraints->min_uV < min_uV) {
8845da84fd9SJoe Perches 			rdev_dbg(rdev, "override min_uV, %d -> %d\n",
8855da84fd9SJoe Perches 				 constraints->min_uV, min_uV);
886e79055d6SMark Brown 			constraints->min_uV = min_uV;
887e79055d6SMark Brown 		}
888e79055d6SMark Brown 		if (constraints->max_uV > max_uV) {
8895da84fd9SJoe Perches 			rdev_dbg(rdev, "override max_uV, %d -> %d\n",
8905da84fd9SJoe Perches 				 constraints->max_uV, max_uV);
891e79055d6SMark Brown 			constraints->max_uV = max_uV;
892e79055d6SMark Brown 		}
893e79055d6SMark Brown 	}
894e79055d6SMark Brown 
895e79055d6SMark Brown 	return 0;
896e79055d6SMark Brown }
897e79055d6SMark Brown 
898a5766f11SLiam Girdwood /**
899a5766f11SLiam Girdwood  * set_machine_constraints - sets regulator constraints
90069279fb9SMark Brown  * @rdev: regulator source
901c8e7e464SMark Brown  * @constraints: constraints to apply
902a5766f11SLiam Girdwood  *
903a5766f11SLiam Girdwood  * Allows platform initialisation code to define and constrain
904a5766f11SLiam Girdwood  * regulator circuits e.g. valid voltage/current ranges, etc.  NOTE:
905a5766f11SLiam Girdwood  * Constraints *must* be set by platform code in order for some
906a5766f11SLiam Girdwood  * regulator operations to proceed i.e. set_voltage, set_current_limit,
907a5766f11SLiam Girdwood  * set_mode.
908a5766f11SLiam Girdwood  */
909a5766f11SLiam Girdwood static int set_machine_constraints(struct regulator_dev *rdev,
910f8c12fe3SMark Brown 	const struct regulation_constraints *constraints)
911a5766f11SLiam Girdwood {
912a5766f11SLiam Girdwood 	int ret = 0;
913e5fda26cSMark Brown 	struct regulator_ops *ops = rdev->desc->ops;
914e06f5b4fSMark Brown 
9159a8f5e07SMark Brown 	if (constraints)
916f8c12fe3SMark Brown 		rdev->constraints = kmemdup(constraints, sizeof(*constraints),
917f8c12fe3SMark Brown 					    GFP_KERNEL);
9189a8f5e07SMark Brown 	else
9199a8f5e07SMark Brown 		rdev->constraints = kzalloc(sizeof(*constraints),
9209a8f5e07SMark Brown 					    GFP_KERNEL);
921f8c12fe3SMark Brown 	if (!rdev->constraints)
922f8c12fe3SMark Brown 		return -ENOMEM;
923af5866c9SMark Brown 
924f8c12fe3SMark Brown 	ret = machine_constraints_voltage(rdev, rdev->constraints);
925e79055d6SMark Brown 	if (ret != 0)
9263e2b9abdSMark Brown 		goto out;
9273e2b9abdSMark Brown 
928a5766f11SLiam Girdwood 	/* do we need to setup our suspend state */
9299a8f5e07SMark Brown 	if (rdev->constraints->initial_state) {
930f8c12fe3SMark Brown 		ret = suspend_prepare(rdev, rdev->constraints->initial_state);
931e06f5b4fSMark Brown 		if (ret < 0) {
9325da84fd9SJoe Perches 			rdev_err(rdev, "failed to set suspend state\n");
933e06f5b4fSMark Brown 			goto out;
934e06f5b4fSMark Brown 		}
935e06f5b4fSMark Brown 	}
936a5766f11SLiam Girdwood 
9379a8f5e07SMark Brown 	if (rdev->constraints->initial_mode) {
938a308466cSMark Brown 		if (!ops->set_mode) {
9395da84fd9SJoe Perches 			rdev_err(rdev, "no set_mode operation\n");
940a308466cSMark Brown 			ret = -EINVAL;
941a308466cSMark Brown 			goto out;
942a308466cSMark Brown 		}
943a308466cSMark Brown 
944f8c12fe3SMark Brown 		ret = ops->set_mode(rdev, rdev->constraints->initial_mode);
945a308466cSMark Brown 		if (ret < 0) {
9465da84fd9SJoe Perches 			rdev_err(rdev, "failed to set initial mode: %d\n", ret);
947a308466cSMark Brown 			goto out;
948a308466cSMark Brown 		}
949a308466cSMark Brown 	}
950a308466cSMark Brown 
951cacf90f2SMark Brown 	/* If the constraints say the regulator should be on at this point
952cacf90f2SMark Brown 	 * and we have control then make sure it is enabled.
953cacf90f2SMark Brown 	 */
954f8c12fe3SMark Brown 	if ((rdev->constraints->always_on || rdev->constraints->boot_on) &&
955f8c12fe3SMark Brown 	    ops->enable) {
956e5fda26cSMark Brown 		ret = ops->enable(rdev);
957e5fda26cSMark Brown 		if (ret < 0) {
9585da84fd9SJoe Perches 			rdev_err(rdev, "failed to enable\n");
959e5fda26cSMark Brown 			goto out;
960e5fda26cSMark Brown 		}
961e5fda26cSMark Brown 	}
962e5fda26cSMark Brown 
963a5766f11SLiam Girdwood 	print_constraints(rdev);
9641a6958e7SAxel Lin 	return 0;
965a5766f11SLiam Girdwood out:
9661a6958e7SAxel Lin 	kfree(rdev->constraints);
9671a6958e7SAxel Lin 	rdev->constraints = NULL;
968a5766f11SLiam Girdwood 	return ret;
969a5766f11SLiam Girdwood }
970a5766f11SLiam Girdwood 
971a5766f11SLiam Girdwood /**
972a5766f11SLiam Girdwood  * set_supply - set regulator supply regulator
97369279fb9SMark Brown  * @rdev: regulator name
97469279fb9SMark Brown  * @supply_rdev: supply regulator name
975a5766f11SLiam Girdwood  *
976a5766f11SLiam Girdwood  * Called by platform initialisation code to set the supply regulator for this
977a5766f11SLiam Girdwood  * regulator. This ensures that a regulators supply will also be enabled by the
978a5766f11SLiam Girdwood  * core if it's child is enabled.
979a5766f11SLiam Girdwood  */
980a5766f11SLiam Girdwood static int set_supply(struct regulator_dev *rdev,
981a5766f11SLiam Girdwood 		      struct regulator_dev *supply_rdev)
982a5766f11SLiam Girdwood {
983a5766f11SLiam Girdwood 	int err;
984a5766f11SLiam Girdwood 
9853801b86aSMark Brown 	rdev_info(rdev, "supplied by %s\n", rdev_get_name(supply_rdev));
9863801b86aSMark Brown 
9873801b86aSMark Brown 	rdev->supply = create_regulator(supply_rdev, &rdev->dev, "SUPPLY");
98832c78de8SAxel Lin 	if (rdev->supply == NULL) {
98932c78de8SAxel Lin 		err = -ENOMEM;
990a5766f11SLiam Girdwood 		return err;
991a5766f11SLiam Girdwood 	}
992a5766f11SLiam Girdwood 
9933801b86aSMark Brown 	return 0;
9943801b86aSMark Brown }
9953801b86aSMark Brown 
996a5766f11SLiam Girdwood /**
99706c63f93SRandy Dunlap  * set_consumer_device_supply - Bind a regulator to a symbolic supply
99869279fb9SMark Brown  * @rdev:         regulator source
99940f9244fSMark Brown  * @consumer_dev_name: dev_name() string for device supply applies to
1000a5766f11SLiam Girdwood  * @supply:       symbolic name for supply
1001a5766f11SLiam Girdwood  *
1002a5766f11SLiam Girdwood  * Allows platform initialisation code to map physical regulator
1003a5766f11SLiam Girdwood  * sources to symbolic names for supplies for use by devices.  Devices
1004a5766f11SLiam Girdwood  * should use these symbolic names to request regulators, avoiding the
1005a5766f11SLiam Girdwood  * need to provide board-specific regulator names as platform data.
1006a5766f11SLiam Girdwood  */
1007a5766f11SLiam Girdwood static int set_consumer_device_supply(struct regulator_dev *rdev,
1008737f360dSMark Brown 				      const char *consumer_dev_name,
100940f9244fSMark Brown 				      const char *supply)
1010a5766f11SLiam Girdwood {
1011a5766f11SLiam Girdwood 	struct regulator_map *node;
10129ed2099eSMark Brown 	int has_dev;
1013a5766f11SLiam Girdwood 
1014a5766f11SLiam Girdwood 	if (supply == NULL)
1015a5766f11SLiam Girdwood 		return -EINVAL;
1016a5766f11SLiam Girdwood 
10179ed2099eSMark Brown 	if (consumer_dev_name != NULL)
10189ed2099eSMark Brown 		has_dev = 1;
10199ed2099eSMark Brown 	else
10209ed2099eSMark Brown 		has_dev = 0;
10219ed2099eSMark Brown 
10226001e13cSDavid Brownell 	list_for_each_entry(node, &regulator_map_list, list) {
102323b5cc2aSJani Nikula 		if (node->dev_name && consumer_dev_name) {
102423b5cc2aSJani Nikula 			if (strcmp(node->dev_name, consumer_dev_name) != 0)
10256001e13cSDavid Brownell 				continue;
102623b5cc2aSJani Nikula 		} else if (node->dev_name || consumer_dev_name) {
102723b5cc2aSJani Nikula 			continue;
102823b5cc2aSJani Nikula 		}
102923b5cc2aSJani Nikula 
10306001e13cSDavid Brownell 		if (strcmp(node->supply, supply) != 0)
10316001e13cSDavid Brownell 			continue;
10326001e13cSDavid Brownell 
1033737f360dSMark Brown 		pr_debug("%s: %s/%s is '%s' supply; fail %s/%s\n",
1034737f360dSMark Brown 			 consumer_dev_name,
10356001e13cSDavid Brownell 			 dev_name(&node->regulator->dev),
10366001e13cSDavid Brownell 			 node->regulator->desc->name,
10376001e13cSDavid Brownell 			 supply,
10381083c393SMark Brown 			 dev_name(&rdev->dev), rdev_get_name(rdev));
10396001e13cSDavid Brownell 		return -EBUSY;
10406001e13cSDavid Brownell 	}
10416001e13cSDavid Brownell 
10429ed2099eSMark Brown 	node = kzalloc(sizeof(struct regulator_map), GFP_KERNEL);
1043a5766f11SLiam Girdwood 	if (node == NULL)
1044a5766f11SLiam Girdwood 		return -ENOMEM;
1045a5766f11SLiam Girdwood 
1046a5766f11SLiam Girdwood 	node->regulator = rdev;
1047a5766f11SLiam Girdwood 	node->supply = supply;
1048a5766f11SLiam Girdwood 
10499ed2099eSMark Brown 	if (has_dev) {
10509ed2099eSMark Brown 		node->dev_name = kstrdup(consumer_dev_name, GFP_KERNEL);
105140f9244fSMark Brown 		if (node->dev_name == NULL) {
105240f9244fSMark Brown 			kfree(node);
105340f9244fSMark Brown 			return -ENOMEM;
105440f9244fSMark Brown 		}
10559ed2099eSMark Brown 	}
105640f9244fSMark Brown 
1057a5766f11SLiam Girdwood 	list_add(&node->list, &regulator_map_list);
1058a5766f11SLiam Girdwood 	return 0;
1059a5766f11SLiam Girdwood }
1060a5766f11SLiam Girdwood 
10610f1d747bSMike Rapoport static void unset_regulator_supplies(struct regulator_dev *rdev)
10620f1d747bSMike Rapoport {
10630f1d747bSMike Rapoport 	struct regulator_map *node, *n;
10640f1d747bSMike Rapoport 
10650f1d747bSMike Rapoport 	list_for_each_entry_safe(node, n, &regulator_map_list, list) {
10660f1d747bSMike Rapoport 		if (rdev == node->regulator) {
10670f1d747bSMike Rapoport 			list_del(&node->list);
106840f9244fSMark Brown 			kfree(node->dev_name);
10690f1d747bSMike Rapoport 			kfree(node);
10700f1d747bSMike Rapoport 		}
10710f1d747bSMike Rapoport 	}
10720f1d747bSMike Rapoport }
10730f1d747bSMike Rapoport 
1074f5726ae3SMark Brown #define REG_STR_SIZE	64
1075414c70cbSLiam Girdwood 
1076414c70cbSLiam Girdwood static struct regulator *create_regulator(struct regulator_dev *rdev,
1077414c70cbSLiam Girdwood 					  struct device *dev,
1078414c70cbSLiam Girdwood 					  const char *supply_name)
1079414c70cbSLiam Girdwood {
1080414c70cbSLiam Girdwood 	struct regulator *regulator;
1081414c70cbSLiam Girdwood 	char buf[REG_STR_SIZE];
1082414c70cbSLiam Girdwood 	int err, size;
1083414c70cbSLiam Girdwood 
1084414c70cbSLiam Girdwood 	regulator = kzalloc(sizeof(*regulator), GFP_KERNEL);
1085414c70cbSLiam Girdwood 	if (regulator == NULL)
1086414c70cbSLiam Girdwood 		return NULL;
1087414c70cbSLiam Girdwood 
1088414c70cbSLiam Girdwood 	mutex_lock(&rdev->mutex);
1089414c70cbSLiam Girdwood 	regulator->rdev = rdev;
1090414c70cbSLiam Girdwood 	list_add(&regulator->list, &rdev->consumer_list);
1091414c70cbSLiam Girdwood 
1092414c70cbSLiam Girdwood 	if (dev) {
1093414c70cbSLiam Girdwood 		/* create a 'requested_microamps_name' sysfs entry */
1094e0eaedefSMark Brown 		size = scnprintf(buf, REG_STR_SIZE,
1095e0eaedefSMark Brown 				 "microamps_requested_%s-%s",
1096e0eaedefSMark Brown 				 dev_name(dev), supply_name);
1097414c70cbSLiam Girdwood 		if (size >= REG_STR_SIZE)
1098414c70cbSLiam Girdwood 			goto overflow_err;
1099414c70cbSLiam Girdwood 
1100414c70cbSLiam Girdwood 		regulator->dev = dev;
11014f26a2abSAmeya Palande 		sysfs_attr_init(&regulator->dev_attr.attr);
1102414c70cbSLiam Girdwood 		regulator->dev_attr.attr.name = kstrdup(buf, GFP_KERNEL);
1103414c70cbSLiam Girdwood 		if (regulator->dev_attr.attr.name == NULL)
1104414c70cbSLiam Girdwood 			goto attr_name_err;
1105414c70cbSLiam Girdwood 
1106414c70cbSLiam Girdwood 		regulator->dev_attr.attr.mode = 0444;
1107414c70cbSLiam Girdwood 		regulator->dev_attr.show = device_requested_uA_show;
1108414c70cbSLiam Girdwood 		err = device_create_file(dev, &regulator->dev_attr);
1109414c70cbSLiam Girdwood 		if (err < 0) {
11105da84fd9SJoe Perches 			rdev_warn(rdev, "could not add regulator_dev requested microamps sysfs entry\n");
1111414c70cbSLiam Girdwood 			goto attr_name_err;
1112414c70cbSLiam Girdwood 		}
1113414c70cbSLiam Girdwood 
1114414c70cbSLiam Girdwood 		/* also add a link to the device sysfs entry */
1115414c70cbSLiam Girdwood 		size = scnprintf(buf, REG_STR_SIZE, "%s-%s",
1116414c70cbSLiam Girdwood 				 dev->kobj.name, supply_name);
1117414c70cbSLiam Girdwood 		if (size >= REG_STR_SIZE)
1118414c70cbSLiam Girdwood 			goto attr_err;
1119414c70cbSLiam Girdwood 
1120414c70cbSLiam Girdwood 		regulator->supply_name = kstrdup(buf, GFP_KERNEL);
1121414c70cbSLiam Girdwood 		if (regulator->supply_name == NULL)
1122414c70cbSLiam Girdwood 			goto attr_err;
1123414c70cbSLiam Girdwood 
1124414c70cbSLiam Girdwood 		err = sysfs_create_link(&rdev->dev.kobj, &dev->kobj,
1125414c70cbSLiam Girdwood 					buf);
1126414c70cbSLiam Girdwood 		if (err) {
11275da84fd9SJoe Perches 			rdev_warn(rdev, "could not add device link %s err %d\n",
11281d7372e1SDaniel Walker 				  dev->kobj.name, err);
1129414c70cbSLiam Girdwood 			goto link_name_err;
1130414c70cbSLiam Girdwood 		}
11315de70519SMark Brown 	} else {
11325de70519SMark Brown 		regulator->supply_name = kstrdup(supply_name, GFP_KERNEL);
11335de70519SMark Brown 		if (regulator->supply_name == NULL)
11345de70519SMark Brown 			goto attr_err;
1135414c70cbSLiam Girdwood 	}
11365de70519SMark Brown 
11375de70519SMark Brown 	regulator->debugfs = debugfs_create_dir(regulator->supply_name,
11385de70519SMark Brown 						rdev->debugfs);
113924751434SStephen Boyd 	if (!regulator->debugfs) {
11405de70519SMark Brown 		rdev_warn(rdev, "Failed to create debugfs directory\n");
11415de70519SMark Brown 	} else {
11425de70519SMark Brown 		debugfs_create_u32("uA_load", 0444, regulator->debugfs,
11435de70519SMark Brown 				   &regulator->uA_load);
11445de70519SMark Brown 		debugfs_create_u32("min_uV", 0444, regulator->debugfs,
11455de70519SMark Brown 				   &regulator->min_uV);
11465de70519SMark Brown 		debugfs_create_u32("max_uV", 0444, regulator->debugfs,
11475de70519SMark Brown 				   &regulator->max_uV);
11485de70519SMark Brown 	}
11495de70519SMark Brown 
1150414c70cbSLiam Girdwood 	mutex_unlock(&rdev->mutex);
1151414c70cbSLiam Girdwood 	return regulator;
1152414c70cbSLiam Girdwood link_name_err:
1153414c70cbSLiam Girdwood 	kfree(regulator->supply_name);
1154414c70cbSLiam Girdwood attr_err:
1155414c70cbSLiam Girdwood 	device_remove_file(regulator->dev, &regulator->dev_attr);
1156414c70cbSLiam Girdwood attr_name_err:
1157414c70cbSLiam Girdwood 	kfree(regulator->dev_attr.attr.name);
1158414c70cbSLiam Girdwood overflow_err:
1159414c70cbSLiam Girdwood 	list_del(&regulator->list);
1160414c70cbSLiam Girdwood 	kfree(regulator);
1161414c70cbSLiam Girdwood 	mutex_unlock(&rdev->mutex);
1162414c70cbSLiam Girdwood 	return NULL;
1163414c70cbSLiam Girdwood }
1164414c70cbSLiam Girdwood 
116531aae2beSMark Brown static int _regulator_get_enable_time(struct regulator_dev *rdev)
116631aae2beSMark Brown {
116731aae2beSMark Brown 	if (!rdev->desc->ops->enable_time)
116831aae2beSMark Brown 		return 0;
116931aae2beSMark Brown 	return rdev->desc->ops->enable_time(rdev);
117031aae2beSMark Brown }
117131aae2beSMark Brown 
117269511a45SRajendra Nayak static struct regulator_dev *regulator_dev_lookup(struct device *dev,
117369511a45SRajendra Nayak 							 const char *supply)
117469511a45SRajendra Nayak {
117569511a45SRajendra Nayak 	struct regulator_dev *r;
117669511a45SRajendra Nayak 	struct device_node *node;
117769511a45SRajendra Nayak 
117869511a45SRajendra Nayak 	/* first do a dt based lookup */
117969511a45SRajendra Nayak 	if (dev && dev->of_node) {
118069511a45SRajendra Nayak 		node = of_get_regulator(dev, supply);
118169511a45SRajendra Nayak 		if (node)
118269511a45SRajendra Nayak 			list_for_each_entry(r, &regulator_list, list)
118369511a45SRajendra Nayak 				if (r->dev.parent &&
118469511a45SRajendra Nayak 					node == r->dev.of_node)
118569511a45SRajendra Nayak 					return r;
118669511a45SRajendra Nayak 	}
118769511a45SRajendra Nayak 
118869511a45SRajendra Nayak 	/* if not found, try doing it non-dt way */
118969511a45SRajendra Nayak 	list_for_each_entry(r, &regulator_list, list)
119069511a45SRajendra Nayak 		if (strcmp(rdev_get_name(r), supply) == 0)
119169511a45SRajendra Nayak 			return r;
119269511a45SRajendra Nayak 
119369511a45SRajendra Nayak 	return NULL;
119469511a45SRajendra Nayak }
119569511a45SRajendra Nayak 
11965ffbd136SMark Brown /* Internal regulator request function */
11975ffbd136SMark Brown static struct regulator *_regulator_get(struct device *dev, const char *id,
11985ffbd136SMark Brown 					int exclusive)
1199414c70cbSLiam Girdwood {
1200414c70cbSLiam Girdwood 	struct regulator_dev *rdev;
1201414c70cbSLiam Girdwood 	struct regulator_map *map;
120204bf3011SMark Brown 	struct regulator *regulator = ERR_PTR(-EPROBE_DEFER);
120340f9244fSMark Brown 	const char *devname = NULL;
12045ffbd136SMark Brown 	int ret;
1205414c70cbSLiam Girdwood 
1206414c70cbSLiam Girdwood 	if (id == NULL) {
12075da84fd9SJoe Perches 		pr_err("get() with no identifier\n");
1208414c70cbSLiam Girdwood 		return regulator;
1209414c70cbSLiam Girdwood 	}
1210414c70cbSLiam Girdwood 
121140f9244fSMark Brown 	if (dev)
121240f9244fSMark Brown 		devname = dev_name(dev);
121340f9244fSMark Brown 
1214414c70cbSLiam Girdwood 	mutex_lock(&regulator_list_mutex);
1215414c70cbSLiam Girdwood 
121669511a45SRajendra Nayak 	rdev = regulator_dev_lookup(dev, id);
121769511a45SRajendra Nayak 	if (rdev)
121869511a45SRajendra Nayak 		goto found;
121969511a45SRajendra Nayak 
1220414c70cbSLiam Girdwood 	list_for_each_entry(map, &regulator_map_list, list) {
122140f9244fSMark Brown 		/* If the mapping has a device set up it must match */
122240f9244fSMark Brown 		if (map->dev_name &&
122340f9244fSMark Brown 		    (!devname || strcmp(map->dev_name, devname)))
122440f9244fSMark Brown 			continue;
122540f9244fSMark Brown 
122640f9244fSMark Brown 		if (strcmp(map->supply, id) == 0) {
1227a5766f11SLiam Girdwood 			rdev = map->regulator;
1228414c70cbSLiam Girdwood 			goto found;
1229414c70cbSLiam Girdwood 		}
1230a5766f11SLiam Girdwood 	}
123134abbd68SMark Brown 
1232688fe99aSMark Brown 	if (board_wants_dummy_regulator) {
1233688fe99aSMark Brown 		rdev = dummy_regulator_rdev;
1234688fe99aSMark Brown 		goto found;
1235688fe99aSMark Brown 	}
1236688fe99aSMark Brown 
123734abbd68SMark Brown #ifdef CONFIG_REGULATOR_DUMMY
123834abbd68SMark Brown 	if (!devname)
123934abbd68SMark Brown 		devname = "deviceless";
124034abbd68SMark Brown 
124134abbd68SMark Brown 	/* If the board didn't flag that it was fully constrained then
124234abbd68SMark Brown 	 * substitute in a dummy regulator so consumers can continue.
124334abbd68SMark Brown 	 */
124434abbd68SMark Brown 	if (!has_full_constraints) {
12455da84fd9SJoe Perches 		pr_warn("%s supply %s not found, using dummy regulator\n",
124634abbd68SMark Brown 			devname, id);
124734abbd68SMark Brown 		rdev = dummy_regulator_rdev;
124834abbd68SMark Brown 		goto found;
124934abbd68SMark Brown 	}
125034abbd68SMark Brown #endif
125134abbd68SMark Brown 
1252414c70cbSLiam Girdwood 	mutex_unlock(&regulator_list_mutex);
1253414c70cbSLiam Girdwood 	return regulator;
1254414c70cbSLiam Girdwood 
1255414c70cbSLiam Girdwood found:
12565ffbd136SMark Brown 	if (rdev->exclusive) {
12575ffbd136SMark Brown 		regulator = ERR_PTR(-EPERM);
12585ffbd136SMark Brown 		goto out;
12595ffbd136SMark Brown 	}
12605ffbd136SMark Brown 
12615ffbd136SMark Brown 	if (exclusive && rdev->open_count) {
12625ffbd136SMark Brown 		regulator = ERR_PTR(-EBUSY);
12635ffbd136SMark Brown 		goto out;
12645ffbd136SMark Brown 	}
12655ffbd136SMark Brown 
1266a5766f11SLiam Girdwood 	if (!try_module_get(rdev->owner))
1267a5766f11SLiam Girdwood 		goto out;
1268a5766f11SLiam Girdwood 
1269414c70cbSLiam Girdwood 	regulator = create_regulator(rdev, dev, id);
1270414c70cbSLiam Girdwood 	if (regulator == NULL) {
1271414c70cbSLiam Girdwood 		regulator = ERR_PTR(-ENOMEM);
1272414c70cbSLiam Girdwood 		module_put(rdev->owner);
1273bcda4321SAxel Lin 		goto out;
1274414c70cbSLiam Girdwood 	}
1275414c70cbSLiam Girdwood 
12765ffbd136SMark Brown 	rdev->open_count++;
12775ffbd136SMark Brown 	if (exclusive) {
12785ffbd136SMark Brown 		rdev->exclusive = 1;
12795ffbd136SMark Brown 
12805ffbd136SMark Brown 		ret = _regulator_is_enabled(rdev);
12815ffbd136SMark Brown 		if (ret > 0)
12825ffbd136SMark Brown 			rdev->use_count = 1;
12835ffbd136SMark Brown 		else
12845ffbd136SMark Brown 			rdev->use_count = 0;
12855ffbd136SMark Brown 	}
12865ffbd136SMark Brown 
1287a5766f11SLiam Girdwood out:
1288414c70cbSLiam Girdwood 	mutex_unlock(&regulator_list_mutex);
12895ffbd136SMark Brown 
1290414c70cbSLiam Girdwood 	return regulator;
1291414c70cbSLiam Girdwood }
12925ffbd136SMark Brown 
12935ffbd136SMark Brown /**
12945ffbd136SMark Brown  * regulator_get - lookup and obtain a reference to a regulator.
12955ffbd136SMark Brown  * @dev: device for regulator "consumer"
12965ffbd136SMark Brown  * @id: Supply name or regulator ID.
12975ffbd136SMark Brown  *
12985ffbd136SMark Brown  * Returns a struct regulator corresponding to the regulator producer,
12995ffbd136SMark Brown  * or IS_ERR() condition containing errno.
13005ffbd136SMark Brown  *
13015ffbd136SMark Brown  * Use of supply names configured via regulator_set_device_supply() is
13025ffbd136SMark Brown  * strongly encouraged.  It is recommended that the supply name used
13035ffbd136SMark Brown  * should match the name used for the supply and/or the relevant
13045ffbd136SMark Brown  * device pins in the datasheet.
13055ffbd136SMark Brown  */
13065ffbd136SMark Brown struct regulator *regulator_get(struct device *dev, const char *id)
13075ffbd136SMark Brown {
13085ffbd136SMark Brown 	return _regulator_get(dev, id, 0);
13095ffbd136SMark Brown }
1310414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_get);
1311414c70cbSLiam Girdwood 
1312070b9079SStephen Boyd static void devm_regulator_release(struct device *dev, void *res)
1313070b9079SStephen Boyd {
1314070b9079SStephen Boyd 	regulator_put(*(struct regulator **)res);
1315070b9079SStephen Boyd }
1316070b9079SStephen Boyd 
1317070b9079SStephen Boyd /**
1318070b9079SStephen Boyd  * devm_regulator_get - Resource managed regulator_get()
1319070b9079SStephen Boyd  * @dev: device for regulator "consumer"
1320070b9079SStephen Boyd  * @id: Supply name or regulator ID.
1321070b9079SStephen Boyd  *
1322070b9079SStephen Boyd  * Managed regulator_get(). Regulators returned from this function are
1323070b9079SStephen Boyd  * automatically regulator_put() on driver detach. See regulator_get() for more
1324070b9079SStephen Boyd  * information.
1325070b9079SStephen Boyd  */
1326070b9079SStephen Boyd struct regulator *devm_regulator_get(struct device *dev, const char *id)
1327070b9079SStephen Boyd {
1328070b9079SStephen Boyd 	struct regulator **ptr, *regulator;
1329070b9079SStephen Boyd 
1330070b9079SStephen Boyd 	ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL);
1331070b9079SStephen Boyd 	if (!ptr)
1332070b9079SStephen Boyd 		return ERR_PTR(-ENOMEM);
1333070b9079SStephen Boyd 
1334070b9079SStephen Boyd 	regulator = regulator_get(dev, id);
1335070b9079SStephen Boyd 	if (!IS_ERR(regulator)) {
1336070b9079SStephen Boyd 		*ptr = regulator;
1337070b9079SStephen Boyd 		devres_add(dev, ptr);
1338070b9079SStephen Boyd 	} else {
1339070b9079SStephen Boyd 		devres_free(ptr);
1340070b9079SStephen Boyd 	}
1341070b9079SStephen Boyd 
1342070b9079SStephen Boyd 	return regulator;
1343070b9079SStephen Boyd }
1344070b9079SStephen Boyd EXPORT_SYMBOL_GPL(devm_regulator_get);
1345070b9079SStephen Boyd 
1346414c70cbSLiam Girdwood /**
13475ffbd136SMark Brown  * regulator_get_exclusive - obtain exclusive access to a regulator.
13485ffbd136SMark Brown  * @dev: device for regulator "consumer"
13495ffbd136SMark Brown  * @id: Supply name or regulator ID.
13505ffbd136SMark Brown  *
13515ffbd136SMark Brown  * Returns a struct regulator corresponding to the regulator producer,
13525ffbd136SMark Brown  * or IS_ERR() condition containing errno.  Other consumers will be
13535ffbd136SMark Brown  * unable to obtain this reference is held and the use count for the
13545ffbd136SMark Brown  * regulator will be initialised to reflect the current state of the
13555ffbd136SMark Brown  * regulator.
13565ffbd136SMark Brown  *
13575ffbd136SMark Brown  * This is intended for use by consumers which cannot tolerate shared
13585ffbd136SMark Brown  * use of the regulator such as those which need to force the
13595ffbd136SMark Brown  * regulator off for correct operation of the hardware they are
13605ffbd136SMark Brown  * controlling.
13615ffbd136SMark Brown  *
13625ffbd136SMark Brown  * Use of supply names configured via regulator_set_device_supply() is
13635ffbd136SMark Brown  * strongly encouraged.  It is recommended that the supply name used
13645ffbd136SMark Brown  * should match the name used for the supply and/or the relevant
13655ffbd136SMark Brown  * device pins in the datasheet.
13665ffbd136SMark Brown  */
13675ffbd136SMark Brown struct regulator *regulator_get_exclusive(struct device *dev, const char *id)
13685ffbd136SMark Brown {
13695ffbd136SMark Brown 	return _regulator_get(dev, id, 1);
13705ffbd136SMark Brown }
13715ffbd136SMark Brown EXPORT_SYMBOL_GPL(regulator_get_exclusive);
13725ffbd136SMark Brown 
13735ffbd136SMark Brown /**
1374414c70cbSLiam Girdwood  * regulator_put - "free" the regulator source
1375414c70cbSLiam Girdwood  * @regulator: regulator source
1376414c70cbSLiam Girdwood  *
1377414c70cbSLiam Girdwood  * Note: drivers must ensure that all regulator_enable calls made on this
1378414c70cbSLiam Girdwood  * regulator source are balanced by regulator_disable calls prior to calling
1379414c70cbSLiam Girdwood  * this function.
1380414c70cbSLiam Girdwood  */
1381414c70cbSLiam Girdwood void regulator_put(struct regulator *regulator)
1382414c70cbSLiam Girdwood {
1383414c70cbSLiam Girdwood 	struct regulator_dev *rdev;
1384414c70cbSLiam Girdwood 
1385414c70cbSLiam Girdwood 	if (regulator == NULL || IS_ERR(regulator))
1386414c70cbSLiam Girdwood 		return;
1387414c70cbSLiam Girdwood 
1388414c70cbSLiam Girdwood 	mutex_lock(&regulator_list_mutex);
1389414c70cbSLiam Girdwood 	rdev = regulator->rdev;
1390414c70cbSLiam Girdwood 
13915de70519SMark Brown 	debugfs_remove_recursive(regulator->debugfs);
13925de70519SMark Brown 
1393414c70cbSLiam Girdwood 	/* remove any sysfs entries */
1394414c70cbSLiam Girdwood 	if (regulator->dev) {
1395414c70cbSLiam Girdwood 		sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name);
1396414c70cbSLiam Girdwood 		device_remove_file(regulator->dev, &regulator->dev_attr);
1397414c70cbSLiam Girdwood 		kfree(regulator->dev_attr.attr.name);
1398414c70cbSLiam Girdwood 	}
13995de70519SMark Brown 	kfree(regulator->supply_name);
1400414c70cbSLiam Girdwood 	list_del(&regulator->list);
1401414c70cbSLiam Girdwood 	kfree(regulator);
1402414c70cbSLiam Girdwood 
14035ffbd136SMark Brown 	rdev->open_count--;
14045ffbd136SMark Brown 	rdev->exclusive = 0;
14055ffbd136SMark Brown 
1406414c70cbSLiam Girdwood 	module_put(rdev->owner);
1407414c70cbSLiam Girdwood 	mutex_unlock(&regulator_list_mutex);
1408414c70cbSLiam Girdwood }
1409414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_put);
1410414c70cbSLiam Girdwood 
1411d5ad34f7SMark Brown static int devm_regulator_match(struct device *dev, void *res, void *data)
1412d5ad34f7SMark Brown {
1413d5ad34f7SMark Brown 	struct regulator **r = res;
1414d5ad34f7SMark Brown 	if (!r || !*r) {
1415d5ad34f7SMark Brown 		WARN_ON(!r || !*r);
1416d5ad34f7SMark Brown 		return 0;
1417d5ad34f7SMark Brown 	}
1418d5ad34f7SMark Brown 	return *r == data;
1419d5ad34f7SMark Brown }
1420d5ad34f7SMark Brown 
1421d5ad34f7SMark Brown /**
1422d5ad34f7SMark Brown  * devm_regulator_put - Resource managed regulator_put()
1423d5ad34f7SMark Brown  * @regulator: regulator to free
1424d5ad34f7SMark Brown  *
1425d5ad34f7SMark Brown  * Deallocate a regulator allocated with devm_regulator_get(). Normally
1426d5ad34f7SMark Brown  * this function will not need to be called and the resource management
1427d5ad34f7SMark Brown  * code will ensure that the resource is freed.
1428d5ad34f7SMark Brown  */
1429d5ad34f7SMark Brown void devm_regulator_put(struct regulator *regulator)
1430d5ad34f7SMark Brown {
1431d5ad34f7SMark Brown 	int rc;
1432d5ad34f7SMark Brown 
1433d5ad34f7SMark Brown 	rc = devres_destroy(regulator->dev, devm_regulator_release,
1434d5ad34f7SMark Brown 			    devm_regulator_match, regulator);
1435d5ad34f7SMark Brown 	WARN_ON(rc);
1436d5ad34f7SMark Brown }
1437d5ad34f7SMark Brown EXPORT_SYMBOL_GPL(devm_regulator_put);
1438d5ad34f7SMark Brown 
14399a2372faSMark Brown static int _regulator_can_change_status(struct regulator_dev *rdev)
14409a2372faSMark Brown {
14419a2372faSMark Brown 	if (!rdev->constraints)
14429a2372faSMark Brown 		return 0;
14439a2372faSMark Brown 
14449a2372faSMark Brown 	if (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_STATUS)
14459a2372faSMark Brown 		return 1;
14469a2372faSMark Brown 	else
14479a2372faSMark Brown 		return 0;
14489a2372faSMark Brown }
14499a2372faSMark Brown 
1450414c70cbSLiam Girdwood /* locks held by regulator_enable() */
1451414c70cbSLiam Girdwood static int _regulator_enable(struct regulator_dev *rdev)
1452414c70cbSLiam Girdwood {
145331aae2beSMark Brown 	int ret, delay;
1454414c70cbSLiam Girdwood 
1455414c70cbSLiam Girdwood 	/* check voltage and requested load before enabling */
1456414c70cbSLiam Girdwood 	if (rdev->constraints &&
14579a2372faSMark Brown 	    (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS))
1458414c70cbSLiam Girdwood 		drms_uA_update(rdev);
1459414c70cbSLiam Girdwood 
14609a2372faSMark Brown 	if (rdev->use_count == 0) {
14619a2372faSMark Brown 		/* The regulator may on if it's not switchable or left on */
14629a2372faSMark Brown 		ret = _regulator_is_enabled(rdev);
14639a2372faSMark Brown 		if (ret == -EINVAL || ret == 0) {
14649a2372faSMark Brown 			if (!_regulator_can_change_status(rdev))
14659a2372faSMark Brown 				return -EPERM;
14669a2372faSMark Brown 
146731aae2beSMark Brown 			if (!rdev->desc->ops->enable)
146831aae2beSMark Brown 				return -EINVAL;
146931aae2beSMark Brown 
147031aae2beSMark Brown 			/* Query before enabling in case configuration
147125985edcSLucas De Marchi 			 * dependent.  */
147231aae2beSMark Brown 			ret = _regulator_get_enable_time(rdev);
147331aae2beSMark Brown 			if (ret >= 0) {
147431aae2beSMark Brown 				delay = ret;
147531aae2beSMark Brown 			} else {
14765da84fd9SJoe Perches 				rdev_warn(rdev, "enable_time() failed: %d\n",
147731aae2beSMark Brown 					   ret);
147831aae2beSMark Brown 				delay = 0;
147931aae2beSMark Brown 			}
148031aae2beSMark Brown 
148102fa3ec0SMark Brown 			trace_regulator_enable(rdev_get_name(rdev));
148202fa3ec0SMark Brown 
148331aae2beSMark Brown 			/* Allow the regulator to ramp; it would be useful
148431aae2beSMark Brown 			 * to extend this for bulk operations so that the
148531aae2beSMark Brown 			 * regulators can ramp together.  */
1486414c70cbSLiam Girdwood 			ret = rdev->desc->ops->enable(rdev);
14879a2372faSMark Brown 			if (ret < 0)
14889a2372faSMark Brown 				return ret;
148931aae2beSMark Brown 
149002fa3ec0SMark Brown 			trace_regulator_enable_delay(rdev_get_name(rdev));
149102fa3ec0SMark Brown 
1492e36c1df8SAxel Lin 			if (delay >= 1000) {
149331aae2beSMark Brown 				mdelay(delay / 1000);
1494e36c1df8SAxel Lin 				udelay(delay % 1000);
1495e36c1df8SAxel Lin 			} else if (delay) {
149631aae2beSMark Brown 				udelay(delay);
1497e36c1df8SAxel Lin 			}
149831aae2beSMark Brown 
149902fa3ec0SMark Brown 			trace_regulator_enable_complete(rdev_get_name(rdev));
150002fa3ec0SMark Brown 
1501a7433cffSLinus Walleij 		} else if (ret < 0) {
15025da84fd9SJoe Perches 			rdev_err(rdev, "is_enabled() failed: %d\n", ret);
1503414c70cbSLiam Girdwood 			return ret;
1504414c70cbSLiam Girdwood 		}
1505a7433cffSLinus Walleij 		/* Fallthrough on positive return values - already enabled */
1506414c70cbSLiam Girdwood 	}
1507414c70cbSLiam Girdwood 
15089a2372faSMark Brown 	rdev->use_count++;
15099a2372faSMark Brown 
15109a2372faSMark Brown 	return 0;
1511414c70cbSLiam Girdwood }
1512414c70cbSLiam Girdwood 
1513414c70cbSLiam Girdwood /**
1514414c70cbSLiam Girdwood  * regulator_enable - enable regulator output
1515414c70cbSLiam Girdwood  * @regulator: regulator source
1516414c70cbSLiam Girdwood  *
1517cf7bbcdfSMark Brown  * Request that the regulator be enabled with the regulator output at
1518cf7bbcdfSMark Brown  * the predefined voltage or current value.  Calls to regulator_enable()
1519cf7bbcdfSMark Brown  * must be balanced with calls to regulator_disable().
1520cf7bbcdfSMark Brown  *
1521414c70cbSLiam Girdwood  * NOTE: the output value can be set by other drivers, boot loader or may be
1522cf7bbcdfSMark Brown  * hardwired in the regulator.
1523414c70cbSLiam Girdwood  */
1524414c70cbSLiam Girdwood int regulator_enable(struct regulator *regulator)
1525414c70cbSLiam Girdwood {
1526412aec61SDavid Brownell 	struct regulator_dev *rdev = regulator->rdev;
1527412aec61SDavid Brownell 	int ret = 0;
1528414c70cbSLiam Girdwood 
15293801b86aSMark Brown 	if (rdev->supply) {
15303801b86aSMark Brown 		ret = regulator_enable(rdev->supply);
15313801b86aSMark Brown 		if (ret != 0)
15323801b86aSMark Brown 			return ret;
15333801b86aSMark Brown 	}
15343801b86aSMark Brown 
1535412aec61SDavid Brownell 	mutex_lock(&rdev->mutex);
1536412aec61SDavid Brownell 	ret = _regulator_enable(rdev);
1537412aec61SDavid Brownell 	mutex_unlock(&rdev->mutex);
15383801b86aSMark Brown 
1539d1685e4eSHeiko Stübner 	if (ret != 0 && rdev->supply)
15403801b86aSMark Brown 		regulator_disable(rdev->supply);
15413801b86aSMark Brown 
1542414c70cbSLiam Girdwood 	return ret;
1543414c70cbSLiam Girdwood }
1544414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_enable);
1545414c70cbSLiam Girdwood 
1546414c70cbSLiam Girdwood /* locks held by regulator_disable() */
15473801b86aSMark Brown static int _regulator_disable(struct regulator_dev *rdev)
1548414c70cbSLiam Girdwood {
1549414c70cbSLiam Girdwood 	int ret = 0;
1550414c70cbSLiam Girdwood 
1551cd94b505SDavid Brownell 	if (WARN(rdev->use_count <= 0,
155243e7ee33SJoe Perches 		 "unbalanced disables for %s\n", rdev_get_name(rdev)))
1553cd94b505SDavid Brownell 		return -EIO;
1554cd94b505SDavid Brownell 
1555414c70cbSLiam Girdwood 	/* are we the last user and permitted to disable ? */
155660ef66fcSMark Brown 	if (rdev->use_count == 1 &&
155760ef66fcSMark Brown 	    (rdev->constraints && !rdev->constraints->always_on)) {
1558414c70cbSLiam Girdwood 
1559414c70cbSLiam Girdwood 		/* we are last user */
15609a2372faSMark Brown 		if (_regulator_can_change_status(rdev) &&
15619a2372faSMark Brown 		    rdev->desc->ops->disable) {
156202fa3ec0SMark Brown 			trace_regulator_disable(rdev_get_name(rdev));
156302fa3ec0SMark Brown 
1564414c70cbSLiam Girdwood 			ret = rdev->desc->ops->disable(rdev);
1565414c70cbSLiam Girdwood 			if (ret < 0) {
15665da84fd9SJoe Perches 				rdev_err(rdev, "failed to disable\n");
1567414c70cbSLiam Girdwood 				return ret;
1568414c70cbSLiam Girdwood 			}
156984b68263SMark Brown 
157002fa3ec0SMark Brown 			trace_regulator_disable_complete(rdev_get_name(rdev));
157102fa3ec0SMark Brown 
157284b68263SMark Brown 			_notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE,
157384b68263SMark Brown 					     NULL);
1574414c70cbSLiam Girdwood 		}
1575414c70cbSLiam Girdwood 
1576414c70cbSLiam Girdwood 		rdev->use_count = 0;
1577414c70cbSLiam Girdwood 	} else if (rdev->use_count > 1) {
1578414c70cbSLiam Girdwood 
1579414c70cbSLiam Girdwood 		if (rdev->constraints &&
1580414c70cbSLiam Girdwood 			(rdev->constraints->valid_ops_mask &
1581414c70cbSLiam Girdwood 			REGULATOR_CHANGE_DRMS))
1582414c70cbSLiam Girdwood 			drms_uA_update(rdev);
1583414c70cbSLiam Girdwood 
1584414c70cbSLiam Girdwood 		rdev->use_count--;
1585414c70cbSLiam Girdwood 	}
15863801b86aSMark Brown 
1587414c70cbSLiam Girdwood 	return ret;
1588414c70cbSLiam Girdwood }
1589414c70cbSLiam Girdwood 
1590414c70cbSLiam Girdwood /**
1591414c70cbSLiam Girdwood  * regulator_disable - disable regulator output
1592414c70cbSLiam Girdwood  * @regulator: regulator source
1593414c70cbSLiam Girdwood  *
1594cf7bbcdfSMark Brown  * Disable the regulator output voltage or current.  Calls to
1595cf7bbcdfSMark Brown  * regulator_enable() must be balanced with calls to
1596cf7bbcdfSMark Brown  * regulator_disable().
159769279fb9SMark Brown  *
1598414c70cbSLiam Girdwood  * NOTE: this will only disable the regulator output if no other consumer
1599cf7bbcdfSMark Brown  * devices have it enabled, the regulator device supports disabling and
1600cf7bbcdfSMark Brown  * machine constraints permit this operation.
1601414c70cbSLiam Girdwood  */
1602414c70cbSLiam Girdwood int regulator_disable(struct regulator *regulator)
1603414c70cbSLiam Girdwood {
1604412aec61SDavid Brownell 	struct regulator_dev *rdev = regulator->rdev;
1605412aec61SDavid Brownell 	int ret = 0;
1606414c70cbSLiam Girdwood 
1607412aec61SDavid Brownell 	mutex_lock(&rdev->mutex);
16083801b86aSMark Brown 	ret = _regulator_disable(rdev);
1609412aec61SDavid Brownell 	mutex_unlock(&rdev->mutex);
16108cbf811dSJeffrey Carlyle 
16113801b86aSMark Brown 	if (ret == 0 && rdev->supply)
16123801b86aSMark Brown 		regulator_disable(rdev->supply);
16138cbf811dSJeffrey Carlyle 
1614414c70cbSLiam Girdwood 	return ret;
1615414c70cbSLiam Girdwood }
1616414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_disable);
1617414c70cbSLiam Girdwood 
1618414c70cbSLiam Girdwood /* locks held by regulator_force_disable() */
16193801b86aSMark Brown static int _regulator_force_disable(struct regulator_dev *rdev)
1620414c70cbSLiam Girdwood {
1621414c70cbSLiam Girdwood 	int ret = 0;
1622414c70cbSLiam Girdwood 
1623414c70cbSLiam Girdwood 	/* force disable */
1624414c70cbSLiam Girdwood 	if (rdev->desc->ops->disable) {
1625414c70cbSLiam Girdwood 		/* ah well, who wants to live forever... */
1626414c70cbSLiam Girdwood 		ret = rdev->desc->ops->disable(rdev);
1627414c70cbSLiam Girdwood 		if (ret < 0) {
16285da84fd9SJoe Perches 			rdev_err(rdev, "failed to force disable\n");
1629414c70cbSLiam Girdwood 			return ret;
1630414c70cbSLiam Girdwood 		}
1631414c70cbSLiam Girdwood 		/* notify other consumers that power has been forced off */
163284b68263SMark Brown 		_notifier_call_chain(rdev, REGULATOR_EVENT_FORCE_DISABLE |
163384b68263SMark Brown 			REGULATOR_EVENT_DISABLE, NULL);
1634414c70cbSLiam Girdwood 	}
1635414c70cbSLiam Girdwood 
1636414c70cbSLiam Girdwood 	return ret;
1637414c70cbSLiam Girdwood }
1638414c70cbSLiam Girdwood 
1639414c70cbSLiam Girdwood /**
1640414c70cbSLiam Girdwood  * regulator_force_disable - force disable regulator output
1641414c70cbSLiam Girdwood  * @regulator: regulator source
1642414c70cbSLiam Girdwood  *
1643414c70cbSLiam Girdwood  * Forcibly disable the regulator output voltage or current.
1644414c70cbSLiam Girdwood  * NOTE: this *will* disable the regulator output even if other consumer
1645414c70cbSLiam Girdwood  * devices have it enabled. This should be used for situations when device
1646414c70cbSLiam Girdwood  * damage will likely occur if the regulator is not disabled (e.g. over temp).
1647414c70cbSLiam Girdwood  */
1648414c70cbSLiam Girdwood int regulator_force_disable(struct regulator *regulator)
1649414c70cbSLiam Girdwood {
165082d15839SMark Brown 	struct regulator_dev *rdev = regulator->rdev;
1651414c70cbSLiam Girdwood 	int ret;
1652414c70cbSLiam Girdwood 
165382d15839SMark Brown 	mutex_lock(&rdev->mutex);
1654414c70cbSLiam Girdwood 	regulator->uA_load = 0;
16553801b86aSMark Brown 	ret = _regulator_force_disable(regulator->rdev);
165682d15839SMark Brown 	mutex_unlock(&rdev->mutex);
16578cbf811dSJeffrey Carlyle 
16583801b86aSMark Brown 	if (rdev->supply)
16593801b86aSMark Brown 		while (rdev->open_count--)
16603801b86aSMark Brown 			regulator_disable(rdev->supply);
16618cbf811dSJeffrey Carlyle 
1662414c70cbSLiam Girdwood 	return ret;
1663414c70cbSLiam Girdwood }
1664414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_force_disable);
1665414c70cbSLiam Girdwood 
1666da07ecd9SMark Brown static void regulator_disable_work(struct work_struct *work)
1667da07ecd9SMark Brown {
1668da07ecd9SMark Brown 	struct regulator_dev *rdev = container_of(work, struct regulator_dev,
1669da07ecd9SMark Brown 						  disable_work.work);
1670da07ecd9SMark Brown 	int count, i, ret;
1671da07ecd9SMark Brown 
1672da07ecd9SMark Brown 	mutex_lock(&rdev->mutex);
1673da07ecd9SMark Brown 
1674da07ecd9SMark Brown 	BUG_ON(!rdev->deferred_disables);
1675da07ecd9SMark Brown 
1676da07ecd9SMark Brown 	count = rdev->deferred_disables;
1677da07ecd9SMark Brown 	rdev->deferred_disables = 0;
1678da07ecd9SMark Brown 
1679da07ecd9SMark Brown 	for (i = 0; i < count; i++) {
1680da07ecd9SMark Brown 		ret = _regulator_disable(rdev);
1681da07ecd9SMark Brown 		if (ret != 0)
1682da07ecd9SMark Brown 			rdev_err(rdev, "Deferred disable failed: %d\n", ret);
1683da07ecd9SMark Brown 	}
1684da07ecd9SMark Brown 
1685da07ecd9SMark Brown 	mutex_unlock(&rdev->mutex);
1686da07ecd9SMark Brown 
1687da07ecd9SMark Brown 	if (rdev->supply) {
1688da07ecd9SMark Brown 		for (i = 0; i < count; i++) {
1689da07ecd9SMark Brown 			ret = regulator_disable(rdev->supply);
1690da07ecd9SMark Brown 			if (ret != 0) {
1691da07ecd9SMark Brown 				rdev_err(rdev,
1692da07ecd9SMark Brown 					 "Supply disable failed: %d\n", ret);
1693da07ecd9SMark Brown 			}
1694da07ecd9SMark Brown 		}
1695da07ecd9SMark Brown 	}
1696da07ecd9SMark Brown }
1697da07ecd9SMark Brown 
1698da07ecd9SMark Brown /**
1699da07ecd9SMark Brown  * regulator_disable_deferred - disable regulator output with delay
1700da07ecd9SMark Brown  * @regulator: regulator source
1701da07ecd9SMark Brown  * @ms: miliseconds until the regulator is disabled
1702da07ecd9SMark Brown  *
1703da07ecd9SMark Brown  * Execute regulator_disable() on the regulator after a delay.  This
1704da07ecd9SMark Brown  * is intended for use with devices that require some time to quiesce.
1705da07ecd9SMark Brown  *
1706da07ecd9SMark Brown  * NOTE: this will only disable the regulator output if no other consumer
1707da07ecd9SMark Brown  * devices have it enabled, the regulator device supports disabling and
1708da07ecd9SMark Brown  * machine constraints permit this operation.
1709da07ecd9SMark Brown  */
1710da07ecd9SMark Brown int regulator_disable_deferred(struct regulator *regulator, int ms)
1711da07ecd9SMark Brown {
1712da07ecd9SMark Brown 	struct regulator_dev *rdev = regulator->rdev;
1713aa59802dSMark Brown 	int ret;
1714da07ecd9SMark Brown 
1715da07ecd9SMark Brown 	mutex_lock(&rdev->mutex);
1716da07ecd9SMark Brown 	rdev->deferred_disables++;
1717da07ecd9SMark Brown 	mutex_unlock(&rdev->mutex);
1718da07ecd9SMark Brown 
1719aa59802dSMark Brown 	ret = schedule_delayed_work(&rdev->disable_work,
1720da07ecd9SMark Brown 				    msecs_to_jiffies(ms));
1721aa59802dSMark Brown 	if (ret < 0)
1722aa59802dSMark Brown 		return ret;
1723aa59802dSMark Brown 	else
1724aa59802dSMark Brown 		return 0;
1725da07ecd9SMark Brown }
1726da07ecd9SMark Brown EXPORT_SYMBOL_GPL(regulator_disable_deferred);
1727da07ecd9SMark Brown 
1728cd6dffb4SMark Brown /**
1729cd6dffb4SMark Brown  * regulator_is_enabled_regmap - standard is_enabled() for regmap users
1730cd6dffb4SMark Brown  *
1731cd6dffb4SMark Brown  * @rdev: regulator to operate on
1732cd6dffb4SMark Brown  *
1733cd6dffb4SMark Brown  * Regulators that use regmap for their register I/O can set the
1734cd6dffb4SMark Brown  * enable_reg and enable_mask fields in their descriptor and then use
1735cd6dffb4SMark Brown  * this as their is_enabled operation, saving some code.
1736cd6dffb4SMark Brown  */
1737cd6dffb4SMark Brown int regulator_is_enabled_regmap(struct regulator_dev *rdev)
1738cd6dffb4SMark Brown {
1739cd6dffb4SMark Brown 	unsigned int val;
1740cd6dffb4SMark Brown 	int ret;
1741cd6dffb4SMark Brown 
1742cd6dffb4SMark Brown 	ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val);
1743cd6dffb4SMark Brown 	if (ret != 0)
1744cd6dffb4SMark Brown 		return ret;
1745cd6dffb4SMark Brown 
1746cd6dffb4SMark Brown 	return (val & rdev->desc->enable_mask) != 0;
1747cd6dffb4SMark Brown }
1748cd6dffb4SMark Brown EXPORT_SYMBOL_GPL(regulator_is_enabled_regmap);
1749cd6dffb4SMark Brown 
1750cd6dffb4SMark Brown /**
1751cd6dffb4SMark Brown  * regulator_enable_regmap - standard enable() for regmap users
1752cd6dffb4SMark Brown  *
1753cd6dffb4SMark Brown  * @rdev: regulator to operate on
1754cd6dffb4SMark Brown  *
1755cd6dffb4SMark Brown  * Regulators that use regmap for their register I/O can set the
1756cd6dffb4SMark Brown  * enable_reg and enable_mask fields in their descriptor and then use
1757cd6dffb4SMark Brown  * this as their enable() operation, saving some code.
1758cd6dffb4SMark Brown  */
1759cd6dffb4SMark Brown int regulator_enable_regmap(struct regulator_dev *rdev)
1760cd6dffb4SMark Brown {
1761cd6dffb4SMark Brown 	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
1762cd6dffb4SMark Brown 				  rdev->desc->enable_mask,
1763cd6dffb4SMark Brown 				  rdev->desc->enable_mask);
1764cd6dffb4SMark Brown }
1765cd6dffb4SMark Brown EXPORT_SYMBOL_GPL(regulator_enable_regmap);
1766cd6dffb4SMark Brown 
1767cd6dffb4SMark Brown /**
1768cd6dffb4SMark Brown  * regulator_disable_regmap - standard disable() for regmap users
1769cd6dffb4SMark Brown  *
1770cd6dffb4SMark Brown  * @rdev: regulator to operate on
1771cd6dffb4SMark Brown  *
1772cd6dffb4SMark Brown  * Regulators that use regmap for their register I/O can set the
1773cd6dffb4SMark Brown  * enable_reg and enable_mask fields in their descriptor and then use
1774cd6dffb4SMark Brown  * this as their disable() operation, saving some code.
1775cd6dffb4SMark Brown  */
1776cd6dffb4SMark Brown int regulator_disable_regmap(struct regulator_dev *rdev)
1777cd6dffb4SMark Brown {
1778cd6dffb4SMark Brown 	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
1779cd6dffb4SMark Brown 				  rdev->desc->enable_mask, 0);
1780cd6dffb4SMark Brown }
1781cd6dffb4SMark Brown EXPORT_SYMBOL_GPL(regulator_disable_regmap);
1782cd6dffb4SMark Brown 
1783414c70cbSLiam Girdwood static int _regulator_is_enabled(struct regulator_dev *rdev)
1784414c70cbSLiam Girdwood {
17859a7f6a4cSMark Brown 	/* If we don't know then assume that the regulator is always on */
17869332546fSMark Brown 	if (!rdev->desc->ops->is_enabled)
17879a7f6a4cSMark Brown 		return 1;
1788414c70cbSLiam Girdwood 
17899332546fSMark Brown 	return rdev->desc->ops->is_enabled(rdev);
1790414c70cbSLiam Girdwood }
1791414c70cbSLiam Girdwood 
1792414c70cbSLiam Girdwood /**
1793414c70cbSLiam Girdwood  * regulator_is_enabled - is the regulator output enabled
1794414c70cbSLiam Girdwood  * @regulator: regulator source
1795414c70cbSLiam Girdwood  *
1796412aec61SDavid Brownell  * Returns positive if the regulator driver backing the source/client
1797412aec61SDavid Brownell  * has requested that the device be enabled, zero if it hasn't, else a
1798412aec61SDavid Brownell  * negative errno code.
1799412aec61SDavid Brownell  *
1800412aec61SDavid Brownell  * Note that the device backing this regulator handle can have multiple
1801412aec61SDavid Brownell  * users, so it might be enabled even if regulator_enable() was never
1802412aec61SDavid Brownell  * called for this particular source.
1803414c70cbSLiam Girdwood  */
1804414c70cbSLiam Girdwood int regulator_is_enabled(struct regulator *regulator)
1805414c70cbSLiam Girdwood {
18069332546fSMark Brown 	int ret;
18079332546fSMark Brown 
18089332546fSMark Brown 	mutex_lock(&regulator->rdev->mutex);
18099332546fSMark Brown 	ret = _regulator_is_enabled(regulator->rdev);
18109332546fSMark Brown 	mutex_unlock(&regulator->rdev->mutex);
18119332546fSMark Brown 
18129332546fSMark Brown 	return ret;
1813414c70cbSLiam Girdwood }
1814414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_is_enabled);
1815414c70cbSLiam Girdwood 
1816414c70cbSLiam Girdwood /**
18174367cfdcSDavid Brownell  * regulator_count_voltages - count regulator_list_voltage() selectors
18184367cfdcSDavid Brownell  * @regulator: regulator source
18194367cfdcSDavid Brownell  *
18204367cfdcSDavid Brownell  * Returns number of selectors, or negative errno.  Selectors are
18214367cfdcSDavid Brownell  * numbered starting at zero, and typically correspond to bitfields
18224367cfdcSDavid Brownell  * in hardware registers.
18234367cfdcSDavid Brownell  */
18244367cfdcSDavid Brownell int regulator_count_voltages(struct regulator *regulator)
18254367cfdcSDavid Brownell {
18264367cfdcSDavid Brownell 	struct regulator_dev	*rdev = regulator->rdev;
18274367cfdcSDavid Brownell 
18284367cfdcSDavid Brownell 	return rdev->desc->n_voltages ? : -EINVAL;
18294367cfdcSDavid Brownell }
18304367cfdcSDavid Brownell EXPORT_SYMBOL_GPL(regulator_count_voltages);
18314367cfdcSDavid Brownell 
18324367cfdcSDavid Brownell /**
18334367cfdcSDavid Brownell  * regulator_list_voltage - enumerate supported voltages
18344367cfdcSDavid Brownell  * @regulator: regulator source
18354367cfdcSDavid Brownell  * @selector: identify voltage to list
18364367cfdcSDavid Brownell  * Context: can sleep
18374367cfdcSDavid Brownell  *
18384367cfdcSDavid Brownell  * Returns a voltage that can be passed to @regulator_set_voltage(),
183988393161SThomas Weber  * zero if this selector code can't be used on this system, or a
18404367cfdcSDavid Brownell  * negative errno.
18414367cfdcSDavid Brownell  */
18424367cfdcSDavid Brownell int regulator_list_voltage(struct regulator *regulator, unsigned selector)
18434367cfdcSDavid Brownell {
18444367cfdcSDavid Brownell 	struct regulator_dev	*rdev = regulator->rdev;
18454367cfdcSDavid Brownell 	struct regulator_ops	*ops = rdev->desc->ops;
18464367cfdcSDavid Brownell 	int			ret;
18474367cfdcSDavid Brownell 
18484367cfdcSDavid Brownell 	if (!ops->list_voltage || selector >= rdev->desc->n_voltages)
18494367cfdcSDavid Brownell 		return -EINVAL;
18504367cfdcSDavid Brownell 
18514367cfdcSDavid Brownell 	mutex_lock(&rdev->mutex);
18524367cfdcSDavid Brownell 	ret = ops->list_voltage(rdev, selector);
18534367cfdcSDavid Brownell 	mutex_unlock(&rdev->mutex);
18544367cfdcSDavid Brownell 
18554367cfdcSDavid Brownell 	if (ret > 0) {
18564367cfdcSDavid Brownell 		if (ret < rdev->constraints->min_uV)
18574367cfdcSDavid Brownell 			ret = 0;
18584367cfdcSDavid Brownell 		else if (ret > rdev->constraints->max_uV)
18594367cfdcSDavid Brownell 			ret = 0;
18604367cfdcSDavid Brownell 	}
18614367cfdcSDavid Brownell 
18624367cfdcSDavid Brownell 	return ret;
18634367cfdcSDavid Brownell }
18644367cfdcSDavid Brownell EXPORT_SYMBOL_GPL(regulator_list_voltage);
18654367cfdcSDavid Brownell 
18664367cfdcSDavid Brownell /**
1867a7a1ad90SMark Brown  * regulator_is_supported_voltage - check if a voltage range can be supported
1868a7a1ad90SMark Brown  *
1869a7a1ad90SMark Brown  * @regulator: Regulator to check.
1870a7a1ad90SMark Brown  * @min_uV: Minimum required voltage in uV.
1871a7a1ad90SMark Brown  * @max_uV: Maximum required voltage in uV.
1872a7a1ad90SMark Brown  *
1873a7a1ad90SMark Brown  * Returns a boolean or a negative error code.
1874a7a1ad90SMark Brown  */
1875a7a1ad90SMark Brown int regulator_is_supported_voltage(struct regulator *regulator,
1876a7a1ad90SMark Brown 				   int min_uV, int max_uV)
1877a7a1ad90SMark Brown {
1878a7a1ad90SMark Brown 	int i, voltages, ret;
1879a7a1ad90SMark Brown 
1880a7a1ad90SMark Brown 	ret = regulator_count_voltages(regulator);
1881a7a1ad90SMark Brown 	if (ret < 0)
1882a7a1ad90SMark Brown 		return ret;
1883a7a1ad90SMark Brown 	voltages = ret;
1884a7a1ad90SMark Brown 
1885a7a1ad90SMark Brown 	for (i = 0; i < voltages; i++) {
1886a7a1ad90SMark Brown 		ret = regulator_list_voltage(regulator, i);
1887a7a1ad90SMark Brown 
1888a7a1ad90SMark Brown 		if (ret >= min_uV && ret <= max_uV)
1889a7a1ad90SMark Brown 			return 1;
1890a7a1ad90SMark Brown 	}
1891a7a1ad90SMark Brown 
1892a7a1ad90SMark Brown 	return 0;
1893a7a1ad90SMark Brown }
1894a398eaa2SMark Brown EXPORT_SYMBOL_GPL(regulator_is_supported_voltage);
1895a7a1ad90SMark Brown 
18964ab5b3d9SMark Brown /**
18974ab5b3d9SMark Brown  * regulator_get_voltage_sel_regmap - standard get_voltage_sel for regmap users
18984ab5b3d9SMark Brown  *
18994ab5b3d9SMark Brown  * @rdev: regulator to operate on
19004ab5b3d9SMark Brown  *
19014ab5b3d9SMark Brown  * Regulators that use regmap for their register I/O can set the
19024ab5b3d9SMark Brown  * vsel_reg and vsel_mask fields in their descriptor and then use this
19034ab5b3d9SMark Brown  * as their get_voltage_vsel operation, saving some code.
19044ab5b3d9SMark Brown  */
19054ab5b3d9SMark Brown int regulator_get_voltage_sel_regmap(struct regulator_dev *rdev)
19064ab5b3d9SMark Brown {
19074ab5b3d9SMark Brown 	unsigned int val;
19084ab5b3d9SMark Brown 	int ret;
19094ab5b3d9SMark Brown 
19104ab5b3d9SMark Brown 	ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val);
19114ab5b3d9SMark Brown 	if (ret != 0)
19124ab5b3d9SMark Brown 		return ret;
19134ab5b3d9SMark Brown 
19144ab5b3d9SMark Brown 	val &= rdev->desc->vsel_mask;
19154ab5b3d9SMark Brown 	val >>= ffs(rdev->desc->vsel_mask) - 1;
19164ab5b3d9SMark Brown 
19174ab5b3d9SMark Brown 	return val;
19184ab5b3d9SMark Brown }
19194ab5b3d9SMark Brown EXPORT_SYMBOL_GPL(regulator_get_voltage_sel_regmap);
19204ab5b3d9SMark Brown 
19214ab5b3d9SMark Brown /**
19224ab5b3d9SMark Brown  * regulator_set_voltage_sel_regmap - standard set_voltage_sel for regmap users
19234ab5b3d9SMark Brown  *
19244ab5b3d9SMark Brown  * @rdev: regulator to operate on
19254ab5b3d9SMark Brown  * @sel: Selector to set
19264ab5b3d9SMark Brown  *
19274ab5b3d9SMark Brown  * Regulators that use regmap for their register I/O can set the
19284ab5b3d9SMark Brown  * vsel_reg and vsel_mask fields in their descriptor and then use this
19294ab5b3d9SMark Brown  * as their set_voltage_vsel operation, saving some code.
19304ab5b3d9SMark Brown  */
19314ab5b3d9SMark Brown int regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel)
19324ab5b3d9SMark Brown {
19334ab5b3d9SMark Brown 	sel <<= ffs(rdev->desc->vsel_mask) - 1;
19344ab5b3d9SMark Brown 
19354ab5b3d9SMark Brown 	return regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
19364ab5b3d9SMark Brown 				  rdev->desc->vsel_mask, sel);
19374ab5b3d9SMark Brown }
19384ab5b3d9SMark Brown EXPORT_SYMBOL_GPL(regulator_set_voltage_sel_regmap);
19394ab5b3d9SMark Brown 
194075790251SMark Brown static int _regulator_do_set_voltage(struct regulator_dev *rdev,
194175790251SMark Brown 				     int min_uV, int max_uV)
194275790251SMark Brown {
194375790251SMark Brown 	int ret;
194477af1b26SLinus Walleij 	int delay = 0;
194575790251SMark Brown 	unsigned int selector;
194675790251SMark Brown 
194775790251SMark Brown 	trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV);
194875790251SMark Brown 
1949bf5892a8SMark Brown 	min_uV += rdev->constraints->uV_offset;
1950bf5892a8SMark Brown 	max_uV += rdev->constraints->uV_offset;
1951bf5892a8SMark Brown 
195275790251SMark Brown 	if (rdev->desc->ops->set_voltage) {
195375790251SMark Brown 		ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV,
195475790251SMark Brown 						   &selector);
195575790251SMark Brown 
195675790251SMark Brown 		if (rdev->desc->ops->list_voltage)
195775790251SMark Brown 			selector = rdev->desc->ops->list_voltage(rdev,
195875790251SMark Brown 								 selector);
195975790251SMark Brown 		else
196075790251SMark Brown 			selector = -1;
1961e8eef82bSMark Brown 	} else if (rdev->desc->ops->set_voltage_sel) {
1962e8eef82bSMark Brown 		int best_val = INT_MAX;
1963e8eef82bSMark Brown 		int i;
1964e8eef82bSMark Brown 
1965e8eef82bSMark Brown 		selector = 0;
1966e8eef82bSMark Brown 
1967e8eef82bSMark Brown 		/* Find the smallest voltage that falls within the specified
1968e8eef82bSMark Brown 		 * range.
1969e8eef82bSMark Brown 		 */
1970e8eef82bSMark Brown 		for (i = 0; i < rdev->desc->n_voltages; i++) {
1971e8eef82bSMark Brown 			ret = rdev->desc->ops->list_voltage(rdev, i);
1972e8eef82bSMark Brown 			if (ret < 0)
1973e8eef82bSMark Brown 				continue;
1974e8eef82bSMark Brown 
1975e8eef82bSMark Brown 			if (ret < best_val && ret >= min_uV && ret <= max_uV) {
1976e8eef82bSMark Brown 				best_val = ret;
1977e8eef82bSMark Brown 				selector = i;
1978e8eef82bSMark Brown 			}
1979e8eef82bSMark Brown 		}
1980e8eef82bSMark Brown 
198177af1b26SLinus Walleij 		/*
198277af1b26SLinus Walleij 		 * If we can't obtain the old selector there is not enough
198377af1b26SLinus Walleij 		 * info to call set_voltage_time_sel().
198477af1b26SLinus Walleij 		 */
198577af1b26SLinus Walleij 		if (rdev->desc->ops->set_voltage_time_sel &&
198677af1b26SLinus Walleij 		    rdev->desc->ops->get_voltage_sel) {
198777af1b26SLinus Walleij 			unsigned int old_selector = 0;
198877af1b26SLinus Walleij 
198977af1b26SLinus Walleij 			ret = rdev->desc->ops->get_voltage_sel(rdev);
199077af1b26SLinus Walleij 			if (ret < 0)
199177af1b26SLinus Walleij 				return ret;
199277af1b26SLinus Walleij 			old_selector = ret;
199307351233SAxel Lin 			ret = rdev->desc->ops->set_voltage_time_sel(rdev,
199477af1b26SLinus Walleij 						old_selector, selector);
199507351233SAxel Lin 			if (ret < 0)
199607351233SAxel Lin 				rdev_warn(rdev, "set_voltage_time_sel() failed: %d\n", ret);
199707351233SAxel Lin 			else
199807351233SAxel Lin 				delay = ret;
199977af1b26SLinus Walleij 		}
200077af1b26SLinus Walleij 
2001e8eef82bSMark Brown 		if (best_val != INT_MAX) {
2002e8eef82bSMark Brown 			ret = rdev->desc->ops->set_voltage_sel(rdev, selector);
2003e8eef82bSMark Brown 			selector = best_val;
2004e8eef82bSMark Brown 		} else {
2005e8eef82bSMark Brown 			ret = -EINVAL;
2006e8eef82bSMark Brown 		}
200775790251SMark Brown 	} else {
200875790251SMark Brown 		ret = -EINVAL;
200975790251SMark Brown 	}
201075790251SMark Brown 
201177af1b26SLinus Walleij 	/* Insert any necessary delays */
201277af1b26SLinus Walleij 	if (delay >= 1000) {
201377af1b26SLinus Walleij 		mdelay(delay / 1000);
201477af1b26SLinus Walleij 		udelay(delay % 1000);
201577af1b26SLinus Walleij 	} else if (delay) {
201677af1b26SLinus Walleij 		udelay(delay);
201777af1b26SLinus Walleij 	}
201877af1b26SLinus Walleij 
2019ded06a52SMark Brown 	if (ret == 0)
2020ded06a52SMark Brown 		_notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE,
2021ded06a52SMark Brown 				     NULL);
2022ded06a52SMark Brown 
202375790251SMark Brown 	trace_regulator_set_voltage_complete(rdev_get_name(rdev), selector);
202475790251SMark Brown 
202575790251SMark Brown 	return ret;
202675790251SMark Brown }
202775790251SMark Brown 
2028a7a1ad90SMark Brown /**
2029414c70cbSLiam Girdwood  * regulator_set_voltage - set regulator output voltage
2030414c70cbSLiam Girdwood  * @regulator: regulator source
2031414c70cbSLiam Girdwood  * @min_uV: Minimum required voltage in uV
2032414c70cbSLiam Girdwood  * @max_uV: Maximum acceptable voltage in uV
2033414c70cbSLiam Girdwood  *
2034414c70cbSLiam Girdwood  * Sets a voltage regulator to the desired output voltage. This can be set
2035414c70cbSLiam Girdwood  * during any regulator state. IOW, regulator can be disabled or enabled.
2036414c70cbSLiam Girdwood  *
2037414c70cbSLiam Girdwood  * If the regulator is enabled then the voltage will change to the new value
2038414c70cbSLiam Girdwood  * immediately otherwise if the regulator is disabled the regulator will
2039414c70cbSLiam Girdwood  * output at the new voltage when enabled.
2040414c70cbSLiam Girdwood  *
2041414c70cbSLiam Girdwood  * NOTE: If the regulator is shared between several devices then the lowest
2042414c70cbSLiam Girdwood  * request voltage that meets the system constraints will be used.
204369279fb9SMark Brown  * Regulator system constraints must be set for this regulator before
2044414c70cbSLiam Girdwood  * calling this function otherwise this call will fail.
2045414c70cbSLiam Girdwood  */
2046414c70cbSLiam Girdwood int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
2047414c70cbSLiam Girdwood {
2048414c70cbSLiam Girdwood 	struct regulator_dev *rdev = regulator->rdev;
204995a3c23aSMark Brown 	int ret = 0;
2050414c70cbSLiam Girdwood 
2051414c70cbSLiam Girdwood 	mutex_lock(&rdev->mutex);
2052414c70cbSLiam Girdwood 
205395a3c23aSMark Brown 	/* If we're setting the same range as last time the change
205495a3c23aSMark Brown 	 * should be a noop (some cpufreq implementations use the same
205595a3c23aSMark Brown 	 * voltage for multiple frequencies, for example).
205695a3c23aSMark Brown 	 */
205795a3c23aSMark Brown 	if (regulator->min_uV == min_uV && regulator->max_uV == max_uV)
205895a3c23aSMark Brown 		goto out;
205995a3c23aSMark Brown 
2060414c70cbSLiam Girdwood 	/* sanity check */
2061e8eef82bSMark Brown 	if (!rdev->desc->ops->set_voltage &&
2062e8eef82bSMark Brown 	    !rdev->desc->ops->set_voltage_sel) {
2063414c70cbSLiam Girdwood 		ret = -EINVAL;
2064414c70cbSLiam Girdwood 		goto out;
2065414c70cbSLiam Girdwood 	}
2066414c70cbSLiam Girdwood 
2067414c70cbSLiam Girdwood 	/* constraints check */
2068414c70cbSLiam Girdwood 	ret = regulator_check_voltage(rdev, &min_uV, &max_uV);
2069414c70cbSLiam Girdwood 	if (ret < 0)
2070414c70cbSLiam Girdwood 		goto out;
2071414c70cbSLiam Girdwood 	regulator->min_uV = min_uV;
2072414c70cbSLiam Girdwood 	regulator->max_uV = max_uV;
20733a93f2a9SMark Brown 
207405fda3b1SThomas Petazzoni 	ret = regulator_check_consumers(rdev, &min_uV, &max_uV);
207505fda3b1SThomas Petazzoni 	if (ret < 0)
207605fda3b1SThomas Petazzoni 		goto out;
207705fda3b1SThomas Petazzoni 
207875790251SMark Brown 	ret = _regulator_do_set_voltage(rdev, min_uV, max_uV);
207902fa3ec0SMark Brown 
2080414c70cbSLiam Girdwood out:
2081414c70cbSLiam Girdwood 	mutex_unlock(&rdev->mutex);
2082414c70cbSLiam Girdwood 	return ret;
2083414c70cbSLiam Girdwood }
2084414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_set_voltage);
2085414c70cbSLiam Girdwood 
2086606a2562SMark Brown /**
208788cd222bSLinus Walleij  * regulator_set_voltage_time - get raise/fall time
208888cd222bSLinus Walleij  * @regulator: regulator source
208988cd222bSLinus Walleij  * @old_uV: starting voltage in microvolts
209088cd222bSLinus Walleij  * @new_uV: target voltage in microvolts
209188cd222bSLinus Walleij  *
209288cd222bSLinus Walleij  * Provided with the starting and ending voltage, this function attempts to
209388cd222bSLinus Walleij  * calculate the time in microseconds required to rise or fall to this new
209488cd222bSLinus Walleij  * voltage.
209588cd222bSLinus Walleij  */
209688cd222bSLinus Walleij int regulator_set_voltage_time(struct regulator *regulator,
209788cd222bSLinus Walleij 			       int old_uV, int new_uV)
209888cd222bSLinus Walleij {
209988cd222bSLinus Walleij 	struct regulator_dev	*rdev = regulator->rdev;
210088cd222bSLinus Walleij 	struct regulator_ops	*ops = rdev->desc->ops;
210188cd222bSLinus Walleij 	int old_sel = -1;
210288cd222bSLinus Walleij 	int new_sel = -1;
210388cd222bSLinus Walleij 	int voltage;
210488cd222bSLinus Walleij 	int i;
210588cd222bSLinus Walleij 
210688cd222bSLinus Walleij 	/* Currently requires operations to do this */
210788cd222bSLinus Walleij 	if (!ops->list_voltage || !ops->set_voltage_time_sel
210888cd222bSLinus Walleij 	    || !rdev->desc->n_voltages)
210988cd222bSLinus Walleij 		return -EINVAL;
211088cd222bSLinus Walleij 
211188cd222bSLinus Walleij 	for (i = 0; i < rdev->desc->n_voltages; i++) {
211288cd222bSLinus Walleij 		/* We only look for exact voltage matches here */
211388cd222bSLinus Walleij 		voltage = regulator_list_voltage(regulator, i);
211488cd222bSLinus Walleij 		if (voltage < 0)
211588cd222bSLinus Walleij 			return -EINVAL;
211688cd222bSLinus Walleij 		if (voltage == 0)
211788cd222bSLinus Walleij 			continue;
211888cd222bSLinus Walleij 		if (voltage == old_uV)
211988cd222bSLinus Walleij 			old_sel = i;
212088cd222bSLinus Walleij 		if (voltage == new_uV)
212188cd222bSLinus Walleij 			new_sel = i;
212288cd222bSLinus Walleij 	}
212388cd222bSLinus Walleij 
212488cd222bSLinus Walleij 	if (old_sel < 0 || new_sel < 0)
212588cd222bSLinus Walleij 		return -EINVAL;
212688cd222bSLinus Walleij 
212788cd222bSLinus Walleij 	return ops->set_voltage_time_sel(rdev, old_sel, new_sel);
212888cd222bSLinus Walleij }
212988cd222bSLinus Walleij EXPORT_SYMBOL_GPL(regulator_set_voltage_time);
213088cd222bSLinus Walleij 
213188cd222bSLinus Walleij /**
2132606a2562SMark Brown  * regulator_sync_voltage - re-apply last regulator output voltage
2133606a2562SMark Brown  * @regulator: regulator source
2134606a2562SMark Brown  *
2135606a2562SMark Brown  * Re-apply the last configured voltage.  This is intended to be used
2136606a2562SMark Brown  * where some external control source the consumer is cooperating with
2137606a2562SMark Brown  * has caused the configured voltage to change.
2138606a2562SMark Brown  */
2139606a2562SMark Brown int regulator_sync_voltage(struct regulator *regulator)
2140606a2562SMark Brown {
2141606a2562SMark Brown 	struct regulator_dev *rdev = regulator->rdev;
2142606a2562SMark Brown 	int ret, min_uV, max_uV;
2143606a2562SMark Brown 
2144606a2562SMark Brown 	mutex_lock(&rdev->mutex);
2145606a2562SMark Brown 
2146606a2562SMark Brown 	if (!rdev->desc->ops->set_voltage &&
2147606a2562SMark Brown 	    !rdev->desc->ops->set_voltage_sel) {
2148606a2562SMark Brown 		ret = -EINVAL;
2149606a2562SMark Brown 		goto out;
2150606a2562SMark Brown 	}
2151606a2562SMark Brown 
2152606a2562SMark Brown 	/* This is only going to work if we've had a voltage configured. */
2153606a2562SMark Brown 	if (!regulator->min_uV && !regulator->max_uV) {
2154606a2562SMark Brown 		ret = -EINVAL;
2155606a2562SMark Brown 		goto out;
2156606a2562SMark Brown 	}
2157606a2562SMark Brown 
2158606a2562SMark Brown 	min_uV = regulator->min_uV;
2159606a2562SMark Brown 	max_uV = regulator->max_uV;
2160606a2562SMark Brown 
2161606a2562SMark Brown 	/* This should be a paranoia check... */
2162606a2562SMark Brown 	ret = regulator_check_voltage(rdev, &min_uV, &max_uV);
2163606a2562SMark Brown 	if (ret < 0)
2164606a2562SMark Brown 		goto out;
2165606a2562SMark Brown 
2166606a2562SMark Brown 	ret = regulator_check_consumers(rdev, &min_uV, &max_uV);
2167606a2562SMark Brown 	if (ret < 0)
2168606a2562SMark Brown 		goto out;
2169606a2562SMark Brown 
2170606a2562SMark Brown 	ret = _regulator_do_set_voltage(rdev, min_uV, max_uV);
2171606a2562SMark Brown 
2172606a2562SMark Brown out:
2173606a2562SMark Brown 	mutex_unlock(&rdev->mutex);
2174606a2562SMark Brown 	return ret;
2175606a2562SMark Brown }
2176606a2562SMark Brown EXPORT_SYMBOL_GPL(regulator_sync_voltage);
2177606a2562SMark Brown 
2178414c70cbSLiam Girdwood static int _regulator_get_voltage(struct regulator_dev *rdev)
2179414c70cbSLiam Girdwood {
2180bf5892a8SMark Brown 	int sel, ret;
2181476c2d83SMark Brown 
2182476c2d83SMark Brown 	if (rdev->desc->ops->get_voltage_sel) {
2183476c2d83SMark Brown 		sel = rdev->desc->ops->get_voltage_sel(rdev);
2184476c2d83SMark Brown 		if (sel < 0)
2185476c2d83SMark Brown 			return sel;
2186bf5892a8SMark Brown 		ret = rdev->desc->ops->list_voltage(rdev, sel);
2187cb220d16SAxel Lin 	} else if (rdev->desc->ops->get_voltage) {
2188bf5892a8SMark Brown 		ret = rdev->desc->ops->get_voltage(rdev);
2189cb220d16SAxel Lin 	} else {
2190414c70cbSLiam Girdwood 		return -EINVAL;
2191cb220d16SAxel Lin 	}
2192bf5892a8SMark Brown 
2193cb220d16SAxel Lin 	if (ret < 0)
2194cb220d16SAxel Lin 		return ret;
2195bf5892a8SMark Brown 	return ret - rdev->constraints->uV_offset;
2196414c70cbSLiam Girdwood }
2197414c70cbSLiam Girdwood 
2198414c70cbSLiam Girdwood /**
2199414c70cbSLiam Girdwood  * regulator_get_voltage - get regulator output voltage
2200414c70cbSLiam Girdwood  * @regulator: regulator source
2201414c70cbSLiam Girdwood  *
2202414c70cbSLiam Girdwood  * This returns the current regulator voltage in uV.
2203414c70cbSLiam Girdwood  *
2204414c70cbSLiam Girdwood  * NOTE: If the regulator is disabled it will return the voltage value. This
2205414c70cbSLiam Girdwood  * function should not be used to determine regulator state.
2206414c70cbSLiam Girdwood  */
2207414c70cbSLiam Girdwood int regulator_get_voltage(struct regulator *regulator)
2208414c70cbSLiam Girdwood {
2209414c70cbSLiam Girdwood 	int ret;
2210414c70cbSLiam Girdwood 
2211414c70cbSLiam Girdwood 	mutex_lock(&regulator->rdev->mutex);
2212414c70cbSLiam Girdwood 
2213414c70cbSLiam Girdwood 	ret = _regulator_get_voltage(regulator->rdev);
2214414c70cbSLiam Girdwood 
2215414c70cbSLiam Girdwood 	mutex_unlock(&regulator->rdev->mutex);
2216414c70cbSLiam Girdwood 
2217414c70cbSLiam Girdwood 	return ret;
2218414c70cbSLiam Girdwood }
2219414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_get_voltage);
2220414c70cbSLiam Girdwood 
2221414c70cbSLiam Girdwood /**
2222414c70cbSLiam Girdwood  * regulator_set_current_limit - set regulator output current limit
2223414c70cbSLiam Girdwood  * @regulator: regulator source
2224414c70cbSLiam Girdwood  * @min_uA: Minimuum supported current in uA
2225414c70cbSLiam Girdwood  * @max_uA: Maximum supported current in uA
2226414c70cbSLiam Girdwood  *
2227414c70cbSLiam Girdwood  * Sets current sink to the desired output current. This can be set during
2228414c70cbSLiam Girdwood  * any regulator state. IOW, regulator can be disabled or enabled.
2229414c70cbSLiam Girdwood  *
2230414c70cbSLiam Girdwood  * If the regulator is enabled then the current will change to the new value
2231414c70cbSLiam Girdwood  * immediately otherwise if the regulator is disabled the regulator will
2232414c70cbSLiam Girdwood  * output at the new current when enabled.
2233414c70cbSLiam Girdwood  *
2234414c70cbSLiam Girdwood  * NOTE: Regulator system constraints must be set for this regulator before
2235414c70cbSLiam Girdwood  * calling this function otherwise this call will fail.
2236414c70cbSLiam Girdwood  */
2237414c70cbSLiam Girdwood int regulator_set_current_limit(struct regulator *regulator,
2238414c70cbSLiam Girdwood 			       int min_uA, int max_uA)
2239414c70cbSLiam Girdwood {
2240414c70cbSLiam Girdwood 	struct regulator_dev *rdev = regulator->rdev;
2241414c70cbSLiam Girdwood 	int ret;
2242414c70cbSLiam Girdwood 
2243414c70cbSLiam Girdwood 	mutex_lock(&rdev->mutex);
2244414c70cbSLiam Girdwood 
2245414c70cbSLiam Girdwood 	/* sanity check */
2246414c70cbSLiam Girdwood 	if (!rdev->desc->ops->set_current_limit) {
2247414c70cbSLiam Girdwood 		ret = -EINVAL;
2248414c70cbSLiam Girdwood 		goto out;
2249414c70cbSLiam Girdwood 	}
2250414c70cbSLiam Girdwood 
2251414c70cbSLiam Girdwood 	/* constraints check */
2252414c70cbSLiam Girdwood 	ret = regulator_check_current_limit(rdev, &min_uA, &max_uA);
2253414c70cbSLiam Girdwood 	if (ret < 0)
2254414c70cbSLiam Girdwood 		goto out;
2255414c70cbSLiam Girdwood 
2256414c70cbSLiam Girdwood 	ret = rdev->desc->ops->set_current_limit(rdev, min_uA, max_uA);
2257414c70cbSLiam Girdwood out:
2258414c70cbSLiam Girdwood 	mutex_unlock(&rdev->mutex);
2259414c70cbSLiam Girdwood 	return ret;
2260414c70cbSLiam Girdwood }
2261414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_set_current_limit);
2262414c70cbSLiam Girdwood 
2263414c70cbSLiam Girdwood static int _regulator_get_current_limit(struct regulator_dev *rdev)
2264414c70cbSLiam Girdwood {
2265414c70cbSLiam Girdwood 	int ret;
2266414c70cbSLiam Girdwood 
2267414c70cbSLiam Girdwood 	mutex_lock(&rdev->mutex);
2268414c70cbSLiam Girdwood 
2269414c70cbSLiam Girdwood 	/* sanity check */
2270414c70cbSLiam Girdwood 	if (!rdev->desc->ops->get_current_limit) {
2271414c70cbSLiam Girdwood 		ret = -EINVAL;
2272414c70cbSLiam Girdwood 		goto out;
2273414c70cbSLiam Girdwood 	}
2274414c70cbSLiam Girdwood 
2275414c70cbSLiam Girdwood 	ret = rdev->desc->ops->get_current_limit(rdev);
2276414c70cbSLiam Girdwood out:
2277414c70cbSLiam Girdwood 	mutex_unlock(&rdev->mutex);
2278414c70cbSLiam Girdwood 	return ret;
2279414c70cbSLiam Girdwood }
2280414c70cbSLiam Girdwood 
2281414c70cbSLiam Girdwood /**
2282414c70cbSLiam Girdwood  * regulator_get_current_limit - get regulator output current
2283414c70cbSLiam Girdwood  * @regulator: regulator source
2284414c70cbSLiam Girdwood  *
2285414c70cbSLiam Girdwood  * This returns the current supplied by the specified current sink in uA.
2286414c70cbSLiam Girdwood  *
2287414c70cbSLiam Girdwood  * NOTE: If the regulator is disabled it will return the current value. This
2288414c70cbSLiam Girdwood  * function should not be used to determine regulator state.
2289414c70cbSLiam Girdwood  */
2290414c70cbSLiam Girdwood int regulator_get_current_limit(struct regulator *regulator)
2291414c70cbSLiam Girdwood {
2292414c70cbSLiam Girdwood 	return _regulator_get_current_limit(regulator->rdev);
2293414c70cbSLiam Girdwood }
2294414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_get_current_limit);
2295414c70cbSLiam Girdwood 
2296414c70cbSLiam Girdwood /**
2297414c70cbSLiam Girdwood  * regulator_set_mode - set regulator operating mode
2298414c70cbSLiam Girdwood  * @regulator: regulator source
2299414c70cbSLiam Girdwood  * @mode: operating mode - one of the REGULATOR_MODE constants
2300414c70cbSLiam Girdwood  *
2301414c70cbSLiam Girdwood  * Set regulator operating mode to increase regulator efficiency or improve
2302414c70cbSLiam Girdwood  * regulation performance.
2303414c70cbSLiam Girdwood  *
2304414c70cbSLiam Girdwood  * NOTE: Regulator system constraints must be set for this regulator before
2305414c70cbSLiam Girdwood  * calling this function otherwise this call will fail.
2306414c70cbSLiam Girdwood  */
2307414c70cbSLiam Girdwood int regulator_set_mode(struct regulator *regulator, unsigned int mode)
2308414c70cbSLiam Girdwood {
2309414c70cbSLiam Girdwood 	struct regulator_dev *rdev = regulator->rdev;
2310414c70cbSLiam Girdwood 	int ret;
2311500b4ac9SSundar R Iyer 	int regulator_curr_mode;
2312414c70cbSLiam Girdwood 
2313414c70cbSLiam Girdwood 	mutex_lock(&rdev->mutex);
2314414c70cbSLiam Girdwood 
2315414c70cbSLiam Girdwood 	/* sanity check */
2316414c70cbSLiam Girdwood 	if (!rdev->desc->ops->set_mode) {
2317414c70cbSLiam Girdwood 		ret = -EINVAL;
2318414c70cbSLiam Girdwood 		goto out;
2319414c70cbSLiam Girdwood 	}
2320414c70cbSLiam Girdwood 
2321500b4ac9SSundar R Iyer 	/* return if the same mode is requested */
2322500b4ac9SSundar R Iyer 	if (rdev->desc->ops->get_mode) {
2323500b4ac9SSundar R Iyer 		regulator_curr_mode = rdev->desc->ops->get_mode(rdev);
2324500b4ac9SSundar R Iyer 		if (regulator_curr_mode == mode) {
2325500b4ac9SSundar R Iyer 			ret = 0;
2326500b4ac9SSundar R Iyer 			goto out;
2327500b4ac9SSundar R Iyer 		}
2328500b4ac9SSundar R Iyer 	}
2329500b4ac9SSundar R Iyer 
2330414c70cbSLiam Girdwood 	/* constraints check */
233122c51b47SAxel Lin 	ret = regulator_mode_constrain(rdev, &mode);
2332414c70cbSLiam Girdwood 	if (ret < 0)
2333414c70cbSLiam Girdwood 		goto out;
2334414c70cbSLiam Girdwood 
2335414c70cbSLiam Girdwood 	ret = rdev->desc->ops->set_mode(rdev, mode);
2336414c70cbSLiam Girdwood out:
2337414c70cbSLiam Girdwood 	mutex_unlock(&rdev->mutex);
2338414c70cbSLiam Girdwood 	return ret;
2339414c70cbSLiam Girdwood }
2340414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_set_mode);
2341414c70cbSLiam Girdwood 
2342414c70cbSLiam Girdwood static unsigned int _regulator_get_mode(struct regulator_dev *rdev)
2343414c70cbSLiam Girdwood {
2344414c70cbSLiam Girdwood 	int ret;
2345414c70cbSLiam Girdwood 
2346414c70cbSLiam Girdwood 	mutex_lock(&rdev->mutex);
2347414c70cbSLiam Girdwood 
2348414c70cbSLiam Girdwood 	/* sanity check */
2349414c70cbSLiam Girdwood 	if (!rdev->desc->ops->get_mode) {
2350414c70cbSLiam Girdwood 		ret = -EINVAL;
2351414c70cbSLiam Girdwood 		goto out;
2352414c70cbSLiam Girdwood 	}
2353414c70cbSLiam Girdwood 
2354414c70cbSLiam Girdwood 	ret = rdev->desc->ops->get_mode(rdev);
2355414c70cbSLiam Girdwood out:
2356414c70cbSLiam Girdwood 	mutex_unlock(&rdev->mutex);
2357414c70cbSLiam Girdwood 	return ret;
2358414c70cbSLiam Girdwood }
2359414c70cbSLiam Girdwood 
2360414c70cbSLiam Girdwood /**
2361414c70cbSLiam Girdwood  * regulator_get_mode - get regulator operating mode
2362414c70cbSLiam Girdwood  * @regulator: regulator source
2363414c70cbSLiam Girdwood  *
2364414c70cbSLiam Girdwood  * Get the current regulator operating mode.
2365414c70cbSLiam Girdwood  */
2366414c70cbSLiam Girdwood unsigned int regulator_get_mode(struct regulator *regulator)
2367414c70cbSLiam Girdwood {
2368414c70cbSLiam Girdwood 	return _regulator_get_mode(regulator->rdev);
2369414c70cbSLiam Girdwood }
2370414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_get_mode);
2371414c70cbSLiam Girdwood 
2372414c70cbSLiam Girdwood /**
2373414c70cbSLiam Girdwood  * regulator_set_optimum_mode - set regulator optimum operating mode
2374414c70cbSLiam Girdwood  * @regulator: regulator source
2375414c70cbSLiam Girdwood  * @uA_load: load current
2376414c70cbSLiam Girdwood  *
2377414c70cbSLiam Girdwood  * Notifies the regulator core of a new device load. This is then used by
2378414c70cbSLiam Girdwood  * DRMS (if enabled by constraints) to set the most efficient regulator
2379414c70cbSLiam Girdwood  * operating mode for the new regulator loading.
2380414c70cbSLiam Girdwood  *
2381414c70cbSLiam Girdwood  * Consumer devices notify their supply regulator of the maximum power
2382414c70cbSLiam Girdwood  * they will require (can be taken from device datasheet in the power
2383414c70cbSLiam Girdwood  * consumption tables) when they change operational status and hence power
2384414c70cbSLiam Girdwood  * state. Examples of operational state changes that can affect power
2385414c70cbSLiam Girdwood  * consumption are :-
2386414c70cbSLiam Girdwood  *
2387414c70cbSLiam Girdwood  *    o Device is opened / closed.
2388414c70cbSLiam Girdwood  *    o Device I/O is about to begin or has just finished.
2389414c70cbSLiam Girdwood  *    o Device is idling in between work.
2390414c70cbSLiam Girdwood  *
2391414c70cbSLiam Girdwood  * This information is also exported via sysfs to userspace.
2392414c70cbSLiam Girdwood  *
2393414c70cbSLiam Girdwood  * DRMS will sum the total requested load on the regulator and change
2394414c70cbSLiam Girdwood  * to the most efficient operating mode if platform constraints allow.
2395414c70cbSLiam Girdwood  *
2396414c70cbSLiam Girdwood  * Returns the new regulator mode or error.
2397414c70cbSLiam Girdwood  */
2398414c70cbSLiam Girdwood int regulator_set_optimum_mode(struct regulator *regulator, int uA_load)
2399414c70cbSLiam Girdwood {
2400414c70cbSLiam Girdwood 	struct regulator_dev *rdev = regulator->rdev;
2401414c70cbSLiam Girdwood 	struct regulator *consumer;
2402414c70cbSLiam Girdwood 	int ret, output_uV, input_uV, total_uA_load = 0;
2403414c70cbSLiam Girdwood 	unsigned int mode;
2404414c70cbSLiam Girdwood 
2405414c70cbSLiam Girdwood 	mutex_lock(&rdev->mutex);
2406414c70cbSLiam Girdwood 
2407a4b41483SMark Brown 	/*
2408a4b41483SMark Brown 	 * first check to see if we can set modes at all, otherwise just
2409a4b41483SMark Brown 	 * tell the consumer everything is OK.
2410a4b41483SMark Brown 	 */
2411414c70cbSLiam Girdwood 	regulator->uA_load = uA_load;
2412414c70cbSLiam Girdwood 	ret = regulator_check_drms(rdev);
2413a4b41483SMark Brown 	if (ret < 0) {
2414a4b41483SMark Brown 		ret = 0;
2415414c70cbSLiam Girdwood 		goto out;
2416a4b41483SMark Brown 	}
2417414c70cbSLiam Girdwood 
2418414c70cbSLiam Girdwood 	if (!rdev->desc->ops->get_optimum_mode)
2419414c70cbSLiam Girdwood 		goto out;
2420414c70cbSLiam Girdwood 
2421a4b41483SMark Brown 	/*
2422a4b41483SMark Brown 	 * we can actually do this so any errors are indicators of
2423a4b41483SMark Brown 	 * potential real failure.
2424a4b41483SMark Brown 	 */
2425a4b41483SMark Brown 	ret = -EINVAL;
2426a4b41483SMark Brown 
2427414c70cbSLiam Girdwood 	/* get output voltage */
24281bf5a1f8SMark Brown 	output_uV = _regulator_get_voltage(rdev);
2429414c70cbSLiam Girdwood 	if (output_uV <= 0) {
24305da84fd9SJoe Perches 		rdev_err(rdev, "invalid output voltage found\n");
2431414c70cbSLiam Girdwood 		goto out;
2432414c70cbSLiam Girdwood 	}
2433414c70cbSLiam Girdwood 
2434414c70cbSLiam Girdwood 	/* get input voltage */
24351bf5a1f8SMark Brown 	input_uV = 0;
24361bf5a1f8SMark Brown 	if (rdev->supply)
24373801b86aSMark Brown 		input_uV = regulator_get_voltage(rdev->supply);
24381bf5a1f8SMark Brown 	if (input_uV <= 0)
2439414c70cbSLiam Girdwood 		input_uV = rdev->constraints->input_uV;
2440414c70cbSLiam Girdwood 	if (input_uV <= 0) {
24415da84fd9SJoe Perches 		rdev_err(rdev, "invalid input voltage found\n");
2442414c70cbSLiam Girdwood 		goto out;
2443414c70cbSLiam Girdwood 	}
2444414c70cbSLiam Girdwood 
2445414c70cbSLiam Girdwood 	/* calc total requested load for this regulator */
2446414c70cbSLiam Girdwood 	list_for_each_entry(consumer, &rdev->consumer_list, list)
2447414c70cbSLiam Girdwood 		total_uA_load += consumer->uA_load;
2448414c70cbSLiam Girdwood 
2449414c70cbSLiam Girdwood 	mode = rdev->desc->ops->get_optimum_mode(rdev,
2450414c70cbSLiam Girdwood 						 input_uV, output_uV,
2451414c70cbSLiam Girdwood 						 total_uA_load);
24522c608234SMark Brown 	ret = regulator_mode_constrain(rdev, &mode);
2453e573520bSDavid Brownell 	if (ret < 0) {
24545da84fd9SJoe Perches 		rdev_err(rdev, "failed to get optimum mode @ %d uA %d -> %d uV\n",
2455414c70cbSLiam Girdwood 			 total_uA_load, input_uV, output_uV);
2456414c70cbSLiam Girdwood 		goto out;
2457414c70cbSLiam Girdwood 	}
2458414c70cbSLiam Girdwood 
2459414c70cbSLiam Girdwood 	ret = rdev->desc->ops->set_mode(rdev, mode);
2460e573520bSDavid Brownell 	if (ret < 0) {
24615da84fd9SJoe Perches 		rdev_err(rdev, "failed to set optimum mode %x\n", mode);
2462414c70cbSLiam Girdwood 		goto out;
2463414c70cbSLiam Girdwood 	}
2464414c70cbSLiam Girdwood 	ret = mode;
2465414c70cbSLiam Girdwood out:
2466414c70cbSLiam Girdwood 	mutex_unlock(&rdev->mutex);
2467414c70cbSLiam Girdwood 	return ret;
2468414c70cbSLiam Girdwood }
2469414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_set_optimum_mode);
2470414c70cbSLiam Girdwood 
2471414c70cbSLiam Girdwood /**
2472414c70cbSLiam Girdwood  * regulator_register_notifier - register regulator event notifier
2473414c70cbSLiam Girdwood  * @regulator: regulator source
247469279fb9SMark Brown  * @nb: notifier block
2475414c70cbSLiam Girdwood  *
2476414c70cbSLiam Girdwood  * Register notifier block to receive regulator events.
2477414c70cbSLiam Girdwood  */
2478414c70cbSLiam Girdwood int regulator_register_notifier(struct regulator *regulator,
2479414c70cbSLiam Girdwood 			      struct notifier_block *nb)
2480414c70cbSLiam Girdwood {
2481414c70cbSLiam Girdwood 	return blocking_notifier_chain_register(&regulator->rdev->notifier,
2482414c70cbSLiam Girdwood 						nb);
2483414c70cbSLiam Girdwood }
2484414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_register_notifier);
2485414c70cbSLiam Girdwood 
2486414c70cbSLiam Girdwood /**
2487414c70cbSLiam Girdwood  * regulator_unregister_notifier - unregister regulator event notifier
2488414c70cbSLiam Girdwood  * @regulator: regulator source
248969279fb9SMark Brown  * @nb: notifier block
2490414c70cbSLiam Girdwood  *
2491414c70cbSLiam Girdwood  * Unregister regulator event notifier block.
2492414c70cbSLiam Girdwood  */
2493414c70cbSLiam Girdwood int regulator_unregister_notifier(struct regulator *regulator,
2494414c70cbSLiam Girdwood 				struct notifier_block *nb)
2495414c70cbSLiam Girdwood {
2496414c70cbSLiam Girdwood 	return blocking_notifier_chain_unregister(&regulator->rdev->notifier,
2497414c70cbSLiam Girdwood 						  nb);
2498414c70cbSLiam Girdwood }
2499414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_unregister_notifier);
2500414c70cbSLiam Girdwood 
2501b136fb44SJonathan Cameron /* notify regulator consumers and downstream regulator consumers.
2502b136fb44SJonathan Cameron  * Note mutex must be held by caller.
2503b136fb44SJonathan Cameron  */
2504414c70cbSLiam Girdwood static void _notifier_call_chain(struct regulator_dev *rdev,
2505414c70cbSLiam Girdwood 				  unsigned long event, void *data)
2506414c70cbSLiam Girdwood {
2507414c70cbSLiam Girdwood 	/* call rdev chain first */
2508414c70cbSLiam Girdwood 	blocking_notifier_call_chain(&rdev->notifier, event, NULL);
2509414c70cbSLiam Girdwood }
2510414c70cbSLiam Girdwood 
2511414c70cbSLiam Girdwood /**
2512414c70cbSLiam Girdwood  * regulator_bulk_get - get multiple regulator consumers
2513414c70cbSLiam Girdwood  *
2514414c70cbSLiam Girdwood  * @dev:           Device to supply
2515414c70cbSLiam Girdwood  * @num_consumers: Number of consumers to register
2516414c70cbSLiam Girdwood  * @consumers:     Configuration of consumers; clients are stored here.
2517414c70cbSLiam Girdwood  *
2518414c70cbSLiam Girdwood  * @return 0 on success, an errno on failure.
2519414c70cbSLiam Girdwood  *
2520414c70cbSLiam Girdwood  * This helper function allows drivers to get several regulator
2521414c70cbSLiam Girdwood  * consumers in one operation.  If any of the regulators cannot be
2522414c70cbSLiam Girdwood  * acquired then any regulators that were allocated will be freed
2523414c70cbSLiam Girdwood  * before returning to the caller.
2524414c70cbSLiam Girdwood  */
2525414c70cbSLiam Girdwood int regulator_bulk_get(struct device *dev, int num_consumers,
2526414c70cbSLiam Girdwood 		       struct regulator_bulk_data *consumers)
2527414c70cbSLiam Girdwood {
2528414c70cbSLiam Girdwood 	int i;
2529414c70cbSLiam Girdwood 	int ret;
2530414c70cbSLiam Girdwood 
2531414c70cbSLiam Girdwood 	for (i = 0; i < num_consumers; i++)
2532414c70cbSLiam Girdwood 		consumers[i].consumer = NULL;
2533414c70cbSLiam Girdwood 
2534414c70cbSLiam Girdwood 	for (i = 0; i < num_consumers; i++) {
2535414c70cbSLiam Girdwood 		consumers[i].consumer = regulator_get(dev,
2536414c70cbSLiam Girdwood 						      consumers[i].supply);
2537414c70cbSLiam Girdwood 		if (IS_ERR(consumers[i].consumer)) {
2538414c70cbSLiam Girdwood 			ret = PTR_ERR(consumers[i].consumer);
25395b307627SMark Brown 			dev_err(dev, "Failed to get supply '%s': %d\n",
25405b307627SMark Brown 				consumers[i].supply, ret);
2541414c70cbSLiam Girdwood 			consumers[i].consumer = NULL;
2542414c70cbSLiam Girdwood 			goto err;
2543414c70cbSLiam Girdwood 		}
2544414c70cbSLiam Girdwood 	}
2545414c70cbSLiam Girdwood 
2546414c70cbSLiam Girdwood 	return 0;
2547414c70cbSLiam Girdwood 
2548414c70cbSLiam Girdwood err:
2549b29c7690SAxel Lin 	while (--i >= 0)
2550414c70cbSLiam Girdwood 		regulator_put(consumers[i].consumer);
2551414c70cbSLiam Girdwood 
2552414c70cbSLiam Girdwood 	return ret;
2553414c70cbSLiam Girdwood }
2554414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_bulk_get);
2555414c70cbSLiam Girdwood 
2556e6e74030SMark Brown /**
2557e6e74030SMark Brown  * devm_regulator_bulk_get - managed get multiple regulator consumers
2558e6e74030SMark Brown  *
2559e6e74030SMark Brown  * @dev:           Device to supply
2560e6e74030SMark Brown  * @num_consumers: Number of consumers to register
2561e6e74030SMark Brown  * @consumers:     Configuration of consumers; clients are stored here.
2562e6e74030SMark Brown  *
2563e6e74030SMark Brown  * @return 0 on success, an errno on failure.
2564e6e74030SMark Brown  *
2565e6e74030SMark Brown  * This helper function allows drivers to get several regulator
2566e6e74030SMark Brown  * consumers in one operation with management, the regulators will
2567e6e74030SMark Brown  * automatically be freed when the device is unbound.  If any of the
2568e6e74030SMark Brown  * regulators cannot be acquired then any regulators that were
2569e6e74030SMark Brown  * allocated will be freed before returning to the caller.
2570e6e74030SMark Brown  */
2571e6e74030SMark Brown int devm_regulator_bulk_get(struct device *dev, int num_consumers,
2572e6e74030SMark Brown 			    struct regulator_bulk_data *consumers)
2573e6e74030SMark Brown {
2574e6e74030SMark Brown 	int i;
2575e6e74030SMark Brown 	int ret;
2576e6e74030SMark Brown 
2577e6e74030SMark Brown 	for (i = 0; i < num_consumers; i++)
2578e6e74030SMark Brown 		consumers[i].consumer = NULL;
2579e6e74030SMark Brown 
2580e6e74030SMark Brown 	for (i = 0; i < num_consumers; i++) {
2581e6e74030SMark Brown 		consumers[i].consumer = devm_regulator_get(dev,
2582e6e74030SMark Brown 							   consumers[i].supply);
2583e6e74030SMark Brown 		if (IS_ERR(consumers[i].consumer)) {
2584e6e74030SMark Brown 			ret = PTR_ERR(consumers[i].consumer);
2585e6e74030SMark Brown 			dev_err(dev, "Failed to get supply '%s': %d\n",
2586e6e74030SMark Brown 				consumers[i].supply, ret);
2587e6e74030SMark Brown 			consumers[i].consumer = NULL;
2588e6e74030SMark Brown 			goto err;
2589e6e74030SMark Brown 		}
2590e6e74030SMark Brown 	}
2591e6e74030SMark Brown 
2592e6e74030SMark Brown 	return 0;
2593e6e74030SMark Brown 
2594e6e74030SMark Brown err:
2595e6e74030SMark Brown 	for (i = 0; i < num_consumers && consumers[i].consumer; i++)
2596e6e74030SMark Brown 		devm_regulator_put(consumers[i].consumer);
2597e6e74030SMark Brown 
2598e6e74030SMark Brown 	return ret;
2599e6e74030SMark Brown }
2600e6e74030SMark Brown EXPORT_SYMBOL_GPL(devm_regulator_bulk_get);
2601e6e74030SMark Brown 
2602f21e0e81SMark Brown static void regulator_bulk_enable_async(void *data, async_cookie_t cookie)
2603f21e0e81SMark Brown {
2604f21e0e81SMark Brown 	struct regulator_bulk_data *bulk = data;
2605f21e0e81SMark Brown 
2606f21e0e81SMark Brown 	bulk->ret = regulator_enable(bulk->consumer);
2607f21e0e81SMark Brown }
2608f21e0e81SMark Brown 
2609414c70cbSLiam Girdwood /**
2610414c70cbSLiam Girdwood  * regulator_bulk_enable - enable multiple regulator consumers
2611414c70cbSLiam Girdwood  *
2612414c70cbSLiam Girdwood  * @num_consumers: Number of consumers
2613414c70cbSLiam Girdwood  * @consumers:     Consumer data; clients are stored here.
2614414c70cbSLiam Girdwood  * @return         0 on success, an errno on failure
2615414c70cbSLiam Girdwood  *
2616414c70cbSLiam Girdwood  * This convenience API allows consumers to enable multiple regulator
2617414c70cbSLiam Girdwood  * clients in a single API call.  If any consumers cannot be enabled
2618414c70cbSLiam Girdwood  * then any others that were enabled will be disabled again prior to
2619414c70cbSLiam Girdwood  * return.
2620414c70cbSLiam Girdwood  */
2621414c70cbSLiam Girdwood int regulator_bulk_enable(int num_consumers,
2622414c70cbSLiam Girdwood 			  struct regulator_bulk_data *consumers)
2623414c70cbSLiam Girdwood {
2624f21e0e81SMark Brown 	LIST_HEAD(async_domain);
2625414c70cbSLiam Girdwood 	int i;
2626f21e0e81SMark Brown 	int ret = 0;
2627414c70cbSLiam Girdwood 
2628f21e0e81SMark Brown 	for (i = 0; i < num_consumers; i++)
2629f21e0e81SMark Brown 		async_schedule_domain(regulator_bulk_enable_async,
2630f21e0e81SMark Brown 				      &consumers[i], &async_domain);
2631f21e0e81SMark Brown 
2632f21e0e81SMark Brown 	async_synchronize_full_domain(&async_domain);
2633f21e0e81SMark Brown 
2634f21e0e81SMark Brown 	/* If any consumer failed we need to unwind any that succeeded */
2635414c70cbSLiam Girdwood 	for (i = 0; i < num_consumers; i++) {
2636f21e0e81SMark Brown 		if (consumers[i].ret != 0) {
2637f21e0e81SMark Brown 			ret = consumers[i].ret;
2638414c70cbSLiam Girdwood 			goto err;
2639414c70cbSLiam Girdwood 		}
2640f21e0e81SMark Brown 	}
2641414c70cbSLiam Girdwood 
2642414c70cbSLiam Girdwood 	return 0;
2643414c70cbSLiam Girdwood 
2644414c70cbSLiam Girdwood err:
2645b29c7690SAxel Lin 	pr_err("Failed to enable %s: %d\n", consumers[i].supply, ret);
2646b29c7690SAxel Lin 	while (--i >= 0)
2647414c70cbSLiam Girdwood 		regulator_disable(consumers[i].consumer);
2648414c70cbSLiam Girdwood 
2649414c70cbSLiam Girdwood 	return ret;
2650414c70cbSLiam Girdwood }
2651414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_bulk_enable);
2652414c70cbSLiam Girdwood 
2653414c70cbSLiam Girdwood /**
2654414c70cbSLiam Girdwood  * regulator_bulk_disable - disable multiple regulator consumers
2655414c70cbSLiam Girdwood  *
2656414c70cbSLiam Girdwood  * @num_consumers: Number of consumers
2657414c70cbSLiam Girdwood  * @consumers:     Consumer data; clients are stored here.
2658414c70cbSLiam Girdwood  * @return         0 on success, an errno on failure
2659414c70cbSLiam Girdwood  *
2660414c70cbSLiam Girdwood  * This convenience API allows consumers to disable multiple regulator
266149e22632SSylwester Nawrocki  * clients in a single API call.  If any consumers cannot be disabled
266249e22632SSylwester Nawrocki  * then any others that were disabled will be enabled again prior to
2663414c70cbSLiam Girdwood  * return.
2664414c70cbSLiam Girdwood  */
2665414c70cbSLiam Girdwood int regulator_bulk_disable(int num_consumers,
2666414c70cbSLiam Girdwood 			   struct regulator_bulk_data *consumers)
2667414c70cbSLiam Girdwood {
2668414c70cbSLiam Girdwood 	int i;
2669414c70cbSLiam Girdwood 	int ret;
2670414c70cbSLiam Girdwood 
267149e22632SSylwester Nawrocki 	for (i = num_consumers - 1; i >= 0; --i) {
2672414c70cbSLiam Girdwood 		ret = regulator_disable(consumers[i].consumer);
2673414c70cbSLiam Girdwood 		if (ret != 0)
2674414c70cbSLiam Girdwood 			goto err;
2675414c70cbSLiam Girdwood 	}
2676414c70cbSLiam Girdwood 
2677414c70cbSLiam Girdwood 	return 0;
2678414c70cbSLiam Girdwood 
2679414c70cbSLiam Girdwood err:
26805da84fd9SJoe Perches 	pr_err("Failed to disable %s: %d\n", consumers[i].supply, ret);
268149e22632SSylwester Nawrocki 	for (++i; i < num_consumers; ++i)
2682414c70cbSLiam Girdwood 		regulator_enable(consumers[i].consumer);
2683414c70cbSLiam Girdwood 
2684414c70cbSLiam Girdwood 	return ret;
2685414c70cbSLiam Girdwood }
2686414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_bulk_disable);
2687414c70cbSLiam Girdwood 
2688414c70cbSLiam Girdwood /**
2689e1de2f42SDonggeun Kim  * regulator_bulk_force_disable - force disable multiple regulator consumers
2690e1de2f42SDonggeun Kim  *
2691e1de2f42SDonggeun Kim  * @num_consumers: Number of consumers
2692e1de2f42SDonggeun Kim  * @consumers:     Consumer data; clients are stored here.
2693e1de2f42SDonggeun Kim  * @return         0 on success, an errno on failure
2694e1de2f42SDonggeun Kim  *
2695e1de2f42SDonggeun Kim  * This convenience API allows consumers to forcibly disable multiple regulator
2696e1de2f42SDonggeun Kim  * clients in a single API call.
2697e1de2f42SDonggeun Kim  * NOTE: This should be used for situations when device damage will
2698e1de2f42SDonggeun Kim  * likely occur if the regulators are not disabled (e.g. over temp).
2699e1de2f42SDonggeun Kim  * Although regulator_force_disable function call for some consumers can
2700e1de2f42SDonggeun Kim  * return error numbers, the function is called for all consumers.
2701e1de2f42SDonggeun Kim  */
2702e1de2f42SDonggeun Kim int regulator_bulk_force_disable(int num_consumers,
2703e1de2f42SDonggeun Kim 			   struct regulator_bulk_data *consumers)
2704e1de2f42SDonggeun Kim {
2705e1de2f42SDonggeun Kim 	int i;
2706e1de2f42SDonggeun Kim 	int ret;
2707e1de2f42SDonggeun Kim 
2708e1de2f42SDonggeun Kim 	for (i = 0; i < num_consumers; i++)
2709e1de2f42SDonggeun Kim 		consumers[i].ret =
2710e1de2f42SDonggeun Kim 			    regulator_force_disable(consumers[i].consumer);
2711e1de2f42SDonggeun Kim 
2712e1de2f42SDonggeun Kim 	for (i = 0; i < num_consumers; i++) {
2713e1de2f42SDonggeun Kim 		if (consumers[i].ret != 0) {
2714e1de2f42SDonggeun Kim 			ret = consumers[i].ret;
2715e1de2f42SDonggeun Kim 			goto out;
2716e1de2f42SDonggeun Kim 		}
2717e1de2f42SDonggeun Kim 	}
2718e1de2f42SDonggeun Kim 
2719e1de2f42SDonggeun Kim 	return 0;
2720e1de2f42SDonggeun Kim out:
2721e1de2f42SDonggeun Kim 	return ret;
2722e1de2f42SDonggeun Kim }
2723e1de2f42SDonggeun Kim EXPORT_SYMBOL_GPL(regulator_bulk_force_disable);
2724e1de2f42SDonggeun Kim 
2725e1de2f42SDonggeun Kim /**
2726414c70cbSLiam Girdwood  * regulator_bulk_free - free multiple regulator consumers
2727414c70cbSLiam Girdwood  *
2728414c70cbSLiam Girdwood  * @num_consumers: Number of consumers
2729414c70cbSLiam Girdwood  * @consumers:     Consumer data; clients are stored here.
2730414c70cbSLiam Girdwood  *
2731414c70cbSLiam Girdwood  * This convenience API allows consumers to free multiple regulator
2732414c70cbSLiam Girdwood  * clients in a single API call.
2733414c70cbSLiam Girdwood  */
2734414c70cbSLiam Girdwood void regulator_bulk_free(int num_consumers,
2735414c70cbSLiam Girdwood 			 struct regulator_bulk_data *consumers)
2736414c70cbSLiam Girdwood {
2737414c70cbSLiam Girdwood 	int i;
2738414c70cbSLiam Girdwood 
2739414c70cbSLiam Girdwood 	for (i = 0; i < num_consumers; i++) {
2740414c70cbSLiam Girdwood 		regulator_put(consumers[i].consumer);
2741414c70cbSLiam Girdwood 		consumers[i].consumer = NULL;
2742414c70cbSLiam Girdwood 	}
2743414c70cbSLiam Girdwood }
2744414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_bulk_free);
2745414c70cbSLiam Girdwood 
2746414c70cbSLiam Girdwood /**
2747414c70cbSLiam Girdwood  * regulator_notifier_call_chain - call regulator event notifier
274869279fb9SMark Brown  * @rdev: regulator source
2749414c70cbSLiam Girdwood  * @event: notifier block
275069279fb9SMark Brown  * @data: callback-specific data.
2751414c70cbSLiam Girdwood  *
2752414c70cbSLiam Girdwood  * Called by regulator drivers to notify clients a regulator event has
2753414c70cbSLiam Girdwood  * occurred. We also notify regulator clients downstream.
2754b136fb44SJonathan Cameron  * Note lock must be held by caller.
2755414c70cbSLiam Girdwood  */
2756414c70cbSLiam Girdwood int regulator_notifier_call_chain(struct regulator_dev *rdev,
2757414c70cbSLiam Girdwood 				  unsigned long event, void *data)
2758414c70cbSLiam Girdwood {
2759414c70cbSLiam Girdwood 	_notifier_call_chain(rdev, event, data);
2760414c70cbSLiam Girdwood 	return NOTIFY_DONE;
2761414c70cbSLiam Girdwood 
2762414c70cbSLiam Girdwood }
2763414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_notifier_call_chain);
2764414c70cbSLiam Girdwood 
2765be721979SMark Brown /**
2766be721979SMark Brown  * regulator_mode_to_status - convert a regulator mode into a status
2767be721979SMark Brown  *
2768be721979SMark Brown  * @mode: Mode to convert
2769be721979SMark Brown  *
2770be721979SMark Brown  * Convert a regulator mode into a status.
2771be721979SMark Brown  */
2772be721979SMark Brown int regulator_mode_to_status(unsigned int mode)
2773be721979SMark Brown {
2774be721979SMark Brown 	switch (mode) {
2775be721979SMark Brown 	case REGULATOR_MODE_FAST:
2776be721979SMark Brown 		return REGULATOR_STATUS_FAST;
2777be721979SMark Brown 	case REGULATOR_MODE_NORMAL:
2778be721979SMark Brown 		return REGULATOR_STATUS_NORMAL;
2779be721979SMark Brown 	case REGULATOR_MODE_IDLE:
2780be721979SMark Brown 		return REGULATOR_STATUS_IDLE;
2781be721979SMark Brown 	case REGULATOR_STATUS_STANDBY:
2782be721979SMark Brown 		return REGULATOR_STATUS_STANDBY;
2783be721979SMark Brown 	default:
2784be721979SMark Brown 		return 0;
2785be721979SMark Brown 	}
2786be721979SMark Brown }
2787be721979SMark Brown EXPORT_SYMBOL_GPL(regulator_mode_to_status);
2788be721979SMark Brown 
27897ad68e2fSDavid Brownell /*
27907ad68e2fSDavid Brownell  * To avoid cluttering sysfs (and memory) with useless state, only
27917ad68e2fSDavid Brownell  * create attributes that can be meaningfully displayed.
27927ad68e2fSDavid Brownell  */
27937ad68e2fSDavid Brownell static int add_regulator_attributes(struct regulator_dev *rdev)
27947ad68e2fSDavid Brownell {
27957ad68e2fSDavid Brownell 	struct device		*dev = &rdev->dev;
27967ad68e2fSDavid Brownell 	struct regulator_ops	*ops = rdev->desc->ops;
27977ad68e2fSDavid Brownell 	int			status = 0;
27987ad68e2fSDavid Brownell 
27997ad68e2fSDavid Brownell 	/* some attributes need specific methods to be displayed */
28004c78899bSMark Brown 	if ((ops->get_voltage && ops->get_voltage(rdev) >= 0) ||
28014c78899bSMark Brown 	    (ops->get_voltage_sel && ops->get_voltage_sel(rdev) >= 0)) {
28027ad68e2fSDavid Brownell 		status = device_create_file(dev, &dev_attr_microvolts);
28037ad68e2fSDavid Brownell 		if (status < 0)
28047ad68e2fSDavid Brownell 			return status;
28057ad68e2fSDavid Brownell 	}
28067ad68e2fSDavid Brownell 	if (ops->get_current_limit) {
28077ad68e2fSDavid Brownell 		status = device_create_file(dev, &dev_attr_microamps);
28087ad68e2fSDavid Brownell 		if (status < 0)
28097ad68e2fSDavid Brownell 			return status;
28107ad68e2fSDavid Brownell 	}
28117ad68e2fSDavid Brownell 	if (ops->get_mode) {
28127ad68e2fSDavid Brownell 		status = device_create_file(dev, &dev_attr_opmode);
28137ad68e2fSDavid Brownell 		if (status < 0)
28147ad68e2fSDavid Brownell 			return status;
28157ad68e2fSDavid Brownell 	}
28167ad68e2fSDavid Brownell 	if (ops->is_enabled) {
28177ad68e2fSDavid Brownell 		status = device_create_file(dev, &dev_attr_state);
28187ad68e2fSDavid Brownell 		if (status < 0)
28197ad68e2fSDavid Brownell 			return status;
28207ad68e2fSDavid Brownell 	}
2821853116a1SDavid Brownell 	if (ops->get_status) {
2822853116a1SDavid Brownell 		status = device_create_file(dev, &dev_attr_status);
2823853116a1SDavid Brownell 		if (status < 0)
2824853116a1SDavid Brownell 			return status;
2825853116a1SDavid Brownell 	}
28267ad68e2fSDavid Brownell 
28277ad68e2fSDavid Brownell 	/* some attributes are type-specific */
28287ad68e2fSDavid Brownell 	if (rdev->desc->type == REGULATOR_CURRENT) {
28297ad68e2fSDavid Brownell 		status = device_create_file(dev, &dev_attr_requested_microamps);
28307ad68e2fSDavid Brownell 		if (status < 0)
28317ad68e2fSDavid Brownell 			return status;
28327ad68e2fSDavid Brownell 	}
28337ad68e2fSDavid Brownell 
28347ad68e2fSDavid Brownell 	/* all the other attributes exist to support constraints;
28357ad68e2fSDavid Brownell 	 * don't show them if there are no constraints, or if the
28367ad68e2fSDavid Brownell 	 * relevant supporting methods are missing.
28377ad68e2fSDavid Brownell 	 */
28387ad68e2fSDavid Brownell 	if (!rdev->constraints)
28397ad68e2fSDavid Brownell 		return status;
28407ad68e2fSDavid Brownell 
28417ad68e2fSDavid Brownell 	/* constraints need specific supporting methods */
2842e8eef82bSMark Brown 	if (ops->set_voltage || ops->set_voltage_sel) {
28437ad68e2fSDavid Brownell 		status = device_create_file(dev, &dev_attr_min_microvolts);
28447ad68e2fSDavid Brownell 		if (status < 0)
28457ad68e2fSDavid Brownell 			return status;
28467ad68e2fSDavid Brownell 		status = device_create_file(dev, &dev_attr_max_microvolts);
28477ad68e2fSDavid Brownell 		if (status < 0)
28487ad68e2fSDavid Brownell 			return status;
28497ad68e2fSDavid Brownell 	}
28507ad68e2fSDavid Brownell 	if (ops->set_current_limit) {
28517ad68e2fSDavid Brownell 		status = device_create_file(dev, &dev_attr_min_microamps);
28527ad68e2fSDavid Brownell 		if (status < 0)
28537ad68e2fSDavid Brownell 			return status;
28547ad68e2fSDavid Brownell 		status = device_create_file(dev, &dev_attr_max_microamps);
28557ad68e2fSDavid Brownell 		if (status < 0)
28567ad68e2fSDavid Brownell 			return status;
28577ad68e2fSDavid Brownell 	}
28587ad68e2fSDavid Brownell 
28597ad68e2fSDavid Brownell 	/* suspend mode constraints need multiple supporting methods */
28607ad68e2fSDavid Brownell 	if (!(ops->set_suspend_enable && ops->set_suspend_disable))
28617ad68e2fSDavid Brownell 		return status;
28627ad68e2fSDavid Brownell 
28637ad68e2fSDavid Brownell 	status = device_create_file(dev, &dev_attr_suspend_standby_state);
28647ad68e2fSDavid Brownell 	if (status < 0)
28657ad68e2fSDavid Brownell 		return status;
28667ad68e2fSDavid Brownell 	status = device_create_file(dev, &dev_attr_suspend_mem_state);
28677ad68e2fSDavid Brownell 	if (status < 0)
28687ad68e2fSDavid Brownell 		return status;
28697ad68e2fSDavid Brownell 	status = device_create_file(dev, &dev_attr_suspend_disk_state);
28707ad68e2fSDavid Brownell 	if (status < 0)
28717ad68e2fSDavid Brownell 		return status;
28727ad68e2fSDavid Brownell 
28737ad68e2fSDavid Brownell 	if (ops->set_suspend_voltage) {
28747ad68e2fSDavid Brownell 		status = device_create_file(dev,
28757ad68e2fSDavid Brownell 				&dev_attr_suspend_standby_microvolts);
28767ad68e2fSDavid Brownell 		if (status < 0)
28777ad68e2fSDavid Brownell 			return status;
28787ad68e2fSDavid Brownell 		status = device_create_file(dev,
28797ad68e2fSDavid Brownell 				&dev_attr_suspend_mem_microvolts);
28807ad68e2fSDavid Brownell 		if (status < 0)
28817ad68e2fSDavid Brownell 			return status;
28827ad68e2fSDavid Brownell 		status = device_create_file(dev,
28837ad68e2fSDavid Brownell 				&dev_attr_suspend_disk_microvolts);
28847ad68e2fSDavid Brownell 		if (status < 0)
28857ad68e2fSDavid Brownell 			return status;
28867ad68e2fSDavid Brownell 	}
28877ad68e2fSDavid Brownell 
28887ad68e2fSDavid Brownell 	if (ops->set_suspend_mode) {
28897ad68e2fSDavid Brownell 		status = device_create_file(dev,
28907ad68e2fSDavid Brownell 				&dev_attr_suspend_standby_mode);
28917ad68e2fSDavid Brownell 		if (status < 0)
28927ad68e2fSDavid Brownell 			return status;
28937ad68e2fSDavid Brownell 		status = device_create_file(dev,
28947ad68e2fSDavid Brownell 				&dev_attr_suspend_mem_mode);
28957ad68e2fSDavid Brownell 		if (status < 0)
28967ad68e2fSDavid Brownell 			return status;
28977ad68e2fSDavid Brownell 		status = device_create_file(dev,
28987ad68e2fSDavid Brownell 				&dev_attr_suspend_disk_mode);
28997ad68e2fSDavid Brownell 		if (status < 0)
29007ad68e2fSDavid Brownell 			return status;
29017ad68e2fSDavid Brownell 	}
29027ad68e2fSDavid Brownell 
29037ad68e2fSDavid Brownell 	return status;
29047ad68e2fSDavid Brownell }
29057ad68e2fSDavid Brownell 
29061130e5b3SMark Brown static void rdev_init_debugfs(struct regulator_dev *rdev)
29071130e5b3SMark Brown {
29081130e5b3SMark Brown 	rdev->debugfs = debugfs_create_dir(rdev_get_name(rdev), debugfs_root);
290924751434SStephen Boyd 	if (!rdev->debugfs) {
29101130e5b3SMark Brown 		rdev_warn(rdev, "Failed to create debugfs directory\n");
29111130e5b3SMark Brown 		return;
29121130e5b3SMark Brown 	}
29131130e5b3SMark Brown 
29141130e5b3SMark Brown 	debugfs_create_u32("use_count", 0444, rdev->debugfs,
29151130e5b3SMark Brown 			   &rdev->use_count);
29161130e5b3SMark Brown 	debugfs_create_u32("open_count", 0444, rdev->debugfs,
29171130e5b3SMark Brown 			   &rdev->open_count);
29181130e5b3SMark Brown }
29191130e5b3SMark Brown 
2920414c70cbSLiam Girdwood /**
2921414c70cbSLiam Girdwood  * regulator_register - register regulator
292269279fb9SMark Brown  * @regulator_desc: regulator to register
2923c172708dSMark Brown  * @config: runtime configuration for regulator
2924414c70cbSLiam Girdwood  *
2925414c70cbSLiam Girdwood  * Called by regulator drivers to register a regulator.
2926414c70cbSLiam Girdwood  * Returns 0 on success.
2927414c70cbSLiam Girdwood  */
292865f26846SMark Brown struct regulator_dev *
292965f26846SMark Brown regulator_register(const struct regulator_desc *regulator_desc,
2930c172708dSMark Brown 		   const struct regulator_config *config)
2931414c70cbSLiam Girdwood {
29329a8f5e07SMark Brown 	const struct regulation_constraints *constraints = NULL;
2933c172708dSMark Brown 	const struct regulator_init_data *init_data;
2934414c70cbSLiam Girdwood 	static atomic_t regulator_no = ATOMIC_INIT(0);
2935414c70cbSLiam Girdwood 	struct regulator_dev *rdev;
293632c8fad4SMark Brown 	struct device *dev;
2937a5766f11SLiam Girdwood 	int ret, i;
293869511a45SRajendra Nayak 	const char *supply = NULL;
2939414c70cbSLiam Girdwood 
2940c172708dSMark Brown 	if (regulator_desc == NULL || config == NULL)
2941414c70cbSLiam Girdwood 		return ERR_PTR(-EINVAL);
2942414c70cbSLiam Girdwood 
294332c8fad4SMark Brown 	dev = config->dev;
294432c8fad4SMark Brown 
2945414c70cbSLiam Girdwood 	if (regulator_desc->name == NULL || regulator_desc->ops == NULL)
2946414c70cbSLiam Girdwood 		return ERR_PTR(-EINVAL);
2947414c70cbSLiam Girdwood 
2948cd78dfc6SDiego Liziero 	if (regulator_desc->type != REGULATOR_VOLTAGE &&
2949cd78dfc6SDiego Liziero 	    regulator_desc->type != REGULATOR_CURRENT)
2950414c70cbSLiam Girdwood 		return ERR_PTR(-EINVAL);
2951414c70cbSLiam Girdwood 
2952476c2d83SMark Brown 	/* Only one of each should be implemented */
2953476c2d83SMark Brown 	WARN_ON(regulator_desc->ops->get_voltage &&
2954476c2d83SMark Brown 		regulator_desc->ops->get_voltage_sel);
2955e8eef82bSMark Brown 	WARN_ON(regulator_desc->ops->set_voltage &&
2956e8eef82bSMark Brown 		regulator_desc->ops->set_voltage_sel);
2957476c2d83SMark Brown 
2958476c2d83SMark Brown 	/* If we're using selectors we must implement list_voltage. */
2959476c2d83SMark Brown 	if (regulator_desc->ops->get_voltage_sel &&
2960476c2d83SMark Brown 	    !regulator_desc->ops->list_voltage) {
2961476c2d83SMark Brown 		return ERR_PTR(-EINVAL);
2962476c2d83SMark Brown 	}
2963e8eef82bSMark Brown 	if (regulator_desc->ops->set_voltage_sel &&
2964e8eef82bSMark Brown 	    !regulator_desc->ops->list_voltage) {
2965e8eef82bSMark Brown 		return ERR_PTR(-EINVAL);
2966e8eef82bSMark Brown 	}
2967476c2d83SMark Brown 
2968c172708dSMark Brown 	init_data = config->init_data;
2969c172708dSMark Brown 
2970414c70cbSLiam Girdwood 	rdev = kzalloc(sizeof(struct regulator_dev), GFP_KERNEL);
2971414c70cbSLiam Girdwood 	if (rdev == NULL)
2972414c70cbSLiam Girdwood 		return ERR_PTR(-ENOMEM);
2973414c70cbSLiam Girdwood 
2974414c70cbSLiam Girdwood 	mutex_lock(&regulator_list_mutex);
2975414c70cbSLiam Girdwood 
2976414c70cbSLiam Girdwood 	mutex_init(&rdev->mutex);
2977c172708dSMark Brown 	rdev->reg_data = config->driver_data;
2978414c70cbSLiam Girdwood 	rdev->owner = regulator_desc->owner;
2979414c70cbSLiam Girdwood 	rdev->desc = regulator_desc;
298065b19ce6SMark Brown 	rdev->regmap = config->regmap;
2981414c70cbSLiam Girdwood 	INIT_LIST_HEAD(&rdev->consumer_list);
2982414c70cbSLiam Girdwood 	INIT_LIST_HEAD(&rdev->list);
2983414c70cbSLiam Girdwood 	BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier);
2984da07ecd9SMark Brown 	INIT_DELAYED_WORK(&rdev->disable_work, regulator_disable_work);
2985414c70cbSLiam Girdwood 
2986a5766f11SLiam Girdwood 	/* preform any regulator specific init */
29879a8f5e07SMark Brown 	if (init_data && init_data->regulator_init) {
2988a5766f11SLiam Girdwood 		ret = init_data->regulator_init(rdev->reg_data);
29894fca9545SDavid Brownell 		if (ret < 0)
29904fca9545SDavid Brownell 			goto clean;
2991a5766f11SLiam Girdwood 	}
2992a5766f11SLiam Girdwood 
2993a5766f11SLiam Girdwood 	/* register with sysfs */
2994a5766f11SLiam Girdwood 	rdev->dev.class = &regulator_class;
2995c172708dSMark Brown 	rdev->dev.of_node = config->of_node;
2996a5766f11SLiam Girdwood 	rdev->dev.parent = dev;
2997812460a9SKay Sievers 	dev_set_name(&rdev->dev, "regulator.%d",
2998812460a9SKay Sievers 		     atomic_inc_return(&regulator_no) - 1);
2999a5766f11SLiam Girdwood 	ret = device_register(&rdev->dev);
3000ad7725cbSVasiliy Kulikov 	if (ret != 0) {
3001ad7725cbSVasiliy Kulikov 		put_device(&rdev->dev);
30024fca9545SDavid Brownell 		goto clean;
3003ad7725cbSVasiliy Kulikov 	}
3004a5766f11SLiam Girdwood 
3005a5766f11SLiam Girdwood 	dev_set_drvdata(&rdev->dev, rdev);
3006a5766f11SLiam Girdwood 
300774f544c1SMike Rapoport 	/* set regulator constraints */
30089a8f5e07SMark Brown 	if (init_data)
30099a8f5e07SMark Brown 		constraints = &init_data->constraints;
30109a8f5e07SMark Brown 
30119a8f5e07SMark Brown 	ret = set_machine_constraints(rdev, constraints);
301274f544c1SMike Rapoport 	if (ret < 0)
301374f544c1SMike Rapoport 		goto scrub;
301474f544c1SMike Rapoport 
30157ad68e2fSDavid Brownell 	/* add attributes supported by this regulator */
30167ad68e2fSDavid Brownell 	ret = add_regulator_attributes(rdev);
30177ad68e2fSDavid Brownell 	if (ret < 0)
30187ad68e2fSDavid Brownell 		goto scrub;
30197ad68e2fSDavid Brownell 
30209a8f5e07SMark Brown 	if (init_data && init_data->supply_regulator)
302169511a45SRajendra Nayak 		supply = init_data->supply_regulator;
302269511a45SRajendra Nayak 	else if (regulator_desc->supply_name)
302369511a45SRajendra Nayak 		supply = regulator_desc->supply_name;
302469511a45SRajendra Nayak 
302569511a45SRajendra Nayak 	if (supply) {
30260178f3e2SMark Brown 		struct regulator_dev *r;
30270178f3e2SMark Brown 
302869511a45SRajendra Nayak 		r = regulator_dev_lookup(dev, supply);
30290178f3e2SMark Brown 
303069511a45SRajendra Nayak 		if (!r) {
303169511a45SRajendra Nayak 			dev_err(dev, "Failed to find supply %s\n", supply);
303204bf3011SMark Brown 			ret = -EPROBE_DEFER;
30330178f3e2SMark Brown 			goto scrub;
30340178f3e2SMark Brown 		}
30350178f3e2SMark Brown 
30360178f3e2SMark Brown 		ret = set_supply(rdev, r);
30370178f3e2SMark Brown 		if (ret < 0)
30380178f3e2SMark Brown 			goto scrub;
3039b2296bd4SLaxman Dewangan 
3040b2296bd4SLaxman Dewangan 		/* Enable supply if rail is enabled */
3041b2296bd4SLaxman Dewangan 		if (rdev->desc->ops->is_enabled &&
3042b2296bd4SLaxman Dewangan 				rdev->desc->ops->is_enabled(rdev)) {
3043b2296bd4SLaxman Dewangan 			ret = regulator_enable(rdev->supply);
3044b2296bd4SLaxman Dewangan 			if (ret < 0)
3045b2296bd4SLaxman Dewangan 				goto scrub;
3046b2296bd4SLaxman Dewangan 		}
30470178f3e2SMark Brown 	}
30480178f3e2SMark Brown 
3049a5766f11SLiam Girdwood 	/* add consumers devices */
30509a8f5e07SMark Brown 	if (init_data) {
3051a5766f11SLiam Girdwood 		for (i = 0; i < init_data->num_consumer_supplies; i++) {
3052a5766f11SLiam Girdwood 			ret = set_consumer_device_supply(rdev,
305340f9244fSMark Brown 				init_data->consumer_supplies[i].dev_name,
3054a5766f11SLiam Girdwood 				init_data->consumer_supplies[i].supply);
305523c2f041SMark Brown 			if (ret < 0) {
305623c2f041SMark Brown 				dev_err(dev, "Failed to set supply %s\n",
305723c2f041SMark Brown 					init_data->consumer_supplies[i].supply);
3058d4033b54SJani Nikula 				goto unset_supplies;
3059a5766f11SLiam Girdwood 			}
306023c2f041SMark Brown 		}
30619a8f5e07SMark Brown 	}
3062a5766f11SLiam Girdwood 
3063a5766f11SLiam Girdwood 	list_add(&rdev->list, &regulator_list);
30641130e5b3SMark Brown 
30651130e5b3SMark Brown 	rdev_init_debugfs(rdev);
3066a5766f11SLiam Girdwood out:
3067414c70cbSLiam Girdwood 	mutex_unlock(&regulator_list_mutex);
3068414c70cbSLiam Girdwood 	return rdev;
30694fca9545SDavid Brownell 
3070d4033b54SJani Nikula unset_supplies:
3071d4033b54SJani Nikula 	unset_regulator_supplies(rdev);
3072d4033b54SJani Nikula 
30734fca9545SDavid Brownell scrub:
30741a6958e7SAxel Lin 	kfree(rdev->constraints);
30754fca9545SDavid Brownell 	device_unregister(&rdev->dev);
307653032dafSPaul Walmsley 	/* device core frees rdev */
307753032dafSPaul Walmsley 	rdev = ERR_PTR(ret);
307853032dafSPaul Walmsley 	goto out;
307953032dafSPaul Walmsley 
30804fca9545SDavid Brownell clean:
30814fca9545SDavid Brownell 	kfree(rdev);
30824fca9545SDavid Brownell 	rdev = ERR_PTR(ret);
30834fca9545SDavid Brownell 	goto out;
3084414c70cbSLiam Girdwood }
3085414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_register);
3086414c70cbSLiam Girdwood 
3087414c70cbSLiam Girdwood /**
3088414c70cbSLiam Girdwood  * regulator_unregister - unregister regulator
308969279fb9SMark Brown  * @rdev: regulator to unregister
3090414c70cbSLiam Girdwood  *
3091414c70cbSLiam Girdwood  * Called by regulator drivers to unregister a regulator.
3092414c70cbSLiam Girdwood  */
3093414c70cbSLiam Girdwood void regulator_unregister(struct regulator_dev *rdev)
3094414c70cbSLiam Girdwood {
3095414c70cbSLiam Girdwood 	if (rdev == NULL)
3096414c70cbSLiam Girdwood 		return;
3097414c70cbSLiam Girdwood 
3098e032b376SMark Brown 	if (rdev->supply)
3099e032b376SMark Brown 		regulator_put(rdev->supply);
3100414c70cbSLiam Girdwood 	mutex_lock(&regulator_list_mutex);
31011130e5b3SMark Brown 	debugfs_remove_recursive(rdev->debugfs);
3102da07ecd9SMark Brown 	flush_work_sync(&rdev->disable_work.work);
31036bf87d17SMark Brown 	WARN_ON(rdev->open_count);
31040f1d747bSMike Rapoport 	unset_regulator_supplies(rdev);
3105414c70cbSLiam Girdwood 	list_del(&rdev->list);
3106f8c12fe3SMark Brown 	kfree(rdev->constraints);
310758fb5cf5SLothar Waßmann 	device_unregister(&rdev->dev);
3108414c70cbSLiam Girdwood 	mutex_unlock(&regulator_list_mutex);
3109414c70cbSLiam Girdwood }
3110414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_unregister);
3111414c70cbSLiam Girdwood 
3112414c70cbSLiam Girdwood /**
3113cf7bbcdfSMark Brown  * regulator_suspend_prepare - prepare regulators for system wide suspend
3114414c70cbSLiam Girdwood  * @state: system suspend state
3115414c70cbSLiam Girdwood  *
3116414c70cbSLiam Girdwood  * Configure each regulator with it's suspend operating parameters for state.
3117414c70cbSLiam Girdwood  * This will usually be called by machine suspend code prior to supending.
3118414c70cbSLiam Girdwood  */
3119414c70cbSLiam Girdwood int regulator_suspend_prepare(suspend_state_t state)
3120414c70cbSLiam Girdwood {
3121414c70cbSLiam Girdwood 	struct regulator_dev *rdev;
3122414c70cbSLiam Girdwood 	int ret = 0;
3123414c70cbSLiam Girdwood 
3124414c70cbSLiam Girdwood 	/* ON is handled by regulator active state */
3125414c70cbSLiam Girdwood 	if (state == PM_SUSPEND_ON)
3126414c70cbSLiam Girdwood 		return -EINVAL;
3127414c70cbSLiam Girdwood 
3128414c70cbSLiam Girdwood 	mutex_lock(&regulator_list_mutex);
3129414c70cbSLiam Girdwood 	list_for_each_entry(rdev, &regulator_list, list) {
3130414c70cbSLiam Girdwood 
3131414c70cbSLiam Girdwood 		mutex_lock(&rdev->mutex);
3132414c70cbSLiam Girdwood 		ret = suspend_prepare(rdev, state);
3133414c70cbSLiam Girdwood 		mutex_unlock(&rdev->mutex);
3134414c70cbSLiam Girdwood 
3135414c70cbSLiam Girdwood 		if (ret < 0) {
31365da84fd9SJoe Perches 			rdev_err(rdev, "failed to prepare\n");
3137414c70cbSLiam Girdwood 			goto out;
3138414c70cbSLiam Girdwood 		}
3139414c70cbSLiam Girdwood 	}
3140414c70cbSLiam Girdwood out:
3141414c70cbSLiam Girdwood 	mutex_unlock(&regulator_list_mutex);
3142414c70cbSLiam Girdwood 	return ret;
3143414c70cbSLiam Girdwood }
3144414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_suspend_prepare);
3145414c70cbSLiam Girdwood 
3146414c70cbSLiam Girdwood /**
31477a32b589SMyungJoo Ham  * regulator_suspend_finish - resume regulators from system wide suspend
31487a32b589SMyungJoo Ham  *
31497a32b589SMyungJoo Ham  * Turn on regulators that might be turned off by regulator_suspend_prepare
31507a32b589SMyungJoo Ham  * and that should be turned on according to the regulators properties.
31517a32b589SMyungJoo Ham  */
31527a32b589SMyungJoo Ham int regulator_suspend_finish(void)
31537a32b589SMyungJoo Ham {
31547a32b589SMyungJoo Ham 	struct regulator_dev *rdev;
31557a32b589SMyungJoo Ham 	int ret = 0, error;
31567a32b589SMyungJoo Ham 
31577a32b589SMyungJoo Ham 	mutex_lock(&regulator_list_mutex);
31587a32b589SMyungJoo Ham 	list_for_each_entry(rdev, &regulator_list, list) {
31597a32b589SMyungJoo Ham 		struct regulator_ops *ops = rdev->desc->ops;
31607a32b589SMyungJoo Ham 
31617a32b589SMyungJoo Ham 		mutex_lock(&rdev->mutex);
31627a32b589SMyungJoo Ham 		if ((rdev->use_count > 0  || rdev->constraints->always_on) &&
31637a32b589SMyungJoo Ham 				ops->enable) {
31647a32b589SMyungJoo Ham 			error = ops->enable(rdev);
31657a32b589SMyungJoo Ham 			if (error)
31667a32b589SMyungJoo Ham 				ret = error;
31677a32b589SMyungJoo Ham 		} else {
31687a32b589SMyungJoo Ham 			if (!has_full_constraints)
31697a32b589SMyungJoo Ham 				goto unlock;
31707a32b589SMyungJoo Ham 			if (!ops->disable)
31717a32b589SMyungJoo Ham 				goto unlock;
31727a32b589SMyungJoo Ham 			if (ops->is_enabled && !ops->is_enabled(rdev))
31737a32b589SMyungJoo Ham 				goto unlock;
31747a32b589SMyungJoo Ham 
31757a32b589SMyungJoo Ham 			error = ops->disable(rdev);
31767a32b589SMyungJoo Ham 			if (error)
31777a32b589SMyungJoo Ham 				ret = error;
31787a32b589SMyungJoo Ham 		}
31797a32b589SMyungJoo Ham unlock:
31807a32b589SMyungJoo Ham 		mutex_unlock(&rdev->mutex);
31817a32b589SMyungJoo Ham 	}
31827a32b589SMyungJoo Ham 	mutex_unlock(&regulator_list_mutex);
31837a32b589SMyungJoo Ham 	return ret;
31847a32b589SMyungJoo Ham }
31857a32b589SMyungJoo Ham EXPORT_SYMBOL_GPL(regulator_suspend_finish);
31867a32b589SMyungJoo Ham 
31877a32b589SMyungJoo Ham /**
3188ca725561SMark Brown  * regulator_has_full_constraints - the system has fully specified constraints
3189ca725561SMark Brown  *
3190ca725561SMark Brown  * Calling this function will cause the regulator API to disable all
3191ca725561SMark Brown  * regulators which have a zero use count and don't have an always_on
3192ca725561SMark Brown  * constraint in a late_initcall.
3193ca725561SMark Brown  *
3194ca725561SMark Brown  * The intention is that this will become the default behaviour in a
3195ca725561SMark Brown  * future kernel release so users are encouraged to use this facility
3196ca725561SMark Brown  * now.
3197ca725561SMark Brown  */
3198ca725561SMark Brown void regulator_has_full_constraints(void)
3199ca725561SMark Brown {
3200ca725561SMark Brown 	has_full_constraints = 1;
3201ca725561SMark Brown }
3202ca725561SMark Brown EXPORT_SYMBOL_GPL(regulator_has_full_constraints);
3203ca725561SMark Brown 
3204ca725561SMark Brown /**
3205688fe99aSMark Brown  * regulator_use_dummy_regulator - Provide a dummy regulator when none is found
3206688fe99aSMark Brown  *
3207688fe99aSMark Brown  * Calling this function will cause the regulator API to provide a
3208688fe99aSMark Brown  * dummy regulator to consumers if no physical regulator is found,
3209688fe99aSMark Brown  * allowing most consumers to proceed as though a regulator were
3210688fe99aSMark Brown  * configured.  This allows systems such as those with software
3211688fe99aSMark Brown  * controllable regulators for the CPU core only to be brought up more
3212688fe99aSMark Brown  * readily.
3213688fe99aSMark Brown  */
3214688fe99aSMark Brown void regulator_use_dummy_regulator(void)
3215688fe99aSMark Brown {
3216688fe99aSMark Brown 	board_wants_dummy_regulator = true;
3217688fe99aSMark Brown }
3218688fe99aSMark Brown EXPORT_SYMBOL_GPL(regulator_use_dummy_regulator);
3219688fe99aSMark Brown 
3220688fe99aSMark Brown /**
3221414c70cbSLiam Girdwood  * rdev_get_drvdata - get rdev regulator driver data
322269279fb9SMark Brown  * @rdev: regulator
3223414c70cbSLiam Girdwood  *
3224414c70cbSLiam Girdwood  * Get rdev regulator driver private data. This call can be used in the
3225414c70cbSLiam Girdwood  * regulator driver context.
3226414c70cbSLiam Girdwood  */
3227414c70cbSLiam Girdwood void *rdev_get_drvdata(struct regulator_dev *rdev)
3228414c70cbSLiam Girdwood {
3229414c70cbSLiam Girdwood 	return rdev->reg_data;
3230414c70cbSLiam Girdwood }
3231414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(rdev_get_drvdata);
3232414c70cbSLiam Girdwood 
3233414c70cbSLiam Girdwood /**
3234414c70cbSLiam Girdwood  * regulator_get_drvdata - get regulator driver data
3235414c70cbSLiam Girdwood  * @regulator: regulator
3236414c70cbSLiam Girdwood  *
3237414c70cbSLiam Girdwood  * Get regulator driver private data. This call can be used in the consumer
3238414c70cbSLiam Girdwood  * driver context when non API regulator specific functions need to be called.
3239414c70cbSLiam Girdwood  */
3240414c70cbSLiam Girdwood void *regulator_get_drvdata(struct regulator *regulator)
3241414c70cbSLiam Girdwood {
3242414c70cbSLiam Girdwood 	return regulator->rdev->reg_data;
3243414c70cbSLiam Girdwood }
3244414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_get_drvdata);
3245414c70cbSLiam Girdwood 
3246414c70cbSLiam Girdwood /**
3247414c70cbSLiam Girdwood  * regulator_set_drvdata - set regulator driver data
3248414c70cbSLiam Girdwood  * @regulator: regulator
3249414c70cbSLiam Girdwood  * @data: data
3250414c70cbSLiam Girdwood  */
3251414c70cbSLiam Girdwood void regulator_set_drvdata(struct regulator *regulator, void *data)
3252414c70cbSLiam Girdwood {
3253414c70cbSLiam Girdwood 	regulator->rdev->reg_data = data;
3254414c70cbSLiam Girdwood }
3255414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_set_drvdata);
3256414c70cbSLiam Girdwood 
3257414c70cbSLiam Girdwood /**
3258414c70cbSLiam Girdwood  * regulator_get_id - get regulator ID
325969279fb9SMark Brown  * @rdev: regulator
3260414c70cbSLiam Girdwood  */
3261414c70cbSLiam Girdwood int rdev_get_id(struct regulator_dev *rdev)
3262414c70cbSLiam Girdwood {
3263414c70cbSLiam Girdwood 	return rdev->desc->id;
3264414c70cbSLiam Girdwood }
3265414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(rdev_get_id);
3266414c70cbSLiam Girdwood 
3267a5766f11SLiam Girdwood struct device *rdev_get_dev(struct regulator_dev *rdev)
3268a5766f11SLiam Girdwood {
3269a5766f11SLiam Girdwood 	return &rdev->dev;
3270a5766f11SLiam Girdwood }
3271a5766f11SLiam Girdwood EXPORT_SYMBOL_GPL(rdev_get_dev);
3272a5766f11SLiam Girdwood 
3273a5766f11SLiam Girdwood void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data)
3274a5766f11SLiam Girdwood {
3275a5766f11SLiam Girdwood 	return reg_init_data->driver_data;
3276a5766f11SLiam Girdwood }
3277a5766f11SLiam Girdwood EXPORT_SYMBOL_GPL(regulator_get_init_drvdata);
3278a5766f11SLiam Girdwood 
3279ba55a974SMark Brown #ifdef CONFIG_DEBUG_FS
3280ba55a974SMark Brown static ssize_t supply_map_read_file(struct file *file, char __user *user_buf,
3281ba55a974SMark Brown 				    size_t count, loff_t *ppos)
3282ba55a974SMark Brown {
3283ba55a974SMark Brown 	char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
3284ba55a974SMark Brown 	ssize_t len, ret = 0;
3285ba55a974SMark Brown 	struct regulator_map *map;
3286ba55a974SMark Brown 
3287ba55a974SMark Brown 	if (!buf)
3288ba55a974SMark Brown 		return -ENOMEM;
3289ba55a974SMark Brown 
3290ba55a974SMark Brown 	list_for_each_entry(map, &regulator_map_list, list) {
3291ba55a974SMark Brown 		len = snprintf(buf + ret, PAGE_SIZE - ret,
3292ba55a974SMark Brown 			       "%s -> %s.%s\n",
3293ba55a974SMark Brown 			       rdev_get_name(map->regulator), map->dev_name,
3294ba55a974SMark Brown 			       map->supply);
3295ba55a974SMark Brown 		if (len >= 0)
3296ba55a974SMark Brown 			ret += len;
3297ba55a974SMark Brown 		if (ret > PAGE_SIZE) {
3298ba55a974SMark Brown 			ret = PAGE_SIZE;
3299ba55a974SMark Brown 			break;
3300ba55a974SMark Brown 		}
3301ba55a974SMark Brown 	}
3302ba55a974SMark Brown 
3303ba55a974SMark Brown 	ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
3304ba55a974SMark Brown 
3305ba55a974SMark Brown 	kfree(buf);
3306ba55a974SMark Brown 
3307ba55a974SMark Brown 	return ret;
3308ba55a974SMark Brown }
330924751434SStephen Boyd #endif
3310ba55a974SMark Brown 
3311ba55a974SMark Brown static const struct file_operations supply_map_fops = {
331224751434SStephen Boyd #ifdef CONFIG_DEBUG_FS
3313ba55a974SMark Brown 	.read = supply_map_read_file,
3314ba55a974SMark Brown 	.llseek = default_llseek,
3315ba55a974SMark Brown #endif
331624751434SStephen Boyd };
3317ba55a974SMark Brown 
3318414c70cbSLiam Girdwood static int __init regulator_init(void)
3319414c70cbSLiam Girdwood {
332034abbd68SMark Brown 	int ret;
332134abbd68SMark Brown 
332234abbd68SMark Brown 	ret = class_register(&regulator_class);
332334abbd68SMark Brown 
33241130e5b3SMark Brown 	debugfs_root = debugfs_create_dir("regulator", NULL);
332524751434SStephen Boyd 	if (!debugfs_root)
33261130e5b3SMark Brown 		pr_warn("regulator: Failed to create debugfs directory\n");
3327ba55a974SMark Brown 
3328f4d562c6SMark Brown 	debugfs_create_file("supply_map", 0444, debugfs_root, NULL,
3329f4d562c6SMark Brown 			    &supply_map_fops);
33301130e5b3SMark Brown 
333134abbd68SMark Brown 	regulator_dummy_init();
333234abbd68SMark Brown 
333334abbd68SMark Brown 	return ret;
3334414c70cbSLiam Girdwood }
3335414c70cbSLiam Girdwood 
3336414c70cbSLiam Girdwood /* init early to allow our consumers to complete system booting */
3337414c70cbSLiam Girdwood core_initcall(regulator_init);
3338ca725561SMark Brown 
3339ca725561SMark Brown static int __init regulator_init_complete(void)
3340ca725561SMark Brown {
3341ca725561SMark Brown 	struct regulator_dev *rdev;
3342ca725561SMark Brown 	struct regulator_ops *ops;
3343ca725561SMark Brown 	struct regulation_constraints *c;
3344ca725561SMark Brown 	int enabled, ret;
3345ca725561SMark Brown 
3346ca725561SMark Brown 	mutex_lock(&regulator_list_mutex);
3347ca725561SMark Brown 
3348ca725561SMark Brown 	/* If we have a full configuration then disable any regulators
3349ca725561SMark Brown 	 * which are not in use or always_on.  This will become the
3350ca725561SMark Brown 	 * default behaviour in the future.
3351ca725561SMark Brown 	 */
3352ca725561SMark Brown 	list_for_each_entry(rdev, &regulator_list, list) {
3353ca725561SMark Brown 		ops = rdev->desc->ops;
3354ca725561SMark Brown 		c = rdev->constraints;
3355ca725561SMark Brown 
3356f25e0b4fSMark Brown 		if (!ops->disable || (c && c->always_on))
3357ca725561SMark Brown 			continue;
3358ca725561SMark Brown 
3359ca725561SMark Brown 		mutex_lock(&rdev->mutex);
3360ca725561SMark Brown 
3361ca725561SMark Brown 		if (rdev->use_count)
3362ca725561SMark Brown 			goto unlock;
3363ca725561SMark Brown 
3364ca725561SMark Brown 		/* If we can't read the status assume it's on. */
3365ca725561SMark Brown 		if (ops->is_enabled)
3366ca725561SMark Brown 			enabled = ops->is_enabled(rdev);
3367ca725561SMark Brown 		else
3368ca725561SMark Brown 			enabled = 1;
3369ca725561SMark Brown 
3370ca725561SMark Brown 		if (!enabled)
3371ca725561SMark Brown 			goto unlock;
3372ca725561SMark Brown 
3373ca725561SMark Brown 		if (has_full_constraints) {
3374ca725561SMark Brown 			/* We log since this may kill the system if it
3375ca725561SMark Brown 			 * goes wrong. */
33765da84fd9SJoe Perches 			rdev_info(rdev, "disabling\n");
3377ca725561SMark Brown 			ret = ops->disable(rdev);
3378ca725561SMark Brown 			if (ret != 0) {
33795da84fd9SJoe Perches 				rdev_err(rdev, "couldn't disable: %d\n", ret);
3380ca725561SMark Brown 			}
3381ca725561SMark Brown 		} else {
3382ca725561SMark Brown 			/* The intention is that in future we will
3383ca725561SMark Brown 			 * assume that full constraints are provided
3384ca725561SMark Brown 			 * so warn even if we aren't going to do
3385ca725561SMark Brown 			 * anything here.
3386ca725561SMark Brown 			 */
33875da84fd9SJoe Perches 			rdev_warn(rdev, "incomplete constraints, leaving on\n");
3388ca725561SMark Brown 		}
3389ca725561SMark Brown 
3390ca725561SMark Brown unlock:
3391ca725561SMark Brown 		mutex_unlock(&rdev->mutex);
3392ca725561SMark Brown 	}
3393ca725561SMark Brown 
3394ca725561SMark Brown 	mutex_unlock(&regulator_list_mutex);
3395ca725561SMark Brown 
3396ca725561SMark Brown 	return 0;
3397ca725561SMark Brown }
3398ca725561SMark Brown late_initcall(regulator_init_complete);
3399