blob: d7e71b5b080ea6b29a88caa8249cb4afe8d6463a [file] [log] [blame]
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001/*
2 * drivers/base/power/domain.c - Common code related to device power domains.
3 *
4 * Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
5 *
6 * This file is released under the GPLv2.
7 */
8
9#include <linux/init.h>
10#include <linux/kernel.h>
11#include <linux/io.h>
12#include <linux/pm_runtime.h>
13#include <linux/pm_domain.h>
Rafael J. Wysocki6ff7bb0d02012-05-01 21:34:07 +020014#include <linux/pm_qos.h>
Rafael J. Wysockif7218892011-07-01 22:12:45 +020015#include <linux/slab.h>
16#include <linux/err.h>
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +020017#include <linux/sched.h>
18#include <linux/suspend.h>
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +010019#include <linux/export.h>
20
21#define GENPD_DEV_CALLBACK(genpd, type, callback, dev) \
22({ \
23 type (*__routine)(struct device *__d); \
24 type __ret = (type)0; \
25 \
26 __routine = genpd->dev_ops.callback; \
27 if (__routine) { \
28 __ret = __routine(dev); \
29 } else { \
30 __routine = dev_gpd_data(dev)->ops.callback; \
31 if (__routine) \
32 __ret = __routine(dev); \
33 } \
34 __ret; \
35})
Rafael J. Wysockif7218892011-07-01 22:12:45 +020036
Rafael J. Wysocki0140d8b2011-12-01 00:02:17 +010037#define GENPD_DEV_TIMED_CALLBACK(genpd, type, callback, dev, field, name) \
38({ \
39 ktime_t __start = ktime_get(); \
40 type __retval = GENPD_DEV_CALLBACK(genpd, type, callback, dev); \
41 s64 __elapsed = ktime_to_ns(ktime_sub(ktime_get(), __start)); \
Rafael J. Wysocki6ff7bb0d02012-05-01 21:34:07 +020042 struct gpd_timing_data *__td = &dev_gpd_data(dev)->td; \
43 if (!__retval && __elapsed > __td->field) { \
44 __td->field = __elapsed; \
Rafael J. Wysocki0140d8b2011-12-01 00:02:17 +010045 dev_warn(dev, name " latency exceeded, new value %lld ns\n", \
46 __elapsed); \
Rafael J. Wysocki6ff7bb0d02012-05-01 21:34:07 +020047 genpd->max_off_time_changed = true; \
48 __td->constraint_changed = true; \
Rafael J. Wysocki0140d8b2011-12-01 00:02:17 +010049 } \
50 __retval; \
51})
52
Rafael J. Wysocki5125bbf2011-07-13 12:31:52 +020053static LIST_HEAD(gpd_list);
54static DEFINE_MUTEX(gpd_list_lock);
55
Rafael J. Wysocki52480512011-07-01 22:13:10 +020056#ifdef CONFIG_PM
57
Rafael J. Wysockib02c9992011-12-01 00:02:05 +010058struct generic_pm_domain *dev_to_genpd(struct device *dev)
Rafael J. Wysocki52480512011-07-01 22:13:10 +020059{
60 if (IS_ERR_OR_NULL(dev->pm_domain))
61 return ERR_PTR(-EINVAL);
62
Rafael J. Wysocki596ba342011-07-01 22:13:19 +020063 return pd_to_genpd(dev->pm_domain);
Rafael J. Wysocki52480512011-07-01 22:13:10 +020064}
Rafael J. Wysockif7218892011-07-01 22:12:45 +020065
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +010066static int genpd_stop_dev(struct generic_pm_domain *genpd, struct device *dev)
67{
Rafael J. Wysocki0140d8b2011-12-01 00:02:17 +010068 return GENPD_DEV_TIMED_CALLBACK(genpd, int, stop, dev,
69 stop_latency_ns, "stop");
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +010070}
71
72static int genpd_start_dev(struct generic_pm_domain *genpd, struct device *dev)
73{
Rafael J. Wysocki0140d8b2011-12-01 00:02:17 +010074 return GENPD_DEV_TIMED_CALLBACK(genpd, int, start, dev,
75 start_latency_ns, "start");
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +010076}
77
Rafael J. Wysockie2e3e4e52012-08-06 01:47:29 +020078static int genpd_start_dev_no_timing(struct generic_pm_domain *genpd,
79 struct device *dev)
80{
81 return GENPD_DEV_CALLBACK(genpd, int, start, dev);
82}
83
Rafael J. Wysockic4bb3162011-08-08 23:43:04 +020084static bool genpd_sd_counter_dec(struct generic_pm_domain *genpd)
Rafael J. Wysockif7218892011-07-01 22:12:45 +020085{
Rafael J. Wysockic4bb3162011-08-08 23:43:04 +020086 bool ret = false;
87
88 if (!WARN_ON(atomic_read(&genpd->sd_count) == 0))
89 ret = !!atomic_dec_and_test(&genpd->sd_count);
90
91 return ret;
92}
93
94static void genpd_sd_counter_inc(struct generic_pm_domain *genpd)
95{
96 atomic_inc(&genpd->sd_count);
97 smp_mb__after_atomic_inc();
Rafael J. Wysockif7218892011-07-01 22:12:45 +020098}
99
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200100static void genpd_acquire_lock(struct generic_pm_domain *genpd)
101{
102 DEFINE_WAIT(wait);
103
104 mutex_lock(&genpd->lock);
105 /*
106 * Wait for the domain to transition into either the active,
107 * or the power off state.
108 */
109 for (;;) {
110 prepare_to_wait(&genpd->status_wait_queue, &wait,
111 TASK_UNINTERRUPTIBLE);
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200112 if (genpd->status == GPD_STATE_ACTIVE
113 || genpd->status == GPD_STATE_POWER_OFF)
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200114 break;
115 mutex_unlock(&genpd->lock);
116
117 schedule();
118
119 mutex_lock(&genpd->lock);
120 }
121 finish_wait(&genpd->status_wait_queue, &wait);
122}
123
124static void genpd_release_lock(struct generic_pm_domain *genpd)
125{
126 mutex_unlock(&genpd->lock);
127}
128
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200129static void genpd_set_active(struct generic_pm_domain *genpd)
130{
131 if (genpd->resume_count == 0)
132 genpd->status = GPD_STATE_ACTIVE;
133}
134
Rafael J. Wysockicbc9ef02012-07-03 19:07:42 +0200135static void genpd_recalc_cpu_exit_latency(struct generic_pm_domain *genpd)
136{
137 s64 usecs64;
138
139 if (!genpd->cpu_data)
140 return;
141
142 usecs64 = genpd->power_on_latency_ns;
143 do_div(usecs64, NSEC_PER_USEC);
144 usecs64 += genpd->cpu_data->saved_exit_latency;
145 genpd->cpu_data->idle_state->exit_latency = usecs64;
146}
147
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200148/**
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200149 * __pm_genpd_poweron - Restore power to a given PM domain and its masters.
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200150 * @genpd: PM domain to power up.
151 *
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200152 * Restore power to @genpd and all of its masters so that it is possible to
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200153 * resume a device belonging to it.
154 */
Sachin Kamat8951ef02012-07-10 21:47:07 +0200155static int __pm_genpd_poweron(struct generic_pm_domain *genpd)
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200156 __releases(&genpd->lock) __acquires(&genpd->lock)
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200157{
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200158 struct gpd_link *link;
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200159 DEFINE_WAIT(wait);
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200160 int ret = 0;
161
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200162 /* If the domain's master is being waited for, we have to wait too. */
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200163 for (;;) {
164 prepare_to_wait(&genpd->status_wait_queue, &wait,
165 TASK_UNINTERRUPTIBLE);
Rafael J. Wysocki17877eb2011-08-08 23:43:50 +0200166 if (genpd->status != GPD_STATE_WAIT_MASTER)
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200167 break;
168 mutex_unlock(&genpd->lock);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200169
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200170 schedule();
Rafael J. Wysocki9e08cf42011-08-08 23:43:22 +0200171
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200172 mutex_lock(&genpd->lock);
173 }
174 finish_wait(&genpd->status_wait_queue, &wait);
175
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200176 if (genpd->status == GPD_STATE_ACTIVE
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200177 || (genpd->prepared_count > 0 && genpd->suspend_power_off))
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200178 return 0;
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200179
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200180 if (genpd->status != GPD_STATE_POWER_OFF) {
181 genpd_set_active(genpd);
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200182 return 0;
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200183 }
184
Rafael J. Wysockicbc9ef02012-07-03 19:07:42 +0200185 if (genpd->cpu_data) {
186 cpuidle_pause_and_lock();
187 genpd->cpu_data->idle_state->disabled = true;
188 cpuidle_resume_and_unlock();
189 goto out;
190 }
191
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200192 /*
193 * The list is guaranteed not to change while the loop below is being
194 * executed, unless one of the masters' .power_on() callbacks fiddles
195 * with it.
196 */
197 list_for_each_entry(link, &genpd->slave_links, slave_node) {
198 genpd_sd_counter_inc(link->master);
Rafael J. Wysocki17877eb2011-08-08 23:43:50 +0200199 genpd->status = GPD_STATE_WAIT_MASTER;
Rafael J. Wysocki3c07cbc2011-08-08 23:43:14 +0200200
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200201 mutex_unlock(&genpd->lock);
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200202
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200203 ret = pm_genpd_poweron(link->master);
Rafael J. Wysocki9e08cf42011-08-08 23:43:22 +0200204
205 mutex_lock(&genpd->lock);
206
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200207 /*
208 * The "wait for parent" status is guaranteed not to change
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200209 * while the master is powering on.
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200210 */
211 genpd->status = GPD_STATE_POWER_OFF;
212 wake_up_all(&genpd->status_wait_queue);
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200213 if (ret) {
214 genpd_sd_counter_dec(link->master);
Rafael J. Wysocki9e08cf42011-08-08 23:43:22 +0200215 goto err;
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200216 }
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200217 }
218
Rafael J. Wysocki9e08cf42011-08-08 23:43:22 +0200219 if (genpd->power_on) {
Rafael J. Wysocki0140d8b2011-12-01 00:02:17 +0100220 ktime_t time_start = ktime_get();
221 s64 elapsed_ns;
222
Rafael J. Wysockife202fd2011-08-05 21:45:11 +0200223 ret = genpd->power_on(genpd);
Rafael J. Wysocki9e08cf42011-08-08 23:43:22 +0200224 if (ret)
225 goto err;
Rafael J. Wysocki0140d8b2011-12-01 00:02:17 +0100226
227 elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
Rafael J. Wysockie84b2c22011-12-06 22:19:54 +0100228 if (elapsed_ns > genpd->power_on_latency_ns) {
Rafael J. Wysocki0140d8b2011-12-01 00:02:17 +0100229 genpd->power_on_latency_ns = elapsed_ns;
Rafael J. Wysocki6ff7bb0d02012-05-01 21:34:07 +0200230 genpd->max_off_time_changed = true;
Rafael J. Wysockicbc9ef02012-07-03 19:07:42 +0200231 genpd_recalc_cpu_exit_latency(genpd);
Rafael J. Wysockie84b2c22011-12-06 22:19:54 +0100232 if (genpd->name)
233 pr_warning("%s: Power-on latency exceeded, "
234 "new value %lld ns\n", genpd->name,
235 elapsed_ns);
236 }
Rafael J. Wysocki3c07cbc2011-08-08 23:43:14 +0200237 }
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200238
Rafael J. Wysockicbc9ef02012-07-03 19:07:42 +0200239 out:
Rafael J. Wysocki9e08cf42011-08-08 23:43:22 +0200240 genpd_set_active(genpd);
241
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200242 return 0;
Rafael J. Wysocki9e08cf42011-08-08 23:43:22 +0200243
244 err:
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200245 list_for_each_entry_continue_reverse(link, &genpd->slave_links, slave_node)
246 genpd_sd_counter_dec(link->master);
Rafael J. Wysocki9e08cf42011-08-08 23:43:22 +0200247
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200248 return ret;
249}
250
251/**
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200252 * pm_genpd_poweron - Restore power to a given PM domain and its masters.
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200253 * @genpd: PM domain to power up.
254 */
255int pm_genpd_poweron(struct generic_pm_domain *genpd)
256{
257 int ret;
258
259 mutex_lock(&genpd->lock);
260 ret = __pm_genpd_poweron(genpd);
261 mutex_unlock(&genpd->lock);
262 return ret;
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200263}
264
265#endif /* CONFIG_PM */
266
267#ifdef CONFIG_PM_RUNTIME
268
Rafael J. Wysocki8e9afaf2012-07-11 22:42:52 +0200269static int genpd_save_dev(struct generic_pm_domain *genpd, struct device *dev)
270{
271 return GENPD_DEV_TIMED_CALLBACK(genpd, int, save_state, dev,
272 save_state_latency_ns, "state save");
273}
274
275static int genpd_restore_dev(struct generic_pm_domain *genpd, struct device *dev)
276{
277 return GENPD_DEV_TIMED_CALLBACK(genpd, int, restore_state, dev,
278 restore_state_latency_ns,
279 "state restore");
280}
281
Rafael J. Wysocki6ff7bb0d02012-05-01 21:34:07 +0200282static int genpd_dev_pm_qos_notifier(struct notifier_block *nb,
283 unsigned long val, void *ptr)
284{
285 struct generic_pm_domain_data *gpd_data;
286 struct device *dev;
287
288 gpd_data = container_of(nb, struct generic_pm_domain_data, nb);
289
290 mutex_lock(&gpd_data->lock);
291 dev = gpd_data->base.dev;
292 if (!dev) {
293 mutex_unlock(&gpd_data->lock);
294 return NOTIFY_DONE;
295 }
296 mutex_unlock(&gpd_data->lock);
297
298 for (;;) {
299 struct generic_pm_domain *genpd;
300 struct pm_domain_data *pdd;
301
302 spin_lock_irq(&dev->power.lock);
303
304 pdd = dev->power.subsys_data ?
305 dev->power.subsys_data->domain_data : NULL;
Rafael J. Wysocki1d5fcfe2012-07-05 22:12:32 +0200306 if (pdd && pdd->dev) {
Rafael J. Wysocki6ff7bb0d02012-05-01 21:34:07 +0200307 to_gpd_data(pdd)->td.constraint_changed = true;
308 genpd = dev_to_genpd(dev);
309 } else {
310 genpd = ERR_PTR(-ENODATA);
311 }
312
313 spin_unlock_irq(&dev->power.lock);
314
315 if (!IS_ERR(genpd)) {
316 mutex_lock(&genpd->lock);
317 genpd->max_off_time_changed = true;
318 mutex_unlock(&genpd->lock);
319 }
320
321 dev = dev->parent;
322 if (!dev || dev->power.ignore_children)
323 break;
324 }
325
326 return NOTIFY_DONE;
327}
328
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200329/**
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200330 * __pm_genpd_save_device - Save the pre-suspend state of a device.
Rafael J. Wysocki4605ab62011-08-25 15:34:12 +0200331 * @pdd: Domain data of the device to save the state of.
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200332 * @genpd: PM domain the device belongs to.
333 */
Rafael J. Wysocki4605ab62011-08-25 15:34:12 +0200334static int __pm_genpd_save_device(struct pm_domain_data *pdd,
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200335 struct generic_pm_domain *genpd)
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200336 __releases(&genpd->lock) __acquires(&genpd->lock)
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200337{
Rafael J. Wysockicd0ea672011-09-26 20:22:02 +0200338 struct generic_pm_domain_data *gpd_data = to_gpd_data(pdd);
Rafael J. Wysocki4605ab62011-08-25 15:34:12 +0200339 struct device *dev = pdd->dev;
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200340 int ret = 0;
341
Rafael J. Wysockicd0ea672011-09-26 20:22:02 +0200342 if (gpd_data->need_restore)
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200343 return 0;
344
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200345 mutex_unlock(&genpd->lock);
346
Rafael J. Wysockiecf00472011-11-27 13:11:44 +0100347 genpd_start_dev(genpd, dev);
348 ret = genpd_save_dev(genpd, dev);
349 genpd_stop_dev(genpd, dev);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200350
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200351 mutex_lock(&genpd->lock);
352
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200353 if (!ret)
Rafael J. Wysockicd0ea672011-09-26 20:22:02 +0200354 gpd_data->need_restore = true;
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200355
356 return ret;
357}
358
359/**
360 * __pm_genpd_restore_device - Restore the pre-suspend state of a device.
Rafael J. Wysocki4605ab62011-08-25 15:34:12 +0200361 * @pdd: Domain data of the device to restore the state of.
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200362 * @genpd: PM domain the device belongs to.
363 */
Rafael J. Wysocki4605ab62011-08-25 15:34:12 +0200364static void __pm_genpd_restore_device(struct pm_domain_data *pdd,
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200365 struct generic_pm_domain *genpd)
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200366 __releases(&genpd->lock) __acquires(&genpd->lock)
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200367{
Rafael J. Wysockicd0ea672011-09-26 20:22:02 +0200368 struct generic_pm_domain_data *gpd_data = to_gpd_data(pdd);
Rafael J. Wysocki4605ab62011-08-25 15:34:12 +0200369 struct device *dev = pdd->dev;
Rafael J. Wysocki80de3d72012-06-16 00:02:34 +0200370 bool need_restore = gpd_data->need_restore;
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200371
Rafael J. Wysocki80de3d72012-06-16 00:02:34 +0200372 gpd_data->need_restore = false;
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200373 mutex_unlock(&genpd->lock);
374
Rafael J. Wysockiecf00472011-11-27 13:11:44 +0100375 genpd_start_dev(genpd, dev);
Rafael J. Wysocki80de3d72012-06-16 00:02:34 +0200376 if (need_restore)
377 genpd_restore_dev(genpd, dev);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200378
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200379 mutex_lock(&genpd->lock);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200380}
381
382/**
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200383 * genpd_abort_poweroff - Check if a PM domain power off should be aborted.
384 * @genpd: PM domain to check.
385 *
386 * Return true if a PM domain's status changed to GPD_STATE_ACTIVE during
387 * a "power off" operation, which means that a "power on" has occured in the
388 * meantime, or if its resume_count field is different from zero, which means
389 * that one of its devices has been resumed in the meantime.
390 */
391static bool genpd_abort_poweroff(struct generic_pm_domain *genpd)
392{
Rafael J. Wysocki17877eb2011-08-08 23:43:50 +0200393 return genpd->status == GPD_STATE_WAIT_MASTER
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200394 || genpd->status == GPD_STATE_ACTIVE || genpd->resume_count > 0;
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200395}
396
397/**
Rafael J. Wysocki56375fd2011-07-12 00:40:03 +0200398 * genpd_queue_power_off_work - Queue up the execution of pm_genpd_poweroff().
399 * @genpd: PM domait to power off.
400 *
401 * Queue up the execution of pm_genpd_poweroff() unless it's already been done
402 * before.
403 */
Rafael J. Wysocki0bc5b2d2011-07-14 20:59:07 +0200404void genpd_queue_power_off_work(struct generic_pm_domain *genpd)
Rafael J. Wysocki56375fd2011-07-12 00:40:03 +0200405{
406 if (!work_pending(&genpd->power_off_work))
407 queue_work(pm_wq, &genpd->power_off_work);
408}
409
410/**
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200411 * pm_genpd_poweroff - Remove power from a given PM domain.
412 * @genpd: PM domain to power down.
413 *
414 * If all of the @genpd's devices have been suspended and all of its subdomains
415 * have been powered down, run the runtime suspend callbacks provided by all of
416 * the @genpd's devices' drivers and remove power from @genpd.
417 */
418static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200419 __releases(&genpd->lock) __acquires(&genpd->lock)
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200420{
Rafael J. Wysocki4605ab62011-08-25 15:34:12 +0200421 struct pm_domain_data *pdd;
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200422 struct gpd_link *link;
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200423 unsigned int not_suspended;
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200424 int ret = 0;
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200425
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200426 start:
427 /*
428 * Do not try to power off the domain in the following situations:
429 * (1) The domain is already in the "power off" state.
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200430 * (2) The domain is waiting for its master to power up.
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200431 * (3) One of the domain's devices is being resumed right now.
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200432 * (4) System suspend is in progress.
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200433 */
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200434 if (genpd->status == GPD_STATE_POWER_OFF
Rafael J. Wysocki17877eb2011-08-08 23:43:50 +0200435 || genpd->status == GPD_STATE_WAIT_MASTER
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200436 || genpd->resume_count > 0 || genpd->prepared_count > 0)
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200437 return 0;
438
Rafael J. Wysockic4bb3162011-08-08 23:43:04 +0200439 if (atomic_read(&genpd->sd_count) > 0)
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200440 return -EBUSY;
441
442 not_suspended = 0;
Rafael J. Wysocki4605ab62011-08-25 15:34:12 +0200443 list_for_each_entry(pdd, &genpd->dev_list, list_node)
Rafael J. Wysocki0aa2a222011-08-25 15:37:04 +0200444 if (pdd->dev->driver && (!pm_runtime_suspended(pdd->dev)
Rafael J. Wysockidbf37412012-08-06 01:46:39 +0200445 || pdd->dev->power.irq_safe || pdd->dev->power.syscore))
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200446 not_suspended++;
447
448 if (not_suspended > genpd->in_progress)
449 return -EBUSY;
450
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200451 if (genpd->poweroff_task) {
452 /*
453 * Another instance of pm_genpd_poweroff() is executing
454 * callbacks, so tell it to start over and return.
455 */
456 genpd->status = GPD_STATE_REPEAT;
457 return 0;
458 }
459
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200460 if (genpd->gov && genpd->gov->power_down_ok) {
461 if (!genpd->gov->power_down_ok(&genpd->domain))
462 return -EAGAIN;
463 }
464
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200465 genpd->status = GPD_STATE_BUSY;
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200466 genpd->poweroff_task = current;
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200467
Rafael J. Wysocki4605ab62011-08-25 15:34:12 +0200468 list_for_each_entry_reverse(pdd, &genpd->dev_list, list_node) {
Rafael J. Wysocki3c07cbc2011-08-08 23:43:14 +0200469 ret = atomic_read(&genpd->sd_count) == 0 ?
Rafael J. Wysocki4605ab62011-08-25 15:34:12 +0200470 __pm_genpd_save_device(pdd, genpd) : -EBUSY;
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200471
472 if (genpd_abort_poweroff(genpd))
473 goto out;
474
Rafael J. Wysocki697a7f32011-07-12 00:39:48 +0200475 if (ret) {
476 genpd_set_active(genpd);
477 goto out;
478 }
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200479
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200480 if (genpd->status == GPD_STATE_REPEAT) {
481 genpd->poweroff_task = NULL;
482 goto start;
483 }
484 }
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200485
Rafael J. Wysockicbc9ef02012-07-03 19:07:42 +0200486 if (genpd->cpu_data) {
487 /*
488 * If cpu_data is set, cpuidle should turn the domain off when
489 * the CPU in it is idle. In that case we don't decrement the
490 * subdomain counts of the master domains, so that power is not
491 * removed from the current domain prematurely as a result of
492 * cutting off the masters' power.
493 */
494 genpd->status = GPD_STATE_POWER_OFF;
495 cpuidle_pause_and_lock();
496 genpd->cpu_data->idle_state->disabled = false;
497 cpuidle_resume_and_unlock();
498 goto out;
499 }
500
Rafael J. Wysocki3c07cbc2011-08-08 23:43:14 +0200501 if (genpd->power_off) {
Rafael J. Wysocki0140d8b2011-12-01 00:02:17 +0100502 ktime_t time_start;
503 s64 elapsed_ns;
504
Rafael J. Wysocki3c07cbc2011-08-08 23:43:14 +0200505 if (atomic_read(&genpd->sd_count) > 0) {
506 ret = -EBUSY;
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200507 goto out;
508 }
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200509
Rafael J. Wysocki0140d8b2011-12-01 00:02:17 +0100510 time_start = ktime_get();
511
Rafael J. Wysocki3c07cbc2011-08-08 23:43:14 +0200512 /*
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200513 * If sd_count > 0 at this point, one of the subdomains hasn't
514 * managed to call pm_genpd_poweron() for the master yet after
Rafael J. Wysocki3c07cbc2011-08-08 23:43:14 +0200515 * incrementing it. In that case pm_genpd_poweron() will wait
516 * for us to drop the lock, so we can call .power_off() and let
517 * the pm_genpd_poweron() restore power for us (this shouldn't
518 * happen very often).
519 */
Rafael J. Wysockid2805402011-07-14 20:59:20 +0200520 ret = genpd->power_off(genpd);
521 if (ret == -EBUSY) {
522 genpd_set_active(genpd);
Rafael J. Wysockid2805402011-07-14 20:59:20 +0200523 goto out;
524 }
Rafael J. Wysocki0140d8b2011-12-01 00:02:17 +0100525
526 elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
Rafael J. Wysockie84b2c22011-12-06 22:19:54 +0100527 if (elapsed_ns > genpd->power_off_latency_ns) {
Rafael J. Wysocki0140d8b2011-12-01 00:02:17 +0100528 genpd->power_off_latency_ns = elapsed_ns;
Rafael J. Wysocki6ff7bb0d02012-05-01 21:34:07 +0200529 genpd->max_off_time_changed = true;
Rafael J. Wysockie84b2c22011-12-06 22:19:54 +0100530 if (genpd->name)
531 pr_warning("%s: Power-off latency exceeded, "
532 "new value %lld ns\n", genpd->name,
533 elapsed_ns);
534 }
Rafael J. Wysockid2805402011-07-14 20:59:20 +0200535 }
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200536
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200537 genpd->status = GPD_STATE_POWER_OFF;
Rafael J. Wysocki221e9b52011-12-01 00:02:10 +0100538
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200539 list_for_each_entry(link, &genpd->slave_links, slave_node) {
540 genpd_sd_counter_dec(link->master);
541 genpd_queue_power_off_work(link->master);
542 }
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200543
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200544 out:
545 genpd->poweroff_task = NULL;
546 wake_up_all(&genpd->status_wait_queue);
547 return ret;
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200548}
549
550/**
551 * genpd_power_off_work_fn - Power off PM domain whose subdomain count is 0.
552 * @work: Work structure used for scheduling the execution of this function.
553 */
554static void genpd_power_off_work_fn(struct work_struct *work)
555{
556 struct generic_pm_domain *genpd;
557
558 genpd = container_of(work, struct generic_pm_domain, power_off_work);
559
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200560 genpd_acquire_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200561 pm_genpd_poweroff(genpd);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200562 genpd_release_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200563}
564
565/**
566 * pm_genpd_runtime_suspend - Suspend a device belonging to I/O PM domain.
567 * @dev: Device to suspend.
568 *
569 * Carry out a runtime suspend of a device under the assumption that its
570 * pm_domain field points to the domain member of an object of type
571 * struct generic_pm_domain representing a PM domain consisting of I/O devices.
572 */
573static int pm_genpd_runtime_suspend(struct device *dev)
574{
575 struct generic_pm_domain *genpd;
Rafael J. Wysockib02c9992011-12-01 00:02:05 +0100576 bool (*stop_ok)(struct device *__dev);
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +0100577 int ret;
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200578
579 dev_dbg(dev, "%s()\n", __func__);
580
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200581 genpd = dev_to_genpd(dev);
582 if (IS_ERR(genpd))
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200583 return -EINVAL;
584
Rafael J. Wysocki0aa2a222011-08-25 15:37:04 +0200585 might_sleep_if(!genpd->dev_irq_safe);
586
Rafael J. Wysockib02c9992011-12-01 00:02:05 +0100587 stop_ok = genpd->gov ? genpd->gov->stop_ok : NULL;
588 if (stop_ok && !stop_ok(dev))
589 return -EBUSY;
590
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +0100591 ret = genpd_stop_dev(genpd, dev);
592 if (ret)
593 return ret;
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200594
Rafael J. Wysocki0aa2a222011-08-25 15:37:04 +0200595 /*
596 * If power.irq_safe is set, this routine will be run with interrupts
597 * off, so it can't use mutexes.
598 */
599 if (dev->power.irq_safe)
600 return 0;
601
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200602 mutex_lock(&genpd->lock);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200603 genpd->in_progress++;
604 pm_genpd_poweroff(genpd);
605 genpd->in_progress--;
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200606 mutex_unlock(&genpd->lock);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200607
608 return 0;
609}
610
611/**
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200612 * pm_genpd_runtime_resume - Resume a device belonging to I/O PM domain.
613 * @dev: Device to resume.
614 *
615 * Carry out a runtime resume of a device under the assumption that its
616 * pm_domain field points to the domain member of an object of type
617 * struct generic_pm_domain representing a PM domain consisting of I/O devices.
618 */
619static int pm_genpd_runtime_resume(struct device *dev)
620{
621 struct generic_pm_domain *genpd;
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200622 DEFINE_WAIT(wait);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200623 int ret;
624
625 dev_dbg(dev, "%s()\n", __func__);
626
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200627 genpd = dev_to_genpd(dev);
628 if (IS_ERR(genpd))
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200629 return -EINVAL;
630
Rafael J. Wysocki0aa2a222011-08-25 15:37:04 +0200631 might_sleep_if(!genpd->dev_irq_safe);
632
633 /* If power.irq_safe, the PM domain is never powered off. */
634 if (dev->power.irq_safe)
Rafael J. Wysockie2e3e4e52012-08-06 01:47:29 +0200635 return genpd_start_dev_no_timing(genpd, dev);
Rafael J. Wysocki0aa2a222011-08-25 15:37:04 +0200636
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200637 mutex_lock(&genpd->lock);
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200638 ret = __pm_genpd_poweron(genpd);
639 if (ret) {
640 mutex_unlock(&genpd->lock);
641 return ret;
642 }
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200643 genpd->status = GPD_STATE_BUSY;
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200644 genpd->resume_count++;
645 for (;;) {
646 prepare_to_wait(&genpd->status_wait_queue, &wait,
647 TASK_UNINTERRUPTIBLE);
648 /*
649 * If current is the powering off task, we have been called
650 * reentrantly from one of the device callbacks, so we should
651 * not wait.
652 */
653 if (!genpd->poweroff_task || genpd->poweroff_task == current)
654 break;
655 mutex_unlock(&genpd->lock);
656
657 schedule();
658
659 mutex_lock(&genpd->lock);
660 }
661 finish_wait(&genpd->status_wait_queue, &wait);
Rafael J. Wysockicd0ea672011-09-26 20:22:02 +0200662 __pm_genpd_restore_device(dev->power.subsys_data->domain_data, genpd);
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200663 genpd->resume_count--;
664 genpd_set_active(genpd);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200665 wake_up_all(&genpd->status_wait_queue);
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200666 mutex_unlock(&genpd->lock);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200667
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200668 return 0;
669}
670
Rafael J. Wysocki17f2ae72011-08-14 13:34:31 +0200671/**
672 * pm_genpd_poweroff_unused - Power off all PM domains with no devices in use.
673 */
674void pm_genpd_poweroff_unused(void)
675{
676 struct generic_pm_domain *genpd;
677
678 mutex_lock(&gpd_list_lock);
679
680 list_for_each_entry(genpd, &gpd_list, gpd_list_node)
681 genpd_queue_power_off_work(genpd);
682
683 mutex_unlock(&gpd_list_lock);
684}
685
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200686#else
687
Rafael J. Wysocki6ff7bb0d02012-05-01 21:34:07 +0200688static inline int genpd_dev_pm_qos_notifier(struct notifier_block *nb,
689 unsigned long val, void *ptr)
690{
691 return NOTIFY_DONE;
692}
693
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200694static inline void genpd_power_off_work_fn(struct work_struct *work) {}
695
696#define pm_genpd_runtime_suspend NULL
697#define pm_genpd_runtime_resume NULL
698
699#endif /* CONFIG_PM_RUNTIME */
700
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200701#ifdef CONFIG_PM_SLEEP
702
Rafael J. Wysocki77f827d2012-08-06 01:39:57 +0200703/**
704 * pm_genpd_present - Check if the given PM domain has been initialized.
705 * @genpd: PM domain to check.
706 */
707static bool pm_genpd_present(struct generic_pm_domain *genpd)
708{
709 struct generic_pm_domain *gpd;
710
711 if (IS_ERR_OR_NULL(genpd))
712 return false;
713
714 list_for_each_entry(gpd, &gpd_list, gpd_list_node)
715 if (gpd == genpd)
716 return true;
717
718 return false;
719}
720
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +0100721static bool genpd_dev_active_wakeup(struct generic_pm_domain *genpd,
722 struct device *dev)
723{
724 return GENPD_DEV_CALLBACK(genpd, bool, active_wakeup, dev);
725}
726
Rafael J. Wysockid23b9b02011-11-27 13:11:51 +0100727static int genpd_suspend_dev(struct generic_pm_domain *genpd, struct device *dev)
728{
729 return GENPD_DEV_CALLBACK(genpd, int, suspend, dev);
730}
731
732static int genpd_suspend_late(struct generic_pm_domain *genpd, struct device *dev)
733{
734 return GENPD_DEV_CALLBACK(genpd, int, suspend_late, dev);
735}
736
737static int genpd_resume_early(struct generic_pm_domain *genpd, struct device *dev)
738{
739 return GENPD_DEV_CALLBACK(genpd, int, resume_early, dev);
740}
741
742static int genpd_resume_dev(struct generic_pm_domain *genpd, struct device *dev)
743{
744 return GENPD_DEV_CALLBACK(genpd, int, resume, dev);
745}
746
747static int genpd_freeze_dev(struct generic_pm_domain *genpd, struct device *dev)
748{
749 return GENPD_DEV_CALLBACK(genpd, int, freeze, dev);
750}
751
752static int genpd_freeze_late(struct generic_pm_domain *genpd, struct device *dev)
753{
754 return GENPD_DEV_CALLBACK(genpd, int, freeze_late, dev);
755}
756
757static int genpd_thaw_early(struct generic_pm_domain *genpd, struct device *dev)
758{
759 return GENPD_DEV_CALLBACK(genpd, int, thaw_early, dev);
760}
761
762static int genpd_thaw_dev(struct generic_pm_domain *genpd, struct device *dev)
763{
764 return GENPD_DEV_CALLBACK(genpd, int, thaw, dev);
765}
766
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200767/**
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200768 * pm_genpd_sync_poweroff - Synchronously power off a PM domain and its masters.
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200769 * @genpd: PM domain to power off, if possible.
770 *
771 * Check if the given PM domain can be powered off (during system suspend or
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200772 * hibernation) and do that if so. Also, in that case propagate to its masters.
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200773 *
Rafael J. Wysocki77f827d2012-08-06 01:39:57 +0200774 * This function is only called in "noirq" and "syscore" stages of system power
775 * transitions, so it need not acquire locks (all of the "noirq" callbacks are
776 * executed sequentially, so it is guaranteed that it will never run twice in
777 * parallel).
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200778 */
779static void pm_genpd_sync_poweroff(struct generic_pm_domain *genpd)
780{
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200781 struct gpd_link *link;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200782
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200783 if (genpd->status == GPD_STATE_POWER_OFF)
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200784 return;
785
Rafael J. Wysockic4bb3162011-08-08 23:43:04 +0200786 if (genpd->suspended_count != genpd->device_count
787 || atomic_read(&genpd->sd_count) > 0)
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200788 return;
789
790 if (genpd->power_off)
791 genpd->power_off(genpd);
792
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200793 genpd->status = GPD_STATE_POWER_OFF;
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200794
795 list_for_each_entry(link, &genpd->slave_links, slave_node) {
796 genpd_sd_counter_dec(link->master);
797 pm_genpd_sync_poweroff(link->master);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200798 }
799}
800
801/**
Rafael J. Wysocki802d8b42012-08-06 01:39:16 +0200802 * pm_genpd_sync_poweron - Synchronously power on a PM domain and its masters.
803 * @genpd: PM domain to power on.
804 *
Rafael J. Wysocki77f827d2012-08-06 01:39:57 +0200805 * This function is only called in "noirq" and "syscore" stages of system power
806 * transitions, so it need not acquire locks (all of the "noirq" callbacks are
807 * executed sequentially, so it is guaranteed that it will never run twice in
808 * parallel).
Rafael J. Wysocki802d8b42012-08-06 01:39:16 +0200809 */
810static void pm_genpd_sync_poweron(struct generic_pm_domain *genpd)
811{
812 struct gpd_link *link;
813
814 if (genpd->status != GPD_STATE_POWER_OFF)
815 return;
816
817 list_for_each_entry(link, &genpd->slave_links, slave_node) {
818 pm_genpd_sync_poweron(link->master);
819 genpd_sd_counter_inc(link->master);
820 }
821
822 if (genpd->power_on)
823 genpd->power_on(genpd);
824
825 genpd->status = GPD_STATE_ACTIVE;
826}
827
828/**
Rafael J. Wysocki4ecd6e62011-07-12 00:39:57 +0200829 * resume_needed - Check whether to resume a device before system suspend.
830 * @dev: Device to check.
831 * @genpd: PM domain the device belongs to.
832 *
833 * There are two cases in which a device that can wake up the system from sleep
834 * states should be resumed by pm_genpd_prepare(): (1) if the device is enabled
835 * to wake up the system and it has to remain active for this purpose while the
836 * system is in the sleep state and (2) if the device is not enabled to wake up
837 * the system from sleep states and it generally doesn't generate wakeup signals
838 * by itself (those signals are generated on its behalf by other parts of the
839 * system). In the latter case it may be necessary to reconfigure the device's
840 * wakeup settings during system suspend, because it may have been set up to
841 * signal remote wakeup from the system's working state as needed by runtime PM.
842 * Return 'true' in either of the above cases.
843 */
844static bool resume_needed(struct device *dev, struct generic_pm_domain *genpd)
845{
846 bool active_wakeup;
847
848 if (!device_can_wakeup(dev))
849 return false;
850
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +0100851 active_wakeup = genpd_dev_active_wakeup(genpd, dev);
Rafael J. Wysocki4ecd6e62011-07-12 00:39:57 +0200852 return device_may_wakeup(dev) ? active_wakeup : !active_wakeup;
853}
854
855/**
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200856 * pm_genpd_prepare - Start power transition of a device in a PM domain.
857 * @dev: Device to start the transition of.
858 *
859 * Start a power transition of a device (during a system-wide power transition)
860 * under the assumption that its pm_domain field points to the domain member of
861 * an object of type struct generic_pm_domain representing a PM domain
862 * consisting of I/O devices.
863 */
864static int pm_genpd_prepare(struct device *dev)
865{
866 struct generic_pm_domain *genpd;
Rafael J. Wysockib6c10c82011-07-12 00:39:21 +0200867 int ret;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200868
869 dev_dbg(dev, "%s()\n", __func__);
870
871 genpd = dev_to_genpd(dev);
872 if (IS_ERR(genpd))
873 return -EINVAL;
874
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200875 /*
876 * If a wakeup request is pending for the device, it should be woken up
877 * at this point and a system wakeup event should be reported if it's
878 * set up to wake up the system from sleep states.
879 */
880 pm_runtime_get_noresume(dev);
881 if (pm_runtime_barrier(dev) && device_may_wakeup(dev))
882 pm_wakeup_event(dev, 0);
883
884 if (pm_wakeup_pending()) {
885 pm_runtime_put_sync(dev);
886 return -EBUSY;
887 }
888
Rafael J. Wysocki4ecd6e62011-07-12 00:39:57 +0200889 if (resume_needed(dev, genpd))
890 pm_runtime_resume(dev);
891
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200892 genpd_acquire_lock(genpd);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200893
Rafael J. Wysocki65533bb2012-03-13 22:39:37 +0100894 if (genpd->prepared_count++ == 0) {
895 genpd->suspended_count = 0;
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200896 genpd->suspend_power_off = genpd->status == GPD_STATE_POWER_OFF;
Rafael J. Wysocki65533bb2012-03-13 22:39:37 +0100897 }
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200898
899 genpd_release_lock(genpd);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200900
901 if (genpd->suspend_power_off) {
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200902 pm_runtime_put_noidle(dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200903 return 0;
904 }
905
906 /*
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200907 * The PM domain must be in the GPD_STATE_ACTIVE state at this point,
908 * so pm_genpd_poweron() will return immediately, but if the device
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +0100909 * is suspended (e.g. it's been stopped by genpd_stop_dev()), we need
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200910 * to make it operational.
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200911 */
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200912 pm_runtime_resume(dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200913 __pm_runtime_disable(dev, false);
914
Rafael J. Wysockib6c10c82011-07-12 00:39:21 +0200915 ret = pm_generic_prepare(dev);
916 if (ret) {
917 mutex_lock(&genpd->lock);
918
919 if (--genpd->prepared_count == 0)
920 genpd->suspend_power_off = false;
921
922 mutex_unlock(&genpd->lock);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200923 pm_runtime_enable(dev);
Rafael J. Wysockib6c10c82011-07-12 00:39:21 +0200924 }
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200925
926 pm_runtime_put_sync(dev);
Rafael J. Wysockib6c10c82011-07-12 00:39:21 +0200927 return ret;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200928}
929
930/**
931 * pm_genpd_suspend - Suspend a device belonging to an I/O PM domain.
932 * @dev: Device to suspend.
933 *
934 * Suspend a device under the assumption that its pm_domain field points to the
935 * domain member of an object of type struct generic_pm_domain representing
936 * a PM domain consisting of I/O devices.
937 */
938static int pm_genpd_suspend(struct device *dev)
939{
940 struct generic_pm_domain *genpd;
941
942 dev_dbg(dev, "%s()\n", __func__);
943
944 genpd = dev_to_genpd(dev);
945 if (IS_ERR(genpd))
946 return -EINVAL;
947
Rafael J. Wysockid23b9b02011-11-27 13:11:51 +0100948 return genpd->suspend_power_off ? 0 : genpd_suspend_dev(genpd, dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200949}
950
951/**
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +0100952 * pm_genpd_suspend_late - Late suspend of a device from an I/O PM domain.
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200953 * @dev: Device to suspend.
954 *
955 * Carry out a late suspend of a device under the assumption that its
956 * pm_domain field points to the domain member of an object of type
957 * struct generic_pm_domain representing a PM domain consisting of I/O devices.
958 */
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +0100959static int pm_genpd_suspend_late(struct device *dev)
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200960{
961 struct generic_pm_domain *genpd;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200962
963 dev_dbg(dev, "%s()\n", __func__);
964
965 genpd = dev_to_genpd(dev);
966 if (IS_ERR(genpd))
967 return -EINVAL;
968
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +0100969 return genpd->suspend_power_off ? 0 : genpd_suspend_late(genpd, dev);
970}
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200971
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +0100972/**
973 * pm_genpd_suspend_noirq - Completion of suspend of device in an I/O PM domain.
974 * @dev: Device to suspend.
975 *
976 * Stop the device and remove power from the domain if all devices in it have
977 * been stopped.
978 */
979static int pm_genpd_suspend_noirq(struct device *dev)
980{
981 struct generic_pm_domain *genpd;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200982
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +0100983 dev_dbg(dev, "%s()\n", __func__);
984
985 genpd = dev_to_genpd(dev);
986 if (IS_ERR(genpd))
987 return -EINVAL;
988
Rafael J. Wysockidbf37412012-08-06 01:46:39 +0200989 if (genpd->suspend_power_off
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +0100990 || (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev)))
Rafael J. Wysockid4f2d872011-07-01 22:13:29 +0200991 return 0;
992
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +0100993 genpd_stop_dev(genpd, dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200994
995 /*
996 * Since all of the "noirq" callbacks are executed sequentially, it is
997 * guaranteed that this function will never run twice in parallel for
998 * the same PM domain, so it is not necessary to use locking here.
999 */
1000 genpd->suspended_count++;
1001 pm_genpd_sync_poweroff(genpd);
1002
1003 return 0;
1004}
1005
1006/**
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +01001007 * pm_genpd_resume_noirq - Start of resume of device in an I/O PM domain.
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001008 * @dev: Device to resume.
1009 *
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +01001010 * Restore power to the device's PM domain, if necessary, and start the device.
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001011 */
1012static int pm_genpd_resume_noirq(struct device *dev)
1013{
1014 struct generic_pm_domain *genpd;
1015
1016 dev_dbg(dev, "%s()\n", __func__);
1017
1018 genpd = dev_to_genpd(dev);
1019 if (IS_ERR(genpd))
1020 return -EINVAL;
1021
Rafael J. Wysockidbf37412012-08-06 01:46:39 +02001022 if (genpd->suspend_power_off
Rafael J. Wysockicc85b202012-03-13 22:39:31 +01001023 || (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev)))
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001024 return 0;
1025
1026 /*
1027 * Since all of the "noirq" callbacks are executed sequentially, it is
1028 * guaranteed that this function will never run twice in parallel for
1029 * the same PM domain, so it is not necessary to use locking here.
1030 */
Rafael J. Wysocki802d8b42012-08-06 01:39:16 +02001031 pm_genpd_sync_poweron(genpd);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001032 genpd->suspended_count--;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001033
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +01001034 return genpd_start_dev(genpd, dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001035}
1036
1037/**
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +01001038 * pm_genpd_resume_early - Early resume of a device in an I/O PM domain.
1039 * @dev: Device to resume.
1040 *
1041 * Carry out an early resume of a device under the assumption that its
1042 * pm_domain field points to the domain member of an object of type
1043 * struct generic_pm_domain representing a power domain consisting of I/O
1044 * devices.
1045 */
1046static int pm_genpd_resume_early(struct device *dev)
1047{
1048 struct generic_pm_domain *genpd;
1049
1050 dev_dbg(dev, "%s()\n", __func__);
1051
1052 genpd = dev_to_genpd(dev);
1053 if (IS_ERR(genpd))
1054 return -EINVAL;
1055
1056 return genpd->suspend_power_off ? 0 : genpd_resume_early(genpd, dev);
1057}
1058
1059/**
1060 * pm_genpd_resume - Resume of device in an I/O PM domain.
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001061 * @dev: Device to resume.
1062 *
1063 * Resume a device under the assumption that its pm_domain field points to the
1064 * domain member of an object of type struct generic_pm_domain representing
1065 * a power domain consisting of I/O devices.
1066 */
1067static int pm_genpd_resume(struct device *dev)
1068{
1069 struct generic_pm_domain *genpd;
1070
1071 dev_dbg(dev, "%s()\n", __func__);
1072
1073 genpd = dev_to_genpd(dev);
1074 if (IS_ERR(genpd))
1075 return -EINVAL;
1076
Rafael J. Wysockid23b9b02011-11-27 13:11:51 +01001077 return genpd->suspend_power_off ? 0 : genpd_resume_dev(genpd, dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001078}
1079
1080/**
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +01001081 * pm_genpd_freeze - Freezing a device in an I/O PM domain.
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001082 * @dev: Device to freeze.
1083 *
1084 * Freeze a device under the assumption that its pm_domain field points to the
1085 * domain member of an object of type struct generic_pm_domain representing
1086 * a power domain consisting of I/O devices.
1087 */
1088static int pm_genpd_freeze(struct device *dev)
1089{
1090 struct generic_pm_domain *genpd;
1091
1092 dev_dbg(dev, "%s()\n", __func__);
1093
1094 genpd = dev_to_genpd(dev);
1095 if (IS_ERR(genpd))
1096 return -EINVAL;
1097
Rafael J. Wysockid23b9b02011-11-27 13:11:51 +01001098 return genpd->suspend_power_off ? 0 : genpd_freeze_dev(genpd, dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001099}
1100
1101/**
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +01001102 * pm_genpd_freeze_late - Late freeze of a device in an I/O PM domain.
1103 * @dev: Device to freeze.
1104 *
1105 * Carry out a late freeze of a device under the assumption that its
1106 * pm_domain field points to the domain member of an object of type
1107 * struct generic_pm_domain representing a power domain consisting of I/O
1108 * devices.
1109 */
1110static int pm_genpd_freeze_late(struct device *dev)
1111{
1112 struct generic_pm_domain *genpd;
1113
1114 dev_dbg(dev, "%s()\n", __func__);
1115
1116 genpd = dev_to_genpd(dev);
1117 if (IS_ERR(genpd))
1118 return -EINVAL;
1119
1120 return genpd->suspend_power_off ? 0 : genpd_freeze_late(genpd, dev);
1121}
1122
1123/**
1124 * pm_genpd_freeze_noirq - Completion of freezing a device in an I/O PM domain.
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001125 * @dev: Device to freeze.
1126 *
1127 * Carry out a late freeze of a device under the assumption that its
1128 * pm_domain field points to the domain member of an object of type
1129 * struct generic_pm_domain representing a power domain consisting of I/O
1130 * devices.
1131 */
1132static int pm_genpd_freeze_noirq(struct device *dev)
1133{
1134 struct generic_pm_domain *genpd;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001135
1136 dev_dbg(dev, "%s()\n", __func__);
1137
1138 genpd = dev_to_genpd(dev);
1139 if (IS_ERR(genpd))
1140 return -EINVAL;
1141
Rafael J. Wysockidbf37412012-08-06 01:46:39 +02001142 return genpd->suspend_power_off ? 0 : genpd_stop_dev(genpd, dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001143}
1144
1145/**
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +01001146 * pm_genpd_thaw_noirq - Early thaw of device in an I/O PM domain.
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001147 * @dev: Device to thaw.
1148 *
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +01001149 * Start the device, unless power has been removed from the domain already
1150 * before the system transition.
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001151 */
1152static int pm_genpd_thaw_noirq(struct device *dev)
1153{
1154 struct generic_pm_domain *genpd;
1155
1156 dev_dbg(dev, "%s()\n", __func__);
1157
1158 genpd = dev_to_genpd(dev);
1159 if (IS_ERR(genpd))
1160 return -EINVAL;
1161
Rafael J. Wysockidbf37412012-08-06 01:46:39 +02001162 return genpd->suspend_power_off ? 0 : genpd_start_dev(genpd, dev);
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +01001163}
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001164
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +01001165/**
1166 * pm_genpd_thaw_early - Early thaw of device in an I/O PM domain.
1167 * @dev: Device to thaw.
1168 *
1169 * Carry out an early thaw of a device under the assumption that its
1170 * pm_domain field points to the domain member of an object of type
1171 * struct generic_pm_domain representing a power domain consisting of I/O
1172 * devices.
1173 */
1174static int pm_genpd_thaw_early(struct device *dev)
1175{
1176 struct generic_pm_domain *genpd;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001177
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +01001178 dev_dbg(dev, "%s()\n", __func__);
1179
1180 genpd = dev_to_genpd(dev);
1181 if (IS_ERR(genpd))
1182 return -EINVAL;
1183
1184 return genpd->suspend_power_off ? 0 : genpd_thaw_early(genpd, dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001185}
1186
1187/**
1188 * pm_genpd_thaw - Thaw a device belonging to an I/O power domain.
1189 * @dev: Device to thaw.
1190 *
1191 * Thaw a device under the assumption that its pm_domain field points to the
1192 * domain member of an object of type struct generic_pm_domain representing
1193 * a power domain consisting of I/O devices.
1194 */
1195static int pm_genpd_thaw(struct device *dev)
1196{
1197 struct generic_pm_domain *genpd;
1198
1199 dev_dbg(dev, "%s()\n", __func__);
1200
1201 genpd = dev_to_genpd(dev);
1202 if (IS_ERR(genpd))
1203 return -EINVAL;
1204
Rafael J. Wysockid23b9b02011-11-27 13:11:51 +01001205 return genpd->suspend_power_off ? 0 : genpd_thaw_dev(genpd, dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001206}
1207
1208/**
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +01001209 * pm_genpd_restore_noirq - Start of restore of device in an I/O PM domain.
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001210 * @dev: Device to resume.
1211 *
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +01001212 * Make sure the domain will be in the same power state as before the
1213 * hibernation the system is resuming from and start the device if necessary.
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001214 */
1215static int pm_genpd_restore_noirq(struct device *dev)
1216{
1217 struct generic_pm_domain *genpd;
1218
1219 dev_dbg(dev, "%s()\n", __func__);
1220
1221 genpd = dev_to_genpd(dev);
1222 if (IS_ERR(genpd))
1223 return -EINVAL;
1224
1225 /*
1226 * Since all of the "noirq" callbacks are executed sequentially, it is
1227 * guaranteed that this function will never run twice in parallel for
1228 * the same PM domain, so it is not necessary to use locking here.
Rafael J. Wysocki65533bb2012-03-13 22:39:37 +01001229 *
1230 * At this point suspended_count == 0 means we are being run for the
1231 * first time for the given domain in the present cycle.
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001232 */
Rafael J. Wysocki65533bb2012-03-13 22:39:37 +01001233 if (genpd->suspended_count++ == 0) {
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001234 /*
Rafael J. Wysocki65533bb2012-03-13 22:39:37 +01001235 * The boot kernel might put the domain into arbitrary state,
Rafael J. Wysocki802d8b42012-08-06 01:39:16 +02001236 * so make it appear as powered off to pm_genpd_sync_poweron(),
1237 * so that it tries to power it on in case it was really off.
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001238 */
Rafael J. Wysocki65533bb2012-03-13 22:39:37 +01001239 genpd->status = GPD_STATE_POWER_OFF;
1240 if (genpd->suspend_power_off) {
1241 /*
1242 * If the domain was off before the hibernation, make
1243 * sure it will be off going forward.
1244 */
1245 if (genpd->power_off)
1246 genpd->power_off(genpd);
1247
1248 return 0;
1249 }
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001250 }
1251
Rafael J. Wysocki18dd2ec2012-03-19 10:38:14 +01001252 if (genpd->suspend_power_off)
1253 return 0;
1254
Rafael J. Wysocki802d8b42012-08-06 01:39:16 +02001255 pm_genpd_sync_poweron(genpd);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001256
Rafael J. Wysockidbf37412012-08-06 01:46:39 +02001257 return genpd_start_dev(genpd, dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001258}
1259
1260/**
1261 * pm_genpd_complete - Complete power transition of a device in a power domain.
1262 * @dev: Device to complete the transition of.
1263 *
1264 * Complete a power transition of a device (during a system-wide power
1265 * transition) under the assumption that its pm_domain field points to the
1266 * domain member of an object of type struct generic_pm_domain representing
1267 * a power domain consisting of I/O devices.
1268 */
1269static void pm_genpd_complete(struct device *dev)
1270{
1271 struct generic_pm_domain *genpd;
1272 bool run_complete;
1273
1274 dev_dbg(dev, "%s()\n", __func__);
1275
1276 genpd = dev_to_genpd(dev);
1277 if (IS_ERR(genpd))
1278 return;
1279
1280 mutex_lock(&genpd->lock);
1281
1282 run_complete = !genpd->suspend_power_off;
1283 if (--genpd->prepared_count == 0)
1284 genpd->suspend_power_off = false;
1285
1286 mutex_unlock(&genpd->lock);
1287
1288 if (run_complete) {
1289 pm_generic_complete(dev);
Rafael J. Wysocki6f00ff72011-07-12 00:39:10 +02001290 pm_runtime_set_active(dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001291 pm_runtime_enable(dev);
Rafael J. Wysocki6f00ff72011-07-12 00:39:10 +02001292 pm_runtime_idle(dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001293 }
1294}
1295
Rafael J. Wysocki77f827d2012-08-06 01:39:57 +02001296/**
1297 * pm_genpd_syscore_switch - Switch power during system core suspend or resume.
1298 * @dev: Device that normally is marked as "always on" to switch power for.
1299 *
1300 * This routine may only be called during the system core (syscore) suspend or
1301 * resume phase for devices whose "always on" flags are set.
1302 */
1303void pm_genpd_syscore_switch(struct device *dev, bool suspend)
1304{
1305 struct generic_pm_domain *genpd;
1306
1307 genpd = dev_to_genpd(dev);
1308 if (!pm_genpd_present(genpd))
1309 return;
1310
1311 if (suspend) {
1312 genpd->suspended_count++;
1313 pm_genpd_sync_poweroff(genpd);
1314 } else {
1315 pm_genpd_sync_poweron(genpd);
1316 genpd->suspended_count--;
1317 }
1318}
1319EXPORT_SYMBOL_GPL(pm_genpd_syscore_switch);
1320
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001321#else
1322
1323#define pm_genpd_prepare NULL
1324#define pm_genpd_suspend NULL
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +01001325#define pm_genpd_suspend_late NULL
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001326#define pm_genpd_suspend_noirq NULL
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +01001327#define pm_genpd_resume_early NULL
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001328#define pm_genpd_resume_noirq NULL
1329#define pm_genpd_resume NULL
1330#define pm_genpd_freeze NULL
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +01001331#define pm_genpd_freeze_late NULL
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001332#define pm_genpd_freeze_noirq NULL
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +01001333#define pm_genpd_thaw_early NULL
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001334#define pm_genpd_thaw_noirq NULL
1335#define pm_genpd_thaw NULL
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001336#define pm_genpd_restore_noirq NULL
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001337#define pm_genpd_complete NULL
1338
1339#endif /* CONFIG_PM_SLEEP */
1340
Rafael J. Wysocki1d5fcfe2012-07-05 22:12:32 +02001341static struct generic_pm_domain_data *__pm_genpd_alloc_dev_data(struct device *dev)
1342{
1343 struct generic_pm_domain_data *gpd_data;
1344
1345 gpd_data = kzalloc(sizeof(*gpd_data), GFP_KERNEL);
1346 if (!gpd_data)
1347 return NULL;
1348
1349 mutex_init(&gpd_data->lock);
1350 gpd_data->nb.notifier_call = genpd_dev_pm_qos_notifier;
1351 dev_pm_qos_add_notifier(dev, &gpd_data->nb);
1352 return gpd_data;
1353}
1354
1355static void __pm_genpd_free_dev_data(struct device *dev,
1356 struct generic_pm_domain_data *gpd_data)
1357{
1358 dev_pm_qos_remove_notifier(dev, &gpd_data->nb);
1359 kfree(gpd_data);
1360}
1361
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001362/**
Rafael J. Wysockib02c9992011-12-01 00:02:05 +01001363 * __pm_genpd_add_device - Add a device to an I/O PM domain.
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001364 * @genpd: PM domain to add the device to.
1365 * @dev: Device to be added.
Rafael J. Wysockib02c9992011-12-01 00:02:05 +01001366 * @td: Set of PM QoS timing parameters to attach to the device.
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001367 */
Rafael J. Wysockib02c9992011-12-01 00:02:05 +01001368int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
1369 struct gpd_timing_data *td)
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001370{
Rafael J. Wysocki1d5fcfe2012-07-05 22:12:32 +02001371 struct generic_pm_domain_data *gpd_data_new, *gpd_data = NULL;
Rafael J. Wysocki4605ab62011-08-25 15:34:12 +02001372 struct pm_domain_data *pdd;
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001373 int ret = 0;
1374
1375 dev_dbg(dev, "%s()\n", __func__);
1376
1377 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev))
1378 return -EINVAL;
1379
Rafael J. Wysocki1d5fcfe2012-07-05 22:12:32 +02001380 gpd_data_new = __pm_genpd_alloc_dev_data(dev);
1381 if (!gpd_data_new)
Rafael J. Wysocki6ff7bb0d02012-05-01 21:34:07 +02001382 return -ENOMEM;
1383
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001384 genpd_acquire_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001385
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001386 if (genpd->prepared_count > 0) {
1387 ret = -EAGAIN;
1388 goto out;
1389 }
1390
Rafael J. Wysocki4605ab62011-08-25 15:34:12 +02001391 list_for_each_entry(pdd, &genpd->dev_list, list_node)
1392 if (pdd->dev == dev) {
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001393 ret = -EINVAL;
1394 goto out;
1395 }
1396
Rafael J. Wysocki1d5fcfe2012-07-05 22:12:32 +02001397 ret = dev_pm_get_subsys_data(dev);
1398 if (ret)
1399 goto out;
1400
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001401 genpd->device_count++;
Rafael J. Wysocki6ff7bb0d02012-05-01 21:34:07 +02001402 genpd->max_off_time_changed = true;
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001403
Rafael J. Wysocki6ff7bb0d02012-05-01 21:34:07 +02001404 spin_lock_irq(&dev->power.lock);
Rafael J. Wysocki1d5fcfe2012-07-05 22:12:32 +02001405
Rafael J. Wysocki6ff7bb0d02012-05-01 21:34:07 +02001406 dev->pm_domain = &genpd->domain;
Rafael J. Wysocki1d5fcfe2012-07-05 22:12:32 +02001407 if (dev->power.subsys_data->domain_data) {
1408 gpd_data = to_gpd_data(dev->power.subsys_data->domain_data);
1409 } else {
1410 gpd_data = gpd_data_new;
1411 dev->power.subsys_data->domain_data = &gpd_data->base;
1412 }
1413 gpd_data->refcount++;
Rafael J. Wysockib02c9992011-12-01 00:02:05 +01001414 if (td)
1415 gpd_data->td = *td;
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001416
Rafael J. Wysocki1d5fcfe2012-07-05 22:12:32 +02001417 spin_unlock_irq(&dev->power.lock);
1418
1419 mutex_lock(&gpd_data->lock);
1420 gpd_data->base.dev = dev;
1421 list_add_tail(&gpd_data->base.list_node, &genpd->dev_list);
1422 gpd_data->need_restore = genpd->status == GPD_STATE_POWER_OFF;
Rafael J. Wysocki6ff7bb0d02012-05-01 21:34:07 +02001423 gpd_data->td.constraint_changed = true;
1424 gpd_data->td.effective_constraint_ns = -1;
Rafael J. Wysocki6ff7bb0d02012-05-01 21:34:07 +02001425 mutex_unlock(&gpd_data->lock);
1426
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001427 out:
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001428 genpd_release_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001429
Rafael J. Wysocki1d5fcfe2012-07-05 22:12:32 +02001430 if (gpd_data != gpd_data_new)
1431 __pm_genpd_free_dev_data(dev, gpd_data_new);
1432
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001433 return ret;
1434}
1435
1436/**
Thomas Abrahamc8aa1302012-01-27 15:22:07 +09001437 * __pm_genpd_of_add_device - Add a device to an I/O PM domain.
1438 * @genpd_node: Device tree node pointer representing a PM domain to which the
1439 * the device is added to.
1440 * @dev: Device to be added.
1441 * @td: Set of PM QoS timing parameters to attach to the device.
1442 */
1443int __pm_genpd_of_add_device(struct device_node *genpd_node, struct device *dev,
1444 struct gpd_timing_data *td)
1445{
1446 struct generic_pm_domain *genpd = NULL, *gpd;
1447
1448 dev_dbg(dev, "%s()\n", __func__);
1449
1450 if (IS_ERR_OR_NULL(genpd_node) || IS_ERR_OR_NULL(dev))
1451 return -EINVAL;
1452
1453 mutex_lock(&gpd_list_lock);
1454 list_for_each_entry(gpd, &gpd_list, gpd_list_node) {
1455 if (gpd->of_node == genpd_node) {
1456 genpd = gpd;
1457 break;
1458 }
1459 }
1460 mutex_unlock(&gpd_list_lock);
1461
1462 if (!genpd)
1463 return -EINVAL;
1464
1465 return __pm_genpd_add_device(genpd, dev, td);
1466}
1467
1468/**
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001469 * pm_genpd_remove_device - Remove a device from an I/O PM domain.
1470 * @genpd: PM domain to remove the device from.
1471 * @dev: Device to be removed.
1472 */
1473int pm_genpd_remove_device(struct generic_pm_domain *genpd,
1474 struct device *dev)
1475{
Rafael J. Wysocki6ff7bb0d02012-05-01 21:34:07 +02001476 struct generic_pm_domain_data *gpd_data;
Rafael J. Wysocki4605ab62011-08-25 15:34:12 +02001477 struct pm_domain_data *pdd;
Rafael J. Wysocki1d5fcfe2012-07-05 22:12:32 +02001478 bool remove = false;
Rafael J. Wysockiefa69022012-05-01 21:33:53 +02001479 int ret = 0;
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001480
1481 dev_dbg(dev, "%s()\n", __func__);
1482
Rafael J. Wysockiefa69022012-05-01 21:33:53 +02001483 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev)
1484 || IS_ERR_OR_NULL(dev->pm_domain)
1485 || pd_to_genpd(dev->pm_domain) != genpd)
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001486 return -EINVAL;
1487
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001488 genpd_acquire_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001489
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001490 if (genpd->prepared_count > 0) {
1491 ret = -EAGAIN;
1492 goto out;
1493 }
1494
Rafael J. Wysocki6ff7bb0d02012-05-01 21:34:07 +02001495 genpd->device_count--;
1496 genpd->max_off_time_changed = true;
1497
1498 spin_lock_irq(&dev->power.lock);
Rafael J. Wysocki1d5fcfe2012-07-05 22:12:32 +02001499
Rafael J. Wysockiefa69022012-05-01 21:33:53 +02001500 dev->pm_domain = NULL;
1501 pdd = dev->power.subsys_data->domain_data;
1502 list_del_init(&pdd->list_node);
Rafael J. Wysocki1d5fcfe2012-07-05 22:12:32 +02001503 gpd_data = to_gpd_data(pdd);
1504 if (--gpd_data->refcount == 0) {
1505 dev->power.subsys_data->domain_data = NULL;
1506 remove = true;
1507 }
1508
Rafael J. Wysocki6ff7bb0d02012-05-01 21:34:07 +02001509 spin_unlock_irq(&dev->power.lock);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001510
Rafael J. Wysocki6ff7bb0d02012-05-01 21:34:07 +02001511 mutex_lock(&gpd_data->lock);
1512 pdd->dev = NULL;
1513 mutex_unlock(&gpd_data->lock);
1514
1515 genpd_release_lock(genpd);
1516
Rafael J. Wysocki6ff7bb0d02012-05-01 21:34:07 +02001517 dev_pm_put_subsys_data(dev);
Rafael J. Wysocki1d5fcfe2012-07-05 22:12:32 +02001518 if (remove)
1519 __pm_genpd_free_dev_data(dev, gpd_data);
1520
Rafael J. Wysocki6ff7bb0d02012-05-01 21:34:07 +02001521 return 0;
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001522
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001523 out:
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001524 genpd_release_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001525
1526 return ret;
1527}
1528
1529/**
Rafael J. Wysockica1d72f2012-05-14 21:45:52 +02001530 * pm_genpd_dev_need_restore - Set/unset the device's "need restore" flag.
1531 * @dev: Device to set/unset the flag for.
1532 * @val: The new value of the device's "need restore" flag.
1533 */
1534void pm_genpd_dev_need_restore(struct device *dev, bool val)
1535{
1536 struct pm_subsys_data *psd;
1537 unsigned long flags;
1538
1539 spin_lock_irqsave(&dev->power.lock, flags);
1540
1541 psd = dev_to_psd(dev);
1542 if (psd && psd->domain_data)
1543 to_gpd_data(psd->domain_data)->need_restore = val;
1544
1545 spin_unlock_irqrestore(&dev->power.lock, flags);
1546}
1547EXPORT_SYMBOL_GPL(pm_genpd_dev_need_restore);
1548
1549/**
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001550 * pm_genpd_add_subdomain - Add a subdomain to an I/O PM domain.
1551 * @genpd: Master PM domain to add the subdomain to.
Rafael J. Wysockibc0403f2011-08-08 23:43:59 +02001552 * @subdomain: Subdomain to be added.
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001553 */
1554int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
Rafael J. Wysockibc0403f2011-08-08 23:43:59 +02001555 struct generic_pm_domain *subdomain)
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001556{
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +02001557 struct gpd_link *link;
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001558 int ret = 0;
1559
Rafael J. Wysockibc0403f2011-08-08 23:43:59 +02001560 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain))
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001561 return -EINVAL;
1562
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001563 start:
1564 genpd_acquire_lock(genpd);
Rafael J. Wysockibc0403f2011-08-08 23:43:59 +02001565 mutex_lock_nested(&subdomain->lock, SINGLE_DEPTH_NESTING);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001566
Rafael J. Wysockibc0403f2011-08-08 23:43:59 +02001567 if (subdomain->status != GPD_STATE_POWER_OFF
1568 && subdomain->status != GPD_STATE_ACTIVE) {
1569 mutex_unlock(&subdomain->lock);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001570 genpd_release_lock(genpd);
1571 goto start;
1572 }
1573
1574 if (genpd->status == GPD_STATE_POWER_OFF
Rafael J. Wysockibc0403f2011-08-08 23:43:59 +02001575 && subdomain->status != GPD_STATE_POWER_OFF) {
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001576 ret = -EINVAL;
1577 goto out;
1578 }
1579
Huang Ying4fcac102012-05-07 21:35:45 +02001580 list_for_each_entry(link, &genpd->master_links, master_node) {
Rafael J. Wysockibc0403f2011-08-08 23:43:59 +02001581 if (link->slave == subdomain && link->master == genpd) {
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001582 ret = -EINVAL;
1583 goto out;
1584 }
1585 }
1586
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +02001587 link = kzalloc(sizeof(*link), GFP_KERNEL);
1588 if (!link) {
1589 ret = -ENOMEM;
1590 goto out;
1591 }
1592 link->master = genpd;
1593 list_add_tail(&link->master_node, &genpd->master_links);
Rafael J. Wysockibc0403f2011-08-08 23:43:59 +02001594 link->slave = subdomain;
1595 list_add_tail(&link->slave_node, &subdomain->slave_links);
1596 if (subdomain->status != GPD_STATE_POWER_OFF)
Rafael J. Wysockic4bb3162011-08-08 23:43:04 +02001597 genpd_sd_counter_inc(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001598
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001599 out:
Rafael J. Wysockibc0403f2011-08-08 23:43:59 +02001600 mutex_unlock(&subdomain->lock);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001601 genpd_release_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001602
1603 return ret;
1604}
1605
1606/**
1607 * pm_genpd_remove_subdomain - Remove a subdomain from an I/O PM domain.
1608 * @genpd: Master PM domain to remove the subdomain from.
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +02001609 * @subdomain: Subdomain to be removed.
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001610 */
1611int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +02001612 struct generic_pm_domain *subdomain)
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001613{
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +02001614 struct gpd_link *link;
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001615 int ret = -EINVAL;
1616
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +02001617 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain))
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001618 return -EINVAL;
1619
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001620 start:
1621 genpd_acquire_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001622
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +02001623 list_for_each_entry(link, &genpd->master_links, master_node) {
1624 if (link->slave != subdomain)
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001625 continue;
1626
1627 mutex_lock_nested(&subdomain->lock, SINGLE_DEPTH_NESTING);
1628
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001629 if (subdomain->status != GPD_STATE_POWER_OFF
1630 && subdomain->status != GPD_STATE_ACTIVE) {
1631 mutex_unlock(&subdomain->lock);
1632 genpd_release_lock(genpd);
1633 goto start;
1634 }
1635
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +02001636 list_del(&link->master_node);
1637 list_del(&link->slave_node);
1638 kfree(link);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001639 if (subdomain->status != GPD_STATE_POWER_OFF)
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001640 genpd_sd_counter_dec(genpd);
1641
1642 mutex_unlock(&subdomain->lock);
1643
1644 ret = 0;
1645 break;
1646 }
1647
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001648 genpd_release_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001649
1650 return ret;
1651}
1652
1653/**
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +01001654 * pm_genpd_add_callbacks - Add PM domain callbacks to a given device.
1655 * @dev: Device to add the callbacks to.
1656 * @ops: Set of callbacks to add.
Rafael J. Wysockib02c9992011-12-01 00:02:05 +01001657 * @td: Timing data to add to the device along with the callbacks (optional).
Rafael J. Wysocki62d44902012-07-05 22:12:54 +02001658 *
1659 * Every call to this routine should be balanced with a call to
1660 * __pm_genpd_remove_callbacks() and they must not be nested.
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +01001661 */
Rafael J. Wysockib02c9992011-12-01 00:02:05 +01001662int pm_genpd_add_callbacks(struct device *dev, struct gpd_dev_ops *ops,
1663 struct gpd_timing_data *td)
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +01001664{
Rafael J. Wysocki62d44902012-07-05 22:12:54 +02001665 struct generic_pm_domain_data *gpd_data_new, *gpd_data = NULL;
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +01001666 int ret = 0;
1667
Rafael J. Wysocki62d44902012-07-05 22:12:54 +02001668 if (!(dev && ops))
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +01001669 return -EINVAL;
1670
Rafael J. Wysocki62d44902012-07-05 22:12:54 +02001671 gpd_data_new = __pm_genpd_alloc_dev_data(dev);
1672 if (!gpd_data_new)
1673 return -ENOMEM;
1674
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +01001675 pm_runtime_disable(dev);
1676 device_pm_lock();
1677
Rafael J. Wysocki62d44902012-07-05 22:12:54 +02001678 ret = dev_pm_get_subsys_data(dev);
1679 if (ret)
1680 goto out;
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +01001681
Rafael J. Wysocki62d44902012-07-05 22:12:54 +02001682 spin_lock_irq(&dev->power.lock);
1683
1684 if (dev->power.subsys_data->domain_data) {
1685 gpd_data = to_gpd_data(dev->power.subsys_data->domain_data);
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +01001686 } else {
Rafael J. Wysocki62d44902012-07-05 22:12:54 +02001687 gpd_data = gpd_data_new;
1688 dev->power.subsys_data->domain_data = &gpd_data->base;
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +01001689 }
Rafael J. Wysocki62d44902012-07-05 22:12:54 +02001690 gpd_data->refcount++;
1691 gpd_data->ops = *ops;
1692 if (td)
1693 gpd_data->td = *td;
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +01001694
Rafael J. Wysocki62d44902012-07-05 22:12:54 +02001695 spin_unlock_irq(&dev->power.lock);
1696
1697 out:
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +01001698 device_pm_unlock();
1699 pm_runtime_enable(dev);
1700
Rafael J. Wysocki62d44902012-07-05 22:12:54 +02001701 if (gpd_data != gpd_data_new)
1702 __pm_genpd_free_dev_data(dev, gpd_data_new);
1703
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +01001704 return ret;
1705}
1706EXPORT_SYMBOL_GPL(pm_genpd_add_callbacks);
1707
1708/**
Rafael J. Wysockib02c9992011-12-01 00:02:05 +01001709 * __pm_genpd_remove_callbacks - Remove PM domain callbacks from a given device.
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +01001710 * @dev: Device to remove the callbacks from.
Rafael J. Wysockib02c9992011-12-01 00:02:05 +01001711 * @clear_td: If set, clear the device's timing data too.
Rafael J. Wysocki62d44902012-07-05 22:12:54 +02001712 *
1713 * This routine can only be called after pm_genpd_add_callbacks().
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +01001714 */
Rafael J. Wysockib02c9992011-12-01 00:02:05 +01001715int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td)
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +01001716{
Rafael J. Wysocki62d44902012-07-05 22:12:54 +02001717 struct generic_pm_domain_data *gpd_data = NULL;
1718 bool remove = false;
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +01001719 int ret = 0;
1720
1721 if (!(dev && dev->power.subsys_data))
1722 return -EINVAL;
1723
1724 pm_runtime_disable(dev);
1725 device_pm_lock();
1726
Rafael J. Wysocki62d44902012-07-05 22:12:54 +02001727 spin_lock_irq(&dev->power.lock);
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +01001728
Rafael J. Wysocki62d44902012-07-05 22:12:54 +02001729 if (dev->power.subsys_data->domain_data) {
1730 gpd_data = to_gpd_data(dev->power.subsys_data->domain_data);
Sachin Kamatdb79e532012-07-11 12:25:49 +02001731 gpd_data->ops = (struct gpd_dev_ops){ NULL };
Rafael J. Wysockib02c9992011-12-01 00:02:05 +01001732 if (clear_td)
1733 gpd_data->td = (struct gpd_timing_data){ 0 };
Rafael J. Wysocki62d44902012-07-05 22:12:54 +02001734
1735 if (--gpd_data->refcount == 0) {
1736 dev->power.subsys_data->domain_data = NULL;
1737 remove = true;
1738 }
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +01001739 } else {
1740 ret = -EINVAL;
1741 }
1742
Rafael J. Wysocki62d44902012-07-05 22:12:54 +02001743 spin_unlock_irq(&dev->power.lock);
1744
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +01001745 device_pm_unlock();
1746 pm_runtime_enable(dev);
1747
Rafael J. Wysocki62d44902012-07-05 22:12:54 +02001748 if (ret)
1749 return ret;
1750
1751 dev_pm_put_subsys_data(dev);
1752 if (remove)
1753 __pm_genpd_free_dev_data(dev, gpd_data);
1754
1755 return 0;
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +01001756}
Rafael J. Wysockib02c9992011-12-01 00:02:05 +01001757EXPORT_SYMBOL_GPL(__pm_genpd_remove_callbacks);
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +01001758
Rafael J. Wysockicbc9ef02012-07-03 19:07:42 +02001759int genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state)
1760{
1761 struct cpuidle_driver *cpuidle_drv;
1762 struct gpd_cpu_data *cpu_data;
1763 struct cpuidle_state *idle_state;
1764 int ret = 0;
1765
1766 if (IS_ERR_OR_NULL(genpd) || state < 0)
1767 return -EINVAL;
1768
1769 genpd_acquire_lock(genpd);
1770
1771 if (genpd->cpu_data) {
1772 ret = -EEXIST;
1773 goto out;
1774 }
1775 cpu_data = kzalloc(sizeof(*cpu_data), GFP_KERNEL);
1776 if (!cpu_data) {
1777 ret = -ENOMEM;
1778 goto out;
1779 }
1780 cpuidle_drv = cpuidle_driver_ref();
1781 if (!cpuidle_drv) {
1782 ret = -ENODEV;
1783 goto out;
1784 }
1785 if (cpuidle_drv->state_count <= state) {
1786 ret = -EINVAL;
1787 goto err;
1788 }
1789 idle_state = &cpuidle_drv->states[state];
1790 if (!idle_state->disabled) {
1791 ret = -EAGAIN;
1792 goto err;
1793 }
1794 cpu_data->idle_state = idle_state;
1795 cpu_data->saved_exit_latency = idle_state->exit_latency;
1796 genpd->cpu_data = cpu_data;
1797 genpd_recalc_cpu_exit_latency(genpd);
1798
1799 out:
1800 genpd_release_lock(genpd);
1801 return ret;
1802
1803 err:
1804 cpuidle_driver_unref();
1805 goto out;
1806}
1807
1808int genpd_detach_cpuidle(struct generic_pm_domain *genpd)
1809{
1810 struct gpd_cpu_data *cpu_data;
1811 struct cpuidle_state *idle_state;
1812 int ret = 0;
1813
1814 if (IS_ERR_OR_NULL(genpd))
1815 return -EINVAL;
1816
1817 genpd_acquire_lock(genpd);
1818
1819 cpu_data = genpd->cpu_data;
1820 if (!cpu_data) {
1821 ret = -ENODEV;
1822 goto out;
1823 }
1824 idle_state = cpu_data->idle_state;
1825 if (!idle_state->disabled) {
1826 ret = -EAGAIN;
1827 goto out;
1828 }
1829 idle_state->exit_latency = cpu_data->saved_exit_latency;
1830 cpuidle_driver_unref();
1831 genpd->cpu_data = NULL;
1832 kfree(cpu_data);
1833
1834 out:
1835 genpd_release_lock(genpd);
1836 return ret;
1837}
1838
Rafael J. Wysockid23b9b02011-11-27 13:11:51 +01001839/* Default device callbacks for generic PM domains. */
1840
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +01001841/**
Rafael J. Wysockiecf00472011-11-27 13:11:44 +01001842 * pm_genpd_default_save_state - Default "save device state" for PM domians.
1843 * @dev: Device to handle.
1844 */
1845static int pm_genpd_default_save_state(struct device *dev)
1846{
1847 int (*cb)(struct device *__dev);
Rafael J. Wysockiecf00472011-11-27 13:11:44 +01001848
1849 cb = dev_gpd_data(dev)->ops.save_state;
1850 if (cb)
1851 return cb(dev);
1852
Rafael J. Wysocki0b589742012-06-16 00:02:22 +02001853 if (dev->type && dev->type->pm)
1854 cb = dev->type->pm->runtime_suspend;
1855 else if (dev->class && dev->class->pm)
1856 cb = dev->class->pm->runtime_suspend;
1857 else if (dev->bus && dev->bus->pm)
1858 cb = dev->bus->pm->runtime_suspend;
1859 else
1860 cb = NULL;
Rafael J. Wysockiecf00472011-11-27 13:11:44 +01001861
Rafael J. Wysocki0b589742012-06-16 00:02:22 +02001862 if (!cb && dev->driver && dev->driver->pm)
1863 cb = dev->driver->pm->runtime_suspend;
1864
1865 return cb ? cb(dev) : 0;
Rafael J. Wysockiecf00472011-11-27 13:11:44 +01001866}
1867
1868/**
1869 * pm_genpd_default_restore_state - Default PM domians "restore device state".
1870 * @dev: Device to handle.
1871 */
1872static int pm_genpd_default_restore_state(struct device *dev)
1873{
1874 int (*cb)(struct device *__dev);
Rafael J. Wysockiecf00472011-11-27 13:11:44 +01001875
1876 cb = dev_gpd_data(dev)->ops.restore_state;
1877 if (cb)
1878 return cb(dev);
1879
Rafael J. Wysocki0b589742012-06-16 00:02:22 +02001880 if (dev->type && dev->type->pm)
1881 cb = dev->type->pm->runtime_resume;
1882 else if (dev->class && dev->class->pm)
1883 cb = dev->class->pm->runtime_resume;
1884 else if (dev->bus && dev->bus->pm)
1885 cb = dev->bus->pm->runtime_resume;
1886 else
1887 cb = NULL;
Rafael J. Wysockiecf00472011-11-27 13:11:44 +01001888
Rafael J. Wysocki0b589742012-06-16 00:02:22 +02001889 if (!cb && dev->driver && dev->driver->pm)
1890 cb = dev->driver->pm->runtime_resume;
1891
1892 return cb ? cb(dev) : 0;
Rafael J. Wysockiecf00472011-11-27 13:11:44 +01001893}
1894
Rafael J. Wysocki0f1d6982012-01-14 00:39:25 +01001895#ifdef CONFIG_PM_SLEEP
1896
Rafael J. Wysockiecf00472011-11-27 13:11:44 +01001897/**
Rafael J. Wysockid23b9b02011-11-27 13:11:51 +01001898 * pm_genpd_default_suspend - Default "device suspend" for PM domians.
1899 * @dev: Device to handle.
1900 */
1901static int pm_genpd_default_suspend(struct device *dev)
1902{
Rafael J. Wysockic9914852011-12-06 23:16:47 +01001903 int (*cb)(struct device *__dev) = dev_gpd_data(dev)->ops.suspend;
Rafael J. Wysockid23b9b02011-11-27 13:11:51 +01001904
1905 return cb ? cb(dev) : pm_generic_suspend(dev);
1906}
1907
1908/**
1909 * pm_genpd_default_suspend_late - Default "late device suspend" for PM domians.
1910 * @dev: Device to handle.
1911 */
1912static int pm_genpd_default_suspend_late(struct device *dev)
1913{
Rafael J. Wysockic9914852011-12-06 23:16:47 +01001914 int (*cb)(struct device *__dev) = dev_gpd_data(dev)->ops.suspend_late;
Rafael J. Wysockid23b9b02011-11-27 13:11:51 +01001915
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +01001916 return cb ? cb(dev) : pm_generic_suspend_late(dev);
Rafael J. Wysockid23b9b02011-11-27 13:11:51 +01001917}
1918
1919/**
1920 * pm_genpd_default_resume_early - Default "early device resume" for PM domians.
1921 * @dev: Device to handle.
1922 */
1923static int pm_genpd_default_resume_early(struct device *dev)
1924{
Rafael J. Wysockic9914852011-12-06 23:16:47 +01001925 int (*cb)(struct device *__dev) = dev_gpd_data(dev)->ops.resume_early;
Rafael J. Wysockid23b9b02011-11-27 13:11:51 +01001926
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +01001927 return cb ? cb(dev) : pm_generic_resume_early(dev);
Rafael J. Wysockid23b9b02011-11-27 13:11:51 +01001928}
1929
1930/**
1931 * pm_genpd_default_resume - Default "device resume" for PM domians.
1932 * @dev: Device to handle.
1933 */
1934static int pm_genpd_default_resume(struct device *dev)
1935{
Rafael J. Wysockic9914852011-12-06 23:16:47 +01001936 int (*cb)(struct device *__dev) = dev_gpd_data(dev)->ops.resume;
Rafael J. Wysockid23b9b02011-11-27 13:11:51 +01001937
1938 return cb ? cb(dev) : pm_generic_resume(dev);
1939}
1940
1941/**
1942 * pm_genpd_default_freeze - Default "device freeze" for PM domians.
1943 * @dev: Device to handle.
1944 */
1945static int pm_genpd_default_freeze(struct device *dev)
1946{
1947 int (*cb)(struct device *__dev) = dev_gpd_data(dev)->ops.freeze;
1948
1949 return cb ? cb(dev) : pm_generic_freeze(dev);
1950}
1951
1952/**
1953 * pm_genpd_default_freeze_late - Default "late device freeze" for PM domians.
1954 * @dev: Device to handle.
1955 */
1956static int pm_genpd_default_freeze_late(struct device *dev)
1957{
1958 int (*cb)(struct device *__dev) = dev_gpd_data(dev)->ops.freeze_late;
1959
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +01001960 return cb ? cb(dev) : pm_generic_freeze_late(dev);
Rafael J. Wysockid23b9b02011-11-27 13:11:51 +01001961}
1962
1963/**
1964 * pm_genpd_default_thaw_early - Default "early device thaw" for PM domians.
1965 * @dev: Device to handle.
1966 */
1967static int pm_genpd_default_thaw_early(struct device *dev)
1968{
1969 int (*cb)(struct device *__dev) = dev_gpd_data(dev)->ops.thaw_early;
1970
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +01001971 return cb ? cb(dev) : pm_generic_thaw_early(dev);
Rafael J. Wysockid23b9b02011-11-27 13:11:51 +01001972}
1973
1974/**
1975 * pm_genpd_default_thaw - Default "device thaw" for PM domians.
1976 * @dev: Device to handle.
1977 */
1978static int pm_genpd_default_thaw(struct device *dev)
1979{
1980 int (*cb)(struct device *__dev) = dev_gpd_data(dev)->ops.thaw;
1981
1982 return cb ? cb(dev) : pm_generic_thaw(dev);
1983}
1984
Rafael J. Wysocki0f1d6982012-01-14 00:39:25 +01001985#else /* !CONFIG_PM_SLEEP */
1986
1987#define pm_genpd_default_suspend NULL
1988#define pm_genpd_default_suspend_late NULL
1989#define pm_genpd_default_resume_early NULL
1990#define pm_genpd_default_resume NULL
1991#define pm_genpd_default_freeze NULL
1992#define pm_genpd_default_freeze_late NULL
1993#define pm_genpd_default_thaw_early NULL
1994#define pm_genpd_default_thaw NULL
1995
1996#endif /* !CONFIG_PM_SLEEP */
1997
Rafael J. Wysockid23b9b02011-11-27 13:11:51 +01001998/**
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001999 * pm_genpd_init - Initialize a generic I/O PM domain object.
2000 * @genpd: PM domain object to initialize.
2001 * @gov: PM domain governor to associate with the domain (may be NULL).
2002 * @is_off: Initial value of the domain's power_is_off field.
2003 */
2004void pm_genpd_init(struct generic_pm_domain *genpd,
2005 struct dev_power_governor *gov, bool is_off)
2006{
2007 if (IS_ERR_OR_NULL(genpd))
2008 return;
2009
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +02002010 INIT_LIST_HEAD(&genpd->master_links);
2011 INIT_LIST_HEAD(&genpd->slave_links);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02002012 INIT_LIST_HEAD(&genpd->dev_list);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02002013 mutex_init(&genpd->lock);
2014 genpd->gov = gov;
2015 INIT_WORK(&genpd->power_off_work, genpd_power_off_work_fn);
2016 genpd->in_progress = 0;
Rafael J. Wysockic4bb3162011-08-08 23:43:04 +02002017 atomic_set(&genpd->sd_count, 0);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02002018 genpd->status = is_off ? GPD_STATE_POWER_OFF : GPD_STATE_ACTIVE;
2019 init_waitqueue_head(&genpd->status_wait_queue);
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +02002020 genpd->poweroff_task = NULL;
2021 genpd->resume_count = 0;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02002022 genpd->device_count = 0;
Rafael J. Wysocki221e9b52011-12-01 00:02:10 +01002023 genpd->max_off_time_ns = -1;
Rafael J. Wysocki6ff7bb0d02012-05-01 21:34:07 +02002024 genpd->max_off_time_changed = true;
Rafael J. Wysockif7218892011-07-01 22:12:45 +02002025 genpd->domain.ops.runtime_suspend = pm_genpd_runtime_suspend;
2026 genpd->domain.ops.runtime_resume = pm_genpd_runtime_resume;
2027 genpd->domain.ops.runtime_idle = pm_generic_runtime_idle;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02002028 genpd->domain.ops.prepare = pm_genpd_prepare;
2029 genpd->domain.ops.suspend = pm_genpd_suspend;
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +01002030 genpd->domain.ops.suspend_late = pm_genpd_suspend_late;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02002031 genpd->domain.ops.suspend_noirq = pm_genpd_suspend_noirq;
2032 genpd->domain.ops.resume_noirq = pm_genpd_resume_noirq;
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +01002033 genpd->domain.ops.resume_early = pm_genpd_resume_early;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02002034 genpd->domain.ops.resume = pm_genpd_resume;
2035 genpd->domain.ops.freeze = pm_genpd_freeze;
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +01002036 genpd->domain.ops.freeze_late = pm_genpd_freeze_late;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02002037 genpd->domain.ops.freeze_noirq = pm_genpd_freeze_noirq;
2038 genpd->domain.ops.thaw_noirq = pm_genpd_thaw_noirq;
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +01002039 genpd->domain.ops.thaw_early = pm_genpd_thaw_early;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02002040 genpd->domain.ops.thaw = pm_genpd_thaw;
Rafael J. Wysockid23b9b02011-11-27 13:11:51 +01002041 genpd->domain.ops.poweroff = pm_genpd_suspend;
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +01002042 genpd->domain.ops.poweroff_late = pm_genpd_suspend_late;
Rafael J. Wysockid23b9b02011-11-27 13:11:51 +01002043 genpd->domain.ops.poweroff_noirq = pm_genpd_suspend_noirq;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02002044 genpd->domain.ops.restore_noirq = pm_genpd_restore_noirq;
Rafael J. Wysocki0496c8a2012-01-29 20:39:02 +01002045 genpd->domain.ops.restore_early = pm_genpd_resume_early;
Rafael J. Wysockid23b9b02011-11-27 13:11:51 +01002046 genpd->domain.ops.restore = pm_genpd_resume;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02002047 genpd->domain.ops.complete = pm_genpd_complete;
Rafael J. Wysockiecf00472011-11-27 13:11:44 +01002048 genpd->dev_ops.save_state = pm_genpd_default_save_state;
2049 genpd->dev_ops.restore_state = pm_genpd_default_restore_state;
Rafael J. Wysockic9914852011-12-06 23:16:47 +01002050 genpd->dev_ops.suspend = pm_genpd_default_suspend;
2051 genpd->dev_ops.suspend_late = pm_genpd_default_suspend_late;
2052 genpd->dev_ops.resume_early = pm_genpd_default_resume_early;
2053 genpd->dev_ops.resume = pm_genpd_default_resume;
Rafael J. Wysockid23b9b02011-11-27 13:11:51 +01002054 genpd->dev_ops.freeze = pm_genpd_default_freeze;
2055 genpd->dev_ops.freeze_late = pm_genpd_default_freeze_late;
2056 genpd->dev_ops.thaw_early = pm_genpd_default_thaw_early;
2057 genpd->dev_ops.thaw = pm_genpd_default_thaw;
Rafael J. Wysocki5125bbf2011-07-13 12:31:52 +02002058 mutex_lock(&gpd_list_lock);
2059 list_add(&genpd->gpd_list_node, &gpd_list);
2060 mutex_unlock(&gpd_list_lock);
2061}