core.c revision 89f425ed5bf3d4fd97e840296dccd75b8e0fe4c9
1414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/*
2414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * core.c  --  Voltage/Current Regulator framework.
3414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
4414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Copyright 2007, 2008 Wolfson Microelectronics PLC.
5a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * Copyright 2008 SlimLogic Ltd.
6414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
7a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * Author: Liam Girdwood <lrg@slimlogic.co.uk>
8414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
9414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *  This program is free software; you can redistribute  it and/or modify it
10414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *  under  the terms of  the GNU General  Public License as published by the
11414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *  Free Software Foundation;  either version 2 of the  License, or (at your
12414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *  option) any later version.
13414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
14414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
15414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
161d7372e15ebd7f56a336fabe6ee31f8e692cd9cbDaniel Walker#define pr_fmt(fmt) "%s: " fmt, __func__
17c5e28ed78274468b92522e7f1e9a5e6080559100Daniel Walker
18414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood#include <linux/kernel.h>
19414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood#include <linux/init.h>
201130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown#include <linux/debugfs.h>
21414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood#include <linux/device.h>
225a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
23f21e0e81d81b649ad309cedc7226f1bed72982e0Mark Brown#include <linux/async.h>
24414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood#include <linux/err.h>
25414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood#include <linux/mutex.h>
26414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood#include <linux/suspend.h>
2731aae2beeb3d601d556b6a8c39085940ad1e9f42Mark Brown#include <linux/delay.h>
28414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood#include <linux/regulator/consumer.h>
29414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood#include <linux/regulator/driver.h>
30414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood#include <linux/regulator/machine.h>
31414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
3202fa3ec01a0df7a8ccc356d8e245a9a1423b3596Mark Brown#define CREATE_TRACE_POINTS
3302fa3ec01a0df7a8ccc356d8e245a9a1423b3596Mark Brown#include <trace/events/regulator.h>
3402fa3ec01a0df7a8ccc356d8e245a9a1423b3596Mark Brown
3534abbd68efe09765465b81dfedeee9994f13302fMark Brown#include "dummy.h"
3634abbd68efe09765465b81dfedeee9994f13302fMark Brown
377d51a0dbe51282f3ed13cadf6e7f13a974374be2Mark Brown#define rdev_crit(rdev, fmt, ...)					\
387d51a0dbe51282f3ed13cadf6e7f13a974374be2Mark Brown	pr_crit("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
395da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches#define rdev_err(rdev, fmt, ...)					\
405da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches	pr_err("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
415da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches#define rdev_warn(rdev, fmt, ...)					\
425da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches	pr_warn("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
435da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches#define rdev_info(rdev, fmt, ...)					\
445da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches	pr_info("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
455da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches#define rdev_dbg(rdev, fmt, ...)					\
465da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches	pr_debug("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
475da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches
48414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic DEFINE_MUTEX(regulator_list_mutex);
49414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic LIST_HEAD(regulator_list);
50414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic LIST_HEAD(regulator_map_list);
5121cf891a47ff5e7bd77fdc524a25072c447d56bbMark Brownstatic bool has_full_constraints;
52688fe99a439f7c9dfcc52fbf7cb347f140a2dc8bMark Brownstatic bool board_wants_dummy_regulator;
53414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
541130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown#ifdef CONFIG_DEBUG_FS
551130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brownstatic struct dentry *debugfs_root;
561130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown#endif
571130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown
588dc5390d4f3fd8acc73773a56fea13544e7924dcMark Brown/*
59414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * struct regulator_map
60414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
61414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Used to provide symbolic supply names to devices.
62414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
63414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstruct regulator_map {
64414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct list_head list;
6540f9244f4da8976eeb6d5ed6313c635ba238a9d3Mark Brown	const char *dev_name;   /* The dev_name() for the consumer */
66414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	const char *supply;
67a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *regulator;
68414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood};
69414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
70414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/*
71414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * struct regulator
72414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
73414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * One for each consumer device.
74414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
75414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstruct regulator {
76414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct device *dev;
77414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct list_head list;
78414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int uA_load;
79414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int min_uV;
80414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int max_uV;
81414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	char *supply_name;
82414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct device_attribute dev_attr;
83414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator_dev *rdev;
845de705194e9883a39f993e2ff96028d5aab99b37Mark Brown#ifdef CONFIG_DEBUG_FS
855de705194e9883a39f993e2ff96028d5aab99b37Mark Brown	struct dentry *debugfs;
865de705194e9883a39f993e2ff96028d5aab99b37Mark Brown#endif
87414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood};
88414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
89414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic int _regulator_is_enabled(struct regulator_dev *rdev);
903801b86aa482d26a8ae460f67fca29e016491a86Mark Brownstatic int _regulator_disable(struct regulator_dev *rdev);
91414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic int _regulator_get_voltage(struct regulator_dev *rdev);
92414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic int _regulator_get_current_limit(struct regulator_dev *rdev);
93414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic unsigned int _regulator_get_mode(struct regulator_dev *rdev);
94414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic void _notifier_call_chain(struct regulator_dev *rdev,
95414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				  unsigned long event, void *data);
96757902513019e6ee469791ff76f954b19ca8d036Mark Brownstatic int _regulator_do_set_voltage(struct regulator_dev *rdev,
97757902513019e6ee469791ff76f954b19ca8d036Mark Brown				     int min_uV, int max_uV);
983801b86aa482d26a8ae460f67fca29e016491a86Mark Brownstatic struct regulator *create_regulator(struct regulator_dev *rdev,
993801b86aa482d26a8ae460f67fca29e016491a86Mark Brown					  struct device *dev,
1003801b86aa482d26a8ae460f67fca29e016491a86Mark Brown					  const char *supply_name);
101414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1021083c39346d482b9001944d05c09191027892226Mark Brownstatic const char *rdev_get_name(struct regulator_dev *rdev)
1031083c39346d482b9001944d05c09191027892226Mark Brown{
1041083c39346d482b9001944d05c09191027892226Mark Brown	if (rdev->constraints && rdev->constraints->name)
1051083c39346d482b9001944d05c09191027892226Mark Brown		return rdev->constraints->name;
1061083c39346d482b9001944d05c09191027892226Mark Brown	else if (rdev->desc->name)
1071083c39346d482b9001944d05c09191027892226Mark Brown		return rdev->desc->name;
1081083c39346d482b9001944d05c09191027892226Mark Brown	else
1091083c39346d482b9001944d05c09191027892226Mark Brown		return "";
1101083c39346d482b9001944d05c09191027892226Mark Brown}
1111083c39346d482b9001944d05c09191027892226Mark Brown
112414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/* gets the regulator for a given consumer device */
113414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic struct regulator *get_device_regulator(struct device *dev)
114414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
115414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator *regulator = NULL;
116414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator_dev *rdev;
117414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
118414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&regulator_list_mutex);
119414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	list_for_each_entry(rdev, &regulator_list, list) {
120414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		mutex_lock(&rdev->mutex);
121414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		list_for_each_entry(regulator, &rdev->consumer_list, list) {
122414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			if (regulator->dev == dev) {
123414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				mutex_unlock(&rdev->mutex);
124414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				mutex_unlock(&regulator_list_mutex);
125414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				return regulator;
126414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			}
127414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		}
128414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		mutex_unlock(&rdev->mutex);
129414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
130414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&regulator_list_mutex);
131414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return NULL;
132414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
133414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
134414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/* Platform voltage constraint check */
135414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic int regulator_check_voltage(struct regulator_dev *rdev,
136414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				   int *min_uV, int *max_uV)
137414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
138414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	BUG_ON(*min_uV > *max_uV);
139414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
140414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->constraints) {
1415da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches		rdev_err(rdev, "no constraints\n");
142414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -ENODEV;
143414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
144414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) {
1455da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches		rdev_err(rdev, "operation not allowed\n");
146414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -EPERM;
147414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
148414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
149414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (*max_uV > rdev->constraints->max_uV)
150414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		*max_uV = rdev->constraints->max_uV;
151414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (*min_uV < rdev->constraints->min_uV)
152414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		*min_uV = rdev->constraints->min_uV;
153414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
15489f425ed5bf3d4fd97e840296dccd75b8e0fe4c9Mark Brown	if (*min_uV > *max_uV) {
15589f425ed5bf3d4fd97e840296dccd75b8e0fe4c9Mark Brown		rdev_err(rdev, "unsupportable voltage range: %d-%duV\n",
15689f425ed5bf3d4fd97e840296dccd75b8e0fe4c9Mark Brown			 min_uV, max_uV);
157414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -EINVAL;
15889f425ed5bf3d4fd97e840296dccd75b8e0fe4c9Mark Brown	}
159414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
160414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return 0;
161414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
162414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
16305fda3b1abc23d832144e9497fb218870927d645Thomas Petazzoni/* Make sure we select a voltage that suits the needs of all
16405fda3b1abc23d832144e9497fb218870927d645Thomas Petazzoni * regulator consumers
16505fda3b1abc23d832144e9497fb218870927d645Thomas Petazzoni */
16605fda3b1abc23d832144e9497fb218870927d645Thomas Petazzonistatic int regulator_check_consumers(struct regulator_dev *rdev,
16705fda3b1abc23d832144e9497fb218870927d645Thomas Petazzoni				     int *min_uV, int *max_uV)
16805fda3b1abc23d832144e9497fb218870927d645Thomas Petazzoni{
16905fda3b1abc23d832144e9497fb218870927d645Thomas Petazzoni	struct regulator *regulator;
17005fda3b1abc23d832144e9497fb218870927d645Thomas Petazzoni
17105fda3b1abc23d832144e9497fb218870927d645Thomas Petazzoni	list_for_each_entry(regulator, &rdev->consumer_list, list) {
1724aa922c024b2a194d7b68b22a66dfcf86e7838b3Mark Brown		/*
1734aa922c024b2a194d7b68b22a66dfcf86e7838b3Mark Brown		 * Assume consumers that didn't say anything are OK
1744aa922c024b2a194d7b68b22a66dfcf86e7838b3Mark Brown		 * with anything in the constraint range.
1754aa922c024b2a194d7b68b22a66dfcf86e7838b3Mark Brown		 */
1764aa922c024b2a194d7b68b22a66dfcf86e7838b3Mark Brown		if (!regulator->min_uV && !regulator->max_uV)
1774aa922c024b2a194d7b68b22a66dfcf86e7838b3Mark Brown			continue;
1784aa922c024b2a194d7b68b22a66dfcf86e7838b3Mark Brown
17905fda3b1abc23d832144e9497fb218870927d645Thomas Petazzoni		if (*max_uV > regulator->max_uV)
18005fda3b1abc23d832144e9497fb218870927d645Thomas Petazzoni			*max_uV = regulator->max_uV;
18105fda3b1abc23d832144e9497fb218870927d645Thomas Petazzoni		if (*min_uV < regulator->min_uV)
18205fda3b1abc23d832144e9497fb218870927d645Thomas Petazzoni			*min_uV = regulator->min_uV;
18305fda3b1abc23d832144e9497fb218870927d645Thomas Petazzoni	}
18405fda3b1abc23d832144e9497fb218870927d645Thomas Petazzoni
18505fda3b1abc23d832144e9497fb218870927d645Thomas Petazzoni	if (*min_uV > *max_uV)
18605fda3b1abc23d832144e9497fb218870927d645Thomas Petazzoni		return -EINVAL;
18705fda3b1abc23d832144e9497fb218870927d645Thomas Petazzoni
18805fda3b1abc23d832144e9497fb218870927d645Thomas Petazzoni	return 0;
18905fda3b1abc23d832144e9497fb218870927d645Thomas Petazzoni}
19005fda3b1abc23d832144e9497fb218870927d645Thomas Petazzoni
191414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/* current constraint check */
192414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic int regulator_check_current_limit(struct regulator_dev *rdev,
193414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood					int *min_uA, int *max_uA)
194414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
195414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	BUG_ON(*min_uA > *max_uA);
196414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
197414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->constraints) {
1985da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches		rdev_err(rdev, "no constraints\n");
199414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -ENODEV;
200414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
201414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_CURRENT)) {
2025da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches		rdev_err(rdev, "operation not allowed\n");
203414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -EPERM;
204414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
205414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
206414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (*max_uA > rdev->constraints->max_uA)
207414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		*max_uA = rdev->constraints->max_uA;
208414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (*min_uA < rdev->constraints->min_uA)
209414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		*min_uA = rdev->constraints->min_uA;
210414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
21189f425ed5bf3d4fd97e840296dccd75b8e0fe4c9Mark Brown	if (*min_uA > *max_uA) {
21289f425ed5bf3d4fd97e840296dccd75b8e0fe4c9Mark Brown		rdev_err(rdev, "unsupportable current range: %d-%duA\n",
21389f425ed5bf3d4fd97e840296dccd75b8e0fe4c9Mark Brown			 min_uA, max_uA);
214414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -EINVAL;
21589f425ed5bf3d4fd97e840296dccd75b8e0fe4c9Mark Brown	}
216414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
217414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return 0;
218414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
219414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
220414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/* operating mode constraint check */
2212c6082341d1896218ca974cc2bb6876e36fcba5cMark Brownstatic int regulator_mode_constrain(struct regulator_dev *rdev, int *mode)
222414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
2232c6082341d1896218ca974cc2bb6876e36fcba5cMark Brown	switch (*mode) {
224e573520b171095c106ffbbbf4f9cbed6d9bff576David Brownell	case REGULATOR_MODE_FAST:
225e573520b171095c106ffbbbf4f9cbed6d9bff576David Brownell	case REGULATOR_MODE_NORMAL:
226e573520b171095c106ffbbbf4f9cbed6d9bff576David Brownell	case REGULATOR_MODE_IDLE:
227e573520b171095c106ffbbbf4f9cbed6d9bff576David Brownell	case REGULATOR_MODE_STANDBY:
228e573520b171095c106ffbbbf4f9cbed6d9bff576David Brownell		break;
229e573520b171095c106ffbbbf4f9cbed6d9bff576David Brownell	default:
23089f425ed5bf3d4fd97e840296dccd75b8e0fe4c9Mark Brown		rdev_err(rdev, "invalid mode %x specified\n", *mode);
231e573520b171095c106ffbbbf4f9cbed6d9bff576David Brownell		return -EINVAL;
232e573520b171095c106ffbbbf4f9cbed6d9bff576David Brownell	}
233e573520b171095c106ffbbbf4f9cbed6d9bff576David Brownell
234414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->constraints) {
2355da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches		rdev_err(rdev, "no constraints\n");
236414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -ENODEV;
237414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
238414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_MODE)) {
2395da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches		rdev_err(rdev, "operation not allowed\n");
240414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -EPERM;
241414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
2422c6082341d1896218ca974cc2bb6876e36fcba5cMark Brown
2432c6082341d1896218ca974cc2bb6876e36fcba5cMark Brown	/* The modes are bitmasks, the most power hungry modes having
2442c6082341d1896218ca974cc2bb6876e36fcba5cMark Brown	 * the lowest values. If the requested mode isn't supported
2452c6082341d1896218ca974cc2bb6876e36fcba5cMark Brown	 * try higher modes. */
2462c6082341d1896218ca974cc2bb6876e36fcba5cMark Brown	while (*mode) {
2472c6082341d1896218ca974cc2bb6876e36fcba5cMark Brown		if (rdev->constraints->valid_modes_mask & *mode)
2482c6082341d1896218ca974cc2bb6876e36fcba5cMark Brown			return 0;
2492c6082341d1896218ca974cc2bb6876e36fcba5cMark Brown		*mode /= 2;
250414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
2512c6082341d1896218ca974cc2bb6876e36fcba5cMark Brown
2522c6082341d1896218ca974cc2bb6876e36fcba5cMark Brown	return -EINVAL;
253414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
254414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
255414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/* dynamic regulator mode switching constraint check */
256414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic int regulator_check_drms(struct regulator_dev *rdev)
257414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
258414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->constraints) {
2595da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches		rdev_err(rdev, "no constraints\n");
260414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -ENODEV;
261414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
262414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS)) {
2635da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches		rdev_err(rdev, "operation not allowed\n");
264414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -EPERM;
265414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
266414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return 0;
267414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
268414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
269414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t device_requested_uA_show(struct device *dev,
270414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			     struct device_attribute *attr, char *buf)
271414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
272414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator *regulator;
273414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
274414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	regulator = get_device_regulator(dev);
275414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (regulator == NULL)
276414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return 0;
277414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
278414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return sprintf(buf, "%d\n", regulator->uA_load);
279414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
280414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
281414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_uV_show(struct device *dev,
282414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				struct device_attribute *attr, char *buf)
283414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
284a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
285414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ssize_t ret;
286414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
287414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&rdev->mutex);
288414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ret = sprintf(buf, "%d\n", _regulator_get_voltage(rdev));
289414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&rdev->mutex);
290414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
291414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
292414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
2937ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownellstatic DEVICE_ATTR(microvolts, 0444, regulator_uV_show, NULL);
294414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
295414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_uA_show(struct device *dev,
296414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				struct device_attribute *attr, char *buf)
297414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
298a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
299414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
300414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return sprintf(buf, "%d\n", _regulator_get_current_limit(rdev));
301414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
3027ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownellstatic DEVICE_ATTR(microamps, 0444, regulator_uA_show, NULL);
303414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
304bc558a60b58f638ee0188affb627d4894a97b1c7Mark Brownstatic ssize_t regulator_name_show(struct device *dev,
305bc558a60b58f638ee0188affb627d4894a97b1c7Mark Brown			     struct device_attribute *attr, char *buf)
306bc558a60b58f638ee0188affb627d4894a97b1c7Mark Brown{
307bc558a60b58f638ee0188affb627d4894a97b1c7Mark Brown	struct regulator_dev *rdev = dev_get_drvdata(dev);
308bc558a60b58f638ee0188affb627d4894a97b1c7Mark Brown
3091083c39346d482b9001944d05c09191027892226Mark Brown	return sprintf(buf, "%s\n", rdev_get_name(rdev));
310bc558a60b58f638ee0188affb627d4894a97b1c7Mark Brown}
311bc558a60b58f638ee0188affb627d4894a97b1c7Mark Brown
3124fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownellstatic ssize_t regulator_print_opmode(char *buf, int mode)
313414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
314414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	switch (mode) {
315414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	case REGULATOR_MODE_FAST:
316414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "fast\n");
317414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	case REGULATOR_MODE_NORMAL:
318414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "normal\n");
319414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	case REGULATOR_MODE_IDLE:
320414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "idle\n");
321414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	case REGULATOR_MODE_STANDBY:
322414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "standby\n");
323414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
324414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return sprintf(buf, "unknown\n");
325414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
326414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
3274fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownellstatic ssize_t regulator_opmode_show(struct device *dev,
3284fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell				    struct device_attribute *attr, char *buf)
329414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
330a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
331414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
3324fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell	return regulator_print_opmode(buf, _regulator_get_mode(rdev));
3334fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell}
3347ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownellstatic DEVICE_ATTR(opmode, 0444, regulator_opmode_show, NULL);
3354fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell
3364fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownellstatic ssize_t regulator_print_state(char *buf, int state)
3374fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell{
338414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (state > 0)
339414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "enabled\n");
340414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	else if (state == 0)
341414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "disabled\n");
342414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	else
343414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "unknown\n");
344414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
345414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
3464fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownellstatic ssize_t regulator_state_show(struct device *dev,
3474fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell				   struct device_attribute *attr, char *buf)
3484fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell{
3494fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell	struct regulator_dev *rdev = dev_get_drvdata(dev);
3509332546fe88fa88bf6a7d9b1dce53ff5d314934eMark Brown	ssize_t ret;
3519332546fe88fa88bf6a7d9b1dce53ff5d314934eMark Brown
3529332546fe88fa88bf6a7d9b1dce53ff5d314934eMark Brown	mutex_lock(&rdev->mutex);
3539332546fe88fa88bf6a7d9b1dce53ff5d314934eMark Brown	ret = regulator_print_state(buf, _regulator_is_enabled(rdev));
3549332546fe88fa88bf6a7d9b1dce53ff5d314934eMark Brown	mutex_unlock(&rdev->mutex);
3554fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell
3569332546fe88fa88bf6a7d9b1dce53ff5d314934eMark Brown	return ret;
3574fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell}
3587ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownellstatic DEVICE_ATTR(state, 0444, regulator_state_show, NULL);
3594fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell
360853116a10544206b6b2cf42ebc9d78fba2668888David Brownellstatic ssize_t regulator_status_show(struct device *dev,
361853116a10544206b6b2cf42ebc9d78fba2668888David Brownell				   struct device_attribute *attr, char *buf)
362853116a10544206b6b2cf42ebc9d78fba2668888David Brownell{
363853116a10544206b6b2cf42ebc9d78fba2668888David Brownell	struct regulator_dev *rdev = dev_get_drvdata(dev);
364853116a10544206b6b2cf42ebc9d78fba2668888David Brownell	int status;
365853116a10544206b6b2cf42ebc9d78fba2668888David Brownell	char *label;
366853116a10544206b6b2cf42ebc9d78fba2668888David Brownell
367853116a10544206b6b2cf42ebc9d78fba2668888David Brownell	status = rdev->desc->ops->get_status(rdev);
368853116a10544206b6b2cf42ebc9d78fba2668888David Brownell	if (status < 0)
369853116a10544206b6b2cf42ebc9d78fba2668888David Brownell		return status;
370853116a10544206b6b2cf42ebc9d78fba2668888David Brownell
371853116a10544206b6b2cf42ebc9d78fba2668888David Brownell	switch (status) {
372853116a10544206b6b2cf42ebc9d78fba2668888David Brownell	case REGULATOR_STATUS_OFF:
373853116a10544206b6b2cf42ebc9d78fba2668888David Brownell		label = "off";
374853116a10544206b6b2cf42ebc9d78fba2668888David Brownell		break;
375853116a10544206b6b2cf42ebc9d78fba2668888David Brownell	case REGULATOR_STATUS_ON:
376853116a10544206b6b2cf42ebc9d78fba2668888David Brownell		label = "on";
377853116a10544206b6b2cf42ebc9d78fba2668888David Brownell		break;
378853116a10544206b6b2cf42ebc9d78fba2668888David Brownell	case REGULATOR_STATUS_ERROR:
379853116a10544206b6b2cf42ebc9d78fba2668888David Brownell		label = "error";
380853116a10544206b6b2cf42ebc9d78fba2668888David Brownell		break;
381853116a10544206b6b2cf42ebc9d78fba2668888David Brownell	case REGULATOR_STATUS_FAST:
382853116a10544206b6b2cf42ebc9d78fba2668888David Brownell		label = "fast";
383853116a10544206b6b2cf42ebc9d78fba2668888David Brownell		break;
384853116a10544206b6b2cf42ebc9d78fba2668888David Brownell	case REGULATOR_STATUS_NORMAL:
385853116a10544206b6b2cf42ebc9d78fba2668888David Brownell		label = "normal";
386853116a10544206b6b2cf42ebc9d78fba2668888David Brownell		break;
387853116a10544206b6b2cf42ebc9d78fba2668888David Brownell	case REGULATOR_STATUS_IDLE:
388853116a10544206b6b2cf42ebc9d78fba2668888David Brownell		label = "idle";
389853116a10544206b6b2cf42ebc9d78fba2668888David Brownell		break;
390853116a10544206b6b2cf42ebc9d78fba2668888David Brownell	case REGULATOR_STATUS_STANDBY:
391853116a10544206b6b2cf42ebc9d78fba2668888David Brownell		label = "standby";
392853116a10544206b6b2cf42ebc9d78fba2668888David Brownell		break;
393853116a10544206b6b2cf42ebc9d78fba2668888David Brownell	default:
394853116a10544206b6b2cf42ebc9d78fba2668888David Brownell		return -ERANGE;
395853116a10544206b6b2cf42ebc9d78fba2668888David Brownell	}
396853116a10544206b6b2cf42ebc9d78fba2668888David Brownell
397853116a10544206b6b2cf42ebc9d78fba2668888David Brownell	return sprintf(buf, "%s\n", label);
398853116a10544206b6b2cf42ebc9d78fba2668888David Brownell}
399853116a10544206b6b2cf42ebc9d78fba2668888David Brownellstatic DEVICE_ATTR(status, 0444, regulator_status_show, NULL);
400853116a10544206b6b2cf42ebc9d78fba2668888David Brownell
401414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_min_uA_show(struct device *dev,
402414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				    struct device_attribute *attr, char *buf)
403414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
404a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
405414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
406414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->constraints)
407414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "constraint not defined\n");
408414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
409414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return sprintf(buf, "%d\n", rdev->constraints->min_uA);
410414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
4117ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownellstatic DEVICE_ATTR(min_microamps, 0444, regulator_min_uA_show, NULL);
412414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
413414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_max_uA_show(struct device *dev,
414414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				    struct device_attribute *attr, char *buf)
415414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
416a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
417414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
418414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->constraints)
419414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "constraint not defined\n");
420414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
421414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return sprintf(buf, "%d\n", rdev->constraints->max_uA);
422414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
4237ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownellstatic DEVICE_ATTR(max_microamps, 0444, regulator_max_uA_show, NULL);
424414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
425414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_min_uV_show(struct device *dev,
426414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				    struct device_attribute *attr, char *buf)
427414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
428a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
429414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
430414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->constraints)
431414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "constraint not defined\n");
432414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
433414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return sprintf(buf, "%d\n", rdev->constraints->min_uV);
434414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
4357ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownellstatic DEVICE_ATTR(min_microvolts, 0444, regulator_min_uV_show, NULL);
436414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
437414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_max_uV_show(struct device *dev,
438414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				    struct device_attribute *attr, char *buf)
439414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
440a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
441414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
442414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->constraints)
443414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "constraint not defined\n");
444414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
445414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return sprintf(buf, "%d\n", rdev->constraints->max_uV);
446414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
4477ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownellstatic DEVICE_ATTR(max_microvolts, 0444, regulator_max_uV_show, NULL);
448414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
449414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_total_uA_show(struct device *dev,
450414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				      struct device_attribute *attr, char *buf)
451414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
452a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
453414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator *regulator;
454414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int uA = 0;
455414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
456414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&rdev->mutex);
457414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	list_for_each_entry(regulator, &rdev->consumer_list, list)
458fa2984d4691c96367d6666694ecc6744135174c6Stefan Roese		uA += regulator->uA_load;
459414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&rdev->mutex);
460414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return sprintf(buf, "%d\n", uA);
461414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
4627ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownellstatic DEVICE_ATTR(requested_microamps, 0444, regulator_total_uA_show, NULL);
463414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
464414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_num_users_show(struct device *dev,
465414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				      struct device_attribute *attr, char *buf)
466414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
467a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
468414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return sprintf(buf, "%d\n", rdev->use_count);
469414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
470414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
471414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_type_show(struct device *dev,
472414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				  struct device_attribute *attr, char *buf)
473414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
474a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
475414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
476414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	switch (rdev->desc->type) {
477414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	case REGULATOR_VOLTAGE:
478414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "voltage\n");
479414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	case REGULATOR_CURRENT:
480414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "current\n");
481414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
482414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return sprintf(buf, "unknown\n");
483414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
484414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
485414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_suspend_mem_uV_show(struct device *dev,
486414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				struct device_attribute *attr, char *buf)
487414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
488a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
489414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
490414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return sprintf(buf, "%d\n", rdev->constraints->state_mem.uV);
491414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
4927ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownellstatic DEVICE_ATTR(suspend_mem_microvolts, 0444,
4937ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		regulator_suspend_mem_uV_show, NULL);
494414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
495414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_suspend_disk_uV_show(struct device *dev,
496414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				struct device_attribute *attr, char *buf)
497414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
498a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
499414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
500414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return sprintf(buf, "%d\n", rdev->constraints->state_disk.uV);
501414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
5027ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownellstatic DEVICE_ATTR(suspend_disk_microvolts, 0444,
5037ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		regulator_suspend_disk_uV_show, NULL);
504414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
505414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_suspend_standby_uV_show(struct device *dev,
506414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				struct device_attribute *attr, char *buf)
507414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
508a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
509414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
510414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return sprintf(buf, "%d\n", rdev->constraints->state_standby.uV);
511414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
5127ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownellstatic DEVICE_ATTR(suspend_standby_microvolts, 0444,
5137ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		regulator_suspend_standby_uV_show, NULL);
514414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
515414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_suspend_mem_mode_show(struct device *dev,
516414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				struct device_attribute *attr, char *buf)
517414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
518a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
519414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
5204fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell	return regulator_print_opmode(buf,
5214fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell		rdev->constraints->state_mem.mode);
522414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
5237ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownellstatic DEVICE_ATTR(suspend_mem_mode, 0444,
5247ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		regulator_suspend_mem_mode_show, NULL);
525414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
526414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_suspend_disk_mode_show(struct device *dev,
527414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				struct device_attribute *attr, char *buf)
528414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
529a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
530414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
5314fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell	return regulator_print_opmode(buf,
5324fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell		rdev->constraints->state_disk.mode);
533414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
5347ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownellstatic DEVICE_ATTR(suspend_disk_mode, 0444,
5357ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		regulator_suspend_disk_mode_show, NULL);
536414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
537414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_suspend_standby_mode_show(struct device *dev,
538414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				struct device_attribute *attr, char *buf)
539414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
540a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
541414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
5424fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell	return regulator_print_opmode(buf,
5434fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell		rdev->constraints->state_standby.mode);
544414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
5457ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownellstatic DEVICE_ATTR(suspend_standby_mode, 0444,
5467ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		regulator_suspend_standby_mode_show, NULL);
547414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
548414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_suspend_mem_state_show(struct device *dev,
549414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				   struct device_attribute *attr, char *buf)
550414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
551a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
552414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
5534fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell	return regulator_print_state(buf,
5544fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell			rdev->constraints->state_mem.enabled);
555414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
5567ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownellstatic DEVICE_ATTR(suspend_mem_state, 0444,
5577ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		regulator_suspend_mem_state_show, NULL);
558414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
559414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_suspend_disk_state_show(struct device *dev,
560414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				   struct device_attribute *attr, char *buf)
561414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
562a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
563414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
5644fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell	return regulator_print_state(buf,
5654fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell			rdev->constraints->state_disk.enabled);
566414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
5677ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownellstatic DEVICE_ATTR(suspend_disk_state, 0444,
5687ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		regulator_suspend_disk_state_show, NULL);
569414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
570414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_suspend_standby_state_show(struct device *dev,
571414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				   struct device_attribute *attr, char *buf)
572414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
573a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
574414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
5754fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell	return regulator_print_state(buf,
5764fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell			rdev->constraints->state_standby.enabled);
577414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
5787ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownellstatic DEVICE_ATTR(suspend_standby_state, 0444,
5797ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		regulator_suspend_standby_state_show, NULL);
5807ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell
581bc558a60b58f638ee0188affb627d4894a97b1c7Mark Brown
5827ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell/*
5837ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell * These are the only attributes are present for all regulators.
5847ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell * Other attributes are a function of regulator functionality.
5857ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell */
586414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic struct device_attribute regulator_dev_attrs[] = {
587bc558a60b58f638ee0188affb627d4894a97b1c7Mark Brown	__ATTR(name, 0444, regulator_name_show, NULL),
588414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	__ATTR(num_users, 0444, regulator_num_users_show, NULL),
589414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	__ATTR(type, 0444, regulator_type_show, NULL),
590414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	__ATTR_NULL,
591414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood};
592414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
593414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic void regulator_dev_release(struct device *dev)
594414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
595a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
596414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	kfree(rdev);
597414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
598414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
599414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic struct class regulator_class = {
600414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	.name = "regulator",
601414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	.dev_release = regulator_dev_release,
602414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	.dev_attrs = regulator_dev_attrs,
603414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood};
604414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
605414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/* Calculate the new optimum regulator operating mode based on the new total
606414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * consumer load. All locks held by caller */
607414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic void drms_uA_update(struct regulator_dev *rdev)
608414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
609414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator *sibling;
610414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int current_uA = 0, output_uV, input_uV, err;
611414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	unsigned int mode;
612414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
613414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	err = regulator_check_drms(rdev);
614414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (err < 0 || !rdev->desc->ops->get_optimum_mode ||
615476c2d83c7ffb2429b2a504fbdb4326fc8a9d0e8Mark Brown	    (!rdev->desc->ops->get_voltage &&
616476c2d83c7ffb2429b2a504fbdb4326fc8a9d0e8Mark Brown	     !rdev->desc->ops->get_voltage_sel) ||
617476c2d83c7ffb2429b2a504fbdb4326fc8a9d0e8Mark Brown	    !rdev->desc->ops->set_mode)
618036de8efae4b81f8e1504fab654070cecce6dfa9Dan Carpenter		return;
619414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
620414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* get output voltage */
6211bf5a1f86a328122714680cd59951074b4f31e07Mark Brown	output_uV = _regulator_get_voltage(rdev);
622414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (output_uV <= 0)
623414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return;
624414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
625414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* get input voltage */
6261bf5a1f86a328122714680cd59951074b4f31e07Mark Brown	input_uV = 0;
6271bf5a1f86a328122714680cd59951074b4f31e07Mark Brown	if (rdev->supply)
6281bf5a1f86a328122714680cd59951074b4f31e07Mark Brown		input_uV = _regulator_get_voltage(rdev);
6291bf5a1f86a328122714680cd59951074b4f31e07Mark Brown	if (input_uV <= 0)
630414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		input_uV = rdev->constraints->input_uV;
631414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (input_uV <= 0)
632414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return;
633414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
634414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* calc total requested load */
635414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	list_for_each_entry(sibling, &rdev->consumer_list, list)
636fa2984d4691c96367d6666694ecc6744135174c6Stefan Roese		current_uA += sibling->uA_load;
637414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
638414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* now get the optimum mode for our new total regulator load */
639414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mode = rdev->desc->ops->get_optimum_mode(rdev, input_uV,
640414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood						  output_uV, current_uA);
641414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
642414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* check the new mode is allowed */
6432c6082341d1896218ca974cc2bb6876e36fcba5cMark Brown	err = regulator_mode_constrain(rdev, &mode);
644414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (err == 0)
645414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		rdev->desc->ops->set_mode(rdev, mode);
646414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
647414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
648414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic int suspend_set_state(struct regulator_dev *rdev,
649414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator_state *rstate)
650414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
651414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret = 0;
652638f85c54f4fed0f8f1fbc23745a8f334112e892Mark Brown	bool can_set_state;
653638f85c54f4fed0f8f1fbc23745a8f334112e892Mark Brown
654638f85c54f4fed0f8f1fbc23745a8f334112e892Mark Brown	can_set_state = rdev->desc->ops->set_suspend_enable &&
655638f85c54f4fed0f8f1fbc23745a8f334112e892Mark Brown		rdev->desc->ops->set_suspend_disable;
656638f85c54f4fed0f8f1fbc23745a8f334112e892Mark Brown
657638f85c54f4fed0f8f1fbc23745a8f334112e892Mark Brown	/* If we have no suspend mode configration don't set anything;
658638f85c54f4fed0f8f1fbc23745a8f334112e892Mark Brown	 * only warn if the driver actually makes the suspend mode
659638f85c54f4fed0f8f1fbc23745a8f334112e892Mark Brown	 * configurable.
660638f85c54f4fed0f8f1fbc23745a8f334112e892Mark Brown	 */
661638f85c54f4fed0f8f1fbc23745a8f334112e892Mark Brown	if (!rstate->enabled && !rstate->disabled) {
662638f85c54f4fed0f8f1fbc23745a8f334112e892Mark Brown		if (can_set_state)
6635da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches			rdev_warn(rdev, "No configuration\n");
664638f85c54f4fed0f8f1fbc23745a8f334112e892Mark Brown		return 0;
665638f85c54f4fed0f8f1fbc23745a8f334112e892Mark Brown	}
666638f85c54f4fed0f8f1fbc23745a8f334112e892Mark Brown
667638f85c54f4fed0f8f1fbc23745a8f334112e892Mark Brown	if (rstate->enabled && rstate->disabled) {
6685da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches		rdev_err(rdev, "invalid configuration\n");
669638f85c54f4fed0f8f1fbc23745a8f334112e892Mark Brown		return -EINVAL;
670638f85c54f4fed0f8f1fbc23745a8f334112e892Mark Brown	}
671414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
672638f85c54f4fed0f8f1fbc23745a8f334112e892Mark Brown	if (!can_set_state) {
6735da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches		rdev_err(rdev, "no way to set suspend state\n");
674414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -EINVAL;
675a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	}
676414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
677414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (rstate->enabled)
678414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		ret = rdev->desc->ops->set_suspend_enable(rdev);
679414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	else
680414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		ret = rdev->desc->ops->set_suspend_disable(rdev);
681414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (ret < 0) {
6825da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches		rdev_err(rdev, "failed to enabled/disable\n");
683414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return ret;
684414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
685414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
686414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (rdev->desc->ops->set_suspend_voltage && rstate->uV > 0) {
687414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		ret = rdev->desc->ops->set_suspend_voltage(rdev, rstate->uV);
688414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (ret < 0) {
6895da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches			rdev_err(rdev, "failed to set voltage\n");
690414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			return ret;
691414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		}
692414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
693414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
694414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (rdev->desc->ops->set_suspend_mode && rstate->mode > 0) {
695414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		ret = rdev->desc->ops->set_suspend_mode(rdev, rstate->mode);
696414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (ret < 0) {
6975da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches			rdev_err(rdev, "failed to set mode\n");
698414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			return ret;
699414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		}
700414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
701414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
702414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
703414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
704414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/* locks held by caller */
705414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic int suspend_prepare(struct regulator_dev *rdev, suspend_state_t state)
706414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
707414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->constraints)
708414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -EINVAL;
709414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
710414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	switch (state) {
711414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	case PM_SUSPEND_STANDBY:
712414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return suspend_set_state(rdev,
713414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			&rdev->constraints->state_standby);
714414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	case PM_SUSPEND_MEM:
715414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return suspend_set_state(rdev,
716414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			&rdev->constraints->state_mem);
717414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	case PM_SUSPEND_MAX:
718414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return suspend_set_state(rdev,
719414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			&rdev->constraints->state_disk);
720414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	default:
721414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -EINVAL;
722414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
723414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
724414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
725414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic void print_constraints(struct regulator_dev *rdev)
726414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
727414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulation_constraints *constraints = rdev->constraints;
728973e9a2795b3b41d8408a0bb6f87b783c5efc88aMark Brown	char buf[80] = "";
7298f031b48cd2eab5fc3e4dffa06706372e90d63feMark Brown	int count = 0;
7308f031b48cd2eab5fc3e4dffa06706372e90d63feMark Brown	int ret;
731414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
7328f031b48cd2eab5fc3e4dffa06706372e90d63feMark Brown	if (constraints->min_uV && constraints->max_uV) {
733414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (constraints->min_uV == constraints->max_uV)
7348f031b48cd2eab5fc3e4dffa06706372e90d63feMark Brown			count += sprintf(buf + count, "%d mV ",
7358f031b48cd2eab5fc3e4dffa06706372e90d63feMark Brown					 constraints->min_uV / 1000);
736414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		else
7378f031b48cd2eab5fc3e4dffa06706372e90d63feMark Brown			count += sprintf(buf + count, "%d <--> %d mV ",
7388f031b48cd2eab5fc3e4dffa06706372e90d63feMark Brown					 constraints->min_uV / 1000,
7398f031b48cd2eab5fc3e4dffa06706372e90d63feMark Brown					 constraints->max_uV / 1000);
7408f031b48cd2eab5fc3e4dffa06706372e90d63feMark Brown	}
7418f031b48cd2eab5fc3e4dffa06706372e90d63feMark Brown
7428f031b48cd2eab5fc3e4dffa06706372e90d63feMark Brown	if (!constraints->min_uV ||
7438f031b48cd2eab5fc3e4dffa06706372e90d63feMark Brown	    constraints->min_uV != constraints->max_uV) {
7448f031b48cd2eab5fc3e4dffa06706372e90d63feMark Brown		ret = _regulator_get_voltage(rdev);
7458f031b48cd2eab5fc3e4dffa06706372e90d63feMark Brown		if (ret > 0)
7468f031b48cd2eab5fc3e4dffa06706372e90d63feMark Brown			count += sprintf(buf + count, "at %d mV ", ret / 1000);
7478f031b48cd2eab5fc3e4dffa06706372e90d63feMark Brown	}
7488f031b48cd2eab5fc3e4dffa06706372e90d63feMark Brown
749bf5892a8167e4aa5a9a6d72f803fde850e0c5753Mark Brown	if (constraints->uV_offset)
750bf5892a8167e4aa5a9a6d72f803fde850e0c5753Mark Brown		count += sprintf(buf, "%dmV offset ",
751bf5892a8167e4aa5a9a6d72f803fde850e0c5753Mark Brown				 constraints->uV_offset / 1000);
752bf5892a8167e4aa5a9a6d72f803fde850e0c5753Mark Brown
7538f031b48cd2eab5fc3e4dffa06706372e90d63feMark Brown	if (constraints->min_uA && constraints->max_uA) {
754414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (constraints->min_uA == constraints->max_uA)
7558f031b48cd2eab5fc3e4dffa06706372e90d63feMark Brown			count += sprintf(buf + count, "%d mA ",
7568f031b48cd2eab5fc3e4dffa06706372e90d63feMark Brown					 constraints->min_uA / 1000);
757414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		else
7588f031b48cd2eab5fc3e4dffa06706372e90d63feMark Brown			count += sprintf(buf + count, "%d <--> %d mA ",
7598f031b48cd2eab5fc3e4dffa06706372e90d63feMark Brown					 constraints->min_uA / 1000,
7608f031b48cd2eab5fc3e4dffa06706372e90d63feMark Brown					 constraints->max_uA / 1000);
7618f031b48cd2eab5fc3e4dffa06706372e90d63feMark Brown	}
7628f031b48cd2eab5fc3e4dffa06706372e90d63feMark Brown
7638f031b48cd2eab5fc3e4dffa06706372e90d63feMark Brown	if (!constraints->min_uA ||
7648f031b48cd2eab5fc3e4dffa06706372e90d63feMark Brown	    constraints->min_uA != constraints->max_uA) {
7658f031b48cd2eab5fc3e4dffa06706372e90d63feMark Brown		ret = _regulator_get_current_limit(rdev);
7668f031b48cd2eab5fc3e4dffa06706372e90d63feMark Brown		if (ret > 0)
767e4a6376b3b2999d169b602a582a8819d95ff79bcCyril Chemparathy			count += sprintf(buf + count, "at %d mA ", ret / 1000);
768414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
7698f031b48cd2eab5fc3e4dffa06706372e90d63feMark Brown
770414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (constraints->valid_modes_mask & REGULATOR_MODE_FAST)
771414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		count += sprintf(buf + count, "fast ");
772414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (constraints->valid_modes_mask & REGULATOR_MODE_NORMAL)
773414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		count += sprintf(buf + count, "normal ");
774414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (constraints->valid_modes_mask & REGULATOR_MODE_IDLE)
775414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		count += sprintf(buf + count, "idle ");
776414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (constraints->valid_modes_mask & REGULATOR_MODE_STANDBY)
777414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		count += sprintf(buf + count, "standby");
778414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
77913ce29f80fe3f61d3865b90244b1d1430f553e9fMark Brown	rdev_info(rdev, "%s\n", buf);
780414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
781414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
782e79055d62ea6ca3c36962209f4c819614972c95aMark Brownstatic int machine_constraints_voltage(struct regulator_dev *rdev,
7831083c39346d482b9001944d05c09191027892226Mark Brown	struct regulation_constraints *constraints)
784a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood{
785e5fda26c7ea9430d7d953364f900bafdce2be67bMark Brown	struct regulator_ops *ops = rdev->desc->ops;
786af5866c9cdc9e43ef775a14765fd8eab95c7fd20Mark Brown	int ret;
787af5866c9cdc9e43ef775a14765fd8eab95c7fd20Mark Brown
788af5866c9cdc9e43ef775a14765fd8eab95c7fd20Mark Brown	/* do we need to apply the constraint voltage */
789af5866c9cdc9e43ef775a14765fd8eab95c7fd20Mark Brown	if (rdev->constraints->apply_uV &&
790757902513019e6ee469791ff76f954b19ca8d036Mark Brown	    rdev->constraints->min_uV == rdev->constraints->max_uV) {
791757902513019e6ee469791ff76f954b19ca8d036Mark Brown		ret = _regulator_do_set_voltage(rdev,
792757902513019e6ee469791ff76f954b19ca8d036Mark Brown						rdev->constraints->min_uV,
793757902513019e6ee469791ff76f954b19ca8d036Mark Brown						rdev->constraints->max_uV);
794757902513019e6ee469791ff76f954b19ca8d036Mark Brown		if (ret < 0) {
795757902513019e6ee469791ff76f954b19ca8d036Mark Brown			rdev_err(rdev, "failed to apply %duV constraint\n",
796757902513019e6ee469791ff76f954b19ca8d036Mark Brown				 rdev->constraints->min_uV);
797757902513019e6ee469791ff76f954b19ca8d036Mark Brown			rdev->constraints = NULL;
798757902513019e6ee469791ff76f954b19ca8d036Mark Brown			return ret;
799757902513019e6ee469791ff76f954b19ca8d036Mark Brown		}
800af5866c9cdc9e43ef775a14765fd8eab95c7fd20Mark Brown	}
801e06f5b4fea243b152c79fe5d9552a852069de483Mark Brown
8024367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell	/* constrain machine-level voltage specs to fit
8034367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell	 * the actual range supported by this regulator.
8044367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell	 */
8054367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell	if (ops->list_voltage && rdev->desc->n_voltages) {
8064367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell		int	count = rdev->desc->n_voltages;
8074367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell		int	i;
8084367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell		int	min_uV = INT_MAX;
8094367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell		int	max_uV = INT_MIN;
8104367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell		int	cmin = constraints->min_uV;
8114367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell		int	cmax = constraints->max_uV;
8124367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell
8133e59091828ed5406c879b899b4257fcef7271e2cMark Brown		/* it's safe to autoconfigure fixed-voltage supplies
8143e59091828ed5406c879b899b4257fcef7271e2cMark Brown		   and the constraints are used by list_voltage. */
8154367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell		if (count == 1 && !cmin) {
8163e59091828ed5406c879b899b4257fcef7271e2cMark Brown			cmin = 1;
8174367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell			cmax = INT_MAX;
8183e59091828ed5406c879b899b4257fcef7271e2cMark Brown			constraints->min_uV = cmin;
8193e59091828ed5406c879b899b4257fcef7271e2cMark Brown			constraints->max_uV = cmax;
8204367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell		}
8214367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell
8223e2b9abda554e9f6105996dca77cca9ef98de17aMark Brown		/* voltage constraints are optional */
8233e2b9abda554e9f6105996dca77cca9ef98de17aMark Brown		if ((cmin == 0) && (cmax == 0))
824e79055d62ea6ca3c36962209f4c819614972c95aMark Brown			return 0;
8253e2b9abda554e9f6105996dca77cca9ef98de17aMark Brown
8264367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell		/* else require explicit machine-level constraints */
8273e2b9abda554e9f6105996dca77cca9ef98de17aMark Brown		if (cmin <= 0 || cmax <= 0 || cmax < cmin) {
8285da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches			rdev_err(rdev, "invalid voltage constraints\n");
829e79055d62ea6ca3c36962209f4c819614972c95aMark Brown			return -EINVAL;
8304367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell		}
8314367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell
8324367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell		/* initial: [cmin..cmax] valid, [min_uV..max_uV] not */
8334367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell		for (i = 0; i < count; i++) {
8344367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell			int	value;
8354367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell
8364367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell			value = ops->list_voltage(rdev, i);
8374367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell			if (value <= 0)
8384367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell				continue;
8394367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell
8404367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell			/* maybe adjust [min_uV..max_uV] */
8414367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell			if (value >= cmin && value < min_uV)
8424367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell				min_uV = value;
8434367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell			if (value <= cmax && value > max_uV)
8444367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell				max_uV = value;
8454367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell		}
8464367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell
8474367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell		/* final: [min_uV..max_uV] valid iff constraints valid */
8484367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell		if (max_uV < min_uV) {
8495da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches			rdev_err(rdev, "unsupportable voltage constraints\n");
850e79055d62ea6ca3c36962209f4c819614972c95aMark Brown			return -EINVAL;
8514367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell		}
8524367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell
8534367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell		/* use regulator's subset of machine constraints */
8544367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell		if (constraints->min_uV < min_uV) {
8555da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches			rdev_dbg(rdev, "override min_uV, %d -> %d\n",
8565da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches				 constraints->min_uV, min_uV);
8574367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell			constraints->min_uV = min_uV;
8584367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell		}
8594367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell		if (constraints->max_uV > max_uV) {
8605da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches			rdev_dbg(rdev, "override max_uV, %d -> %d\n",
8615da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches				 constraints->max_uV, max_uV);
8624367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell			constraints->max_uV = max_uV;
8634367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell		}
8644367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell	}
8654367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell
866e79055d62ea6ca3c36962209f4c819614972c95aMark Brown	return 0;
867e79055d62ea6ca3c36962209f4c819614972c95aMark Brown}
868e79055d62ea6ca3c36962209f4c819614972c95aMark Brown
869e79055d62ea6ca3c36962209f4c819614972c95aMark Brown/**
870e79055d62ea6ca3c36962209f4c819614972c95aMark Brown * set_machine_constraints - sets regulator constraints
871e79055d62ea6ca3c36962209f4c819614972c95aMark Brown * @rdev: regulator source
872e79055d62ea6ca3c36962209f4c819614972c95aMark Brown * @constraints: constraints to apply
873e79055d62ea6ca3c36962209f4c819614972c95aMark Brown *
874e79055d62ea6ca3c36962209f4c819614972c95aMark Brown * Allows platform initialisation code to define and constrain
875e79055d62ea6ca3c36962209f4c819614972c95aMark Brown * regulator circuits e.g. valid voltage/current ranges, etc.  NOTE:
876e79055d62ea6ca3c36962209f4c819614972c95aMark Brown * Constraints *must* be set by platform code in order for some
877e79055d62ea6ca3c36962209f4c819614972c95aMark Brown * regulator operations to proceed i.e. set_voltage, set_current_limit,
878e79055d62ea6ca3c36962209f4c819614972c95aMark Brown * set_mode.
879e79055d62ea6ca3c36962209f4c819614972c95aMark Brown */
880e79055d62ea6ca3c36962209f4c819614972c95aMark Brownstatic int set_machine_constraints(struct regulator_dev *rdev,
881f8c12fe329c8da9f50d8b2b1183eeaa4d587e747Mark Brown	const struct regulation_constraints *constraints)
882e79055d62ea6ca3c36962209f4c819614972c95aMark Brown{
883e79055d62ea6ca3c36962209f4c819614972c95aMark Brown	int ret = 0;
884e79055d62ea6ca3c36962209f4c819614972c95aMark Brown	struct regulator_ops *ops = rdev->desc->ops;
885e79055d62ea6ca3c36962209f4c819614972c95aMark Brown
886f8c12fe329c8da9f50d8b2b1183eeaa4d587e747Mark Brown	rdev->constraints = kmemdup(constraints, sizeof(*constraints),
887f8c12fe329c8da9f50d8b2b1183eeaa4d587e747Mark Brown				    GFP_KERNEL);
888f8c12fe329c8da9f50d8b2b1183eeaa4d587e747Mark Brown	if (!rdev->constraints)
889f8c12fe329c8da9f50d8b2b1183eeaa4d587e747Mark Brown		return -ENOMEM;
890af5866c9cdc9e43ef775a14765fd8eab95c7fd20Mark Brown
891f8c12fe329c8da9f50d8b2b1183eeaa4d587e747Mark Brown	ret = machine_constraints_voltage(rdev, rdev->constraints);
892e79055d62ea6ca3c36962209f4c819614972c95aMark Brown	if (ret != 0)
893e79055d62ea6ca3c36962209f4c819614972c95aMark Brown		goto out;
894e79055d62ea6ca3c36962209f4c819614972c95aMark Brown
895a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	/* do we need to setup our suspend state */
896e06f5b4fea243b152c79fe5d9552a852069de483Mark Brown	if (constraints->initial_state) {
897f8c12fe329c8da9f50d8b2b1183eeaa4d587e747Mark Brown		ret = suspend_prepare(rdev, rdev->constraints->initial_state);
898e06f5b4fea243b152c79fe5d9552a852069de483Mark Brown		if (ret < 0) {
8995da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches			rdev_err(rdev, "failed to set suspend state\n");
900e06f5b4fea243b152c79fe5d9552a852069de483Mark Brown			rdev->constraints = NULL;
901e06f5b4fea243b152c79fe5d9552a852069de483Mark Brown			goto out;
902e06f5b4fea243b152c79fe5d9552a852069de483Mark Brown		}
903e06f5b4fea243b152c79fe5d9552a852069de483Mark Brown	}
904a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
905a308466c24b4f42bab6945026e938874d22cde50Mark Brown	if (constraints->initial_mode) {
906a308466c24b4f42bab6945026e938874d22cde50Mark Brown		if (!ops->set_mode) {
9075da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches			rdev_err(rdev, "no set_mode operation\n");
908a308466c24b4f42bab6945026e938874d22cde50Mark Brown			ret = -EINVAL;
909a308466c24b4f42bab6945026e938874d22cde50Mark Brown			goto out;
910a308466c24b4f42bab6945026e938874d22cde50Mark Brown		}
911a308466c24b4f42bab6945026e938874d22cde50Mark Brown
912f8c12fe329c8da9f50d8b2b1183eeaa4d587e747Mark Brown		ret = ops->set_mode(rdev, rdev->constraints->initial_mode);
913a308466c24b4f42bab6945026e938874d22cde50Mark Brown		if (ret < 0) {
9145da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches			rdev_err(rdev, "failed to set initial mode: %d\n", ret);
915a308466c24b4f42bab6945026e938874d22cde50Mark Brown			goto out;
916a308466c24b4f42bab6945026e938874d22cde50Mark Brown		}
917a308466c24b4f42bab6945026e938874d22cde50Mark Brown	}
918a308466c24b4f42bab6945026e938874d22cde50Mark Brown
919cacf90f24e80cec9334f98e0377149f943fe9f16Mark Brown	/* If the constraints say the regulator should be on at this point
920cacf90f24e80cec9334f98e0377149f943fe9f16Mark Brown	 * and we have control then make sure it is enabled.
921cacf90f24e80cec9334f98e0377149f943fe9f16Mark Brown	 */
922f8c12fe329c8da9f50d8b2b1183eeaa4d587e747Mark Brown	if ((rdev->constraints->always_on || rdev->constraints->boot_on) &&
923f8c12fe329c8da9f50d8b2b1183eeaa4d587e747Mark Brown	    ops->enable) {
924e5fda26c7ea9430d7d953364f900bafdce2be67bMark Brown		ret = ops->enable(rdev);
925e5fda26c7ea9430d7d953364f900bafdce2be67bMark Brown		if (ret < 0) {
9265da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches			rdev_err(rdev, "failed to enable\n");
927e5fda26c7ea9430d7d953364f900bafdce2be67bMark Brown			rdev->constraints = NULL;
928e5fda26c7ea9430d7d953364f900bafdce2be67bMark Brown			goto out;
929e5fda26c7ea9430d7d953364f900bafdce2be67bMark Brown		}
930e5fda26c7ea9430d7d953364f900bafdce2be67bMark Brown	}
931e5fda26c7ea9430d7d953364f900bafdce2be67bMark Brown
932a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	print_constraints(rdev);
933a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwoodout:
934a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	return ret;
935a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood}
936a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
937a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood/**
938a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * set_supply - set regulator supply regulator
93969279fb9a95051971ac03e558c4d46e7ba84ab3aMark Brown * @rdev: regulator name
94069279fb9a95051971ac03e558c4d46e7ba84ab3aMark Brown * @supply_rdev: supply regulator name
941a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood *
942a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * Called by platform initialisation code to set the supply regulator for this
943a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * regulator. This ensures that a regulators supply will also be enabled by the
944a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * core if it's child is enabled.
945a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood */
946a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwoodstatic int set_supply(struct regulator_dev *rdev,
9473801b86aa482d26a8ae460f67fca29e016491a86Mark Brown		      struct regulator_dev *supply_rdev)
948a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood{
949a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	int err;
950a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
9513801b86aa482d26a8ae460f67fca29e016491a86Mark Brown	rdev_info(rdev, "supplied by %s\n", rdev_get_name(supply_rdev));
9523801b86aa482d26a8ae460f67fca29e016491a86Mark Brown
9533801b86aa482d26a8ae460f67fca29e016491a86Mark Brown	rdev->supply = create_regulator(supply_rdev, &rdev->dev, "SUPPLY");
9543801b86aa482d26a8ae460f67fca29e016491a86Mark Brown	if (IS_ERR(rdev->supply)) {
9553801b86aa482d26a8ae460f67fca29e016491a86Mark Brown		err = PTR_ERR(rdev->supply);
9563801b86aa482d26a8ae460f67fca29e016491a86Mark Brown		rdev->supply = NULL;
9573801b86aa482d26a8ae460f67fca29e016491a86Mark Brown		return err;
958a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	}
9593801b86aa482d26a8ae460f67fca29e016491a86Mark Brown
9603801b86aa482d26a8ae460f67fca29e016491a86Mark Brown	return 0;
961a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood}
962a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
963a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood/**
96406c63f9396133f312c5a49c2285c2c8015e80934Randy Dunlap * set_consumer_device_supply - Bind a regulator to a symbolic supply
96569279fb9a95051971ac03e558c4d46e7ba84ab3aMark Brown * @rdev:         regulator source
96669279fb9a95051971ac03e558c4d46e7ba84ab3aMark Brown * @consumer_dev: device the supply applies to
96740f9244f4da8976eeb6d5ed6313c635ba238a9d3Mark Brown * @consumer_dev_name: dev_name() string for device supply applies to
96869279fb9a95051971ac03e558c4d46e7ba84ab3aMark Brown * @supply:       symbolic name for supply
969a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood *
970a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * Allows platform initialisation code to map physical regulator
971a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * sources to symbolic names for supplies for use by devices.  Devices
972a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * should use these symbolic names to request regulators, avoiding the
973a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * need to provide board-specific regulator names as platform data.
97440f9244f4da8976eeb6d5ed6313c635ba238a9d3Mark Brown *
97540f9244f4da8976eeb6d5ed6313c635ba238a9d3Mark Brown * Only one of consumer_dev and consumer_dev_name may be specified.
976a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood */
977a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwoodstatic int set_consumer_device_supply(struct regulator_dev *rdev,
97840f9244f4da8976eeb6d5ed6313c635ba238a9d3Mark Brown	struct device *consumer_dev, const char *consumer_dev_name,
97940f9244f4da8976eeb6d5ed6313c635ba238a9d3Mark Brown	const char *supply)
980a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood{
981a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_map *node;
9829ed2099edca26d07947beb42c12bd1d6669e82bcMark Brown	int has_dev;
983a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
98440f9244f4da8976eeb6d5ed6313c635ba238a9d3Mark Brown	if (consumer_dev && consumer_dev_name)
98540f9244f4da8976eeb6d5ed6313c635ba238a9d3Mark Brown		return -EINVAL;
98640f9244f4da8976eeb6d5ed6313c635ba238a9d3Mark Brown
98740f9244f4da8976eeb6d5ed6313c635ba238a9d3Mark Brown	if (!consumer_dev_name && consumer_dev)
98840f9244f4da8976eeb6d5ed6313c635ba238a9d3Mark Brown		consumer_dev_name = dev_name(consumer_dev);
98940f9244f4da8976eeb6d5ed6313c635ba238a9d3Mark Brown
990a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	if (supply == NULL)
991a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		return -EINVAL;
992a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
9939ed2099edca26d07947beb42c12bd1d6669e82bcMark Brown	if (consumer_dev_name != NULL)
9949ed2099edca26d07947beb42c12bd1d6669e82bcMark Brown		has_dev = 1;
9959ed2099edca26d07947beb42c12bd1d6669e82bcMark Brown	else
9969ed2099edca26d07947beb42c12bd1d6669e82bcMark Brown		has_dev = 0;
9979ed2099edca26d07947beb42c12bd1d6669e82bcMark Brown
9986001e13c5f708eb68c744a69df3c2c281156030dDavid Brownell	list_for_each_entry(node, &regulator_map_list, list) {
99923b5cc2ab6783256cf06779e1d522482b819b808Jani Nikula		if (node->dev_name && consumer_dev_name) {
100023b5cc2ab6783256cf06779e1d522482b819b808Jani Nikula			if (strcmp(node->dev_name, consumer_dev_name) != 0)
100123b5cc2ab6783256cf06779e1d522482b819b808Jani Nikula				continue;
100223b5cc2ab6783256cf06779e1d522482b819b808Jani Nikula		} else if (node->dev_name || consumer_dev_name) {
10036001e13c5f708eb68c744a69df3c2c281156030dDavid Brownell			continue;
100423b5cc2ab6783256cf06779e1d522482b819b808Jani Nikula		}
100523b5cc2ab6783256cf06779e1d522482b819b808Jani Nikula
10066001e13c5f708eb68c744a69df3c2c281156030dDavid Brownell		if (strcmp(node->supply, supply) != 0)
10076001e13c5f708eb68c744a69df3c2c281156030dDavid Brownell			continue;
10086001e13c5f708eb68c744a69df3c2c281156030dDavid Brownell
10096001e13c5f708eb68c744a69df3c2c281156030dDavid Brownell		dev_dbg(consumer_dev, "%s/%s is '%s' supply; fail %s/%s\n",
10105da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches			dev_name(&node->regulator->dev),
10115da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches			node->regulator->desc->name,
10125da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches			supply,
10135da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches			dev_name(&rdev->dev), rdev_get_name(rdev));
10146001e13c5f708eb68c744a69df3c2c281156030dDavid Brownell		return -EBUSY;
10156001e13c5f708eb68c744a69df3c2c281156030dDavid Brownell	}
10166001e13c5f708eb68c744a69df3c2c281156030dDavid Brownell
10179ed2099edca26d07947beb42c12bd1d6669e82bcMark Brown	node = kzalloc(sizeof(struct regulator_map), GFP_KERNEL);
1018a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	if (node == NULL)
1019a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		return -ENOMEM;
1020a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
1021a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	node->regulator = rdev;
1022a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	node->supply = supply;
1023a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
10249ed2099edca26d07947beb42c12bd1d6669e82bcMark Brown	if (has_dev) {
10259ed2099edca26d07947beb42c12bd1d6669e82bcMark Brown		node->dev_name = kstrdup(consumer_dev_name, GFP_KERNEL);
10269ed2099edca26d07947beb42c12bd1d6669e82bcMark Brown		if (node->dev_name == NULL) {
10279ed2099edca26d07947beb42c12bd1d6669e82bcMark Brown			kfree(node);
10289ed2099edca26d07947beb42c12bd1d6669e82bcMark Brown			return -ENOMEM;
10299ed2099edca26d07947beb42c12bd1d6669e82bcMark Brown		}
103040f9244f4da8976eeb6d5ed6313c635ba238a9d3Mark Brown	}
103140f9244f4da8976eeb6d5ed6313c635ba238a9d3Mark Brown
1032a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	list_add(&node->list, &regulator_map_list);
1033a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	return 0;
1034a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood}
1035a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
10360f1d747bfa89de4ca52dc1dffdcce35a2b8a1532Mike Rapoportstatic void unset_regulator_supplies(struct regulator_dev *rdev)
10370f1d747bfa89de4ca52dc1dffdcce35a2b8a1532Mike Rapoport{
10380f1d747bfa89de4ca52dc1dffdcce35a2b8a1532Mike Rapoport	struct regulator_map *node, *n;
10390f1d747bfa89de4ca52dc1dffdcce35a2b8a1532Mike Rapoport
10400f1d747bfa89de4ca52dc1dffdcce35a2b8a1532Mike Rapoport	list_for_each_entry_safe(node, n, &regulator_map_list, list) {
10410f1d747bfa89de4ca52dc1dffdcce35a2b8a1532Mike Rapoport		if (rdev == node->regulator) {
10420f1d747bfa89de4ca52dc1dffdcce35a2b8a1532Mike Rapoport			list_del(&node->list);
104340f9244f4da8976eeb6d5ed6313c635ba238a9d3Mark Brown			kfree(node->dev_name);
10440f1d747bfa89de4ca52dc1dffdcce35a2b8a1532Mike Rapoport			kfree(node);
10450f1d747bfa89de4ca52dc1dffdcce35a2b8a1532Mike Rapoport		}
10460f1d747bfa89de4ca52dc1dffdcce35a2b8a1532Mike Rapoport	}
10470f1d747bfa89de4ca52dc1dffdcce35a2b8a1532Mike Rapoport}
10480f1d747bfa89de4ca52dc1dffdcce35a2b8a1532Mike Rapoport
1049f5726ae33c382366ea1b23240d5620dcf675d81dMark Brown#define REG_STR_SIZE	64
1050414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1051414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic struct regulator *create_regulator(struct regulator_dev *rdev,
1052414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood					  struct device *dev,
1053414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood					  const char *supply_name)
1054414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1055414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator *regulator;
1056414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	char buf[REG_STR_SIZE];
1057414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int err, size;
1058414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1059414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	regulator = kzalloc(sizeof(*regulator), GFP_KERNEL);
1060414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (regulator == NULL)
1061414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return NULL;
1062414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1063414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&rdev->mutex);
1064414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	regulator->rdev = rdev;
1065414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	list_add(&regulator->list, &rdev->consumer_list);
1066414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1067414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (dev) {
1068414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		/* create a 'requested_microamps_name' sysfs entry */
1069e0eaedefda8e14ed3f445f382c568c5d69e4223fMark Brown		size = scnprintf(buf, REG_STR_SIZE,
1070e0eaedefda8e14ed3f445f382c568c5d69e4223fMark Brown				 "microamps_requested_%s-%s",
1071e0eaedefda8e14ed3f445f382c568c5d69e4223fMark Brown				 dev_name(dev), supply_name);
1072414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (size >= REG_STR_SIZE)
1073414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			goto overflow_err;
1074414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1075414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator->dev = dev;
10764f26a2abe1eed18dc6adddf2d0ae5553e51578c2Ameya Palande		sysfs_attr_init(&regulator->dev_attr.attr);
1077414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator->dev_attr.attr.name = kstrdup(buf, GFP_KERNEL);
1078414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (regulator->dev_attr.attr.name == NULL)
1079414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			goto attr_name_err;
1080414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1081414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator->dev_attr.attr.mode = 0444;
1082414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator->dev_attr.show = device_requested_uA_show;
1083414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		err = device_create_file(dev, &regulator->dev_attr);
1084414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (err < 0) {
10855da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches			rdev_warn(rdev, "could not add regulator_dev requested microamps sysfs entry\n");
1086414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			goto attr_name_err;
1087414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		}
1088414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1089414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		/* also add a link to the device sysfs entry */
1090414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		size = scnprintf(buf, REG_STR_SIZE, "%s-%s",
1091414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				 dev->kobj.name, supply_name);
1092414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (size >= REG_STR_SIZE)
1093414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			goto attr_err;
1094414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1095414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator->supply_name = kstrdup(buf, GFP_KERNEL);
1096414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (regulator->supply_name == NULL)
1097414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			goto attr_err;
1098414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1099414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		err = sysfs_create_link(&rdev->dev.kobj, &dev->kobj,
1100414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood					buf);
1101414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (err) {
11025da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches			rdev_warn(rdev, "could not add device link %s err %d\n",
11035da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches				  dev->kobj.name, err);
1104414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			goto link_name_err;
1105414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		}
11065de705194e9883a39f993e2ff96028d5aab99b37Mark Brown	} else {
11075de705194e9883a39f993e2ff96028d5aab99b37Mark Brown		regulator->supply_name = kstrdup(supply_name, GFP_KERNEL);
11085de705194e9883a39f993e2ff96028d5aab99b37Mark Brown		if (regulator->supply_name == NULL)
11095de705194e9883a39f993e2ff96028d5aab99b37Mark Brown			goto attr_err;
11105de705194e9883a39f993e2ff96028d5aab99b37Mark Brown	}
11115de705194e9883a39f993e2ff96028d5aab99b37Mark Brown
11125de705194e9883a39f993e2ff96028d5aab99b37Mark Brown#ifdef CONFIG_DEBUG_FS
11135de705194e9883a39f993e2ff96028d5aab99b37Mark Brown	regulator->debugfs = debugfs_create_dir(regulator->supply_name,
11145de705194e9883a39f993e2ff96028d5aab99b37Mark Brown						rdev->debugfs);
11155de705194e9883a39f993e2ff96028d5aab99b37Mark Brown	if (IS_ERR_OR_NULL(regulator->debugfs)) {
11165de705194e9883a39f993e2ff96028d5aab99b37Mark Brown		rdev_warn(rdev, "Failed to create debugfs directory\n");
11175de705194e9883a39f993e2ff96028d5aab99b37Mark Brown		regulator->debugfs = NULL;
11185de705194e9883a39f993e2ff96028d5aab99b37Mark Brown	} else {
11195de705194e9883a39f993e2ff96028d5aab99b37Mark Brown		debugfs_create_u32("uA_load", 0444, regulator->debugfs,
11205de705194e9883a39f993e2ff96028d5aab99b37Mark Brown				   &regulator->uA_load);
11215de705194e9883a39f993e2ff96028d5aab99b37Mark Brown		debugfs_create_u32("min_uV", 0444, regulator->debugfs,
11225de705194e9883a39f993e2ff96028d5aab99b37Mark Brown				   &regulator->min_uV);
11235de705194e9883a39f993e2ff96028d5aab99b37Mark Brown		debugfs_create_u32("max_uV", 0444, regulator->debugfs,
11245de705194e9883a39f993e2ff96028d5aab99b37Mark Brown				   &regulator->max_uV);
1125414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
11265de705194e9883a39f993e2ff96028d5aab99b37Mark Brown#endif
11275de705194e9883a39f993e2ff96028d5aab99b37Mark Brown
1128414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&rdev->mutex);
1129414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return regulator;
1130414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodlink_name_err:
1131414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	kfree(regulator->supply_name);
1132414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodattr_err:
1133414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	device_remove_file(regulator->dev, &regulator->dev_attr);
1134414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodattr_name_err:
1135414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	kfree(regulator->dev_attr.attr.name);
1136414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodoverflow_err:
1137414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	list_del(&regulator->list);
1138414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	kfree(regulator);
1139414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&rdev->mutex);
1140414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return NULL;
1141414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1142414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
114331aae2beeb3d601d556b6a8c39085940ad1e9f42Mark Brownstatic int _regulator_get_enable_time(struct regulator_dev *rdev)
114431aae2beeb3d601d556b6a8c39085940ad1e9f42Mark Brown{
114531aae2beeb3d601d556b6a8c39085940ad1e9f42Mark Brown	if (!rdev->desc->ops->enable_time)
114631aae2beeb3d601d556b6a8c39085940ad1e9f42Mark Brown		return 0;
114731aae2beeb3d601d556b6a8c39085940ad1e9f42Mark Brown	return rdev->desc->ops->enable_time(rdev);
114831aae2beeb3d601d556b6a8c39085940ad1e9f42Mark Brown}
114931aae2beeb3d601d556b6a8c39085940ad1e9f42Mark Brown
11505ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown/* Internal regulator request function */
11515ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brownstatic struct regulator *_regulator_get(struct device *dev, const char *id,
11525ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown					int exclusive)
1153414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1154414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator_dev *rdev;
1155414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator_map *map;
1156414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator *regulator = ERR_PTR(-ENODEV);
115740f9244f4da8976eeb6d5ed6313c635ba238a9d3Mark Brown	const char *devname = NULL;
11585ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown	int ret;
1159414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1160414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (id == NULL) {
11615da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches		pr_err("get() with no identifier\n");
1162414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return regulator;
1163414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
1164414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
116540f9244f4da8976eeb6d5ed6313c635ba238a9d3Mark Brown	if (dev)
116640f9244f4da8976eeb6d5ed6313c635ba238a9d3Mark Brown		devname = dev_name(dev);
116740f9244f4da8976eeb6d5ed6313c635ba238a9d3Mark Brown
1168414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&regulator_list_mutex);
1169414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1170414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	list_for_each_entry(map, &regulator_map_list, list) {
117140f9244f4da8976eeb6d5ed6313c635ba238a9d3Mark Brown		/* If the mapping has a device set up it must match */
117240f9244f4da8976eeb6d5ed6313c635ba238a9d3Mark Brown		if (map->dev_name &&
117340f9244f4da8976eeb6d5ed6313c635ba238a9d3Mark Brown		    (!devname || strcmp(map->dev_name, devname)))
117440f9244f4da8976eeb6d5ed6313c635ba238a9d3Mark Brown			continue;
117540f9244f4da8976eeb6d5ed6313c635ba238a9d3Mark Brown
117640f9244f4da8976eeb6d5ed6313c635ba238a9d3Mark Brown		if (strcmp(map->supply, id) == 0) {
1177a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood			rdev = map->regulator;
1178414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			goto found;
1179a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		}
1180414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
118134abbd68efe09765465b81dfedeee9994f13302fMark Brown
1182688fe99a439f7c9dfcc52fbf7cb347f140a2dc8bMark Brown	if (board_wants_dummy_regulator) {
1183688fe99a439f7c9dfcc52fbf7cb347f140a2dc8bMark Brown		rdev = dummy_regulator_rdev;
1184688fe99a439f7c9dfcc52fbf7cb347f140a2dc8bMark Brown		goto found;
1185688fe99a439f7c9dfcc52fbf7cb347f140a2dc8bMark Brown	}
1186688fe99a439f7c9dfcc52fbf7cb347f140a2dc8bMark Brown
118734abbd68efe09765465b81dfedeee9994f13302fMark Brown#ifdef CONFIG_REGULATOR_DUMMY
118834abbd68efe09765465b81dfedeee9994f13302fMark Brown	if (!devname)
118934abbd68efe09765465b81dfedeee9994f13302fMark Brown		devname = "deviceless";
119034abbd68efe09765465b81dfedeee9994f13302fMark Brown
119134abbd68efe09765465b81dfedeee9994f13302fMark Brown	/* If the board didn't flag that it was fully constrained then
119234abbd68efe09765465b81dfedeee9994f13302fMark Brown	 * substitute in a dummy regulator so consumers can continue.
119334abbd68efe09765465b81dfedeee9994f13302fMark Brown	 */
119434abbd68efe09765465b81dfedeee9994f13302fMark Brown	if (!has_full_constraints) {
11955da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches		pr_warn("%s supply %s not found, using dummy regulator\n",
11965da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches			devname, id);
119734abbd68efe09765465b81dfedeee9994f13302fMark Brown		rdev = dummy_regulator_rdev;
119834abbd68efe09765465b81dfedeee9994f13302fMark Brown		goto found;
119934abbd68efe09765465b81dfedeee9994f13302fMark Brown	}
120034abbd68efe09765465b81dfedeee9994f13302fMark Brown#endif
120134abbd68efe09765465b81dfedeee9994f13302fMark Brown
1202414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&regulator_list_mutex);
1203414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return regulator;
1204414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1205414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodfound:
12065ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown	if (rdev->exclusive) {
12075ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown		regulator = ERR_PTR(-EPERM);
12085ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown		goto out;
12095ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown	}
12105ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown
12115ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown	if (exclusive && rdev->open_count) {
12125ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown		regulator = ERR_PTR(-EBUSY);
12135ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown		goto out;
12145ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown	}
12155ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown
1216a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	if (!try_module_get(rdev->owner))
1217a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		goto out;
1218a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
1219414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	regulator = create_regulator(rdev, dev, id);
1220414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (regulator == NULL) {
1221414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator = ERR_PTR(-ENOMEM);
1222414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		module_put(rdev->owner);
1223414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
1224414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
12255ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown	rdev->open_count++;
12265ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown	if (exclusive) {
12275ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown		rdev->exclusive = 1;
12285ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown
12295ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown		ret = _regulator_is_enabled(rdev);
12305ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown		if (ret > 0)
12315ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown			rdev->use_count = 1;
12325ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown		else
12335ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown			rdev->use_count = 0;
12345ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown	}
12355ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown
1236a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwoodout:
1237414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&regulator_list_mutex);
12385ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown
1239414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return regulator;
1240414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
12415ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown
12425ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown/**
12435ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown * regulator_get - lookup and obtain a reference to a regulator.
12445ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown * @dev: device for regulator "consumer"
12455ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown * @id: Supply name or regulator ID.
12465ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown *
12475ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown * Returns a struct regulator corresponding to the regulator producer,
12485ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown * or IS_ERR() condition containing errno.
12495ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown *
12505ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown * Use of supply names configured via regulator_set_device_supply() is
12515ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown * strongly encouraged.  It is recommended that the supply name used
12525ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown * should match the name used for the supply and/or the relevant
12535ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown * device pins in the datasheet.
12545ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown */
12555ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brownstruct regulator *regulator_get(struct device *dev, const char *id)
12565ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown{
12575ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown	return _regulator_get(dev, id, 0);
12585ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown}
1259414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_get);
1260414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1261414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
12625ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown * regulator_get_exclusive - obtain exclusive access to a regulator.
12635ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown * @dev: device for regulator "consumer"
12645ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown * @id: Supply name or regulator ID.
12655ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown *
12665ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown * Returns a struct regulator corresponding to the regulator producer,
12675ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown * or IS_ERR() condition containing errno.  Other consumers will be
12685ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown * unable to obtain this reference is held and the use count for the
12695ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown * regulator will be initialised to reflect the current state of the
12705ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown * regulator.
12715ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown *
12725ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown * This is intended for use by consumers which cannot tolerate shared
12735ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown * use of the regulator such as those which need to force the
12745ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown * regulator off for correct operation of the hardware they are
12755ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown * controlling.
12765ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown *
12775ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown * Use of supply names configured via regulator_set_device_supply() is
12785ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown * strongly encouraged.  It is recommended that the supply name used
12795ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown * should match the name used for the supply and/or the relevant
12805ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown * device pins in the datasheet.
12815ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown */
12825ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brownstruct regulator *regulator_get_exclusive(struct device *dev, const char *id)
12835ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown{
12845ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown	return _regulator_get(dev, id, 1);
12855ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown}
12865ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark BrownEXPORT_SYMBOL_GPL(regulator_get_exclusive);
12875ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown
12885ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown/**
1289414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_put - "free" the regulator source
1290414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
1291414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1292414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Note: drivers must ensure that all regulator_enable calls made on this
1293414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator source are balanced by regulator_disable calls prior to calling
1294414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * this function.
1295414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1296414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodvoid regulator_put(struct regulator *regulator)
1297414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1298414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator_dev *rdev;
1299414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1300414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (regulator == NULL || IS_ERR(regulator))
1301414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return;
1302414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1303414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&regulator_list_mutex);
1304414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	rdev = regulator->rdev;
1305414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
13065de705194e9883a39f993e2ff96028d5aab99b37Mark Brown#ifdef CONFIG_DEBUG_FS
13075de705194e9883a39f993e2ff96028d5aab99b37Mark Brown	debugfs_remove_recursive(regulator->debugfs);
13085de705194e9883a39f993e2ff96028d5aab99b37Mark Brown#endif
13095de705194e9883a39f993e2ff96028d5aab99b37Mark Brown
1310414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* remove any sysfs entries */
1311414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (regulator->dev) {
1312414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name);
1313414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		device_remove_file(regulator->dev, &regulator->dev_attr);
1314414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		kfree(regulator->dev_attr.attr.name);
1315414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
13165de705194e9883a39f993e2ff96028d5aab99b37Mark Brown	kfree(regulator->supply_name);
1317414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	list_del(&regulator->list);
1318414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	kfree(regulator);
1319414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
13205ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown	rdev->open_count--;
13215ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown	rdev->exclusive = 0;
13225ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30Mark Brown
1323414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	module_put(rdev->owner);
1324414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&regulator_list_mutex);
1325414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1326414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_put);
1327414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
13289a2372fa7a403ba327873d0208a619d781a8a150Mark Brownstatic int _regulator_can_change_status(struct regulator_dev *rdev)
13299a2372fa7a403ba327873d0208a619d781a8a150Mark Brown{
13309a2372fa7a403ba327873d0208a619d781a8a150Mark Brown	if (!rdev->constraints)
13319a2372fa7a403ba327873d0208a619d781a8a150Mark Brown		return 0;
13329a2372fa7a403ba327873d0208a619d781a8a150Mark Brown
13339a2372fa7a403ba327873d0208a619d781a8a150Mark Brown	if (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_STATUS)
13349a2372fa7a403ba327873d0208a619d781a8a150Mark Brown		return 1;
13359a2372fa7a403ba327873d0208a619d781a8a150Mark Brown	else
13369a2372fa7a403ba327873d0208a619d781a8a150Mark Brown		return 0;
13379a2372fa7a403ba327873d0208a619d781a8a150Mark Brown}
13389a2372fa7a403ba327873d0208a619d781a8a150Mark Brown
1339414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/* locks held by regulator_enable() */
1340414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic int _regulator_enable(struct regulator_dev *rdev)
1341414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
134231aae2beeb3d601d556b6a8c39085940ad1e9f42Mark Brown	int ret, delay;
1343414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1344414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* check voltage and requested load before enabling */
13459a2372fa7a403ba327873d0208a619d781a8a150Mark Brown	if (rdev->constraints &&
13469a2372fa7a403ba327873d0208a619d781a8a150Mark Brown	    (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS))
13479a2372fa7a403ba327873d0208a619d781a8a150Mark Brown		drms_uA_update(rdev);
1348414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
13499a2372fa7a403ba327873d0208a619d781a8a150Mark Brown	if (rdev->use_count == 0) {
13509a2372fa7a403ba327873d0208a619d781a8a150Mark Brown		/* The regulator may on if it's not switchable or left on */
13519a2372fa7a403ba327873d0208a619d781a8a150Mark Brown		ret = _regulator_is_enabled(rdev);
13529a2372fa7a403ba327873d0208a619d781a8a150Mark Brown		if (ret == -EINVAL || ret == 0) {
13539a2372fa7a403ba327873d0208a619d781a8a150Mark Brown			if (!_regulator_can_change_status(rdev))
13549a2372fa7a403ba327873d0208a619d781a8a150Mark Brown				return -EPERM;
13559a2372fa7a403ba327873d0208a619d781a8a150Mark Brown
135631aae2beeb3d601d556b6a8c39085940ad1e9f42Mark Brown			if (!rdev->desc->ops->enable)
13579a2372fa7a403ba327873d0208a619d781a8a150Mark Brown				return -EINVAL;
135831aae2beeb3d601d556b6a8c39085940ad1e9f42Mark Brown
135931aae2beeb3d601d556b6a8c39085940ad1e9f42Mark Brown			/* Query before enabling in case configuration
136025985edcedea6396277003854657b5f3cb31a628Lucas De Marchi			 * dependent.  */
136131aae2beeb3d601d556b6a8c39085940ad1e9f42Mark Brown			ret = _regulator_get_enable_time(rdev);
136231aae2beeb3d601d556b6a8c39085940ad1e9f42Mark Brown			if (ret >= 0) {
136331aae2beeb3d601d556b6a8c39085940ad1e9f42Mark Brown				delay = ret;
136431aae2beeb3d601d556b6a8c39085940ad1e9f42Mark Brown			} else {
13655da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches				rdev_warn(rdev, "enable_time() failed: %d\n",
13661d7372e15ebd7f56a336fabe6ee31f8e692cd9cbDaniel Walker					   ret);
136731aae2beeb3d601d556b6a8c39085940ad1e9f42Mark Brown				delay = 0;
13689a2372fa7a403ba327873d0208a619d781a8a150Mark Brown			}
136931aae2beeb3d601d556b6a8c39085940ad1e9f42Mark Brown
137002fa3ec01a0df7a8ccc356d8e245a9a1423b3596Mark Brown			trace_regulator_enable(rdev_get_name(rdev));
137102fa3ec01a0df7a8ccc356d8e245a9a1423b3596Mark Brown
137231aae2beeb3d601d556b6a8c39085940ad1e9f42Mark Brown			/* Allow the regulator to ramp; it would be useful
137331aae2beeb3d601d556b6a8c39085940ad1e9f42Mark Brown			 * to extend this for bulk operations so that the
137431aae2beeb3d601d556b6a8c39085940ad1e9f42Mark Brown			 * regulators can ramp together.  */
137531aae2beeb3d601d556b6a8c39085940ad1e9f42Mark Brown			ret = rdev->desc->ops->enable(rdev);
137631aae2beeb3d601d556b6a8c39085940ad1e9f42Mark Brown			if (ret < 0)
137731aae2beeb3d601d556b6a8c39085940ad1e9f42Mark Brown				return ret;
137831aae2beeb3d601d556b6a8c39085940ad1e9f42Mark Brown
137902fa3ec01a0df7a8ccc356d8e245a9a1423b3596Mark Brown			trace_regulator_enable_delay(rdev_get_name(rdev));
138002fa3ec01a0df7a8ccc356d8e245a9a1423b3596Mark Brown
1381e36c1df8e18183ba2c691fe766a52c94020cdc5eAxel Lin			if (delay >= 1000) {
138231aae2beeb3d601d556b6a8c39085940ad1e9f42Mark Brown				mdelay(delay / 1000);
1383e36c1df8e18183ba2c691fe766a52c94020cdc5eAxel Lin				udelay(delay % 1000);
1384e36c1df8e18183ba2c691fe766a52c94020cdc5eAxel Lin			} else if (delay) {
138531aae2beeb3d601d556b6a8c39085940ad1e9f42Mark Brown				udelay(delay);
1386e36c1df8e18183ba2c691fe766a52c94020cdc5eAxel Lin			}
138731aae2beeb3d601d556b6a8c39085940ad1e9f42Mark Brown
138802fa3ec01a0df7a8ccc356d8e245a9a1423b3596Mark Brown			trace_regulator_enable_complete(rdev_get_name(rdev));
138902fa3ec01a0df7a8ccc356d8e245a9a1423b3596Mark Brown
1390a7433cff9ed8e7982de8e0f210f0325d0f3d1949Linus Walleij		} else if (ret < 0) {
13915da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches			rdev_err(rdev, "is_enabled() failed: %d\n", ret);
1392414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			return ret;
1393414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		}
1394a7433cff9ed8e7982de8e0f210f0325d0f3d1949Linus Walleij		/* Fallthrough on positive return values - already enabled */
1395414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
1396414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
13979a2372fa7a403ba327873d0208a619d781a8a150Mark Brown	rdev->use_count++;
13989a2372fa7a403ba327873d0208a619d781a8a150Mark Brown
13999a2372fa7a403ba327873d0208a619d781a8a150Mark Brown	return 0;
1400414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1401414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1402414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
1403414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_enable - enable regulator output
1404414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
1405414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1406cf7bbcdf4d267eff580cb7ce6cf4fe16a940a005Mark Brown * Request that the regulator be enabled with the regulator output at
1407cf7bbcdf4d267eff580cb7ce6cf4fe16a940a005Mark Brown * the predefined voltage or current value.  Calls to regulator_enable()
1408cf7bbcdf4d267eff580cb7ce6cf4fe16a940a005Mark Brown * must be balanced with calls to regulator_disable().
1409cf7bbcdf4d267eff580cb7ce6cf4fe16a940a005Mark Brown *
1410414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * NOTE: the output value can be set by other drivers, boot loader or may be
1411cf7bbcdf4d267eff580cb7ce6cf4fe16a940a005Mark Brown * hardwired in the regulator.
1412414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1413414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_enable(struct regulator *regulator)
1414414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1415412aec610559bdb602a0a21ce149ba8ffbb6f983David Brownell	struct regulator_dev *rdev = regulator->rdev;
1416412aec610559bdb602a0a21ce149ba8ffbb6f983David Brownell	int ret = 0;
1417414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
14183801b86aa482d26a8ae460f67fca29e016491a86Mark Brown	if (rdev->supply) {
14193801b86aa482d26a8ae460f67fca29e016491a86Mark Brown		ret = regulator_enable(rdev->supply);
14203801b86aa482d26a8ae460f67fca29e016491a86Mark Brown		if (ret != 0)
14213801b86aa482d26a8ae460f67fca29e016491a86Mark Brown			return ret;
14223801b86aa482d26a8ae460f67fca29e016491a86Mark Brown	}
14233801b86aa482d26a8ae460f67fca29e016491a86Mark Brown
1424412aec610559bdb602a0a21ce149ba8ffbb6f983David Brownell	mutex_lock(&rdev->mutex);
1425cd94b5053081963614f6ad77b9b66a7968056c84David Brownell	ret = _regulator_enable(rdev);
1426412aec610559bdb602a0a21ce149ba8ffbb6f983David Brownell	mutex_unlock(&rdev->mutex);
14273801b86aa482d26a8ae460f67fca29e016491a86Mark Brown
14283801b86aa482d26a8ae460f67fca29e016491a86Mark Brown	if (ret != 0)
14293801b86aa482d26a8ae460f67fca29e016491a86Mark Brown		regulator_disable(rdev->supply);
14303801b86aa482d26a8ae460f67fca29e016491a86Mark Brown
1431414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
1432414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1433414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_enable);
1434414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1435414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/* locks held by regulator_disable() */
14363801b86aa482d26a8ae460f67fca29e016491a86Mark Brownstatic int _regulator_disable(struct regulator_dev *rdev)
1437414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1438414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret = 0;
1439414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1440cd94b5053081963614f6ad77b9b66a7968056c84David Brownell	if (WARN(rdev->use_count <= 0,
144143e7ee33f2a8d20238267b789791386739247478Joe Perches		 "unbalanced disables for %s\n", rdev_get_name(rdev)))
1442cd94b5053081963614f6ad77b9b66a7968056c84David Brownell		return -EIO;
1443cd94b5053081963614f6ad77b9b66a7968056c84David Brownell
1444414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* are we the last user and permitted to disable ? */
144560ef66fcf40f0e7bc9579981aa16bd8218942a83Mark Brown	if (rdev->use_count == 1 &&
144660ef66fcf40f0e7bc9579981aa16bd8218942a83Mark Brown	    (rdev->constraints && !rdev->constraints->always_on)) {
1447414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1448414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		/* we are last user */
14499a2372fa7a403ba327873d0208a619d781a8a150Mark Brown		if (_regulator_can_change_status(rdev) &&
14509a2372fa7a403ba327873d0208a619d781a8a150Mark Brown		    rdev->desc->ops->disable) {
145102fa3ec01a0df7a8ccc356d8e245a9a1423b3596Mark Brown			trace_regulator_disable(rdev_get_name(rdev));
145202fa3ec01a0df7a8ccc356d8e245a9a1423b3596Mark Brown
1453414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			ret = rdev->desc->ops->disable(rdev);
1454414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			if (ret < 0) {
14555da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches				rdev_err(rdev, "failed to disable\n");
1456414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				return ret;
1457414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			}
145884b6826306119dc3c41ef9d7ed6c408112f63301Mark Brown
145902fa3ec01a0df7a8ccc356d8e245a9a1423b3596Mark Brown			trace_regulator_disable_complete(rdev_get_name(rdev));
146002fa3ec01a0df7a8ccc356d8e245a9a1423b3596Mark Brown
146184b6826306119dc3c41ef9d7ed6c408112f63301Mark Brown			_notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE,
146284b6826306119dc3c41ef9d7ed6c408112f63301Mark Brown					     NULL);
1463414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		}
1464414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1465414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		rdev->use_count = 0;
1466414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	} else if (rdev->use_count > 1) {
1467414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1468414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (rdev->constraints &&
1469414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			(rdev->constraints->valid_ops_mask &
1470414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			REGULATOR_CHANGE_DRMS))
1471414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			drms_uA_update(rdev);
1472414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1473414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		rdev->use_count--;
1474414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
14753801b86aa482d26a8ae460f67fca29e016491a86Mark Brown
1476414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
1477414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1478414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1479414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
1480414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_disable - disable regulator output
1481414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
1482414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1483cf7bbcdf4d267eff580cb7ce6cf4fe16a940a005Mark Brown * Disable the regulator output voltage or current.  Calls to
1484cf7bbcdf4d267eff580cb7ce6cf4fe16a940a005Mark Brown * regulator_enable() must be balanced with calls to
1485cf7bbcdf4d267eff580cb7ce6cf4fe16a940a005Mark Brown * regulator_disable().
148669279fb9a95051971ac03e558c4d46e7ba84ab3aMark Brown *
1487414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * NOTE: this will only disable the regulator output if no other consumer
1488cf7bbcdf4d267eff580cb7ce6cf4fe16a940a005Mark Brown * devices have it enabled, the regulator device supports disabling and
1489cf7bbcdf4d267eff580cb7ce6cf4fe16a940a005Mark Brown * machine constraints permit this operation.
1490414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1491414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_disable(struct regulator *regulator)
1492414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1493412aec610559bdb602a0a21ce149ba8ffbb6f983David Brownell	struct regulator_dev *rdev = regulator->rdev;
1494412aec610559bdb602a0a21ce149ba8ffbb6f983David Brownell	int ret = 0;
1495414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1496412aec610559bdb602a0a21ce149ba8ffbb6f983David Brownell	mutex_lock(&rdev->mutex);
14973801b86aa482d26a8ae460f67fca29e016491a86Mark Brown	ret = _regulator_disable(rdev);
1498412aec610559bdb602a0a21ce149ba8ffbb6f983David Brownell	mutex_unlock(&rdev->mutex);
14998cbf811dfd027bde8504e541d0009c5722b98be5Jeffrey Carlyle
15003801b86aa482d26a8ae460f67fca29e016491a86Mark Brown	if (ret == 0 && rdev->supply)
15013801b86aa482d26a8ae460f67fca29e016491a86Mark Brown		regulator_disable(rdev->supply);
15028cbf811dfd027bde8504e541d0009c5722b98be5Jeffrey Carlyle
1503414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
1504414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1505414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_disable);
1506414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1507414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/* locks held by regulator_force_disable() */
15083801b86aa482d26a8ae460f67fca29e016491a86Mark Brownstatic int _regulator_force_disable(struct regulator_dev *rdev)
1509414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1510414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret = 0;
1511414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1512414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* force disable */
1513414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (rdev->desc->ops->disable) {
1514414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		/* ah well, who wants to live forever... */
1515414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		ret = rdev->desc->ops->disable(rdev);
1516414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (ret < 0) {
15175da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches			rdev_err(rdev, "failed to force disable\n");
1518414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			return ret;
1519414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		}
1520414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		/* notify other consumers that power has been forced off */
152184b6826306119dc3c41ef9d7ed6c408112f63301Mark Brown		_notifier_call_chain(rdev, REGULATOR_EVENT_FORCE_DISABLE |
152284b6826306119dc3c41ef9d7ed6c408112f63301Mark Brown			REGULATOR_EVENT_DISABLE, NULL);
1523414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
1524414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1525414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
1526414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1527414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1528414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
1529414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_force_disable - force disable regulator output
1530414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
1531414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1532414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Forcibly disable the regulator output voltage or current.
1533414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * NOTE: this *will* disable the regulator output even if other consumer
1534414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * devices have it enabled. This should be used for situations when device
1535414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * damage will likely occur if the regulator is not disabled (e.g. over temp).
1536414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1537414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_force_disable(struct regulator *regulator)
1538414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
153982d158397b6eeb464263a6ef6a739c4118a34720Mark Brown	struct regulator_dev *rdev = regulator->rdev;
1540414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret;
1541414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
154282d158397b6eeb464263a6ef6a739c4118a34720Mark Brown	mutex_lock(&rdev->mutex);
1543414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	regulator->uA_load = 0;
15443801b86aa482d26a8ae460f67fca29e016491a86Mark Brown	ret = _regulator_force_disable(regulator->rdev);
154582d158397b6eeb464263a6ef6a739c4118a34720Mark Brown	mutex_unlock(&rdev->mutex);
15468cbf811dfd027bde8504e541d0009c5722b98be5Jeffrey Carlyle
15473801b86aa482d26a8ae460f67fca29e016491a86Mark Brown	if (rdev->supply)
15483801b86aa482d26a8ae460f67fca29e016491a86Mark Brown		while (rdev->open_count--)
15493801b86aa482d26a8ae460f67fca29e016491a86Mark Brown			regulator_disable(rdev->supply);
15508cbf811dfd027bde8504e541d0009c5722b98be5Jeffrey Carlyle
1551414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
1552414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1553414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_force_disable);
1554414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1555414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic int _regulator_is_enabled(struct regulator_dev *rdev)
1556414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
15579a7f6a4c6edc84748c6477c9df56691a0e61b8fdMark Brown	/* If we don't know then assume that the regulator is always on */
15589332546fe88fa88bf6a7d9b1dce53ff5d314934eMark Brown	if (!rdev->desc->ops->is_enabled)
15599a7f6a4c6edc84748c6477c9df56691a0e61b8fdMark Brown		return 1;
1560414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
15619332546fe88fa88bf6a7d9b1dce53ff5d314934eMark Brown	return rdev->desc->ops->is_enabled(rdev);
1562414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1563414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1564414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
1565414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_is_enabled - is the regulator output enabled
1566414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
1567414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1568412aec610559bdb602a0a21ce149ba8ffbb6f983David Brownell * Returns positive if the regulator driver backing the source/client
1569412aec610559bdb602a0a21ce149ba8ffbb6f983David Brownell * has requested that the device be enabled, zero if it hasn't, else a
1570412aec610559bdb602a0a21ce149ba8ffbb6f983David Brownell * negative errno code.
1571412aec610559bdb602a0a21ce149ba8ffbb6f983David Brownell *
1572412aec610559bdb602a0a21ce149ba8ffbb6f983David Brownell * Note that the device backing this regulator handle can have multiple
1573412aec610559bdb602a0a21ce149ba8ffbb6f983David Brownell * users, so it might be enabled even if regulator_enable() was never
1574412aec610559bdb602a0a21ce149ba8ffbb6f983David Brownell * called for this particular source.
1575414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1576414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_is_enabled(struct regulator *regulator)
1577414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
15789332546fe88fa88bf6a7d9b1dce53ff5d314934eMark Brown	int ret;
15799332546fe88fa88bf6a7d9b1dce53ff5d314934eMark Brown
15809332546fe88fa88bf6a7d9b1dce53ff5d314934eMark Brown	mutex_lock(&regulator->rdev->mutex);
15819332546fe88fa88bf6a7d9b1dce53ff5d314934eMark Brown	ret = _regulator_is_enabled(regulator->rdev);
15829332546fe88fa88bf6a7d9b1dce53ff5d314934eMark Brown	mutex_unlock(&regulator->rdev->mutex);
15839332546fe88fa88bf6a7d9b1dce53ff5d314934eMark Brown
15849332546fe88fa88bf6a7d9b1dce53ff5d314934eMark Brown	return ret;
1585414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1586414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_is_enabled);
1587414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1588414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
15894367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell * regulator_count_voltages - count regulator_list_voltage() selectors
15904367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell * @regulator: regulator source
15914367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell *
15924367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell * Returns number of selectors, or negative errno.  Selectors are
15934367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell * numbered starting at zero, and typically correspond to bitfields
15944367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell * in hardware registers.
15954367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell */
15964367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownellint regulator_count_voltages(struct regulator *regulator)
15974367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell{
15984367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell	struct regulator_dev	*rdev = regulator->rdev;
15994367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell
16004367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell	return rdev->desc->n_voltages ? : -EINVAL;
16014367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell}
16024367cfdc7c657ad8a797f51b9ffd3c64b31910e7David BrownellEXPORT_SYMBOL_GPL(regulator_count_voltages);
16034367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell
16044367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell/**
16054367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell * regulator_list_voltage - enumerate supported voltages
16064367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell * @regulator: regulator source
16074367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell * @selector: identify voltage to list
16084367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell * Context: can sleep
16094367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell *
16104367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell * Returns a voltage that can be passed to @regulator_set_voltage(),
161188393161210493e317ae391696ee8ef463cb3c23Thomas Weber * zero if this selector code can't be used on this system, or a
16124367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell * negative errno.
16134367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell */
16144367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownellint regulator_list_voltage(struct regulator *regulator, unsigned selector)
16154367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell{
16164367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell	struct regulator_dev	*rdev = regulator->rdev;
16174367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell	struct regulator_ops	*ops = rdev->desc->ops;
16184367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell	int			ret;
16194367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell
16204367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell	if (!ops->list_voltage || selector >= rdev->desc->n_voltages)
16214367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell		return -EINVAL;
16224367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell
16234367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell	mutex_lock(&rdev->mutex);
16244367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell	ret = ops->list_voltage(rdev, selector);
16254367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell	mutex_unlock(&rdev->mutex);
16264367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell
16274367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell	if (ret > 0) {
16284367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell		if (ret < rdev->constraints->min_uV)
16294367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell			ret = 0;
16304367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell		else if (ret > rdev->constraints->max_uV)
16314367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell			ret = 0;
16324367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell	}
16334367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell
16344367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell	return ret;
16354367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell}
16364367cfdc7c657ad8a797f51b9ffd3c64b31910e7David BrownellEXPORT_SYMBOL_GPL(regulator_list_voltage);
16374367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell
16384367cfdc7c657ad8a797f51b9ffd3c64b31910e7David Brownell/**
1639a7a1ad9066e0266c8a4357ba3dbaeebfb80f531dMark Brown * regulator_is_supported_voltage - check if a voltage range can be supported
1640a7a1ad9066e0266c8a4357ba3dbaeebfb80f531dMark Brown *
1641a7a1ad9066e0266c8a4357ba3dbaeebfb80f531dMark Brown * @regulator: Regulator to check.
1642a7a1ad9066e0266c8a4357ba3dbaeebfb80f531dMark Brown * @min_uV: Minimum required voltage in uV.
1643a7a1ad9066e0266c8a4357ba3dbaeebfb80f531dMark Brown * @max_uV: Maximum required voltage in uV.
1644a7a1ad9066e0266c8a4357ba3dbaeebfb80f531dMark Brown *
1645a7a1ad9066e0266c8a4357ba3dbaeebfb80f531dMark Brown * Returns a boolean or a negative error code.
1646a7a1ad9066e0266c8a4357ba3dbaeebfb80f531dMark Brown */
1647a7a1ad9066e0266c8a4357ba3dbaeebfb80f531dMark Brownint regulator_is_supported_voltage(struct regulator *regulator,
1648a7a1ad9066e0266c8a4357ba3dbaeebfb80f531dMark Brown				   int min_uV, int max_uV)
1649a7a1ad9066e0266c8a4357ba3dbaeebfb80f531dMark Brown{
1650a7a1ad9066e0266c8a4357ba3dbaeebfb80f531dMark Brown	int i, voltages, ret;
1651a7a1ad9066e0266c8a4357ba3dbaeebfb80f531dMark Brown
1652a7a1ad9066e0266c8a4357ba3dbaeebfb80f531dMark Brown	ret = regulator_count_voltages(regulator);
1653a7a1ad9066e0266c8a4357ba3dbaeebfb80f531dMark Brown	if (ret < 0)
1654a7a1ad9066e0266c8a4357ba3dbaeebfb80f531dMark Brown		return ret;
1655a7a1ad9066e0266c8a4357ba3dbaeebfb80f531dMark Brown	voltages = ret;
1656a7a1ad9066e0266c8a4357ba3dbaeebfb80f531dMark Brown
1657a7a1ad9066e0266c8a4357ba3dbaeebfb80f531dMark Brown	for (i = 0; i < voltages; i++) {
1658a7a1ad9066e0266c8a4357ba3dbaeebfb80f531dMark Brown		ret = regulator_list_voltage(regulator, i);
1659a7a1ad9066e0266c8a4357ba3dbaeebfb80f531dMark Brown
1660a7a1ad9066e0266c8a4357ba3dbaeebfb80f531dMark Brown		if (ret >= min_uV && ret <= max_uV)
1661a7a1ad9066e0266c8a4357ba3dbaeebfb80f531dMark Brown			return 1;
1662a7a1ad9066e0266c8a4357ba3dbaeebfb80f531dMark Brown	}
1663a7a1ad9066e0266c8a4357ba3dbaeebfb80f531dMark Brown
1664a7a1ad9066e0266c8a4357ba3dbaeebfb80f531dMark Brown	return 0;
1665a7a1ad9066e0266c8a4357ba3dbaeebfb80f531dMark Brown}
1666a7a1ad9066e0266c8a4357ba3dbaeebfb80f531dMark Brown
1667757902513019e6ee469791ff76f954b19ca8d036Mark Brownstatic int _regulator_do_set_voltage(struct regulator_dev *rdev,
1668757902513019e6ee469791ff76f954b19ca8d036Mark Brown				     int min_uV, int max_uV)
1669757902513019e6ee469791ff76f954b19ca8d036Mark Brown{
1670757902513019e6ee469791ff76f954b19ca8d036Mark Brown	int ret;
167177af1b2641faf45788a0d480db94082ebee931dcLinus Walleij	int delay = 0;
1672757902513019e6ee469791ff76f954b19ca8d036Mark Brown	unsigned int selector;
1673757902513019e6ee469791ff76f954b19ca8d036Mark Brown
1674757902513019e6ee469791ff76f954b19ca8d036Mark Brown	trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV);
1675757902513019e6ee469791ff76f954b19ca8d036Mark Brown
1676bf5892a8167e4aa5a9a6d72f803fde850e0c5753Mark Brown	min_uV += rdev->constraints->uV_offset;
1677bf5892a8167e4aa5a9a6d72f803fde850e0c5753Mark Brown	max_uV += rdev->constraints->uV_offset;
1678bf5892a8167e4aa5a9a6d72f803fde850e0c5753Mark Brown
1679757902513019e6ee469791ff76f954b19ca8d036Mark Brown	if (rdev->desc->ops->set_voltage) {
1680757902513019e6ee469791ff76f954b19ca8d036Mark Brown		ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV,
1681757902513019e6ee469791ff76f954b19ca8d036Mark Brown						   &selector);
1682757902513019e6ee469791ff76f954b19ca8d036Mark Brown
1683757902513019e6ee469791ff76f954b19ca8d036Mark Brown		if (rdev->desc->ops->list_voltage)
1684757902513019e6ee469791ff76f954b19ca8d036Mark Brown			selector = rdev->desc->ops->list_voltage(rdev,
1685757902513019e6ee469791ff76f954b19ca8d036Mark Brown								 selector);
1686757902513019e6ee469791ff76f954b19ca8d036Mark Brown		else
1687757902513019e6ee469791ff76f954b19ca8d036Mark Brown			selector = -1;
1688e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown	} else if (rdev->desc->ops->set_voltage_sel) {
1689e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown		int best_val = INT_MAX;
1690e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown		int i;
1691e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown
1692e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown		selector = 0;
1693e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown
1694e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown		/* Find the smallest voltage that falls within the specified
1695e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown		 * range.
1696e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown		 */
1697e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown		for (i = 0; i < rdev->desc->n_voltages; i++) {
1698e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown			ret = rdev->desc->ops->list_voltage(rdev, i);
1699e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown			if (ret < 0)
1700e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown				continue;
1701e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown
1702e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown			if (ret < best_val && ret >= min_uV && ret <= max_uV) {
1703e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown				best_val = ret;
1704e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown				selector = i;
1705e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown			}
1706e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown		}
1707e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown
170877af1b2641faf45788a0d480db94082ebee931dcLinus Walleij		/*
170977af1b2641faf45788a0d480db94082ebee931dcLinus Walleij		 * If we can't obtain the old selector there is not enough
171077af1b2641faf45788a0d480db94082ebee931dcLinus Walleij		 * info to call set_voltage_time_sel().
171177af1b2641faf45788a0d480db94082ebee931dcLinus Walleij		 */
171277af1b2641faf45788a0d480db94082ebee931dcLinus Walleij		if (rdev->desc->ops->set_voltage_time_sel &&
171377af1b2641faf45788a0d480db94082ebee931dcLinus Walleij		    rdev->desc->ops->get_voltage_sel) {
171477af1b2641faf45788a0d480db94082ebee931dcLinus Walleij			unsigned int old_selector = 0;
171577af1b2641faf45788a0d480db94082ebee931dcLinus Walleij
171677af1b2641faf45788a0d480db94082ebee931dcLinus Walleij			ret = rdev->desc->ops->get_voltage_sel(rdev);
171777af1b2641faf45788a0d480db94082ebee931dcLinus Walleij			if (ret < 0)
171877af1b2641faf45788a0d480db94082ebee931dcLinus Walleij				return ret;
171977af1b2641faf45788a0d480db94082ebee931dcLinus Walleij			old_selector = ret;
172077af1b2641faf45788a0d480db94082ebee931dcLinus Walleij			delay = rdev->desc->ops->set_voltage_time_sel(rdev,
172177af1b2641faf45788a0d480db94082ebee931dcLinus Walleij						old_selector, selector);
172277af1b2641faf45788a0d480db94082ebee931dcLinus Walleij		}
172377af1b2641faf45788a0d480db94082ebee931dcLinus Walleij
1724e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown		if (best_val != INT_MAX) {
1725e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown			ret = rdev->desc->ops->set_voltage_sel(rdev, selector);
1726e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown			selector = best_val;
1727e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown		} else {
1728e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown			ret = -EINVAL;
1729e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown		}
1730757902513019e6ee469791ff76f954b19ca8d036Mark Brown	} else {
1731757902513019e6ee469791ff76f954b19ca8d036Mark Brown		ret = -EINVAL;
1732757902513019e6ee469791ff76f954b19ca8d036Mark Brown	}
1733757902513019e6ee469791ff76f954b19ca8d036Mark Brown
173477af1b2641faf45788a0d480db94082ebee931dcLinus Walleij	/* Insert any necessary delays */
173577af1b2641faf45788a0d480db94082ebee931dcLinus Walleij	if (delay >= 1000) {
173677af1b2641faf45788a0d480db94082ebee931dcLinus Walleij		mdelay(delay / 1000);
173777af1b2641faf45788a0d480db94082ebee931dcLinus Walleij		udelay(delay % 1000);
173877af1b2641faf45788a0d480db94082ebee931dcLinus Walleij	} else if (delay) {
173977af1b2641faf45788a0d480db94082ebee931dcLinus Walleij		udelay(delay);
174077af1b2641faf45788a0d480db94082ebee931dcLinus Walleij	}
174177af1b2641faf45788a0d480db94082ebee931dcLinus Walleij
1742ded06a5270ddd6c3c3e25d9ddcaaaa4cb8385c2fMark Brown	if (ret == 0)
1743ded06a5270ddd6c3c3e25d9ddcaaaa4cb8385c2fMark Brown		_notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE,
1744ded06a5270ddd6c3c3e25d9ddcaaaa4cb8385c2fMark Brown				     NULL);
1745ded06a5270ddd6c3c3e25d9ddcaaaa4cb8385c2fMark Brown
1746757902513019e6ee469791ff76f954b19ca8d036Mark Brown	trace_regulator_set_voltage_complete(rdev_get_name(rdev), selector);
1747757902513019e6ee469791ff76f954b19ca8d036Mark Brown
1748757902513019e6ee469791ff76f954b19ca8d036Mark Brown	return ret;
1749757902513019e6ee469791ff76f954b19ca8d036Mark Brown}
1750757902513019e6ee469791ff76f954b19ca8d036Mark Brown
1751a7a1ad9066e0266c8a4357ba3dbaeebfb80f531dMark Brown/**
1752414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_set_voltage - set regulator output voltage
1753414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
1754414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @min_uV: Minimum required voltage in uV
1755414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @max_uV: Maximum acceptable voltage in uV
1756414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1757414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Sets a voltage regulator to the desired output voltage. This can be set
1758414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * during any regulator state. IOW, regulator can be disabled or enabled.
1759414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1760414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * If the regulator is enabled then the voltage will change to the new value
1761414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * immediately otherwise if the regulator is disabled the regulator will
1762414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * output at the new voltage when enabled.
1763414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1764414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * NOTE: If the regulator is shared between several devices then the lowest
1765414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * request voltage that meets the system constraints will be used.
176669279fb9a95051971ac03e558c4d46e7ba84ab3aMark Brown * Regulator system constraints must be set for this regulator before
1767414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * calling this function otherwise this call will fail.
1768414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1769414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
1770414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1771414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator_dev *rdev = regulator->rdev;
177295a3c23ae620c1b4c499746e70f4034bdc067737Mark Brown	int ret = 0;
1773414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1774414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&rdev->mutex);
1775414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
177695a3c23ae620c1b4c499746e70f4034bdc067737Mark Brown	/* If we're setting the same range as last time the change
177795a3c23ae620c1b4c499746e70f4034bdc067737Mark Brown	 * should be a noop (some cpufreq implementations use the same
177895a3c23ae620c1b4c499746e70f4034bdc067737Mark Brown	 * voltage for multiple frequencies, for example).
177995a3c23ae620c1b4c499746e70f4034bdc067737Mark Brown	 */
178095a3c23ae620c1b4c499746e70f4034bdc067737Mark Brown	if (regulator->min_uV == min_uV && regulator->max_uV == max_uV)
178195a3c23ae620c1b4c499746e70f4034bdc067737Mark Brown		goto out;
178295a3c23ae620c1b4c499746e70f4034bdc067737Mark Brown
1783414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* sanity check */
1784e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown	if (!rdev->desc->ops->set_voltage &&
1785e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown	    !rdev->desc->ops->set_voltage_sel) {
1786414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		ret = -EINVAL;
1787414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		goto out;
1788414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
1789414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1790414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* constraints check */
1791414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ret = regulator_check_voltage(rdev, &min_uV, &max_uV);
1792414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (ret < 0)
1793414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		goto out;
1794414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	regulator->min_uV = min_uV;
1795414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	regulator->max_uV = max_uV;
17963a93f2a9f4d8f73d74c0e552feb68a10f778a219Mark Brown
179705fda3b1abc23d832144e9497fb218870927d645Thomas Petazzoni	ret = regulator_check_consumers(rdev, &min_uV, &max_uV);
179805fda3b1abc23d832144e9497fb218870927d645Thomas Petazzoni	if (ret < 0)
179905fda3b1abc23d832144e9497fb218870927d645Thomas Petazzoni		goto out;
180005fda3b1abc23d832144e9497fb218870927d645Thomas Petazzoni
1801757902513019e6ee469791ff76f954b19ca8d036Mark Brown	ret = _regulator_do_set_voltage(rdev, min_uV, max_uV);
180202fa3ec01a0df7a8ccc356d8e245a9a1423b3596Mark Brown
1803414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodout:
1804414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&rdev->mutex);
1805414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
1806414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1807414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_set_voltage);
1808414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1809606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown/**
181088cd222b259d62148ab8c82398498b1a01314476Linus Walleij * regulator_set_voltage_time - get raise/fall time
181188cd222b259d62148ab8c82398498b1a01314476Linus Walleij * @regulator: regulator source
181288cd222b259d62148ab8c82398498b1a01314476Linus Walleij * @old_uV: starting voltage in microvolts
181388cd222b259d62148ab8c82398498b1a01314476Linus Walleij * @new_uV: target voltage in microvolts
181488cd222b259d62148ab8c82398498b1a01314476Linus Walleij *
181588cd222b259d62148ab8c82398498b1a01314476Linus Walleij * Provided with the starting and ending voltage, this function attempts to
181688cd222b259d62148ab8c82398498b1a01314476Linus Walleij * calculate the time in microseconds required to rise or fall to this new
181788cd222b259d62148ab8c82398498b1a01314476Linus Walleij * voltage.
181888cd222b259d62148ab8c82398498b1a01314476Linus Walleij */
181988cd222b259d62148ab8c82398498b1a01314476Linus Walleijint regulator_set_voltage_time(struct regulator *regulator,
182088cd222b259d62148ab8c82398498b1a01314476Linus Walleij			       int old_uV, int new_uV)
182188cd222b259d62148ab8c82398498b1a01314476Linus Walleij{
182288cd222b259d62148ab8c82398498b1a01314476Linus Walleij	struct regulator_dev	*rdev = regulator->rdev;
182388cd222b259d62148ab8c82398498b1a01314476Linus Walleij	struct regulator_ops	*ops = rdev->desc->ops;
182488cd222b259d62148ab8c82398498b1a01314476Linus Walleij	int old_sel = -1;
182588cd222b259d62148ab8c82398498b1a01314476Linus Walleij	int new_sel = -1;
182688cd222b259d62148ab8c82398498b1a01314476Linus Walleij	int voltage;
182788cd222b259d62148ab8c82398498b1a01314476Linus Walleij	int i;
182888cd222b259d62148ab8c82398498b1a01314476Linus Walleij
182988cd222b259d62148ab8c82398498b1a01314476Linus Walleij	/* Currently requires operations to do this */
183088cd222b259d62148ab8c82398498b1a01314476Linus Walleij	if (!ops->list_voltage || !ops->set_voltage_time_sel
183188cd222b259d62148ab8c82398498b1a01314476Linus Walleij	    || !rdev->desc->n_voltages)
183288cd222b259d62148ab8c82398498b1a01314476Linus Walleij		return -EINVAL;
183388cd222b259d62148ab8c82398498b1a01314476Linus Walleij
183488cd222b259d62148ab8c82398498b1a01314476Linus Walleij	for (i = 0; i < rdev->desc->n_voltages; i++) {
183588cd222b259d62148ab8c82398498b1a01314476Linus Walleij		/* We only look for exact voltage matches here */
183688cd222b259d62148ab8c82398498b1a01314476Linus Walleij		voltage = regulator_list_voltage(regulator, i);
183788cd222b259d62148ab8c82398498b1a01314476Linus Walleij		if (voltage < 0)
183888cd222b259d62148ab8c82398498b1a01314476Linus Walleij			return -EINVAL;
183988cd222b259d62148ab8c82398498b1a01314476Linus Walleij		if (voltage == 0)
184088cd222b259d62148ab8c82398498b1a01314476Linus Walleij			continue;
184188cd222b259d62148ab8c82398498b1a01314476Linus Walleij		if (voltage == old_uV)
184288cd222b259d62148ab8c82398498b1a01314476Linus Walleij			old_sel = i;
184388cd222b259d62148ab8c82398498b1a01314476Linus Walleij		if (voltage == new_uV)
184488cd222b259d62148ab8c82398498b1a01314476Linus Walleij			new_sel = i;
184588cd222b259d62148ab8c82398498b1a01314476Linus Walleij	}
184688cd222b259d62148ab8c82398498b1a01314476Linus Walleij
184788cd222b259d62148ab8c82398498b1a01314476Linus Walleij	if (old_sel < 0 || new_sel < 0)
184888cd222b259d62148ab8c82398498b1a01314476Linus Walleij		return -EINVAL;
184988cd222b259d62148ab8c82398498b1a01314476Linus Walleij
185088cd222b259d62148ab8c82398498b1a01314476Linus Walleij	return ops->set_voltage_time_sel(rdev, old_sel, new_sel);
185188cd222b259d62148ab8c82398498b1a01314476Linus Walleij}
185288cd222b259d62148ab8c82398498b1a01314476Linus WalleijEXPORT_SYMBOL_GPL(regulator_set_voltage_time);
185388cd222b259d62148ab8c82398498b1a01314476Linus Walleij
185488cd222b259d62148ab8c82398498b1a01314476Linus Walleij/**
1855606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown * regulator_sync_voltage - re-apply last regulator output voltage
1856606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown * @regulator: regulator source
1857606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown *
1858606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown * Re-apply the last configured voltage.  This is intended to be used
1859606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown * where some external control source the consumer is cooperating with
1860606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown * has caused the configured voltage to change.
1861606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown */
1862606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brownint regulator_sync_voltage(struct regulator *regulator)
1863606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown{
1864606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown	struct regulator_dev *rdev = regulator->rdev;
1865606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown	int ret, min_uV, max_uV;
1866606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown
1867606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown	mutex_lock(&rdev->mutex);
1868606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown
1869606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown	if (!rdev->desc->ops->set_voltage &&
1870606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown	    !rdev->desc->ops->set_voltage_sel) {
1871606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown		ret = -EINVAL;
1872606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown		goto out;
1873606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown	}
1874606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown
1875606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown	/* This is only going to work if we've had a voltage configured. */
1876606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown	if (!regulator->min_uV && !regulator->max_uV) {
1877606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown		ret = -EINVAL;
1878606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown		goto out;
1879606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown	}
1880606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown
1881606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown	min_uV = regulator->min_uV;
1882606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown	max_uV = regulator->max_uV;
1883606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown
1884606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown	/* This should be a paranoia check... */
1885606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown	ret = regulator_check_voltage(rdev, &min_uV, &max_uV);
1886606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown	if (ret < 0)
1887606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown		goto out;
1888606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown
1889606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown	ret = regulator_check_consumers(rdev, &min_uV, &max_uV);
1890606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown	if (ret < 0)
1891606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown		goto out;
1892606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown
1893606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown	ret = _regulator_do_set_voltage(rdev, min_uV, max_uV);
1894606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown
1895606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brownout:
1896606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown	mutex_unlock(&rdev->mutex);
1897606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown	return ret;
1898606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown}
1899606a25628187ce863b48d43ca42bc0cbe8342de9Mark BrownEXPORT_SYMBOL_GPL(regulator_sync_voltage);
1900606a25628187ce863b48d43ca42bc0cbe8342de9Mark Brown
1901414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic int _regulator_get_voltage(struct regulator_dev *rdev)
1902414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1903bf5892a8167e4aa5a9a6d72f803fde850e0c5753Mark Brown	int sel, ret;
1904476c2d83c7ffb2429b2a504fbdb4326fc8a9d0e8Mark Brown
1905476c2d83c7ffb2429b2a504fbdb4326fc8a9d0e8Mark Brown	if (rdev->desc->ops->get_voltage_sel) {
1906476c2d83c7ffb2429b2a504fbdb4326fc8a9d0e8Mark Brown		sel = rdev->desc->ops->get_voltage_sel(rdev);
1907476c2d83c7ffb2429b2a504fbdb4326fc8a9d0e8Mark Brown		if (sel < 0)
1908476c2d83c7ffb2429b2a504fbdb4326fc8a9d0e8Mark Brown			return sel;
1909bf5892a8167e4aa5a9a6d72f803fde850e0c5753Mark Brown		ret = rdev->desc->ops->list_voltage(rdev, sel);
1910cb220d16f91f8d5fa1450c7af17e028e8cb3f0f1Axel Lin	} else if (rdev->desc->ops->get_voltage) {
1911bf5892a8167e4aa5a9a6d72f803fde850e0c5753Mark Brown		ret = rdev->desc->ops->get_voltage(rdev);
1912cb220d16f91f8d5fa1450c7af17e028e8cb3f0f1Axel Lin	} else {
1913414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -EINVAL;
1914cb220d16f91f8d5fa1450c7af17e028e8cb3f0f1Axel Lin	}
1915bf5892a8167e4aa5a9a6d72f803fde850e0c5753Mark Brown
1916cb220d16f91f8d5fa1450c7af17e028e8cb3f0f1Axel Lin	if (ret < 0)
1917cb220d16f91f8d5fa1450c7af17e028e8cb3f0f1Axel Lin		return ret;
1918bf5892a8167e4aa5a9a6d72f803fde850e0c5753Mark Brown	return ret - rdev->constraints->uV_offset;
1919414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1920414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1921414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
1922414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_get_voltage - get regulator output voltage
1923414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
1924414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1925414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * This returns the current regulator voltage in uV.
1926414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1927414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * NOTE: If the regulator is disabled it will return the voltage value. This
1928414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * function should not be used to determine regulator state.
1929414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1930414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_get_voltage(struct regulator *regulator)
1931414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1932414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret;
1933414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1934414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&regulator->rdev->mutex);
1935414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1936414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ret = _regulator_get_voltage(regulator->rdev);
1937414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1938414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&regulator->rdev->mutex);
1939414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1940414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
1941414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1942414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_get_voltage);
1943414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1944414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
1945414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_set_current_limit - set regulator output current limit
1946414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
1947414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @min_uA: Minimuum supported current in uA
1948414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @max_uA: Maximum supported current in uA
1949414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1950414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Sets current sink to the desired output current. This can be set during
1951414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * any regulator state. IOW, regulator can be disabled or enabled.
1952414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1953414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * If the regulator is enabled then the current will change to the new value
1954414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * immediately otherwise if the regulator is disabled the regulator will
1955414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * output at the new current when enabled.
1956414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1957414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * NOTE: Regulator system constraints must be set for this regulator before
1958414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * calling this function otherwise this call will fail.
1959414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1960414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_set_current_limit(struct regulator *regulator,
1961414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			       int min_uA, int max_uA)
1962414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1963414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator_dev *rdev = regulator->rdev;
1964414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret;
1965414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1966414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&rdev->mutex);
1967414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1968414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* sanity check */
1969414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->desc->ops->set_current_limit) {
1970414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		ret = -EINVAL;
1971414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		goto out;
1972414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
1973414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1974414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* constraints check */
1975414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ret = regulator_check_current_limit(rdev, &min_uA, &max_uA);
1976414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (ret < 0)
1977414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		goto out;
1978414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1979414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ret = rdev->desc->ops->set_current_limit(rdev, min_uA, max_uA);
1980414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodout:
1981414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&rdev->mutex);
1982414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
1983414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1984414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_set_current_limit);
1985414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1986414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic int _regulator_get_current_limit(struct regulator_dev *rdev)
1987414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1988414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret;
1989414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1990414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&rdev->mutex);
1991414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1992414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* sanity check */
1993414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->desc->ops->get_current_limit) {
1994414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		ret = -EINVAL;
1995414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		goto out;
1996414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
1997414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1998414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ret = rdev->desc->ops->get_current_limit(rdev);
1999414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodout:
2000414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&rdev->mutex);
2001414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
2002414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
2003414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2004414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
2005414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_get_current_limit - get regulator output current
2006414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
2007414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
2008414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * This returns the current supplied by the specified current sink in uA.
2009414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
2010414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * NOTE: If the regulator is disabled it will return the current value. This
2011414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * function should not be used to determine regulator state.
2012414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
2013414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_get_current_limit(struct regulator *regulator)
2014414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
2015414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return _regulator_get_current_limit(regulator->rdev);
2016414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
2017414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_get_current_limit);
2018414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2019414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
2020414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_set_mode - set regulator operating mode
2021414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
2022414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @mode: operating mode - one of the REGULATOR_MODE constants
2023414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
2024414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Set regulator operating mode to increase regulator efficiency or improve
2025414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulation performance.
2026414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
2027414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * NOTE: Regulator system constraints must be set for this regulator before
2028414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * calling this function otherwise this call will fail.
2029414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
2030414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_set_mode(struct regulator *regulator, unsigned int mode)
2031414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
2032414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator_dev *rdev = regulator->rdev;
2033414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret;
2034500b4ac90d1103a7c302d5bb16c53f4ffc45d057Sundar R Iyer	int regulator_curr_mode;
2035414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2036414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&rdev->mutex);
2037414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2038414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* sanity check */
2039414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->desc->ops->set_mode) {
2040414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		ret = -EINVAL;
2041414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		goto out;
2042414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
2043414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2044500b4ac90d1103a7c302d5bb16c53f4ffc45d057Sundar R Iyer	/* return if the same mode is requested */
2045500b4ac90d1103a7c302d5bb16c53f4ffc45d057Sundar R Iyer	if (rdev->desc->ops->get_mode) {
2046500b4ac90d1103a7c302d5bb16c53f4ffc45d057Sundar R Iyer		regulator_curr_mode = rdev->desc->ops->get_mode(rdev);
2047500b4ac90d1103a7c302d5bb16c53f4ffc45d057Sundar R Iyer		if (regulator_curr_mode == mode) {
2048500b4ac90d1103a7c302d5bb16c53f4ffc45d057Sundar R Iyer			ret = 0;
2049500b4ac90d1103a7c302d5bb16c53f4ffc45d057Sundar R Iyer			goto out;
2050500b4ac90d1103a7c302d5bb16c53f4ffc45d057Sundar R Iyer		}
2051500b4ac90d1103a7c302d5bb16c53f4ffc45d057Sundar R Iyer	}
2052500b4ac90d1103a7c302d5bb16c53f4ffc45d057Sundar R Iyer
2053414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* constraints check */
205422c51b47aa7cded7e4768540ebbbfddc91e31d90Axel Lin	ret = regulator_mode_constrain(rdev, &mode);
2055414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (ret < 0)
2056414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		goto out;
2057414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2058414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ret = rdev->desc->ops->set_mode(rdev, mode);
2059414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodout:
2060414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&rdev->mutex);
2061414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
2062414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
2063414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_set_mode);
2064414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2065414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic unsigned int _regulator_get_mode(struct regulator_dev *rdev)
2066414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
2067414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret;
2068414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2069414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&rdev->mutex);
2070414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2071414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* sanity check */
2072414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->desc->ops->get_mode) {
2073414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		ret = -EINVAL;
2074414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		goto out;
2075414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
2076414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2077414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ret = rdev->desc->ops->get_mode(rdev);
2078414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodout:
2079414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&rdev->mutex);
2080414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
2081414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
2082414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2083414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
2084414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_get_mode - get regulator operating mode
2085414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
2086414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
2087414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Get the current regulator operating mode.
2088414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
2089414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodunsigned int regulator_get_mode(struct regulator *regulator)
2090414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
2091414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return _regulator_get_mode(regulator->rdev);
2092414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
2093414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_get_mode);
2094414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2095414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
2096414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_set_optimum_mode - set regulator optimum operating mode
2097414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
2098414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @uA_load: load current
2099414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
2100414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Notifies the regulator core of a new device load. This is then used by
2101414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * DRMS (if enabled by constraints) to set the most efficient regulator
2102414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * operating mode for the new regulator loading.
2103414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
2104414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Consumer devices notify their supply regulator of the maximum power
2105414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * they will require (can be taken from device datasheet in the power
2106414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * consumption tables) when they change operational status and hence power
2107414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * state. Examples of operational state changes that can affect power
2108414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * consumption are :-
2109414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
2110414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *    o Device is opened / closed.
2111414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *    o Device I/O is about to begin or has just finished.
2112414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *    o Device is idling in between work.
2113414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
2114414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * This information is also exported via sysfs to userspace.
2115414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
2116414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * DRMS will sum the total requested load on the regulator and change
2117414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * to the most efficient operating mode if platform constraints allow.
2118414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
2119414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Returns the new regulator mode or error.
2120414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
2121414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_set_optimum_mode(struct regulator *regulator, int uA_load)
2122414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
2123414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator_dev *rdev = regulator->rdev;
2124414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator *consumer;
2125414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret, output_uV, input_uV, total_uA_load = 0;
2126414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	unsigned int mode;
2127414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2128414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&rdev->mutex);
2129414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2130a4b4148379ef1ad460fc1aa6bcf2cde99cd91166Mark Brown	/*
2131a4b4148379ef1ad460fc1aa6bcf2cde99cd91166Mark Brown	 * first check to see if we can set modes at all, otherwise just
2132a4b4148379ef1ad460fc1aa6bcf2cde99cd91166Mark Brown	 * tell the consumer everything is OK.
2133a4b4148379ef1ad460fc1aa6bcf2cde99cd91166Mark Brown	 */
2134414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	regulator->uA_load = uA_load;
2135414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ret = regulator_check_drms(rdev);
2136a4b4148379ef1ad460fc1aa6bcf2cde99cd91166Mark Brown	if (ret < 0) {
2137a4b4148379ef1ad460fc1aa6bcf2cde99cd91166Mark Brown		ret = 0;
2138414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		goto out;
2139a4b4148379ef1ad460fc1aa6bcf2cde99cd91166Mark Brown	}
2140414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2141414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->desc->ops->get_optimum_mode)
2142414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		goto out;
2143414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2144a4b4148379ef1ad460fc1aa6bcf2cde99cd91166Mark Brown	/*
2145a4b4148379ef1ad460fc1aa6bcf2cde99cd91166Mark Brown	 * we can actually do this so any errors are indicators of
2146a4b4148379ef1ad460fc1aa6bcf2cde99cd91166Mark Brown	 * potential real failure.
2147a4b4148379ef1ad460fc1aa6bcf2cde99cd91166Mark Brown	 */
2148a4b4148379ef1ad460fc1aa6bcf2cde99cd91166Mark Brown	ret = -EINVAL;
2149a4b4148379ef1ad460fc1aa6bcf2cde99cd91166Mark Brown
2150414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* get output voltage */
21511bf5a1f86a328122714680cd59951074b4f31e07Mark Brown	output_uV = _regulator_get_voltage(rdev);
2152414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (output_uV <= 0) {
21535da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches		rdev_err(rdev, "invalid output voltage found\n");
2154414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		goto out;
2155414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
2156414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2157414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* get input voltage */
21581bf5a1f86a328122714680cd59951074b4f31e07Mark Brown	input_uV = 0;
21591bf5a1f86a328122714680cd59951074b4f31e07Mark Brown	if (rdev->supply)
21603801b86aa482d26a8ae460f67fca29e016491a86Mark Brown		input_uV = regulator_get_voltage(rdev->supply);
21611bf5a1f86a328122714680cd59951074b4f31e07Mark Brown	if (input_uV <= 0)
2162414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		input_uV = rdev->constraints->input_uV;
2163414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (input_uV <= 0) {
21645da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches		rdev_err(rdev, "invalid input voltage found\n");
2165414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		goto out;
2166414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
2167414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2168414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* calc total requested load for this regulator */
2169414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	list_for_each_entry(consumer, &rdev->consumer_list, list)
2170fa2984d4691c96367d6666694ecc6744135174c6Stefan Roese		total_uA_load += consumer->uA_load;
2171414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2172414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mode = rdev->desc->ops->get_optimum_mode(rdev,
2173414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood						 input_uV, output_uV,
2174414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood						 total_uA_load);
21752c6082341d1896218ca974cc2bb6876e36fcba5cMark Brown	ret = regulator_mode_constrain(rdev, &mode);
2176e573520b171095c106ffbbbf4f9cbed6d9bff576David Brownell	if (ret < 0) {
21775da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches		rdev_err(rdev, "failed to get optimum mode @ %d uA %d -> %d uV\n",
21785da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches			 total_uA_load, input_uV, output_uV);
2179414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		goto out;
2180414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
2181414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2182414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ret = rdev->desc->ops->set_mode(rdev, mode);
2183e573520b171095c106ffbbbf4f9cbed6d9bff576David Brownell	if (ret < 0) {
21845da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches		rdev_err(rdev, "failed to set optimum mode %x\n", mode);
2185414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		goto out;
2186414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
2187414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ret = mode;
2188414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodout:
2189414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&rdev->mutex);
2190414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
2191414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
2192414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_set_optimum_mode);
2193414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2194414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
2195414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_register_notifier - register regulator event notifier
2196414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
219769279fb9a95051971ac03e558c4d46e7ba84ab3aMark Brown * @nb: notifier block
2198414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
2199414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Register notifier block to receive regulator events.
2200414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
2201414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_register_notifier(struct regulator *regulator,
2202414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			      struct notifier_block *nb)
2203414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
2204414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return blocking_notifier_chain_register(&regulator->rdev->notifier,
2205414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood						nb);
2206414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
2207414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_register_notifier);
2208414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2209414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
2210414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_unregister_notifier - unregister regulator event notifier
2211414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
221269279fb9a95051971ac03e558c4d46e7ba84ab3aMark Brown * @nb: notifier block
2213414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
2214414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Unregister regulator event notifier block.
2215414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
2216414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_unregister_notifier(struct regulator *regulator,
2217414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				struct notifier_block *nb)
2218414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
2219414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return blocking_notifier_chain_unregister(&regulator->rdev->notifier,
2220414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood						  nb);
2221414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
2222414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_unregister_notifier);
2223414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2224b136fb4463d13eea129bf090a8a465bba6bf0003Jonathan Cameron/* notify regulator consumers and downstream regulator consumers.
2225b136fb4463d13eea129bf090a8a465bba6bf0003Jonathan Cameron * Note mutex must be held by caller.
2226b136fb4463d13eea129bf090a8a465bba6bf0003Jonathan Cameron */
2227414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic void _notifier_call_chain(struct regulator_dev *rdev,
2228414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				  unsigned long event, void *data)
2229414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
2230414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* call rdev chain first */
2231414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	blocking_notifier_call_chain(&rdev->notifier, event, NULL);
2232414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
2233414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2234414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
2235414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_bulk_get - get multiple regulator consumers
2236414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
2237414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @dev:           Device to supply
2238414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @num_consumers: Number of consumers to register
2239414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @consumers:     Configuration of consumers; clients are stored here.
2240414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
2241414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @return 0 on success, an errno on failure.
2242414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
2243414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * This helper function allows drivers to get several regulator
2244414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * consumers in one operation.  If any of the regulators cannot be
2245414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * acquired then any regulators that were allocated will be freed
2246414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * before returning to the caller.
2247414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
2248414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_bulk_get(struct device *dev, int num_consumers,
2249414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		       struct regulator_bulk_data *consumers)
2250414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
2251414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int i;
2252414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret;
2253414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2254414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	for (i = 0; i < num_consumers; i++)
2255414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		consumers[i].consumer = NULL;
2256414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2257414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	for (i = 0; i < num_consumers; i++) {
2258414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		consumers[i].consumer = regulator_get(dev,
2259414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood						      consumers[i].supply);
2260414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (IS_ERR(consumers[i].consumer)) {
2261414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			ret = PTR_ERR(consumers[i].consumer);
22625b307627738f1f6cbc31fad9e28a299b5fe55602Mark Brown			dev_err(dev, "Failed to get supply '%s': %d\n",
22635b307627738f1f6cbc31fad9e28a299b5fe55602Mark Brown				consumers[i].supply, ret);
2264414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			consumers[i].consumer = NULL;
2265414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			goto err;
2266414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		}
2267414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
2268414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2269414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return 0;
2270414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2271414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwooderr:
2272414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	for (i = 0; i < num_consumers && consumers[i].consumer; i++)
2273414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator_put(consumers[i].consumer);
2274414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2275414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
2276414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
2277414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_bulk_get);
2278414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2279f21e0e81d81b649ad309cedc7226f1bed72982e0Mark Brownstatic void regulator_bulk_enable_async(void *data, async_cookie_t cookie)
2280f21e0e81d81b649ad309cedc7226f1bed72982e0Mark Brown{
2281f21e0e81d81b649ad309cedc7226f1bed72982e0Mark Brown	struct regulator_bulk_data *bulk = data;
2282f21e0e81d81b649ad309cedc7226f1bed72982e0Mark Brown
2283f21e0e81d81b649ad309cedc7226f1bed72982e0Mark Brown	bulk->ret = regulator_enable(bulk->consumer);
2284f21e0e81d81b649ad309cedc7226f1bed72982e0Mark Brown}
2285f21e0e81d81b649ad309cedc7226f1bed72982e0Mark Brown
2286414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
2287414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_bulk_enable - enable multiple regulator consumers
2288414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
2289414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @num_consumers: Number of consumers
2290414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @consumers:     Consumer data; clients are stored here.
2291414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @return         0 on success, an errno on failure
2292414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
2293414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * This convenience API allows consumers to enable multiple regulator
2294414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * clients in a single API call.  If any consumers cannot be enabled
2295414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * then any others that were enabled will be disabled again prior to
2296414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * return.
2297414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
2298414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_bulk_enable(int num_consumers,
2299414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			  struct regulator_bulk_data *consumers)
2300414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
2301f21e0e81d81b649ad309cedc7226f1bed72982e0Mark Brown	LIST_HEAD(async_domain);
2302414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int i;
2303f21e0e81d81b649ad309cedc7226f1bed72982e0Mark Brown	int ret = 0;
2304414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2305f21e0e81d81b649ad309cedc7226f1bed72982e0Mark Brown	for (i = 0; i < num_consumers; i++)
2306f21e0e81d81b649ad309cedc7226f1bed72982e0Mark Brown		async_schedule_domain(regulator_bulk_enable_async,
2307f21e0e81d81b649ad309cedc7226f1bed72982e0Mark Brown				      &consumers[i], &async_domain);
2308f21e0e81d81b649ad309cedc7226f1bed72982e0Mark Brown
2309f21e0e81d81b649ad309cedc7226f1bed72982e0Mark Brown	async_synchronize_full_domain(&async_domain);
2310f21e0e81d81b649ad309cedc7226f1bed72982e0Mark Brown
2311f21e0e81d81b649ad309cedc7226f1bed72982e0Mark Brown	/* If any consumer failed we need to unwind any that succeeded */
2312414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	for (i = 0; i < num_consumers; i++) {
2313f21e0e81d81b649ad309cedc7226f1bed72982e0Mark Brown		if (consumers[i].ret != 0) {
2314f21e0e81d81b649ad309cedc7226f1bed72982e0Mark Brown			ret = consumers[i].ret;
2315414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			goto err;
2316f21e0e81d81b649ad309cedc7226f1bed72982e0Mark Brown		}
2317414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
2318414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2319414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return 0;
2320414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2321414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwooderr:
2322f21e0e81d81b649ad309cedc7226f1bed72982e0Mark Brown	for (i = 0; i < num_consumers; i++)
2323f21e0e81d81b649ad309cedc7226f1bed72982e0Mark Brown		if (consumers[i].ret == 0)
2324f21e0e81d81b649ad309cedc7226f1bed72982e0Mark Brown			regulator_disable(consumers[i].consumer);
2325f21e0e81d81b649ad309cedc7226f1bed72982e0Mark Brown		else
2326f21e0e81d81b649ad309cedc7226f1bed72982e0Mark Brown			pr_err("Failed to enable %s: %d\n",
2327f21e0e81d81b649ad309cedc7226f1bed72982e0Mark Brown			       consumers[i].supply, consumers[i].ret);
2328414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2329414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
2330414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
2331414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_bulk_enable);
2332414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2333414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
2334414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_bulk_disable - disable multiple regulator consumers
2335414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
2336414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @num_consumers: Number of consumers
2337414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @consumers:     Consumer data; clients are stored here.
2338414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @return         0 on success, an errno on failure
2339414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
2340414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * This convenience API allows consumers to disable multiple regulator
2341414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * clients in a single API call.  If any consumers cannot be enabled
2342414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * then any others that were disabled will be disabled again prior to
2343414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * return.
2344414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
2345414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_bulk_disable(int num_consumers,
2346414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			   struct regulator_bulk_data *consumers)
2347414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
2348414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int i;
2349414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret;
2350414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2351414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	for (i = 0; i < num_consumers; i++) {
2352414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		ret = regulator_disable(consumers[i].consumer);
2353414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (ret != 0)
2354414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			goto err;
2355414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
2356414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2357414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return 0;
2358414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2359414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwooderr:
23605da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches	pr_err("Failed to disable %s: %d\n", consumers[i].supply, ret);
2361eb143ac1b9f56ca9c6dc782d795acda1f60c5fd2Lars-Peter Clausen	for (--i; i >= 0; --i)
2362414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator_enable(consumers[i].consumer);
2363414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2364414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
2365414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
2366414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_bulk_disable);
2367414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2368414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
2369414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_bulk_free - free multiple regulator consumers
2370414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
2371414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @num_consumers: Number of consumers
2372414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @consumers:     Consumer data; clients are stored here.
2373414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
2374414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * This convenience API allows consumers to free multiple regulator
2375414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * clients in a single API call.
2376414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
2377414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodvoid regulator_bulk_free(int num_consumers,
2378414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			 struct regulator_bulk_data *consumers)
2379414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
2380414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int i;
2381414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2382414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	for (i = 0; i < num_consumers; i++) {
2383414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator_put(consumers[i].consumer);
2384414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		consumers[i].consumer = NULL;
2385414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
2386414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
2387414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_bulk_free);
2388414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2389414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
2390414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_notifier_call_chain - call regulator event notifier
239169279fb9a95051971ac03e558c4d46e7ba84ab3aMark Brown * @rdev: regulator source
2392414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @event: notifier block
239369279fb9a95051971ac03e558c4d46e7ba84ab3aMark Brown * @data: callback-specific data.
2394414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
2395414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Called by regulator drivers to notify clients a regulator event has
2396414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * occurred. We also notify regulator clients downstream.
2397b136fb4463d13eea129bf090a8a465bba6bf0003Jonathan Cameron * Note lock must be held by caller.
2398414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
2399414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_notifier_call_chain(struct regulator_dev *rdev,
2400414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				  unsigned long event, void *data)
2401414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
2402414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	_notifier_call_chain(rdev, event, data);
2403414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return NOTIFY_DONE;
2404414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2405414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
2406414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_notifier_call_chain);
2407414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2408be721979dd6b335e4ab6f83abb5cc11c33662aa8Mark Brown/**
2409be721979dd6b335e4ab6f83abb5cc11c33662aa8Mark Brown * regulator_mode_to_status - convert a regulator mode into a status
2410be721979dd6b335e4ab6f83abb5cc11c33662aa8Mark Brown *
2411be721979dd6b335e4ab6f83abb5cc11c33662aa8Mark Brown * @mode: Mode to convert
2412be721979dd6b335e4ab6f83abb5cc11c33662aa8Mark Brown *
2413be721979dd6b335e4ab6f83abb5cc11c33662aa8Mark Brown * Convert a regulator mode into a status.
2414be721979dd6b335e4ab6f83abb5cc11c33662aa8Mark Brown */
2415be721979dd6b335e4ab6f83abb5cc11c33662aa8Mark Brownint regulator_mode_to_status(unsigned int mode)
2416be721979dd6b335e4ab6f83abb5cc11c33662aa8Mark Brown{
2417be721979dd6b335e4ab6f83abb5cc11c33662aa8Mark Brown	switch (mode) {
2418be721979dd6b335e4ab6f83abb5cc11c33662aa8Mark Brown	case REGULATOR_MODE_FAST:
2419be721979dd6b335e4ab6f83abb5cc11c33662aa8Mark Brown		return REGULATOR_STATUS_FAST;
2420be721979dd6b335e4ab6f83abb5cc11c33662aa8Mark Brown	case REGULATOR_MODE_NORMAL:
2421be721979dd6b335e4ab6f83abb5cc11c33662aa8Mark Brown		return REGULATOR_STATUS_NORMAL;
2422be721979dd6b335e4ab6f83abb5cc11c33662aa8Mark Brown	case REGULATOR_MODE_IDLE:
2423be721979dd6b335e4ab6f83abb5cc11c33662aa8Mark Brown		return REGULATOR_STATUS_IDLE;
2424be721979dd6b335e4ab6f83abb5cc11c33662aa8Mark Brown	case REGULATOR_STATUS_STANDBY:
2425be721979dd6b335e4ab6f83abb5cc11c33662aa8Mark Brown		return REGULATOR_STATUS_STANDBY;
2426be721979dd6b335e4ab6f83abb5cc11c33662aa8Mark Brown	default:
2427be721979dd6b335e4ab6f83abb5cc11c33662aa8Mark Brown		return 0;
2428be721979dd6b335e4ab6f83abb5cc11c33662aa8Mark Brown	}
2429be721979dd6b335e4ab6f83abb5cc11c33662aa8Mark Brown}
2430be721979dd6b335e4ab6f83abb5cc11c33662aa8Mark BrownEXPORT_SYMBOL_GPL(regulator_mode_to_status);
2431be721979dd6b335e4ab6f83abb5cc11c33662aa8Mark Brown
24327ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell/*
24337ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell * To avoid cluttering sysfs (and memory) with useless state, only
24347ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell * create attributes that can be meaningfully displayed.
24357ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell */
24367ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownellstatic int add_regulator_attributes(struct regulator_dev *rdev)
24377ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell{
24387ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	struct device		*dev = &rdev->dev;
24397ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	struct regulator_ops	*ops = rdev->desc->ops;
24407ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	int			status = 0;
24417ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell
24427ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	/* some attributes need specific methods to be displayed */
2443476c2d83c7ffb2429b2a504fbdb4326fc8a9d0e8Mark Brown	if (ops->get_voltage || ops->get_voltage_sel) {
24447ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		status = device_create_file(dev, &dev_attr_microvolts);
24457ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		if (status < 0)
24467ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell			return status;
24477ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	}
24487ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	if (ops->get_current_limit) {
24497ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		status = device_create_file(dev, &dev_attr_microamps);
24507ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		if (status < 0)
24517ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell			return status;
24527ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	}
24537ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	if (ops->get_mode) {
24547ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		status = device_create_file(dev, &dev_attr_opmode);
24557ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		if (status < 0)
24567ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell			return status;
24577ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	}
24587ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	if (ops->is_enabled) {
24597ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		status = device_create_file(dev, &dev_attr_state);
24607ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		if (status < 0)
24617ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell			return status;
24627ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	}
2463853116a10544206b6b2cf42ebc9d78fba2668888David Brownell	if (ops->get_status) {
2464853116a10544206b6b2cf42ebc9d78fba2668888David Brownell		status = device_create_file(dev, &dev_attr_status);
2465853116a10544206b6b2cf42ebc9d78fba2668888David Brownell		if (status < 0)
2466853116a10544206b6b2cf42ebc9d78fba2668888David Brownell			return status;
2467853116a10544206b6b2cf42ebc9d78fba2668888David Brownell	}
24687ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell
24697ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	/* some attributes are type-specific */
24707ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	if (rdev->desc->type == REGULATOR_CURRENT) {
24717ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		status = device_create_file(dev, &dev_attr_requested_microamps);
24727ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		if (status < 0)
24737ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell			return status;
24747ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	}
24757ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell
24767ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	/* all the other attributes exist to support constraints;
24777ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	 * don't show them if there are no constraints, or if the
24787ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	 * relevant supporting methods are missing.
24797ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	 */
24807ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	if (!rdev->constraints)
24817ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		return status;
24827ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell
24837ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	/* constraints need specific supporting methods */
2484e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown	if (ops->set_voltage || ops->set_voltage_sel) {
24857ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		status = device_create_file(dev, &dev_attr_min_microvolts);
24867ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		if (status < 0)
24877ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell			return status;
24887ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		status = device_create_file(dev, &dev_attr_max_microvolts);
24897ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		if (status < 0)
24907ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell			return status;
24917ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	}
24927ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	if (ops->set_current_limit) {
24937ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		status = device_create_file(dev, &dev_attr_min_microamps);
24947ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		if (status < 0)
24957ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell			return status;
24967ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		status = device_create_file(dev, &dev_attr_max_microamps);
24977ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		if (status < 0)
24987ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell			return status;
24997ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	}
25007ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell
25017ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	/* suspend mode constraints need multiple supporting methods */
25027ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	if (!(ops->set_suspend_enable && ops->set_suspend_disable))
25037ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		return status;
25047ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell
25057ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	status = device_create_file(dev, &dev_attr_suspend_standby_state);
25067ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	if (status < 0)
25077ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		return status;
25087ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	status = device_create_file(dev, &dev_attr_suspend_mem_state);
25097ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	if (status < 0)
25107ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		return status;
25117ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	status = device_create_file(dev, &dev_attr_suspend_disk_state);
25127ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	if (status < 0)
25137ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		return status;
25147ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell
25157ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	if (ops->set_suspend_voltage) {
25167ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		status = device_create_file(dev,
25177ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell				&dev_attr_suspend_standby_microvolts);
25187ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		if (status < 0)
25197ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell			return status;
25207ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		status = device_create_file(dev,
25217ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell				&dev_attr_suspend_mem_microvolts);
25227ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		if (status < 0)
25237ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell			return status;
25247ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		status = device_create_file(dev,
25257ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell				&dev_attr_suspend_disk_microvolts);
25267ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		if (status < 0)
25277ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell			return status;
25287ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	}
25297ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell
25307ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	if (ops->set_suspend_mode) {
25317ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		status = device_create_file(dev,
25327ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell				&dev_attr_suspend_standby_mode);
25337ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		if (status < 0)
25347ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell			return status;
25357ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		status = device_create_file(dev,
25367ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell				&dev_attr_suspend_mem_mode);
25377ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		if (status < 0)
25387ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell			return status;
25397ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		status = device_create_file(dev,
25407ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell				&dev_attr_suspend_disk_mode);
25417ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		if (status < 0)
25427ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell			return status;
25437ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	}
25447ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell
25457ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	return status;
25467ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell}
25477ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell
25481130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brownstatic void rdev_init_debugfs(struct regulator_dev *rdev)
25491130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown{
25501130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown#ifdef CONFIG_DEBUG_FS
25511130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown	rdev->debugfs = debugfs_create_dir(rdev_get_name(rdev), debugfs_root);
25521130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown	if (IS_ERR(rdev->debugfs) || !rdev->debugfs) {
25531130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown		rdev_warn(rdev, "Failed to create debugfs directory\n");
25541130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown		rdev->debugfs = NULL;
25551130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown		return;
25561130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown	}
25571130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown
25581130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown	debugfs_create_u32("use_count", 0444, rdev->debugfs,
25591130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown			   &rdev->use_count);
25601130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown	debugfs_create_u32("open_count", 0444, rdev->debugfs,
25611130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown			   &rdev->open_count);
25621130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown#endif
25631130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown}
25641130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown
2565414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
2566414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_register - register regulator
256769279fb9a95051971ac03e558c4d46e7ba84ab3aMark Brown * @regulator_desc: regulator to register
256869279fb9a95051971ac03e558c4d46e7ba84ab3aMark Brown * @dev: struct device for the regulator
25690527100fd11d9710c7e153d791da78824b7b46faMark Brown * @init_data: platform provided init data, passed through by driver
257069279fb9a95051971ac03e558c4d46e7ba84ab3aMark Brown * @driver_data: private regulator data
2571414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
2572414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Called by regulator drivers to register a regulator.
2573414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Returns 0 on success.
2574414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
2575414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstruct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
2576f8c12fe329c8da9f50d8b2b1183eeaa4d587e747Mark Brown	struct device *dev, const struct regulator_init_data *init_data,
25770527100fd11d9710c7e153d791da78824b7b46faMark Brown	void *driver_data)
2578414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
2579414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	static atomic_t regulator_no = ATOMIC_INIT(0);
2580414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator_dev *rdev;
2581a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	int ret, i;
2582414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2583414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (regulator_desc == NULL)
2584414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return ERR_PTR(-EINVAL);
2585414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2586414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (regulator_desc->name == NULL || regulator_desc->ops == NULL)
2587414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return ERR_PTR(-EINVAL);
2588414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2589cd78dfc6c6e321a310a73ef7b0df3d262704dd55Diego Liziero	if (regulator_desc->type != REGULATOR_VOLTAGE &&
2590cd78dfc6c6e321a310a73ef7b0df3d262704dd55Diego Liziero	    regulator_desc->type != REGULATOR_CURRENT)
2591414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return ERR_PTR(-EINVAL);
2592414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
259346fabe1edd44a8893d88d7982f88d01ccf77f0bbMark Brown	if (!init_data)
259446fabe1edd44a8893d88d7982f88d01ccf77f0bbMark Brown		return ERR_PTR(-EINVAL);
259546fabe1edd44a8893d88d7982f88d01ccf77f0bbMark Brown
2596476c2d83c7ffb2429b2a504fbdb4326fc8a9d0e8Mark Brown	/* Only one of each should be implemented */
2597476c2d83c7ffb2429b2a504fbdb4326fc8a9d0e8Mark Brown	WARN_ON(regulator_desc->ops->get_voltage &&
2598476c2d83c7ffb2429b2a504fbdb4326fc8a9d0e8Mark Brown		regulator_desc->ops->get_voltage_sel);
2599e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown	WARN_ON(regulator_desc->ops->set_voltage &&
2600e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown		regulator_desc->ops->set_voltage_sel);
2601476c2d83c7ffb2429b2a504fbdb4326fc8a9d0e8Mark Brown
2602476c2d83c7ffb2429b2a504fbdb4326fc8a9d0e8Mark Brown	/* If we're using selectors we must implement list_voltage. */
2603476c2d83c7ffb2429b2a504fbdb4326fc8a9d0e8Mark Brown	if (regulator_desc->ops->get_voltage_sel &&
2604476c2d83c7ffb2429b2a504fbdb4326fc8a9d0e8Mark Brown	    !regulator_desc->ops->list_voltage) {
2605476c2d83c7ffb2429b2a504fbdb4326fc8a9d0e8Mark Brown		return ERR_PTR(-EINVAL);
2606476c2d83c7ffb2429b2a504fbdb4326fc8a9d0e8Mark Brown	}
2607e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown	if (regulator_desc->ops->set_voltage_sel &&
2608e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown	    !regulator_desc->ops->list_voltage) {
2609e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown		return ERR_PTR(-EINVAL);
2610e8eef82b2c652d031bee9dff9762325672f5a1e0Mark Brown	}
2611476c2d83c7ffb2429b2a504fbdb4326fc8a9d0e8Mark Brown
2612414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	rdev = kzalloc(sizeof(struct regulator_dev), GFP_KERNEL);
2613414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (rdev == NULL)
2614414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return ERR_PTR(-ENOMEM);
2615414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2616414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&regulator_list_mutex);
2617414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2618414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_init(&rdev->mutex);
2619a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	rdev->reg_data = driver_data;
2620414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	rdev->owner = regulator_desc->owner;
2621414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	rdev->desc = regulator_desc;
2622414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	INIT_LIST_HEAD(&rdev->consumer_list);
2623414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	INIT_LIST_HEAD(&rdev->list);
2624414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier);
2625414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2626a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	/* preform any regulator specific init */
2627a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	if (init_data->regulator_init) {
2628a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		ret = init_data->regulator_init(rdev->reg_data);
26294fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell		if (ret < 0)
26304fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell			goto clean;
2631a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	}
2632a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
2633a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	/* register with sysfs */
2634414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	rdev->dev.class = &regulator_class;
2635a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	rdev->dev.parent = dev;
2636812460a927c1d0dc1fbdbec9aa07de1b04043d83Kay Sievers	dev_set_name(&rdev->dev, "regulator.%d",
2637812460a927c1d0dc1fbdbec9aa07de1b04043d83Kay Sievers		     atomic_inc_return(&regulator_no) - 1);
2638a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	ret = device_register(&rdev->dev);
2639ad7725cb43b8badb2fec2c2bfca07c067f2e19a7Vasiliy Kulikov	if (ret != 0) {
2640ad7725cb43b8badb2fec2c2bfca07c067f2e19a7Vasiliy Kulikov		put_device(&rdev->dev);
26414fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell		goto clean;
2642ad7725cb43b8badb2fec2c2bfca07c067f2e19a7Vasiliy Kulikov	}
2643a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
2644a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	dev_set_drvdata(&rdev->dev, rdev);
2645a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
264674f544c1fc0339acf6f66ff438b8543b1f9faf10Mike Rapoport	/* set regulator constraints */
264774f544c1fc0339acf6f66ff438b8543b1f9faf10Mike Rapoport	ret = set_machine_constraints(rdev, &init_data->constraints);
264874f544c1fc0339acf6f66ff438b8543b1f9faf10Mike Rapoport	if (ret < 0)
264974f544c1fc0339acf6f66ff438b8543b1f9faf10Mike Rapoport		goto scrub;
265074f544c1fc0339acf6f66ff438b8543b1f9faf10Mike Rapoport
26517ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	/* add attributes supported by this regulator */
26527ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	ret = add_regulator_attributes(rdev);
26537ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell	if (ret < 0)
26547ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell		goto scrub;
26557ad68e2f970fd84d15ad67ce3216aed05f944a9cDavid Brownell
26560178f3e28e2166664916265c5d4922b1376b9fa1Mark Brown	if (init_data->supply_regulator) {
26570178f3e28e2166664916265c5d4922b1376b9fa1Mark Brown		struct regulator_dev *r;
26580178f3e28e2166664916265c5d4922b1376b9fa1Mark Brown		int found = 0;
26590178f3e28e2166664916265c5d4922b1376b9fa1Mark Brown
26600178f3e28e2166664916265c5d4922b1376b9fa1Mark Brown		list_for_each_entry(r, &regulator_list, list) {
26610178f3e28e2166664916265c5d4922b1376b9fa1Mark Brown			if (strcmp(rdev_get_name(r),
26620178f3e28e2166664916265c5d4922b1376b9fa1Mark Brown				   init_data->supply_regulator) == 0) {
26630178f3e28e2166664916265c5d4922b1376b9fa1Mark Brown				found = 1;
26640178f3e28e2166664916265c5d4922b1376b9fa1Mark Brown				break;
26650178f3e28e2166664916265c5d4922b1376b9fa1Mark Brown			}
26660178f3e28e2166664916265c5d4922b1376b9fa1Mark Brown		}
26670178f3e28e2166664916265c5d4922b1376b9fa1Mark Brown
26680178f3e28e2166664916265c5d4922b1376b9fa1Mark Brown		if (!found) {
26690178f3e28e2166664916265c5d4922b1376b9fa1Mark Brown			dev_err(dev, "Failed to find supply %s\n",
26700178f3e28e2166664916265c5d4922b1376b9fa1Mark Brown				init_data->supply_regulator);
26717727da22e820a96ab394db2fc0ab58f7f7ecb323Axel Lin			ret = -ENODEV;
26720178f3e28e2166664916265c5d4922b1376b9fa1Mark Brown			goto scrub;
26730178f3e28e2166664916265c5d4922b1376b9fa1Mark Brown		}
26740178f3e28e2166664916265c5d4922b1376b9fa1Mark Brown
26750178f3e28e2166664916265c5d4922b1376b9fa1Mark Brown		ret = set_supply(rdev, r);
26760178f3e28e2166664916265c5d4922b1376b9fa1Mark Brown		if (ret < 0)
26770178f3e28e2166664916265c5d4922b1376b9fa1Mark Brown			goto scrub;
26780178f3e28e2166664916265c5d4922b1376b9fa1Mark Brown	}
26790178f3e28e2166664916265c5d4922b1376b9fa1Mark Brown
2680a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	/* add consumers devices */
2681a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	for (i = 0; i < init_data->num_consumer_supplies; i++) {
2682a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		ret = set_consumer_device_supply(rdev,
2683a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood			init_data->consumer_supplies[i].dev,
268440f9244f4da8976eeb6d5ed6313c635ba238a9d3Mark Brown			init_data->consumer_supplies[i].dev_name,
2685a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood			init_data->consumer_supplies[i].supply);
268623c2f041efa891e6ec0706dc9ad4f776a9aa8c14Mark Brown		if (ret < 0) {
268723c2f041efa891e6ec0706dc9ad4f776a9aa8c14Mark Brown			dev_err(dev, "Failed to set supply %s\n",
268823c2f041efa891e6ec0706dc9ad4f776a9aa8c14Mark Brown				init_data->consumer_supplies[i].supply);
2689d4033b54fc91221b13e2850bf298683c0f2ff37dJani Nikula			goto unset_supplies;
269023c2f041efa891e6ec0706dc9ad4f776a9aa8c14Mark Brown		}
2691414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
2692a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
2693a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	list_add(&rdev->list, &regulator_list);
26941130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown
26951130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown	rdev_init_debugfs(rdev);
2696a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwoodout:
2697414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&regulator_list_mutex);
2698414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return rdev;
26994fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell
2700d4033b54fc91221b13e2850bf298683c0f2ff37dJani Nikulaunset_supplies:
2701d4033b54fc91221b13e2850bf298683c0f2ff37dJani Nikula	unset_regulator_supplies(rdev);
2702d4033b54fc91221b13e2850bf298683c0f2ff37dJani Nikula
27034fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownellscrub:
27044fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell	device_unregister(&rdev->dev);
270553032dafc6b93ac178ca2340ff8eb4ee2b3d1a92Paul Walmsley	/* device core frees rdev */
270653032dafc6b93ac178ca2340ff8eb4ee2b3d1a92Paul Walmsley	rdev = ERR_PTR(ret);
270753032dafc6b93ac178ca2340ff8eb4ee2b3d1a92Paul Walmsley	goto out;
270853032dafc6b93ac178ca2340ff8eb4ee2b3d1a92Paul Walmsley
27094fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownellclean:
27104fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell	kfree(rdev);
27114fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell	rdev = ERR_PTR(ret);
27124fca9545d17b99cdb2774716b034c62a70151bcdDavid Brownell	goto out;
2713414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
2714414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_register);
2715414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2716414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
2717414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_unregister - unregister regulator
271869279fb9a95051971ac03e558c4d46e7ba84ab3aMark Brown * @rdev: regulator to unregister
2719414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
2720414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Called by regulator drivers to unregister a regulator.
2721414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
2722414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodvoid regulator_unregister(struct regulator_dev *rdev)
2723414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
2724414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (rdev == NULL)
2725414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return;
2726414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2727414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&regulator_list_mutex);
27281130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown#ifdef CONFIG_DEBUG_FS
27291130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown	debugfs_remove_recursive(rdev->debugfs);
27301130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown#endif
27316bf87d17c9f5b855e9dde7b3d6f726385b966814Mark Brown	WARN_ON(rdev->open_count);
27320f1d747bfa89de4ca52dc1dffdcce35a2b8a1532Mike Rapoport	unset_regulator_supplies(rdev);
2733414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	list_del(&rdev->list);
2734414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (rdev->supply)
27353801b86aa482d26a8ae460f67fca29e016491a86Mark Brown		regulator_put(rdev->supply);
2736414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	device_unregister(&rdev->dev);
2737f8c12fe329c8da9f50d8b2b1183eeaa4d587e747Mark Brown	kfree(rdev->constraints);
2738414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&regulator_list_mutex);
2739414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
2740414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_unregister);
2741414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2742414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
2743cf7bbcdf4d267eff580cb7ce6cf4fe16a940a005Mark Brown * regulator_suspend_prepare - prepare regulators for system wide suspend
2744414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @state: system suspend state
2745414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
2746414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Configure each regulator with it's suspend operating parameters for state.
2747414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * This will usually be called by machine suspend code prior to supending.
2748414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
2749414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_suspend_prepare(suspend_state_t state)
2750414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
2751414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator_dev *rdev;
2752414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret = 0;
2753414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2754414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* ON is handled by regulator active state */
2755414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (state == PM_SUSPEND_ON)
2756414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -EINVAL;
2757414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2758414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&regulator_list_mutex);
2759414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	list_for_each_entry(rdev, &regulator_list, list) {
2760414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2761414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		mutex_lock(&rdev->mutex);
2762414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		ret = suspend_prepare(rdev, state);
2763414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		mutex_unlock(&rdev->mutex);
2764414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2765414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (ret < 0) {
27665da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches			rdev_err(rdev, "failed to prepare\n");
2767414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			goto out;
2768414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		}
2769414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
2770414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodout:
2771414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&regulator_list_mutex);
2772414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
2773414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
2774414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_suspend_prepare);
2775414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2776414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
27777a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham * regulator_suspend_finish - resume regulators from system wide suspend
27787a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham *
27797a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham * Turn on regulators that might be turned off by regulator_suspend_prepare
27807a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham * and that should be turned on according to the regulators properties.
27817a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham */
27827a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Hamint regulator_suspend_finish(void)
27837a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham{
27847a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham	struct regulator_dev *rdev;
27857a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham	int ret = 0, error;
27867a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham
27877a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham	mutex_lock(&regulator_list_mutex);
27887a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham	list_for_each_entry(rdev, &regulator_list, list) {
27897a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham		struct regulator_ops *ops = rdev->desc->ops;
27907a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham
27917a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham		mutex_lock(&rdev->mutex);
27927a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham		if ((rdev->use_count > 0  || rdev->constraints->always_on) &&
27937a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham				ops->enable) {
27947a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham			error = ops->enable(rdev);
27957a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham			if (error)
27967a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham				ret = error;
27977a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham		} else {
27987a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham			if (!has_full_constraints)
27997a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham				goto unlock;
28007a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham			if (!ops->disable)
28017a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham				goto unlock;
28027a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham			if (ops->is_enabled && !ops->is_enabled(rdev))
28037a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham				goto unlock;
28047a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham
28057a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham			error = ops->disable(rdev);
28067a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham			if (error)
28077a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham				ret = error;
28087a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham		}
28097a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Hamunlock:
28107a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham		mutex_unlock(&rdev->mutex);
28117a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham	}
28127a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham	mutex_unlock(&regulator_list_mutex);
28137a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham	return ret;
28147a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham}
28157a32b589a9c856493bccb02db55047edc04eee7bMyungJoo HamEXPORT_SYMBOL_GPL(regulator_suspend_finish);
28167a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham
28177a32b589a9c856493bccb02db55047edc04eee7bMyungJoo Ham/**
2818ca7255614e0861e36480103f4a402a115803d7b5Mark Brown * regulator_has_full_constraints - the system has fully specified constraints
2819ca7255614e0861e36480103f4a402a115803d7b5Mark Brown *
2820ca7255614e0861e36480103f4a402a115803d7b5Mark Brown * Calling this function will cause the regulator API to disable all
2821ca7255614e0861e36480103f4a402a115803d7b5Mark Brown * regulators which have a zero use count and don't have an always_on
2822ca7255614e0861e36480103f4a402a115803d7b5Mark Brown * constraint in a late_initcall.
2823ca7255614e0861e36480103f4a402a115803d7b5Mark Brown *
2824ca7255614e0861e36480103f4a402a115803d7b5Mark Brown * The intention is that this will become the default behaviour in a
2825ca7255614e0861e36480103f4a402a115803d7b5Mark Brown * future kernel release so users are encouraged to use this facility
2826ca7255614e0861e36480103f4a402a115803d7b5Mark Brown * now.
2827ca7255614e0861e36480103f4a402a115803d7b5Mark Brown */
2828ca7255614e0861e36480103f4a402a115803d7b5Mark Brownvoid regulator_has_full_constraints(void)
2829ca7255614e0861e36480103f4a402a115803d7b5Mark Brown{
2830ca7255614e0861e36480103f4a402a115803d7b5Mark Brown	has_full_constraints = 1;
2831ca7255614e0861e36480103f4a402a115803d7b5Mark Brown}
2832ca7255614e0861e36480103f4a402a115803d7b5Mark BrownEXPORT_SYMBOL_GPL(regulator_has_full_constraints);
2833ca7255614e0861e36480103f4a402a115803d7b5Mark Brown
2834ca7255614e0861e36480103f4a402a115803d7b5Mark Brown/**
2835688fe99a439f7c9dfcc52fbf7cb347f140a2dc8bMark Brown * regulator_use_dummy_regulator - Provide a dummy regulator when none is found
2836688fe99a439f7c9dfcc52fbf7cb347f140a2dc8bMark Brown *
2837688fe99a439f7c9dfcc52fbf7cb347f140a2dc8bMark Brown * Calling this function will cause the regulator API to provide a
2838688fe99a439f7c9dfcc52fbf7cb347f140a2dc8bMark Brown * dummy regulator to consumers if no physical regulator is found,
2839688fe99a439f7c9dfcc52fbf7cb347f140a2dc8bMark Brown * allowing most consumers to proceed as though a regulator were
2840688fe99a439f7c9dfcc52fbf7cb347f140a2dc8bMark Brown * configured.  This allows systems such as those with software
2841688fe99a439f7c9dfcc52fbf7cb347f140a2dc8bMark Brown * controllable regulators for the CPU core only to be brought up more
2842688fe99a439f7c9dfcc52fbf7cb347f140a2dc8bMark Brown * readily.
2843688fe99a439f7c9dfcc52fbf7cb347f140a2dc8bMark Brown */
2844688fe99a439f7c9dfcc52fbf7cb347f140a2dc8bMark Brownvoid regulator_use_dummy_regulator(void)
2845688fe99a439f7c9dfcc52fbf7cb347f140a2dc8bMark Brown{
2846688fe99a439f7c9dfcc52fbf7cb347f140a2dc8bMark Brown	board_wants_dummy_regulator = true;
2847688fe99a439f7c9dfcc52fbf7cb347f140a2dc8bMark Brown}
2848688fe99a439f7c9dfcc52fbf7cb347f140a2dc8bMark BrownEXPORT_SYMBOL_GPL(regulator_use_dummy_regulator);
2849688fe99a439f7c9dfcc52fbf7cb347f140a2dc8bMark Brown
2850688fe99a439f7c9dfcc52fbf7cb347f140a2dc8bMark Brown/**
2851414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * rdev_get_drvdata - get rdev regulator driver data
285269279fb9a95051971ac03e558c4d46e7ba84ab3aMark Brown * @rdev: regulator
2853414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
2854414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Get rdev regulator driver private data. This call can be used in the
2855414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator driver context.
2856414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
2857414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodvoid *rdev_get_drvdata(struct regulator_dev *rdev)
2858414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
2859414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return rdev->reg_data;
2860414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
2861414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(rdev_get_drvdata);
2862414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2863414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
2864414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_get_drvdata - get regulator driver data
2865414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator
2866414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
2867414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Get regulator driver private data. This call can be used in the consumer
2868414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * driver context when non API regulator specific functions need to be called.
2869414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
2870414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodvoid *regulator_get_drvdata(struct regulator *regulator)
2871414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
2872414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return regulator->rdev->reg_data;
2873414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
2874414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_get_drvdata);
2875414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2876414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
2877414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_set_drvdata - set regulator driver data
2878414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator
2879414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @data: data
2880414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
2881414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodvoid regulator_set_drvdata(struct regulator *regulator, void *data)
2882414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
2883414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	regulator->rdev->reg_data = data;
2884414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
2885414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_set_drvdata);
2886414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2887414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
2888414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_get_id - get regulator ID
288969279fb9a95051971ac03e558c4d46e7ba84ab3aMark Brown * @rdev: regulator
2890414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
2891414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint rdev_get_id(struct regulator_dev *rdev)
2892414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
2893414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return rdev->desc->id;
2894414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
2895414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(rdev_get_id);
2896414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2897a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwoodstruct device *rdev_get_dev(struct regulator_dev *rdev)
2898a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood{
2899a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	return &rdev->dev;
2900a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood}
2901a5766f11cfd3a0c03450d99c8fe548c2940be884Liam GirdwoodEXPORT_SYMBOL_GPL(rdev_get_dev);
2902a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
2903a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwoodvoid *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data)
2904a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood{
2905a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	return reg_init_data->driver_data;
2906a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood}
2907a5766f11cfd3a0c03450d99c8fe548c2940be884Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_get_init_drvdata);
2908a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
2909414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic int __init regulator_init(void)
2910414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
291134abbd68efe09765465b81dfedeee9994f13302fMark Brown	int ret;
291234abbd68efe09765465b81dfedeee9994f13302fMark Brown
291334abbd68efe09765465b81dfedeee9994f13302fMark Brown	ret = class_register(&regulator_class);
291434abbd68efe09765465b81dfedeee9994f13302fMark Brown
29151130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown#ifdef CONFIG_DEBUG_FS
29161130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown	debugfs_root = debugfs_create_dir("regulator", NULL);
29171130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown	if (IS_ERR(debugfs_root) || !debugfs_root) {
29181130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown		pr_warn("regulator: Failed to create debugfs directory\n");
29191130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown		debugfs_root = NULL;
29201130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown	}
29211130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown#endif
29221130e5b3ff4a7f3f54a48d46e9d0d81b47765bd8Mark Brown
292334abbd68efe09765465b81dfedeee9994f13302fMark Brown	regulator_dummy_init();
292434abbd68efe09765465b81dfedeee9994f13302fMark Brown
292534abbd68efe09765465b81dfedeee9994f13302fMark Brown	return ret;
2926414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
2927414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
2928414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/* init early to allow our consumers to complete system booting */
2929414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodcore_initcall(regulator_init);
2930ca7255614e0861e36480103f4a402a115803d7b5Mark Brown
2931ca7255614e0861e36480103f4a402a115803d7b5Mark Brownstatic int __init regulator_init_complete(void)
2932ca7255614e0861e36480103f4a402a115803d7b5Mark Brown{
2933ca7255614e0861e36480103f4a402a115803d7b5Mark Brown	struct regulator_dev *rdev;
2934ca7255614e0861e36480103f4a402a115803d7b5Mark Brown	struct regulator_ops *ops;
2935ca7255614e0861e36480103f4a402a115803d7b5Mark Brown	struct regulation_constraints *c;
2936ca7255614e0861e36480103f4a402a115803d7b5Mark Brown	int enabled, ret;
2937ca7255614e0861e36480103f4a402a115803d7b5Mark Brown
2938ca7255614e0861e36480103f4a402a115803d7b5Mark Brown	mutex_lock(&regulator_list_mutex);
2939ca7255614e0861e36480103f4a402a115803d7b5Mark Brown
2940ca7255614e0861e36480103f4a402a115803d7b5Mark Brown	/* If we have a full configuration then disable any regulators
2941ca7255614e0861e36480103f4a402a115803d7b5Mark Brown	 * which are not in use or always_on.  This will become the
2942ca7255614e0861e36480103f4a402a115803d7b5Mark Brown	 * default behaviour in the future.
2943ca7255614e0861e36480103f4a402a115803d7b5Mark Brown	 */
2944ca7255614e0861e36480103f4a402a115803d7b5Mark Brown	list_for_each_entry(rdev, &regulator_list, list) {
2945ca7255614e0861e36480103f4a402a115803d7b5Mark Brown		ops = rdev->desc->ops;
2946ca7255614e0861e36480103f4a402a115803d7b5Mark Brown		c = rdev->constraints;
2947ca7255614e0861e36480103f4a402a115803d7b5Mark Brown
2948f25e0b4fcc38d120e704c377791158c4b2a54daaMark Brown		if (!ops->disable || (c && c->always_on))
2949ca7255614e0861e36480103f4a402a115803d7b5Mark Brown			continue;
2950ca7255614e0861e36480103f4a402a115803d7b5Mark Brown
2951ca7255614e0861e36480103f4a402a115803d7b5Mark Brown		mutex_lock(&rdev->mutex);
2952ca7255614e0861e36480103f4a402a115803d7b5Mark Brown
2953ca7255614e0861e36480103f4a402a115803d7b5Mark Brown		if (rdev->use_count)
2954ca7255614e0861e36480103f4a402a115803d7b5Mark Brown			goto unlock;
2955ca7255614e0861e36480103f4a402a115803d7b5Mark Brown
2956ca7255614e0861e36480103f4a402a115803d7b5Mark Brown		/* If we can't read the status assume it's on. */
2957ca7255614e0861e36480103f4a402a115803d7b5Mark Brown		if (ops->is_enabled)
2958ca7255614e0861e36480103f4a402a115803d7b5Mark Brown			enabled = ops->is_enabled(rdev);
2959ca7255614e0861e36480103f4a402a115803d7b5Mark Brown		else
2960ca7255614e0861e36480103f4a402a115803d7b5Mark Brown			enabled = 1;
2961ca7255614e0861e36480103f4a402a115803d7b5Mark Brown
2962ca7255614e0861e36480103f4a402a115803d7b5Mark Brown		if (!enabled)
2963ca7255614e0861e36480103f4a402a115803d7b5Mark Brown			goto unlock;
2964ca7255614e0861e36480103f4a402a115803d7b5Mark Brown
2965ca7255614e0861e36480103f4a402a115803d7b5Mark Brown		if (has_full_constraints) {
2966ca7255614e0861e36480103f4a402a115803d7b5Mark Brown			/* We log since this may kill the system if it
2967ca7255614e0861e36480103f4a402a115803d7b5Mark Brown			 * goes wrong. */
29685da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches			rdev_info(rdev, "disabling\n");
2969ca7255614e0861e36480103f4a402a115803d7b5Mark Brown			ret = ops->disable(rdev);
2970ca7255614e0861e36480103f4a402a115803d7b5Mark Brown			if (ret != 0) {
29715da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches				rdev_err(rdev, "couldn't disable: %d\n", ret);
2972ca7255614e0861e36480103f4a402a115803d7b5Mark Brown			}
2973ca7255614e0861e36480103f4a402a115803d7b5Mark Brown		} else {
2974ca7255614e0861e36480103f4a402a115803d7b5Mark Brown			/* The intention is that in future we will
2975ca7255614e0861e36480103f4a402a115803d7b5Mark Brown			 * assume that full constraints are provided
2976ca7255614e0861e36480103f4a402a115803d7b5Mark Brown			 * so warn even if we aren't going to do
2977ca7255614e0861e36480103f4a402a115803d7b5Mark Brown			 * anything here.
2978ca7255614e0861e36480103f4a402a115803d7b5Mark Brown			 */
29795da84fd99bb1ab1c7cd39d0cf7c08bb63931a59aJoe Perches			rdev_warn(rdev, "incomplete constraints, leaving on\n");
2980ca7255614e0861e36480103f4a402a115803d7b5Mark Brown		}
2981ca7255614e0861e36480103f4a402a115803d7b5Mark Brown
2982ca7255614e0861e36480103f4a402a115803d7b5Mark Brownunlock:
2983ca7255614e0861e36480103f4a402a115803d7b5Mark Brown		mutex_unlock(&rdev->mutex);
2984ca7255614e0861e36480103f4a402a115803d7b5Mark Brown	}
2985ca7255614e0861e36480103f4a402a115803d7b5Mark Brown
2986ca7255614e0861e36480103f4a402a115803d7b5Mark Brown	mutex_unlock(&regulator_list_mutex);
2987ca7255614e0861e36480103f4a402a115803d7b5Mark Brown
2988ca7255614e0861e36480103f4a402a115803d7b5Mark Brown	return 0;
2989ca7255614e0861e36480103f4a402a115803d7b5Mark Brown}
2990ca7255614e0861e36480103f4a402a115803d7b5Mark Brownlate_initcall(regulator_init_complete);
2991