xref: /openbmc/linux/drivers/regulator/core.c (revision 070260f0)
1414c70cbSLiam Girdwood /*
2414c70cbSLiam Girdwood  * core.c  --  Voltage/Current Regulator framework.
3414c70cbSLiam Girdwood  *
4414c70cbSLiam Girdwood  * Copyright 2007, 2008 Wolfson Microelectronics PLC.
5a5766f11SLiam Girdwood  * Copyright 2008 SlimLogic Ltd.
6414c70cbSLiam Girdwood  *
7a5766f11SLiam Girdwood  * Author: Liam Girdwood <lrg@slimlogic.co.uk>
8414c70cbSLiam Girdwood  *
9414c70cbSLiam Girdwood  *  This program is free software; you can redistribute  it and/or modify it
10414c70cbSLiam Girdwood  *  under  the terms of  the GNU General  Public License as published by the
11414c70cbSLiam Girdwood  *  Free Software Foundation;  either version 2 of the  License, or (at your
12414c70cbSLiam Girdwood  *  option) any later version.
13414c70cbSLiam Girdwood  *
14414c70cbSLiam Girdwood  */
15414c70cbSLiam Girdwood 
16414c70cbSLiam Girdwood #include <linux/kernel.h>
17414c70cbSLiam Girdwood #include <linux/init.h>
181130e5b3SMark Brown #include <linux/debugfs.h>
19414c70cbSLiam Girdwood #include <linux/device.h>
205a0e3ad6STejun Heo #include <linux/slab.h>
21f21e0e81SMark Brown #include <linux/async.h>
22414c70cbSLiam Girdwood #include <linux/err.h>
23414c70cbSLiam Girdwood #include <linux/mutex.h>
24414c70cbSLiam Girdwood #include <linux/suspend.h>
2531aae2beSMark Brown #include <linux/delay.h>
2665f73508SMark Brown #include <linux/gpio.h>
2769511a45SRajendra Nayak #include <linux/of.h>
2865b19ce6SMark Brown #include <linux/regmap.h>
2969511a45SRajendra Nayak #include <linux/regulator/of_regulator.h>
30414c70cbSLiam Girdwood #include <linux/regulator/consumer.h>
31414c70cbSLiam Girdwood #include <linux/regulator/driver.h>
32414c70cbSLiam Girdwood #include <linux/regulator/machine.h>
3365602c32SPaul Gortmaker #include <linux/module.h>
34414c70cbSLiam Girdwood 
3502fa3ec0SMark Brown #define CREATE_TRACE_POINTS
3602fa3ec0SMark Brown #include <trace/events/regulator.h>
3702fa3ec0SMark Brown 
3834abbd68SMark Brown #include "dummy.h"
3934abbd68SMark Brown 
407d51a0dbSMark Brown #define rdev_crit(rdev, fmt, ...)					\
417d51a0dbSMark Brown 	pr_crit("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
425da84fd9SJoe Perches #define rdev_err(rdev, fmt, ...)					\
435da84fd9SJoe Perches 	pr_err("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
445da84fd9SJoe Perches #define rdev_warn(rdev, fmt, ...)					\
455da84fd9SJoe Perches 	pr_warn("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
465da84fd9SJoe Perches #define rdev_info(rdev, fmt, ...)					\
475da84fd9SJoe Perches 	pr_info("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
485da84fd9SJoe Perches #define rdev_dbg(rdev, fmt, ...)					\
495da84fd9SJoe Perches 	pr_debug("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
505da84fd9SJoe Perches 
51414c70cbSLiam Girdwood static DEFINE_MUTEX(regulator_list_mutex);
52414c70cbSLiam Girdwood static LIST_HEAD(regulator_list);
53414c70cbSLiam Girdwood static LIST_HEAD(regulator_map_list);
54f19b00daSKim, Milo static LIST_HEAD(regulator_ena_gpio_list);
5521cf891aSMark Brown static bool has_full_constraints;
56688fe99aSMark Brown static bool board_wants_dummy_regulator;
57414c70cbSLiam Girdwood 
581130e5b3SMark Brown static struct dentry *debugfs_root;
591130e5b3SMark Brown 
608dc5390dSMark Brown /*
61414c70cbSLiam Girdwood  * struct regulator_map
62414c70cbSLiam Girdwood  *
63414c70cbSLiam Girdwood  * Used to provide symbolic supply names to devices.
64414c70cbSLiam Girdwood  */
65414c70cbSLiam Girdwood struct regulator_map {
66414c70cbSLiam Girdwood 	struct list_head list;
6740f9244fSMark Brown 	const char *dev_name;   /* The dev_name() for the consumer */
68414c70cbSLiam Girdwood 	const char *supply;
69a5766f11SLiam Girdwood 	struct regulator_dev *regulator;
70414c70cbSLiam Girdwood };
71414c70cbSLiam Girdwood 
72414c70cbSLiam Girdwood /*
73f19b00daSKim, Milo  * struct regulator_enable_gpio
74f19b00daSKim, Milo  *
75f19b00daSKim, Milo  * Management for shared enable GPIO pin
76f19b00daSKim, Milo  */
77f19b00daSKim, Milo struct regulator_enable_gpio {
78f19b00daSKim, Milo 	struct list_head list;
79f19b00daSKim, Milo 	int gpio;
80f19b00daSKim, Milo 	u32 enable_count;	/* a number of enabled shared GPIO */
81f19b00daSKim, Milo 	u32 request_count;	/* a number of requested shared GPIO */
82f19b00daSKim, Milo 	unsigned int ena_gpio_invert:1;
83f19b00daSKim, Milo };
84f19b00daSKim, Milo 
85f19b00daSKim, Milo /*
86414c70cbSLiam Girdwood  * struct regulator
87414c70cbSLiam Girdwood  *
88414c70cbSLiam Girdwood  * One for each consumer device.
89414c70cbSLiam Girdwood  */
90414c70cbSLiam Girdwood struct regulator {
91414c70cbSLiam Girdwood 	struct device *dev;
92414c70cbSLiam Girdwood 	struct list_head list;
936492bc1bSMark Brown 	unsigned int always_on:1;
94f59c8f9fSMark Brown 	unsigned int bypass:1;
95414c70cbSLiam Girdwood 	int uA_load;
96414c70cbSLiam Girdwood 	int min_uV;
97414c70cbSLiam Girdwood 	int max_uV;
98414c70cbSLiam Girdwood 	char *supply_name;
99414c70cbSLiam Girdwood 	struct device_attribute dev_attr;
100414c70cbSLiam Girdwood 	struct regulator_dev *rdev;
1015de70519SMark Brown 	struct dentry *debugfs;
102414c70cbSLiam Girdwood };
103414c70cbSLiam Girdwood 
104414c70cbSLiam Girdwood static int _regulator_is_enabled(struct regulator_dev *rdev);
1053801b86aSMark Brown static int _regulator_disable(struct regulator_dev *rdev);
106414c70cbSLiam Girdwood static int _regulator_get_voltage(struct regulator_dev *rdev);
107414c70cbSLiam Girdwood static int _regulator_get_current_limit(struct regulator_dev *rdev);
108414c70cbSLiam Girdwood static unsigned int _regulator_get_mode(struct regulator_dev *rdev);
109414c70cbSLiam Girdwood static void _notifier_call_chain(struct regulator_dev *rdev,
110414c70cbSLiam Girdwood 				  unsigned long event, void *data);
11175790251SMark Brown static int _regulator_do_set_voltage(struct regulator_dev *rdev,
11275790251SMark Brown 				     int min_uV, int max_uV);
1133801b86aSMark Brown static struct regulator *create_regulator(struct regulator_dev *rdev,
1143801b86aSMark Brown 					  struct device *dev,
1153801b86aSMark Brown 					  const char *supply_name);
116414c70cbSLiam Girdwood 
1171083c393SMark Brown static const char *rdev_get_name(struct regulator_dev *rdev)
1181083c393SMark Brown {
1191083c393SMark Brown 	if (rdev->constraints && rdev->constraints->name)
1201083c393SMark Brown 		return rdev->constraints->name;
1211083c393SMark Brown 	else if (rdev->desc->name)
1221083c393SMark Brown 		return rdev->desc->name;
1231083c393SMark Brown 	else
1241083c393SMark Brown 		return "";
1251083c393SMark Brown }
1261083c393SMark Brown 
12769511a45SRajendra Nayak /**
12869511a45SRajendra Nayak  * of_get_regulator - get a regulator device node based on supply name
12969511a45SRajendra Nayak  * @dev: Device pointer for the consumer (of regulator) device
13069511a45SRajendra Nayak  * @supply: regulator supply name
13169511a45SRajendra Nayak  *
13269511a45SRajendra Nayak  * Extract the regulator device node corresponding to the supply name.
133167d41dcSMaxime Ripard  * returns the device node corresponding to the regulator if found, else
13469511a45SRajendra Nayak  * returns NULL.
13569511a45SRajendra Nayak  */
13669511a45SRajendra Nayak static struct device_node *of_get_regulator(struct device *dev, const char *supply)
13769511a45SRajendra Nayak {
13869511a45SRajendra Nayak 	struct device_node *regnode = NULL;
13969511a45SRajendra Nayak 	char prop_name[32]; /* 32 is max size of property name */
14069511a45SRajendra Nayak 
14169511a45SRajendra Nayak 	dev_dbg(dev, "Looking up %s-supply from device tree\n", supply);
14269511a45SRajendra Nayak 
14369511a45SRajendra Nayak 	snprintf(prop_name, 32, "%s-supply", supply);
14469511a45SRajendra Nayak 	regnode = of_parse_phandle(dev->of_node, prop_name, 0);
14569511a45SRajendra Nayak 
14669511a45SRajendra Nayak 	if (!regnode) {
14716fbcc3bSRajendra Nayak 		dev_dbg(dev, "Looking up %s property in node %s failed",
14869511a45SRajendra Nayak 				prop_name, dev->of_node->full_name);
14969511a45SRajendra Nayak 		return NULL;
15069511a45SRajendra Nayak 	}
15169511a45SRajendra Nayak 	return regnode;
15269511a45SRajendra Nayak }
15369511a45SRajendra Nayak 
1546492bc1bSMark Brown static int _regulator_can_change_status(struct regulator_dev *rdev)
1556492bc1bSMark Brown {
1566492bc1bSMark Brown 	if (!rdev->constraints)
1576492bc1bSMark Brown 		return 0;
1586492bc1bSMark Brown 
1596492bc1bSMark Brown 	if (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_STATUS)
1606492bc1bSMark Brown 		return 1;
1616492bc1bSMark Brown 	else
1626492bc1bSMark Brown 		return 0;
1636492bc1bSMark Brown }
1646492bc1bSMark Brown 
165414c70cbSLiam Girdwood /* Platform voltage constraint check */
166414c70cbSLiam Girdwood static int regulator_check_voltage(struct regulator_dev *rdev,
167414c70cbSLiam Girdwood 				   int *min_uV, int *max_uV)
168414c70cbSLiam Girdwood {
169414c70cbSLiam Girdwood 	BUG_ON(*min_uV > *max_uV);
170414c70cbSLiam Girdwood 
171414c70cbSLiam Girdwood 	if (!rdev->constraints) {
1725da84fd9SJoe Perches 		rdev_err(rdev, "no constraints\n");
173414c70cbSLiam Girdwood 		return -ENODEV;
174414c70cbSLiam Girdwood 	}
175414c70cbSLiam Girdwood 	if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) {
1765da84fd9SJoe Perches 		rdev_err(rdev, "operation not allowed\n");
177414c70cbSLiam Girdwood 		return -EPERM;
178414c70cbSLiam Girdwood 	}
179414c70cbSLiam Girdwood 
180414c70cbSLiam Girdwood 	if (*max_uV > rdev->constraints->max_uV)
181414c70cbSLiam Girdwood 		*max_uV = rdev->constraints->max_uV;
182414c70cbSLiam Girdwood 	if (*min_uV < rdev->constraints->min_uV)
183414c70cbSLiam Girdwood 		*min_uV = rdev->constraints->min_uV;
184414c70cbSLiam Girdwood 
18589f425edSMark Brown 	if (*min_uV > *max_uV) {
18689f425edSMark Brown 		rdev_err(rdev, "unsupportable voltage range: %d-%duV\n",
18754abd335SMark Brown 			 *min_uV, *max_uV);
188414c70cbSLiam Girdwood 		return -EINVAL;
18989f425edSMark Brown 	}
190414c70cbSLiam Girdwood 
191414c70cbSLiam Girdwood 	return 0;
192414c70cbSLiam Girdwood }
193414c70cbSLiam Girdwood 
19405fda3b1SThomas Petazzoni /* Make sure we select a voltage that suits the needs of all
19505fda3b1SThomas Petazzoni  * regulator consumers
19605fda3b1SThomas Petazzoni  */
19705fda3b1SThomas Petazzoni static int regulator_check_consumers(struct regulator_dev *rdev,
19805fda3b1SThomas Petazzoni 				     int *min_uV, int *max_uV)
19905fda3b1SThomas Petazzoni {
20005fda3b1SThomas Petazzoni 	struct regulator *regulator;
20105fda3b1SThomas Petazzoni 
20205fda3b1SThomas Petazzoni 	list_for_each_entry(regulator, &rdev->consumer_list, list) {
2034aa922c0SMark Brown 		/*
2044aa922c0SMark Brown 		 * Assume consumers that didn't say anything are OK
2054aa922c0SMark Brown 		 * with anything in the constraint range.
2064aa922c0SMark Brown 		 */
2074aa922c0SMark Brown 		if (!regulator->min_uV && !regulator->max_uV)
2084aa922c0SMark Brown 			continue;
2094aa922c0SMark Brown 
21005fda3b1SThomas Petazzoni 		if (*max_uV > regulator->max_uV)
21105fda3b1SThomas Petazzoni 			*max_uV = regulator->max_uV;
21205fda3b1SThomas Petazzoni 		if (*min_uV < regulator->min_uV)
21305fda3b1SThomas Petazzoni 			*min_uV = regulator->min_uV;
21405fda3b1SThomas Petazzoni 	}
21505fda3b1SThomas Petazzoni 
216dd8004afSMark Brown 	if (*min_uV > *max_uV) {
2179c7b4e8aSRuss Dill 		rdev_err(rdev, "Restricting voltage, %u-%uuV\n",
2189c7b4e8aSRuss Dill 			*min_uV, *max_uV);
21905fda3b1SThomas Petazzoni 		return -EINVAL;
220dd8004afSMark Brown 	}
22105fda3b1SThomas Petazzoni 
22205fda3b1SThomas Petazzoni 	return 0;
22305fda3b1SThomas Petazzoni }
22405fda3b1SThomas Petazzoni 
225414c70cbSLiam Girdwood /* current constraint check */
226414c70cbSLiam Girdwood static int regulator_check_current_limit(struct regulator_dev *rdev,
227414c70cbSLiam Girdwood 					int *min_uA, int *max_uA)
228414c70cbSLiam Girdwood {
229414c70cbSLiam Girdwood 	BUG_ON(*min_uA > *max_uA);
230414c70cbSLiam Girdwood 
231414c70cbSLiam Girdwood 	if (!rdev->constraints) {
2325da84fd9SJoe Perches 		rdev_err(rdev, "no constraints\n");
233414c70cbSLiam Girdwood 		return -ENODEV;
234414c70cbSLiam Girdwood 	}
235414c70cbSLiam Girdwood 	if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_CURRENT)) {
2365da84fd9SJoe Perches 		rdev_err(rdev, "operation not allowed\n");
237414c70cbSLiam Girdwood 		return -EPERM;
238414c70cbSLiam Girdwood 	}
239414c70cbSLiam Girdwood 
240414c70cbSLiam Girdwood 	if (*max_uA > rdev->constraints->max_uA)
241414c70cbSLiam Girdwood 		*max_uA = rdev->constraints->max_uA;
242414c70cbSLiam Girdwood 	if (*min_uA < rdev->constraints->min_uA)
243414c70cbSLiam Girdwood 		*min_uA = rdev->constraints->min_uA;
244414c70cbSLiam Girdwood 
24589f425edSMark Brown 	if (*min_uA > *max_uA) {
24689f425edSMark Brown 		rdev_err(rdev, "unsupportable current range: %d-%duA\n",
24754abd335SMark Brown 			 *min_uA, *max_uA);
248414c70cbSLiam Girdwood 		return -EINVAL;
24989f425edSMark Brown 	}
250414c70cbSLiam Girdwood 
251414c70cbSLiam Girdwood 	return 0;
252414c70cbSLiam Girdwood }
253414c70cbSLiam Girdwood 
254414c70cbSLiam Girdwood /* operating mode constraint check */
2552c608234SMark Brown static int regulator_mode_constrain(struct regulator_dev *rdev, int *mode)
256414c70cbSLiam Girdwood {
2572c608234SMark Brown 	switch (*mode) {
258e573520bSDavid Brownell 	case REGULATOR_MODE_FAST:
259e573520bSDavid Brownell 	case REGULATOR_MODE_NORMAL:
260e573520bSDavid Brownell 	case REGULATOR_MODE_IDLE:
261e573520bSDavid Brownell 	case REGULATOR_MODE_STANDBY:
262e573520bSDavid Brownell 		break;
263e573520bSDavid Brownell 	default:
26489f425edSMark Brown 		rdev_err(rdev, "invalid mode %x specified\n", *mode);
265e573520bSDavid Brownell 		return -EINVAL;
266e573520bSDavid Brownell 	}
267e573520bSDavid Brownell 
268414c70cbSLiam Girdwood 	if (!rdev->constraints) {
2695da84fd9SJoe Perches 		rdev_err(rdev, "no constraints\n");
270414c70cbSLiam Girdwood 		return -ENODEV;
271414c70cbSLiam Girdwood 	}
272414c70cbSLiam Girdwood 	if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_MODE)) {
2735da84fd9SJoe Perches 		rdev_err(rdev, "operation not allowed\n");
274414c70cbSLiam Girdwood 		return -EPERM;
275414c70cbSLiam Girdwood 	}
2762c608234SMark Brown 
2772c608234SMark Brown 	/* The modes are bitmasks, the most power hungry modes having
2782c608234SMark Brown 	 * the lowest values. If the requested mode isn't supported
2792c608234SMark Brown 	 * try higher modes. */
2802c608234SMark Brown 	while (*mode) {
2812c608234SMark Brown 		if (rdev->constraints->valid_modes_mask & *mode)
282414c70cbSLiam Girdwood 			return 0;
2832c608234SMark Brown 		*mode /= 2;
2842c608234SMark Brown 	}
2852c608234SMark Brown 
2862c608234SMark Brown 	return -EINVAL;
287414c70cbSLiam Girdwood }
288414c70cbSLiam Girdwood 
289414c70cbSLiam Girdwood /* dynamic regulator mode switching constraint check */
290414c70cbSLiam Girdwood static int regulator_check_drms(struct regulator_dev *rdev)
291414c70cbSLiam Girdwood {
292414c70cbSLiam Girdwood 	if (!rdev->constraints) {
2935da84fd9SJoe Perches 		rdev_err(rdev, "no constraints\n");
294414c70cbSLiam Girdwood 		return -ENODEV;
295414c70cbSLiam Girdwood 	}
296414c70cbSLiam Girdwood 	if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS)) {
2975da84fd9SJoe Perches 		rdev_err(rdev, "operation not allowed\n");
298414c70cbSLiam Girdwood 		return -EPERM;
299414c70cbSLiam Girdwood 	}
300414c70cbSLiam Girdwood 	return 0;
301414c70cbSLiam Girdwood }
302414c70cbSLiam Girdwood 
303414c70cbSLiam Girdwood static ssize_t regulator_uV_show(struct device *dev,
304414c70cbSLiam Girdwood 				struct device_attribute *attr, char *buf)
305414c70cbSLiam Girdwood {
306a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
307414c70cbSLiam Girdwood 	ssize_t ret;
308414c70cbSLiam Girdwood 
309414c70cbSLiam Girdwood 	mutex_lock(&rdev->mutex);
310414c70cbSLiam Girdwood 	ret = sprintf(buf, "%d\n", _regulator_get_voltage(rdev));
311414c70cbSLiam Girdwood 	mutex_unlock(&rdev->mutex);
312414c70cbSLiam Girdwood 
313414c70cbSLiam Girdwood 	return ret;
314414c70cbSLiam Girdwood }
3157ad68e2fSDavid Brownell static DEVICE_ATTR(microvolts, 0444, regulator_uV_show, NULL);
316414c70cbSLiam Girdwood 
317414c70cbSLiam Girdwood static ssize_t regulator_uA_show(struct device *dev,
318414c70cbSLiam Girdwood 				struct device_attribute *attr, char *buf)
319414c70cbSLiam Girdwood {
320a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
321414c70cbSLiam Girdwood 
322414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", _regulator_get_current_limit(rdev));
323414c70cbSLiam Girdwood }
3247ad68e2fSDavid Brownell static DEVICE_ATTR(microamps, 0444, regulator_uA_show, NULL);
325414c70cbSLiam Girdwood 
326bc558a60SMark Brown static ssize_t regulator_name_show(struct device *dev,
327bc558a60SMark Brown 			     struct device_attribute *attr, char *buf)
328bc558a60SMark Brown {
329bc558a60SMark Brown 	struct regulator_dev *rdev = dev_get_drvdata(dev);
330bc558a60SMark Brown 
3311083c393SMark Brown 	return sprintf(buf, "%s\n", rdev_get_name(rdev));
332bc558a60SMark Brown }
333bc558a60SMark Brown 
3344fca9545SDavid Brownell static ssize_t regulator_print_opmode(char *buf, int mode)
335414c70cbSLiam Girdwood {
336414c70cbSLiam Girdwood 	switch (mode) {
337414c70cbSLiam Girdwood 	case REGULATOR_MODE_FAST:
338414c70cbSLiam Girdwood 		return sprintf(buf, "fast\n");
339414c70cbSLiam Girdwood 	case REGULATOR_MODE_NORMAL:
340414c70cbSLiam Girdwood 		return sprintf(buf, "normal\n");
341414c70cbSLiam Girdwood 	case REGULATOR_MODE_IDLE:
342414c70cbSLiam Girdwood 		return sprintf(buf, "idle\n");
343414c70cbSLiam Girdwood 	case REGULATOR_MODE_STANDBY:
344414c70cbSLiam Girdwood 		return sprintf(buf, "standby\n");
345414c70cbSLiam Girdwood 	}
346414c70cbSLiam Girdwood 	return sprintf(buf, "unknown\n");
347414c70cbSLiam Girdwood }
348414c70cbSLiam Girdwood 
3494fca9545SDavid Brownell static ssize_t regulator_opmode_show(struct device *dev,
350414c70cbSLiam Girdwood 				    struct device_attribute *attr, char *buf)
351414c70cbSLiam Girdwood {
352a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
353414c70cbSLiam Girdwood 
3544fca9545SDavid Brownell 	return regulator_print_opmode(buf, _regulator_get_mode(rdev));
3554fca9545SDavid Brownell }
3567ad68e2fSDavid Brownell static DEVICE_ATTR(opmode, 0444, regulator_opmode_show, NULL);
3574fca9545SDavid Brownell 
3584fca9545SDavid Brownell static ssize_t regulator_print_state(char *buf, int state)
3594fca9545SDavid Brownell {
360414c70cbSLiam Girdwood 	if (state > 0)
361414c70cbSLiam Girdwood 		return sprintf(buf, "enabled\n");
362414c70cbSLiam Girdwood 	else if (state == 0)
363414c70cbSLiam Girdwood 		return sprintf(buf, "disabled\n");
364414c70cbSLiam Girdwood 	else
365414c70cbSLiam Girdwood 		return sprintf(buf, "unknown\n");
366414c70cbSLiam Girdwood }
367414c70cbSLiam Girdwood 
3684fca9545SDavid Brownell static ssize_t regulator_state_show(struct device *dev,
3694fca9545SDavid Brownell 				   struct device_attribute *attr, char *buf)
3704fca9545SDavid Brownell {
3714fca9545SDavid Brownell 	struct regulator_dev *rdev = dev_get_drvdata(dev);
3729332546fSMark Brown 	ssize_t ret;
3734fca9545SDavid Brownell 
3749332546fSMark Brown 	mutex_lock(&rdev->mutex);
3759332546fSMark Brown 	ret = regulator_print_state(buf, _regulator_is_enabled(rdev));
3769332546fSMark Brown 	mutex_unlock(&rdev->mutex);
3779332546fSMark Brown 
3789332546fSMark Brown 	return ret;
3794fca9545SDavid Brownell }
3807ad68e2fSDavid Brownell static DEVICE_ATTR(state, 0444, regulator_state_show, NULL);
3814fca9545SDavid Brownell 
382853116a1SDavid Brownell static ssize_t regulator_status_show(struct device *dev,
383853116a1SDavid Brownell 				   struct device_attribute *attr, char *buf)
384853116a1SDavid Brownell {
385853116a1SDavid Brownell 	struct regulator_dev *rdev = dev_get_drvdata(dev);
386853116a1SDavid Brownell 	int status;
387853116a1SDavid Brownell 	char *label;
388853116a1SDavid Brownell 
389853116a1SDavid Brownell 	status = rdev->desc->ops->get_status(rdev);
390853116a1SDavid Brownell 	if (status < 0)
391853116a1SDavid Brownell 		return status;
392853116a1SDavid Brownell 
393853116a1SDavid Brownell 	switch (status) {
394853116a1SDavid Brownell 	case REGULATOR_STATUS_OFF:
395853116a1SDavid Brownell 		label = "off";
396853116a1SDavid Brownell 		break;
397853116a1SDavid Brownell 	case REGULATOR_STATUS_ON:
398853116a1SDavid Brownell 		label = "on";
399853116a1SDavid Brownell 		break;
400853116a1SDavid Brownell 	case REGULATOR_STATUS_ERROR:
401853116a1SDavid Brownell 		label = "error";
402853116a1SDavid Brownell 		break;
403853116a1SDavid Brownell 	case REGULATOR_STATUS_FAST:
404853116a1SDavid Brownell 		label = "fast";
405853116a1SDavid Brownell 		break;
406853116a1SDavid Brownell 	case REGULATOR_STATUS_NORMAL:
407853116a1SDavid Brownell 		label = "normal";
408853116a1SDavid Brownell 		break;
409853116a1SDavid Brownell 	case REGULATOR_STATUS_IDLE:
410853116a1SDavid Brownell 		label = "idle";
411853116a1SDavid Brownell 		break;
412853116a1SDavid Brownell 	case REGULATOR_STATUS_STANDBY:
413853116a1SDavid Brownell 		label = "standby";
414853116a1SDavid Brownell 		break;
415f59c8f9fSMark Brown 	case REGULATOR_STATUS_BYPASS:
416f59c8f9fSMark Brown 		label = "bypass";
417f59c8f9fSMark Brown 		break;
4181beaf762SKrystian Garbaciak 	case REGULATOR_STATUS_UNDEFINED:
4191beaf762SKrystian Garbaciak 		label = "undefined";
4201beaf762SKrystian Garbaciak 		break;
421853116a1SDavid Brownell 	default:
422853116a1SDavid Brownell 		return -ERANGE;
423853116a1SDavid Brownell 	}
424853116a1SDavid Brownell 
425853116a1SDavid Brownell 	return sprintf(buf, "%s\n", label);
426853116a1SDavid Brownell }
427853116a1SDavid Brownell static DEVICE_ATTR(status, 0444, regulator_status_show, NULL);
428853116a1SDavid Brownell 
429414c70cbSLiam Girdwood static ssize_t regulator_min_uA_show(struct device *dev,
430414c70cbSLiam Girdwood 				    struct device_attribute *attr, char *buf)
431414c70cbSLiam Girdwood {
432a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
433414c70cbSLiam Girdwood 
434414c70cbSLiam Girdwood 	if (!rdev->constraints)
435414c70cbSLiam Girdwood 		return sprintf(buf, "constraint not defined\n");
436414c70cbSLiam Girdwood 
437414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", rdev->constraints->min_uA);
438414c70cbSLiam Girdwood }
4397ad68e2fSDavid Brownell static DEVICE_ATTR(min_microamps, 0444, regulator_min_uA_show, NULL);
440414c70cbSLiam Girdwood 
441414c70cbSLiam Girdwood static ssize_t regulator_max_uA_show(struct device *dev,
442414c70cbSLiam Girdwood 				    struct device_attribute *attr, char *buf)
443414c70cbSLiam Girdwood {
444a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
445414c70cbSLiam Girdwood 
446414c70cbSLiam Girdwood 	if (!rdev->constraints)
447414c70cbSLiam Girdwood 		return sprintf(buf, "constraint not defined\n");
448414c70cbSLiam Girdwood 
449414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", rdev->constraints->max_uA);
450414c70cbSLiam Girdwood }
4517ad68e2fSDavid Brownell static DEVICE_ATTR(max_microamps, 0444, regulator_max_uA_show, NULL);
452414c70cbSLiam Girdwood 
453414c70cbSLiam Girdwood static ssize_t regulator_min_uV_show(struct device *dev,
454414c70cbSLiam Girdwood 				    struct device_attribute *attr, char *buf)
455414c70cbSLiam Girdwood {
456a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
457414c70cbSLiam Girdwood 
458414c70cbSLiam Girdwood 	if (!rdev->constraints)
459414c70cbSLiam Girdwood 		return sprintf(buf, "constraint not defined\n");
460414c70cbSLiam Girdwood 
461414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", rdev->constraints->min_uV);
462414c70cbSLiam Girdwood }
4637ad68e2fSDavid Brownell static DEVICE_ATTR(min_microvolts, 0444, regulator_min_uV_show, NULL);
464414c70cbSLiam Girdwood 
465414c70cbSLiam Girdwood static ssize_t regulator_max_uV_show(struct device *dev,
466414c70cbSLiam Girdwood 				    struct device_attribute *attr, char *buf)
467414c70cbSLiam Girdwood {
468a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
469414c70cbSLiam Girdwood 
470414c70cbSLiam Girdwood 	if (!rdev->constraints)
471414c70cbSLiam Girdwood 		return sprintf(buf, "constraint not defined\n");
472414c70cbSLiam Girdwood 
473414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", rdev->constraints->max_uV);
474414c70cbSLiam Girdwood }
4757ad68e2fSDavid Brownell static DEVICE_ATTR(max_microvolts, 0444, regulator_max_uV_show, NULL);
476414c70cbSLiam Girdwood 
477414c70cbSLiam Girdwood static ssize_t regulator_total_uA_show(struct device *dev,
478414c70cbSLiam Girdwood 				      struct device_attribute *attr, char *buf)
479414c70cbSLiam Girdwood {
480a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
481414c70cbSLiam Girdwood 	struct regulator *regulator;
482414c70cbSLiam Girdwood 	int uA = 0;
483414c70cbSLiam Girdwood 
484414c70cbSLiam Girdwood 	mutex_lock(&rdev->mutex);
485414c70cbSLiam Girdwood 	list_for_each_entry(regulator, &rdev->consumer_list, list)
486414c70cbSLiam Girdwood 		uA += regulator->uA_load;
487414c70cbSLiam Girdwood 	mutex_unlock(&rdev->mutex);
488414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", uA);
489414c70cbSLiam Girdwood }
4907ad68e2fSDavid Brownell static DEVICE_ATTR(requested_microamps, 0444, regulator_total_uA_show, NULL);
491414c70cbSLiam Girdwood 
492414c70cbSLiam Girdwood static ssize_t regulator_num_users_show(struct device *dev,
493414c70cbSLiam Girdwood 				      struct device_attribute *attr, char *buf)
494414c70cbSLiam Girdwood {
495a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
496414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", rdev->use_count);
497414c70cbSLiam Girdwood }
498414c70cbSLiam Girdwood 
499414c70cbSLiam Girdwood static ssize_t regulator_type_show(struct device *dev,
500414c70cbSLiam Girdwood 				  struct device_attribute *attr, char *buf)
501414c70cbSLiam Girdwood {
502a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
503414c70cbSLiam Girdwood 
504414c70cbSLiam Girdwood 	switch (rdev->desc->type) {
505414c70cbSLiam Girdwood 	case REGULATOR_VOLTAGE:
506414c70cbSLiam Girdwood 		return sprintf(buf, "voltage\n");
507414c70cbSLiam Girdwood 	case REGULATOR_CURRENT:
508414c70cbSLiam Girdwood 		return sprintf(buf, "current\n");
509414c70cbSLiam Girdwood 	}
510414c70cbSLiam Girdwood 	return sprintf(buf, "unknown\n");
511414c70cbSLiam Girdwood }
512414c70cbSLiam Girdwood 
513414c70cbSLiam Girdwood static ssize_t regulator_suspend_mem_uV_show(struct device *dev,
514414c70cbSLiam Girdwood 				struct device_attribute *attr, char *buf)
515414c70cbSLiam Girdwood {
516a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
517414c70cbSLiam Girdwood 
518414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", rdev->constraints->state_mem.uV);
519414c70cbSLiam Girdwood }
5207ad68e2fSDavid Brownell static DEVICE_ATTR(suspend_mem_microvolts, 0444,
5217ad68e2fSDavid Brownell 		regulator_suspend_mem_uV_show, NULL);
522414c70cbSLiam Girdwood 
523414c70cbSLiam Girdwood static ssize_t regulator_suspend_disk_uV_show(struct device *dev,
524414c70cbSLiam Girdwood 				struct device_attribute *attr, char *buf)
525414c70cbSLiam Girdwood {
526a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
527414c70cbSLiam Girdwood 
528414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", rdev->constraints->state_disk.uV);
529414c70cbSLiam Girdwood }
5307ad68e2fSDavid Brownell static DEVICE_ATTR(suspend_disk_microvolts, 0444,
5317ad68e2fSDavid Brownell 		regulator_suspend_disk_uV_show, NULL);
532414c70cbSLiam Girdwood 
533414c70cbSLiam Girdwood static ssize_t regulator_suspend_standby_uV_show(struct device *dev,
534414c70cbSLiam Girdwood 				struct device_attribute *attr, char *buf)
535414c70cbSLiam Girdwood {
536a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
537414c70cbSLiam Girdwood 
538414c70cbSLiam Girdwood 	return sprintf(buf, "%d\n", rdev->constraints->state_standby.uV);
539414c70cbSLiam Girdwood }
5407ad68e2fSDavid Brownell static DEVICE_ATTR(suspend_standby_microvolts, 0444,
5417ad68e2fSDavid Brownell 		regulator_suspend_standby_uV_show, NULL);
542414c70cbSLiam Girdwood 
543414c70cbSLiam Girdwood static ssize_t regulator_suspend_mem_mode_show(struct device *dev,
544414c70cbSLiam Girdwood 				struct device_attribute *attr, char *buf)
545414c70cbSLiam Girdwood {
546a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
547414c70cbSLiam Girdwood 
5484fca9545SDavid Brownell 	return regulator_print_opmode(buf,
5494fca9545SDavid Brownell 		rdev->constraints->state_mem.mode);
550414c70cbSLiam Girdwood }
5517ad68e2fSDavid Brownell static DEVICE_ATTR(suspend_mem_mode, 0444,
5527ad68e2fSDavid Brownell 		regulator_suspend_mem_mode_show, NULL);
553414c70cbSLiam Girdwood 
554414c70cbSLiam Girdwood static ssize_t regulator_suspend_disk_mode_show(struct device *dev,
555414c70cbSLiam Girdwood 				struct device_attribute *attr, char *buf)
556414c70cbSLiam Girdwood {
557a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
558414c70cbSLiam Girdwood 
5594fca9545SDavid Brownell 	return regulator_print_opmode(buf,
5604fca9545SDavid Brownell 		rdev->constraints->state_disk.mode);
561414c70cbSLiam Girdwood }
5627ad68e2fSDavid Brownell static DEVICE_ATTR(suspend_disk_mode, 0444,
5637ad68e2fSDavid Brownell 		regulator_suspend_disk_mode_show, NULL);
564414c70cbSLiam Girdwood 
565414c70cbSLiam Girdwood static ssize_t regulator_suspend_standby_mode_show(struct device *dev,
566414c70cbSLiam Girdwood 				struct device_attribute *attr, char *buf)
567414c70cbSLiam Girdwood {
568a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
569414c70cbSLiam Girdwood 
5704fca9545SDavid Brownell 	return regulator_print_opmode(buf,
5714fca9545SDavid Brownell 		rdev->constraints->state_standby.mode);
572414c70cbSLiam Girdwood }
5737ad68e2fSDavid Brownell static DEVICE_ATTR(suspend_standby_mode, 0444,
5747ad68e2fSDavid Brownell 		regulator_suspend_standby_mode_show, NULL);
575414c70cbSLiam Girdwood 
576414c70cbSLiam Girdwood static ssize_t regulator_suspend_mem_state_show(struct device *dev,
577414c70cbSLiam Girdwood 				   struct device_attribute *attr, char *buf)
578414c70cbSLiam Girdwood {
579a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
580414c70cbSLiam Girdwood 
5814fca9545SDavid Brownell 	return regulator_print_state(buf,
5824fca9545SDavid Brownell 			rdev->constraints->state_mem.enabled);
583414c70cbSLiam Girdwood }
5847ad68e2fSDavid Brownell static DEVICE_ATTR(suspend_mem_state, 0444,
5857ad68e2fSDavid Brownell 		regulator_suspend_mem_state_show, NULL);
586414c70cbSLiam Girdwood 
587414c70cbSLiam Girdwood static ssize_t regulator_suspend_disk_state_show(struct device *dev,
588414c70cbSLiam Girdwood 				   struct device_attribute *attr, char *buf)
589414c70cbSLiam Girdwood {
590a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
591414c70cbSLiam Girdwood 
5924fca9545SDavid Brownell 	return regulator_print_state(buf,
5934fca9545SDavid Brownell 			rdev->constraints->state_disk.enabled);
594414c70cbSLiam Girdwood }
5957ad68e2fSDavid Brownell static DEVICE_ATTR(suspend_disk_state, 0444,
5967ad68e2fSDavid Brownell 		regulator_suspend_disk_state_show, NULL);
597414c70cbSLiam Girdwood 
598414c70cbSLiam Girdwood static ssize_t regulator_suspend_standby_state_show(struct device *dev,
599414c70cbSLiam Girdwood 				   struct device_attribute *attr, char *buf)
600414c70cbSLiam Girdwood {
601a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
602414c70cbSLiam Girdwood 
6034fca9545SDavid Brownell 	return regulator_print_state(buf,
6044fca9545SDavid Brownell 			rdev->constraints->state_standby.enabled);
605414c70cbSLiam Girdwood }
6067ad68e2fSDavid Brownell static DEVICE_ATTR(suspend_standby_state, 0444,
6077ad68e2fSDavid Brownell 		regulator_suspend_standby_state_show, NULL);
608bc558a60SMark Brown 
609f59c8f9fSMark Brown static ssize_t regulator_bypass_show(struct device *dev,
610f59c8f9fSMark Brown 				     struct device_attribute *attr, char *buf)
611f59c8f9fSMark Brown {
612f59c8f9fSMark Brown 	struct regulator_dev *rdev = dev_get_drvdata(dev);
613f59c8f9fSMark Brown 	const char *report;
614f59c8f9fSMark Brown 	bool bypass;
615f59c8f9fSMark Brown 	int ret;
616f59c8f9fSMark Brown 
617f59c8f9fSMark Brown 	ret = rdev->desc->ops->get_bypass(rdev, &bypass);
618f59c8f9fSMark Brown 
619f59c8f9fSMark Brown 	if (ret != 0)
620f59c8f9fSMark Brown 		report = "unknown";
621f59c8f9fSMark Brown 	else if (bypass)
622f59c8f9fSMark Brown 		report = "enabled";
623f59c8f9fSMark Brown 	else
624f59c8f9fSMark Brown 		report = "disabled";
625f59c8f9fSMark Brown 
626f59c8f9fSMark Brown 	return sprintf(buf, "%s\n", report);
627f59c8f9fSMark Brown }
628f59c8f9fSMark Brown static DEVICE_ATTR(bypass, 0444,
629f59c8f9fSMark Brown 		   regulator_bypass_show, NULL);
6307ad68e2fSDavid Brownell 
6317ad68e2fSDavid Brownell /*
6327ad68e2fSDavid Brownell  * These are the only attributes are present for all regulators.
6337ad68e2fSDavid Brownell  * Other attributes are a function of regulator functionality.
6347ad68e2fSDavid Brownell  */
635414c70cbSLiam Girdwood static struct device_attribute regulator_dev_attrs[] = {
636bc558a60SMark Brown 	__ATTR(name, 0444, regulator_name_show, NULL),
637414c70cbSLiam Girdwood 	__ATTR(num_users, 0444, regulator_num_users_show, NULL),
638414c70cbSLiam Girdwood 	__ATTR(type, 0444, regulator_type_show, NULL),
639414c70cbSLiam Girdwood 	__ATTR_NULL,
640414c70cbSLiam Girdwood };
641414c70cbSLiam Girdwood 
642414c70cbSLiam Girdwood static void regulator_dev_release(struct device *dev)
643414c70cbSLiam Girdwood {
644a5766f11SLiam Girdwood 	struct regulator_dev *rdev = dev_get_drvdata(dev);
645414c70cbSLiam Girdwood 	kfree(rdev);
646414c70cbSLiam Girdwood }
647414c70cbSLiam Girdwood 
648414c70cbSLiam Girdwood static struct class regulator_class = {
649414c70cbSLiam Girdwood 	.name = "regulator",
650414c70cbSLiam Girdwood 	.dev_release = regulator_dev_release,
651414c70cbSLiam Girdwood 	.dev_attrs = regulator_dev_attrs,
652414c70cbSLiam Girdwood };
653414c70cbSLiam Girdwood 
654414c70cbSLiam Girdwood /* Calculate the new optimum regulator operating mode based on the new total
655414c70cbSLiam Girdwood  * consumer load. All locks held by caller */
656414c70cbSLiam Girdwood static void drms_uA_update(struct regulator_dev *rdev)
657414c70cbSLiam Girdwood {
658414c70cbSLiam Girdwood 	struct regulator *sibling;
659414c70cbSLiam Girdwood 	int current_uA = 0, output_uV, input_uV, err;
660414c70cbSLiam Girdwood 	unsigned int mode;
661414c70cbSLiam Girdwood 
662414c70cbSLiam Girdwood 	err = regulator_check_drms(rdev);
663414c70cbSLiam Girdwood 	if (err < 0 || !rdev->desc->ops->get_optimum_mode ||
664476c2d83SMark Brown 	    (!rdev->desc->ops->get_voltage &&
665476c2d83SMark Brown 	     !rdev->desc->ops->get_voltage_sel) ||
666476c2d83SMark Brown 	    !rdev->desc->ops->set_mode)
667414c70cbSLiam Girdwood 		return;
668414c70cbSLiam Girdwood 
669414c70cbSLiam Girdwood 	/* get output voltage */
6701bf5a1f8SMark Brown 	output_uV = _regulator_get_voltage(rdev);
671414c70cbSLiam Girdwood 	if (output_uV <= 0)
672414c70cbSLiam Girdwood 		return;
673414c70cbSLiam Girdwood 
674414c70cbSLiam Girdwood 	/* get input voltage */
6751bf5a1f8SMark Brown 	input_uV = 0;
6761bf5a1f8SMark Brown 	if (rdev->supply)
6773f24f5adSAxel Lin 		input_uV = regulator_get_voltage(rdev->supply);
6781bf5a1f8SMark Brown 	if (input_uV <= 0)
679414c70cbSLiam Girdwood 		input_uV = rdev->constraints->input_uV;
680414c70cbSLiam Girdwood 	if (input_uV <= 0)
681414c70cbSLiam Girdwood 		return;
682414c70cbSLiam Girdwood 
683414c70cbSLiam Girdwood 	/* calc total requested load */
684414c70cbSLiam Girdwood 	list_for_each_entry(sibling, &rdev->consumer_list, list)
685414c70cbSLiam Girdwood 		current_uA += sibling->uA_load;
686414c70cbSLiam Girdwood 
687414c70cbSLiam Girdwood 	/* now get the optimum mode for our new total regulator load */
688414c70cbSLiam Girdwood 	mode = rdev->desc->ops->get_optimum_mode(rdev, input_uV,
689414c70cbSLiam Girdwood 						  output_uV, current_uA);
690414c70cbSLiam Girdwood 
691414c70cbSLiam Girdwood 	/* check the new mode is allowed */
6922c608234SMark Brown 	err = regulator_mode_constrain(rdev, &mode);
693414c70cbSLiam Girdwood 	if (err == 0)
694414c70cbSLiam Girdwood 		rdev->desc->ops->set_mode(rdev, mode);
695414c70cbSLiam Girdwood }
696414c70cbSLiam Girdwood 
697414c70cbSLiam Girdwood static int suspend_set_state(struct regulator_dev *rdev,
698414c70cbSLiam Girdwood 	struct regulator_state *rstate)
699414c70cbSLiam Girdwood {
700414c70cbSLiam Girdwood 	int ret = 0;
701638f85c5SMark Brown 
702638f85c5SMark Brown 	/* If we have no suspend mode configration don't set anything;
7038ac0e95dSAxel Lin 	 * only warn if the driver implements set_suspend_voltage or
7048ac0e95dSAxel Lin 	 * set_suspend_mode callback.
705638f85c5SMark Brown 	 */
706638f85c5SMark Brown 	if (!rstate->enabled && !rstate->disabled) {
7078ac0e95dSAxel Lin 		if (rdev->desc->ops->set_suspend_voltage ||
7088ac0e95dSAxel Lin 		    rdev->desc->ops->set_suspend_mode)
7095da84fd9SJoe Perches 			rdev_warn(rdev, "No configuration\n");
710638f85c5SMark Brown 		return 0;
711638f85c5SMark Brown 	}
712638f85c5SMark Brown 
713638f85c5SMark Brown 	if (rstate->enabled && rstate->disabled) {
7145da84fd9SJoe Perches 		rdev_err(rdev, "invalid configuration\n");
715638f85c5SMark Brown 		return -EINVAL;
716638f85c5SMark Brown 	}
717638f85c5SMark Brown 
7188ac0e95dSAxel Lin 	if (rstate->enabled && rdev->desc->ops->set_suspend_enable)
719414c70cbSLiam Girdwood 		ret = rdev->desc->ops->set_suspend_enable(rdev);
7208ac0e95dSAxel Lin 	else if (rstate->disabled && rdev->desc->ops->set_suspend_disable)
721414c70cbSLiam Girdwood 		ret = rdev->desc->ops->set_suspend_disable(rdev);
7228ac0e95dSAxel Lin 	else /* OK if set_suspend_enable or set_suspend_disable is NULL */
7238ac0e95dSAxel Lin 		ret = 0;
7248ac0e95dSAxel Lin 
725414c70cbSLiam Girdwood 	if (ret < 0) {
7265da84fd9SJoe Perches 		rdev_err(rdev, "failed to enabled/disable\n");
727414c70cbSLiam Girdwood 		return ret;
728414c70cbSLiam Girdwood 	}
729414c70cbSLiam Girdwood 
730414c70cbSLiam Girdwood 	if (rdev->desc->ops->set_suspend_voltage && rstate->uV > 0) {
731414c70cbSLiam Girdwood 		ret = rdev->desc->ops->set_suspend_voltage(rdev, rstate->uV);
732414c70cbSLiam Girdwood 		if (ret < 0) {
7335da84fd9SJoe Perches 			rdev_err(rdev, "failed to set voltage\n");
734414c70cbSLiam Girdwood 			return ret;
735414c70cbSLiam Girdwood 		}
736414c70cbSLiam Girdwood 	}
737414c70cbSLiam Girdwood 
738414c70cbSLiam Girdwood 	if (rdev->desc->ops->set_suspend_mode && rstate->mode > 0) {
739414c70cbSLiam Girdwood 		ret = rdev->desc->ops->set_suspend_mode(rdev, rstate->mode);
740414c70cbSLiam Girdwood 		if (ret < 0) {
7415da84fd9SJoe Perches 			rdev_err(rdev, "failed to set mode\n");
742414c70cbSLiam Girdwood 			return ret;
743414c70cbSLiam Girdwood 		}
744414c70cbSLiam Girdwood 	}
745414c70cbSLiam Girdwood 	return ret;
746414c70cbSLiam Girdwood }
747414c70cbSLiam Girdwood 
748414c70cbSLiam Girdwood /* locks held by caller */
749414c70cbSLiam Girdwood static int suspend_prepare(struct regulator_dev *rdev, suspend_state_t state)
750414c70cbSLiam Girdwood {
751414c70cbSLiam Girdwood 	if (!rdev->constraints)
752414c70cbSLiam Girdwood 		return -EINVAL;
753414c70cbSLiam Girdwood 
754414c70cbSLiam Girdwood 	switch (state) {
755414c70cbSLiam Girdwood 	case PM_SUSPEND_STANDBY:
756414c70cbSLiam Girdwood 		return suspend_set_state(rdev,
757414c70cbSLiam Girdwood 			&rdev->constraints->state_standby);
758414c70cbSLiam Girdwood 	case PM_SUSPEND_MEM:
759414c70cbSLiam Girdwood 		return suspend_set_state(rdev,
760414c70cbSLiam Girdwood 			&rdev->constraints->state_mem);
761414c70cbSLiam Girdwood 	case PM_SUSPEND_MAX:
762414c70cbSLiam Girdwood 		return suspend_set_state(rdev,
763414c70cbSLiam Girdwood 			&rdev->constraints->state_disk);
764414c70cbSLiam Girdwood 	default:
765414c70cbSLiam Girdwood 		return -EINVAL;
766414c70cbSLiam Girdwood 	}
767414c70cbSLiam Girdwood }
768414c70cbSLiam Girdwood 
769414c70cbSLiam Girdwood static void print_constraints(struct regulator_dev *rdev)
770414c70cbSLiam Girdwood {
771414c70cbSLiam Girdwood 	struct regulation_constraints *constraints = rdev->constraints;
772973e9a27SMark Brown 	char buf[80] = "";
7738f031b48SMark Brown 	int count = 0;
7748f031b48SMark Brown 	int ret;
775414c70cbSLiam Girdwood 
7768f031b48SMark Brown 	if (constraints->min_uV && constraints->max_uV) {
777414c70cbSLiam Girdwood 		if (constraints->min_uV == constraints->max_uV)
7788f031b48SMark Brown 			count += sprintf(buf + count, "%d mV ",
779414c70cbSLiam Girdwood 					 constraints->min_uV / 1000);
780414c70cbSLiam Girdwood 		else
7818f031b48SMark Brown 			count += sprintf(buf + count, "%d <--> %d mV ",
782414c70cbSLiam Girdwood 					 constraints->min_uV / 1000,
783414c70cbSLiam Girdwood 					 constraints->max_uV / 1000);
7848f031b48SMark Brown 	}
7858f031b48SMark Brown 
7868f031b48SMark Brown 	if (!constraints->min_uV ||
7878f031b48SMark Brown 	    constraints->min_uV != constraints->max_uV) {
7888f031b48SMark Brown 		ret = _regulator_get_voltage(rdev);
7898f031b48SMark Brown 		if (ret > 0)
7908f031b48SMark Brown 			count += sprintf(buf + count, "at %d mV ", ret / 1000);
7918f031b48SMark Brown 	}
7928f031b48SMark Brown 
793bf5892a8SMark Brown 	if (constraints->uV_offset)
794bf5892a8SMark Brown 		count += sprintf(buf, "%dmV offset ",
795bf5892a8SMark Brown 				 constraints->uV_offset / 1000);
796bf5892a8SMark Brown 
7978f031b48SMark Brown 	if (constraints->min_uA && constraints->max_uA) {
798414c70cbSLiam Girdwood 		if (constraints->min_uA == constraints->max_uA)
7998f031b48SMark Brown 			count += sprintf(buf + count, "%d mA ",
800414c70cbSLiam Girdwood 					 constraints->min_uA / 1000);
801414c70cbSLiam Girdwood 		else
8028f031b48SMark Brown 			count += sprintf(buf + count, "%d <--> %d mA ",
803414c70cbSLiam Girdwood 					 constraints->min_uA / 1000,
804414c70cbSLiam Girdwood 					 constraints->max_uA / 1000);
805414c70cbSLiam Girdwood 	}
8068f031b48SMark Brown 
8078f031b48SMark Brown 	if (!constraints->min_uA ||
8088f031b48SMark Brown 	    constraints->min_uA != constraints->max_uA) {
8098f031b48SMark Brown 		ret = _regulator_get_current_limit(rdev);
8108f031b48SMark Brown 		if (ret > 0)
811e4a6376bSCyril Chemparathy 			count += sprintf(buf + count, "at %d mA ", ret / 1000);
8128f031b48SMark Brown 	}
8138f031b48SMark Brown 
814414c70cbSLiam Girdwood 	if (constraints->valid_modes_mask & REGULATOR_MODE_FAST)
815414c70cbSLiam Girdwood 		count += sprintf(buf + count, "fast ");
816414c70cbSLiam Girdwood 	if (constraints->valid_modes_mask & REGULATOR_MODE_NORMAL)
817414c70cbSLiam Girdwood 		count += sprintf(buf + count, "normal ");
818414c70cbSLiam Girdwood 	if (constraints->valid_modes_mask & REGULATOR_MODE_IDLE)
819414c70cbSLiam Girdwood 		count += sprintf(buf + count, "idle ");
820414c70cbSLiam Girdwood 	if (constraints->valid_modes_mask & REGULATOR_MODE_STANDBY)
821414c70cbSLiam Girdwood 		count += sprintf(buf + count, "standby");
822414c70cbSLiam Girdwood 
823215b8b05SUwe Kleine-König 	if (!count)
824215b8b05SUwe Kleine-König 		sprintf(buf, "no parameters");
825215b8b05SUwe Kleine-König 
82613ce29f8SMark Brown 	rdev_info(rdev, "%s\n", buf);
8274a682922SMark Brown 
8284a682922SMark Brown 	if ((constraints->min_uV != constraints->max_uV) &&
8294a682922SMark Brown 	    !(constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE))
8304a682922SMark Brown 		rdev_warn(rdev,
8314a682922SMark Brown 			  "Voltage range but no REGULATOR_CHANGE_VOLTAGE\n");
832414c70cbSLiam Girdwood }
833414c70cbSLiam Girdwood 
834e79055d6SMark Brown static int machine_constraints_voltage(struct regulator_dev *rdev,
8351083c393SMark Brown 	struct regulation_constraints *constraints)
836e79055d6SMark Brown {
837e79055d6SMark Brown 	struct regulator_ops *ops = rdev->desc->ops;
838af5866c9SMark Brown 	int ret;
839af5866c9SMark Brown 
840af5866c9SMark Brown 	/* do we need to apply the constraint voltage */
841af5866c9SMark Brown 	if (rdev->constraints->apply_uV &&
84275790251SMark Brown 	    rdev->constraints->min_uV == rdev->constraints->max_uV) {
84375790251SMark Brown 		ret = _regulator_do_set_voltage(rdev,
8443a93f2a9SMark Brown 						rdev->constraints->min_uV,
84575790251SMark Brown 						rdev->constraints->max_uV);
846af5866c9SMark Brown 		if (ret < 0) {
8475da84fd9SJoe Perches 			rdev_err(rdev, "failed to apply %duV constraint\n",
8485da84fd9SJoe Perches 				 rdev->constraints->min_uV);
849af5866c9SMark Brown 			return ret;
850af5866c9SMark Brown 		}
851af5866c9SMark Brown 	}
852e79055d6SMark Brown 
853e79055d6SMark Brown 	/* constrain machine-level voltage specs to fit
854e79055d6SMark Brown 	 * the actual range supported by this regulator.
855e79055d6SMark Brown 	 */
856e79055d6SMark Brown 	if (ops->list_voltage && rdev->desc->n_voltages) {
857e79055d6SMark Brown 		int	count = rdev->desc->n_voltages;
858e79055d6SMark Brown 		int	i;
859e79055d6SMark Brown 		int	min_uV = INT_MAX;
860e79055d6SMark Brown 		int	max_uV = INT_MIN;
861e79055d6SMark Brown 		int	cmin = constraints->min_uV;
862e79055d6SMark Brown 		int	cmax = constraints->max_uV;
863e79055d6SMark Brown 
864e79055d6SMark Brown 		/* it's safe to autoconfigure fixed-voltage supplies
865e79055d6SMark Brown 		   and the constraints are used by list_voltage. */
866e79055d6SMark Brown 		if (count == 1 && !cmin) {
867e79055d6SMark Brown 			cmin = 1;
868e79055d6SMark Brown 			cmax = INT_MAX;
869e79055d6SMark Brown 			constraints->min_uV = cmin;
870e79055d6SMark Brown 			constraints->max_uV = cmax;
871e79055d6SMark Brown 		}
872e79055d6SMark Brown 
873e79055d6SMark Brown 		/* voltage constraints are optional */
874e79055d6SMark Brown 		if ((cmin == 0) && (cmax == 0))
875e79055d6SMark Brown 			return 0;
876e79055d6SMark Brown 
877e79055d6SMark Brown 		/* else require explicit machine-level constraints */
878e79055d6SMark Brown 		if (cmin <= 0 || cmax <= 0 || cmax < cmin) {
8795da84fd9SJoe Perches 			rdev_err(rdev, "invalid voltage constraints\n");
880e79055d6SMark Brown 			return -EINVAL;
881e79055d6SMark Brown 		}
882e79055d6SMark Brown 
883e79055d6SMark Brown 		/* initial: [cmin..cmax] valid, [min_uV..max_uV] not */
884e79055d6SMark Brown 		for (i = 0; i < count; i++) {
885e79055d6SMark Brown 			int	value;
886e79055d6SMark Brown 
887e79055d6SMark Brown 			value = ops->list_voltage(rdev, i);
888e79055d6SMark Brown 			if (value <= 0)
889e79055d6SMark Brown 				continue;
890e79055d6SMark Brown 
891e79055d6SMark Brown 			/* maybe adjust [min_uV..max_uV] */
892e79055d6SMark Brown 			if (value >= cmin && value < min_uV)
893e79055d6SMark Brown 				min_uV = value;
894e79055d6SMark Brown 			if (value <= cmax && value > max_uV)
895e79055d6SMark Brown 				max_uV = value;
896e79055d6SMark Brown 		}
897e79055d6SMark Brown 
898e79055d6SMark Brown 		/* final: [min_uV..max_uV] valid iff constraints valid */
899e79055d6SMark Brown 		if (max_uV < min_uV) {
900fff15befSMark Brown 			rdev_err(rdev,
901fff15befSMark Brown 				 "unsupportable voltage constraints %u-%uuV\n",
902fff15befSMark Brown 				 min_uV, max_uV);
903e79055d6SMark Brown 			return -EINVAL;
904e79055d6SMark Brown 		}
905e79055d6SMark Brown 
906e79055d6SMark Brown 		/* use regulator's subset of machine constraints */
907e79055d6SMark Brown 		if (constraints->min_uV < min_uV) {
9085da84fd9SJoe Perches 			rdev_dbg(rdev, "override min_uV, %d -> %d\n",
9095da84fd9SJoe Perches 				 constraints->min_uV, min_uV);
910e79055d6SMark Brown 			constraints->min_uV = min_uV;
911e79055d6SMark Brown 		}
912e79055d6SMark Brown 		if (constraints->max_uV > max_uV) {
9135da84fd9SJoe Perches 			rdev_dbg(rdev, "override max_uV, %d -> %d\n",
9145da84fd9SJoe Perches 				 constraints->max_uV, max_uV);
915e79055d6SMark Brown 			constraints->max_uV = max_uV;
916e79055d6SMark Brown 		}
917e79055d6SMark Brown 	}
918e79055d6SMark Brown 
919e79055d6SMark Brown 	return 0;
920e79055d6SMark Brown }
921e79055d6SMark Brown 
922a5766f11SLiam Girdwood /**
923a5766f11SLiam Girdwood  * set_machine_constraints - sets regulator constraints
92469279fb9SMark Brown  * @rdev: regulator source
925c8e7e464SMark Brown  * @constraints: constraints to apply
926a5766f11SLiam Girdwood  *
927a5766f11SLiam Girdwood  * Allows platform initialisation code to define and constrain
928a5766f11SLiam Girdwood  * regulator circuits e.g. valid voltage/current ranges, etc.  NOTE:
929a5766f11SLiam Girdwood  * Constraints *must* be set by platform code in order for some
930a5766f11SLiam Girdwood  * regulator operations to proceed i.e. set_voltage, set_current_limit,
931a5766f11SLiam Girdwood  * set_mode.
932a5766f11SLiam Girdwood  */
933a5766f11SLiam Girdwood static int set_machine_constraints(struct regulator_dev *rdev,
934f8c12fe3SMark Brown 	const struct regulation_constraints *constraints)
935a5766f11SLiam Girdwood {
936a5766f11SLiam Girdwood 	int ret = 0;
937e5fda26cSMark Brown 	struct regulator_ops *ops = rdev->desc->ops;
938e06f5b4fSMark Brown 
9399a8f5e07SMark Brown 	if (constraints)
940f8c12fe3SMark Brown 		rdev->constraints = kmemdup(constraints, sizeof(*constraints),
941f8c12fe3SMark Brown 					    GFP_KERNEL);
9429a8f5e07SMark Brown 	else
9439a8f5e07SMark Brown 		rdev->constraints = kzalloc(sizeof(*constraints),
9449a8f5e07SMark Brown 					    GFP_KERNEL);
945f8c12fe3SMark Brown 	if (!rdev->constraints)
946f8c12fe3SMark Brown 		return -ENOMEM;
947af5866c9SMark Brown 
948f8c12fe3SMark Brown 	ret = machine_constraints_voltage(rdev, rdev->constraints);
949e79055d6SMark Brown 	if (ret != 0)
9503e2b9abdSMark Brown 		goto out;
9513e2b9abdSMark Brown 
952a5766f11SLiam Girdwood 	/* do we need to setup our suspend state */
9539a8f5e07SMark Brown 	if (rdev->constraints->initial_state) {
954f8c12fe3SMark Brown 		ret = suspend_prepare(rdev, rdev->constraints->initial_state);
955e06f5b4fSMark Brown 		if (ret < 0) {
9565da84fd9SJoe Perches 			rdev_err(rdev, "failed to set suspend state\n");
957e06f5b4fSMark Brown 			goto out;
958e06f5b4fSMark Brown 		}
959e06f5b4fSMark Brown 	}
960a5766f11SLiam Girdwood 
9619a8f5e07SMark Brown 	if (rdev->constraints->initial_mode) {
962a308466cSMark Brown 		if (!ops->set_mode) {
9635da84fd9SJoe Perches 			rdev_err(rdev, "no set_mode operation\n");
964a308466cSMark Brown 			ret = -EINVAL;
965a308466cSMark Brown 			goto out;
966a308466cSMark Brown 		}
967a308466cSMark Brown 
968f8c12fe3SMark Brown 		ret = ops->set_mode(rdev, rdev->constraints->initial_mode);
969a308466cSMark Brown 		if (ret < 0) {
9705da84fd9SJoe Perches 			rdev_err(rdev, "failed to set initial mode: %d\n", ret);
971a308466cSMark Brown 			goto out;
972a308466cSMark Brown 		}
973a308466cSMark Brown 	}
974a308466cSMark Brown 
975cacf90f2SMark Brown 	/* If the constraints say the regulator should be on at this point
976cacf90f2SMark Brown 	 * and we have control then make sure it is enabled.
977cacf90f2SMark Brown 	 */
978f8c12fe3SMark Brown 	if ((rdev->constraints->always_on || rdev->constraints->boot_on) &&
979f8c12fe3SMark Brown 	    ops->enable) {
980e5fda26cSMark Brown 		ret = ops->enable(rdev);
981e5fda26cSMark Brown 		if (ret < 0) {
9825da84fd9SJoe Perches 			rdev_err(rdev, "failed to enable\n");
983e5fda26cSMark Brown 			goto out;
984e5fda26cSMark Brown 		}
985e5fda26cSMark Brown 	}
986e5fda26cSMark Brown 
9876f0b2c69SYadwinder Singh Brar 	if (rdev->constraints->ramp_delay && ops->set_ramp_delay) {
9886f0b2c69SYadwinder Singh Brar 		ret = ops->set_ramp_delay(rdev, rdev->constraints->ramp_delay);
9896f0b2c69SYadwinder Singh Brar 		if (ret < 0) {
9906f0b2c69SYadwinder Singh Brar 			rdev_err(rdev, "failed to set ramp_delay\n");
9916f0b2c69SYadwinder Singh Brar 			goto out;
9926f0b2c69SYadwinder Singh Brar 		}
9936f0b2c69SYadwinder Singh Brar 	}
9946f0b2c69SYadwinder Singh Brar 
995a5766f11SLiam Girdwood 	print_constraints(rdev);
9961a6958e7SAxel Lin 	return 0;
997a5766f11SLiam Girdwood out:
9981a6958e7SAxel Lin 	kfree(rdev->constraints);
9991a6958e7SAxel Lin 	rdev->constraints = NULL;
1000a5766f11SLiam Girdwood 	return ret;
1001a5766f11SLiam Girdwood }
1002a5766f11SLiam Girdwood 
1003a5766f11SLiam Girdwood /**
1004a5766f11SLiam Girdwood  * set_supply - set regulator supply regulator
100569279fb9SMark Brown  * @rdev: regulator name
100669279fb9SMark Brown  * @supply_rdev: supply regulator name
1007a5766f11SLiam Girdwood  *
1008a5766f11SLiam Girdwood  * Called by platform initialisation code to set the supply regulator for this
1009a5766f11SLiam Girdwood  * regulator. This ensures that a regulators supply will also be enabled by the
1010a5766f11SLiam Girdwood  * core if it's child is enabled.
1011a5766f11SLiam Girdwood  */
1012a5766f11SLiam Girdwood static int set_supply(struct regulator_dev *rdev,
1013a5766f11SLiam Girdwood 		      struct regulator_dev *supply_rdev)
1014a5766f11SLiam Girdwood {
1015a5766f11SLiam Girdwood 	int err;
1016a5766f11SLiam Girdwood 
10173801b86aSMark Brown 	rdev_info(rdev, "supplied by %s\n", rdev_get_name(supply_rdev));
10183801b86aSMark Brown 
10193801b86aSMark Brown 	rdev->supply = create_regulator(supply_rdev, &rdev->dev, "SUPPLY");
102032c78de8SAxel Lin 	if (rdev->supply == NULL) {
102132c78de8SAxel Lin 		err = -ENOMEM;
1022a5766f11SLiam Girdwood 		return err;
1023a5766f11SLiam Girdwood 	}
102457ad526aSLaxman Dewangan 	supply_rdev->open_count++;
1025a5766f11SLiam Girdwood 
10263801b86aSMark Brown 	return 0;
10273801b86aSMark Brown }
10283801b86aSMark Brown 
1029a5766f11SLiam Girdwood /**
103006c63f93SRandy Dunlap  * set_consumer_device_supply - Bind a regulator to a symbolic supply
103169279fb9SMark Brown  * @rdev:         regulator source
103240f9244fSMark Brown  * @consumer_dev_name: dev_name() string for device supply applies to
1033a5766f11SLiam Girdwood  * @supply:       symbolic name for supply
1034a5766f11SLiam Girdwood  *
1035a5766f11SLiam Girdwood  * Allows platform initialisation code to map physical regulator
1036a5766f11SLiam Girdwood  * sources to symbolic names for supplies for use by devices.  Devices
1037a5766f11SLiam Girdwood  * should use these symbolic names to request regulators, avoiding the
1038a5766f11SLiam Girdwood  * need to provide board-specific regulator names as platform data.
1039a5766f11SLiam Girdwood  */
1040a5766f11SLiam Girdwood static int set_consumer_device_supply(struct regulator_dev *rdev,
1041737f360dSMark Brown 				      const char *consumer_dev_name,
104240f9244fSMark Brown 				      const char *supply)
1043a5766f11SLiam Girdwood {
1044a5766f11SLiam Girdwood 	struct regulator_map *node;
10459ed2099eSMark Brown 	int has_dev;
1046a5766f11SLiam Girdwood 
1047a5766f11SLiam Girdwood 	if (supply == NULL)
1048a5766f11SLiam Girdwood 		return -EINVAL;
1049a5766f11SLiam Girdwood 
10509ed2099eSMark Brown 	if (consumer_dev_name != NULL)
10519ed2099eSMark Brown 		has_dev = 1;
10529ed2099eSMark Brown 	else
10539ed2099eSMark Brown 		has_dev = 0;
10549ed2099eSMark Brown 
10556001e13cSDavid Brownell 	list_for_each_entry(node, &regulator_map_list, list) {
105623b5cc2aSJani Nikula 		if (node->dev_name && consumer_dev_name) {
105723b5cc2aSJani Nikula 			if (strcmp(node->dev_name, consumer_dev_name) != 0)
10586001e13cSDavid Brownell 				continue;
105923b5cc2aSJani Nikula 		} else if (node->dev_name || consumer_dev_name) {
106023b5cc2aSJani Nikula 			continue;
106123b5cc2aSJani Nikula 		}
106223b5cc2aSJani Nikula 
10636001e13cSDavid Brownell 		if (strcmp(node->supply, supply) != 0)
10646001e13cSDavid Brownell 			continue;
10656001e13cSDavid Brownell 
1066737f360dSMark Brown 		pr_debug("%s: %s/%s is '%s' supply; fail %s/%s\n",
1067737f360dSMark Brown 			 consumer_dev_name,
10686001e13cSDavid Brownell 			 dev_name(&node->regulator->dev),
10696001e13cSDavid Brownell 			 node->regulator->desc->name,
10706001e13cSDavid Brownell 			 supply,
10711083c393SMark Brown 			 dev_name(&rdev->dev), rdev_get_name(rdev));
10726001e13cSDavid Brownell 		return -EBUSY;
10736001e13cSDavid Brownell 	}
10746001e13cSDavid Brownell 
10759ed2099eSMark Brown 	node = kzalloc(sizeof(struct regulator_map), GFP_KERNEL);
1076a5766f11SLiam Girdwood 	if (node == NULL)
1077a5766f11SLiam Girdwood 		return -ENOMEM;
1078a5766f11SLiam Girdwood 
1079a5766f11SLiam Girdwood 	node->regulator = rdev;
1080a5766f11SLiam Girdwood 	node->supply = supply;
1081a5766f11SLiam Girdwood 
10829ed2099eSMark Brown 	if (has_dev) {
10839ed2099eSMark Brown 		node->dev_name = kstrdup(consumer_dev_name, GFP_KERNEL);
108440f9244fSMark Brown 		if (node->dev_name == NULL) {
108540f9244fSMark Brown 			kfree(node);
108640f9244fSMark Brown 			return -ENOMEM;
108740f9244fSMark Brown 		}
10889ed2099eSMark Brown 	}
108940f9244fSMark Brown 
1090a5766f11SLiam Girdwood 	list_add(&node->list, &regulator_map_list);
1091a5766f11SLiam Girdwood 	return 0;
1092a5766f11SLiam Girdwood }
1093a5766f11SLiam Girdwood 
10940f1d747bSMike Rapoport static void unset_regulator_supplies(struct regulator_dev *rdev)
10950f1d747bSMike Rapoport {
10960f1d747bSMike Rapoport 	struct regulator_map *node, *n;
10970f1d747bSMike Rapoport 
10980f1d747bSMike Rapoport 	list_for_each_entry_safe(node, n, &regulator_map_list, list) {
10990f1d747bSMike Rapoport 		if (rdev == node->regulator) {
11000f1d747bSMike Rapoport 			list_del(&node->list);
110140f9244fSMark Brown 			kfree(node->dev_name);
11020f1d747bSMike Rapoport 			kfree(node);
11030f1d747bSMike Rapoport 		}
11040f1d747bSMike Rapoport 	}
11050f1d747bSMike Rapoport }
11060f1d747bSMike Rapoport 
1107f5726ae3SMark Brown #define REG_STR_SIZE	64
1108414c70cbSLiam Girdwood 
1109414c70cbSLiam Girdwood static struct regulator *create_regulator(struct regulator_dev *rdev,
1110414c70cbSLiam Girdwood 					  struct device *dev,
1111414c70cbSLiam Girdwood 					  const char *supply_name)
1112414c70cbSLiam Girdwood {
1113414c70cbSLiam Girdwood 	struct regulator *regulator;
1114414c70cbSLiam Girdwood 	char buf[REG_STR_SIZE];
1115414c70cbSLiam Girdwood 	int err, size;
1116414c70cbSLiam Girdwood 
1117414c70cbSLiam Girdwood 	regulator = kzalloc(sizeof(*regulator), GFP_KERNEL);
1118414c70cbSLiam Girdwood 	if (regulator == NULL)
1119414c70cbSLiam Girdwood 		return NULL;
1120414c70cbSLiam Girdwood 
1121414c70cbSLiam Girdwood 	mutex_lock(&rdev->mutex);
1122414c70cbSLiam Girdwood 	regulator->rdev = rdev;
1123414c70cbSLiam Girdwood 	list_add(&regulator->list, &rdev->consumer_list);
1124414c70cbSLiam Girdwood 
1125414c70cbSLiam Girdwood 	if (dev) {
1126e2c98eafSShawn Guo 		regulator->dev = dev;
1127e2c98eafSShawn Guo 
1128222cc7b1SMark Brown 		/* Add a link to the device sysfs entry */
1129414c70cbSLiam Girdwood 		size = scnprintf(buf, REG_STR_SIZE, "%s-%s",
1130414c70cbSLiam Girdwood 				 dev->kobj.name, supply_name);
1131414c70cbSLiam Girdwood 		if (size >= REG_STR_SIZE)
1132222cc7b1SMark Brown 			goto overflow_err;
1133414c70cbSLiam Girdwood 
1134414c70cbSLiam Girdwood 		regulator->supply_name = kstrdup(buf, GFP_KERNEL);
1135414c70cbSLiam Girdwood 		if (regulator->supply_name == NULL)
1136222cc7b1SMark Brown 			goto overflow_err;
1137414c70cbSLiam Girdwood 
1138414c70cbSLiam Girdwood 		err = sysfs_create_link(&rdev->dev.kobj, &dev->kobj,
1139414c70cbSLiam Girdwood 					buf);
1140414c70cbSLiam Girdwood 		if (err) {
11415da84fd9SJoe Perches 			rdev_warn(rdev, "could not add device link %s err %d\n",
11421d7372e1SDaniel Walker 				  dev->kobj.name, err);
1143222cc7b1SMark Brown 			/* non-fatal */
1144414c70cbSLiam Girdwood 		}
11455de70519SMark Brown 	} else {
11465de70519SMark Brown 		regulator->supply_name = kstrdup(supply_name, GFP_KERNEL);
11475de70519SMark Brown 		if (regulator->supply_name == NULL)
1148222cc7b1SMark Brown 			goto overflow_err;
1149414c70cbSLiam Girdwood 	}
11505de70519SMark Brown 
11515de70519SMark Brown 	regulator->debugfs = debugfs_create_dir(regulator->supply_name,
11525de70519SMark Brown 						rdev->debugfs);
115324751434SStephen Boyd 	if (!regulator->debugfs) {
11545de70519SMark Brown 		rdev_warn(rdev, "Failed to create debugfs directory\n");
11555de70519SMark Brown 	} else {
11565de70519SMark Brown 		debugfs_create_u32("uA_load", 0444, regulator->debugfs,
11575de70519SMark Brown 				   &regulator->uA_load);
11585de70519SMark Brown 		debugfs_create_u32("min_uV", 0444, regulator->debugfs,
11595de70519SMark Brown 				   &regulator->min_uV);
11605de70519SMark Brown 		debugfs_create_u32("max_uV", 0444, regulator->debugfs,
11615de70519SMark Brown 				   &regulator->max_uV);
11625de70519SMark Brown 	}
11635de70519SMark Brown 
11646492bc1bSMark Brown 	/*
11656492bc1bSMark Brown 	 * Check now if the regulator is an always on regulator - if
11666492bc1bSMark Brown 	 * it is then we don't need to do nearly so much work for
11676492bc1bSMark Brown 	 * enable/disable calls.
11686492bc1bSMark Brown 	 */
11696492bc1bSMark Brown 	if (!_regulator_can_change_status(rdev) &&
11706492bc1bSMark Brown 	    _regulator_is_enabled(rdev))
11716492bc1bSMark Brown 		regulator->always_on = true;
11726492bc1bSMark Brown 
1173414c70cbSLiam Girdwood 	mutex_unlock(&rdev->mutex);
1174414c70cbSLiam Girdwood 	return regulator;
1175414c70cbSLiam Girdwood overflow_err:
1176414c70cbSLiam Girdwood 	list_del(&regulator->list);
1177414c70cbSLiam Girdwood 	kfree(regulator);
1178414c70cbSLiam Girdwood 	mutex_unlock(&rdev->mutex);
1179414c70cbSLiam Girdwood 	return NULL;
1180414c70cbSLiam Girdwood }
1181414c70cbSLiam Girdwood 
118231aae2beSMark Brown static int _regulator_get_enable_time(struct regulator_dev *rdev)
118331aae2beSMark Brown {
118431aae2beSMark Brown 	if (!rdev->desc->ops->enable_time)
118579511ed3SMark Brown 		return rdev->desc->enable_time;
118631aae2beSMark Brown 	return rdev->desc->ops->enable_time(rdev);
118731aae2beSMark Brown }
118831aae2beSMark Brown 
118969511a45SRajendra Nayak static struct regulator_dev *regulator_dev_lookup(struct device *dev,
11906d191a5fSMark Brown 						  const char *supply,
11916d191a5fSMark Brown 						  int *ret)
119269511a45SRajendra Nayak {
119369511a45SRajendra Nayak 	struct regulator_dev *r;
119469511a45SRajendra Nayak 	struct device_node *node;
1195576ca436SMark Brown 	struct regulator_map *map;
1196576ca436SMark Brown 	const char *devname = NULL;
119769511a45SRajendra Nayak 
119869511a45SRajendra Nayak 	/* first do a dt based lookup */
119969511a45SRajendra Nayak 	if (dev && dev->of_node) {
120069511a45SRajendra Nayak 		node = of_get_regulator(dev, supply);
12016d191a5fSMark Brown 		if (node) {
120269511a45SRajendra Nayak 			list_for_each_entry(r, &regulator_list, list)
120369511a45SRajendra Nayak 				if (r->dev.parent &&
120469511a45SRajendra Nayak 					node == r->dev.of_node)
120569511a45SRajendra Nayak 					return r;
12066d191a5fSMark Brown 		} else {
12076d191a5fSMark Brown 			/*
12086d191a5fSMark Brown 			 * If we couldn't even get the node then it's
12096d191a5fSMark Brown 			 * not just that the device didn't register
12106d191a5fSMark Brown 			 * yet, there's no node and we'll never
12116d191a5fSMark Brown 			 * succeed.
12126d191a5fSMark Brown 			 */
12136d191a5fSMark Brown 			*ret = -ENODEV;
12146d191a5fSMark Brown 		}
121569511a45SRajendra Nayak 	}
121669511a45SRajendra Nayak 
121769511a45SRajendra Nayak 	/* if not found, try doing it non-dt way */
1218576ca436SMark Brown 	if (dev)
1219576ca436SMark Brown 		devname = dev_name(dev);
1220576ca436SMark Brown 
122169511a45SRajendra Nayak 	list_for_each_entry(r, &regulator_list, list)
122269511a45SRajendra Nayak 		if (strcmp(rdev_get_name(r), supply) == 0)
122369511a45SRajendra Nayak 			return r;
122469511a45SRajendra Nayak 
1225576ca436SMark Brown 	list_for_each_entry(map, &regulator_map_list, list) {
1226576ca436SMark Brown 		/* If the mapping has a device set up it must match */
1227576ca436SMark Brown 		if (map->dev_name &&
1228576ca436SMark Brown 		    (!devname || strcmp(map->dev_name, devname)))
1229576ca436SMark Brown 			continue;
1230576ca436SMark Brown 
1231576ca436SMark Brown 		if (strcmp(map->supply, supply) == 0)
1232576ca436SMark Brown 			return map->regulator;
1233576ca436SMark Brown 	}
1234576ca436SMark Brown 
1235576ca436SMark Brown 
123669511a45SRajendra Nayak 	return NULL;
123769511a45SRajendra Nayak }
123869511a45SRajendra Nayak 
12395ffbd136SMark Brown /* Internal regulator request function */
12405ffbd136SMark Brown static struct regulator *_regulator_get(struct device *dev, const char *id,
12415ffbd136SMark Brown 					int exclusive)
1242414c70cbSLiam Girdwood {
1243414c70cbSLiam Girdwood 	struct regulator_dev *rdev;
124404bf3011SMark Brown 	struct regulator *regulator = ERR_PTR(-EPROBE_DEFER);
124540f9244fSMark Brown 	const char *devname = NULL;
12461e4b545cSNishanth Menon 	int ret = 0;
1247414c70cbSLiam Girdwood 
1248414c70cbSLiam Girdwood 	if (id == NULL) {
12495da84fd9SJoe Perches 		pr_err("get() with no identifier\n");
1250414c70cbSLiam Girdwood 		return regulator;
1251414c70cbSLiam Girdwood 	}
1252414c70cbSLiam Girdwood 
125340f9244fSMark Brown 	if (dev)
125440f9244fSMark Brown 		devname = dev_name(dev);
125540f9244fSMark Brown 
1256414c70cbSLiam Girdwood 	mutex_lock(&regulator_list_mutex);
1257414c70cbSLiam Girdwood 
12586d191a5fSMark Brown 	rdev = regulator_dev_lookup(dev, id, &ret);
125969511a45SRajendra Nayak 	if (rdev)
126069511a45SRajendra Nayak 		goto found;
126169511a45SRajendra Nayak 
12621e4b545cSNishanth Menon 	/*
12631e4b545cSNishanth Menon 	 * If we have return value from dev_lookup fail, we do not expect to
12641e4b545cSNishanth Menon 	 * succeed, so, quit with appropriate error value
12651e4b545cSNishanth Menon 	 */
12661e4b545cSNishanth Menon 	if (ret) {
12671e4b545cSNishanth Menon 		regulator = ERR_PTR(ret);
12681e4b545cSNishanth Menon 		goto out;
12691e4b545cSNishanth Menon 	}
12701e4b545cSNishanth Menon 
1271688fe99aSMark Brown 	if (board_wants_dummy_regulator) {
1272688fe99aSMark Brown 		rdev = dummy_regulator_rdev;
1273688fe99aSMark Brown 		goto found;
1274688fe99aSMark Brown 	}
1275688fe99aSMark Brown 
127634abbd68SMark Brown #ifdef CONFIG_REGULATOR_DUMMY
127734abbd68SMark Brown 	if (!devname)
127834abbd68SMark Brown 		devname = "deviceless";
127934abbd68SMark Brown 
128034abbd68SMark Brown 	/* If the board didn't flag that it was fully constrained then
128134abbd68SMark Brown 	 * substitute in a dummy regulator so consumers can continue.
128234abbd68SMark Brown 	 */
128334abbd68SMark Brown 	if (!has_full_constraints) {
12845da84fd9SJoe Perches 		pr_warn("%s supply %s not found, using dummy regulator\n",
128534abbd68SMark Brown 			devname, id);
128634abbd68SMark Brown 		rdev = dummy_regulator_rdev;
128734abbd68SMark Brown 		goto found;
128834abbd68SMark Brown 	}
128934abbd68SMark Brown #endif
129034abbd68SMark Brown 
1291414c70cbSLiam Girdwood 	mutex_unlock(&regulator_list_mutex);
1292414c70cbSLiam Girdwood 	return regulator;
1293414c70cbSLiam Girdwood 
1294414c70cbSLiam Girdwood found:
12955ffbd136SMark Brown 	if (rdev->exclusive) {
12965ffbd136SMark Brown 		regulator = ERR_PTR(-EPERM);
12975ffbd136SMark Brown 		goto out;
12985ffbd136SMark Brown 	}
12995ffbd136SMark Brown 
13005ffbd136SMark Brown 	if (exclusive && rdev->open_count) {
13015ffbd136SMark Brown 		regulator = ERR_PTR(-EBUSY);
13025ffbd136SMark Brown 		goto out;
13035ffbd136SMark Brown 	}
13045ffbd136SMark Brown 
1305a5766f11SLiam Girdwood 	if (!try_module_get(rdev->owner))
1306a5766f11SLiam Girdwood 		goto out;
1307a5766f11SLiam Girdwood 
1308414c70cbSLiam Girdwood 	regulator = create_regulator(rdev, dev, id);
1309414c70cbSLiam Girdwood 	if (regulator == NULL) {
1310414c70cbSLiam Girdwood 		regulator = ERR_PTR(-ENOMEM);
1311414c70cbSLiam Girdwood 		module_put(rdev->owner);
1312bcda4321SAxel Lin 		goto out;
1313414c70cbSLiam Girdwood 	}
1314414c70cbSLiam Girdwood 
13155ffbd136SMark Brown 	rdev->open_count++;
13165ffbd136SMark Brown 	if (exclusive) {
13175ffbd136SMark Brown 		rdev->exclusive = 1;
13185ffbd136SMark Brown 
13195ffbd136SMark Brown 		ret = _regulator_is_enabled(rdev);
13205ffbd136SMark Brown 		if (ret > 0)
13215ffbd136SMark Brown 			rdev->use_count = 1;
13225ffbd136SMark Brown 		else
13235ffbd136SMark Brown 			rdev->use_count = 0;
13245ffbd136SMark Brown 	}
13255ffbd136SMark Brown 
1326a5766f11SLiam Girdwood out:
1327414c70cbSLiam Girdwood 	mutex_unlock(&regulator_list_mutex);
13285ffbd136SMark Brown 
1329414c70cbSLiam Girdwood 	return regulator;
1330414c70cbSLiam Girdwood }
13315ffbd136SMark Brown 
13325ffbd136SMark Brown /**
13335ffbd136SMark Brown  * regulator_get - lookup and obtain a reference to a regulator.
13345ffbd136SMark Brown  * @dev: device for regulator "consumer"
13355ffbd136SMark Brown  * @id: Supply name or regulator ID.
13365ffbd136SMark Brown  *
13375ffbd136SMark Brown  * Returns a struct regulator corresponding to the regulator producer,
13385ffbd136SMark Brown  * or IS_ERR() condition containing errno.
13395ffbd136SMark Brown  *
13405ffbd136SMark Brown  * Use of supply names configured via regulator_set_device_supply() is
13415ffbd136SMark Brown  * strongly encouraged.  It is recommended that the supply name used
13425ffbd136SMark Brown  * should match the name used for the supply and/or the relevant
13435ffbd136SMark Brown  * device pins in the datasheet.
13445ffbd136SMark Brown  */
13455ffbd136SMark Brown struct regulator *regulator_get(struct device *dev, const char *id)
13465ffbd136SMark Brown {
13475ffbd136SMark Brown 	return _regulator_get(dev, id, 0);
13485ffbd136SMark Brown }
1349414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_get);
1350414c70cbSLiam Girdwood 
1351070b9079SStephen Boyd static void devm_regulator_release(struct device *dev, void *res)
1352070b9079SStephen Boyd {
1353070b9079SStephen Boyd 	regulator_put(*(struct regulator **)res);
1354070b9079SStephen Boyd }
1355070b9079SStephen Boyd 
1356070b9079SStephen Boyd /**
1357070b9079SStephen Boyd  * devm_regulator_get - Resource managed regulator_get()
1358070b9079SStephen Boyd  * @dev: device for regulator "consumer"
1359070b9079SStephen Boyd  * @id: Supply name or regulator ID.
1360070b9079SStephen Boyd  *
1361070b9079SStephen Boyd  * Managed regulator_get(). Regulators returned from this function are
1362070b9079SStephen Boyd  * automatically regulator_put() on driver detach. See regulator_get() for more
1363070b9079SStephen Boyd  * information.
1364070b9079SStephen Boyd  */
1365070b9079SStephen Boyd struct regulator *devm_regulator_get(struct device *dev, const char *id)
1366070b9079SStephen Boyd {
1367070b9079SStephen Boyd 	struct regulator **ptr, *regulator;
1368070b9079SStephen Boyd 
1369070b9079SStephen Boyd 	ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL);
1370070b9079SStephen Boyd 	if (!ptr)
1371070b9079SStephen Boyd 		return ERR_PTR(-ENOMEM);
1372070b9079SStephen Boyd 
1373070b9079SStephen Boyd 	regulator = regulator_get(dev, id);
1374070b9079SStephen Boyd 	if (!IS_ERR(regulator)) {
1375070b9079SStephen Boyd 		*ptr = regulator;
1376070b9079SStephen Boyd 		devres_add(dev, ptr);
1377070b9079SStephen Boyd 	} else {
1378070b9079SStephen Boyd 		devres_free(ptr);
1379070b9079SStephen Boyd 	}
1380070b9079SStephen Boyd 
1381070b9079SStephen Boyd 	return regulator;
1382070b9079SStephen Boyd }
1383070b9079SStephen Boyd EXPORT_SYMBOL_GPL(devm_regulator_get);
1384070b9079SStephen Boyd 
1385414c70cbSLiam Girdwood /**
13865ffbd136SMark Brown  * regulator_get_exclusive - obtain exclusive access to a regulator.
13875ffbd136SMark Brown  * @dev: device for regulator "consumer"
13885ffbd136SMark Brown  * @id: Supply name or regulator ID.
13895ffbd136SMark Brown  *
13905ffbd136SMark Brown  * Returns a struct regulator corresponding to the regulator producer,
13915ffbd136SMark Brown  * or IS_ERR() condition containing errno.  Other consumers will be
13925ffbd136SMark Brown  * unable to obtain this reference is held and the use count for the
13935ffbd136SMark Brown  * regulator will be initialised to reflect the current state of the
13945ffbd136SMark Brown  * regulator.
13955ffbd136SMark Brown  *
13965ffbd136SMark Brown  * This is intended for use by consumers which cannot tolerate shared
13975ffbd136SMark Brown  * use of the regulator such as those which need to force the
13985ffbd136SMark Brown  * regulator off for correct operation of the hardware they are
13995ffbd136SMark Brown  * controlling.
14005ffbd136SMark Brown  *
14015ffbd136SMark Brown  * Use of supply names configured via regulator_set_device_supply() is
14025ffbd136SMark Brown  * strongly encouraged.  It is recommended that the supply name used
14035ffbd136SMark Brown  * should match the name used for the supply and/or the relevant
14045ffbd136SMark Brown  * device pins in the datasheet.
14055ffbd136SMark Brown  */
14065ffbd136SMark Brown struct regulator *regulator_get_exclusive(struct device *dev, const char *id)
14075ffbd136SMark Brown {
14085ffbd136SMark Brown 	return _regulator_get(dev, id, 1);
14095ffbd136SMark Brown }
14105ffbd136SMark Brown EXPORT_SYMBOL_GPL(regulator_get_exclusive);
14115ffbd136SMark Brown 
141223ff2f0fSCharles Keepax /* Locks held by regulator_put() */
141323ff2f0fSCharles Keepax static void _regulator_put(struct regulator *regulator)
1414414c70cbSLiam Girdwood {
1415414c70cbSLiam Girdwood 	struct regulator_dev *rdev;
1416414c70cbSLiam Girdwood 
1417414c70cbSLiam Girdwood 	if (regulator == NULL || IS_ERR(regulator))
1418414c70cbSLiam Girdwood 		return;
1419414c70cbSLiam Girdwood 
1420414c70cbSLiam Girdwood 	rdev = regulator->rdev;
1421414c70cbSLiam Girdwood 
14225de70519SMark Brown 	debugfs_remove_recursive(regulator->debugfs);
14235de70519SMark Brown 
1424414c70cbSLiam Girdwood 	/* remove any sysfs entries */
1425e2c98eafSShawn Guo 	if (regulator->dev)
1426414c70cbSLiam Girdwood 		sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name);
14275de70519SMark Brown 	kfree(regulator->supply_name);
1428414c70cbSLiam Girdwood 	list_del(&regulator->list);
1429414c70cbSLiam Girdwood 	kfree(regulator);
1430414c70cbSLiam Girdwood 
14315ffbd136SMark Brown 	rdev->open_count--;
14325ffbd136SMark Brown 	rdev->exclusive = 0;
14335ffbd136SMark Brown 
1434414c70cbSLiam Girdwood 	module_put(rdev->owner);
143523ff2f0fSCharles Keepax }
143623ff2f0fSCharles Keepax 
143723ff2f0fSCharles Keepax /**
143823ff2f0fSCharles Keepax  * regulator_put - "free" the regulator source
143923ff2f0fSCharles Keepax  * @regulator: regulator source
144023ff2f0fSCharles Keepax  *
144123ff2f0fSCharles Keepax  * Note: drivers must ensure that all regulator_enable calls made on this
144223ff2f0fSCharles Keepax  * regulator source are balanced by regulator_disable calls prior to calling
144323ff2f0fSCharles Keepax  * this function.
144423ff2f0fSCharles Keepax  */
144523ff2f0fSCharles Keepax void regulator_put(struct regulator *regulator)
144623ff2f0fSCharles Keepax {
144723ff2f0fSCharles Keepax 	mutex_lock(&regulator_list_mutex);
144823ff2f0fSCharles Keepax 	_regulator_put(regulator);
1449414c70cbSLiam Girdwood 	mutex_unlock(&regulator_list_mutex);
1450414c70cbSLiam Girdwood }
1451414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_put);
1452414c70cbSLiam Girdwood 
1453d5ad34f7SMark Brown static int devm_regulator_match(struct device *dev, void *res, void *data)
1454d5ad34f7SMark Brown {
1455d5ad34f7SMark Brown 	struct regulator **r = res;
1456d5ad34f7SMark Brown 	if (!r || !*r) {
1457d5ad34f7SMark Brown 		WARN_ON(!r || !*r);
1458d5ad34f7SMark Brown 		return 0;
1459d5ad34f7SMark Brown 	}
1460d5ad34f7SMark Brown 	return *r == data;
1461d5ad34f7SMark Brown }
1462d5ad34f7SMark Brown 
1463d5ad34f7SMark Brown /**
1464d5ad34f7SMark Brown  * devm_regulator_put - Resource managed regulator_put()
1465d5ad34f7SMark Brown  * @regulator: regulator to free
1466d5ad34f7SMark Brown  *
1467d5ad34f7SMark Brown  * Deallocate a regulator allocated with devm_regulator_get(). Normally
1468d5ad34f7SMark Brown  * this function will not need to be called and the resource management
1469d5ad34f7SMark Brown  * code will ensure that the resource is freed.
1470d5ad34f7SMark Brown  */
1471d5ad34f7SMark Brown void devm_regulator_put(struct regulator *regulator)
1472d5ad34f7SMark Brown {
1473d5ad34f7SMark Brown 	int rc;
1474d5ad34f7SMark Brown 
1475361ff501SMark Brown 	rc = devres_release(regulator->dev, devm_regulator_release,
1476d5ad34f7SMark Brown 			    devm_regulator_match, regulator);
1477230a5a1cSMark Brown 	if (rc != 0)
1478d5ad34f7SMark Brown 		WARN_ON(rc);
1479d5ad34f7SMark Brown }
1480d5ad34f7SMark Brown EXPORT_SYMBOL_GPL(devm_regulator_put);
1481d5ad34f7SMark Brown 
1482f19b00daSKim, Milo /* Manage enable GPIO list. Same GPIO pin can be shared among regulators */
1483f19b00daSKim, Milo static int regulator_ena_gpio_request(struct regulator_dev *rdev,
1484f19b00daSKim, Milo 				const struct regulator_config *config)
1485f19b00daSKim, Milo {
1486f19b00daSKim, Milo 	struct regulator_enable_gpio *pin;
1487f19b00daSKim, Milo 	int ret;
1488f19b00daSKim, Milo 
1489f19b00daSKim, Milo 	list_for_each_entry(pin, &regulator_ena_gpio_list, list) {
1490f19b00daSKim, Milo 		if (pin->gpio == config->ena_gpio) {
1491f19b00daSKim, Milo 			rdev_dbg(rdev, "GPIO %d is already used\n",
1492f19b00daSKim, Milo 				config->ena_gpio);
1493f19b00daSKim, Milo 			goto update_ena_gpio_to_rdev;
1494f19b00daSKim, Milo 		}
1495f19b00daSKim, Milo 	}
1496f19b00daSKim, Milo 
1497f19b00daSKim, Milo 	ret = gpio_request_one(config->ena_gpio,
1498f19b00daSKim, Milo 				GPIOF_DIR_OUT | config->ena_gpio_flags,
1499f19b00daSKim, Milo 				rdev_get_name(rdev));
1500f19b00daSKim, Milo 	if (ret)
1501f19b00daSKim, Milo 		return ret;
1502f19b00daSKim, Milo 
1503f19b00daSKim, Milo 	pin = kzalloc(sizeof(struct regulator_enable_gpio), GFP_KERNEL);
1504f19b00daSKim, Milo 	if (pin == NULL) {
1505f19b00daSKim, Milo 		gpio_free(config->ena_gpio);
1506f19b00daSKim, Milo 		return -ENOMEM;
1507f19b00daSKim, Milo 	}
1508f19b00daSKim, Milo 
1509f19b00daSKim, Milo 	pin->gpio = config->ena_gpio;
1510f19b00daSKim, Milo 	pin->ena_gpio_invert = config->ena_gpio_invert;
1511f19b00daSKim, Milo 	list_add(&pin->list, &regulator_ena_gpio_list);
1512f19b00daSKim, Milo 
1513f19b00daSKim, Milo update_ena_gpio_to_rdev:
1514f19b00daSKim, Milo 	pin->request_count++;
1515f19b00daSKim, Milo 	rdev->ena_pin = pin;
1516f19b00daSKim, Milo 	return 0;
1517f19b00daSKim, Milo }
1518f19b00daSKim, Milo 
1519f19b00daSKim, Milo static void regulator_ena_gpio_free(struct regulator_dev *rdev)
1520f19b00daSKim, Milo {
1521f19b00daSKim, Milo 	struct regulator_enable_gpio *pin, *n;
1522f19b00daSKim, Milo 
1523f19b00daSKim, Milo 	if (!rdev->ena_pin)
1524f19b00daSKim, Milo 		return;
1525f19b00daSKim, Milo 
1526f19b00daSKim, Milo 	/* Free the GPIO only in case of no use */
1527f19b00daSKim, Milo 	list_for_each_entry_safe(pin, n, &regulator_ena_gpio_list, list) {
1528f19b00daSKim, Milo 		if (pin->gpio == rdev->ena_pin->gpio) {
1529f19b00daSKim, Milo 			if (pin->request_count <= 1) {
1530f19b00daSKim, Milo 				pin->request_count = 0;
1531f19b00daSKim, Milo 				gpio_free(pin->gpio);
1532f19b00daSKim, Milo 				list_del(&pin->list);
1533f19b00daSKim, Milo 				kfree(pin);
1534f19b00daSKim, Milo 			} else {
1535f19b00daSKim, Milo 				pin->request_count--;
1536f19b00daSKim, Milo 			}
1537f19b00daSKim, Milo 		}
1538f19b00daSKim, Milo 	}
1539f19b00daSKim, Milo }
1540f19b00daSKim, Milo 
1541967cfb18SKim, Milo /**
154231d6eebfSRobert P. J. Day  * regulator_ena_gpio_ctrl - balance enable_count of each GPIO and actual GPIO pin control
154331d6eebfSRobert P. J. Day  * @rdev: regulator_dev structure
154431d6eebfSRobert P. J. Day  * @enable: enable GPIO at initial use?
154531d6eebfSRobert P. J. Day  *
1546967cfb18SKim, Milo  * GPIO is enabled in case of initial use. (enable_count is 0)
1547967cfb18SKim, Milo  * GPIO is disabled when it is not shared any more. (enable_count <= 1)
1548967cfb18SKim, Milo  */
1549967cfb18SKim, Milo static int regulator_ena_gpio_ctrl(struct regulator_dev *rdev, bool enable)
1550967cfb18SKim, Milo {
1551967cfb18SKim, Milo 	struct regulator_enable_gpio *pin = rdev->ena_pin;
1552967cfb18SKim, Milo 
1553967cfb18SKim, Milo 	if (!pin)
1554967cfb18SKim, Milo 		return -EINVAL;
1555967cfb18SKim, Milo 
1556967cfb18SKim, Milo 	if (enable) {
1557967cfb18SKim, Milo 		/* Enable GPIO at initial use */
1558967cfb18SKim, Milo 		if (pin->enable_count == 0)
1559967cfb18SKim, Milo 			gpio_set_value_cansleep(pin->gpio,
1560967cfb18SKim, Milo 						!pin->ena_gpio_invert);
1561967cfb18SKim, Milo 
1562967cfb18SKim, Milo 		pin->enable_count++;
1563967cfb18SKim, Milo 	} else {
1564967cfb18SKim, Milo 		if (pin->enable_count > 1) {
1565967cfb18SKim, Milo 			pin->enable_count--;
1566967cfb18SKim, Milo 			return 0;
1567967cfb18SKim, Milo 		}
1568967cfb18SKim, Milo 
1569967cfb18SKim, Milo 		/* Disable GPIO if not used */
1570967cfb18SKim, Milo 		if (pin->enable_count <= 1) {
1571967cfb18SKim, Milo 			gpio_set_value_cansleep(pin->gpio,
1572967cfb18SKim, Milo 						pin->ena_gpio_invert);
1573967cfb18SKim, Milo 			pin->enable_count = 0;
1574967cfb18SKim, Milo 		}
1575967cfb18SKim, Milo 	}
1576967cfb18SKim, Milo 
1577967cfb18SKim, Milo 	return 0;
1578967cfb18SKim, Milo }
1579967cfb18SKim, Milo 
15805c5659d0SMark Brown static int _regulator_do_enable(struct regulator_dev *rdev)
15815c5659d0SMark Brown {
15825c5659d0SMark Brown 	int ret, delay;
15835c5659d0SMark Brown 
15845c5659d0SMark Brown 	/* Query before enabling in case configuration dependent.  */
15855c5659d0SMark Brown 	ret = _regulator_get_enable_time(rdev);
15865c5659d0SMark Brown 	if (ret >= 0) {
15875c5659d0SMark Brown 		delay = ret;
15885c5659d0SMark Brown 	} else {
15895c5659d0SMark Brown 		rdev_warn(rdev, "enable_time() failed: %d\n", ret);
15905c5659d0SMark Brown 		delay = 0;
15915c5659d0SMark Brown 	}
15925c5659d0SMark Brown 
15935c5659d0SMark Brown 	trace_regulator_enable(rdev_get_name(rdev));
15945c5659d0SMark Brown 
1595967cfb18SKim, Milo 	if (rdev->ena_pin) {
1596967cfb18SKim, Milo 		ret = regulator_ena_gpio_ctrl(rdev, true);
1597967cfb18SKim, Milo 		if (ret < 0)
1598967cfb18SKim, Milo 			return ret;
159965f73508SMark Brown 		rdev->ena_gpio_state = 1;
160065f73508SMark Brown 	} else if (rdev->desc->ops->enable) {
16015c5659d0SMark Brown 		ret = rdev->desc->ops->enable(rdev);
16025c5659d0SMark Brown 		if (ret < 0)
16035c5659d0SMark Brown 			return ret;
16045c5659d0SMark Brown 	} else {
16055c5659d0SMark Brown 		return -EINVAL;
16065c5659d0SMark Brown 	}
16075c5659d0SMark Brown 
16085c5659d0SMark Brown 	/* Allow the regulator to ramp; it would be useful to extend
16095c5659d0SMark Brown 	 * this for bulk operations so that the regulators can ramp
16105c5659d0SMark Brown 	 * together.  */
16115c5659d0SMark Brown 	trace_regulator_enable_delay(rdev_get_name(rdev));
16125c5659d0SMark Brown 
16135c5659d0SMark Brown 	if (delay >= 1000) {
16145c5659d0SMark Brown 		mdelay(delay / 1000);
16155c5659d0SMark Brown 		udelay(delay % 1000);
16165c5659d0SMark Brown 	} else if (delay) {
16175c5659d0SMark Brown 		udelay(delay);
16185c5659d0SMark Brown 	}
16195c5659d0SMark Brown 
16205c5659d0SMark Brown 	trace_regulator_enable_complete(rdev_get_name(rdev));
16215c5659d0SMark Brown 
16225c5659d0SMark Brown 	return 0;
16235c5659d0SMark Brown }
16245c5659d0SMark Brown 
1625414c70cbSLiam Girdwood /* locks held by regulator_enable() */
1626414c70cbSLiam Girdwood static int _regulator_enable(struct regulator_dev *rdev)
1627414c70cbSLiam Girdwood {
16285c5659d0SMark Brown 	int ret;
1629414c70cbSLiam Girdwood 
1630414c70cbSLiam Girdwood 	/* check voltage and requested load before enabling */
1631414c70cbSLiam Girdwood 	if (rdev->constraints &&
16329a2372faSMark Brown 	    (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS))
1633414c70cbSLiam Girdwood 		drms_uA_update(rdev);
1634414c70cbSLiam Girdwood 
16359a2372faSMark Brown 	if (rdev->use_count == 0) {
16369a2372faSMark Brown 		/* The regulator may on if it's not switchable or left on */
16379a2372faSMark Brown 		ret = _regulator_is_enabled(rdev);
16389a2372faSMark Brown 		if (ret == -EINVAL || ret == 0) {
16399a2372faSMark Brown 			if (!_regulator_can_change_status(rdev))
16409a2372faSMark Brown 				return -EPERM;
16419a2372faSMark Brown 
16425c5659d0SMark Brown 			ret = _regulator_do_enable(rdev);
16439a2372faSMark Brown 			if (ret < 0)
16449a2372faSMark Brown 				return ret;
164531aae2beSMark Brown 
1646a7433cffSLinus Walleij 		} else if (ret < 0) {
16475da84fd9SJoe Perches 			rdev_err(rdev, "is_enabled() failed: %d\n", ret);
1648414c70cbSLiam Girdwood 			return ret;
1649414c70cbSLiam Girdwood 		}
1650a7433cffSLinus Walleij 		/* Fallthrough on positive return values - already enabled */
1651414c70cbSLiam Girdwood 	}
1652414c70cbSLiam Girdwood 
16539a2372faSMark Brown 	rdev->use_count++;
16549a2372faSMark Brown 
16559a2372faSMark Brown 	return 0;
1656414c70cbSLiam Girdwood }
1657414c70cbSLiam Girdwood 
1658414c70cbSLiam Girdwood /**
1659414c70cbSLiam Girdwood  * regulator_enable - enable regulator output
1660414c70cbSLiam Girdwood  * @regulator: regulator source
1661414c70cbSLiam Girdwood  *
1662cf7bbcdfSMark Brown  * Request that the regulator be enabled with the regulator output at
1663cf7bbcdfSMark Brown  * the predefined voltage or current value.  Calls to regulator_enable()
1664cf7bbcdfSMark Brown  * must be balanced with calls to regulator_disable().
1665cf7bbcdfSMark Brown  *
1666414c70cbSLiam Girdwood  * NOTE: the output value can be set by other drivers, boot loader or may be
1667cf7bbcdfSMark Brown  * hardwired in the regulator.
1668414c70cbSLiam Girdwood  */
1669414c70cbSLiam Girdwood int regulator_enable(struct regulator *regulator)
1670414c70cbSLiam Girdwood {
1671412aec61SDavid Brownell 	struct regulator_dev *rdev = regulator->rdev;
1672412aec61SDavid Brownell 	int ret = 0;
1673414c70cbSLiam Girdwood 
16746492bc1bSMark Brown 	if (regulator->always_on)
16756492bc1bSMark Brown 		return 0;
16766492bc1bSMark Brown 
16773801b86aSMark Brown 	if (rdev->supply) {
16783801b86aSMark Brown 		ret = regulator_enable(rdev->supply);
16793801b86aSMark Brown 		if (ret != 0)
16803801b86aSMark Brown 			return ret;
16813801b86aSMark Brown 	}
16823801b86aSMark Brown 
1683412aec61SDavid Brownell 	mutex_lock(&rdev->mutex);
1684412aec61SDavid Brownell 	ret = _regulator_enable(rdev);
1685412aec61SDavid Brownell 	mutex_unlock(&rdev->mutex);
16863801b86aSMark Brown 
1687d1685e4eSHeiko Stübner 	if (ret != 0 && rdev->supply)
16883801b86aSMark Brown 		regulator_disable(rdev->supply);
16893801b86aSMark Brown 
1690414c70cbSLiam Girdwood 	return ret;
1691414c70cbSLiam Girdwood }
1692414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_enable);
1693414c70cbSLiam Girdwood 
16945c5659d0SMark Brown static int _regulator_do_disable(struct regulator_dev *rdev)
16955c5659d0SMark Brown {
16965c5659d0SMark Brown 	int ret;
16975c5659d0SMark Brown 
16985c5659d0SMark Brown 	trace_regulator_disable(rdev_get_name(rdev));
16995c5659d0SMark Brown 
1700967cfb18SKim, Milo 	if (rdev->ena_pin) {
1701967cfb18SKim, Milo 		ret = regulator_ena_gpio_ctrl(rdev, false);
1702967cfb18SKim, Milo 		if (ret < 0)
1703967cfb18SKim, Milo 			return ret;
17045c5659d0SMark Brown 		rdev->ena_gpio_state = 0;
17055c5659d0SMark Brown 
17065c5659d0SMark Brown 	} else if (rdev->desc->ops->disable) {
17075c5659d0SMark Brown 		ret = rdev->desc->ops->disable(rdev);
17085c5659d0SMark Brown 		if (ret != 0)
17095c5659d0SMark Brown 			return ret;
17105c5659d0SMark Brown 	}
17115c5659d0SMark Brown 
17125c5659d0SMark Brown 	trace_regulator_disable_complete(rdev_get_name(rdev));
17135c5659d0SMark Brown 
17145c5659d0SMark Brown 	_notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE,
17155c5659d0SMark Brown 			     NULL);
17165c5659d0SMark Brown 	return 0;
17175c5659d0SMark Brown }
17185c5659d0SMark Brown 
1719414c70cbSLiam Girdwood /* locks held by regulator_disable() */
17203801b86aSMark Brown static int _regulator_disable(struct regulator_dev *rdev)
1721414c70cbSLiam Girdwood {
1722414c70cbSLiam Girdwood 	int ret = 0;
1723414c70cbSLiam Girdwood 
1724cd94b505SDavid Brownell 	if (WARN(rdev->use_count <= 0,
172543e7ee33SJoe Perches 		 "unbalanced disables for %s\n", rdev_get_name(rdev)))
1726cd94b505SDavid Brownell 		return -EIO;
1727cd94b505SDavid Brownell 
1728414c70cbSLiam Girdwood 	/* are we the last user and permitted to disable ? */
172960ef66fcSMark Brown 	if (rdev->use_count == 1 &&
173060ef66fcSMark Brown 	    (rdev->constraints && !rdev->constraints->always_on)) {
1731414c70cbSLiam Girdwood 
1732414c70cbSLiam Girdwood 		/* we are last user */
17335c5659d0SMark Brown 		if (_regulator_can_change_status(rdev)) {
17345c5659d0SMark Brown 			ret = _regulator_do_disable(rdev);
1735414c70cbSLiam Girdwood 			if (ret < 0) {
17365da84fd9SJoe Perches 				rdev_err(rdev, "failed to disable\n");
1737414c70cbSLiam Girdwood 				return ret;
1738414c70cbSLiam Girdwood 			}
1739414c70cbSLiam Girdwood 		}
1740414c70cbSLiam Girdwood 
1741414c70cbSLiam Girdwood 		rdev->use_count = 0;
1742414c70cbSLiam Girdwood 	} else if (rdev->use_count > 1) {
1743414c70cbSLiam Girdwood 
1744414c70cbSLiam Girdwood 		if (rdev->constraints &&
1745414c70cbSLiam Girdwood 			(rdev->constraints->valid_ops_mask &
1746414c70cbSLiam Girdwood 			REGULATOR_CHANGE_DRMS))
1747414c70cbSLiam Girdwood 			drms_uA_update(rdev);
1748414c70cbSLiam Girdwood 
1749414c70cbSLiam Girdwood 		rdev->use_count--;
1750414c70cbSLiam Girdwood 	}
17513801b86aSMark Brown 
1752414c70cbSLiam Girdwood 	return ret;
1753414c70cbSLiam Girdwood }
1754414c70cbSLiam Girdwood 
1755414c70cbSLiam Girdwood /**
1756414c70cbSLiam Girdwood  * regulator_disable - disable regulator output
1757414c70cbSLiam Girdwood  * @regulator: regulator source
1758414c70cbSLiam Girdwood  *
1759cf7bbcdfSMark Brown  * Disable the regulator output voltage or current.  Calls to
1760cf7bbcdfSMark Brown  * regulator_enable() must be balanced with calls to
1761cf7bbcdfSMark Brown  * regulator_disable().
176269279fb9SMark Brown  *
1763414c70cbSLiam Girdwood  * NOTE: this will only disable the regulator output if no other consumer
1764cf7bbcdfSMark Brown  * devices have it enabled, the regulator device supports disabling and
1765cf7bbcdfSMark Brown  * machine constraints permit this operation.
1766414c70cbSLiam Girdwood  */
1767414c70cbSLiam Girdwood int regulator_disable(struct regulator *regulator)
1768414c70cbSLiam Girdwood {
1769412aec61SDavid Brownell 	struct regulator_dev *rdev = regulator->rdev;
1770412aec61SDavid Brownell 	int ret = 0;
1771414c70cbSLiam Girdwood 
17726492bc1bSMark Brown 	if (regulator->always_on)
17736492bc1bSMark Brown 		return 0;
17746492bc1bSMark Brown 
1775412aec61SDavid Brownell 	mutex_lock(&rdev->mutex);
17763801b86aSMark Brown 	ret = _regulator_disable(rdev);
1777412aec61SDavid Brownell 	mutex_unlock(&rdev->mutex);
17788cbf811dSJeffrey Carlyle 
17793801b86aSMark Brown 	if (ret == 0 && rdev->supply)
17803801b86aSMark Brown 		regulator_disable(rdev->supply);
17818cbf811dSJeffrey Carlyle 
1782414c70cbSLiam Girdwood 	return ret;
1783414c70cbSLiam Girdwood }
1784414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_disable);
1785414c70cbSLiam Girdwood 
1786414c70cbSLiam Girdwood /* locks held by regulator_force_disable() */
17873801b86aSMark Brown static int _regulator_force_disable(struct regulator_dev *rdev)
1788414c70cbSLiam Girdwood {
1789414c70cbSLiam Girdwood 	int ret = 0;
1790414c70cbSLiam Girdwood 
1791414c70cbSLiam Girdwood 	/* force disable */
1792414c70cbSLiam Girdwood 	if (rdev->desc->ops->disable) {
1793414c70cbSLiam Girdwood 		/* ah well, who wants to live forever... */
1794414c70cbSLiam Girdwood 		ret = rdev->desc->ops->disable(rdev);
1795414c70cbSLiam Girdwood 		if (ret < 0) {
17965da84fd9SJoe Perches 			rdev_err(rdev, "failed to force disable\n");
1797414c70cbSLiam Girdwood 			return ret;
1798414c70cbSLiam Girdwood 		}
1799414c70cbSLiam Girdwood 		/* notify other consumers that power has been forced off */
180084b68263SMark Brown 		_notifier_call_chain(rdev, REGULATOR_EVENT_FORCE_DISABLE |
180184b68263SMark Brown 			REGULATOR_EVENT_DISABLE, NULL);
1802414c70cbSLiam Girdwood 	}
1803414c70cbSLiam Girdwood 
1804414c70cbSLiam Girdwood 	return ret;
1805414c70cbSLiam Girdwood }
1806414c70cbSLiam Girdwood 
1807414c70cbSLiam Girdwood /**
1808414c70cbSLiam Girdwood  * regulator_force_disable - force disable regulator output
1809414c70cbSLiam Girdwood  * @regulator: regulator source
1810414c70cbSLiam Girdwood  *
1811414c70cbSLiam Girdwood  * Forcibly disable the regulator output voltage or current.
1812414c70cbSLiam Girdwood  * NOTE: this *will* disable the regulator output even if other consumer
1813414c70cbSLiam Girdwood  * devices have it enabled. This should be used for situations when device
1814414c70cbSLiam Girdwood  * damage will likely occur if the regulator is not disabled (e.g. over temp).
1815414c70cbSLiam Girdwood  */
1816414c70cbSLiam Girdwood int regulator_force_disable(struct regulator *regulator)
1817414c70cbSLiam Girdwood {
181882d15839SMark Brown 	struct regulator_dev *rdev = regulator->rdev;
1819414c70cbSLiam Girdwood 	int ret;
1820414c70cbSLiam Girdwood 
182182d15839SMark Brown 	mutex_lock(&rdev->mutex);
1822414c70cbSLiam Girdwood 	regulator->uA_load = 0;
18233801b86aSMark Brown 	ret = _regulator_force_disable(regulator->rdev);
182482d15839SMark Brown 	mutex_unlock(&rdev->mutex);
18258cbf811dSJeffrey Carlyle 
18263801b86aSMark Brown 	if (rdev->supply)
18273801b86aSMark Brown 		while (rdev->open_count--)
18283801b86aSMark Brown 			regulator_disable(rdev->supply);
18298cbf811dSJeffrey Carlyle 
1830414c70cbSLiam Girdwood 	return ret;
1831414c70cbSLiam Girdwood }
1832414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_force_disable);
1833414c70cbSLiam Girdwood 
1834da07ecd9SMark Brown static void regulator_disable_work(struct work_struct *work)
1835da07ecd9SMark Brown {
1836da07ecd9SMark Brown 	struct regulator_dev *rdev = container_of(work, struct regulator_dev,
1837da07ecd9SMark Brown 						  disable_work.work);
1838da07ecd9SMark Brown 	int count, i, ret;
1839da07ecd9SMark Brown 
1840da07ecd9SMark Brown 	mutex_lock(&rdev->mutex);
1841da07ecd9SMark Brown 
1842da07ecd9SMark Brown 	BUG_ON(!rdev->deferred_disables);
1843da07ecd9SMark Brown 
1844da07ecd9SMark Brown 	count = rdev->deferred_disables;
1845da07ecd9SMark Brown 	rdev->deferred_disables = 0;
1846da07ecd9SMark Brown 
1847da07ecd9SMark Brown 	for (i = 0; i < count; i++) {
1848da07ecd9SMark Brown 		ret = _regulator_disable(rdev);
1849da07ecd9SMark Brown 		if (ret != 0)
1850da07ecd9SMark Brown 			rdev_err(rdev, "Deferred disable failed: %d\n", ret);
1851da07ecd9SMark Brown 	}
1852da07ecd9SMark Brown 
1853da07ecd9SMark Brown 	mutex_unlock(&rdev->mutex);
1854da07ecd9SMark Brown 
1855da07ecd9SMark Brown 	if (rdev->supply) {
1856da07ecd9SMark Brown 		for (i = 0; i < count; i++) {
1857da07ecd9SMark Brown 			ret = regulator_disable(rdev->supply);
1858da07ecd9SMark Brown 			if (ret != 0) {
1859da07ecd9SMark Brown 				rdev_err(rdev,
1860da07ecd9SMark Brown 					 "Supply disable failed: %d\n", ret);
1861da07ecd9SMark Brown 			}
1862da07ecd9SMark Brown 		}
1863da07ecd9SMark Brown 	}
1864da07ecd9SMark Brown }
1865da07ecd9SMark Brown 
1866da07ecd9SMark Brown /**
1867da07ecd9SMark Brown  * regulator_disable_deferred - disable regulator output with delay
1868da07ecd9SMark Brown  * @regulator: regulator source
1869da07ecd9SMark Brown  * @ms: miliseconds until the regulator is disabled
1870da07ecd9SMark Brown  *
1871da07ecd9SMark Brown  * Execute regulator_disable() on the regulator after a delay.  This
1872da07ecd9SMark Brown  * is intended for use with devices that require some time to quiesce.
1873da07ecd9SMark Brown  *
1874da07ecd9SMark Brown  * NOTE: this will only disable the regulator output if no other consumer
1875da07ecd9SMark Brown  * devices have it enabled, the regulator device supports disabling and
1876da07ecd9SMark Brown  * machine constraints permit this operation.
1877da07ecd9SMark Brown  */
1878da07ecd9SMark Brown int regulator_disable_deferred(struct regulator *regulator, int ms)
1879da07ecd9SMark Brown {
1880da07ecd9SMark Brown 	struct regulator_dev *rdev = regulator->rdev;
1881aa59802dSMark Brown 	int ret;
1882da07ecd9SMark Brown 
18836492bc1bSMark Brown 	if (regulator->always_on)
18846492bc1bSMark Brown 		return 0;
18856492bc1bSMark Brown 
18862b5a24a0SMark Brown 	if (!ms)
18872b5a24a0SMark Brown 		return regulator_disable(regulator);
18882b5a24a0SMark Brown 
1889da07ecd9SMark Brown 	mutex_lock(&rdev->mutex);
1890da07ecd9SMark Brown 	rdev->deferred_disables++;
1891da07ecd9SMark Brown 	mutex_unlock(&rdev->mutex);
1892da07ecd9SMark Brown 
1893070260f0SMark Brown 	ret = queue_delayed_work(system_power_efficient_wq,
1894070260f0SMark Brown 				 &rdev->disable_work,
1895da07ecd9SMark Brown 				 msecs_to_jiffies(ms));
1896aa59802dSMark Brown 	if (ret < 0)
1897aa59802dSMark Brown 		return ret;
1898aa59802dSMark Brown 	else
1899aa59802dSMark Brown 		return 0;
1900da07ecd9SMark Brown }
1901da07ecd9SMark Brown EXPORT_SYMBOL_GPL(regulator_disable_deferred);
1902da07ecd9SMark Brown 
1903cd6dffb4SMark Brown /**
1904cd6dffb4SMark Brown  * regulator_is_enabled_regmap - standard is_enabled() for regmap users
1905cd6dffb4SMark Brown  *
1906cd6dffb4SMark Brown  * @rdev: regulator to operate on
1907cd6dffb4SMark Brown  *
1908cd6dffb4SMark Brown  * Regulators that use regmap for their register I/O can set the
1909cd6dffb4SMark Brown  * enable_reg and enable_mask fields in their descriptor and then use
1910cd6dffb4SMark Brown  * this as their is_enabled operation, saving some code.
1911cd6dffb4SMark Brown  */
1912cd6dffb4SMark Brown int regulator_is_enabled_regmap(struct regulator_dev *rdev)
1913cd6dffb4SMark Brown {
1914cd6dffb4SMark Brown 	unsigned int val;
1915cd6dffb4SMark Brown 	int ret;
1916cd6dffb4SMark Brown 
1917cd6dffb4SMark Brown 	ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val);
1918cd6dffb4SMark Brown 	if (ret != 0)
1919cd6dffb4SMark Brown 		return ret;
1920cd6dffb4SMark Brown 
192151dcdafcSAxel Lin 	if (rdev->desc->enable_is_inverted)
192251dcdafcSAxel Lin 		return (val & rdev->desc->enable_mask) == 0;
192351dcdafcSAxel Lin 	else
1924cd6dffb4SMark Brown 		return (val & rdev->desc->enable_mask) != 0;
1925cd6dffb4SMark Brown }
1926cd6dffb4SMark Brown EXPORT_SYMBOL_GPL(regulator_is_enabled_regmap);
1927cd6dffb4SMark Brown 
1928cd6dffb4SMark Brown /**
1929cd6dffb4SMark Brown  * regulator_enable_regmap - standard enable() for regmap users
1930cd6dffb4SMark Brown  *
1931cd6dffb4SMark Brown  * @rdev: regulator to operate on
1932cd6dffb4SMark Brown  *
1933cd6dffb4SMark Brown  * Regulators that use regmap for their register I/O can set the
1934cd6dffb4SMark Brown  * enable_reg and enable_mask fields in their descriptor and then use
1935cd6dffb4SMark Brown  * this as their enable() operation, saving some code.
1936cd6dffb4SMark Brown  */
1937cd6dffb4SMark Brown int regulator_enable_regmap(struct regulator_dev *rdev)
1938cd6dffb4SMark Brown {
193951dcdafcSAxel Lin 	unsigned int val;
194051dcdafcSAxel Lin 
194151dcdafcSAxel Lin 	if (rdev->desc->enable_is_inverted)
194251dcdafcSAxel Lin 		val = 0;
194351dcdafcSAxel Lin 	else
194451dcdafcSAxel Lin 		val = rdev->desc->enable_mask;
194551dcdafcSAxel Lin 
1946cd6dffb4SMark Brown 	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
194751dcdafcSAxel Lin 				  rdev->desc->enable_mask, val);
1948cd6dffb4SMark Brown }
1949cd6dffb4SMark Brown EXPORT_SYMBOL_GPL(regulator_enable_regmap);
1950cd6dffb4SMark Brown 
1951cd6dffb4SMark Brown /**
1952cd6dffb4SMark Brown  * regulator_disable_regmap - standard disable() for regmap users
1953cd6dffb4SMark Brown  *
1954cd6dffb4SMark Brown  * @rdev: regulator to operate on
1955cd6dffb4SMark Brown  *
1956cd6dffb4SMark Brown  * Regulators that use regmap for their register I/O can set the
1957cd6dffb4SMark Brown  * enable_reg and enable_mask fields in their descriptor and then use
1958cd6dffb4SMark Brown  * this as their disable() operation, saving some code.
1959cd6dffb4SMark Brown  */
1960cd6dffb4SMark Brown int regulator_disable_regmap(struct regulator_dev *rdev)
1961cd6dffb4SMark Brown {
196251dcdafcSAxel Lin 	unsigned int val;
196351dcdafcSAxel Lin 
196451dcdafcSAxel Lin 	if (rdev->desc->enable_is_inverted)
196551dcdafcSAxel Lin 		val = rdev->desc->enable_mask;
196651dcdafcSAxel Lin 	else
196751dcdafcSAxel Lin 		val = 0;
196851dcdafcSAxel Lin 
1969cd6dffb4SMark Brown 	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
197051dcdafcSAxel Lin 				  rdev->desc->enable_mask, val);
1971cd6dffb4SMark Brown }
1972cd6dffb4SMark Brown EXPORT_SYMBOL_GPL(regulator_disable_regmap);
1973cd6dffb4SMark Brown 
1974414c70cbSLiam Girdwood static int _regulator_is_enabled(struct regulator_dev *rdev)
1975414c70cbSLiam Girdwood {
197665f73508SMark Brown 	/* A GPIO control always takes precedence */
19777b74d149SKim, Milo 	if (rdev->ena_pin)
197865f73508SMark Brown 		return rdev->ena_gpio_state;
197965f73508SMark Brown 
19809a7f6a4cSMark Brown 	/* If we don't know then assume that the regulator is always on */
19819332546fSMark Brown 	if (!rdev->desc->ops->is_enabled)
19829a7f6a4cSMark Brown 		return 1;
1983414c70cbSLiam Girdwood 
19849332546fSMark Brown 	return rdev->desc->ops->is_enabled(rdev);
1985414c70cbSLiam Girdwood }
1986414c70cbSLiam Girdwood 
1987414c70cbSLiam Girdwood /**
1988414c70cbSLiam Girdwood  * regulator_is_enabled - is the regulator output enabled
1989414c70cbSLiam Girdwood  * @regulator: regulator source
1990414c70cbSLiam Girdwood  *
1991412aec61SDavid Brownell  * Returns positive if the regulator driver backing the source/client
1992412aec61SDavid Brownell  * has requested that the device be enabled, zero if it hasn't, else a
1993412aec61SDavid Brownell  * negative errno code.
1994412aec61SDavid Brownell  *
1995412aec61SDavid Brownell  * Note that the device backing this regulator handle can have multiple
1996412aec61SDavid Brownell  * users, so it might be enabled even if regulator_enable() was never
1997412aec61SDavid Brownell  * called for this particular source.
1998414c70cbSLiam Girdwood  */
1999414c70cbSLiam Girdwood int regulator_is_enabled(struct regulator *regulator)
2000414c70cbSLiam Girdwood {
20019332546fSMark Brown 	int ret;
20029332546fSMark Brown 
20036492bc1bSMark Brown 	if (regulator->always_on)
20046492bc1bSMark Brown 		return 1;
20056492bc1bSMark Brown 
20069332546fSMark Brown 	mutex_lock(&regulator->rdev->mutex);
20079332546fSMark Brown 	ret = _regulator_is_enabled(regulator->rdev);
20089332546fSMark Brown 	mutex_unlock(&regulator->rdev->mutex);
20099332546fSMark Brown 
20109332546fSMark Brown 	return ret;
2011414c70cbSLiam Girdwood }
2012414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_is_enabled);
2013414c70cbSLiam Girdwood 
2014414c70cbSLiam Girdwood /**
2015d1e7de30SMarek Szyprowski  * regulator_can_change_voltage - check if regulator can change voltage
2016d1e7de30SMarek Szyprowski  * @regulator: regulator source
2017d1e7de30SMarek Szyprowski  *
2018d1e7de30SMarek Szyprowski  * Returns positive if the regulator driver backing the source/client
2019d1e7de30SMarek Szyprowski  * can change its voltage, false otherwise. Usefull for detecting fixed
2020d1e7de30SMarek Szyprowski  * or dummy regulators and disabling voltage change logic in the client
2021d1e7de30SMarek Szyprowski  * driver.
2022d1e7de30SMarek Szyprowski  */
2023d1e7de30SMarek Szyprowski int regulator_can_change_voltage(struct regulator *regulator)
2024d1e7de30SMarek Szyprowski {
2025d1e7de30SMarek Szyprowski 	struct regulator_dev	*rdev = regulator->rdev;
2026d1e7de30SMarek Szyprowski 
2027d1e7de30SMarek Szyprowski 	if (rdev->constraints &&
202819280e40SAxel Lin 	    (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) {
202919280e40SAxel Lin 		if (rdev->desc->n_voltages - rdev->desc->linear_min_sel > 1)
2030d1e7de30SMarek Szyprowski 			return 1;
2031d1e7de30SMarek Szyprowski 
203219280e40SAxel Lin 		if (rdev->desc->continuous_voltage_range &&
203319280e40SAxel Lin 		    rdev->constraints->min_uV && rdev->constraints->max_uV &&
203419280e40SAxel Lin 		    rdev->constraints->min_uV != rdev->constraints->max_uV)
203519280e40SAxel Lin 			return 1;
203619280e40SAxel Lin 	}
203719280e40SAxel Lin 
2038d1e7de30SMarek Szyprowski 	return 0;
2039d1e7de30SMarek Szyprowski }
2040d1e7de30SMarek Szyprowski EXPORT_SYMBOL_GPL(regulator_can_change_voltage);
2041d1e7de30SMarek Szyprowski 
2042d1e7de30SMarek Szyprowski /**
20434367cfdcSDavid Brownell  * regulator_count_voltages - count regulator_list_voltage() selectors
20444367cfdcSDavid Brownell  * @regulator: regulator source
20454367cfdcSDavid Brownell  *
20464367cfdcSDavid Brownell  * Returns number of selectors, or negative errno.  Selectors are
20474367cfdcSDavid Brownell  * numbered starting at zero, and typically correspond to bitfields
20484367cfdcSDavid Brownell  * in hardware registers.
20494367cfdcSDavid Brownell  */
20504367cfdcSDavid Brownell int regulator_count_voltages(struct regulator *regulator)
20514367cfdcSDavid Brownell {
20524367cfdcSDavid Brownell 	struct regulator_dev	*rdev = regulator->rdev;
20534367cfdcSDavid Brownell 
20544367cfdcSDavid Brownell 	return rdev->desc->n_voltages ? : -EINVAL;
20554367cfdcSDavid Brownell }
20564367cfdcSDavid Brownell EXPORT_SYMBOL_GPL(regulator_count_voltages);
20574367cfdcSDavid Brownell 
20584367cfdcSDavid Brownell /**
2059bca7bbffSMark Brown  * regulator_list_voltage_linear - List voltages with simple calculation
2060bca7bbffSMark Brown  *
2061bca7bbffSMark Brown  * @rdev: Regulator device
2062bca7bbffSMark Brown  * @selector: Selector to convert into a voltage
2063bca7bbffSMark Brown  *
2064bca7bbffSMark Brown  * Regulators with a simple linear mapping between voltages and
2065bca7bbffSMark Brown  * selectors can set min_uV and uV_step in the regulator descriptor
2066bca7bbffSMark Brown  * and then use this function as their list_voltage() operation,
2067bca7bbffSMark Brown  */
2068bca7bbffSMark Brown int regulator_list_voltage_linear(struct regulator_dev *rdev,
2069bca7bbffSMark Brown 				  unsigned int selector)
2070bca7bbffSMark Brown {
2071bca7bbffSMark Brown 	if (selector >= rdev->desc->n_voltages)
2072bca7bbffSMark Brown 		return -EINVAL;
207333234e79SAxel Lin 	if (selector < rdev->desc->linear_min_sel)
207433234e79SAxel Lin 		return 0;
207533234e79SAxel Lin 
207633234e79SAxel Lin 	selector -= rdev->desc->linear_min_sel;
2077bca7bbffSMark Brown 
2078bca7bbffSMark Brown 	return rdev->desc->min_uV + (rdev->desc->uV_step * selector);
2079bca7bbffSMark Brown }
2080bca7bbffSMark Brown EXPORT_SYMBOL_GPL(regulator_list_voltage_linear);
2081bca7bbffSMark Brown 
2082bca7bbffSMark Brown /**
2083cffc9592SAxel Lin  * regulator_list_voltage_table - List voltages with table based mapping
2084cffc9592SAxel Lin  *
2085cffc9592SAxel Lin  * @rdev: Regulator device
2086cffc9592SAxel Lin  * @selector: Selector to convert into a voltage
2087cffc9592SAxel Lin  *
2088cffc9592SAxel Lin  * Regulators with table based mapping between voltages and
2089cffc9592SAxel Lin  * selectors can set volt_table in the regulator descriptor
2090cffc9592SAxel Lin  * and then use this function as their list_voltage() operation.
2091cffc9592SAxel Lin  */
2092cffc9592SAxel Lin int regulator_list_voltage_table(struct regulator_dev *rdev,
2093cffc9592SAxel Lin 				 unsigned int selector)
2094cffc9592SAxel Lin {
2095cffc9592SAxel Lin 	if (!rdev->desc->volt_table) {
2096cffc9592SAxel Lin 		BUG_ON(!rdev->desc->volt_table);
2097cffc9592SAxel Lin 		return -EINVAL;
2098cffc9592SAxel Lin 	}
2099cffc9592SAxel Lin 
2100cffc9592SAxel Lin 	if (selector >= rdev->desc->n_voltages)
2101cffc9592SAxel Lin 		return -EINVAL;
2102cffc9592SAxel Lin 
2103cffc9592SAxel Lin 	return rdev->desc->volt_table[selector];
2104cffc9592SAxel Lin }
2105cffc9592SAxel Lin EXPORT_SYMBOL_GPL(regulator_list_voltage_table);
2106cffc9592SAxel Lin 
2107cffc9592SAxel Lin /**
21084367cfdcSDavid Brownell  * regulator_list_voltage - enumerate supported voltages
21094367cfdcSDavid Brownell  * @regulator: regulator source
21104367cfdcSDavid Brownell  * @selector: identify voltage to list
21114367cfdcSDavid Brownell  * Context: can sleep
21124367cfdcSDavid Brownell  *
21134367cfdcSDavid Brownell  * Returns a voltage that can be passed to @regulator_set_voltage(),
211488393161SThomas Weber  * zero if this selector code can't be used on this system, or a
21154367cfdcSDavid Brownell  * negative errno.
21164367cfdcSDavid Brownell  */
21174367cfdcSDavid Brownell int regulator_list_voltage(struct regulator *regulator, unsigned selector)
21184367cfdcSDavid Brownell {
21194367cfdcSDavid Brownell 	struct regulator_dev	*rdev = regulator->rdev;
21204367cfdcSDavid Brownell 	struct regulator_ops	*ops = rdev->desc->ops;
21214367cfdcSDavid Brownell 	int			ret;
21224367cfdcSDavid Brownell 
21234367cfdcSDavid Brownell 	if (!ops->list_voltage || selector >= rdev->desc->n_voltages)
21244367cfdcSDavid Brownell 		return -EINVAL;
21254367cfdcSDavid Brownell 
21264367cfdcSDavid Brownell 	mutex_lock(&rdev->mutex);
21274367cfdcSDavid Brownell 	ret = ops->list_voltage(rdev, selector);
21284367cfdcSDavid Brownell 	mutex_unlock(&rdev->mutex);
21294367cfdcSDavid Brownell 
21304367cfdcSDavid Brownell 	if (ret > 0) {
21314367cfdcSDavid Brownell 		if (ret < rdev->constraints->min_uV)
21324367cfdcSDavid Brownell 			ret = 0;
21334367cfdcSDavid Brownell 		else if (ret > rdev->constraints->max_uV)
21344367cfdcSDavid Brownell 			ret = 0;
21354367cfdcSDavid Brownell 	}
21364367cfdcSDavid Brownell 
21374367cfdcSDavid Brownell 	return ret;
21384367cfdcSDavid Brownell }
21394367cfdcSDavid Brownell EXPORT_SYMBOL_GPL(regulator_list_voltage);
21404367cfdcSDavid Brownell 
21414367cfdcSDavid Brownell /**
21422a668a8bSPaul Walmsley  * regulator_get_linear_step - return the voltage step size between VSEL values
21432a668a8bSPaul Walmsley  * @regulator: regulator source
21442a668a8bSPaul Walmsley  *
21452a668a8bSPaul Walmsley  * Returns the voltage step size between VSEL values for linear
21462a668a8bSPaul Walmsley  * regulators, or return 0 if the regulator isn't a linear regulator.
21472a668a8bSPaul Walmsley  */
21482a668a8bSPaul Walmsley unsigned int regulator_get_linear_step(struct regulator *regulator)
21492a668a8bSPaul Walmsley {
21502a668a8bSPaul Walmsley 	struct regulator_dev *rdev = regulator->rdev;
21512a668a8bSPaul Walmsley 
21522a668a8bSPaul Walmsley 	return rdev->desc->uV_step;
21532a668a8bSPaul Walmsley }
21542a668a8bSPaul Walmsley EXPORT_SYMBOL_GPL(regulator_get_linear_step);
21552a668a8bSPaul Walmsley 
21562a668a8bSPaul Walmsley /**
2157a7a1ad90SMark Brown  * regulator_is_supported_voltage - check if a voltage range can be supported
2158a7a1ad90SMark Brown  *
2159a7a1ad90SMark Brown  * @regulator: Regulator to check.
2160a7a1ad90SMark Brown  * @min_uV: Minimum required voltage in uV.
2161a7a1ad90SMark Brown  * @max_uV: Maximum required voltage in uV.
2162a7a1ad90SMark Brown  *
2163a7a1ad90SMark Brown  * Returns a boolean or a negative error code.
2164a7a1ad90SMark Brown  */
2165a7a1ad90SMark Brown int regulator_is_supported_voltage(struct regulator *regulator,
2166a7a1ad90SMark Brown 				   int min_uV, int max_uV)
2167a7a1ad90SMark Brown {
2168c5f3939bSMark Brown 	struct regulator_dev *rdev = regulator->rdev;
2169a7a1ad90SMark Brown 	int i, voltages, ret;
2170a7a1ad90SMark Brown 
2171c5f3939bSMark Brown 	/* If we can't change voltage check the current voltage */
2172c5f3939bSMark Brown 	if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) {
2173c5f3939bSMark Brown 		ret = regulator_get_voltage(regulator);
2174c5f3939bSMark Brown 		if (ret >= 0)
2175f0f98b19SMarek Szyprowski 			return (min_uV <= ret && ret <= max_uV);
2176c5f3939bSMark Brown 		else
2177c5f3939bSMark Brown 			return ret;
2178c5f3939bSMark Brown 	}
2179c5f3939bSMark Brown 
2180bd7a2b60SPawel Moll 	/* Any voltage within constrains range is fine? */
2181bd7a2b60SPawel Moll 	if (rdev->desc->continuous_voltage_range)
2182bd7a2b60SPawel Moll 		return min_uV >= rdev->constraints->min_uV &&
2183bd7a2b60SPawel Moll 				max_uV <= rdev->constraints->max_uV;
2184bd7a2b60SPawel Moll 
2185a7a1ad90SMark Brown 	ret = regulator_count_voltages(regulator);
2186a7a1ad90SMark Brown 	if (ret < 0)
2187a7a1ad90SMark Brown 		return ret;
2188a7a1ad90SMark Brown 	voltages = ret;
2189a7a1ad90SMark Brown 
2190a7a1ad90SMark Brown 	for (i = 0; i < voltages; i++) {
2191a7a1ad90SMark Brown 		ret = regulator_list_voltage(regulator, i);
2192a7a1ad90SMark Brown 
2193a7a1ad90SMark Brown 		if (ret >= min_uV && ret <= max_uV)
2194a7a1ad90SMark Brown 			return 1;
2195a7a1ad90SMark Brown 	}
2196a7a1ad90SMark Brown 
2197a7a1ad90SMark Brown 	return 0;
2198a7a1ad90SMark Brown }
2199a398eaa2SMark Brown EXPORT_SYMBOL_GPL(regulator_is_supported_voltage);
2200a7a1ad90SMark Brown 
22014ab5b3d9SMark Brown /**
22024ab5b3d9SMark Brown  * regulator_get_voltage_sel_regmap - standard get_voltage_sel for regmap users
22034ab5b3d9SMark Brown  *
22044ab5b3d9SMark Brown  * @rdev: regulator to operate on
22054ab5b3d9SMark Brown  *
22064ab5b3d9SMark Brown  * Regulators that use regmap for their register I/O can set the
22074ab5b3d9SMark Brown  * vsel_reg and vsel_mask fields in their descriptor and then use this
22084ab5b3d9SMark Brown  * as their get_voltage_vsel operation, saving some code.
22094ab5b3d9SMark Brown  */
22104ab5b3d9SMark Brown int regulator_get_voltage_sel_regmap(struct regulator_dev *rdev)
22114ab5b3d9SMark Brown {
22124ab5b3d9SMark Brown 	unsigned int val;
22134ab5b3d9SMark Brown 	int ret;
22144ab5b3d9SMark Brown 
22154ab5b3d9SMark Brown 	ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val);
22164ab5b3d9SMark Brown 	if (ret != 0)
22174ab5b3d9SMark Brown 		return ret;
22184ab5b3d9SMark Brown 
22194ab5b3d9SMark Brown 	val &= rdev->desc->vsel_mask;
22204ab5b3d9SMark Brown 	val >>= ffs(rdev->desc->vsel_mask) - 1;
22214ab5b3d9SMark Brown 
22224ab5b3d9SMark Brown 	return val;
22234ab5b3d9SMark Brown }
22244ab5b3d9SMark Brown EXPORT_SYMBOL_GPL(regulator_get_voltage_sel_regmap);
22254ab5b3d9SMark Brown 
22264ab5b3d9SMark Brown /**
22274ab5b3d9SMark Brown  * regulator_set_voltage_sel_regmap - standard set_voltage_sel for regmap users
22284ab5b3d9SMark Brown  *
22294ab5b3d9SMark Brown  * @rdev: regulator to operate on
22304ab5b3d9SMark Brown  * @sel: Selector to set
22314ab5b3d9SMark Brown  *
22324ab5b3d9SMark Brown  * Regulators that use regmap for their register I/O can set the
22334ab5b3d9SMark Brown  * vsel_reg and vsel_mask fields in their descriptor and then use this
22344ab5b3d9SMark Brown  * as their set_voltage_vsel operation, saving some code.
22354ab5b3d9SMark Brown  */
22364ab5b3d9SMark Brown int regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel)
22374ab5b3d9SMark Brown {
2238c8520b4cSAxel Lin 	int ret;
2239c8520b4cSAxel Lin 
22404ab5b3d9SMark Brown 	sel <<= ffs(rdev->desc->vsel_mask) - 1;
22414ab5b3d9SMark Brown 
2242c8520b4cSAxel Lin 	ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
22434ab5b3d9SMark Brown 				  rdev->desc->vsel_mask, sel);
2244c8520b4cSAxel Lin 	if (ret)
2245c8520b4cSAxel Lin 		return ret;
2246c8520b4cSAxel Lin 
2247c8520b4cSAxel Lin 	if (rdev->desc->apply_bit)
2248c8520b4cSAxel Lin 		ret = regmap_update_bits(rdev->regmap, rdev->desc->apply_reg,
2249c8520b4cSAxel Lin 					 rdev->desc->apply_bit,
2250c8520b4cSAxel Lin 					 rdev->desc->apply_bit);
2251c8520b4cSAxel Lin 	return ret;
22524ab5b3d9SMark Brown }
22534ab5b3d9SMark Brown EXPORT_SYMBOL_GPL(regulator_set_voltage_sel_regmap);
22544ab5b3d9SMark Brown 
2255e843fc46SMark Brown /**
2256e843fc46SMark Brown  * regulator_map_voltage_iterate - map_voltage() based on list_voltage()
2257e843fc46SMark Brown  *
2258e843fc46SMark Brown  * @rdev: Regulator to operate on
2259e843fc46SMark Brown  * @min_uV: Lower bound for voltage
2260e843fc46SMark Brown  * @max_uV: Upper bound for voltage
2261e843fc46SMark Brown  *
2262e843fc46SMark Brown  * Drivers implementing set_voltage_sel() and list_voltage() can use
2263e843fc46SMark Brown  * this as their map_voltage() operation.  It will find a suitable
2264e843fc46SMark Brown  * voltage by calling list_voltage() until it gets something in bounds
2265e843fc46SMark Brown  * for the requested voltages.
2266e843fc46SMark Brown  */
2267e843fc46SMark Brown int regulator_map_voltage_iterate(struct regulator_dev *rdev,
226875790251SMark Brown 				  int min_uV, int max_uV)
226975790251SMark Brown {
2270e8eef82bSMark Brown 	int best_val = INT_MAX;
2271e843fc46SMark Brown 	int selector = 0;
2272e843fc46SMark Brown 	int i, ret;
2273e8eef82bSMark Brown 
2274e8eef82bSMark Brown 	/* Find the smallest voltage that falls within the specified
2275e8eef82bSMark Brown 	 * range.
2276e8eef82bSMark Brown 	 */
2277e8eef82bSMark Brown 	for (i = 0; i < rdev->desc->n_voltages; i++) {
2278e8eef82bSMark Brown 		ret = rdev->desc->ops->list_voltage(rdev, i);
2279e8eef82bSMark Brown 		if (ret < 0)
2280e8eef82bSMark Brown 			continue;
2281e8eef82bSMark Brown 
2282e8eef82bSMark Brown 		if (ret < best_val && ret >= min_uV && ret <= max_uV) {
2283e8eef82bSMark Brown 			best_val = ret;
2284e8eef82bSMark Brown 			selector = i;
2285e8eef82bSMark Brown 		}
2286e8eef82bSMark Brown 	}
2287e8eef82bSMark Brown 
2288e843fc46SMark Brown 	if (best_val != INT_MAX)
2289e843fc46SMark Brown 		return selector;
2290e843fc46SMark Brown 	else
2291e843fc46SMark Brown 		return -EINVAL;
2292e843fc46SMark Brown }
2293e843fc46SMark Brown EXPORT_SYMBOL_GPL(regulator_map_voltage_iterate);
2294e843fc46SMark Brown 
2295bca7bbffSMark Brown /**
2296fcf371eeSAxel Lin  * regulator_map_voltage_ascend - map_voltage() for ascendant voltage list
2297fcf371eeSAxel Lin  *
2298fcf371eeSAxel Lin  * @rdev: Regulator to operate on
2299fcf371eeSAxel Lin  * @min_uV: Lower bound for voltage
2300fcf371eeSAxel Lin  * @max_uV: Upper bound for voltage
2301fcf371eeSAxel Lin  *
2302fcf371eeSAxel Lin  * Drivers that have ascendant voltage list can use this as their
2303fcf371eeSAxel Lin  * map_voltage() operation.
2304fcf371eeSAxel Lin  */
2305fcf371eeSAxel Lin int regulator_map_voltage_ascend(struct regulator_dev *rdev,
2306fcf371eeSAxel Lin 				 int min_uV, int max_uV)
2307fcf371eeSAxel Lin {
2308fcf371eeSAxel Lin 	int i, ret;
2309fcf371eeSAxel Lin 
2310fcf371eeSAxel Lin 	for (i = 0; i < rdev->desc->n_voltages; i++) {
2311fcf371eeSAxel Lin 		ret = rdev->desc->ops->list_voltage(rdev, i);
2312fcf371eeSAxel Lin 		if (ret < 0)
2313fcf371eeSAxel Lin 			continue;
2314fcf371eeSAxel Lin 
2315fcf371eeSAxel Lin 		if (ret > max_uV)
2316fcf371eeSAxel Lin 			break;
2317fcf371eeSAxel Lin 
2318fcf371eeSAxel Lin 		if (ret >= min_uV && ret <= max_uV)
2319fcf371eeSAxel Lin 			return i;
2320fcf371eeSAxel Lin 	}
2321fcf371eeSAxel Lin 
2322fcf371eeSAxel Lin 	return -EINVAL;
2323fcf371eeSAxel Lin }
2324fcf371eeSAxel Lin EXPORT_SYMBOL_GPL(regulator_map_voltage_ascend);
2325fcf371eeSAxel Lin 
2326fcf371eeSAxel Lin /**
2327bca7bbffSMark Brown  * regulator_map_voltage_linear - map_voltage() for simple linear mappings
2328bca7bbffSMark Brown  *
2329bca7bbffSMark Brown  * @rdev: Regulator to operate on
2330bca7bbffSMark Brown  * @min_uV: Lower bound for voltage
2331bca7bbffSMark Brown  * @max_uV: Upper bound for voltage
2332bca7bbffSMark Brown  *
2333bca7bbffSMark Brown  * Drivers providing min_uV and uV_step in their regulator_desc can
2334bca7bbffSMark Brown  * use this as their map_voltage() operation.
2335bca7bbffSMark Brown  */
2336bca7bbffSMark Brown int regulator_map_voltage_linear(struct regulator_dev *rdev,
2337bca7bbffSMark Brown 				 int min_uV, int max_uV)
2338bca7bbffSMark Brown {
2339bca7bbffSMark Brown 	int ret, voltage;
2340bca7bbffSMark Brown 
23415a6881e8SAxel Lin 	/* Allow uV_step to be 0 for fixed voltage */
23425a6881e8SAxel Lin 	if (rdev->desc->n_voltages == 1 && rdev->desc->uV_step == 0) {
23435a6881e8SAxel Lin 		if (min_uV <= rdev->desc->min_uV && rdev->desc->min_uV <= max_uV)
23445a6881e8SAxel Lin 			return 0;
23455a6881e8SAxel Lin 		else
23465a6881e8SAxel Lin 			return -EINVAL;
23475a6881e8SAxel Lin 	}
23485a6881e8SAxel Lin 
2349bca7bbffSMark Brown 	if (!rdev->desc->uV_step) {
2350bca7bbffSMark Brown 		BUG_ON(!rdev->desc->uV_step);
2351bca7bbffSMark Brown 		return -EINVAL;
2352bca7bbffSMark Brown 	}
2353bca7bbffSMark Brown 
23540bdc81e4SAxel Lin 	if (min_uV < rdev->desc->min_uV)
23550bdc81e4SAxel Lin 		min_uV = rdev->desc->min_uV;
23560bdc81e4SAxel Lin 
2357ccfcb1c3SAxel Lin 	ret = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step);
2358bca7bbffSMark Brown 	if (ret < 0)
2359bca7bbffSMark Brown 		return ret;
2360bca7bbffSMark Brown 
236133234e79SAxel Lin 	ret += rdev->desc->linear_min_sel;
236233234e79SAxel Lin 
2363bca7bbffSMark Brown 	/* Map back into a voltage to verify we're still in bounds */
2364bca7bbffSMark Brown 	voltage = rdev->desc->ops->list_voltage(rdev, ret);
2365bca7bbffSMark Brown 	if (voltage < min_uV || voltage > max_uV)
2366bca7bbffSMark Brown 		return -EINVAL;
2367bca7bbffSMark Brown 
2368bca7bbffSMark Brown 	return ret;
2369bca7bbffSMark Brown }
2370bca7bbffSMark Brown EXPORT_SYMBOL_GPL(regulator_map_voltage_linear);
2371bca7bbffSMark Brown 
2372a7a1ad90SMark Brown static int _regulator_do_set_voltage(struct regulator_dev *rdev,
2373a7a1ad90SMark Brown 				     int min_uV, int max_uV)
2374a7a1ad90SMark Brown {
2375a7a1ad90SMark Brown 	int ret;
237675790251SMark Brown 	int delay = 0;
2377e113d792SMark Brown 	int best_val = 0;
237875790251SMark Brown 	unsigned int selector;
2379eba41a5eSAxel Lin 	int old_selector = -1;
238075790251SMark Brown 
238175790251SMark Brown 	trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV);
238275790251SMark Brown 
238375790251SMark Brown 	min_uV += rdev->constraints->uV_offset;
238475790251SMark Brown 	max_uV += rdev->constraints->uV_offset;
238575790251SMark Brown 
238677af1b26SLinus Walleij 	/*
238777af1b26SLinus Walleij 	 * If we can't obtain the old selector there is not enough
238877af1b26SLinus Walleij 	 * info to call set_voltage_time_sel().
238977af1b26SLinus Walleij 	 */
23908b7485efSAxel Lin 	if (_regulator_is_enabled(rdev) &&
23918b7485efSAxel Lin 	    rdev->desc->ops->set_voltage_time_sel &&
239277af1b26SLinus Walleij 	    rdev->desc->ops->get_voltage_sel) {
2393eba41a5eSAxel Lin 		old_selector = rdev->desc->ops->get_voltage_sel(rdev);
2394eba41a5eSAxel Lin 		if (old_selector < 0)
2395eba41a5eSAxel Lin 			return old_selector;
2396eba41a5eSAxel Lin 	}
239777af1b26SLinus Walleij 
239875790251SMark Brown 	if (rdev->desc->ops->set_voltage) {
239975790251SMark Brown 		ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV,
240075790251SMark Brown 						   &selector);
2401e113d792SMark Brown 
2402e113d792SMark Brown 		if (ret >= 0) {
2403e113d792SMark Brown 			if (rdev->desc->ops->list_voltage)
2404e113d792SMark Brown 				best_val = rdev->desc->ops->list_voltage(rdev,
2405e113d792SMark Brown 									 selector);
2406e113d792SMark Brown 			else
2407e113d792SMark Brown 				best_val = _regulator_get_voltage(rdev);
2408e113d792SMark Brown 		}
2409e113d792SMark Brown 
2410e8eef82bSMark Brown 	} else if (rdev->desc->ops->set_voltage_sel) {
24119152c36aSAxel Lin 		if (rdev->desc->ops->map_voltage) {
2412e843fc46SMark Brown 			ret = rdev->desc->ops->map_voltage(rdev, min_uV,
2413e843fc46SMark Brown 							   max_uV);
24149152c36aSAxel Lin 		} else {
24159152c36aSAxel Lin 			if (rdev->desc->ops->list_voltage ==
24169152c36aSAxel Lin 			    regulator_list_voltage_linear)
24179152c36aSAxel Lin 				ret = regulator_map_voltage_linear(rdev,
24189152c36aSAxel Lin 								min_uV, max_uV);
241907351233SAxel Lin 			else
24209152c36aSAxel Lin 				ret = regulator_map_voltage_iterate(rdev,
24219152c36aSAxel Lin 								min_uV, max_uV);
24229152c36aSAxel Lin 		}
2423e843fc46SMark Brown 
2424e843fc46SMark Brown 		if (ret >= 0) {
2425e113d792SMark Brown 			best_val = rdev->desc->ops->list_voltage(rdev, ret);
2426e113d792SMark Brown 			if (min_uV <= best_val && max_uV >= best_val) {
2427e843fc46SMark Brown 				selector = ret;
2428c66a566aSAxel Lin 				if (old_selector == selector)
2429c66a566aSAxel Lin 					ret = 0;
2430c66a566aSAxel Lin 				else
2431c66a566aSAxel Lin 					ret = rdev->desc->ops->set_voltage_sel(
2432c66a566aSAxel Lin 								rdev, ret);
2433e113d792SMark Brown 			} else {
2434e113d792SMark Brown 				ret = -EINVAL;
2435e113d792SMark Brown 			}
2436e843fc46SMark Brown 		}
2437e8eef82bSMark Brown 	} else {
2438e8eef82bSMark Brown 		ret = -EINVAL;
2439e8eef82bSMark Brown 	}
2440e8eef82bSMark Brown 
2441eba41a5eSAxel Lin 	/* Call set_voltage_time_sel if successfully obtained old_selector */
24425aff3a8bSMark Brown 	if (ret == 0 && _regulator_is_enabled(rdev) && old_selector >= 0 &&
2443c66a566aSAxel Lin 	    old_selector != selector && rdev->desc->ops->set_voltage_time_sel) {
2444eba41a5eSAxel Lin 
2445eba41a5eSAxel Lin 		delay = rdev->desc->ops->set_voltage_time_sel(rdev,
2446eba41a5eSAxel Lin 						old_selector, selector);
2447eba41a5eSAxel Lin 		if (delay < 0) {
2448eba41a5eSAxel Lin 			rdev_warn(rdev, "set_voltage_time_sel() failed: %d\n",
2449eba41a5eSAxel Lin 				  delay);
2450eba41a5eSAxel Lin 			delay = 0;
2451e8eef82bSMark Brown 		}
245275790251SMark Brown 
245377af1b26SLinus Walleij 		/* Insert any necessary delays */
245477af1b26SLinus Walleij 		if (delay >= 1000) {
245577af1b26SLinus Walleij 			mdelay(delay / 1000);
245677af1b26SLinus Walleij 			udelay(delay % 1000);
245777af1b26SLinus Walleij 		} else if (delay) {
245877af1b26SLinus Walleij 			udelay(delay);
245977af1b26SLinus Walleij 		}
24608b96de31SPhilip Rakity 	}
246177af1b26SLinus Walleij 
24622f6c797fSAxel Lin 	if (ret == 0 && best_val >= 0) {
24632f6c797fSAxel Lin 		unsigned long data = best_val;
24642f6c797fSAxel Lin 
2465ded06a52SMark Brown 		_notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE,
24662f6c797fSAxel Lin 				     (void *)data);
24672f6c797fSAxel Lin 	}
2468ded06a52SMark Brown 
2469eba41a5eSAxel Lin 	trace_regulator_set_voltage_complete(rdev_get_name(rdev), best_val);
247075790251SMark Brown 
247175790251SMark Brown 	return ret;
247275790251SMark Brown }
247375790251SMark Brown 
2474a7a1ad90SMark Brown /**
2475414c70cbSLiam Girdwood  * regulator_set_voltage - set regulator output voltage
2476414c70cbSLiam Girdwood  * @regulator: regulator source
2477414c70cbSLiam Girdwood  * @min_uV: Minimum required voltage in uV
2478414c70cbSLiam Girdwood  * @max_uV: Maximum acceptable voltage in uV
2479414c70cbSLiam Girdwood  *
2480414c70cbSLiam Girdwood  * Sets a voltage regulator to the desired output voltage. This can be set
2481414c70cbSLiam Girdwood  * during any regulator state. IOW, regulator can be disabled or enabled.
2482414c70cbSLiam Girdwood  *
2483414c70cbSLiam Girdwood  * If the regulator is enabled then the voltage will change to the new value
2484414c70cbSLiam Girdwood  * immediately otherwise if the regulator is disabled the regulator will
2485414c70cbSLiam Girdwood  * output at the new voltage when enabled.
2486414c70cbSLiam Girdwood  *
2487414c70cbSLiam Girdwood  * NOTE: If the regulator is shared between several devices then the lowest
2488414c70cbSLiam Girdwood  * request voltage that meets the system constraints will be used.
248969279fb9SMark Brown  * Regulator system constraints must be set for this regulator before
2490414c70cbSLiam Girdwood  * calling this function otherwise this call will fail.
2491414c70cbSLiam Girdwood  */
2492414c70cbSLiam Girdwood int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
2493414c70cbSLiam Girdwood {
2494414c70cbSLiam Girdwood 	struct regulator_dev *rdev = regulator->rdev;
249595a3c23aSMark Brown 	int ret = 0;
249692d7a558SPaolo Pisati 	int old_min_uV, old_max_uV;
2497414c70cbSLiam Girdwood 
2498414c70cbSLiam Girdwood 	mutex_lock(&rdev->mutex);
2499414c70cbSLiam Girdwood 
250095a3c23aSMark Brown 	/* If we're setting the same range as last time the change
250195a3c23aSMark Brown 	 * should be a noop (some cpufreq implementations use the same
250295a3c23aSMark Brown 	 * voltage for multiple frequencies, for example).
250395a3c23aSMark Brown 	 */
250495a3c23aSMark Brown 	if (regulator->min_uV == min_uV && regulator->max_uV == max_uV)
250595a3c23aSMark Brown 		goto out;
250695a3c23aSMark Brown 
2507414c70cbSLiam Girdwood 	/* sanity check */
2508e8eef82bSMark Brown 	if (!rdev->desc->ops->set_voltage &&
2509e8eef82bSMark Brown 	    !rdev->desc->ops->set_voltage_sel) {
2510414c70cbSLiam Girdwood 		ret = -EINVAL;
2511414c70cbSLiam Girdwood 		goto out;
2512414c70cbSLiam Girdwood 	}
2513414c70cbSLiam Girdwood 
2514414c70cbSLiam Girdwood 	/* constraints check */
2515414c70cbSLiam Girdwood 	ret = regulator_check_voltage(rdev, &min_uV, &max_uV);
2516414c70cbSLiam Girdwood 	if (ret < 0)
2517414c70cbSLiam Girdwood 		goto out;
251892d7a558SPaolo Pisati 
251992d7a558SPaolo Pisati 	/* restore original values in case of error */
252092d7a558SPaolo Pisati 	old_min_uV = regulator->min_uV;
252192d7a558SPaolo Pisati 	old_max_uV = regulator->max_uV;
2522414c70cbSLiam Girdwood 	regulator->min_uV = min_uV;
2523414c70cbSLiam Girdwood 	regulator->max_uV = max_uV;
25243a93f2a9SMark Brown 
252505fda3b1SThomas Petazzoni 	ret = regulator_check_consumers(rdev, &min_uV, &max_uV);
252605fda3b1SThomas Petazzoni 	if (ret < 0)
252792d7a558SPaolo Pisati 		goto out2;
252805fda3b1SThomas Petazzoni 
252975790251SMark Brown 	ret = _regulator_do_set_voltage(rdev, min_uV, max_uV);
253092d7a558SPaolo Pisati 	if (ret < 0)
253192d7a558SPaolo Pisati 		goto out2;
253202fa3ec0SMark Brown 
2533414c70cbSLiam Girdwood out:
2534414c70cbSLiam Girdwood 	mutex_unlock(&rdev->mutex);
2535414c70cbSLiam Girdwood 	return ret;
253692d7a558SPaolo Pisati out2:
253792d7a558SPaolo Pisati 	regulator->min_uV = old_min_uV;
253892d7a558SPaolo Pisati 	regulator->max_uV = old_max_uV;
253992d7a558SPaolo Pisati 	mutex_unlock(&rdev->mutex);
254092d7a558SPaolo Pisati 	return ret;
2541414c70cbSLiam Girdwood }
2542414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_set_voltage);
2543414c70cbSLiam Girdwood 
2544606a2562SMark Brown /**
254588cd222bSLinus Walleij  * regulator_set_voltage_time - get raise/fall time
254688cd222bSLinus Walleij  * @regulator: regulator source
254788cd222bSLinus Walleij  * @old_uV: starting voltage in microvolts
254888cd222bSLinus Walleij  * @new_uV: target voltage in microvolts
254988cd222bSLinus Walleij  *
255088cd222bSLinus Walleij  * Provided with the starting and ending voltage, this function attempts to
255188cd222bSLinus Walleij  * calculate the time in microseconds required to rise or fall to this new
255288cd222bSLinus Walleij  * voltage.
255388cd222bSLinus Walleij  */
255488cd222bSLinus Walleij int regulator_set_voltage_time(struct regulator *regulator,
255588cd222bSLinus Walleij 			       int old_uV, int new_uV)
255688cd222bSLinus Walleij {
255788cd222bSLinus Walleij 	struct regulator_dev	*rdev = regulator->rdev;
255888cd222bSLinus Walleij 	struct regulator_ops	*ops = rdev->desc->ops;
255988cd222bSLinus Walleij 	int old_sel = -1;
256088cd222bSLinus Walleij 	int new_sel = -1;
256188cd222bSLinus Walleij 	int voltage;
256288cd222bSLinus Walleij 	int i;
256388cd222bSLinus Walleij 
256488cd222bSLinus Walleij 	/* Currently requires operations to do this */
256588cd222bSLinus Walleij 	if (!ops->list_voltage || !ops->set_voltage_time_sel
256688cd222bSLinus Walleij 	    || !rdev->desc->n_voltages)
256788cd222bSLinus Walleij 		return -EINVAL;
256888cd222bSLinus Walleij 
256988cd222bSLinus Walleij 	for (i = 0; i < rdev->desc->n_voltages; i++) {
257088cd222bSLinus Walleij 		/* We only look for exact voltage matches here */
257188cd222bSLinus Walleij 		voltage = regulator_list_voltage(regulator, i);
257288cd222bSLinus Walleij 		if (voltage < 0)
257388cd222bSLinus Walleij 			return -EINVAL;
257488cd222bSLinus Walleij 		if (voltage == 0)
257588cd222bSLinus Walleij 			continue;
257688cd222bSLinus Walleij 		if (voltage == old_uV)
257788cd222bSLinus Walleij 			old_sel = i;
257888cd222bSLinus Walleij 		if (voltage == new_uV)
257988cd222bSLinus Walleij 			new_sel = i;
258088cd222bSLinus Walleij 	}
258188cd222bSLinus Walleij 
258288cd222bSLinus Walleij 	if (old_sel < 0 || new_sel < 0)
258388cd222bSLinus Walleij 		return -EINVAL;
258488cd222bSLinus Walleij 
258588cd222bSLinus Walleij 	return ops->set_voltage_time_sel(rdev, old_sel, new_sel);
258688cd222bSLinus Walleij }
258788cd222bSLinus Walleij EXPORT_SYMBOL_GPL(regulator_set_voltage_time);
258888cd222bSLinus Walleij 
258988cd222bSLinus Walleij /**
259098a175b6SYadwinder Singh Brar  * regulator_set_voltage_time_sel - get raise/fall time
2591296c6566SRandy Dunlap  * @rdev: regulator source device
259298a175b6SYadwinder Singh Brar  * @old_selector: selector for starting voltage
259398a175b6SYadwinder Singh Brar  * @new_selector: selector for target voltage
259498a175b6SYadwinder Singh Brar  *
259598a175b6SYadwinder Singh Brar  * Provided with the starting and target voltage selectors, this function
259698a175b6SYadwinder Singh Brar  * returns time in microseconds required to rise or fall to this new voltage
259798a175b6SYadwinder Singh Brar  *
2598f11d08c3SAxel Lin  * Drivers providing ramp_delay in regulation_constraints can use this as their
2599398715abSAxel Lin  * set_voltage_time_sel() operation.
260098a175b6SYadwinder Singh Brar  */
260198a175b6SYadwinder Singh Brar int regulator_set_voltage_time_sel(struct regulator_dev *rdev,
260298a175b6SYadwinder Singh Brar 				   unsigned int old_selector,
260398a175b6SYadwinder Singh Brar 				   unsigned int new_selector)
260498a175b6SYadwinder Singh Brar {
2605398715abSAxel Lin 	unsigned int ramp_delay = 0;
2606f11d08c3SAxel Lin 	int old_volt, new_volt;
2607398715abSAxel Lin 
26086f0b2c69SYadwinder Singh Brar 	if (rdev->constraints->ramp_delay)
2609398715abSAxel Lin 		ramp_delay = rdev->constraints->ramp_delay;
2610398715abSAxel Lin 	else if (rdev->desc->ramp_delay)
2611398715abSAxel Lin 		ramp_delay = rdev->desc->ramp_delay;
2612398715abSAxel Lin 
2613398715abSAxel Lin 	if (ramp_delay == 0) {
26146f0b2c69SYadwinder Singh Brar 		rdev_warn(rdev, "ramp_delay not set\n");
2615398715abSAxel Lin 		return 0;
26166f0b2c69SYadwinder Singh Brar 	}
2617398715abSAxel Lin 
2618f11d08c3SAxel Lin 	/* sanity check */
2619f11d08c3SAxel Lin 	if (!rdev->desc->ops->list_voltage)
2620f11d08c3SAxel Lin 		return -EINVAL;
2621398715abSAxel Lin 
2622f11d08c3SAxel Lin 	old_volt = rdev->desc->ops->list_voltage(rdev, old_selector);
2623f11d08c3SAxel Lin 	new_volt = rdev->desc->ops->list_voltage(rdev, new_selector);
2624f11d08c3SAxel Lin 
2625f11d08c3SAxel Lin 	return DIV_ROUND_UP(abs(new_volt - old_volt), ramp_delay);
262698a175b6SYadwinder Singh Brar }
2627b19dbf71SMark Brown EXPORT_SYMBOL_GPL(regulator_set_voltage_time_sel);
262898a175b6SYadwinder Singh Brar 
262998a175b6SYadwinder Singh Brar /**
2630606a2562SMark Brown  * regulator_sync_voltage - re-apply last regulator output voltage
2631606a2562SMark Brown  * @regulator: regulator source
2632606a2562SMark Brown  *
2633606a2562SMark Brown  * Re-apply the last configured voltage.  This is intended to be used
2634606a2562SMark Brown  * where some external control source the consumer is cooperating with
2635606a2562SMark Brown  * has caused the configured voltage to change.
2636606a2562SMark Brown  */
2637606a2562SMark Brown int regulator_sync_voltage(struct regulator *regulator)
2638606a2562SMark Brown {
2639606a2562SMark Brown 	struct regulator_dev *rdev = regulator->rdev;
2640606a2562SMark Brown 	int ret, min_uV, max_uV;
2641606a2562SMark Brown 
2642606a2562SMark Brown 	mutex_lock(&rdev->mutex);
2643606a2562SMark Brown 
2644606a2562SMark Brown 	if (!rdev->desc->ops->set_voltage &&
2645606a2562SMark Brown 	    !rdev->desc->ops->set_voltage_sel) {
2646606a2562SMark Brown 		ret = -EINVAL;
2647606a2562SMark Brown 		goto out;
2648606a2562SMark Brown 	}
2649606a2562SMark Brown 
2650606a2562SMark Brown 	/* This is only going to work if we've had a voltage configured. */
2651606a2562SMark Brown 	if (!regulator->min_uV && !regulator->max_uV) {
2652606a2562SMark Brown 		ret = -EINVAL;
2653606a2562SMark Brown 		goto out;
2654606a2562SMark Brown 	}
2655606a2562SMark Brown 
2656606a2562SMark Brown 	min_uV = regulator->min_uV;
2657606a2562SMark Brown 	max_uV = regulator->max_uV;
2658606a2562SMark Brown 
2659606a2562SMark Brown 	/* This should be a paranoia check... */
2660606a2562SMark Brown 	ret = regulator_check_voltage(rdev, &min_uV, &max_uV);
2661606a2562SMark Brown 	if (ret < 0)
2662606a2562SMark Brown 		goto out;
2663606a2562SMark Brown 
2664606a2562SMark Brown 	ret = regulator_check_consumers(rdev, &min_uV, &max_uV);
2665606a2562SMark Brown 	if (ret < 0)
2666606a2562SMark Brown 		goto out;
2667606a2562SMark Brown 
2668606a2562SMark Brown 	ret = _regulator_do_set_voltage(rdev, min_uV, max_uV);
2669606a2562SMark Brown 
2670606a2562SMark Brown out:
2671606a2562SMark Brown 	mutex_unlock(&rdev->mutex);
2672606a2562SMark Brown 	return ret;
2673606a2562SMark Brown }
2674606a2562SMark Brown EXPORT_SYMBOL_GPL(regulator_sync_voltage);
2675606a2562SMark Brown 
2676414c70cbSLiam Girdwood static int _regulator_get_voltage(struct regulator_dev *rdev)
2677414c70cbSLiam Girdwood {
2678bf5892a8SMark Brown 	int sel, ret;
2679476c2d83SMark Brown 
2680476c2d83SMark Brown 	if (rdev->desc->ops->get_voltage_sel) {
2681476c2d83SMark Brown 		sel = rdev->desc->ops->get_voltage_sel(rdev);
2682476c2d83SMark Brown 		if (sel < 0)
2683476c2d83SMark Brown 			return sel;
2684bf5892a8SMark Brown 		ret = rdev->desc->ops->list_voltage(rdev, sel);
2685cb220d16SAxel Lin 	} else if (rdev->desc->ops->get_voltage) {
2686bf5892a8SMark Brown 		ret = rdev->desc->ops->get_voltage(rdev);
2687f7df20ecSMark Brown 	} else if (rdev->desc->ops->list_voltage) {
2688f7df20ecSMark Brown 		ret = rdev->desc->ops->list_voltage(rdev, 0);
2689cb220d16SAxel Lin 	} else {
2690414c70cbSLiam Girdwood 		return -EINVAL;
2691cb220d16SAxel Lin 	}
2692bf5892a8SMark Brown 
2693cb220d16SAxel Lin 	if (ret < 0)
2694cb220d16SAxel Lin 		return ret;
2695bf5892a8SMark Brown 	return ret - rdev->constraints->uV_offset;
2696414c70cbSLiam Girdwood }
2697414c70cbSLiam Girdwood 
2698414c70cbSLiam Girdwood /**
2699414c70cbSLiam Girdwood  * regulator_get_voltage - get regulator output voltage
2700414c70cbSLiam Girdwood  * @regulator: regulator source
2701414c70cbSLiam Girdwood  *
2702414c70cbSLiam Girdwood  * This returns the current regulator voltage in uV.
2703414c70cbSLiam Girdwood  *
2704414c70cbSLiam Girdwood  * NOTE: If the regulator is disabled it will return the voltage value. This
2705414c70cbSLiam Girdwood  * function should not be used to determine regulator state.
2706414c70cbSLiam Girdwood  */
2707414c70cbSLiam Girdwood int regulator_get_voltage(struct regulator *regulator)
2708414c70cbSLiam Girdwood {
2709414c70cbSLiam Girdwood 	int ret;
2710414c70cbSLiam Girdwood 
2711414c70cbSLiam Girdwood 	mutex_lock(&regulator->rdev->mutex);
2712414c70cbSLiam Girdwood 
2713414c70cbSLiam Girdwood 	ret = _regulator_get_voltage(regulator->rdev);
2714414c70cbSLiam Girdwood 
2715414c70cbSLiam Girdwood 	mutex_unlock(&regulator->rdev->mutex);
2716414c70cbSLiam Girdwood 
2717414c70cbSLiam Girdwood 	return ret;
2718414c70cbSLiam Girdwood }
2719414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_get_voltage);
2720414c70cbSLiam Girdwood 
2721414c70cbSLiam Girdwood /**
2722414c70cbSLiam Girdwood  * regulator_set_current_limit - set regulator output current limit
2723414c70cbSLiam Girdwood  * @regulator: regulator source
2724ce0d10f8SCharles Keepax  * @min_uA: Minimum supported current in uA
2725414c70cbSLiam Girdwood  * @max_uA: Maximum supported current in uA
2726414c70cbSLiam Girdwood  *
2727414c70cbSLiam Girdwood  * Sets current sink to the desired output current. This can be set during
2728414c70cbSLiam Girdwood  * any regulator state. IOW, regulator can be disabled or enabled.
2729414c70cbSLiam Girdwood  *
2730414c70cbSLiam Girdwood  * If the regulator is enabled then the current will change to the new value
2731414c70cbSLiam Girdwood  * immediately otherwise if the regulator is disabled the regulator will
2732414c70cbSLiam Girdwood  * output at the new current when enabled.
2733414c70cbSLiam Girdwood  *
2734414c70cbSLiam Girdwood  * NOTE: Regulator system constraints must be set for this regulator before
2735414c70cbSLiam Girdwood  * calling this function otherwise this call will fail.
2736414c70cbSLiam Girdwood  */
2737414c70cbSLiam Girdwood int regulator_set_current_limit(struct regulator *regulator,
2738414c70cbSLiam Girdwood 			       int min_uA, int max_uA)
2739414c70cbSLiam Girdwood {
2740414c70cbSLiam Girdwood 	struct regulator_dev *rdev = regulator->rdev;
2741414c70cbSLiam Girdwood 	int ret;
2742414c70cbSLiam Girdwood 
2743414c70cbSLiam Girdwood 	mutex_lock(&rdev->mutex);
2744414c70cbSLiam Girdwood 
2745414c70cbSLiam Girdwood 	/* sanity check */
2746414c70cbSLiam Girdwood 	if (!rdev->desc->ops->set_current_limit) {
2747414c70cbSLiam Girdwood 		ret = -EINVAL;
2748414c70cbSLiam Girdwood 		goto out;
2749414c70cbSLiam Girdwood 	}
2750414c70cbSLiam Girdwood 
2751414c70cbSLiam Girdwood 	/* constraints check */
2752414c70cbSLiam Girdwood 	ret = regulator_check_current_limit(rdev, &min_uA, &max_uA);
2753414c70cbSLiam Girdwood 	if (ret < 0)
2754414c70cbSLiam Girdwood 		goto out;
2755414c70cbSLiam Girdwood 
2756414c70cbSLiam Girdwood 	ret = rdev->desc->ops->set_current_limit(rdev, min_uA, max_uA);
2757414c70cbSLiam Girdwood out:
2758414c70cbSLiam Girdwood 	mutex_unlock(&rdev->mutex);
2759414c70cbSLiam Girdwood 	return ret;
2760414c70cbSLiam Girdwood }
2761414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_set_current_limit);
2762414c70cbSLiam Girdwood 
2763414c70cbSLiam Girdwood static int _regulator_get_current_limit(struct regulator_dev *rdev)
2764414c70cbSLiam Girdwood {
2765414c70cbSLiam Girdwood 	int ret;
2766414c70cbSLiam Girdwood 
2767414c70cbSLiam Girdwood 	mutex_lock(&rdev->mutex);
2768414c70cbSLiam Girdwood 
2769414c70cbSLiam Girdwood 	/* sanity check */
2770414c70cbSLiam Girdwood 	if (!rdev->desc->ops->get_current_limit) {
2771414c70cbSLiam Girdwood 		ret = -EINVAL;
2772414c70cbSLiam Girdwood 		goto out;
2773414c70cbSLiam Girdwood 	}
2774414c70cbSLiam Girdwood 
2775414c70cbSLiam Girdwood 	ret = rdev->desc->ops->get_current_limit(rdev);
2776414c70cbSLiam Girdwood out:
2777414c70cbSLiam Girdwood 	mutex_unlock(&rdev->mutex);
2778414c70cbSLiam Girdwood 	return ret;
2779414c70cbSLiam Girdwood }
2780414c70cbSLiam Girdwood 
2781414c70cbSLiam Girdwood /**
2782414c70cbSLiam Girdwood  * regulator_get_current_limit - get regulator output current
2783414c70cbSLiam Girdwood  * @regulator: regulator source
2784414c70cbSLiam Girdwood  *
2785414c70cbSLiam Girdwood  * This returns the current supplied by the specified current sink in uA.
2786414c70cbSLiam Girdwood  *
2787414c70cbSLiam Girdwood  * NOTE: If the regulator is disabled it will return the current value. This
2788414c70cbSLiam Girdwood  * function should not be used to determine regulator state.
2789414c70cbSLiam Girdwood  */
2790414c70cbSLiam Girdwood int regulator_get_current_limit(struct regulator *regulator)
2791414c70cbSLiam Girdwood {
2792414c70cbSLiam Girdwood 	return _regulator_get_current_limit(regulator->rdev);
2793414c70cbSLiam Girdwood }
2794414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_get_current_limit);
2795414c70cbSLiam Girdwood 
2796414c70cbSLiam Girdwood /**
2797414c70cbSLiam Girdwood  * regulator_set_mode - set regulator operating mode
2798414c70cbSLiam Girdwood  * @regulator: regulator source
2799414c70cbSLiam Girdwood  * @mode: operating mode - one of the REGULATOR_MODE constants
2800414c70cbSLiam Girdwood  *
2801414c70cbSLiam Girdwood  * Set regulator operating mode to increase regulator efficiency or improve
2802414c70cbSLiam Girdwood  * regulation performance.
2803414c70cbSLiam Girdwood  *
2804414c70cbSLiam Girdwood  * NOTE: Regulator system constraints must be set for this regulator before
2805414c70cbSLiam Girdwood  * calling this function otherwise this call will fail.
2806414c70cbSLiam Girdwood  */
2807414c70cbSLiam Girdwood int regulator_set_mode(struct regulator *regulator, unsigned int mode)
2808414c70cbSLiam Girdwood {
2809414c70cbSLiam Girdwood 	struct regulator_dev *rdev = regulator->rdev;
2810414c70cbSLiam Girdwood 	int ret;
2811500b4ac9SSundar R Iyer 	int regulator_curr_mode;
2812414c70cbSLiam Girdwood 
2813414c70cbSLiam Girdwood 	mutex_lock(&rdev->mutex);
2814414c70cbSLiam Girdwood 
2815414c70cbSLiam Girdwood 	/* sanity check */
2816414c70cbSLiam Girdwood 	if (!rdev->desc->ops->set_mode) {
2817414c70cbSLiam Girdwood 		ret = -EINVAL;
2818414c70cbSLiam Girdwood 		goto out;
2819414c70cbSLiam Girdwood 	}
2820414c70cbSLiam Girdwood 
2821500b4ac9SSundar R Iyer 	/* return if the same mode is requested */
2822500b4ac9SSundar R Iyer 	if (rdev->desc->ops->get_mode) {
2823500b4ac9SSundar R Iyer 		regulator_curr_mode = rdev->desc->ops->get_mode(rdev);
2824500b4ac9SSundar R Iyer 		if (regulator_curr_mode == mode) {
2825500b4ac9SSundar R Iyer 			ret = 0;
2826500b4ac9SSundar R Iyer 			goto out;
2827500b4ac9SSundar R Iyer 		}
2828500b4ac9SSundar R Iyer 	}
2829500b4ac9SSundar R Iyer 
2830414c70cbSLiam Girdwood 	/* constraints check */
283122c51b47SAxel Lin 	ret = regulator_mode_constrain(rdev, &mode);
2832414c70cbSLiam Girdwood 	if (ret < 0)
2833414c70cbSLiam Girdwood 		goto out;
2834414c70cbSLiam Girdwood 
2835414c70cbSLiam Girdwood 	ret = rdev->desc->ops->set_mode(rdev, mode);
2836414c70cbSLiam Girdwood out:
2837414c70cbSLiam Girdwood 	mutex_unlock(&rdev->mutex);
2838414c70cbSLiam Girdwood 	return ret;
2839414c70cbSLiam Girdwood }
2840414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_set_mode);
2841414c70cbSLiam Girdwood 
2842414c70cbSLiam Girdwood static unsigned int _regulator_get_mode(struct regulator_dev *rdev)
2843414c70cbSLiam Girdwood {
2844414c70cbSLiam Girdwood 	int ret;
2845414c70cbSLiam Girdwood 
2846414c70cbSLiam Girdwood 	mutex_lock(&rdev->mutex);
2847414c70cbSLiam Girdwood 
2848414c70cbSLiam Girdwood 	/* sanity check */
2849414c70cbSLiam Girdwood 	if (!rdev->desc->ops->get_mode) {
2850414c70cbSLiam Girdwood 		ret = -EINVAL;
2851414c70cbSLiam Girdwood 		goto out;
2852414c70cbSLiam Girdwood 	}
2853414c70cbSLiam Girdwood 
2854414c70cbSLiam Girdwood 	ret = rdev->desc->ops->get_mode(rdev);
2855414c70cbSLiam Girdwood out:
2856414c70cbSLiam Girdwood 	mutex_unlock(&rdev->mutex);
2857414c70cbSLiam Girdwood 	return ret;
2858414c70cbSLiam Girdwood }
2859414c70cbSLiam Girdwood 
2860414c70cbSLiam Girdwood /**
2861414c70cbSLiam Girdwood  * regulator_get_mode - get regulator operating mode
2862414c70cbSLiam Girdwood  * @regulator: regulator source
2863414c70cbSLiam Girdwood  *
2864414c70cbSLiam Girdwood  * Get the current regulator operating mode.
2865414c70cbSLiam Girdwood  */
2866414c70cbSLiam Girdwood unsigned int regulator_get_mode(struct regulator *regulator)
2867414c70cbSLiam Girdwood {
2868414c70cbSLiam Girdwood 	return _regulator_get_mode(regulator->rdev);
2869414c70cbSLiam Girdwood }
2870414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_get_mode);
2871414c70cbSLiam Girdwood 
2872414c70cbSLiam Girdwood /**
2873414c70cbSLiam Girdwood  * regulator_set_optimum_mode - set regulator optimum operating mode
2874414c70cbSLiam Girdwood  * @regulator: regulator source
2875414c70cbSLiam Girdwood  * @uA_load: load current
2876414c70cbSLiam Girdwood  *
2877414c70cbSLiam Girdwood  * Notifies the regulator core of a new device load. This is then used by
2878414c70cbSLiam Girdwood  * DRMS (if enabled by constraints) to set the most efficient regulator
2879414c70cbSLiam Girdwood  * operating mode for the new regulator loading.
2880414c70cbSLiam Girdwood  *
2881414c70cbSLiam Girdwood  * Consumer devices notify their supply regulator of the maximum power
2882414c70cbSLiam Girdwood  * they will require (can be taken from device datasheet in the power
2883414c70cbSLiam Girdwood  * consumption tables) when they change operational status and hence power
2884414c70cbSLiam Girdwood  * state. Examples of operational state changes that can affect power
2885414c70cbSLiam Girdwood  * consumption are :-
2886414c70cbSLiam Girdwood  *
2887414c70cbSLiam Girdwood  *    o Device is opened / closed.
2888414c70cbSLiam Girdwood  *    o Device I/O is about to begin or has just finished.
2889414c70cbSLiam Girdwood  *    o Device is idling in between work.
2890414c70cbSLiam Girdwood  *
2891414c70cbSLiam Girdwood  * This information is also exported via sysfs to userspace.
2892414c70cbSLiam Girdwood  *
2893414c70cbSLiam Girdwood  * DRMS will sum the total requested load on the regulator and change
2894414c70cbSLiam Girdwood  * to the most efficient operating mode if platform constraints allow.
2895414c70cbSLiam Girdwood  *
2896414c70cbSLiam Girdwood  * Returns the new regulator mode or error.
2897414c70cbSLiam Girdwood  */
2898414c70cbSLiam Girdwood int regulator_set_optimum_mode(struct regulator *regulator, int uA_load)
2899414c70cbSLiam Girdwood {
2900414c70cbSLiam Girdwood 	struct regulator_dev *rdev = regulator->rdev;
2901414c70cbSLiam Girdwood 	struct regulator *consumer;
2902d92d95b6SStephen Boyd 	int ret, output_uV, input_uV = 0, total_uA_load = 0;
2903414c70cbSLiam Girdwood 	unsigned int mode;
2904414c70cbSLiam Girdwood 
2905d92d95b6SStephen Boyd 	if (rdev->supply)
2906d92d95b6SStephen Boyd 		input_uV = regulator_get_voltage(rdev->supply);
2907d92d95b6SStephen Boyd 
2908414c70cbSLiam Girdwood 	mutex_lock(&rdev->mutex);
2909414c70cbSLiam Girdwood 
2910a4b41483SMark Brown 	/*
2911a4b41483SMark Brown 	 * first check to see if we can set modes at all, otherwise just
2912a4b41483SMark Brown 	 * tell the consumer everything is OK.
2913a4b41483SMark Brown 	 */
2914414c70cbSLiam Girdwood 	regulator->uA_load = uA_load;
2915414c70cbSLiam Girdwood 	ret = regulator_check_drms(rdev);
2916a4b41483SMark Brown 	if (ret < 0) {
2917a4b41483SMark Brown 		ret = 0;
2918414c70cbSLiam Girdwood 		goto out;
2919a4b41483SMark Brown 	}
2920414c70cbSLiam Girdwood 
2921414c70cbSLiam Girdwood 	if (!rdev->desc->ops->get_optimum_mode)
2922414c70cbSLiam Girdwood 		goto out;
2923414c70cbSLiam Girdwood 
2924a4b41483SMark Brown 	/*
2925a4b41483SMark Brown 	 * we can actually do this so any errors are indicators of
2926a4b41483SMark Brown 	 * potential real failure.
2927a4b41483SMark Brown 	 */
2928a4b41483SMark Brown 	ret = -EINVAL;
2929a4b41483SMark Brown 
2930854ccbaeSAxel Lin 	if (!rdev->desc->ops->set_mode)
2931854ccbaeSAxel Lin 		goto out;
2932854ccbaeSAxel Lin 
2933414c70cbSLiam Girdwood 	/* get output voltage */
29341bf5a1f8SMark Brown 	output_uV = _regulator_get_voltage(rdev);
2935414c70cbSLiam Girdwood 	if (output_uV <= 0) {
29365da84fd9SJoe Perches 		rdev_err(rdev, "invalid output voltage found\n");
2937414c70cbSLiam Girdwood 		goto out;
2938414c70cbSLiam Girdwood 	}
2939414c70cbSLiam Girdwood 
2940d92d95b6SStephen Boyd 	/* No supply? Use constraint voltage */
29411bf5a1f8SMark Brown 	if (input_uV <= 0)
2942414c70cbSLiam Girdwood 		input_uV = rdev->constraints->input_uV;
2943414c70cbSLiam Girdwood 	if (input_uV <= 0) {
29445da84fd9SJoe Perches 		rdev_err(rdev, "invalid input voltage found\n");
2945414c70cbSLiam Girdwood 		goto out;
2946414c70cbSLiam Girdwood 	}
2947414c70cbSLiam Girdwood 
2948414c70cbSLiam Girdwood 	/* calc total requested load for this regulator */
2949414c70cbSLiam Girdwood 	list_for_each_entry(consumer, &rdev->consumer_list, list)
2950414c70cbSLiam Girdwood 		total_uA_load += consumer->uA_load;
2951414c70cbSLiam Girdwood 
2952414c70cbSLiam Girdwood 	mode = rdev->desc->ops->get_optimum_mode(rdev,
2953414c70cbSLiam Girdwood 						 input_uV, output_uV,
2954414c70cbSLiam Girdwood 						 total_uA_load);
29552c608234SMark Brown 	ret = regulator_mode_constrain(rdev, &mode);
2956e573520bSDavid Brownell 	if (ret < 0) {
29575da84fd9SJoe Perches 		rdev_err(rdev, "failed to get optimum mode @ %d uA %d -> %d uV\n",
2958414c70cbSLiam Girdwood 			 total_uA_load, input_uV, output_uV);
2959414c70cbSLiam Girdwood 		goto out;
2960414c70cbSLiam Girdwood 	}
2961414c70cbSLiam Girdwood 
2962414c70cbSLiam Girdwood 	ret = rdev->desc->ops->set_mode(rdev, mode);
2963e573520bSDavid Brownell 	if (ret < 0) {
29645da84fd9SJoe Perches 		rdev_err(rdev, "failed to set optimum mode %x\n", mode);
2965414c70cbSLiam Girdwood 		goto out;
2966414c70cbSLiam Girdwood 	}
2967414c70cbSLiam Girdwood 	ret = mode;
2968414c70cbSLiam Girdwood out:
2969414c70cbSLiam Girdwood 	mutex_unlock(&rdev->mutex);
2970414c70cbSLiam Girdwood 	return ret;
2971414c70cbSLiam Girdwood }
2972414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_set_optimum_mode);
2973414c70cbSLiam Girdwood 
2974414c70cbSLiam Girdwood /**
2975df367931SMark Brown  * regulator_set_bypass_regmap - Default set_bypass() using regmap
2976df367931SMark Brown  *
2977df367931SMark Brown  * @rdev: device to operate on.
2978df367931SMark Brown  * @enable: state to set.
2979df367931SMark Brown  */
2980df367931SMark Brown int regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable)
2981df367931SMark Brown {
2982df367931SMark Brown 	unsigned int val;
2983df367931SMark Brown 
2984df367931SMark Brown 	if (enable)
2985df367931SMark Brown 		val = rdev->desc->bypass_mask;
2986df367931SMark Brown 	else
2987df367931SMark Brown 		val = 0;
2988df367931SMark Brown 
2989df367931SMark Brown 	return regmap_update_bits(rdev->regmap, rdev->desc->bypass_reg,
2990df367931SMark Brown 				  rdev->desc->bypass_mask, val);
2991df367931SMark Brown }
2992df367931SMark Brown EXPORT_SYMBOL_GPL(regulator_set_bypass_regmap);
2993df367931SMark Brown 
2994df367931SMark Brown /**
2995df367931SMark Brown  * regulator_get_bypass_regmap - Default get_bypass() using regmap
2996df367931SMark Brown  *
2997df367931SMark Brown  * @rdev: device to operate on.
2998df367931SMark Brown  * @enable: current state.
2999df367931SMark Brown  */
3000df367931SMark Brown int regulator_get_bypass_regmap(struct regulator_dev *rdev, bool *enable)
3001df367931SMark Brown {
3002df367931SMark Brown 	unsigned int val;
3003df367931SMark Brown 	int ret;
3004df367931SMark Brown 
3005df367931SMark Brown 	ret = regmap_read(rdev->regmap, rdev->desc->bypass_reg, &val);
3006df367931SMark Brown 	if (ret != 0)
3007df367931SMark Brown 		return ret;
3008df367931SMark Brown 
3009df367931SMark Brown 	*enable = val & rdev->desc->bypass_mask;
3010df367931SMark Brown 
3011df367931SMark Brown 	return 0;
3012df367931SMark Brown }
3013df367931SMark Brown EXPORT_SYMBOL_GPL(regulator_get_bypass_regmap);
3014df367931SMark Brown 
3015df367931SMark Brown /**
3016f59c8f9fSMark Brown  * regulator_allow_bypass - allow the regulator to go into bypass mode
3017f59c8f9fSMark Brown  *
3018f59c8f9fSMark Brown  * @regulator: Regulator to configure
30199345dfb8SNishanth Menon  * @enable: enable or disable bypass mode
3020f59c8f9fSMark Brown  *
3021f59c8f9fSMark Brown  * Allow the regulator to go into bypass mode if all other consumers
3022f59c8f9fSMark Brown  * for the regulator also enable bypass mode and the machine
3023f59c8f9fSMark Brown  * constraints allow this.  Bypass mode means that the regulator is
3024f59c8f9fSMark Brown  * simply passing the input directly to the output with no regulation.
3025f59c8f9fSMark Brown  */
3026f59c8f9fSMark Brown int regulator_allow_bypass(struct regulator *regulator, bool enable)
3027f59c8f9fSMark Brown {
3028f59c8f9fSMark Brown 	struct regulator_dev *rdev = regulator->rdev;
3029f59c8f9fSMark Brown 	int ret = 0;
3030f59c8f9fSMark Brown 
3031f59c8f9fSMark Brown 	if (!rdev->desc->ops->set_bypass)
3032f59c8f9fSMark Brown 		return 0;
3033f59c8f9fSMark Brown 
3034f59c8f9fSMark Brown 	if (rdev->constraints &&
3035f59c8f9fSMark Brown 	    !(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_BYPASS))
3036f59c8f9fSMark Brown 		return 0;
3037f59c8f9fSMark Brown 
3038f59c8f9fSMark Brown 	mutex_lock(&rdev->mutex);
3039f59c8f9fSMark Brown 
3040f59c8f9fSMark Brown 	if (enable && !regulator->bypass) {
3041f59c8f9fSMark Brown 		rdev->bypass_count++;
3042f59c8f9fSMark Brown 
3043f59c8f9fSMark Brown 		if (rdev->bypass_count == rdev->open_count) {
3044f59c8f9fSMark Brown 			ret = rdev->desc->ops->set_bypass(rdev, enable);
3045f59c8f9fSMark Brown 			if (ret != 0)
3046f59c8f9fSMark Brown 				rdev->bypass_count--;
3047f59c8f9fSMark Brown 		}
3048f59c8f9fSMark Brown 
3049f59c8f9fSMark Brown 	} else if (!enable && regulator->bypass) {
3050f59c8f9fSMark Brown 		rdev->bypass_count--;
3051f59c8f9fSMark Brown 
3052f59c8f9fSMark Brown 		if (rdev->bypass_count != rdev->open_count) {
3053f59c8f9fSMark Brown 			ret = rdev->desc->ops->set_bypass(rdev, enable);
3054f59c8f9fSMark Brown 			if (ret != 0)
3055f59c8f9fSMark Brown 				rdev->bypass_count++;
3056f59c8f9fSMark Brown 		}
3057f59c8f9fSMark Brown 	}
3058f59c8f9fSMark Brown 
3059f59c8f9fSMark Brown 	if (ret == 0)
3060f59c8f9fSMark Brown 		regulator->bypass = enable;
3061f59c8f9fSMark Brown 
3062f59c8f9fSMark Brown 	mutex_unlock(&rdev->mutex);
3063f59c8f9fSMark Brown 
3064f59c8f9fSMark Brown 	return ret;
3065f59c8f9fSMark Brown }
3066f59c8f9fSMark Brown EXPORT_SYMBOL_GPL(regulator_allow_bypass);
3067f59c8f9fSMark Brown 
3068f59c8f9fSMark Brown /**
3069414c70cbSLiam Girdwood  * regulator_register_notifier - register regulator event notifier
3070414c70cbSLiam Girdwood  * @regulator: regulator source
307169279fb9SMark Brown  * @nb: notifier block
3072414c70cbSLiam Girdwood  *
3073414c70cbSLiam Girdwood  * Register notifier block to receive regulator events.
3074414c70cbSLiam Girdwood  */
3075414c70cbSLiam Girdwood int regulator_register_notifier(struct regulator *regulator,
3076414c70cbSLiam Girdwood 			      struct notifier_block *nb)
3077414c70cbSLiam Girdwood {
3078414c70cbSLiam Girdwood 	return blocking_notifier_chain_register(&regulator->rdev->notifier,
3079414c70cbSLiam Girdwood 						nb);
3080414c70cbSLiam Girdwood }
3081414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_register_notifier);
3082414c70cbSLiam Girdwood 
3083414c70cbSLiam Girdwood /**
3084414c70cbSLiam Girdwood  * regulator_unregister_notifier - unregister regulator event notifier
3085414c70cbSLiam Girdwood  * @regulator: regulator source
308669279fb9SMark Brown  * @nb: notifier block
3087414c70cbSLiam Girdwood  *
3088414c70cbSLiam Girdwood  * Unregister regulator event notifier block.
3089414c70cbSLiam Girdwood  */
3090414c70cbSLiam Girdwood int regulator_unregister_notifier(struct regulator *regulator,
3091414c70cbSLiam Girdwood 				struct notifier_block *nb)
3092414c70cbSLiam Girdwood {
3093414c70cbSLiam Girdwood 	return blocking_notifier_chain_unregister(&regulator->rdev->notifier,
3094414c70cbSLiam Girdwood 						  nb);
3095414c70cbSLiam Girdwood }
3096414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_unregister_notifier);
3097414c70cbSLiam Girdwood 
3098b136fb44SJonathan Cameron /* notify regulator consumers and downstream regulator consumers.
3099b136fb44SJonathan Cameron  * Note mutex must be held by caller.
3100b136fb44SJonathan Cameron  */
3101414c70cbSLiam Girdwood static void _notifier_call_chain(struct regulator_dev *rdev,
3102414c70cbSLiam Girdwood 				  unsigned long event, void *data)
3103414c70cbSLiam Girdwood {
3104414c70cbSLiam Girdwood 	/* call rdev chain first */
3105d8493d21SMark Brown 	blocking_notifier_call_chain(&rdev->notifier, event, data);
3106414c70cbSLiam Girdwood }
3107414c70cbSLiam Girdwood 
3108414c70cbSLiam Girdwood /**
3109414c70cbSLiam Girdwood  * regulator_bulk_get - get multiple regulator consumers
3110414c70cbSLiam Girdwood  *
3111414c70cbSLiam Girdwood  * @dev:           Device to supply
3112414c70cbSLiam Girdwood  * @num_consumers: Number of consumers to register
3113414c70cbSLiam Girdwood  * @consumers:     Configuration of consumers; clients are stored here.
3114414c70cbSLiam Girdwood  *
3115414c70cbSLiam Girdwood  * @return 0 on success, an errno on failure.
3116414c70cbSLiam Girdwood  *
3117414c70cbSLiam Girdwood  * This helper function allows drivers to get several regulator
3118414c70cbSLiam Girdwood  * consumers in one operation.  If any of the regulators cannot be
3119414c70cbSLiam Girdwood  * acquired then any regulators that were allocated will be freed
3120414c70cbSLiam Girdwood  * before returning to the caller.
3121414c70cbSLiam Girdwood  */
3122414c70cbSLiam Girdwood int regulator_bulk_get(struct device *dev, int num_consumers,
3123414c70cbSLiam Girdwood 		       struct regulator_bulk_data *consumers)
3124414c70cbSLiam Girdwood {
3125414c70cbSLiam Girdwood 	int i;
3126414c70cbSLiam Girdwood 	int ret;
3127414c70cbSLiam Girdwood 
3128414c70cbSLiam Girdwood 	for (i = 0; i < num_consumers; i++)
3129414c70cbSLiam Girdwood 		consumers[i].consumer = NULL;
3130414c70cbSLiam Girdwood 
3131414c70cbSLiam Girdwood 	for (i = 0; i < num_consumers; i++) {
3132414c70cbSLiam Girdwood 		consumers[i].consumer = regulator_get(dev,
3133414c70cbSLiam Girdwood 						      consumers[i].supply);
3134414c70cbSLiam Girdwood 		if (IS_ERR(consumers[i].consumer)) {
3135414c70cbSLiam Girdwood 			ret = PTR_ERR(consumers[i].consumer);
31365b307627SMark Brown 			dev_err(dev, "Failed to get supply '%s': %d\n",
31375b307627SMark Brown 				consumers[i].supply, ret);
3138414c70cbSLiam Girdwood 			consumers[i].consumer = NULL;
3139414c70cbSLiam Girdwood 			goto err;
3140414c70cbSLiam Girdwood 		}
3141414c70cbSLiam Girdwood 	}
3142414c70cbSLiam Girdwood 
3143414c70cbSLiam Girdwood 	return 0;
3144414c70cbSLiam Girdwood 
3145414c70cbSLiam Girdwood err:
3146b29c7690SAxel Lin 	while (--i >= 0)
3147414c70cbSLiam Girdwood 		regulator_put(consumers[i].consumer);
3148414c70cbSLiam Girdwood 
3149414c70cbSLiam Girdwood 	return ret;
3150414c70cbSLiam Girdwood }
3151414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_bulk_get);
3152414c70cbSLiam Girdwood 
3153e6e74030SMark Brown /**
3154e6e74030SMark Brown  * devm_regulator_bulk_get - managed get multiple regulator consumers
3155e6e74030SMark Brown  *
3156e6e74030SMark Brown  * @dev:           Device to supply
3157e6e74030SMark Brown  * @num_consumers: Number of consumers to register
3158e6e74030SMark Brown  * @consumers:     Configuration of consumers; clients are stored here.
3159e6e74030SMark Brown  *
3160e6e74030SMark Brown  * @return 0 on success, an errno on failure.
3161e6e74030SMark Brown  *
3162e6e74030SMark Brown  * This helper function allows drivers to get several regulator
3163e6e74030SMark Brown  * consumers in one operation with management, the regulators will
3164e6e74030SMark Brown  * automatically be freed when the device is unbound.  If any of the
3165e6e74030SMark Brown  * regulators cannot be acquired then any regulators that were
3166e6e74030SMark Brown  * allocated will be freed before returning to the caller.
3167e6e74030SMark Brown  */
3168e6e74030SMark Brown int devm_regulator_bulk_get(struct device *dev, int num_consumers,
3169e6e74030SMark Brown 			    struct regulator_bulk_data *consumers)
3170e6e74030SMark Brown {
3171e6e74030SMark Brown 	int i;
3172e6e74030SMark Brown 	int ret;
3173e6e74030SMark Brown 
3174e6e74030SMark Brown 	for (i = 0; i < num_consumers; i++)
3175e6e74030SMark Brown 		consumers[i].consumer = NULL;
3176e6e74030SMark Brown 
3177e6e74030SMark Brown 	for (i = 0; i < num_consumers; i++) {
3178e6e74030SMark Brown 		consumers[i].consumer = devm_regulator_get(dev,
3179e6e74030SMark Brown 							   consumers[i].supply);
3180e6e74030SMark Brown 		if (IS_ERR(consumers[i].consumer)) {
3181e6e74030SMark Brown 			ret = PTR_ERR(consumers[i].consumer);
3182e6e74030SMark Brown 			dev_err(dev, "Failed to get supply '%s': %d\n",
3183e6e74030SMark Brown 				consumers[i].supply, ret);
3184e6e74030SMark Brown 			consumers[i].consumer = NULL;
3185e6e74030SMark Brown 			goto err;
3186e6e74030SMark Brown 		}
3187e6e74030SMark Brown 	}
3188e6e74030SMark Brown 
3189e6e74030SMark Brown 	return 0;
3190e6e74030SMark Brown 
3191e6e74030SMark Brown err:
3192e6e74030SMark Brown 	for (i = 0; i < num_consumers && consumers[i].consumer; i++)
3193e6e74030SMark Brown 		devm_regulator_put(consumers[i].consumer);
3194e6e74030SMark Brown 
3195e6e74030SMark Brown 	return ret;
3196e6e74030SMark Brown }
3197e6e74030SMark Brown EXPORT_SYMBOL_GPL(devm_regulator_bulk_get);
3198e6e74030SMark Brown 
3199f21e0e81SMark Brown static void regulator_bulk_enable_async(void *data, async_cookie_t cookie)
3200f21e0e81SMark Brown {
3201f21e0e81SMark Brown 	struct regulator_bulk_data *bulk = data;
3202f21e0e81SMark Brown 
3203f21e0e81SMark Brown 	bulk->ret = regulator_enable(bulk->consumer);
3204f21e0e81SMark Brown }
3205f21e0e81SMark Brown 
3206414c70cbSLiam Girdwood /**
3207414c70cbSLiam Girdwood  * regulator_bulk_enable - enable multiple regulator consumers
3208414c70cbSLiam Girdwood  *
3209414c70cbSLiam Girdwood  * @num_consumers: Number of consumers
3210414c70cbSLiam Girdwood  * @consumers:     Consumer data; clients are stored here.
3211414c70cbSLiam Girdwood  * @return         0 on success, an errno on failure
3212414c70cbSLiam Girdwood  *
3213414c70cbSLiam Girdwood  * This convenience API allows consumers to enable multiple regulator
3214414c70cbSLiam Girdwood  * clients in a single API call.  If any consumers cannot be enabled
3215414c70cbSLiam Girdwood  * then any others that were enabled will be disabled again prior to
3216414c70cbSLiam Girdwood  * return.
3217414c70cbSLiam Girdwood  */
3218414c70cbSLiam Girdwood int regulator_bulk_enable(int num_consumers,
3219414c70cbSLiam Girdwood 			  struct regulator_bulk_data *consumers)
3220414c70cbSLiam Girdwood {
32212955b47dSDan Williams 	ASYNC_DOMAIN_EXCLUSIVE(async_domain);
3222414c70cbSLiam Girdwood 	int i;
3223f21e0e81SMark Brown 	int ret = 0;
3224414c70cbSLiam Girdwood 
32256492bc1bSMark Brown 	for (i = 0; i < num_consumers; i++) {
32266492bc1bSMark Brown 		if (consumers[i].consumer->always_on)
32276492bc1bSMark Brown 			consumers[i].ret = 0;
32286492bc1bSMark Brown 		else
3229f21e0e81SMark Brown 			async_schedule_domain(regulator_bulk_enable_async,
3230f21e0e81SMark Brown 					      &consumers[i], &async_domain);
32316492bc1bSMark Brown 	}
3232f21e0e81SMark Brown 
3233f21e0e81SMark Brown 	async_synchronize_full_domain(&async_domain);
3234f21e0e81SMark Brown 
3235f21e0e81SMark Brown 	/* If any consumer failed we need to unwind any that succeeded */
3236414c70cbSLiam Girdwood 	for (i = 0; i < num_consumers; i++) {
3237f21e0e81SMark Brown 		if (consumers[i].ret != 0) {
3238f21e0e81SMark Brown 			ret = consumers[i].ret;
3239414c70cbSLiam Girdwood 			goto err;
3240414c70cbSLiam Girdwood 		}
3241f21e0e81SMark Brown 	}
3242414c70cbSLiam Girdwood 
3243414c70cbSLiam Girdwood 	return 0;
3244414c70cbSLiam Girdwood 
3245414c70cbSLiam Girdwood err:
3246fbe31057SAndrzej Hajda 	for (i = 0; i < num_consumers; i++) {
3247fbe31057SAndrzej Hajda 		if (consumers[i].ret < 0)
3248fbe31057SAndrzej Hajda 			pr_err("Failed to enable %s: %d\n", consumers[i].supply,
3249fbe31057SAndrzej Hajda 			       consumers[i].ret);
3250fbe31057SAndrzej Hajda 		else
3251414c70cbSLiam Girdwood 			regulator_disable(consumers[i].consumer);
3252fbe31057SAndrzej Hajda 	}
3253414c70cbSLiam Girdwood 
3254414c70cbSLiam Girdwood 	return ret;
3255414c70cbSLiam Girdwood }
3256414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_bulk_enable);
3257414c70cbSLiam Girdwood 
3258414c70cbSLiam Girdwood /**
3259414c70cbSLiam Girdwood  * regulator_bulk_disable - disable multiple regulator consumers
3260414c70cbSLiam Girdwood  *
3261414c70cbSLiam Girdwood  * @num_consumers: Number of consumers
3262414c70cbSLiam Girdwood  * @consumers:     Consumer data; clients are stored here.
3263414c70cbSLiam Girdwood  * @return         0 on success, an errno on failure
3264414c70cbSLiam Girdwood  *
3265414c70cbSLiam Girdwood  * This convenience API allows consumers to disable multiple regulator
326649e22632SSylwester Nawrocki  * clients in a single API call.  If any consumers cannot be disabled
326749e22632SSylwester Nawrocki  * then any others that were disabled will be enabled again prior to
3268414c70cbSLiam Girdwood  * return.
3269414c70cbSLiam Girdwood  */
3270414c70cbSLiam Girdwood int regulator_bulk_disable(int num_consumers,
3271414c70cbSLiam Girdwood 			   struct regulator_bulk_data *consumers)
3272414c70cbSLiam Girdwood {
3273414c70cbSLiam Girdwood 	int i;
327401e86f49SMark Brown 	int ret, r;
3275414c70cbSLiam Girdwood 
327649e22632SSylwester Nawrocki 	for (i = num_consumers - 1; i >= 0; --i) {
3277414c70cbSLiam Girdwood 		ret = regulator_disable(consumers[i].consumer);
3278414c70cbSLiam Girdwood 		if (ret != 0)
3279414c70cbSLiam Girdwood 			goto err;
3280414c70cbSLiam Girdwood 	}
3281414c70cbSLiam Girdwood 
3282414c70cbSLiam Girdwood 	return 0;
3283414c70cbSLiam Girdwood 
3284414c70cbSLiam Girdwood err:
32855da84fd9SJoe Perches 	pr_err("Failed to disable %s: %d\n", consumers[i].supply, ret);
328601e86f49SMark Brown 	for (++i; i < num_consumers; ++i) {
328701e86f49SMark Brown 		r = regulator_enable(consumers[i].consumer);
328801e86f49SMark Brown 		if (r != 0)
328901e86f49SMark Brown 			pr_err("Failed to reename %s: %d\n",
329001e86f49SMark Brown 			       consumers[i].supply, r);
329101e86f49SMark Brown 	}
3292414c70cbSLiam Girdwood 
3293414c70cbSLiam Girdwood 	return ret;
3294414c70cbSLiam Girdwood }
3295414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_bulk_disable);
3296414c70cbSLiam Girdwood 
3297414c70cbSLiam Girdwood /**
3298e1de2f42SDonggeun Kim  * regulator_bulk_force_disable - force disable multiple regulator consumers
3299e1de2f42SDonggeun Kim  *
3300e1de2f42SDonggeun Kim  * @num_consumers: Number of consumers
3301e1de2f42SDonggeun Kim  * @consumers:     Consumer data; clients are stored here.
3302e1de2f42SDonggeun Kim  * @return         0 on success, an errno on failure
3303e1de2f42SDonggeun Kim  *
3304e1de2f42SDonggeun Kim  * This convenience API allows consumers to forcibly disable multiple regulator
3305e1de2f42SDonggeun Kim  * clients in a single API call.
3306e1de2f42SDonggeun Kim  * NOTE: This should be used for situations when device damage will
3307e1de2f42SDonggeun Kim  * likely occur if the regulators are not disabled (e.g. over temp).
3308e1de2f42SDonggeun Kim  * Although regulator_force_disable function call for some consumers can
3309e1de2f42SDonggeun Kim  * return error numbers, the function is called for all consumers.
3310e1de2f42SDonggeun Kim  */
3311e1de2f42SDonggeun Kim int regulator_bulk_force_disable(int num_consumers,
3312e1de2f42SDonggeun Kim 			   struct regulator_bulk_data *consumers)
3313e1de2f42SDonggeun Kim {
3314e1de2f42SDonggeun Kim 	int i;
3315e1de2f42SDonggeun Kim 	int ret;
3316e1de2f42SDonggeun Kim 
3317e1de2f42SDonggeun Kim 	for (i = 0; i < num_consumers; i++)
3318e1de2f42SDonggeun Kim 		consumers[i].ret =
3319e1de2f42SDonggeun Kim 			    regulator_force_disable(consumers[i].consumer);
3320e1de2f42SDonggeun Kim 
3321e1de2f42SDonggeun Kim 	for (i = 0; i < num_consumers; i++) {
3322e1de2f42SDonggeun Kim 		if (consumers[i].ret != 0) {
3323e1de2f42SDonggeun Kim 			ret = consumers[i].ret;
3324e1de2f42SDonggeun Kim 			goto out;
3325e1de2f42SDonggeun Kim 		}
3326e1de2f42SDonggeun Kim 	}
3327e1de2f42SDonggeun Kim 
3328e1de2f42SDonggeun Kim 	return 0;
3329e1de2f42SDonggeun Kim out:
3330e1de2f42SDonggeun Kim 	return ret;
3331e1de2f42SDonggeun Kim }
3332e1de2f42SDonggeun Kim EXPORT_SYMBOL_GPL(regulator_bulk_force_disable);
3333e1de2f42SDonggeun Kim 
3334e1de2f42SDonggeun Kim /**
3335414c70cbSLiam Girdwood  * regulator_bulk_free - free multiple regulator consumers
3336414c70cbSLiam Girdwood  *
3337414c70cbSLiam Girdwood  * @num_consumers: Number of consumers
3338414c70cbSLiam Girdwood  * @consumers:     Consumer data; clients are stored here.
3339414c70cbSLiam Girdwood  *
3340414c70cbSLiam Girdwood  * This convenience API allows consumers to free multiple regulator
3341414c70cbSLiam Girdwood  * clients in a single API call.
3342414c70cbSLiam Girdwood  */
3343414c70cbSLiam Girdwood void regulator_bulk_free(int num_consumers,
3344414c70cbSLiam Girdwood 			 struct regulator_bulk_data *consumers)
3345414c70cbSLiam Girdwood {
3346414c70cbSLiam Girdwood 	int i;
3347414c70cbSLiam Girdwood 
3348414c70cbSLiam Girdwood 	for (i = 0; i < num_consumers; i++) {
3349414c70cbSLiam Girdwood 		regulator_put(consumers[i].consumer);
3350414c70cbSLiam Girdwood 		consumers[i].consumer = NULL;
3351414c70cbSLiam Girdwood 	}
3352414c70cbSLiam Girdwood }
3353414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_bulk_free);
3354414c70cbSLiam Girdwood 
3355414c70cbSLiam Girdwood /**
3356414c70cbSLiam Girdwood  * regulator_notifier_call_chain - call regulator event notifier
335769279fb9SMark Brown  * @rdev: regulator source
3358414c70cbSLiam Girdwood  * @event: notifier block
335969279fb9SMark Brown  * @data: callback-specific data.
3360414c70cbSLiam Girdwood  *
3361414c70cbSLiam Girdwood  * Called by regulator drivers to notify clients a regulator event has
3362414c70cbSLiam Girdwood  * occurred. We also notify regulator clients downstream.
3363b136fb44SJonathan Cameron  * Note lock must be held by caller.
3364414c70cbSLiam Girdwood  */
3365414c70cbSLiam Girdwood int regulator_notifier_call_chain(struct regulator_dev *rdev,
3366414c70cbSLiam Girdwood 				  unsigned long event, void *data)
3367414c70cbSLiam Girdwood {
3368414c70cbSLiam Girdwood 	_notifier_call_chain(rdev, event, data);
3369414c70cbSLiam Girdwood 	return NOTIFY_DONE;
3370414c70cbSLiam Girdwood 
3371414c70cbSLiam Girdwood }
3372414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_notifier_call_chain);
3373414c70cbSLiam Girdwood 
3374be721979SMark Brown /**
3375be721979SMark Brown  * regulator_mode_to_status - convert a regulator mode into a status
3376be721979SMark Brown  *
3377be721979SMark Brown  * @mode: Mode to convert
3378be721979SMark Brown  *
3379be721979SMark Brown  * Convert a regulator mode into a status.
3380be721979SMark Brown  */
3381be721979SMark Brown int regulator_mode_to_status(unsigned int mode)
3382be721979SMark Brown {
3383be721979SMark Brown 	switch (mode) {
3384be721979SMark Brown 	case REGULATOR_MODE_FAST:
3385be721979SMark Brown 		return REGULATOR_STATUS_FAST;
3386be721979SMark Brown 	case REGULATOR_MODE_NORMAL:
3387be721979SMark Brown 		return REGULATOR_STATUS_NORMAL;
3388be721979SMark Brown 	case REGULATOR_MODE_IDLE:
3389be721979SMark Brown 		return REGULATOR_STATUS_IDLE;
339003ffcf3dSKrystian Garbaciak 	case REGULATOR_MODE_STANDBY:
3391be721979SMark Brown 		return REGULATOR_STATUS_STANDBY;
3392be721979SMark Brown 	default:
33931beaf762SKrystian Garbaciak 		return REGULATOR_STATUS_UNDEFINED;
3394be721979SMark Brown 	}
3395be721979SMark Brown }
3396be721979SMark Brown EXPORT_SYMBOL_GPL(regulator_mode_to_status);
3397be721979SMark Brown 
33987ad68e2fSDavid Brownell /*
33997ad68e2fSDavid Brownell  * To avoid cluttering sysfs (and memory) with useless state, only
34007ad68e2fSDavid Brownell  * create attributes that can be meaningfully displayed.
34017ad68e2fSDavid Brownell  */
34027ad68e2fSDavid Brownell static int add_regulator_attributes(struct regulator_dev *rdev)
34037ad68e2fSDavid Brownell {
34047ad68e2fSDavid Brownell 	struct device		*dev = &rdev->dev;
34057ad68e2fSDavid Brownell 	struct regulator_ops	*ops = rdev->desc->ops;
34067ad68e2fSDavid Brownell 	int			status = 0;
34077ad68e2fSDavid Brownell 
34087ad68e2fSDavid Brownell 	/* some attributes need specific methods to be displayed */
34094c78899bSMark Brown 	if ((ops->get_voltage && ops->get_voltage(rdev) >= 0) ||
3410f2889e65SMark Brown 	    (ops->get_voltage_sel && ops->get_voltage_sel(rdev) >= 0) ||
3411f2889e65SMark Brown 	    (ops->list_voltage && ops->list_voltage(rdev, 0) >= 0)) {
34127ad68e2fSDavid Brownell 		status = device_create_file(dev, &dev_attr_microvolts);
34137ad68e2fSDavid Brownell 		if (status < 0)
34147ad68e2fSDavid Brownell 			return status;
34157ad68e2fSDavid Brownell 	}
34167ad68e2fSDavid Brownell 	if (ops->get_current_limit) {
34177ad68e2fSDavid Brownell 		status = device_create_file(dev, &dev_attr_microamps);
34187ad68e2fSDavid Brownell 		if (status < 0)
34197ad68e2fSDavid Brownell 			return status;
34207ad68e2fSDavid Brownell 	}
34217ad68e2fSDavid Brownell 	if (ops->get_mode) {
34227ad68e2fSDavid Brownell 		status = device_create_file(dev, &dev_attr_opmode);
34237ad68e2fSDavid Brownell 		if (status < 0)
34247ad68e2fSDavid Brownell 			return status;
34257ad68e2fSDavid Brownell 	}
34267b74d149SKim, Milo 	if (rdev->ena_pin || ops->is_enabled) {
34277ad68e2fSDavid Brownell 		status = device_create_file(dev, &dev_attr_state);
34287ad68e2fSDavid Brownell 		if (status < 0)
34297ad68e2fSDavid Brownell 			return status;
34307ad68e2fSDavid Brownell 	}
3431853116a1SDavid Brownell 	if (ops->get_status) {
3432853116a1SDavid Brownell 		status = device_create_file(dev, &dev_attr_status);
3433853116a1SDavid Brownell 		if (status < 0)
3434853116a1SDavid Brownell 			return status;
3435853116a1SDavid Brownell 	}
3436f59c8f9fSMark Brown 	if (ops->get_bypass) {
3437f59c8f9fSMark Brown 		status = device_create_file(dev, &dev_attr_bypass);
3438f59c8f9fSMark Brown 		if (status < 0)
3439f59c8f9fSMark Brown 			return status;
3440f59c8f9fSMark Brown 	}
34417ad68e2fSDavid Brownell 
34427ad68e2fSDavid Brownell 	/* some attributes are type-specific */
34437ad68e2fSDavid Brownell 	if (rdev->desc->type == REGULATOR_CURRENT) {
34447ad68e2fSDavid Brownell 		status = device_create_file(dev, &dev_attr_requested_microamps);
34457ad68e2fSDavid Brownell 		if (status < 0)
34467ad68e2fSDavid Brownell 			return status;
34477ad68e2fSDavid Brownell 	}
34487ad68e2fSDavid Brownell 
34497ad68e2fSDavid Brownell 	/* all the other attributes exist to support constraints;
34507ad68e2fSDavid Brownell 	 * don't show them if there are no constraints, or if the
34517ad68e2fSDavid Brownell 	 * relevant supporting methods are missing.
34527ad68e2fSDavid Brownell 	 */
34537ad68e2fSDavid Brownell 	if (!rdev->constraints)
34547ad68e2fSDavid Brownell 		return status;
34557ad68e2fSDavid Brownell 
34567ad68e2fSDavid Brownell 	/* constraints need specific supporting methods */
3457e8eef82bSMark Brown 	if (ops->set_voltage || ops->set_voltage_sel) {
34587ad68e2fSDavid Brownell 		status = device_create_file(dev, &dev_attr_min_microvolts);
34597ad68e2fSDavid Brownell 		if (status < 0)
34607ad68e2fSDavid Brownell 			return status;
34617ad68e2fSDavid Brownell 		status = device_create_file(dev, &dev_attr_max_microvolts);
34627ad68e2fSDavid Brownell 		if (status < 0)
34637ad68e2fSDavid Brownell 			return status;
34647ad68e2fSDavid Brownell 	}
34657ad68e2fSDavid Brownell 	if (ops->set_current_limit) {
34667ad68e2fSDavid Brownell 		status = device_create_file(dev, &dev_attr_min_microamps);
34677ad68e2fSDavid Brownell 		if (status < 0)
34687ad68e2fSDavid Brownell 			return status;
34697ad68e2fSDavid Brownell 		status = device_create_file(dev, &dev_attr_max_microamps);
34707ad68e2fSDavid Brownell 		if (status < 0)
34717ad68e2fSDavid Brownell 			return status;
34727ad68e2fSDavid Brownell 	}
34737ad68e2fSDavid Brownell 
34747ad68e2fSDavid Brownell 	status = device_create_file(dev, &dev_attr_suspend_standby_state);
34757ad68e2fSDavid Brownell 	if (status < 0)
34767ad68e2fSDavid Brownell 		return status;
34777ad68e2fSDavid Brownell 	status = device_create_file(dev, &dev_attr_suspend_mem_state);
34787ad68e2fSDavid Brownell 	if (status < 0)
34797ad68e2fSDavid Brownell 		return status;
34807ad68e2fSDavid Brownell 	status = device_create_file(dev, &dev_attr_suspend_disk_state);
34817ad68e2fSDavid Brownell 	if (status < 0)
34827ad68e2fSDavid Brownell 		return status;
34837ad68e2fSDavid Brownell 
34847ad68e2fSDavid Brownell 	if (ops->set_suspend_voltage) {
34857ad68e2fSDavid Brownell 		status = device_create_file(dev,
34867ad68e2fSDavid Brownell 				&dev_attr_suspend_standby_microvolts);
34877ad68e2fSDavid Brownell 		if (status < 0)
34887ad68e2fSDavid Brownell 			return status;
34897ad68e2fSDavid Brownell 		status = device_create_file(dev,
34907ad68e2fSDavid Brownell 				&dev_attr_suspend_mem_microvolts);
34917ad68e2fSDavid Brownell 		if (status < 0)
34927ad68e2fSDavid Brownell 			return status;
34937ad68e2fSDavid Brownell 		status = device_create_file(dev,
34947ad68e2fSDavid Brownell 				&dev_attr_suspend_disk_microvolts);
34957ad68e2fSDavid Brownell 		if (status < 0)
34967ad68e2fSDavid Brownell 			return status;
34977ad68e2fSDavid Brownell 	}
34987ad68e2fSDavid Brownell 
34997ad68e2fSDavid Brownell 	if (ops->set_suspend_mode) {
35007ad68e2fSDavid Brownell 		status = device_create_file(dev,
35017ad68e2fSDavid Brownell 				&dev_attr_suspend_standby_mode);
35027ad68e2fSDavid Brownell 		if (status < 0)
35037ad68e2fSDavid Brownell 			return status;
35047ad68e2fSDavid Brownell 		status = device_create_file(dev,
35057ad68e2fSDavid Brownell 				&dev_attr_suspend_mem_mode);
35067ad68e2fSDavid Brownell 		if (status < 0)
35077ad68e2fSDavid Brownell 			return status;
35087ad68e2fSDavid Brownell 		status = device_create_file(dev,
35097ad68e2fSDavid Brownell 				&dev_attr_suspend_disk_mode);
35107ad68e2fSDavid Brownell 		if (status < 0)
35117ad68e2fSDavid Brownell 			return status;
35127ad68e2fSDavid Brownell 	}
35137ad68e2fSDavid Brownell 
35147ad68e2fSDavid Brownell 	return status;
35157ad68e2fSDavid Brownell }
35167ad68e2fSDavid Brownell 
35171130e5b3SMark Brown static void rdev_init_debugfs(struct regulator_dev *rdev)
35181130e5b3SMark Brown {
35191130e5b3SMark Brown 	rdev->debugfs = debugfs_create_dir(rdev_get_name(rdev), debugfs_root);
352024751434SStephen Boyd 	if (!rdev->debugfs) {
35211130e5b3SMark Brown 		rdev_warn(rdev, "Failed to create debugfs directory\n");
35221130e5b3SMark Brown 		return;
35231130e5b3SMark Brown 	}
35241130e5b3SMark Brown 
35251130e5b3SMark Brown 	debugfs_create_u32("use_count", 0444, rdev->debugfs,
35261130e5b3SMark Brown 			   &rdev->use_count);
35271130e5b3SMark Brown 	debugfs_create_u32("open_count", 0444, rdev->debugfs,
35281130e5b3SMark Brown 			   &rdev->open_count);
3529f59c8f9fSMark Brown 	debugfs_create_u32("bypass_count", 0444, rdev->debugfs,
3530f59c8f9fSMark Brown 			   &rdev->bypass_count);
35311130e5b3SMark Brown }
35321130e5b3SMark Brown 
3533414c70cbSLiam Girdwood /**
3534414c70cbSLiam Girdwood  * regulator_register - register regulator
353569279fb9SMark Brown  * @regulator_desc: regulator to register
3536c172708dSMark Brown  * @config: runtime configuration for regulator
3537414c70cbSLiam Girdwood  *
3538414c70cbSLiam Girdwood  * Called by regulator drivers to register a regulator.
35390384618aSAxel Lin  * Returns a valid pointer to struct regulator_dev on success
35400384618aSAxel Lin  * or an ERR_PTR() on error.
3541414c70cbSLiam Girdwood  */
354265f26846SMark Brown struct regulator_dev *
354365f26846SMark Brown regulator_register(const struct regulator_desc *regulator_desc,
3544c172708dSMark Brown 		   const struct regulator_config *config)
3545414c70cbSLiam Girdwood {
35469a8f5e07SMark Brown 	const struct regulation_constraints *constraints = NULL;
3547c172708dSMark Brown 	const struct regulator_init_data *init_data;
3548414c70cbSLiam Girdwood 	static atomic_t regulator_no = ATOMIC_INIT(0);
3549414c70cbSLiam Girdwood 	struct regulator_dev *rdev;
355032c8fad4SMark Brown 	struct device *dev;
3551a5766f11SLiam Girdwood 	int ret, i;
355269511a45SRajendra Nayak 	const char *supply = NULL;
3553414c70cbSLiam Girdwood 
3554c172708dSMark Brown 	if (regulator_desc == NULL || config == NULL)
3555414c70cbSLiam Girdwood 		return ERR_PTR(-EINVAL);
3556414c70cbSLiam Girdwood 
355732c8fad4SMark Brown 	dev = config->dev;
3558dcf70112SMark Brown 	WARN_ON(!dev);
355932c8fad4SMark Brown 
3560414c70cbSLiam Girdwood 	if (regulator_desc->name == NULL || regulator_desc->ops == NULL)
3561414c70cbSLiam Girdwood 		return ERR_PTR(-EINVAL);
3562414c70cbSLiam Girdwood 
3563cd78dfc6SDiego Liziero 	if (regulator_desc->type != REGULATOR_VOLTAGE &&
3564cd78dfc6SDiego Liziero 	    regulator_desc->type != REGULATOR_CURRENT)
3565414c70cbSLiam Girdwood 		return ERR_PTR(-EINVAL);
3566414c70cbSLiam Girdwood 
3567476c2d83SMark Brown 	/* Only one of each should be implemented */
3568476c2d83SMark Brown 	WARN_ON(regulator_desc->ops->get_voltage &&
3569476c2d83SMark Brown 		regulator_desc->ops->get_voltage_sel);
3570e8eef82bSMark Brown 	WARN_ON(regulator_desc->ops->set_voltage &&
3571e8eef82bSMark Brown 		regulator_desc->ops->set_voltage_sel);
3572476c2d83SMark Brown 
3573476c2d83SMark Brown 	/* If we're using selectors we must implement list_voltage. */
3574476c2d83SMark Brown 	if (regulator_desc->ops->get_voltage_sel &&
3575476c2d83SMark Brown 	    !regulator_desc->ops->list_voltage) {
3576476c2d83SMark Brown 		return ERR_PTR(-EINVAL);
3577476c2d83SMark Brown 	}
3578e8eef82bSMark Brown 	if (regulator_desc->ops->set_voltage_sel &&
3579e8eef82bSMark Brown 	    !regulator_desc->ops->list_voltage) {
3580e8eef82bSMark Brown 		return ERR_PTR(-EINVAL);
3581e8eef82bSMark Brown 	}
3582476c2d83SMark Brown 
3583c172708dSMark Brown 	init_data = config->init_data;
3584c172708dSMark Brown 
3585414c70cbSLiam Girdwood 	rdev = kzalloc(sizeof(struct regulator_dev), GFP_KERNEL);
3586414c70cbSLiam Girdwood 	if (rdev == NULL)
3587414c70cbSLiam Girdwood 		return ERR_PTR(-ENOMEM);
3588414c70cbSLiam Girdwood 
3589414c70cbSLiam Girdwood 	mutex_lock(&regulator_list_mutex);
3590414c70cbSLiam Girdwood 
3591414c70cbSLiam Girdwood 	mutex_init(&rdev->mutex);
3592c172708dSMark Brown 	rdev->reg_data = config->driver_data;
3593414c70cbSLiam Girdwood 	rdev->owner = regulator_desc->owner;
3594414c70cbSLiam Girdwood 	rdev->desc = regulator_desc;
35953a4b0a07SMark Brown 	if (config->regmap)
359665b19ce6SMark Brown 		rdev->regmap = config->regmap;
359752b84dacSAnilKumar Ch 	else if (dev_get_regmap(dev, NULL))
35983a4b0a07SMark Brown 		rdev->regmap = dev_get_regmap(dev, NULL);
359952b84dacSAnilKumar Ch 	else if (dev->parent)
360052b84dacSAnilKumar Ch 		rdev->regmap = dev_get_regmap(dev->parent, NULL);
3601414c70cbSLiam Girdwood 	INIT_LIST_HEAD(&rdev->consumer_list);
3602414c70cbSLiam Girdwood 	INIT_LIST_HEAD(&rdev->list);
3603414c70cbSLiam Girdwood 	BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier);
3604da07ecd9SMark Brown 	INIT_DELAYED_WORK(&rdev->disable_work, regulator_disable_work);
3605414c70cbSLiam Girdwood 
3606a5766f11SLiam Girdwood 	/* preform any regulator specific init */
36079a8f5e07SMark Brown 	if (init_data && init_data->regulator_init) {
3608a5766f11SLiam Girdwood 		ret = init_data->regulator_init(rdev->reg_data);
36094fca9545SDavid Brownell 		if (ret < 0)
36104fca9545SDavid Brownell 			goto clean;
3611a5766f11SLiam Girdwood 	}
3612a5766f11SLiam Girdwood 
3613a5766f11SLiam Girdwood 	/* register with sysfs */
3614a5766f11SLiam Girdwood 	rdev->dev.class = &regulator_class;
3615c172708dSMark Brown 	rdev->dev.of_node = config->of_node;
3616a5766f11SLiam Girdwood 	rdev->dev.parent = dev;
3617812460a9SKay Sievers 	dev_set_name(&rdev->dev, "regulator.%d",
3618812460a9SKay Sievers 		     atomic_inc_return(&regulator_no) - 1);
3619a5766f11SLiam Girdwood 	ret = device_register(&rdev->dev);
3620ad7725cbSVasiliy Kulikov 	if (ret != 0) {
3621ad7725cbSVasiliy Kulikov 		put_device(&rdev->dev);
36224fca9545SDavid Brownell 		goto clean;
3623ad7725cbSVasiliy Kulikov 	}
3624a5766f11SLiam Girdwood 
3625a5766f11SLiam Girdwood 	dev_set_drvdata(&rdev->dev, rdev);
3626a5766f11SLiam Girdwood 
3627b2a1ef47SMarek Szyprowski 	if (config->ena_gpio && gpio_is_valid(config->ena_gpio)) {
3628f19b00daSKim, Milo 		ret = regulator_ena_gpio_request(rdev, config);
362965f73508SMark Brown 		if (ret != 0) {
363065f73508SMark Brown 			rdev_err(rdev, "Failed to request enable GPIO%d: %d\n",
363165f73508SMark Brown 				 config->ena_gpio, ret);
3632b2da55d9SAndrew Lunn 			goto wash;
363365f73508SMark Brown 		}
363465f73508SMark Brown 
363565f73508SMark Brown 		if (config->ena_gpio_flags & GPIOF_OUT_INIT_HIGH)
363665f73508SMark Brown 			rdev->ena_gpio_state = 1;
363765f73508SMark Brown 
36387b74d149SKim, Milo 		if (config->ena_gpio_invert)
363965f73508SMark Brown 			rdev->ena_gpio_state = !rdev->ena_gpio_state;
364065f73508SMark Brown 	}
364165f73508SMark Brown 
364274f544c1SMike Rapoport 	/* set regulator constraints */
36439a8f5e07SMark Brown 	if (init_data)
36449a8f5e07SMark Brown 		constraints = &init_data->constraints;
36459a8f5e07SMark Brown 
36469a8f5e07SMark Brown 	ret = set_machine_constraints(rdev, constraints);
364774f544c1SMike Rapoport 	if (ret < 0)
364874f544c1SMike Rapoport 		goto scrub;
364974f544c1SMike Rapoport 
36507ad68e2fSDavid Brownell 	/* add attributes supported by this regulator */
36517ad68e2fSDavid Brownell 	ret = add_regulator_attributes(rdev);
36527ad68e2fSDavid Brownell 	if (ret < 0)
36537ad68e2fSDavid Brownell 		goto scrub;
36547ad68e2fSDavid Brownell 
36559a8f5e07SMark Brown 	if (init_data && init_data->supply_regulator)
365669511a45SRajendra Nayak 		supply = init_data->supply_regulator;
365769511a45SRajendra Nayak 	else if (regulator_desc->supply_name)
365869511a45SRajendra Nayak 		supply = regulator_desc->supply_name;
365969511a45SRajendra Nayak 
366069511a45SRajendra Nayak 	if (supply) {
36610178f3e2SMark Brown 		struct regulator_dev *r;
36620178f3e2SMark Brown 
36636d191a5fSMark Brown 		r = regulator_dev_lookup(dev, supply, &ret);
36640178f3e2SMark Brown 
36650f7b87f0SAndrew Bresticker 		if (ret == -ENODEV) {
36660f7b87f0SAndrew Bresticker 			/*
36670f7b87f0SAndrew Bresticker 			 * No supply was specified for this regulator and
36680f7b87f0SAndrew Bresticker 			 * there will never be one.
36690f7b87f0SAndrew Bresticker 			 */
36700f7b87f0SAndrew Bresticker 			ret = 0;
36710f7b87f0SAndrew Bresticker 			goto add_dev;
36720f7b87f0SAndrew Bresticker 		} else if (!r) {
367369511a45SRajendra Nayak 			dev_err(dev, "Failed to find supply %s\n", supply);
367404bf3011SMark Brown 			ret = -EPROBE_DEFER;
36750178f3e2SMark Brown 			goto scrub;
36760178f3e2SMark Brown 		}
36770178f3e2SMark Brown 
36780178f3e2SMark Brown 		ret = set_supply(rdev, r);
36790178f3e2SMark Brown 		if (ret < 0)
36800178f3e2SMark Brown 			goto scrub;
3681b2296bd4SLaxman Dewangan 
3682b2296bd4SLaxman Dewangan 		/* Enable supply if rail is enabled */
3683b1a86831SMark Brown 		if (_regulator_is_enabled(rdev)) {
3684b2296bd4SLaxman Dewangan 			ret = regulator_enable(rdev->supply);
3685b2296bd4SLaxman Dewangan 			if (ret < 0)
3686b2296bd4SLaxman Dewangan 				goto scrub;
3687b2296bd4SLaxman Dewangan 		}
36880178f3e2SMark Brown 	}
36890178f3e2SMark Brown 
36900f7b87f0SAndrew Bresticker add_dev:
3691a5766f11SLiam Girdwood 	/* add consumers devices */
36929a8f5e07SMark Brown 	if (init_data) {
3693a5766f11SLiam Girdwood 		for (i = 0; i < init_data->num_consumer_supplies; i++) {
3694a5766f11SLiam Girdwood 			ret = set_consumer_device_supply(rdev,
369540f9244fSMark Brown 				init_data->consumer_supplies[i].dev_name,
3696a5766f11SLiam Girdwood 				init_data->consumer_supplies[i].supply);
369723c2f041SMark Brown 			if (ret < 0) {
369823c2f041SMark Brown 				dev_err(dev, "Failed to set supply %s\n",
369923c2f041SMark Brown 					init_data->consumer_supplies[i].supply);
3700d4033b54SJani Nikula 				goto unset_supplies;
3701a5766f11SLiam Girdwood 			}
370223c2f041SMark Brown 		}
37039a8f5e07SMark Brown 	}
3704a5766f11SLiam Girdwood 
3705a5766f11SLiam Girdwood 	list_add(&rdev->list, &regulator_list);
37061130e5b3SMark Brown 
37071130e5b3SMark Brown 	rdev_init_debugfs(rdev);
3708a5766f11SLiam Girdwood out:
3709414c70cbSLiam Girdwood 	mutex_unlock(&regulator_list_mutex);
3710414c70cbSLiam Girdwood 	return rdev;
37114fca9545SDavid Brownell 
3712d4033b54SJani Nikula unset_supplies:
3713d4033b54SJani Nikula 	unset_regulator_supplies(rdev);
3714d4033b54SJani Nikula 
37154fca9545SDavid Brownell scrub:
3716e81dba85SMark Brown 	if (rdev->supply)
371723ff2f0fSCharles Keepax 		_regulator_put(rdev->supply);
3718f19b00daSKim, Milo 	regulator_ena_gpio_free(rdev);
37191a6958e7SAxel Lin 	kfree(rdev->constraints);
3720b2da55d9SAndrew Lunn wash:
37214fca9545SDavid Brownell 	device_unregister(&rdev->dev);
372253032dafSPaul Walmsley 	/* device core frees rdev */
372353032dafSPaul Walmsley 	rdev = ERR_PTR(ret);
372453032dafSPaul Walmsley 	goto out;
372553032dafSPaul Walmsley 
37264fca9545SDavid Brownell clean:
37274fca9545SDavid Brownell 	kfree(rdev);
37284fca9545SDavid Brownell 	rdev = ERR_PTR(ret);
37294fca9545SDavid Brownell 	goto out;
3730414c70cbSLiam Girdwood }
3731414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_register);
3732414c70cbSLiam Girdwood 
3733414c70cbSLiam Girdwood /**
3734414c70cbSLiam Girdwood  * regulator_unregister - unregister regulator
373569279fb9SMark Brown  * @rdev: regulator to unregister
3736414c70cbSLiam Girdwood  *
3737414c70cbSLiam Girdwood  * Called by regulator drivers to unregister a regulator.
3738414c70cbSLiam Girdwood  */
3739414c70cbSLiam Girdwood void regulator_unregister(struct regulator_dev *rdev)
3740414c70cbSLiam Girdwood {
3741414c70cbSLiam Girdwood 	if (rdev == NULL)
3742414c70cbSLiam Girdwood 		return;
3743414c70cbSLiam Girdwood 
3744891636eaSMark Brown 	if (rdev->supply) {
3745891636eaSMark Brown 		while (rdev->use_count--)
3746891636eaSMark Brown 			regulator_disable(rdev->supply);
3747e032b376SMark Brown 		regulator_put(rdev->supply);
3748891636eaSMark Brown 	}
3749414c70cbSLiam Girdwood 	mutex_lock(&regulator_list_mutex);
37501130e5b3SMark Brown 	debugfs_remove_recursive(rdev->debugfs);
375143829731STejun Heo 	flush_work(&rdev->disable_work.work);
37526bf87d17SMark Brown 	WARN_ON(rdev->open_count);
37530f1d747bSMike Rapoport 	unset_regulator_supplies(rdev);
3754414c70cbSLiam Girdwood 	list_del(&rdev->list);
3755f8c12fe3SMark Brown 	kfree(rdev->constraints);
3756f19b00daSKim, Milo 	regulator_ena_gpio_free(rdev);
375758fb5cf5SLothar Waßmann 	device_unregister(&rdev->dev);
3758414c70cbSLiam Girdwood 	mutex_unlock(&regulator_list_mutex);
3759414c70cbSLiam Girdwood }
3760414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_unregister);
3761414c70cbSLiam Girdwood 
3762414c70cbSLiam Girdwood /**
3763cf7bbcdfSMark Brown  * regulator_suspend_prepare - prepare regulators for system wide suspend
3764414c70cbSLiam Girdwood  * @state: system suspend state
3765414c70cbSLiam Girdwood  *
3766414c70cbSLiam Girdwood  * Configure each regulator with it's suspend operating parameters for state.
3767414c70cbSLiam Girdwood  * This will usually be called by machine suspend code prior to supending.
3768414c70cbSLiam Girdwood  */
3769414c70cbSLiam Girdwood int regulator_suspend_prepare(suspend_state_t state)
3770414c70cbSLiam Girdwood {
3771414c70cbSLiam Girdwood 	struct regulator_dev *rdev;
3772414c70cbSLiam Girdwood 	int ret = 0;
3773414c70cbSLiam Girdwood 
3774414c70cbSLiam Girdwood 	/* ON is handled by regulator active state */
3775414c70cbSLiam Girdwood 	if (state == PM_SUSPEND_ON)
3776414c70cbSLiam Girdwood 		return -EINVAL;
3777414c70cbSLiam Girdwood 
3778414c70cbSLiam Girdwood 	mutex_lock(&regulator_list_mutex);
3779414c70cbSLiam Girdwood 	list_for_each_entry(rdev, &regulator_list, list) {
3780414c70cbSLiam Girdwood 
3781414c70cbSLiam Girdwood 		mutex_lock(&rdev->mutex);
3782414c70cbSLiam Girdwood 		ret = suspend_prepare(rdev, state);
3783414c70cbSLiam Girdwood 		mutex_unlock(&rdev->mutex);
3784414c70cbSLiam Girdwood 
3785414c70cbSLiam Girdwood 		if (ret < 0) {
37865da84fd9SJoe Perches 			rdev_err(rdev, "failed to prepare\n");
3787414c70cbSLiam Girdwood 			goto out;
3788414c70cbSLiam Girdwood 		}
3789414c70cbSLiam Girdwood 	}
3790414c70cbSLiam Girdwood out:
3791414c70cbSLiam Girdwood 	mutex_unlock(&regulator_list_mutex);
3792414c70cbSLiam Girdwood 	return ret;
3793414c70cbSLiam Girdwood }
3794414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_suspend_prepare);
3795414c70cbSLiam Girdwood 
3796414c70cbSLiam Girdwood /**
37977a32b589SMyungJoo Ham  * regulator_suspend_finish - resume regulators from system wide suspend
37987a32b589SMyungJoo Ham  *
37997a32b589SMyungJoo Ham  * Turn on regulators that might be turned off by regulator_suspend_prepare
38007a32b589SMyungJoo Ham  * and that should be turned on according to the regulators properties.
38017a32b589SMyungJoo Ham  */
38027a32b589SMyungJoo Ham int regulator_suspend_finish(void)
38037a32b589SMyungJoo Ham {
38047a32b589SMyungJoo Ham 	struct regulator_dev *rdev;
38057a32b589SMyungJoo Ham 	int ret = 0, error;
38067a32b589SMyungJoo Ham 
38077a32b589SMyungJoo Ham 	mutex_lock(&regulator_list_mutex);
38087a32b589SMyungJoo Ham 	list_for_each_entry(rdev, &regulator_list, list) {
38097a32b589SMyungJoo Ham 		struct regulator_ops *ops = rdev->desc->ops;
38107a32b589SMyungJoo Ham 
38117a32b589SMyungJoo Ham 		mutex_lock(&rdev->mutex);
38127a32b589SMyungJoo Ham 		if ((rdev->use_count > 0  || rdev->constraints->always_on) &&
38137a32b589SMyungJoo Ham 				ops->enable) {
38147a32b589SMyungJoo Ham 			error = ops->enable(rdev);
38157a32b589SMyungJoo Ham 			if (error)
38167a32b589SMyungJoo Ham 				ret = error;
38177a32b589SMyungJoo Ham 		} else {
38187a32b589SMyungJoo Ham 			if (!has_full_constraints)
38197a32b589SMyungJoo Ham 				goto unlock;
38207a32b589SMyungJoo Ham 			if (!ops->disable)
38217a32b589SMyungJoo Ham 				goto unlock;
3822b1a86831SMark Brown 			if (!_regulator_is_enabled(rdev))
38237a32b589SMyungJoo Ham 				goto unlock;
38247a32b589SMyungJoo Ham 
38257a32b589SMyungJoo Ham 			error = ops->disable(rdev);
38267a32b589SMyungJoo Ham 			if (error)
38277a32b589SMyungJoo Ham 				ret = error;
38287a32b589SMyungJoo Ham 		}
38297a32b589SMyungJoo Ham unlock:
38307a32b589SMyungJoo Ham 		mutex_unlock(&rdev->mutex);
38317a32b589SMyungJoo Ham 	}
38327a32b589SMyungJoo Ham 	mutex_unlock(&regulator_list_mutex);
38337a32b589SMyungJoo Ham 	return ret;
38347a32b589SMyungJoo Ham }
38357a32b589SMyungJoo Ham EXPORT_SYMBOL_GPL(regulator_suspend_finish);
38367a32b589SMyungJoo Ham 
38377a32b589SMyungJoo Ham /**
3838ca725561SMark Brown  * regulator_has_full_constraints - the system has fully specified constraints
3839ca725561SMark Brown  *
3840ca725561SMark Brown  * Calling this function will cause the regulator API to disable all
3841ca725561SMark Brown  * regulators which have a zero use count and don't have an always_on
3842ca725561SMark Brown  * constraint in a late_initcall.
3843ca725561SMark Brown  *
3844ca725561SMark Brown  * The intention is that this will become the default behaviour in a
3845ca725561SMark Brown  * future kernel release so users are encouraged to use this facility
3846ca725561SMark Brown  * now.
3847ca725561SMark Brown  */
3848ca725561SMark Brown void regulator_has_full_constraints(void)
3849ca725561SMark Brown {
3850ca725561SMark Brown 	has_full_constraints = 1;
3851ca725561SMark Brown }
3852ca725561SMark Brown EXPORT_SYMBOL_GPL(regulator_has_full_constraints);
3853ca725561SMark Brown 
3854ca725561SMark Brown /**
3855688fe99aSMark Brown  * regulator_use_dummy_regulator - Provide a dummy regulator when none is found
3856688fe99aSMark Brown  *
3857688fe99aSMark Brown  * Calling this function will cause the regulator API to provide a
3858688fe99aSMark Brown  * dummy regulator to consumers if no physical regulator is found,
3859688fe99aSMark Brown  * allowing most consumers to proceed as though a regulator were
3860688fe99aSMark Brown  * configured.  This allows systems such as those with software
3861688fe99aSMark Brown  * controllable regulators for the CPU core only to be brought up more
3862688fe99aSMark Brown  * readily.
3863688fe99aSMark Brown  */
3864688fe99aSMark Brown void regulator_use_dummy_regulator(void)
3865688fe99aSMark Brown {
3866688fe99aSMark Brown 	board_wants_dummy_regulator = true;
3867688fe99aSMark Brown }
3868688fe99aSMark Brown EXPORT_SYMBOL_GPL(regulator_use_dummy_regulator);
3869688fe99aSMark Brown 
3870688fe99aSMark Brown /**
3871414c70cbSLiam Girdwood  * rdev_get_drvdata - get rdev regulator driver data
387269279fb9SMark Brown  * @rdev: regulator
3873414c70cbSLiam Girdwood  *
3874414c70cbSLiam Girdwood  * Get rdev regulator driver private data. This call can be used in the
3875414c70cbSLiam Girdwood  * regulator driver context.
3876414c70cbSLiam Girdwood  */
3877414c70cbSLiam Girdwood void *rdev_get_drvdata(struct regulator_dev *rdev)
3878414c70cbSLiam Girdwood {
3879414c70cbSLiam Girdwood 	return rdev->reg_data;
3880414c70cbSLiam Girdwood }
3881414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(rdev_get_drvdata);
3882414c70cbSLiam Girdwood 
3883414c70cbSLiam Girdwood /**
3884414c70cbSLiam Girdwood  * regulator_get_drvdata - get regulator driver data
3885414c70cbSLiam Girdwood  * @regulator: regulator
3886414c70cbSLiam Girdwood  *
3887414c70cbSLiam Girdwood  * Get regulator driver private data. This call can be used in the consumer
3888414c70cbSLiam Girdwood  * driver context when non API regulator specific functions need to be called.
3889414c70cbSLiam Girdwood  */
3890414c70cbSLiam Girdwood void *regulator_get_drvdata(struct regulator *regulator)
3891414c70cbSLiam Girdwood {
3892414c70cbSLiam Girdwood 	return regulator->rdev->reg_data;
3893414c70cbSLiam Girdwood }
3894414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_get_drvdata);
3895414c70cbSLiam Girdwood 
3896414c70cbSLiam Girdwood /**
3897414c70cbSLiam Girdwood  * regulator_set_drvdata - set regulator driver data
3898414c70cbSLiam Girdwood  * @regulator: regulator
3899414c70cbSLiam Girdwood  * @data: data
3900414c70cbSLiam Girdwood  */
3901414c70cbSLiam Girdwood void regulator_set_drvdata(struct regulator *regulator, void *data)
3902414c70cbSLiam Girdwood {
3903414c70cbSLiam Girdwood 	regulator->rdev->reg_data = data;
3904414c70cbSLiam Girdwood }
3905414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(regulator_set_drvdata);
3906414c70cbSLiam Girdwood 
3907414c70cbSLiam Girdwood /**
3908414c70cbSLiam Girdwood  * regulator_get_id - get regulator ID
390969279fb9SMark Brown  * @rdev: regulator
3910414c70cbSLiam Girdwood  */
3911414c70cbSLiam Girdwood int rdev_get_id(struct regulator_dev *rdev)
3912414c70cbSLiam Girdwood {
3913414c70cbSLiam Girdwood 	return rdev->desc->id;
3914414c70cbSLiam Girdwood }
3915414c70cbSLiam Girdwood EXPORT_SYMBOL_GPL(rdev_get_id);
3916414c70cbSLiam Girdwood 
3917a5766f11SLiam Girdwood struct device *rdev_get_dev(struct regulator_dev *rdev)
3918a5766f11SLiam Girdwood {
3919a5766f11SLiam Girdwood 	return &rdev->dev;
3920a5766f11SLiam Girdwood }
3921a5766f11SLiam Girdwood EXPORT_SYMBOL_GPL(rdev_get_dev);
3922a5766f11SLiam Girdwood 
3923a5766f11SLiam Girdwood void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data)
3924a5766f11SLiam Girdwood {
3925a5766f11SLiam Girdwood 	return reg_init_data->driver_data;
3926a5766f11SLiam Girdwood }
3927a5766f11SLiam Girdwood EXPORT_SYMBOL_GPL(regulator_get_init_drvdata);
3928a5766f11SLiam Girdwood 
3929ba55a974SMark Brown #ifdef CONFIG_DEBUG_FS
3930ba55a974SMark Brown static ssize_t supply_map_read_file(struct file *file, char __user *user_buf,
3931ba55a974SMark Brown 				    size_t count, loff_t *ppos)
3932ba55a974SMark Brown {
3933ba55a974SMark Brown 	char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
3934ba55a974SMark Brown 	ssize_t len, ret = 0;
3935ba55a974SMark Brown 	struct regulator_map *map;
3936ba55a974SMark Brown 
3937ba55a974SMark Brown 	if (!buf)
3938ba55a974SMark Brown 		return -ENOMEM;
3939ba55a974SMark Brown 
3940ba55a974SMark Brown 	list_for_each_entry(map, &regulator_map_list, list) {
3941ba55a974SMark Brown 		len = snprintf(buf + ret, PAGE_SIZE - ret,
3942ba55a974SMark Brown 			       "%s -> %s.%s\n",
3943ba55a974SMark Brown 			       rdev_get_name(map->regulator), map->dev_name,
3944ba55a974SMark Brown 			       map->supply);
3945ba55a974SMark Brown 		if (len >= 0)
3946ba55a974SMark Brown 			ret += len;
3947ba55a974SMark Brown 		if (ret > PAGE_SIZE) {
3948ba55a974SMark Brown 			ret = PAGE_SIZE;
3949ba55a974SMark Brown 			break;
3950ba55a974SMark Brown 		}
3951ba55a974SMark Brown 	}
3952ba55a974SMark Brown 
3953ba55a974SMark Brown 	ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
3954ba55a974SMark Brown 
3955ba55a974SMark Brown 	kfree(buf);
3956ba55a974SMark Brown 
3957ba55a974SMark Brown 	return ret;
3958ba55a974SMark Brown }
395924751434SStephen Boyd #endif
3960ba55a974SMark Brown 
3961ba55a974SMark Brown static const struct file_operations supply_map_fops = {
396224751434SStephen Boyd #ifdef CONFIG_DEBUG_FS
3963ba55a974SMark Brown 	.read = supply_map_read_file,
3964ba55a974SMark Brown 	.llseek = default_llseek,
3965ba55a974SMark Brown #endif
396624751434SStephen Boyd };
3967ba55a974SMark Brown 
3968414c70cbSLiam Girdwood static int __init regulator_init(void)
3969414c70cbSLiam Girdwood {
397034abbd68SMark Brown 	int ret;
397134abbd68SMark Brown 
397234abbd68SMark Brown 	ret = class_register(&regulator_class);
397334abbd68SMark Brown 
39741130e5b3SMark Brown 	debugfs_root = debugfs_create_dir("regulator", NULL);
397524751434SStephen Boyd 	if (!debugfs_root)
39761130e5b3SMark Brown 		pr_warn("regulator: Failed to create debugfs directory\n");
3977ba55a974SMark Brown 
3978f4d562c6SMark Brown 	debugfs_create_file("supply_map", 0444, debugfs_root, NULL,
3979f4d562c6SMark Brown 			    &supply_map_fops);
39801130e5b3SMark Brown 
398134abbd68SMark Brown 	regulator_dummy_init();
398234abbd68SMark Brown 
398334abbd68SMark Brown 	return ret;
3984414c70cbSLiam Girdwood }
3985414c70cbSLiam Girdwood 
3986414c70cbSLiam Girdwood /* init early to allow our consumers to complete system booting */
3987414c70cbSLiam Girdwood core_initcall(regulator_init);
3988ca725561SMark Brown 
3989ca725561SMark Brown static int __init regulator_init_complete(void)
3990ca725561SMark Brown {
3991ca725561SMark Brown 	struct regulator_dev *rdev;
3992ca725561SMark Brown 	struct regulator_ops *ops;
3993ca725561SMark Brown 	struct regulation_constraints *c;
3994ca725561SMark Brown 	int enabled, ret;
3995ca725561SMark Brown 
399686f5fcfcSMark Brown 	/*
399786f5fcfcSMark Brown 	 * Since DT doesn't provide an idiomatic mechanism for
399886f5fcfcSMark Brown 	 * enabling full constraints and since it's much more natural
399986f5fcfcSMark Brown 	 * with DT to provide them just assume that a DT enabled
400086f5fcfcSMark Brown 	 * system has full constraints.
400186f5fcfcSMark Brown 	 */
400286f5fcfcSMark Brown 	if (of_have_populated_dt())
400386f5fcfcSMark Brown 		has_full_constraints = true;
400486f5fcfcSMark Brown 
4005ca725561SMark Brown 	mutex_lock(&regulator_list_mutex);
4006ca725561SMark Brown 
4007ca725561SMark Brown 	/* If we have a full configuration then disable any regulators
4008ca725561SMark Brown 	 * which are not in use or always_on.  This will become the
4009ca725561SMark Brown 	 * default behaviour in the future.
4010ca725561SMark Brown 	 */
4011ca725561SMark Brown 	list_for_each_entry(rdev, &regulator_list, list) {
4012ca725561SMark Brown 		ops = rdev->desc->ops;
4013ca725561SMark Brown 		c = rdev->constraints;
4014ca725561SMark Brown 
4015f25e0b4fSMark Brown 		if (!ops->disable || (c && c->always_on))
4016ca725561SMark Brown 			continue;
4017ca725561SMark Brown 
4018ca725561SMark Brown 		mutex_lock(&rdev->mutex);
4019ca725561SMark Brown 
4020ca725561SMark Brown 		if (rdev->use_count)
4021ca725561SMark Brown 			goto unlock;
4022ca725561SMark Brown 
4023ca725561SMark Brown 		/* If we can't read the status assume it's on. */
4024ca725561SMark Brown 		if (ops->is_enabled)
4025ca725561SMark Brown 			enabled = ops->is_enabled(rdev);
4026ca725561SMark Brown 		else
4027ca725561SMark Brown 			enabled = 1;
4028ca725561SMark Brown 
4029ca725561SMark Brown 		if (!enabled)
4030ca725561SMark Brown 			goto unlock;
4031ca725561SMark Brown 
4032ca725561SMark Brown 		if (has_full_constraints) {
4033ca725561SMark Brown 			/* We log since this may kill the system if it
4034ca725561SMark Brown 			 * goes wrong. */
40355da84fd9SJoe Perches 			rdev_info(rdev, "disabling\n");
4036ca725561SMark Brown 			ret = ops->disable(rdev);
4037ca725561SMark Brown 			if (ret != 0) {
40385da84fd9SJoe Perches 				rdev_err(rdev, "couldn't disable: %d\n", ret);
4039ca725561SMark Brown 			}
4040ca725561SMark Brown 		} else {
4041ca725561SMark Brown 			/* The intention is that in future we will
4042ca725561SMark Brown 			 * assume that full constraints are provided
4043ca725561SMark Brown 			 * so warn even if we aren't going to do
4044ca725561SMark Brown 			 * anything here.
4045ca725561SMark Brown 			 */
40465da84fd9SJoe Perches 			rdev_warn(rdev, "incomplete constraints, leaving on\n");
4047ca725561SMark Brown 		}
4048ca725561SMark Brown 
4049ca725561SMark Brown unlock:
4050ca725561SMark Brown 		mutex_unlock(&rdev->mutex);
4051ca725561SMark Brown 	}
4052ca725561SMark Brown 
4053ca725561SMark Brown 	mutex_unlock(&regulator_list_mutex);
4054ca725561SMark Brown 
4055ca725561SMark Brown 	return 0;
4056ca725561SMark Brown }
4057ca725561SMark Brown late_initcall(regulator_init_complete);
4058