blob: c3e4e2934e1635d0bafbb41f131fa6d7f13f4e43 [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>
14#include <linux/slab.h>
15#include <linux/err.h>
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +020016#include <linux/sched.h>
17#include <linux/suspend.h>
Rafael J. Wysockif7218892011-07-01 22:12:45 +020018
Rafael J. Wysocki52480512011-07-01 22:13:10 +020019#ifdef CONFIG_PM
20
21static struct generic_pm_domain *dev_to_genpd(struct device *dev)
22{
23 if (IS_ERR_OR_NULL(dev->pm_domain))
24 return ERR_PTR(-EINVAL);
25
Rafael J. Wysocki596ba342011-07-01 22:13:19 +020026 return pd_to_genpd(dev->pm_domain);
Rafael J. Wysocki52480512011-07-01 22:13:10 +020027}
Rafael J. Wysockif7218892011-07-01 22:12:45 +020028
29static void genpd_sd_counter_dec(struct generic_pm_domain *genpd)
30{
31 if (!WARN_ON(genpd->sd_count == 0))
32 genpd->sd_count--;
33}
34
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +020035static void genpd_acquire_lock(struct generic_pm_domain *genpd)
36{
37 DEFINE_WAIT(wait);
38
39 mutex_lock(&genpd->lock);
40 /*
41 * Wait for the domain to transition into either the active,
42 * or the power off state.
43 */
44 for (;;) {
45 prepare_to_wait(&genpd->status_wait_queue, &wait,
46 TASK_UNINTERRUPTIBLE);
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +020047 if (genpd->status == GPD_STATE_ACTIVE
48 || genpd->status == GPD_STATE_POWER_OFF)
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +020049 break;
50 mutex_unlock(&genpd->lock);
51
52 schedule();
53
54 mutex_lock(&genpd->lock);
55 }
56 finish_wait(&genpd->status_wait_queue, &wait);
57}
58
59static void genpd_release_lock(struct generic_pm_domain *genpd)
60{
61 mutex_unlock(&genpd->lock);
62}
63
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +020064static void genpd_set_active(struct generic_pm_domain *genpd)
65{
66 if (genpd->resume_count == 0)
67 genpd->status = GPD_STATE_ACTIVE;
68}
69
Rafael J. Wysockif7218892011-07-01 22:12:45 +020070/**
Rafael J. Wysocki52480512011-07-01 22:13:10 +020071 * pm_genpd_poweron - Restore power to a given PM domain and its parents.
72 * @genpd: PM domain to power up.
73 *
74 * Restore power to @genpd and all of its parents so that it is possible to
75 * resume a device belonging to it.
76 */
Magnus Damm18b4f3f2011-07-10 10:39:14 +020077int pm_genpd_poweron(struct generic_pm_domain *genpd)
Rafael J. Wysocki52480512011-07-01 22:13:10 +020078{
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +020079 struct generic_pm_domain *parent = genpd->parent;
80 DEFINE_WAIT(wait);
Rafael J. Wysocki52480512011-07-01 22:13:10 +020081 int ret = 0;
82
83 start:
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +020084 if (parent) {
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +020085 genpd_acquire_lock(parent);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +020086 mutex_lock_nested(&genpd->lock, SINGLE_DEPTH_NESTING);
87 } else {
88 mutex_lock(&genpd->lock);
89 }
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +020090
91 if (genpd->status == GPD_STATE_ACTIVE
Rafael J. Wysocki596ba342011-07-01 22:13:19 +020092 || (genpd->prepared_count > 0 && genpd->suspend_power_off))
Rafael J. Wysocki52480512011-07-01 22:13:10 +020093 goto out;
94
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +020095 if (genpd->status != GPD_STATE_POWER_OFF) {
96 genpd_set_active(genpd);
97 goto out;
98 }
99
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200100 if (parent && parent->status != GPD_STATE_ACTIVE) {
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200101 mutex_unlock(&genpd->lock);
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200102 genpd_release_lock(parent);
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200103
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200104 ret = pm_genpd_poweron(parent);
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200105 if (ret)
106 return ret;
107
108 goto start;
109 }
110
111 if (genpd->power_on) {
112 int ret = genpd->power_on(genpd);
113 if (ret)
114 goto out;
115 }
116
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200117 genpd_set_active(genpd);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200118 if (parent)
119 parent->sd_count++;
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200120
121 out:
122 mutex_unlock(&genpd->lock);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200123 if (parent)
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200124 genpd_release_lock(parent);
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200125
126 return ret;
127}
128
129#endif /* CONFIG_PM */
130
131#ifdef CONFIG_PM_RUNTIME
132
133/**
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200134 * __pm_genpd_save_device - Save the pre-suspend state of a device.
135 * @dle: Device list entry of the device to save the state of.
136 * @genpd: PM domain the device belongs to.
137 */
138static int __pm_genpd_save_device(struct dev_list_entry *dle,
139 struct generic_pm_domain *genpd)
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200140 __releases(&genpd->lock) __acquires(&genpd->lock)
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200141{
142 struct device *dev = dle->dev;
143 struct device_driver *drv = dev->driver;
144 int ret = 0;
145
146 if (dle->need_restore)
147 return 0;
148
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200149 mutex_unlock(&genpd->lock);
150
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200151 if (drv && drv->pm && drv->pm->runtime_suspend) {
152 if (genpd->start_device)
153 genpd->start_device(dev);
154
155 ret = drv->pm->runtime_suspend(dev);
156
157 if (genpd->stop_device)
158 genpd->stop_device(dev);
159 }
160
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200161 mutex_lock(&genpd->lock);
162
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200163 if (!ret)
164 dle->need_restore = true;
165
166 return ret;
167}
168
169/**
170 * __pm_genpd_restore_device - Restore the pre-suspend state of a device.
171 * @dle: Device list entry of the device to restore the state of.
172 * @genpd: PM domain the device belongs to.
173 */
174static void __pm_genpd_restore_device(struct dev_list_entry *dle,
175 struct generic_pm_domain *genpd)
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200176 __releases(&genpd->lock) __acquires(&genpd->lock)
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200177{
178 struct device *dev = dle->dev;
179 struct device_driver *drv = dev->driver;
180
181 if (!dle->need_restore)
182 return;
183
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200184 mutex_unlock(&genpd->lock);
185
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200186 if (drv && drv->pm && drv->pm->runtime_resume) {
187 if (genpd->start_device)
188 genpd->start_device(dev);
189
190 drv->pm->runtime_resume(dev);
191
192 if (genpd->stop_device)
193 genpd->stop_device(dev);
194 }
195
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200196 mutex_lock(&genpd->lock);
197
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200198 dle->need_restore = false;
199}
200
201/**
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200202 * genpd_abort_poweroff - Check if a PM domain power off should be aborted.
203 * @genpd: PM domain to check.
204 *
205 * Return true if a PM domain's status changed to GPD_STATE_ACTIVE during
206 * a "power off" operation, which means that a "power on" has occured in the
207 * meantime, or if its resume_count field is different from zero, which means
208 * that one of its devices has been resumed in the meantime.
209 */
210static bool genpd_abort_poweroff(struct generic_pm_domain *genpd)
211{
212 return genpd->status == GPD_STATE_ACTIVE || genpd->resume_count > 0;
213}
214
215/**
Rafael J. Wysocki56375fd2011-07-12 00:40:03 +0200216 * genpd_queue_power_off_work - Queue up the execution of pm_genpd_poweroff().
217 * @genpd: PM domait to power off.
218 *
219 * Queue up the execution of pm_genpd_poweroff() unless it's already been done
220 * before.
221 */
222static void genpd_queue_power_off_work(struct generic_pm_domain *genpd)
223{
224 if (!work_pending(&genpd->power_off_work))
225 queue_work(pm_wq, &genpd->power_off_work);
226}
227
228/**
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200229 * pm_genpd_poweroff - Remove power from a given PM domain.
230 * @genpd: PM domain to power down.
231 *
232 * If all of the @genpd's devices have been suspended and all of its subdomains
233 * have been powered down, run the runtime suspend callbacks provided by all of
234 * the @genpd's devices' drivers and remove power from @genpd.
235 */
236static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200237 __releases(&genpd->lock) __acquires(&genpd->lock)
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200238{
239 struct generic_pm_domain *parent;
240 struct dev_list_entry *dle;
241 unsigned int not_suspended;
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200242 int ret = 0;
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200243
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200244 start:
245 /*
246 * Do not try to power off the domain in the following situations:
247 * (1) The domain is already in the "power off" state.
248 * (2) System suspend is in progress.
249 * (3) One of the domain's devices is being resumed right now.
250 */
251 if (genpd->status == GPD_STATE_POWER_OFF || genpd->prepared_count > 0
252 || genpd->resume_count > 0)
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200253 return 0;
254
255 if (genpd->sd_count > 0)
256 return -EBUSY;
257
258 not_suspended = 0;
259 list_for_each_entry(dle, &genpd->dev_list, node)
260 if (dle->dev->driver && !pm_runtime_suspended(dle->dev))
261 not_suspended++;
262
263 if (not_suspended > genpd->in_progress)
264 return -EBUSY;
265
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200266 if (genpd->poweroff_task) {
267 /*
268 * Another instance of pm_genpd_poweroff() is executing
269 * callbacks, so tell it to start over and return.
270 */
271 genpd->status = GPD_STATE_REPEAT;
272 return 0;
273 }
274
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200275 if (genpd->gov && genpd->gov->power_down_ok) {
276 if (!genpd->gov->power_down_ok(&genpd->domain))
277 return -EAGAIN;
278 }
279
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200280 genpd->status = GPD_STATE_BUSY;
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200281 genpd->poweroff_task = current;
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200282
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200283 list_for_each_entry_reverse(dle, &genpd->dev_list, node) {
284 ret = __pm_genpd_save_device(dle, genpd);
Rafael J. Wysocki697a7f32011-07-12 00:39:48 +0200285 if (ret) {
286 genpd_set_active(genpd);
287 goto out;
288 }
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200289
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200290 if (genpd_abort_poweroff(genpd))
291 goto out;
292
293 if (genpd->status == GPD_STATE_REPEAT) {
294 genpd->poweroff_task = NULL;
295 goto start;
296 }
297 }
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200298
299 parent = genpd->parent;
300 if (parent) {
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200301 mutex_unlock(&genpd->lock);
302
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200303 genpd_acquire_lock(parent);
304 mutex_lock_nested(&genpd->lock, SINGLE_DEPTH_NESTING);
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200305
306 if (genpd_abort_poweroff(genpd)) {
307 genpd_release_lock(parent);
308 goto out;
309 }
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200310 }
311
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200312 if (genpd->power_off)
313 genpd->power_off(genpd);
314
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200315 genpd->status = GPD_STATE_POWER_OFF;
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200316
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200317 if (parent) {
318 genpd_sd_counter_dec(parent);
319 if (parent->sd_count == 0)
Rafael J. Wysocki56375fd2011-07-12 00:40:03 +0200320 genpd_queue_power_off_work(parent);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200321
322 genpd_release_lock(parent);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200323 }
324
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200325 out:
326 genpd->poweroff_task = NULL;
327 wake_up_all(&genpd->status_wait_queue);
328 return ret;
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200329}
330
331/**
332 * genpd_power_off_work_fn - Power off PM domain whose subdomain count is 0.
333 * @work: Work structure used for scheduling the execution of this function.
334 */
335static void genpd_power_off_work_fn(struct work_struct *work)
336{
337 struct generic_pm_domain *genpd;
338
339 genpd = container_of(work, struct generic_pm_domain, power_off_work);
340
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200341 genpd_acquire_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200342 pm_genpd_poweroff(genpd);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200343 genpd_release_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200344}
345
346/**
347 * pm_genpd_runtime_suspend - Suspend a device belonging to I/O PM domain.
348 * @dev: Device to suspend.
349 *
350 * Carry out a runtime suspend of a device under the assumption that its
351 * pm_domain field points to the domain member of an object of type
352 * struct generic_pm_domain representing a PM domain consisting of I/O devices.
353 */
354static int pm_genpd_runtime_suspend(struct device *dev)
355{
356 struct generic_pm_domain *genpd;
357
358 dev_dbg(dev, "%s()\n", __func__);
359
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200360 genpd = dev_to_genpd(dev);
361 if (IS_ERR(genpd))
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200362 return -EINVAL;
363
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200364 if (genpd->stop_device) {
365 int ret = genpd->stop_device(dev);
366 if (ret)
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200367 return ret;
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200368 }
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200369
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200370 mutex_lock(&genpd->lock);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200371 genpd->in_progress++;
372 pm_genpd_poweroff(genpd);
373 genpd->in_progress--;
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200374 mutex_unlock(&genpd->lock);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200375
376 return 0;
377}
378
379/**
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200380 * __pm_genpd_runtime_resume - Resume a device belonging to I/O PM domain.
381 * @dev: Device to resume.
382 * @genpd: PM domain the device belongs to.
383 */
384static void __pm_genpd_runtime_resume(struct device *dev,
385 struct generic_pm_domain *genpd)
386{
387 struct dev_list_entry *dle;
388
389 list_for_each_entry(dle, &genpd->dev_list, node) {
390 if (dle->dev == dev) {
391 __pm_genpd_restore_device(dle, genpd);
392 break;
393 }
394 }
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200395}
396
397/**
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200398 * pm_genpd_runtime_resume - Resume a device belonging to I/O PM domain.
399 * @dev: Device to resume.
400 *
401 * Carry out a runtime resume of a device under the assumption that its
402 * pm_domain field points to the domain member of an object of type
403 * struct generic_pm_domain representing a PM domain consisting of I/O devices.
404 */
405static int pm_genpd_runtime_resume(struct device *dev)
406{
407 struct generic_pm_domain *genpd;
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200408 DEFINE_WAIT(wait);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200409 int ret;
410
411 dev_dbg(dev, "%s()\n", __func__);
412
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200413 genpd = dev_to_genpd(dev);
414 if (IS_ERR(genpd))
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200415 return -EINVAL;
416
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200417 ret = pm_genpd_poweron(genpd);
418 if (ret)
419 return ret;
420
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200421 mutex_lock(&genpd->lock);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200422 genpd->status = GPD_STATE_BUSY;
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200423 genpd->resume_count++;
424 for (;;) {
425 prepare_to_wait(&genpd->status_wait_queue, &wait,
426 TASK_UNINTERRUPTIBLE);
427 /*
428 * If current is the powering off task, we have been called
429 * reentrantly from one of the device callbacks, so we should
430 * not wait.
431 */
432 if (!genpd->poweroff_task || genpd->poweroff_task == current)
433 break;
434 mutex_unlock(&genpd->lock);
435
436 schedule();
437
438 mutex_lock(&genpd->lock);
439 }
440 finish_wait(&genpd->status_wait_queue, &wait);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200441 __pm_genpd_runtime_resume(dev, genpd);
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200442 genpd->resume_count--;
443 genpd_set_active(genpd);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200444 wake_up_all(&genpd->status_wait_queue);
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200445 mutex_unlock(&genpd->lock);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200446
447 if (genpd->start_device)
448 genpd->start_device(dev);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200449
450 return 0;
451}
452
453#else
454
455static inline void genpd_power_off_work_fn(struct work_struct *work) {}
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200456static inline void __pm_genpd_runtime_resume(struct device *dev,
457 struct generic_pm_domain *genpd) {}
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200458
459#define pm_genpd_runtime_suspend NULL
460#define pm_genpd_runtime_resume NULL
461
462#endif /* CONFIG_PM_RUNTIME */
463
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200464#ifdef CONFIG_PM_SLEEP
465
466/**
467 * pm_genpd_sync_poweroff - Synchronously power off a PM domain and its parents.
468 * @genpd: PM domain to power off, if possible.
469 *
470 * Check if the given PM domain can be powered off (during system suspend or
471 * hibernation) and do that if so. Also, in that case propagate to its parent.
472 *
473 * This function is only called in "noirq" stages of system power transitions,
474 * so it need not acquire locks (all of the "noirq" callbacks are executed
475 * sequentially, so it is guaranteed that it will never run twice in parallel).
476 */
477static void pm_genpd_sync_poweroff(struct generic_pm_domain *genpd)
478{
479 struct generic_pm_domain *parent = genpd->parent;
480
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200481 if (genpd->status == GPD_STATE_POWER_OFF)
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200482 return;
483
484 if (genpd->suspended_count != genpd->device_count || genpd->sd_count > 0)
485 return;
486
487 if (genpd->power_off)
488 genpd->power_off(genpd);
489
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200490 genpd->status = GPD_STATE_POWER_OFF;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200491 if (parent) {
492 genpd_sd_counter_dec(parent);
493 pm_genpd_sync_poweroff(parent);
494 }
495}
496
497/**
Rafael J. Wysocki4ecd6e62011-07-12 00:39:57 +0200498 * resume_needed - Check whether to resume a device before system suspend.
499 * @dev: Device to check.
500 * @genpd: PM domain the device belongs to.
501 *
502 * There are two cases in which a device that can wake up the system from sleep
503 * states should be resumed by pm_genpd_prepare(): (1) if the device is enabled
504 * to wake up the system and it has to remain active for this purpose while the
505 * system is in the sleep state and (2) if the device is not enabled to wake up
506 * the system from sleep states and it generally doesn't generate wakeup signals
507 * by itself (those signals are generated on its behalf by other parts of the
508 * system). In the latter case it may be necessary to reconfigure the device's
509 * wakeup settings during system suspend, because it may have been set up to
510 * signal remote wakeup from the system's working state as needed by runtime PM.
511 * Return 'true' in either of the above cases.
512 */
513static bool resume_needed(struct device *dev, struct generic_pm_domain *genpd)
514{
515 bool active_wakeup;
516
517 if (!device_can_wakeup(dev))
518 return false;
519
520 active_wakeup = genpd->active_wakeup && genpd->active_wakeup(dev);
521 return device_may_wakeup(dev) ? active_wakeup : !active_wakeup;
522}
523
524/**
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200525 * pm_genpd_prepare - Start power transition of a device in a PM domain.
526 * @dev: Device to start the transition of.
527 *
528 * Start a power transition of a device (during a system-wide power transition)
529 * under the assumption that its pm_domain field points to the domain member of
530 * an object of type struct generic_pm_domain representing a PM domain
531 * consisting of I/O devices.
532 */
533static int pm_genpd_prepare(struct device *dev)
534{
535 struct generic_pm_domain *genpd;
Rafael J. Wysockib6c10c82011-07-12 00:39:21 +0200536 int ret;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200537
538 dev_dbg(dev, "%s()\n", __func__);
539
540 genpd = dev_to_genpd(dev);
541 if (IS_ERR(genpd))
542 return -EINVAL;
543
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200544 /*
545 * If a wakeup request is pending for the device, it should be woken up
546 * at this point and a system wakeup event should be reported if it's
547 * set up to wake up the system from sleep states.
548 */
549 pm_runtime_get_noresume(dev);
550 if (pm_runtime_barrier(dev) && device_may_wakeup(dev))
551 pm_wakeup_event(dev, 0);
552
553 if (pm_wakeup_pending()) {
554 pm_runtime_put_sync(dev);
555 return -EBUSY;
556 }
557
Rafael J. Wysocki4ecd6e62011-07-12 00:39:57 +0200558 if (resume_needed(dev, genpd))
559 pm_runtime_resume(dev);
560
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200561 genpd_acquire_lock(genpd);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200562
563 if (genpd->prepared_count++ == 0)
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200564 genpd->suspend_power_off = genpd->status == GPD_STATE_POWER_OFF;
565
566 genpd_release_lock(genpd);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200567
568 if (genpd->suspend_power_off) {
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200569 pm_runtime_put_noidle(dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200570 return 0;
571 }
572
573 /*
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200574 * The PM domain must be in the GPD_STATE_ACTIVE state at this point,
575 * so pm_genpd_poweron() will return immediately, but if the device
576 * is suspended (e.g. it's been stopped by .stop_device()), we need
577 * to make it operational.
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200578 */
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200579 pm_runtime_resume(dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200580 __pm_runtime_disable(dev, false);
581
Rafael J. Wysockib6c10c82011-07-12 00:39:21 +0200582 ret = pm_generic_prepare(dev);
583 if (ret) {
584 mutex_lock(&genpd->lock);
585
586 if (--genpd->prepared_count == 0)
587 genpd->suspend_power_off = false;
588
589 mutex_unlock(&genpd->lock);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200590 pm_runtime_enable(dev);
Rafael J. Wysockib6c10c82011-07-12 00:39:21 +0200591 }
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200592
593 pm_runtime_put_sync(dev);
Rafael J. Wysockib6c10c82011-07-12 00:39:21 +0200594 return ret;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200595}
596
597/**
598 * pm_genpd_suspend - Suspend a device belonging to an I/O PM domain.
599 * @dev: Device to suspend.
600 *
601 * Suspend a device under the assumption that its pm_domain field points to the
602 * domain member of an object of type struct generic_pm_domain representing
603 * a PM domain consisting of I/O devices.
604 */
605static int pm_genpd_suspend(struct device *dev)
606{
607 struct generic_pm_domain *genpd;
608
609 dev_dbg(dev, "%s()\n", __func__);
610
611 genpd = dev_to_genpd(dev);
612 if (IS_ERR(genpd))
613 return -EINVAL;
614
615 return genpd->suspend_power_off ? 0 : pm_generic_suspend(dev);
616}
617
618/**
619 * pm_genpd_suspend_noirq - Late suspend of a device from an I/O PM domain.
620 * @dev: Device to suspend.
621 *
622 * Carry out a late suspend of a device under the assumption that its
623 * pm_domain field points to the domain member of an object of type
624 * struct generic_pm_domain representing a PM domain consisting of I/O devices.
625 */
626static int pm_genpd_suspend_noirq(struct device *dev)
627{
628 struct generic_pm_domain *genpd;
629 int ret;
630
631 dev_dbg(dev, "%s()\n", __func__);
632
633 genpd = dev_to_genpd(dev);
634 if (IS_ERR(genpd))
635 return -EINVAL;
636
637 if (genpd->suspend_power_off)
638 return 0;
639
640 ret = pm_generic_suspend_noirq(dev);
641 if (ret)
642 return ret;
643
Rafael J. Wysockid4f2d872011-07-01 22:13:29 +0200644 if (device_may_wakeup(dev)
645 && genpd->active_wakeup && genpd->active_wakeup(dev))
646 return 0;
647
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200648 if (genpd->stop_device)
649 genpd->stop_device(dev);
650
651 /*
652 * Since all of the "noirq" callbacks are executed sequentially, it is
653 * guaranteed that this function will never run twice in parallel for
654 * the same PM domain, so it is not necessary to use locking here.
655 */
656 genpd->suspended_count++;
657 pm_genpd_sync_poweroff(genpd);
658
659 return 0;
660}
661
662/**
663 * pm_genpd_resume_noirq - Early resume of a device from an I/O power domain.
664 * @dev: Device to resume.
665 *
666 * Carry out an early resume of a device under the assumption that its
667 * pm_domain field points to the domain member of an object of type
668 * struct generic_pm_domain representing a power domain consisting of I/O
669 * devices.
670 */
671static int pm_genpd_resume_noirq(struct device *dev)
672{
673 struct generic_pm_domain *genpd;
674
675 dev_dbg(dev, "%s()\n", __func__);
676
677 genpd = dev_to_genpd(dev);
678 if (IS_ERR(genpd))
679 return -EINVAL;
680
681 if (genpd->suspend_power_off)
682 return 0;
683
684 /*
685 * Since all of the "noirq" callbacks are executed sequentially, it is
686 * guaranteed that this function will never run twice in parallel for
687 * the same PM domain, so it is not necessary to use locking here.
688 */
689 pm_genpd_poweron(genpd);
690 genpd->suspended_count--;
691 if (genpd->start_device)
692 genpd->start_device(dev);
693
694 return pm_generic_resume_noirq(dev);
695}
696
697/**
698 * pm_genpd_resume - Resume a device belonging to an I/O power domain.
699 * @dev: Device to resume.
700 *
701 * Resume a device under the assumption that its pm_domain field points to the
702 * domain member of an object of type struct generic_pm_domain representing
703 * a power domain consisting of I/O devices.
704 */
705static int pm_genpd_resume(struct device *dev)
706{
707 struct generic_pm_domain *genpd;
708
709 dev_dbg(dev, "%s()\n", __func__);
710
711 genpd = dev_to_genpd(dev);
712 if (IS_ERR(genpd))
713 return -EINVAL;
714
715 return genpd->suspend_power_off ? 0 : pm_generic_resume(dev);
716}
717
718/**
719 * pm_genpd_freeze - Freeze a device belonging to an I/O power domain.
720 * @dev: Device to freeze.
721 *
722 * Freeze a device under the assumption that its pm_domain field points to the
723 * domain member of an object of type struct generic_pm_domain representing
724 * a power domain consisting of I/O devices.
725 */
726static int pm_genpd_freeze(struct device *dev)
727{
728 struct generic_pm_domain *genpd;
729
730 dev_dbg(dev, "%s()\n", __func__);
731
732 genpd = dev_to_genpd(dev);
733 if (IS_ERR(genpd))
734 return -EINVAL;
735
736 return genpd->suspend_power_off ? 0 : pm_generic_freeze(dev);
737}
738
739/**
740 * pm_genpd_freeze_noirq - Late freeze of a device from an I/O power domain.
741 * @dev: Device to freeze.
742 *
743 * Carry out a late freeze of a device under the assumption that its
744 * pm_domain field points to the domain member of an object of type
745 * struct generic_pm_domain representing a power domain consisting of I/O
746 * devices.
747 */
748static int pm_genpd_freeze_noirq(struct device *dev)
749{
750 struct generic_pm_domain *genpd;
751 int ret;
752
753 dev_dbg(dev, "%s()\n", __func__);
754
755 genpd = dev_to_genpd(dev);
756 if (IS_ERR(genpd))
757 return -EINVAL;
758
759 if (genpd->suspend_power_off)
760 return 0;
761
762 ret = pm_generic_freeze_noirq(dev);
763 if (ret)
764 return ret;
765
766 if (genpd->stop_device)
767 genpd->stop_device(dev);
768
769 return 0;
770}
771
772/**
773 * pm_genpd_thaw_noirq - Early thaw of a device from an I/O power domain.
774 * @dev: Device to thaw.
775 *
776 * Carry out an early thaw of a device under the assumption that its
777 * pm_domain field points to the domain member of an object of type
778 * struct generic_pm_domain representing a power domain consisting of I/O
779 * devices.
780 */
781static int pm_genpd_thaw_noirq(struct device *dev)
782{
783 struct generic_pm_domain *genpd;
784
785 dev_dbg(dev, "%s()\n", __func__);
786
787 genpd = dev_to_genpd(dev);
788 if (IS_ERR(genpd))
789 return -EINVAL;
790
791 if (genpd->suspend_power_off)
792 return 0;
793
794 if (genpd->start_device)
795 genpd->start_device(dev);
796
797 return pm_generic_thaw_noirq(dev);
798}
799
800/**
801 * pm_genpd_thaw - Thaw a device belonging to an I/O power domain.
802 * @dev: Device to thaw.
803 *
804 * Thaw a device under the assumption that its pm_domain field points to the
805 * domain member of an object of type struct generic_pm_domain representing
806 * a power domain consisting of I/O devices.
807 */
808static int pm_genpd_thaw(struct device *dev)
809{
810 struct generic_pm_domain *genpd;
811
812 dev_dbg(dev, "%s()\n", __func__);
813
814 genpd = dev_to_genpd(dev);
815 if (IS_ERR(genpd))
816 return -EINVAL;
817
818 return genpd->suspend_power_off ? 0 : pm_generic_thaw(dev);
819}
820
821/**
822 * pm_genpd_dev_poweroff - Power off a device belonging to an I/O PM domain.
823 * @dev: Device to suspend.
824 *
825 * Power off a device under the assumption that its pm_domain field points to
826 * the domain member of an object of type struct generic_pm_domain representing
827 * a PM domain consisting of I/O devices.
828 */
829static int pm_genpd_dev_poweroff(struct device *dev)
830{
831 struct generic_pm_domain *genpd;
832
833 dev_dbg(dev, "%s()\n", __func__);
834
835 genpd = dev_to_genpd(dev);
836 if (IS_ERR(genpd))
837 return -EINVAL;
838
839 return genpd->suspend_power_off ? 0 : pm_generic_poweroff(dev);
840}
841
842/**
843 * pm_genpd_dev_poweroff_noirq - Late power off of a device from a PM domain.
844 * @dev: Device to suspend.
845 *
846 * Carry out a late powering off of a device under the assumption that its
847 * pm_domain field points to the domain member of an object of type
848 * struct generic_pm_domain representing a PM domain consisting of I/O devices.
849 */
850static int pm_genpd_dev_poweroff_noirq(struct device *dev)
851{
852 struct generic_pm_domain *genpd;
853 int ret;
854
855 dev_dbg(dev, "%s()\n", __func__);
856
857 genpd = dev_to_genpd(dev);
858 if (IS_ERR(genpd))
859 return -EINVAL;
860
861 if (genpd->suspend_power_off)
862 return 0;
863
864 ret = pm_generic_poweroff_noirq(dev);
865 if (ret)
866 return ret;
867
Rafael J. Wysockid4f2d872011-07-01 22:13:29 +0200868 if (device_may_wakeup(dev)
869 && genpd->active_wakeup && genpd->active_wakeup(dev))
870 return 0;
871
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200872 if (genpd->stop_device)
873 genpd->stop_device(dev);
874
875 /*
876 * Since all of the "noirq" callbacks are executed sequentially, it is
877 * guaranteed that this function will never run twice in parallel for
878 * the same PM domain, so it is not necessary to use locking here.
879 */
880 genpd->suspended_count++;
881 pm_genpd_sync_poweroff(genpd);
882
883 return 0;
884}
885
886/**
887 * pm_genpd_restore_noirq - Early restore of a device from an I/O power domain.
888 * @dev: Device to resume.
889 *
890 * Carry out an early restore of a device under the assumption that its
891 * pm_domain field points to the domain member of an object of type
892 * struct generic_pm_domain representing a power domain consisting of I/O
893 * devices.
894 */
895static int pm_genpd_restore_noirq(struct device *dev)
896{
897 struct generic_pm_domain *genpd;
898
899 dev_dbg(dev, "%s()\n", __func__);
900
901 genpd = dev_to_genpd(dev);
902 if (IS_ERR(genpd))
903 return -EINVAL;
904
905 /*
906 * Since all of the "noirq" callbacks are executed sequentially, it is
907 * guaranteed that this function will never run twice in parallel for
908 * the same PM domain, so it is not necessary to use locking here.
909 */
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200910 genpd->status = GPD_STATE_POWER_OFF;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200911 if (genpd->suspend_power_off) {
912 /*
913 * The boot kernel might put the domain into the power on state,
914 * so make sure it really is powered off.
915 */
916 if (genpd->power_off)
917 genpd->power_off(genpd);
918 return 0;
919 }
920
921 pm_genpd_poweron(genpd);
922 genpd->suspended_count--;
923 if (genpd->start_device)
924 genpd->start_device(dev);
925
926 return pm_generic_restore_noirq(dev);
927}
928
929/**
930 * pm_genpd_restore - Restore a device belonging to an I/O power domain.
931 * @dev: Device to resume.
932 *
933 * Restore a device under the assumption that its pm_domain field points to the
934 * domain member of an object of type struct generic_pm_domain representing
935 * a power domain consisting of I/O devices.
936 */
937static int pm_genpd_restore(struct device *dev)
938{
939 struct generic_pm_domain *genpd;
940
941 dev_dbg(dev, "%s()\n", __func__);
942
943 genpd = dev_to_genpd(dev);
944 if (IS_ERR(genpd))
945 return -EINVAL;
946
947 return genpd->suspend_power_off ? 0 : pm_generic_restore(dev);
948}
949
950/**
951 * pm_genpd_complete - Complete power transition of a device in a power domain.
952 * @dev: Device to complete the transition of.
953 *
954 * Complete a power transition of a device (during a system-wide power
955 * transition) under the assumption that its pm_domain field points to the
956 * domain member of an object of type struct generic_pm_domain representing
957 * a power domain consisting of I/O devices.
958 */
959static void pm_genpd_complete(struct device *dev)
960{
961 struct generic_pm_domain *genpd;
962 bool run_complete;
963
964 dev_dbg(dev, "%s()\n", __func__);
965
966 genpd = dev_to_genpd(dev);
967 if (IS_ERR(genpd))
968 return;
969
970 mutex_lock(&genpd->lock);
971
972 run_complete = !genpd->suspend_power_off;
973 if (--genpd->prepared_count == 0)
974 genpd->suspend_power_off = false;
975
976 mutex_unlock(&genpd->lock);
977
978 if (run_complete) {
979 pm_generic_complete(dev);
Rafael J. Wysocki6f00ff72011-07-12 00:39:10 +0200980 pm_runtime_set_active(dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200981 pm_runtime_enable(dev);
Rafael J. Wysocki6f00ff72011-07-12 00:39:10 +0200982 pm_runtime_idle(dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200983 }
984}
985
986#else
987
988#define pm_genpd_prepare NULL
989#define pm_genpd_suspend NULL
990#define pm_genpd_suspend_noirq NULL
991#define pm_genpd_resume_noirq NULL
992#define pm_genpd_resume NULL
993#define pm_genpd_freeze NULL
994#define pm_genpd_freeze_noirq NULL
995#define pm_genpd_thaw_noirq NULL
996#define pm_genpd_thaw NULL
997#define pm_genpd_dev_poweroff_noirq NULL
998#define pm_genpd_dev_poweroff NULL
999#define pm_genpd_restore_noirq NULL
1000#define pm_genpd_restore NULL
1001#define pm_genpd_complete NULL
1002
1003#endif /* CONFIG_PM_SLEEP */
1004
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001005/**
1006 * pm_genpd_add_device - Add a device to an I/O PM domain.
1007 * @genpd: PM domain to add the device to.
1008 * @dev: Device to be added.
1009 */
1010int pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev)
1011{
1012 struct dev_list_entry *dle;
1013 int ret = 0;
1014
1015 dev_dbg(dev, "%s()\n", __func__);
1016
1017 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev))
1018 return -EINVAL;
1019
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001020 genpd_acquire_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001021
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001022 if (genpd->status == GPD_STATE_POWER_OFF) {
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001023 ret = -EINVAL;
1024 goto out;
1025 }
1026
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001027 if (genpd->prepared_count > 0) {
1028 ret = -EAGAIN;
1029 goto out;
1030 }
1031
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001032 list_for_each_entry(dle, &genpd->dev_list, node)
1033 if (dle->dev == dev) {
1034 ret = -EINVAL;
1035 goto out;
1036 }
1037
1038 dle = kzalloc(sizeof(*dle), GFP_KERNEL);
1039 if (!dle) {
1040 ret = -ENOMEM;
1041 goto out;
1042 }
1043
1044 dle->dev = dev;
1045 dle->need_restore = false;
1046 list_add_tail(&dle->node, &genpd->dev_list);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001047 genpd->device_count++;
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001048
1049 spin_lock_irq(&dev->power.lock);
1050 dev->pm_domain = &genpd->domain;
1051 spin_unlock_irq(&dev->power.lock);
1052
1053 out:
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001054 genpd_release_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001055
1056 return ret;
1057}
1058
1059/**
1060 * pm_genpd_remove_device - Remove a device from an I/O PM domain.
1061 * @genpd: PM domain to remove the device from.
1062 * @dev: Device to be removed.
1063 */
1064int pm_genpd_remove_device(struct generic_pm_domain *genpd,
1065 struct device *dev)
1066{
1067 struct dev_list_entry *dle;
1068 int ret = -EINVAL;
1069
1070 dev_dbg(dev, "%s()\n", __func__);
1071
1072 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev))
1073 return -EINVAL;
1074
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001075 genpd_acquire_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001076
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001077 if (genpd->prepared_count > 0) {
1078 ret = -EAGAIN;
1079 goto out;
1080 }
1081
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001082 list_for_each_entry(dle, &genpd->dev_list, node) {
1083 if (dle->dev != dev)
1084 continue;
1085
1086 spin_lock_irq(&dev->power.lock);
1087 dev->pm_domain = NULL;
1088 spin_unlock_irq(&dev->power.lock);
1089
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001090 genpd->device_count--;
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001091 list_del(&dle->node);
1092 kfree(dle);
1093
1094 ret = 0;
1095 break;
1096 }
1097
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001098 out:
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001099 genpd_release_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001100
1101 return ret;
1102}
1103
1104/**
1105 * pm_genpd_add_subdomain - Add a subdomain to an I/O PM domain.
1106 * @genpd: Master PM domain to add the subdomain to.
1107 * @new_subdomain: Subdomain to be added.
1108 */
1109int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
1110 struct generic_pm_domain *new_subdomain)
1111{
1112 struct generic_pm_domain *subdomain;
1113 int ret = 0;
1114
1115 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(new_subdomain))
1116 return -EINVAL;
1117
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001118 start:
1119 genpd_acquire_lock(genpd);
1120 mutex_lock_nested(&new_subdomain->lock, SINGLE_DEPTH_NESTING);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001121
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001122 if (new_subdomain->status != GPD_STATE_POWER_OFF
1123 && new_subdomain->status != GPD_STATE_ACTIVE) {
1124 mutex_unlock(&new_subdomain->lock);
1125 genpd_release_lock(genpd);
1126 goto start;
1127 }
1128
1129 if (genpd->status == GPD_STATE_POWER_OFF
1130 && new_subdomain->status != GPD_STATE_POWER_OFF) {
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001131 ret = -EINVAL;
1132 goto out;
1133 }
1134
1135 list_for_each_entry(subdomain, &genpd->sd_list, sd_node) {
1136 if (subdomain == new_subdomain) {
1137 ret = -EINVAL;
1138 goto out;
1139 }
1140 }
1141
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001142 list_add_tail(&new_subdomain->sd_node, &genpd->sd_list);
1143 new_subdomain->parent = genpd;
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001144 if (subdomain->status != GPD_STATE_POWER_OFF)
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001145 genpd->sd_count++;
1146
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001147 out:
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001148 mutex_unlock(&new_subdomain->lock);
1149 genpd_release_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001150
1151 return ret;
1152}
1153
1154/**
1155 * pm_genpd_remove_subdomain - Remove a subdomain from an I/O PM domain.
1156 * @genpd: Master PM domain to remove the subdomain from.
1157 * @target: Subdomain to be removed.
1158 */
1159int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
1160 struct generic_pm_domain *target)
1161{
1162 struct generic_pm_domain *subdomain;
1163 int ret = -EINVAL;
1164
1165 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(target))
1166 return -EINVAL;
1167
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001168 start:
1169 genpd_acquire_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001170
1171 list_for_each_entry(subdomain, &genpd->sd_list, sd_node) {
1172 if (subdomain != target)
1173 continue;
1174
1175 mutex_lock_nested(&subdomain->lock, SINGLE_DEPTH_NESTING);
1176
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001177 if (subdomain->status != GPD_STATE_POWER_OFF
1178 && subdomain->status != GPD_STATE_ACTIVE) {
1179 mutex_unlock(&subdomain->lock);
1180 genpd_release_lock(genpd);
1181 goto start;
1182 }
1183
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001184 list_del(&subdomain->sd_node);
1185 subdomain->parent = NULL;
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001186 if (subdomain->status != GPD_STATE_POWER_OFF)
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001187 genpd_sd_counter_dec(genpd);
1188
1189 mutex_unlock(&subdomain->lock);
1190
1191 ret = 0;
1192 break;
1193 }
1194
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001195 genpd_release_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001196
1197 return ret;
1198}
1199
1200/**
1201 * pm_genpd_init - Initialize a generic I/O PM domain object.
1202 * @genpd: PM domain object to initialize.
1203 * @gov: PM domain governor to associate with the domain (may be NULL).
1204 * @is_off: Initial value of the domain's power_is_off field.
1205 */
1206void pm_genpd_init(struct generic_pm_domain *genpd,
1207 struct dev_power_governor *gov, bool is_off)
1208{
1209 if (IS_ERR_OR_NULL(genpd))
1210 return;
1211
1212 INIT_LIST_HEAD(&genpd->sd_node);
1213 genpd->parent = NULL;
1214 INIT_LIST_HEAD(&genpd->dev_list);
1215 INIT_LIST_HEAD(&genpd->sd_list);
1216 mutex_init(&genpd->lock);
1217 genpd->gov = gov;
1218 INIT_WORK(&genpd->power_off_work, genpd_power_off_work_fn);
1219 genpd->in_progress = 0;
1220 genpd->sd_count = 0;
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001221 genpd->status = is_off ? GPD_STATE_POWER_OFF : GPD_STATE_ACTIVE;
1222 init_waitqueue_head(&genpd->status_wait_queue);
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +02001223 genpd->poweroff_task = NULL;
1224 genpd->resume_count = 0;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001225 genpd->device_count = 0;
1226 genpd->suspended_count = 0;
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001227 genpd->domain.ops.runtime_suspend = pm_genpd_runtime_suspend;
1228 genpd->domain.ops.runtime_resume = pm_genpd_runtime_resume;
1229 genpd->domain.ops.runtime_idle = pm_generic_runtime_idle;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001230 genpd->domain.ops.prepare = pm_genpd_prepare;
1231 genpd->domain.ops.suspend = pm_genpd_suspend;
1232 genpd->domain.ops.suspend_noirq = pm_genpd_suspend_noirq;
1233 genpd->domain.ops.resume_noirq = pm_genpd_resume_noirq;
1234 genpd->domain.ops.resume = pm_genpd_resume;
1235 genpd->domain.ops.freeze = pm_genpd_freeze;
1236 genpd->domain.ops.freeze_noirq = pm_genpd_freeze_noirq;
1237 genpd->domain.ops.thaw_noirq = pm_genpd_thaw_noirq;
1238 genpd->domain.ops.thaw = pm_genpd_thaw;
1239 genpd->domain.ops.poweroff = pm_genpd_dev_poweroff;
1240 genpd->domain.ops.poweroff_noirq = pm_genpd_dev_poweroff_noirq;
1241 genpd->domain.ops.restore_noirq = pm_genpd_restore_noirq;
1242 genpd->domain.ops.restore = pm_genpd_restore;
1243 genpd->domain.ops.complete = pm_genpd_complete;
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001244}