core.c revision a5766f11cfd3a0c03450d99c8fe548c2940be884
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
16414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood#include <linux/kernel.h>
17414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood#include <linux/init.h>
18414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood#include <linux/device.h>
19414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood#include <linux/err.h>
20414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood#include <linux/mutex.h>
21414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood#include <linux/suspend.h>
22414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood#include <linux/regulator/consumer.h>
23414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood#include <linux/regulator/driver.h>
24414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood#include <linux/regulator/machine.h>
25414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
26414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood#define REGULATOR_VERSION "0.5"
27414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
28414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic DEFINE_MUTEX(regulator_list_mutex);
29414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic LIST_HEAD(regulator_list);
30414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic LIST_HEAD(regulator_map_list);
31414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
32414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
33414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * struct regulator_dev
34414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
35414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Voltage / Current regulator class device. One for each regulator.
36414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
37414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstruct regulator_dev {
38414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator_desc *desc;
39414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int use_count;
40414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
41414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* lists we belong to */
42414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct list_head list; /* list of all regulators */
43414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct list_head slist; /* list of supplied regulators */
44414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
45414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* lists we own */
46414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct list_head consumer_list; /* consumers we supply */
47414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct list_head supply_list; /* regulators we supply */
48414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
49414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct blocking_notifier_head notifier;
50414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct mutex mutex; /* consumer lock */
51414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct module *owner;
52414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct device dev;
53414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulation_constraints *constraints;
54414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator_dev *supply;	/* for tree */
55414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
56414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	void *reg_data;		/* regulator_dev data */
57414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood};
58414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
59414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
60414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * struct regulator_map
61414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
62414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Used to provide symbolic supply names to devices.
63414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
64414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstruct regulator_map {
65414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct list_head list;
66414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct device *dev;
67414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	const char *supply;
68a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *regulator;
69414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood};
70414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
71414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/*
72414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * struct regulator
73414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
74414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * One for each consumer device.
75414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
76414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstruct regulator {
77414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct device *dev;
78414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct list_head list;
79414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int uA_load;
80414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int min_uV;
81414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int max_uV;
82414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int enabled; /* client has called enabled */
83414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	char *supply_name;
84414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct device_attribute dev_attr;
85414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator_dev *rdev;
86414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood};
87414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
88414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic int _regulator_is_enabled(struct regulator_dev *rdev);
89414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic int _regulator_disable(struct regulator_dev *rdev);
90414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic int _regulator_get_voltage(struct regulator_dev *rdev);
91414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic int _regulator_get_current_limit(struct regulator_dev *rdev);
92414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic unsigned int _regulator_get_mode(struct regulator_dev *rdev);
93414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic void _notifier_call_chain(struct regulator_dev *rdev,
94414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				  unsigned long event, void *data);
95414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
96414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/* gets the regulator for a given consumer device */
97414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic struct regulator *get_device_regulator(struct device *dev)
98414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
99414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator *regulator = NULL;
100414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator_dev *rdev;
101414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
102414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&regulator_list_mutex);
103414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	list_for_each_entry(rdev, &regulator_list, list) {
104414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		mutex_lock(&rdev->mutex);
105414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		list_for_each_entry(regulator, &rdev->consumer_list, list) {
106414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			if (regulator->dev == dev) {
107414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				mutex_unlock(&rdev->mutex);
108414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				mutex_unlock(&regulator_list_mutex);
109414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				return regulator;
110414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			}
111414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		}
112414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		mutex_unlock(&rdev->mutex);
113414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
114414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&regulator_list_mutex);
115414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return NULL;
116414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
117414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
118414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/* Platform voltage constraint check */
119414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic int regulator_check_voltage(struct regulator_dev *rdev,
120414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				   int *min_uV, int *max_uV)
121414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
122414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	BUG_ON(*min_uV > *max_uV);
123414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
124414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->constraints) {
125414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		printk(KERN_ERR "%s: no constraints for %s\n", __func__,
126414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		       rdev->desc->name);
127414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -ENODEV;
128414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
129414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) {
130414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		printk(KERN_ERR "%s: operation not allowed for %s\n",
131414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		       __func__, rdev->desc->name);
132414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -EPERM;
133414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
134414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
135414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (*max_uV > rdev->constraints->max_uV)
136414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		*max_uV = rdev->constraints->max_uV;
137414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (*min_uV < rdev->constraints->min_uV)
138414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		*min_uV = rdev->constraints->min_uV;
139414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
140414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (*min_uV > *max_uV)
141414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -EINVAL;
142414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
143414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return 0;
144414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
145414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
146414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/* current constraint check */
147414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic int regulator_check_current_limit(struct regulator_dev *rdev,
148414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood					int *min_uA, int *max_uA)
149414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
150414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	BUG_ON(*min_uA > *max_uA);
151414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
152414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->constraints) {
153414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		printk(KERN_ERR "%s: no constraints for %s\n", __func__,
154414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		       rdev->desc->name);
155414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -ENODEV;
156414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
157414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_CURRENT)) {
158414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		printk(KERN_ERR "%s: operation not allowed for %s\n",
159414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		       __func__, rdev->desc->name);
160414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -EPERM;
161414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
162414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
163414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (*max_uA > rdev->constraints->max_uA)
164414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		*max_uA = rdev->constraints->max_uA;
165414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (*min_uA < rdev->constraints->min_uA)
166414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		*min_uA = rdev->constraints->min_uA;
167414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
168414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (*min_uA > *max_uA)
169414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -EINVAL;
170414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
171414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return 0;
172414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
173414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
174414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/* operating mode constraint check */
175414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic int regulator_check_mode(struct regulator_dev *rdev, int mode)
176414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
177414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->constraints) {
178414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		printk(KERN_ERR "%s: no constraints for %s\n", __func__,
179414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		       rdev->desc->name);
180414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -ENODEV;
181414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
182414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_MODE)) {
183414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		printk(KERN_ERR "%s: operation not allowed for %s\n",
184414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		       __func__, rdev->desc->name);
185414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -EPERM;
186414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
187414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!(rdev->constraints->valid_modes_mask & mode)) {
188414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		printk(KERN_ERR "%s: invalid mode %x for %s\n",
189414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		       __func__, mode, rdev->desc->name);
190414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -EINVAL;
191414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
192414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return 0;
193414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
194414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
195414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/* dynamic regulator mode switching constraint check */
196414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic int regulator_check_drms(struct regulator_dev *rdev)
197414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
198414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->constraints) {
199414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		printk(KERN_ERR "%s: no constraints for %s\n", __func__,
200414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		       rdev->desc->name);
201414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -ENODEV;
202414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
203414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS)) {
204414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		printk(KERN_ERR "%s: operation not allowed for %s\n",
205414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		       __func__, rdev->desc->name);
206414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -EPERM;
207414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
208414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return 0;
209414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
210414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
211414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t device_requested_uA_show(struct device *dev,
212414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			     struct device_attribute *attr, char *buf)
213414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
214414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator *regulator;
215414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
216414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	regulator = get_device_regulator(dev);
217414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (regulator == NULL)
218414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return 0;
219414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
220414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return sprintf(buf, "%d\n", regulator->uA_load);
221414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
222414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
223414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_uV_show(struct device *dev,
224414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				struct device_attribute *attr, char *buf)
225414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
226a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
227414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ssize_t ret;
228414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
229414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&rdev->mutex);
230414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ret = sprintf(buf, "%d\n", _regulator_get_voltage(rdev));
231414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&rdev->mutex);
232414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
233414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
234414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
235414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
236414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_uA_show(struct device *dev,
237414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				struct device_attribute *attr, char *buf)
238414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
239a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
240414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
241414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return sprintf(buf, "%d\n", _regulator_get_current_limit(rdev));
242414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
243414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
244414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_opmode_show(struct device *dev,
245414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				    struct device_attribute *attr, char *buf)
246414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
247a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
248414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int mode = _regulator_get_mode(rdev);
249414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
250414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	switch (mode) {
251414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	case REGULATOR_MODE_FAST:
252414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "fast\n");
253414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	case REGULATOR_MODE_NORMAL:
254414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "normal\n");
255414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	case REGULATOR_MODE_IDLE:
256414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "idle\n");
257414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	case REGULATOR_MODE_STANDBY:
258414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "standby\n");
259414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
260414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return sprintf(buf, "unknown\n");
261414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
262414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
263414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_state_show(struct device *dev,
264414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				   struct device_attribute *attr, char *buf)
265414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
266a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
267414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int state = _regulator_is_enabled(rdev);
268414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
269414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (state > 0)
270414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "enabled\n");
271414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	else if (state == 0)
272414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "disabled\n");
273414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	else
274414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "unknown\n");
275414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
276414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
277414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_min_uA_show(struct device *dev,
278414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				    struct device_attribute *attr, char *buf)
279414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
280a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
281414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
282414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->constraints)
283414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "constraint not defined\n");
284414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
285414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return sprintf(buf, "%d\n", rdev->constraints->min_uA);
286414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
287414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
288414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_max_uA_show(struct device *dev,
289414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				    struct device_attribute *attr, char *buf)
290414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
291a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
292414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
293414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->constraints)
294414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "constraint not defined\n");
295414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
296414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return sprintf(buf, "%d\n", rdev->constraints->max_uA);
297414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
298414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
299414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_min_uV_show(struct device *dev,
300414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				    struct device_attribute *attr, char *buf)
301414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
302a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
303414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
304414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->constraints)
305414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "constraint not defined\n");
306414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
307414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return sprintf(buf, "%d\n", rdev->constraints->min_uV);
308414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
309414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
310414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_max_uV_show(struct device *dev,
311414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				    struct device_attribute *attr, char *buf)
312414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
313a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
314414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
315414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->constraints)
316414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "constraint not defined\n");
317414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
318414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return sprintf(buf, "%d\n", rdev->constraints->max_uV);
319414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
320414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
321414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_total_uA_show(struct device *dev,
322414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				      struct device_attribute *attr, char *buf)
323414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
324a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
325414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator *regulator;
326414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int uA = 0;
327414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
328414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&rdev->mutex);
329414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	list_for_each_entry(regulator, &rdev->consumer_list, list)
330414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	    uA += regulator->uA_load;
331414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&rdev->mutex);
332414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return sprintf(buf, "%d\n", uA);
333414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
334414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
335414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_num_users_show(struct device *dev,
336414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				      struct device_attribute *attr, char *buf)
337414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
338a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
339414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return sprintf(buf, "%d\n", rdev->use_count);
340414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
341414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
342414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_type_show(struct device *dev,
343414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				  struct device_attribute *attr, char *buf)
344414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
345a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
346414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
347414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	switch (rdev->desc->type) {
348414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	case REGULATOR_VOLTAGE:
349414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "voltage\n");
350414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	case REGULATOR_CURRENT:
351414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "current\n");
352414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
353414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return sprintf(buf, "unknown\n");
354414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
355414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
356414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_suspend_mem_uV_show(struct device *dev,
357414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				struct device_attribute *attr, char *buf)
358414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
359a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
360414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
361414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->constraints)
362414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "not defined\n");
363414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return sprintf(buf, "%d\n", rdev->constraints->state_mem.uV);
364414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
365414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
366414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_suspend_disk_uV_show(struct device *dev,
367414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				struct device_attribute *attr, char *buf)
368414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
369a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
370414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
371414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->constraints)
372414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "not defined\n");
373414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return sprintf(buf, "%d\n", rdev->constraints->state_disk.uV);
374414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
375414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
376414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_suspend_standby_uV_show(struct device *dev,
377414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				struct device_attribute *attr, char *buf)
378414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
379a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
380414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
381414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->constraints)
382414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "not defined\n");
383414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return sprintf(buf, "%d\n", rdev->constraints->state_standby.uV);
384414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
385414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
386414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t suspend_opmode_show(struct regulator_dev *rdev,
387414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	unsigned int mode, char *buf)
388414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
389414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	switch (mode) {
390414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	case REGULATOR_MODE_FAST:
391414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "fast\n");
392414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	case REGULATOR_MODE_NORMAL:
393414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "normal\n");
394414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	case REGULATOR_MODE_IDLE:
395414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "idle\n");
396414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	case REGULATOR_MODE_STANDBY:
397414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "standby\n");
398414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
399414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return sprintf(buf, "unknown\n");
400414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
401414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
402414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_suspend_mem_mode_show(struct device *dev,
403414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				struct device_attribute *attr, char *buf)
404414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
405a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
406414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
407414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->constraints)
408414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "not defined\n");
409414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return suspend_opmode_show(rdev,
410414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		rdev->constraints->state_mem.mode, buf);
411414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
412414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
413414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_suspend_disk_mode_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, "not defined\n");
420414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return suspend_opmode_show(rdev,
421414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		rdev->constraints->state_disk.mode, buf);
422414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
423414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
424414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_suspend_standby_mode_show(struct device *dev,
425414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				struct device_attribute *attr, char *buf)
426414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
427a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
428414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
429414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->constraints)
430414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "not defined\n");
431414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return suspend_opmode_show(rdev,
432414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		rdev->constraints->state_standby.mode, buf);
433414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
434414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
435414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_suspend_mem_state_show(struct device *dev,
436414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				   struct device_attribute *attr, char *buf)
437414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
438a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
439414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
440414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->constraints)
441414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "not defined\n");
442414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
443414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (rdev->constraints->state_mem.enabled)
444414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "enabled\n");
445414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	else
446414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "disabled\n");
447414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
448414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
449414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_suspend_disk_state_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
454414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->constraints)
455414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "not defined\n");
456414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
457414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (rdev->constraints->state_disk.enabled)
458414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "enabled\n");
459414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	else
460414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "disabled\n");
461414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
462414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
463414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic ssize_t regulator_suspend_standby_state_show(struct device *dev,
464414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				   struct device_attribute *attr, char *buf)
465414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
466a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
467414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
468414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->constraints)
469414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "not defined\n");
470414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
471414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (rdev->constraints->state_standby.enabled)
472414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "enabled\n");
473414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	else
474414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return sprintf(buf, "disabled\n");
475414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
476414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic struct device_attribute regulator_dev_attrs[] = {
477414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	__ATTR(microvolts, 0444, regulator_uV_show, NULL),
478414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	__ATTR(microamps, 0444, regulator_uA_show, NULL),
479414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	__ATTR(opmode, 0444, regulator_opmode_show, NULL),
480414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	__ATTR(state, 0444, regulator_state_show, NULL),
481414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	__ATTR(min_microvolts, 0444, regulator_min_uV_show, NULL),
482414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	__ATTR(min_microamps, 0444, regulator_min_uA_show, NULL),
483414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	__ATTR(max_microvolts, 0444, regulator_max_uV_show, NULL),
484414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	__ATTR(max_microamps, 0444, regulator_max_uA_show, NULL),
485414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	__ATTR(requested_microamps, 0444, regulator_total_uA_show, NULL),
486414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	__ATTR(num_users, 0444, regulator_num_users_show, NULL),
487414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	__ATTR(type, 0444, regulator_type_show, NULL),
488414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	__ATTR(suspend_mem_microvolts, 0444,
489414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator_suspend_mem_uV_show, NULL),
490414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	__ATTR(suspend_disk_microvolts, 0444,
491414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator_suspend_disk_uV_show, NULL),
492414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	__ATTR(suspend_standby_microvolts, 0444,
493414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator_suspend_standby_uV_show, NULL),
494414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	__ATTR(suspend_mem_mode, 0444,
495414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator_suspend_mem_mode_show, NULL),
496414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	__ATTR(suspend_disk_mode, 0444,
497414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator_suspend_disk_mode_show, NULL),
498414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	__ATTR(suspend_standby_mode, 0444,
499414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator_suspend_standby_mode_show, NULL),
500414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	__ATTR(suspend_mem_state, 0444,
501414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator_suspend_mem_state_show, NULL),
502414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	__ATTR(suspend_disk_state, 0444,
503414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator_suspend_disk_state_show, NULL),
504414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	__ATTR(suspend_standby_state, 0444,
505414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator_suspend_standby_state_show, NULL),
506414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	__ATTR_NULL,
507414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood};
508414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
509414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic void regulator_dev_release(struct device *dev)
510414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
511a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *rdev = dev_get_drvdata(dev);
512414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	kfree(rdev);
513414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
514414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
515414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic struct class regulator_class = {
516414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	.name = "regulator",
517414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	.dev_release = regulator_dev_release,
518414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	.dev_attrs = regulator_dev_attrs,
519414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood};
520414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
521414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/* Calculate the new optimum regulator operating mode based on the new total
522414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * consumer load. All locks held by caller */
523414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic void drms_uA_update(struct regulator_dev *rdev)
524414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
525414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator *sibling;
526414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int current_uA = 0, output_uV, input_uV, err;
527414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	unsigned int mode;
528414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
529414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	err = regulator_check_drms(rdev);
530414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (err < 0 || !rdev->desc->ops->get_optimum_mode ||
531414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	    !rdev->desc->ops->get_voltage || !rdev->desc->ops->set_mode);
532414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return;
533414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
534414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* get output voltage */
535414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	output_uV = rdev->desc->ops->get_voltage(rdev);
536414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (output_uV <= 0)
537414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return;
538414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
539414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* get input voltage */
540414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (rdev->supply && rdev->supply->desc->ops->get_voltage)
541414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		input_uV = rdev->supply->desc->ops->get_voltage(rdev->supply);
542414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	else
543414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		input_uV = rdev->constraints->input_uV;
544414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (input_uV <= 0)
545414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return;
546414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
547414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* calc total requested load */
548414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	list_for_each_entry(sibling, &rdev->consumer_list, list)
549414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	    current_uA += sibling->uA_load;
550414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
551414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* now get the optimum mode for our new total regulator load */
552414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mode = rdev->desc->ops->get_optimum_mode(rdev, input_uV,
553414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood						  output_uV, current_uA);
554414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
555414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* check the new mode is allowed */
556414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	err = regulator_check_mode(rdev, mode);
557414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (err == 0)
558414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		rdev->desc->ops->set_mode(rdev, mode);
559414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
560414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
561414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic int suspend_set_state(struct regulator_dev *rdev,
562414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator_state *rstate)
563414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
564414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret = 0;
565414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
566414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* enable & disable are mandatory for suspend control */
567414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->desc->ops->set_suspend_enable ||
568a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		!rdev->desc->ops->set_suspend_disable) {
569a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		printk(KERN_ERR "%s: no way to set suspend state\n",
570a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood			__func__);
571414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -EINVAL;
572a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	}
573414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
574414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (rstate->enabled)
575414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		ret = rdev->desc->ops->set_suspend_enable(rdev);
576414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	else
577414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		ret = rdev->desc->ops->set_suspend_disable(rdev);
578414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (ret < 0) {
579414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		printk(KERN_ERR "%s: failed to enabled/disable\n", __func__);
580414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return ret;
581414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
582414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
583414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (rdev->desc->ops->set_suspend_voltage && rstate->uV > 0) {
584414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		ret = rdev->desc->ops->set_suspend_voltage(rdev, rstate->uV);
585414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (ret < 0) {
586414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			printk(KERN_ERR "%s: failed to set voltage\n",
587414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				__func__);
588414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			return ret;
589414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		}
590414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
591414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
592414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (rdev->desc->ops->set_suspend_mode && rstate->mode > 0) {
593414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		ret = rdev->desc->ops->set_suspend_mode(rdev, rstate->mode);
594414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (ret < 0) {
595414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			printk(KERN_ERR "%s: failed to set mode\n", __func__);
596414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			return ret;
597414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		}
598414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
599414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
600414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
601414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
602414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/* locks held by caller */
603414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic int suspend_prepare(struct regulator_dev *rdev, suspend_state_t state)
604414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
605414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->constraints)
606414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -EINVAL;
607414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
608414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	switch (state) {
609414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	case PM_SUSPEND_STANDBY:
610414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return suspend_set_state(rdev,
611414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			&rdev->constraints->state_standby);
612414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	case PM_SUSPEND_MEM:
613414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return suspend_set_state(rdev,
614414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			&rdev->constraints->state_mem);
615414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	case PM_SUSPEND_MAX:
616414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return suspend_set_state(rdev,
617414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			&rdev->constraints->state_disk);
618414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	default:
619414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -EINVAL;
620414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
621414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
622414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
623414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic void print_constraints(struct regulator_dev *rdev)
624414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
625414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulation_constraints *constraints = rdev->constraints;
626414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	char buf[80];
627414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int count;
628414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
629414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (rdev->desc->type == REGULATOR_VOLTAGE) {
630414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (constraints->min_uV == constraints->max_uV)
631414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			count = sprintf(buf, "%d mV ",
632414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood					constraints->min_uV / 1000);
633414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		else
634414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			count = sprintf(buf, "%d <--> %d mV ",
635414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood					constraints->min_uV / 1000,
636414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood					constraints->max_uV / 1000);
637414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	} else {
638414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (constraints->min_uA == constraints->max_uA)
639414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			count = sprintf(buf, "%d mA ",
640414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood					constraints->min_uA / 1000);
641414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		else
642414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			count = sprintf(buf, "%d <--> %d mA ",
643414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood					constraints->min_uA / 1000,
644414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood					constraints->max_uA / 1000);
645414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
646414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (constraints->valid_modes_mask & REGULATOR_MODE_FAST)
647414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		count += sprintf(buf + count, "fast ");
648414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (constraints->valid_modes_mask & REGULATOR_MODE_NORMAL)
649414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		count += sprintf(buf + count, "normal ");
650414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (constraints->valid_modes_mask & REGULATOR_MODE_IDLE)
651414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		count += sprintf(buf + count, "idle ");
652414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (constraints->valid_modes_mask & REGULATOR_MODE_STANDBY)
653414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		count += sprintf(buf + count, "standby");
654414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
655414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	printk(KERN_INFO "regulator: %s: %s\n", rdev->desc->name, buf);
656414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
657414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
658a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood/**
659a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * set_machine_constraints - sets regulator constraints
660a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * @regulator: regulator source
661a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood *
662a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * Allows platform initialisation code to define and constrain
663a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * regulator circuits e.g. valid voltage/current ranges, etc.  NOTE:
664a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * Constraints *must* be set by platform code in order for some
665a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * regulator operations to proceed i.e. set_voltage, set_current_limit,
666a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * set_mode.
667a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood */
668a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwoodstatic int set_machine_constraints(struct regulator_dev *rdev,
669a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulation_constraints *constraints)
670a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood{
671a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	int ret = 0;
672a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
673a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	rdev->constraints = constraints;
674a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
675a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	/* do we need to apply the constraint voltage */
676a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	if (rdev->constraints->apply_uV &&
677a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		rdev->constraints->min_uV == rdev->constraints->max_uV &&
678a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		rdev->desc->ops->set_voltage) {
679a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		ret = rdev->desc->ops->set_voltage(rdev,
680a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood			rdev->constraints->min_uV, rdev->constraints->max_uV);
681a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood			if (ret < 0) {
682a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood				printk(KERN_ERR "%s: failed to apply %duV"
683a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood					" constraint\n", __func__,
684a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood					rdev->constraints->min_uV);
685a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood				rdev->constraints = NULL;
686a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood				goto out;
687a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood			}
688a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	}
689a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
690a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	/* are we enabled at boot time by firmware / bootloader */
691a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	if (rdev->constraints->boot_on)
692a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		rdev->use_count = 1;
693a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
694a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	/* do we need to setup our suspend state */
695a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	if (constraints->initial_state)
696a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		ret = suspend_prepare(rdev, constraints->initial_state);
697a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
698a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	print_constraints(rdev);
699a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwoodout:
700a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	return ret;
701a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood}
702a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
703a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood/**
704a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * set_supply - set regulator supply regulator
705a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * @regulator: regulator name
706a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * @supply: supply regulator name
707a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood *
708a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * Called by platform initialisation code to set the supply regulator for this
709a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * regulator. This ensures that a regulators supply will also be enabled by the
710a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * core if it's child is enabled.
711a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood */
712a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwoodstatic int set_supply(struct regulator_dev *rdev,
713a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_dev *supply_rdev)
714a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood{
715a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	int err;
716a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
717a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	err = sysfs_create_link(&rdev->dev.kobj, &supply_rdev->dev.kobj,
718a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood				"supply");
719a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	if (err) {
720a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		printk(KERN_ERR
721a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		       "%s: could not add device link %s err %d\n",
722a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		       __func__, supply_rdev->dev.kobj.name, err);
723a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		       goto out;
724a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	}
725a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	rdev->supply = supply_rdev;
726a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	list_add(&rdev->slist, &supply_rdev->supply_list);
727a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwoodout:
728a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	return err;
729a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood}
730a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
731a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood/**
732a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * set_consumer_device_supply: Bind a regulator to a symbolic supply
733a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * @regulator: regulator source
734a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * @dev:       device the supply applies to
735a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * @supply:    symbolic name for supply
736a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood *
737a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * Allows platform initialisation code to map physical regulator
738a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * sources to symbolic names for supplies for use by devices.  Devices
739a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * should use these symbolic names to request regulators, avoiding the
740a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood * need to provide board-specific regulator names as platform data.
741a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood */
742a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwoodstatic int set_consumer_device_supply(struct regulator_dev *rdev,
743a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct device *consumer_dev, const char *supply)
744a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood{
745a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_map *node;
746a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
747a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	if (supply == NULL)
748a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		return -EINVAL;
749a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
750a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	node = kmalloc(sizeof(struct regulator_map), GFP_KERNEL);
751a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	if (node == NULL)
752a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		return -ENOMEM;
753a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
754a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	node->regulator = rdev;
755a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	node->dev = consumer_dev;
756a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	node->supply = supply;
757a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
758a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	list_add(&node->list, &regulator_map_list);
759a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	return 0;
760a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood}
761a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
762a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwoodstatic void unset_consumer_device_supply(struct regulator_dev *rdev,
763a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct device *consumer_dev)
764a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood{
765a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_map *node, *n;
766a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
767a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	list_for_each_entry_safe(node, n, &regulator_map_list, list) {
768a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		if (rdev == node->regulator &&
769a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood			consumer_dev == node->dev) {
770a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood			list_del(&node->list);
771a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood			kfree(node);
772a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood			return;
773a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		}
774a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	}
775a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood}
776a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
777414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood#define REG_STR_SIZE	32
778414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
779414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic struct regulator *create_regulator(struct regulator_dev *rdev,
780414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood					  struct device *dev,
781414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood					  const char *supply_name)
782414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
783414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator *regulator;
784414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	char buf[REG_STR_SIZE];
785414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int err, size;
786414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
787414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	regulator = kzalloc(sizeof(*regulator), GFP_KERNEL);
788414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (regulator == NULL)
789414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return NULL;
790414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
791414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&rdev->mutex);
792414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	regulator->rdev = rdev;
793414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	list_add(&regulator->list, &rdev->consumer_list);
794414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
795414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (dev) {
796414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		/* create a 'requested_microamps_name' sysfs entry */
797414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		size = scnprintf(buf, REG_STR_SIZE, "microamps_requested_%s",
798414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			supply_name);
799414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (size >= REG_STR_SIZE)
800414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			goto overflow_err;
801414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
802414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator->dev = dev;
803414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator->dev_attr.attr.name = kstrdup(buf, GFP_KERNEL);
804414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (regulator->dev_attr.attr.name == NULL)
805414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			goto attr_name_err;
806414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
807414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator->dev_attr.attr.owner = THIS_MODULE;
808414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator->dev_attr.attr.mode = 0444;
809414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator->dev_attr.show = device_requested_uA_show;
810414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		err = device_create_file(dev, &regulator->dev_attr);
811414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (err < 0) {
812414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			printk(KERN_WARNING "%s: could not add regulator_dev"
813414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				" load sysfs\n", __func__);
814414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			goto attr_name_err;
815414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		}
816414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
817414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		/* also add a link to the device sysfs entry */
818414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		size = scnprintf(buf, REG_STR_SIZE, "%s-%s",
819414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				 dev->kobj.name, supply_name);
820414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (size >= REG_STR_SIZE)
821414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			goto attr_err;
822414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
823414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator->supply_name = kstrdup(buf, GFP_KERNEL);
824414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (regulator->supply_name == NULL)
825414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			goto attr_err;
826414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
827414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		err = sysfs_create_link(&rdev->dev.kobj, &dev->kobj,
828414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood					buf);
829414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (err) {
830414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			printk(KERN_WARNING
831414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			       "%s: could not add device link %s err %d\n",
832414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			       __func__, dev->kobj.name, err);
833414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			device_remove_file(dev, &regulator->dev_attr);
834414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			goto link_name_err;
835414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		}
836414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
837414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&rdev->mutex);
838414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return regulator;
839414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodlink_name_err:
840414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	kfree(regulator->supply_name);
841414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodattr_err:
842414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	device_remove_file(regulator->dev, &regulator->dev_attr);
843414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodattr_name_err:
844414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	kfree(regulator->dev_attr.attr.name);
845414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodoverflow_err:
846414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	list_del(&regulator->list);
847414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	kfree(regulator);
848414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&rdev->mutex);
849414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return NULL;
850414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
851414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
852414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
853414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_get - lookup and obtain a reference to a regulator.
854414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @dev: device for regulator "consumer"
855414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @id: Supply name or regulator ID.
856414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
857414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Returns a struct regulator corresponding to the regulator producer,
858414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * or IS_ERR() condition containing errno.  Use of supply names
859414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * configured via regulator_set_device_supply() is strongly
860414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * encouraged.
861414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
862414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstruct regulator *regulator_get(struct device *dev, const char *id)
863414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
864414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator_dev *rdev;
865414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator_map *map;
866414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator *regulator = ERR_PTR(-ENODEV);
867414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
868414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (id == NULL) {
869414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		printk(KERN_ERR "regulator: get() with no identifier\n");
870414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return regulator;
871414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
872414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
873414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&regulator_list_mutex);
874414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
875414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	list_for_each_entry(map, &regulator_map_list, list) {
876414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (dev == map->dev &&
877414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		    strcmp(map->supply, id) == 0) {
878a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood			rdev = map->regulator;
879414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			goto found;
880a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		}
881414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
882414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	printk(KERN_ERR "regulator: Unable to get requested regulator: %s\n",
883414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	       id);
884414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&regulator_list_mutex);
885414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return regulator;
886414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
887414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodfound:
888a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	if (!try_module_get(rdev->owner))
889a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		goto out;
890a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
891414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	regulator = create_regulator(rdev, dev, id);
892414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (regulator == NULL) {
893414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator = ERR_PTR(-ENOMEM);
894414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		module_put(rdev->owner);
895414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
896414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
897a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwoodout:
898414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&regulator_list_mutex);
899414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return regulator;
900414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
901414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_get);
902414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
903414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
904414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_put - "free" the regulator source
905414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
906414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
907414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Note: drivers must ensure that all regulator_enable calls made on this
908414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator source are balanced by regulator_disable calls prior to calling
909414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * this function.
910414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
911414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodvoid regulator_put(struct regulator *regulator)
912414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
913414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator_dev *rdev;
914414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
915414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (regulator == NULL || IS_ERR(regulator))
916414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return;
917414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
918414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (regulator->enabled) {
919414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		printk(KERN_WARNING "Releasing supply %s while enabled\n",
920414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		       regulator->supply_name);
921414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		WARN_ON(regulator->enabled);
922414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator_disable(regulator);
923414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
924414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
925414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&regulator_list_mutex);
926414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	rdev = regulator->rdev;
927414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
928414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* remove any sysfs entries */
929414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (regulator->dev) {
930414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name);
931414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		kfree(regulator->supply_name);
932414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		device_remove_file(regulator->dev, &regulator->dev_attr);
933414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		kfree(regulator->dev_attr.attr.name);
934414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
935414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	list_del(&regulator->list);
936414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	kfree(regulator);
937414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
938414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	module_put(rdev->owner);
939414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&regulator_list_mutex);
940414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
941414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_put);
942414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
943414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/* locks held by regulator_enable() */
944414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic int _regulator_enable(struct regulator_dev *rdev)
945414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
946414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret = -EINVAL;
947414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
948414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->constraints) {
949414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		printk(KERN_ERR "%s: %s has no constraints\n",
950414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		       __func__, rdev->desc->name);
951414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return ret;
952414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
953414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
954414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* do we need to enable the supply regulator first */
955414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (rdev->supply) {
956414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		ret = _regulator_enable(rdev->supply);
957414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (ret < 0) {
958414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			printk(KERN_ERR "%s: failed to enable %s: %d\n",
959414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			       __func__, rdev->desc->name, ret);
960414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			return ret;
961414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		}
962414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
963414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
964414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* check voltage and requested load before enabling */
965414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (rdev->desc->ops->enable) {
966414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
967414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (rdev->constraints &&
968414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			(rdev->constraints->valid_ops_mask &
969414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			REGULATOR_CHANGE_DRMS))
970414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			drms_uA_update(rdev);
971414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
972414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		ret = rdev->desc->ops->enable(rdev);
973414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (ret < 0) {
974414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			printk(KERN_ERR "%s: failed to enable %s: %d\n",
975414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			       __func__, rdev->desc->name, ret);
976414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			return ret;
977414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		}
978414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		rdev->use_count++;
979414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return ret;
980414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
981414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
982414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
983414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
984414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
985414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
986414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_enable - enable regulator output
987414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
988414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
989414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Enable the regulator output at the predefined voltage or current value.
990414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * NOTE: the output value can be set by other drivers, boot loader or may be
991414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * hardwired in the regulator.
992414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * NOTE: calls to regulator_enable() must be balanced with calls to
993414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_disable().
994414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
995414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_enable(struct regulator *regulator)
996414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
997414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret;
998414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
999414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (regulator->enabled) {
1000414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		printk(KERN_CRIT "Regulator %s already enabled\n",
1001414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		       regulator->supply_name);
1002414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		WARN_ON(regulator->enabled);
1003414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return 0;
1004414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
1005414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1006414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&regulator->rdev->mutex);
1007414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	regulator->enabled = 1;
1008414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ret = _regulator_enable(regulator->rdev);
1009414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (ret != 0)
1010414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator->enabled = 0;
1011414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&regulator->rdev->mutex);
1012414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
1013414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1014414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_enable);
1015414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1016414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/* locks held by regulator_disable() */
1017414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic int _regulator_disable(struct regulator_dev *rdev)
1018414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1019414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret = 0;
1020414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1021414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* are we the last user and permitted to disable ? */
1022414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (rdev->use_count == 1 && !rdev->constraints->always_on) {
1023414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1024414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		/* we are last user */
1025414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (rdev->desc->ops->disable) {
1026414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			ret = rdev->desc->ops->disable(rdev);
1027414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			if (ret < 0) {
1028414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				printk(KERN_ERR "%s: failed to disable %s\n",
1029414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				       __func__, rdev->desc->name);
1030414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				return ret;
1031414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			}
1032414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		}
1033414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1034414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		/* decrease our supplies ref count and disable if required */
1035414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (rdev->supply)
1036414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			_regulator_disable(rdev->supply);
1037414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1038414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		rdev->use_count = 0;
1039414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	} else if (rdev->use_count > 1) {
1040414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1041414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (rdev->constraints &&
1042414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			(rdev->constraints->valid_ops_mask &
1043414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			REGULATOR_CHANGE_DRMS))
1044414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			drms_uA_update(rdev);
1045414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1046414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		rdev->use_count--;
1047414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
1048414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
1049414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1050414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1051414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
1052414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_disable - disable regulator output
1053414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
1054414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1055414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Disable the regulator output voltage or current.
1056414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * NOTE: this will only disable the regulator output if no other consumer
1057414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * devices have it enabled.
1058414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * NOTE: calls to regulator_enable() must be balanced with calls to
1059414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_disable().
1060414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1061414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_disable(struct regulator *regulator)
1062414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1063414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret;
1064414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1065414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!regulator->enabled) {
1066414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		printk(KERN_ERR "%s: not in use by this consumer\n",
1067414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			__func__);
1068414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return 0;
1069414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
1070414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1071414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&regulator->rdev->mutex);
1072414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	regulator->enabled = 0;
1073414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	regulator->uA_load = 0;
1074414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ret = _regulator_disable(regulator->rdev);
1075414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&regulator->rdev->mutex);
1076414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
1077414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1078414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_disable);
1079414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1080414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/* locks held by regulator_force_disable() */
1081414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic int _regulator_force_disable(struct regulator_dev *rdev)
1082414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1083414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret = 0;
1084414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1085414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* force disable */
1086414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (rdev->desc->ops->disable) {
1087414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		/* ah well, who wants to live forever... */
1088414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		ret = rdev->desc->ops->disable(rdev);
1089414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (ret < 0) {
1090414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			printk(KERN_ERR "%s: failed to force disable %s\n",
1091414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			       __func__, rdev->desc->name);
1092414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			return ret;
1093414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		}
1094414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		/* notify other consumers that power has been forced off */
1095414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		_notifier_call_chain(rdev, REGULATOR_EVENT_FORCE_DISABLE,
1096414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			NULL);
1097414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
1098414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1099414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* decrease our supplies ref count and disable if required */
1100414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (rdev->supply)
1101414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		_regulator_disable(rdev->supply);
1102414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1103414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	rdev->use_count = 0;
1104414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
1105414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1106414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1107414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
1108414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_force_disable - force disable regulator output
1109414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
1110414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1111414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Forcibly disable the regulator output voltage or current.
1112414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * NOTE: this *will* disable the regulator output even if other consumer
1113414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * devices have it enabled. This should be used for situations when device
1114414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * damage will likely occur if the regulator is not disabled (e.g. over temp).
1115414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1116414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_force_disable(struct regulator *regulator)
1117414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1118414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret;
1119414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1120414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&regulator->rdev->mutex);
1121414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	regulator->enabled = 0;
1122414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	regulator->uA_load = 0;
1123414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ret = _regulator_force_disable(regulator->rdev);
1124414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&regulator->rdev->mutex);
1125414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
1126414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1127414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_force_disable);
1128414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1129414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic int _regulator_is_enabled(struct regulator_dev *rdev)
1130414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1131414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret;
1132414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1133414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&rdev->mutex);
1134414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1135414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* sanity check */
1136414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->desc->ops->is_enabled) {
1137414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		ret = -EINVAL;
1138414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		goto out;
1139414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
1140414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1141414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ret = rdev->desc->ops->is_enabled(rdev);
1142414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodout:
1143414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&rdev->mutex);
1144414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
1145414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1146414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1147414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
1148414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_is_enabled - is the regulator output enabled
1149414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
1150414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1151414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Returns zero for disabled otherwise return number of enable requests.
1152414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1153414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_is_enabled(struct regulator *regulator)
1154414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1155414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return _regulator_is_enabled(regulator->rdev);
1156414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1157414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_is_enabled);
1158414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1159414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
1160414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_set_voltage - set regulator output voltage
1161414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
1162414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @min_uV: Minimum required voltage in uV
1163414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @max_uV: Maximum acceptable voltage in uV
1164414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1165414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Sets a voltage regulator to the desired output voltage. This can be set
1166414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * during any regulator state. IOW, regulator can be disabled or enabled.
1167414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1168414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * If the regulator is enabled then the voltage will change to the new value
1169414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * immediately otherwise if the regulator is disabled the regulator will
1170414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * output at the new voltage when enabled.
1171414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1172414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * NOTE: If the regulator is shared between several devices then the lowest
1173414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * request voltage that meets the system constraints will be used.
1174414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * NOTE: Regulator system constraints must be set for this regulator before
1175414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * calling this function otherwise this call will fail.
1176414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1177414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
1178414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1179414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator_dev *rdev = regulator->rdev;
1180414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret;
1181414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1182414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&rdev->mutex);
1183414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1184414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* sanity check */
1185414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->desc->ops->set_voltage) {
1186414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		ret = -EINVAL;
1187414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		goto out;
1188414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
1189414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1190414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* constraints check */
1191414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ret = regulator_check_voltage(rdev, &min_uV, &max_uV);
1192414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (ret < 0)
1193414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		goto out;
1194414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	regulator->min_uV = min_uV;
1195414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	regulator->max_uV = max_uV;
1196414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV);
1197414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1198414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodout:
1199414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&rdev->mutex);
1200414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
1201414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1202414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_set_voltage);
1203414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1204414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic int _regulator_get_voltage(struct regulator_dev *rdev)
1205414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1206414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* sanity check */
1207414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (rdev->desc->ops->get_voltage)
1208414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return rdev->desc->ops->get_voltage(rdev);
1209414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	else
1210414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -EINVAL;
1211414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1212414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1213414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
1214414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_get_voltage - get regulator output voltage
1215414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
1216414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1217414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * This returns the current regulator voltage in uV.
1218414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1219414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * NOTE: If the regulator is disabled it will return the voltage value. This
1220414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * function should not be used to determine regulator state.
1221414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1222414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_get_voltage(struct regulator *regulator)
1223414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1224414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret;
1225414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1226414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&regulator->rdev->mutex);
1227414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1228414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ret = _regulator_get_voltage(regulator->rdev);
1229414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1230414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&regulator->rdev->mutex);
1231414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1232414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
1233414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1234414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_get_voltage);
1235414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1236414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
1237414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_set_current_limit - set regulator output current limit
1238414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
1239414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @min_uA: Minimuum supported current in uA
1240414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @max_uA: Maximum supported current in uA
1241414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1242414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Sets current sink to the desired output current. This can be set during
1243414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * any regulator state. IOW, regulator can be disabled or enabled.
1244414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1245414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * If the regulator is enabled then the current will change to the new value
1246414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * immediately otherwise if the regulator is disabled the regulator will
1247414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * output at the new current when enabled.
1248414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1249414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * NOTE: Regulator system constraints must be set for this regulator before
1250414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * calling this function otherwise this call will fail.
1251414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1252414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_set_current_limit(struct regulator *regulator,
1253414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			       int min_uA, int max_uA)
1254414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1255414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator_dev *rdev = regulator->rdev;
1256414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret;
1257414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1258414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&rdev->mutex);
1259414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1260414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* sanity check */
1261414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->desc->ops->set_current_limit) {
1262414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		ret = -EINVAL;
1263414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		goto out;
1264414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
1265414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1266414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* constraints check */
1267414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ret = regulator_check_current_limit(rdev, &min_uA, &max_uA);
1268414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (ret < 0)
1269414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		goto out;
1270414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1271414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ret = rdev->desc->ops->set_current_limit(rdev, min_uA, max_uA);
1272414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodout:
1273414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&rdev->mutex);
1274414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
1275414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1276414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_set_current_limit);
1277414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1278414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic int _regulator_get_current_limit(struct regulator_dev *rdev)
1279414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1280414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret;
1281414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1282414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&rdev->mutex);
1283414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1284414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* sanity check */
1285414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->desc->ops->get_current_limit) {
1286414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		ret = -EINVAL;
1287414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		goto out;
1288414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
1289414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1290414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ret = rdev->desc->ops->get_current_limit(rdev);
1291414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodout:
1292414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&rdev->mutex);
1293414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
1294414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1295414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1296414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
1297414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_get_current_limit - get regulator output current
1298414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
1299414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1300414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * This returns the current supplied by the specified current sink in uA.
1301414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1302414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * NOTE: If the regulator is disabled it will return the current value. This
1303414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * function should not be used to determine regulator state.
1304414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1305414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_get_current_limit(struct regulator *regulator)
1306414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1307414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return _regulator_get_current_limit(regulator->rdev);
1308414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1309414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_get_current_limit);
1310414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1311414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
1312414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_set_mode - set regulator operating mode
1313414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
1314414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @mode: operating mode - one of the REGULATOR_MODE constants
1315414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1316414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Set regulator operating mode to increase regulator efficiency or improve
1317414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulation performance.
1318414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1319414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * NOTE: Regulator system constraints must be set for this regulator before
1320414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * calling this function otherwise this call will fail.
1321414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1322414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_set_mode(struct regulator *regulator, unsigned int mode)
1323414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1324414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator_dev *rdev = regulator->rdev;
1325414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret;
1326414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1327414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&rdev->mutex);
1328414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1329414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* sanity check */
1330414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->desc->ops->set_mode) {
1331414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		ret = -EINVAL;
1332414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		goto out;
1333414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
1334414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1335414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* constraints check */
1336414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ret = regulator_check_mode(rdev, mode);
1337414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (ret < 0)
1338414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		goto out;
1339414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1340414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ret = rdev->desc->ops->set_mode(rdev, mode);
1341414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodout:
1342414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&rdev->mutex);
1343414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
1344414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1345414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_set_mode);
1346414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1347414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic unsigned int _regulator_get_mode(struct regulator_dev *rdev)
1348414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1349414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret;
1350414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1351414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&rdev->mutex);
1352414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1353414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* sanity check */
1354414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->desc->ops->get_mode) {
1355414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		ret = -EINVAL;
1356414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		goto out;
1357414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
1358414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1359414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ret = rdev->desc->ops->get_mode(rdev);
1360414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodout:
1361414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&rdev->mutex);
1362414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
1363414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1364414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1365414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
1366414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_get_mode - get regulator operating mode
1367414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
1368414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1369414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Get the current regulator operating mode.
1370414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1371414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodunsigned int regulator_get_mode(struct regulator *regulator)
1372414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1373414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return _regulator_get_mode(regulator->rdev);
1374414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1375414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_get_mode);
1376414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1377414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
1378414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_set_optimum_mode - set regulator optimum operating mode
1379414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
1380414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @uA_load: load current
1381414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1382414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Notifies the regulator core of a new device load. This is then used by
1383414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * DRMS (if enabled by constraints) to set the most efficient regulator
1384414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * operating mode for the new regulator loading.
1385414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1386414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Consumer devices notify their supply regulator of the maximum power
1387414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * they will require (can be taken from device datasheet in the power
1388414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * consumption tables) when they change operational status and hence power
1389414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * state. Examples of operational state changes that can affect power
1390414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * consumption are :-
1391414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1392414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *    o Device is opened / closed.
1393414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *    o Device I/O is about to begin or has just finished.
1394414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *    o Device is idling in between work.
1395414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1396414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * This information is also exported via sysfs to userspace.
1397414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1398414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * DRMS will sum the total requested load on the regulator and change
1399414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * to the most efficient operating mode if platform constraints allow.
1400414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1401414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Returns the new regulator mode or error.
1402414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1403414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_set_optimum_mode(struct regulator *regulator, int uA_load)
1404414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1405414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator_dev *rdev = regulator->rdev;
1406414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator *consumer;
1407414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret, output_uV, input_uV, total_uA_load = 0;
1408414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	unsigned int mode;
1409414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1410414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&rdev->mutex);
1411414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1412414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	regulator->uA_load = uA_load;
1413414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ret = regulator_check_drms(rdev);
1414414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (ret < 0)
1415414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		goto out;
1416414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ret = -EINVAL;
1417414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1418414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* sanity check */
1419414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!rdev->desc->ops->get_optimum_mode)
1420414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		goto out;
1421414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1422414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* get output voltage */
1423414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	output_uV = rdev->desc->ops->get_voltage(rdev);
1424414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (output_uV <= 0) {
1425414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		printk(KERN_ERR "%s: invalid output voltage found for %s\n",
1426414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			__func__, rdev->desc->name);
1427414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		goto out;
1428414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
1429414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1430414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* get input voltage */
1431414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (rdev->supply && rdev->supply->desc->ops->get_voltage)
1432414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		input_uV = rdev->supply->desc->ops->get_voltage(rdev->supply);
1433414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	else
1434414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		input_uV = rdev->constraints->input_uV;
1435414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (input_uV <= 0) {
1436414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		printk(KERN_ERR "%s: invalid input voltage found for %s\n",
1437414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			__func__, rdev->desc->name);
1438414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		goto out;
1439414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
1440414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1441414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* calc total requested load for this regulator */
1442414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	list_for_each_entry(consumer, &rdev->consumer_list, list)
1443414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	    total_uA_load += consumer->uA_load;
1444414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1445414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mode = rdev->desc->ops->get_optimum_mode(rdev,
1446414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood						 input_uV, output_uV,
1447414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood						 total_uA_load);
1448414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (ret <= 0) {
1449414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		printk(KERN_ERR "%s: failed to get optimum mode for %s @"
1450414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			" %d uA %d -> %d uV\n", __func__, rdev->desc->name,
1451414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			total_uA_load, input_uV, output_uV);
1452414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		goto out;
1453414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
1454414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1455414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ret = rdev->desc->ops->set_mode(rdev, mode);
1456414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (ret <= 0) {
1457414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		printk(KERN_ERR "%s: failed to set optimum mode %x for %s\n",
1458414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			__func__, mode, rdev->desc->name);
1459414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		goto out;
1460414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
1461414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	ret = mode;
1462414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodout:
1463414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&rdev->mutex);
1464414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
1465414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1466414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_set_optimum_mode);
1467414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1468414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
1469414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_register_notifier - register regulator event notifier
1470414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
1471414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @notifier_block: notifier block
1472414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1473414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Register notifier block to receive regulator events.
1474414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1475414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_register_notifier(struct regulator *regulator,
1476414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			      struct notifier_block *nb)
1477414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1478414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return blocking_notifier_chain_register(&regulator->rdev->notifier,
1479414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood						nb);
1480414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1481414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_register_notifier);
1482414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1483414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
1484414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_unregister_notifier - unregister regulator event notifier
1485414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
1486414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @notifier_block: notifier block
1487414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1488414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Unregister regulator event notifier block.
1489414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1490414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_unregister_notifier(struct regulator *regulator,
1491414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				struct notifier_block *nb)
1492414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1493414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return blocking_notifier_chain_unregister(&regulator->rdev->notifier,
1494414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood						  nb);
1495414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1496414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_unregister_notifier);
1497414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1498414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/* notify regulator consumers and downstream regulator consumers */
1499414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic void _notifier_call_chain(struct regulator_dev *rdev,
1500414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				  unsigned long event, void *data)
1501414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1502414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator_dev *_rdev;
1503414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1504414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* call rdev chain first */
1505414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&rdev->mutex);
1506414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	blocking_notifier_call_chain(&rdev->notifier, event, NULL);
1507414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&rdev->mutex);
1508414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1509414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* now notify regulator we supply */
1510414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	list_for_each_entry(_rdev, &rdev->supply_list, slist)
1511414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		_notifier_call_chain(_rdev, event, data);
1512414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1513414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1514414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
1515414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_bulk_get - get multiple regulator consumers
1516414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1517414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @dev:           Device to supply
1518414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @num_consumers: Number of consumers to register
1519414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @consumers:     Configuration of consumers; clients are stored here.
1520414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1521414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @return 0 on success, an errno on failure.
1522414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1523414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * This helper function allows drivers to get several regulator
1524414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * consumers in one operation.  If any of the regulators cannot be
1525414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * acquired then any regulators that were allocated will be freed
1526414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * before returning to the caller.
1527414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1528414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_bulk_get(struct device *dev, int num_consumers,
1529414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		       struct regulator_bulk_data *consumers)
1530414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1531414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int i;
1532414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret;
1533414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1534414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	for (i = 0; i < num_consumers; i++)
1535414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		consumers[i].consumer = NULL;
1536414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1537414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	for (i = 0; i < num_consumers; i++) {
1538414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		consumers[i].consumer = regulator_get(dev,
1539414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood						      consumers[i].supply);
1540414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (IS_ERR(consumers[i].consumer)) {
1541414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			dev_err(dev, "Failed to get supply '%s'\n",
1542414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				consumers[i].supply);
1543414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			ret = PTR_ERR(consumers[i].consumer);
1544414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			consumers[i].consumer = NULL;
1545414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			goto err;
1546414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		}
1547414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
1548414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1549414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return 0;
1550414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1551414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwooderr:
1552414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	for (i = 0; i < num_consumers && consumers[i].consumer; i++)
1553414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator_put(consumers[i].consumer);
1554414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1555414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
1556414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1557414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_bulk_get);
1558414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1559414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
1560414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_bulk_enable - enable multiple regulator consumers
1561414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1562414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @num_consumers: Number of consumers
1563414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @consumers:     Consumer data; clients are stored here.
1564414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @return         0 on success, an errno on failure
1565414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1566414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * This convenience API allows consumers to enable multiple regulator
1567414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * clients in a single API call.  If any consumers cannot be enabled
1568414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * then any others that were enabled will be disabled again prior to
1569414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * return.
1570414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1571414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_bulk_enable(int num_consumers,
1572414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			  struct regulator_bulk_data *consumers)
1573414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1574414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int i;
1575414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret;
1576414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1577414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	for (i = 0; i < num_consumers; i++) {
1578414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		ret = regulator_enable(consumers[i].consumer);
1579414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (ret != 0)
1580414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			goto err;
1581414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
1582414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1583414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return 0;
1584414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1585414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwooderr:
1586414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	printk(KERN_ERR "Failed to enable %s\n", consumers[i].supply);
1587414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	for (i = 0; i < num_consumers; i++)
1588414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator_disable(consumers[i].consumer);
1589414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1590414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
1591414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1592414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_bulk_enable);
1593414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1594414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
1595414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_bulk_disable - disable multiple regulator consumers
1596414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1597414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @num_consumers: Number of consumers
1598414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @consumers:     Consumer data; clients are stored here.
1599414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @return         0 on success, an errno on failure
1600414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1601414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * This convenience API allows consumers to disable multiple regulator
1602414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * clients in a single API call.  If any consumers cannot be enabled
1603414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * then any others that were disabled will be disabled again prior to
1604414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * return.
1605414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1606414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_bulk_disable(int num_consumers,
1607414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			   struct regulator_bulk_data *consumers)
1608414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1609414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int i;
1610414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret;
1611414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1612414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	for (i = 0; i < num_consumers; i++) {
1613414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		ret = regulator_disable(consumers[i].consumer);
1614414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (ret != 0)
1615414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			goto err;
1616414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
1617414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1618414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return 0;
1619414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1620414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwooderr:
1621414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	printk(KERN_ERR "Failed to disable %s\n", consumers[i].supply);
1622414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	for (i = 0; i < num_consumers; i++)
1623414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator_enable(consumers[i].consumer);
1624414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1625414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
1626414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1627414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_bulk_disable);
1628414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1629414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
1630414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_bulk_free - free multiple regulator consumers
1631414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1632414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @num_consumers: Number of consumers
1633414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @consumers:     Consumer data; clients are stored here.
1634414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1635414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * This convenience API allows consumers to free multiple regulator
1636414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * clients in a single API call.
1637414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1638414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodvoid regulator_bulk_free(int num_consumers,
1639414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			 struct regulator_bulk_data *consumers)
1640414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1641414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int i;
1642414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1643414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	for (i = 0; i < num_consumers; i++) {
1644414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		regulator_put(consumers[i].consumer);
1645414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		consumers[i].consumer = NULL;
1646414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
1647414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1648414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_bulk_free);
1649414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1650414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
1651414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_notifier_call_chain - call regulator event notifier
1652414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
1653414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @event: notifier block
1654414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @data:
1655414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1656414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Called by regulator drivers to notify clients a regulator event has
1657414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * occurred. We also notify regulator clients downstream.
1658414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1659414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_notifier_call_chain(struct regulator_dev *rdev,
1660414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				  unsigned long event, void *data)
1661414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1662414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	_notifier_call_chain(rdev, event, data);
1663414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return NOTIFY_DONE;
1664414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1665414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1666414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_notifier_call_chain);
1667414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1668414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
1669414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_register - register regulator
1670414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
1671414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @reg_data: private regulator data
1672414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1673414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Called by regulator drivers to register a regulator.
1674414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Returns 0 on success.
1675414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1676414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstruct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
1677a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct device *dev, void *driver_data)
1678414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1679414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	static atomic_t regulator_no = ATOMIC_INIT(0);
1680414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator_dev *rdev;
1681a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	struct regulator_init_data *init_data = dev->platform_data;
1682a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	int ret, i;
1683414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1684414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (regulator_desc == NULL)
1685414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return ERR_PTR(-EINVAL);
1686414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1687414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (regulator_desc->name == NULL || regulator_desc->ops == NULL)
1688414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return ERR_PTR(-EINVAL);
1689414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1690414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (!regulator_desc->type == REGULATOR_VOLTAGE &&
1691414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	    !regulator_desc->type == REGULATOR_CURRENT)
1692414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return ERR_PTR(-EINVAL);
1693414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1694414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	rdev = kzalloc(sizeof(struct regulator_dev), GFP_KERNEL);
1695414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (rdev == NULL)
1696414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return ERR_PTR(-ENOMEM);
1697414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1698414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&regulator_list_mutex);
1699414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1700414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_init(&rdev->mutex);
1701a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	rdev->reg_data = driver_data;
1702414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	rdev->owner = regulator_desc->owner;
1703414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	rdev->desc = regulator_desc;
1704414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	INIT_LIST_HEAD(&rdev->consumer_list);
1705414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	INIT_LIST_HEAD(&rdev->supply_list);
1706414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	INIT_LIST_HEAD(&rdev->list);
1707414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	INIT_LIST_HEAD(&rdev->slist);
1708414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier);
1709414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1710a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	/* preform any regulator specific init */
1711a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	if (init_data->regulator_init) {
1712a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		ret = init_data->regulator_init(rdev->reg_data);
1713a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		if (ret < 0) {
1714a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood			kfree(rdev);
1715a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood			rdev = ERR_PTR(ret);
1716a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood			goto out;
1717a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		}
1718a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	}
1719a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
1720a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	/* set regulator constraints */
1721a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	ret = set_machine_constraints(rdev, &init_data->constraints);
1722a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	if (ret < 0) {
1723a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		kfree(rdev);
1724a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		rdev = ERR_PTR(ret);
1725a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		goto out;
1726a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	}
1727a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
1728a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	/* register with sysfs */
1729414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	rdev->dev.class = &regulator_class;
1730a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	rdev->dev.parent = dev;
1731414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	snprintf(rdev->dev.bus_id, sizeof(rdev->dev.bus_id),
1732a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		 "regulator.%d", atomic_inc_return(&regulator_no) - 1);
1733a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	ret = device_register(&rdev->dev);
1734a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	if (ret != 0) {
1735414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		kfree(rdev);
1736414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		rdev = ERR_PTR(ret);
1737a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		goto out;
1738a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	}
1739a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
1740a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	dev_set_drvdata(&rdev->dev, rdev);
1741a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
1742a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	/* set supply regulator if it exists */
1743a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	if (init_data->supply_regulator_dev) {
1744a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		ret = set_supply(rdev,
1745a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood			dev_get_drvdata(init_data->supply_regulator_dev));
1746a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		if (ret < 0) {
1747a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood			device_unregister(&rdev->dev);
1748a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood			kfree(rdev);
1749a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood			rdev = ERR_PTR(ret);
1750a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood			goto out;
1751a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		}
1752a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	}
1753a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
1754a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	/* add consumers devices */
1755a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	for (i = 0; i < init_data->num_consumer_supplies; i++) {
1756a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		ret = set_consumer_device_supply(rdev,
1757a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood			init_data->consumer_supplies[i].dev,
1758a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood			init_data->consumer_supplies[i].supply);
1759a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		if (ret < 0) {
1760a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood			for (--i; i >= 0; i--)
1761a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood				unset_consumer_device_supply(rdev,
1762a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood					init_data->consumer_supplies[i].dev);
1763a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood			device_unregister(&rdev->dev);
1764a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood			kfree(rdev);
1765a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood			rdev = ERR_PTR(ret);
1766a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood			goto out;
1767a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood		}
1768414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
1769a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
1770a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	list_add(&rdev->list, &regulator_list);
1771a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwoodout:
1772414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&regulator_list_mutex);
1773414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return rdev;
1774414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1775414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_register);
1776414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1777414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
1778414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_unregister - unregister regulator
1779414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator source
1780414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1781414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Called by regulator drivers to unregister a regulator.
1782414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1783414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodvoid regulator_unregister(struct regulator_dev *rdev)
1784414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1785414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (rdev == NULL)
1786414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return;
1787414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1788414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&regulator_list_mutex);
1789414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	list_del(&rdev->list);
1790414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (rdev->supply)
1791414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		sysfs_remove_link(&rdev->dev.kobj, "supply");
1792414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	device_unregister(&rdev->dev);
1793414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&regulator_list_mutex);
1794414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1795414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_unregister);
1796414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1797414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
1798414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_suspend_prepare: prepare regulators for system wide suspend
1799414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @state: system suspend state
1800414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1801414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Configure each regulator with it's suspend operating parameters for state.
1802414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * This will usually be called by machine suspend code prior to supending.
1803414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1804414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint regulator_suspend_prepare(suspend_state_t state)
1805414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1806414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	struct regulator_dev *rdev;
1807414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	int ret = 0;
1808414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1809414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	/* ON is handled by regulator active state */
1810414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	if (state == PM_SUSPEND_ON)
1811414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		return -EINVAL;
1812414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1813414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_lock(&regulator_list_mutex);
1814414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	list_for_each_entry(rdev, &regulator_list, list) {
1815414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1816414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		mutex_lock(&rdev->mutex);
1817414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		ret = suspend_prepare(rdev, state);
1818414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		mutex_unlock(&rdev->mutex);
1819414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1820414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		if (ret < 0) {
1821414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			printk(KERN_ERR "%s: failed to prepare %s\n",
1822414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood				__func__, rdev->desc->name);
1823414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood			goto out;
1824414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood		}
1825414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	}
1826414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodout:
1827414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	mutex_unlock(&regulator_list_mutex);
1828414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return ret;
1829414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1830414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_suspend_prepare);
1831414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1832414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
1833414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * rdev_get_drvdata - get rdev regulator driver data
1834414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator
1835414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1836414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Get rdev regulator driver private data. This call can be used in the
1837414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator driver context.
1838414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1839414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodvoid *rdev_get_drvdata(struct regulator_dev *rdev)
1840414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1841414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return rdev->reg_data;
1842414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1843414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(rdev_get_drvdata);
1844414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1845414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
1846414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_get_drvdata - get regulator driver data
1847414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator
1848414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood *
1849414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * Get regulator driver private data. This call can be used in the consumer
1850414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * driver context when non API regulator specific functions need to be called.
1851414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1852414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodvoid *regulator_get_drvdata(struct regulator *regulator)
1853414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1854414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return regulator->rdev->reg_data;
1855414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1856414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_get_drvdata);
1857414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1858414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
1859414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_set_drvdata - set regulator driver data
1860414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator
1861414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @data: data
1862414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1863414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodvoid regulator_set_drvdata(struct regulator *regulator, void *data)
1864414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1865414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	regulator->rdev->reg_data = data;
1866414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1867414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_set_drvdata);
1868414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1869414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/**
1870414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * regulator_get_id - get regulator ID
1871414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood * @regulator: regulator
1872414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood */
1873414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodint rdev_get_id(struct regulator_dev *rdev)
1874414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1875414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return rdev->desc->id;
1876414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1877414c70cb91c445ec813b61e16fe4882807e40240Liam GirdwoodEXPORT_SYMBOL_GPL(rdev_get_id);
1878414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1879a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwoodstruct device *rdev_get_dev(struct regulator_dev *rdev)
1880a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood{
1881a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	return &rdev->dev;
1882a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood}
1883a5766f11cfd3a0c03450d99c8fe548c2940be884Liam GirdwoodEXPORT_SYMBOL_GPL(rdev_get_dev);
1884a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
1885a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwoodvoid *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data)
1886a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood{
1887a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood	return reg_init_data->driver_data;
1888a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood}
1889a5766f11cfd3a0c03450d99c8fe548c2940be884Liam GirdwoodEXPORT_SYMBOL_GPL(regulator_get_init_drvdata);
1890a5766f11cfd3a0c03450d99c8fe548c2940be884Liam Girdwood
1891414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodstatic int __init regulator_init(void)
1892414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood{
1893414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	printk(KERN_INFO "regulator: core version %s\n", REGULATOR_VERSION);
1894414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood	return class_register(&regulator_class);
1895414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood}
1896414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood
1897414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwood/* init early to allow our consumers to complete system booting */
1898414c70cb91c445ec813b61e16fe4882807e40240Liam Girdwoodcore_initcall(regulator_init);
1899