blob: 1aed94c73cfc63c161a2ba61b9e0be47dc69062f [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>
16
Rafael J. Wysocki52480512011-07-01 22:13:10 +020017#ifdef CONFIG_PM
18
19static struct generic_pm_domain *dev_to_genpd(struct device *dev)
20{
21 if (IS_ERR_OR_NULL(dev->pm_domain))
22 return ERR_PTR(-EINVAL);
23
Rafael J. Wysocki596ba342011-07-01 22:13:19 +020024 return pd_to_genpd(dev->pm_domain);
Rafael J. Wysocki52480512011-07-01 22:13:10 +020025}
Rafael J. Wysockif7218892011-07-01 22:12:45 +020026
27static void genpd_sd_counter_dec(struct generic_pm_domain *genpd)
28{
29 if (!WARN_ON(genpd->sd_count == 0))
30 genpd->sd_count--;
31}
32
33/**
Rafael J. Wysocki52480512011-07-01 22:13:10 +020034 * pm_genpd_poweron - Restore power to a given PM domain and its parents.
35 * @genpd: PM domain to power up.
36 *
37 * Restore power to @genpd and all of its parents so that it is possible to
38 * resume a device belonging to it.
39 */
40static int pm_genpd_poweron(struct generic_pm_domain *genpd)
41{
42 int ret = 0;
43
44 start:
45 if (genpd->parent)
46 mutex_lock(&genpd->parent->lock);
47 mutex_lock_nested(&genpd->lock, SINGLE_DEPTH_NESTING);
48
Rafael J. Wysocki596ba342011-07-01 22:13:19 +020049 if (!genpd->power_is_off
50 || (genpd->prepared_count > 0 && genpd->suspend_power_off))
Rafael J. Wysocki52480512011-07-01 22:13:10 +020051 goto out;
52
53 if (genpd->parent && genpd->parent->power_is_off) {
54 mutex_unlock(&genpd->lock);
55 mutex_unlock(&genpd->parent->lock);
56
57 ret = pm_genpd_poweron(genpd->parent);
58 if (ret)
59 return ret;
60
61 goto start;
62 }
63
64 if (genpd->power_on) {
65 int ret = genpd->power_on(genpd);
66 if (ret)
67 goto out;
68 }
69
70 genpd->power_is_off = false;
71 if (genpd->parent)
72 genpd->parent->sd_count++;
73
74 out:
75 mutex_unlock(&genpd->lock);
76 if (genpd->parent)
77 mutex_unlock(&genpd->parent->lock);
78
79 return ret;
80}
81
82#endif /* CONFIG_PM */
83
84#ifdef CONFIG_PM_RUNTIME
85
86/**
Rafael J. Wysockif7218892011-07-01 22:12:45 +020087 * __pm_genpd_save_device - Save the pre-suspend state of a device.
88 * @dle: Device list entry of the device to save the state of.
89 * @genpd: PM domain the device belongs to.
90 */
91static int __pm_genpd_save_device(struct dev_list_entry *dle,
92 struct generic_pm_domain *genpd)
93{
94 struct device *dev = dle->dev;
95 struct device_driver *drv = dev->driver;
96 int ret = 0;
97
98 if (dle->need_restore)
99 return 0;
100
101 if (drv && drv->pm && drv->pm->runtime_suspend) {
102 if (genpd->start_device)
103 genpd->start_device(dev);
104
105 ret = drv->pm->runtime_suspend(dev);
106
107 if (genpd->stop_device)
108 genpd->stop_device(dev);
109 }
110
111 if (!ret)
112 dle->need_restore = true;
113
114 return ret;
115}
116
117/**
118 * __pm_genpd_restore_device - Restore the pre-suspend state of a device.
119 * @dle: Device list entry of the device to restore the state of.
120 * @genpd: PM domain the device belongs to.
121 */
122static void __pm_genpd_restore_device(struct dev_list_entry *dle,
123 struct generic_pm_domain *genpd)
124{
125 struct device *dev = dle->dev;
126 struct device_driver *drv = dev->driver;
127
128 if (!dle->need_restore)
129 return;
130
131 if (drv && drv->pm && drv->pm->runtime_resume) {
132 if (genpd->start_device)
133 genpd->start_device(dev);
134
135 drv->pm->runtime_resume(dev);
136
137 if (genpd->stop_device)
138 genpd->stop_device(dev);
139 }
140
141 dle->need_restore = false;
142}
143
144/**
145 * pm_genpd_poweroff - Remove power from a given PM domain.
146 * @genpd: PM domain to power down.
147 *
148 * If all of the @genpd's devices have been suspended and all of its subdomains
149 * have been powered down, run the runtime suspend callbacks provided by all of
150 * the @genpd's devices' drivers and remove power from @genpd.
151 */
152static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
153{
154 struct generic_pm_domain *parent;
155 struct dev_list_entry *dle;
156 unsigned int not_suspended;
157 int ret;
158
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200159 if (genpd->power_is_off || genpd->prepared_count > 0)
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200160 return 0;
161
162 if (genpd->sd_count > 0)
163 return -EBUSY;
164
165 not_suspended = 0;
166 list_for_each_entry(dle, &genpd->dev_list, node)
167 if (dle->dev->driver && !pm_runtime_suspended(dle->dev))
168 not_suspended++;
169
170 if (not_suspended > genpd->in_progress)
171 return -EBUSY;
172
173 if (genpd->gov && genpd->gov->power_down_ok) {
174 if (!genpd->gov->power_down_ok(&genpd->domain))
175 return -EAGAIN;
176 }
177
178 list_for_each_entry_reverse(dle, &genpd->dev_list, node) {
179 ret = __pm_genpd_save_device(dle, genpd);
180 if (ret)
181 goto err_dev;
182 }
183
184 if (genpd->power_off)
185 genpd->power_off(genpd);
186
187 genpd->power_is_off = true;
188
189 parent = genpd->parent;
190 if (parent) {
191 genpd_sd_counter_dec(parent);
192 if (parent->sd_count == 0)
193 queue_work(pm_wq, &parent->power_off_work);
194 }
195
196 return 0;
197
198 err_dev:
199 list_for_each_entry_continue(dle, &genpd->dev_list, node)
200 __pm_genpd_restore_device(dle, genpd);
201
202 return ret;
203}
204
205/**
206 * genpd_power_off_work_fn - Power off PM domain whose subdomain count is 0.
207 * @work: Work structure used for scheduling the execution of this function.
208 */
209static void genpd_power_off_work_fn(struct work_struct *work)
210{
211 struct generic_pm_domain *genpd;
212
213 genpd = container_of(work, struct generic_pm_domain, power_off_work);
214
215 if (genpd->parent)
216 mutex_lock(&genpd->parent->lock);
217 mutex_lock_nested(&genpd->lock, SINGLE_DEPTH_NESTING);
218 pm_genpd_poweroff(genpd);
219 mutex_unlock(&genpd->lock);
220 if (genpd->parent)
221 mutex_unlock(&genpd->parent->lock);
222}
223
224/**
225 * pm_genpd_runtime_suspend - Suspend a device belonging to I/O PM domain.
226 * @dev: Device to suspend.
227 *
228 * Carry out a runtime suspend of a device under the assumption that its
229 * pm_domain field points to the domain member of an object of type
230 * struct generic_pm_domain representing a PM domain consisting of I/O devices.
231 */
232static int pm_genpd_runtime_suspend(struct device *dev)
233{
234 struct generic_pm_domain *genpd;
235
236 dev_dbg(dev, "%s()\n", __func__);
237
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200238 genpd = dev_to_genpd(dev);
239 if (IS_ERR(genpd))
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200240 return -EINVAL;
241
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200242 if (genpd->parent)
243 mutex_lock(&genpd->parent->lock);
244 mutex_lock_nested(&genpd->lock, SINGLE_DEPTH_NESTING);
245
246 if (genpd->stop_device) {
247 int ret = genpd->stop_device(dev);
248 if (ret)
249 goto out;
250 }
251 genpd->in_progress++;
252 pm_genpd_poweroff(genpd);
253 genpd->in_progress--;
254
255 out:
256 mutex_unlock(&genpd->lock);
257 if (genpd->parent)
258 mutex_unlock(&genpd->parent->lock);
259
260 return 0;
261}
262
263/**
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200264 * __pm_genpd_runtime_resume - Resume a device belonging to I/O PM domain.
265 * @dev: Device to resume.
266 * @genpd: PM domain the device belongs to.
267 */
268static void __pm_genpd_runtime_resume(struct device *dev,
269 struct generic_pm_domain *genpd)
270{
271 struct dev_list_entry *dle;
272
273 list_for_each_entry(dle, &genpd->dev_list, node) {
274 if (dle->dev == dev) {
275 __pm_genpd_restore_device(dle, genpd);
276 break;
277 }
278 }
279
280 if (genpd->start_device)
281 genpd->start_device(dev);
282}
283
284/**
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200285 * pm_genpd_runtime_resume - Resume a device belonging to I/O PM domain.
286 * @dev: Device to resume.
287 *
288 * Carry out a runtime resume of a device under the assumption that its
289 * pm_domain field points to the domain member of an object of type
290 * struct generic_pm_domain representing a PM domain consisting of I/O devices.
291 */
292static int pm_genpd_runtime_resume(struct device *dev)
293{
294 struct generic_pm_domain *genpd;
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200295 int ret;
296
297 dev_dbg(dev, "%s()\n", __func__);
298
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200299 genpd = dev_to_genpd(dev);
300 if (IS_ERR(genpd))
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200301 return -EINVAL;
302
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200303 ret = pm_genpd_poweron(genpd);
304 if (ret)
305 return ret;
306
307 mutex_lock(&genpd->lock);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200308 __pm_genpd_runtime_resume(dev, genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200309 mutex_unlock(&genpd->lock);
310
311 return 0;
312}
313
314#else
315
316static inline void genpd_power_off_work_fn(struct work_struct *work) {}
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200317static inline void __pm_genpd_runtime_resume(struct device *dev,
318 struct generic_pm_domain *genpd) {}
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200319
320#define pm_genpd_runtime_suspend NULL
321#define pm_genpd_runtime_resume NULL
322
323#endif /* CONFIG_PM_RUNTIME */
324
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200325#ifdef CONFIG_PM_SLEEP
326
327/**
328 * pm_genpd_sync_poweroff - Synchronously power off a PM domain and its parents.
329 * @genpd: PM domain to power off, if possible.
330 *
331 * Check if the given PM domain can be powered off (during system suspend or
332 * hibernation) and do that if so. Also, in that case propagate to its parent.
333 *
334 * This function is only called in "noirq" stages of system power transitions,
335 * so it need not acquire locks (all of the "noirq" callbacks are executed
336 * sequentially, so it is guaranteed that it will never run twice in parallel).
337 */
338static void pm_genpd_sync_poweroff(struct generic_pm_domain *genpd)
339{
340 struct generic_pm_domain *parent = genpd->parent;
341
342 if (genpd->power_is_off)
343 return;
344
345 if (genpd->suspended_count != genpd->device_count || genpd->sd_count > 0)
346 return;
347
348 if (genpd->power_off)
349 genpd->power_off(genpd);
350
351 genpd->power_is_off = true;
352 if (parent) {
353 genpd_sd_counter_dec(parent);
354 pm_genpd_sync_poweroff(parent);
355 }
356}
357
358/**
359 * pm_genpd_prepare - Start power transition of a device in a PM domain.
360 * @dev: Device to start the transition of.
361 *
362 * Start a power transition of a device (during a system-wide power transition)
363 * under the assumption that its pm_domain field points to the domain member of
364 * an object of type struct generic_pm_domain representing a PM domain
365 * consisting of I/O devices.
366 */
367static int pm_genpd_prepare(struct device *dev)
368{
369 struct generic_pm_domain *genpd;
370
371 dev_dbg(dev, "%s()\n", __func__);
372
373 genpd = dev_to_genpd(dev);
374 if (IS_ERR(genpd))
375 return -EINVAL;
376
377 mutex_lock(&genpd->lock);
378
379 if (genpd->prepared_count++ == 0)
380 genpd->suspend_power_off = genpd->power_is_off;
381
382 if (genpd->suspend_power_off) {
383 mutex_unlock(&genpd->lock);
384 return 0;
385 }
386
387 /*
388 * If the device is in the (runtime) "suspended" state, call
389 * .start_device() for it, if defined.
390 */
391 if (pm_runtime_suspended(dev))
392 __pm_genpd_runtime_resume(dev, genpd);
393
394 /*
395 * Do not check if runtime resume is pending at this point, because it
396 * has been taken care of already and if pm_genpd_poweron() ran at this
397 * point as a result of the check, it would deadlock.
398 */
399 __pm_runtime_disable(dev, false);
400
401 mutex_unlock(&genpd->lock);
402
403 return pm_generic_prepare(dev);
404}
405
406/**
407 * pm_genpd_suspend - Suspend a device belonging to an I/O PM domain.
408 * @dev: Device to suspend.
409 *
410 * Suspend a device under the assumption that its pm_domain field points to the
411 * domain member of an object of type struct generic_pm_domain representing
412 * a PM domain consisting of I/O devices.
413 */
414static int pm_genpd_suspend(struct device *dev)
415{
416 struct generic_pm_domain *genpd;
417
418 dev_dbg(dev, "%s()\n", __func__);
419
420 genpd = dev_to_genpd(dev);
421 if (IS_ERR(genpd))
422 return -EINVAL;
423
424 return genpd->suspend_power_off ? 0 : pm_generic_suspend(dev);
425}
426
427/**
428 * pm_genpd_suspend_noirq - Late suspend of a device from an I/O PM domain.
429 * @dev: Device to suspend.
430 *
431 * Carry out a late suspend of a device under the assumption that its
432 * pm_domain field points to the domain member of an object of type
433 * struct generic_pm_domain representing a PM domain consisting of I/O devices.
434 */
435static int pm_genpd_suspend_noirq(struct device *dev)
436{
437 struct generic_pm_domain *genpd;
438 int ret;
439
440 dev_dbg(dev, "%s()\n", __func__);
441
442 genpd = dev_to_genpd(dev);
443 if (IS_ERR(genpd))
444 return -EINVAL;
445
446 if (genpd->suspend_power_off)
447 return 0;
448
449 ret = pm_generic_suspend_noirq(dev);
450 if (ret)
451 return ret;
452
Rafael J. Wysockid4f2d872011-07-01 22:13:29 +0200453 if (device_may_wakeup(dev)
454 && genpd->active_wakeup && genpd->active_wakeup(dev))
455 return 0;
456
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200457 if (genpd->stop_device)
458 genpd->stop_device(dev);
459
460 /*
461 * Since all of the "noirq" callbacks are executed sequentially, it is
462 * guaranteed that this function will never run twice in parallel for
463 * the same PM domain, so it is not necessary to use locking here.
464 */
465 genpd->suspended_count++;
466 pm_genpd_sync_poweroff(genpd);
467
468 return 0;
469}
470
471/**
472 * pm_genpd_resume_noirq - Early resume of a device from an I/O power domain.
473 * @dev: Device to resume.
474 *
475 * Carry out an early resume of a device under the assumption that its
476 * pm_domain field points to the domain member of an object of type
477 * struct generic_pm_domain representing a power domain consisting of I/O
478 * devices.
479 */
480static int pm_genpd_resume_noirq(struct device *dev)
481{
482 struct generic_pm_domain *genpd;
483
484 dev_dbg(dev, "%s()\n", __func__);
485
486 genpd = dev_to_genpd(dev);
487 if (IS_ERR(genpd))
488 return -EINVAL;
489
490 if (genpd->suspend_power_off)
491 return 0;
492
493 /*
494 * Since all of the "noirq" callbacks are executed sequentially, it is
495 * guaranteed that this function will never run twice in parallel for
496 * the same PM domain, so it is not necessary to use locking here.
497 */
498 pm_genpd_poweron(genpd);
499 genpd->suspended_count--;
500 if (genpd->start_device)
501 genpd->start_device(dev);
502
503 return pm_generic_resume_noirq(dev);
504}
505
506/**
507 * pm_genpd_resume - Resume a device belonging to an I/O power domain.
508 * @dev: Device to resume.
509 *
510 * Resume a device under the assumption that its pm_domain field points to the
511 * domain member of an object of type struct generic_pm_domain representing
512 * a power domain consisting of I/O devices.
513 */
514static int pm_genpd_resume(struct device *dev)
515{
516 struct generic_pm_domain *genpd;
517
518 dev_dbg(dev, "%s()\n", __func__);
519
520 genpd = dev_to_genpd(dev);
521 if (IS_ERR(genpd))
522 return -EINVAL;
523
524 return genpd->suspend_power_off ? 0 : pm_generic_resume(dev);
525}
526
527/**
528 * pm_genpd_freeze - Freeze a device belonging to an I/O power domain.
529 * @dev: Device to freeze.
530 *
531 * Freeze a device under the assumption that its pm_domain field points to the
532 * domain member of an object of type struct generic_pm_domain representing
533 * a power domain consisting of I/O devices.
534 */
535static int pm_genpd_freeze(struct device *dev)
536{
537 struct generic_pm_domain *genpd;
538
539 dev_dbg(dev, "%s()\n", __func__);
540
541 genpd = dev_to_genpd(dev);
542 if (IS_ERR(genpd))
543 return -EINVAL;
544
545 return genpd->suspend_power_off ? 0 : pm_generic_freeze(dev);
546}
547
548/**
549 * pm_genpd_freeze_noirq - Late freeze of a device from an I/O power domain.
550 * @dev: Device to freeze.
551 *
552 * Carry out a late freeze of a device under the assumption that its
553 * pm_domain field points to the domain member of an object of type
554 * struct generic_pm_domain representing a power domain consisting of I/O
555 * devices.
556 */
557static int pm_genpd_freeze_noirq(struct device *dev)
558{
559 struct generic_pm_domain *genpd;
560 int ret;
561
562 dev_dbg(dev, "%s()\n", __func__);
563
564 genpd = dev_to_genpd(dev);
565 if (IS_ERR(genpd))
566 return -EINVAL;
567
568 if (genpd->suspend_power_off)
569 return 0;
570
571 ret = pm_generic_freeze_noirq(dev);
572 if (ret)
573 return ret;
574
575 if (genpd->stop_device)
576 genpd->stop_device(dev);
577
578 return 0;
579}
580
581/**
582 * pm_genpd_thaw_noirq - Early thaw of a device from an I/O power domain.
583 * @dev: Device to thaw.
584 *
585 * Carry out an early thaw of a device under the assumption that its
586 * pm_domain field points to the domain member of an object of type
587 * struct generic_pm_domain representing a power domain consisting of I/O
588 * devices.
589 */
590static int pm_genpd_thaw_noirq(struct device *dev)
591{
592 struct generic_pm_domain *genpd;
593
594 dev_dbg(dev, "%s()\n", __func__);
595
596 genpd = dev_to_genpd(dev);
597 if (IS_ERR(genpd))
598 return -EINVAL;
599
600 if (genpd->suspend_power_off)
601 return 0;
602
603 if (genpd->start_device)
604 genpd->start_device(dev);
605
606 return pm_generic_thaw_noirq(dev);
607}
608
609/**
610 * pm_genpd_thaw - Thaw a device belonging to an I/O power domain.
611 * @dev: Device to thaw.
612 *
613 * Thaw a device under the assumption that its pm_domain field points to the
614 * domain member of an object of type struct generic_pm_domain representing
615 * a power domain consisting of I/O devices.
616 */
617static int pm_genpd_thaw(struct device *dev)
618{
619 struct generic_pm_domain *genpd;
620
621 dev_dbg(dev, "%s()\n", __func__);
622
623 genpd = dev_to_genpd(dev);
624 if (IS_ERR(genpd))
625 return -EINVAL;
626
627 return genpd->suspend_power_off ? 0 : pm_generic_thaw(dev);
628}
629
630/**
631 * pm_genpd_dev_poweroff - Power off a device belonging to an I/O PM domain.
632 * @dev: Device to suspend.
633 *
634 * Power off a device under the assumption that its pm_domain field points to
635 * the domain member of an object of type struct generic_pm_domain representing
636 * a PM domain consisting of I/O devices.
637 */
638static int pm_genpd_dev_poweroff(struct device *dev)
639{
640 struct generic_pm_domain *genpd;
641
642 dev_dbg(dev, "%s()\n", __func__);
643
644 genpd = dev_to_genpd(dev);
645 if (IS_ERR(genpd))
646 return -EINVAL;
647
648 return genpd->suspend_power_off ? 0 : pm_generic_poweroff(dev);
649}
650
651/**
652 * pm_genpd_dev_poweroff_noirq - Late power off of a device from a PM domain.
653 * @dev: Device to suspend.
654 *
655 * Carry out a late powering off of a device under the assumption that its
656 * pm_domain field points to the domain member of an object of type
657 * struct generic_pm_domain representing a PM domain consisting of I/O devices.
658 */
659static int pm_genpd_dev_poweroff_noirq(struct device *dev)
660{
661 struct generic_pm_domain *genpd;
662 int ret;
663
664 dev_dbg(dev, "%s()\n", __func__);
665
666 genpd = dev_to_genpd(dev);
667 if (IS_ERR(genpd))
668 return -EINVAL;
669
670 if (genpd->suspend_power_off)
671 return 0;
672
673 ret = pm_generic_poweroff_noirq(dev);
674 if (ret)
675 return ret;
676
Rafael J. Wysockid4f2d872011-07-01 22:13:29 +0200677 if (device_may_wakeup(dev)
678 && genpd->active_wakeup && genpd->active_wakeup(dev))
679 return 0;
680
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200681 if (genpd->stop_device)
682 genpd->stop_device(dev);
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 genpd->suspended_count++;
690 pm_genpd_sync_poweroff(genpd);
691
692 return 0;
693}
694
695/**
696 * pm_genpd_restore_noirq - Early restore of a device from an I/O power domain.
697 * @dev: Device to resume.
698 *
699 * Carry out an early restore of a device under the assumption that its
700 * pm_domain field points to the domain member of an object of type
701 * struct generic_pm_domain representing a power domain consisting of I/O
702 * devices.
703 */
704static int pm_genpd_restore_noirq(struct device *dev)
705{
706 struct generic_pm_domain *genpd;
707
708 dev_dbg(dev, "%s()\n", __func__);
709
710 genpd = dev_to_genpd(dev);
711 if (IS_ERR(genpd))
712 return -EINVAL;
713
714 /*
715 * Since all of the "noirq" callbacks are executed sequentially, it is
716 * guaranteed that this function will never run twice in parallel for
717 * the same PM domain, so it is not necessary to use locking here.
718 */
719 genpd->power_is_off = true;
720 if (genpd->suspend_power_off) {
721 /*
722 * The boot kernel might put the domain into the power on state,
723 * so make sure it really is powered off.
724 */
725 if (genpd->power_off)
726 genpd->power_off(genpd);
727 return 0;
728 }
729
730 pm_genpd_poweron(genpd);
731 genpd->suspended_count--;
732 if (genpd->start_device)
733 genpd->start_device(dev);
734
735 return pm_generic_restore_noirq(dev);
736}
737
738/**
739 * pm_genpd_restore - Restore a device belonging to an I/O power domain.
740 * @dev: Device to resume.
741 *
742 * Restore a device under the assumption that its pm_domain field points to the
743 * domain member of an object of type struct generic_pm_domain representing
744 * a power domain consisting of I/O devices.
745 */
746static int pm_genpd_restore(struct device *dev)
747{
748 struct generic_pm_domain *genpd;
749
750 dev_dbg(dev, "%s()\n", __func__);
751
752 genpd = dev_to_genpd(dev);
753 if (IS_ERR(genpd))
754 return -EINVAL;
755
756 return genpd->suspend_power_off ? 0 : pm_generic_restore(dev);
757}
758
759/**
760 * pm_genpd_complete - Complete power transition of a device in a power domain.
761 * @dev: Device to complete the transition of.
762 *
763 * Complete a power transition of a device (during a system-wide power
764 * transition) under the assumption that its pm_domain field points to the
765 * domain member of an object of type struct generic_pm_domain representing
766 * a power domain consisting of I/O devices.
767 */
768static void pm_genpd_complete(struct device *dev)
769{
770 struct generic_pm_domain *genpd;
771 bool run_complete;
772
773 dev_dbg(dev, "%s()\n", __func__);
774
775 genpd = dev_to_genpd(dev);
776 if (IS_ERR(genpd))
777 return;
778
779 mutex_lock(&genpd->lock);
780
781 run_complete = !genpd->suspend_power_off;
782 if (--genpd->prepared_count == 0)
783 genpd->suspend_power_off = false;
784
785 mutex_unlock(&genpd->lock);
786
787 if (run_complete) {
788 pm_generic_complete(dev);
789 pm_runtime_enable(dev);
790 }
791}
792
793#else
794
795#define pm_genpd_prepare NULL
796#define pm_genpd_suspend NULL
797#define pm_genpd_suspend_noirq NULL
798#define pm_genpd_resume_noirq NULL
799#define pm_genpd_resume NULL
800#define pm_genpd_freeze NULL
801#define pm_genpd_freeze_noirq NULL
802#define pm_genpd_thaw_noirq NULL
803#define pm_genpd_thaw NULL
804#define pm_genpd_dev_poweroff_noirq NULL
805#define pm_genpd_dev_poweroff NULL
806#define pm_genpd_restore_noirq NULL
807#define pm_genpd_restore NULL
808#define pm_genpd_complete NULL
809
810#endif /* CONFIG_PM_SLEEP */
811
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200812/**
813 * pm_genpd_add_device - Add a device to an I/O PM domain.
814 * @genpd: PM domain to add the device to.
815 * @dev: Device to be added.
816 */
817int pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev)
818{
819 struct dev_list_entry *dle;
820 int ret = 0;
821
822 dev_dbg(dev, "%s()\n", __func__);
823
824 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev))
825 return -EINVAL;
826
827 mutex_lock(&genpd->lock);
828
829 if (genpd->power_is_off) {
830 ret = -EINVAL;
831 goto out;
832 }
833
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200834 if (genpd->prepared_count > 0) {
835 ret = -EAGAIN;
836 goto out;
837 }
838
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200839 list_for_each_entry(dle, &genpd->dev_list, node)
840 if (dle->dev == dev) {
841 ret = -EINVAL;
842 goto out;
843 }
844
845 dle = kzalloc(sizeof(*dle), GFP_KERNEL);
846 if (!dle) {
847 ret = -ENOMEM;
848 goto out;
849 }
850
851 dle->dev = dev;
852 dle->need_restore = false;
853 list_add_tail(&dle->node, &genpd->dev_list);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200854 genpd->device_count++;
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200855
856 spin_lock_irq(&dev->power.lock);
857 dev->pm_domain = &genpd->domain;
858 spin_unlock_irq(&dev->power.lock);
859
860 out:
861 mutex_unlock(&genpd->lock);
862
863 return ret;
864}
865
866/**
867 * pm_genpd_remove_device - Remove a device from an I/O PM domain.
868 * @genpd: PM domain to remove the device from.
869 * @dev: Device to be removed.
870 */
871int pm_genpd_remove_device(struct generic_pm_domain *genpd,
872 struct device *dev)
873{
874 struct dev_list_entry *dle;
875 int ret = -EINVAL;
876
877 dev_dbg(dev, "%s()\n", __func__);
878
879 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev))
880 return -EINVAL;
881
882 mutex_lock(&genpd->lock);
883
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200884 if (genpd->prepared_count > 0) {
885 ret = -EAGAIN;
886 goto out;
887 }
888
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200889 list_for_each_entry(dle, &genpd->dev_list, node) {
890 if (dle->dev != dev)
891 continue;
892
893 spin_lock_irq(&dev->power.lock);
894 dev->pm_domain = NULL;
895 spin_unlock_irq(&dev->power.lock);
896
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200897 genpd->device_count--;
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200898 list_del(&dle->node);
899 kfree(dle);
900
901 ret = 0;
902 break;
903 }
904
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200905 out:
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200906 mutex_unlock(&genpd->lock);
907
908 return ret;
909}
910
911/**
912 * pm_genpd_add_subdomain - Add a subdomain to an I/O PM domain.
913 * @genpd: Master PM domain to add the subdomain to.
914 * @new_subdomain: Subdomain to be added.
915 */
916int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
917 struct generic_pm_domain *new_subdomain)
918{
919 struct generic_pm_domain *subdomain;
920 int ret = 0;
921
922 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(new_subdomain))
923 return -EINVAL;
924
925 mutex_lock(&genpd->lock);
926
927 if (genpd->power_is_off && !new_subdomain->power_is_off) {
928 ret = -EINVAL;
929 goto out;
930 }
931
932 list_for_each_entry(subdomain, &genpd->sd_list, sd_node) {
933 if (subdomain == new_subdomain) {
934 ret = -EINVAL;
935 goto out;
936 }
937 }
938
939 mutex_lock_nested(&new_subdomain->lock, SINGLE_DEPTH_NESTING);
940
941 list_add_tail(&new_subdomain->sd_node, &genpd->sd_list);
942 new_subdomain->parent = genpd;
943 if (!subdomain->power_is_off)
944 genpd->sd_count++;
945
946 mutex_unlock(&new_subdomain->lock);
947
948 out:
949 mutex_unlock(&genpd->lock);
950
951 return ret;
952}
953
954/**
955 * pm_genpd_remove_subdomain - Remove a subdomain from an I/O PM domain.
956 * @genpd: Master PM domain to remove the subdomain from.
957 * @target: Subdomain to be removed.
958 */
959int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
960 struct generic_pm_domain *target)
961{
962 struct generic_pm_domain *subdomain;
963 int ret = -EINVAL;
964
965 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(target))
966 return -EINVAL;
967
968 mutex_lock(&genpd->lock);
969
970 list_for_each_entry(subdomain, &genpd->sd_list, sd_node) {
971 if (subdomain != target)
972 continue;
973
974 mutex_lock_nested(&subdomain->lock, SINGLE_DEPTH_NESTING);
975
976 list_del(&subdomain->sd_node);
977 subdomain->parent = NULL;
978 if (!subdomain->power_is_off)
979 genpd_sd_counter_dec(genpd);
980
981 mutex_unlock(&subdomain->lock);
982
983 ret = 0;
984 break;
985 }
986
987 mutex_unlock(&genpd->lock);
988
989 return ret;
990}
991
992/**
993 * pm_genpd_init - Initialize a generic I/O PM domain object.
994 * @genpd: PM domain object to initialize.
995 * @gov: PM domain governor to associate with the domain (may be NULL).
996 * @is_off: Initial value of the domain's power_is_off field.
997 */
998void pm_genpd_init(struct generic_pm_domain *genpd,
999 struct dev_power_governor *gov, bool is_off)
1000{
1001 if (IS_ERR_OR_NULL(genpd))
1002 return;
1003
1004 INIT_LIST_HEAD(&genpd->sd_node);
1005 genpd->parent = NULL;
1006 INIT_LIST_HEAD(&genpd->dev_list);
1007 INIT_LIST_HEAD(&genpd->sd_list);
1008 mutex_init(&genpd->lock);
1009 genpd->gov = gov;
1010 INIT_WORK(&genpd->power_off_work, genpd_power_off_work_fn);
1011 genpd->in_progress = 0;
1012 genpd->sd_count = 0;
1013 genpd->power_is_off = is_off;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001014 genpd->device_count = 0;
1015 genpd->suspended_count = 0;
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001016 genpd->domain.ops.runtime_suspend = pm_genpd_runtime_suspend;
1017 genpd->domain.ops.runtime_resume = pm_genpd_runtime_resume;
1018 genpd->domain.ops.runtime_idle = pm_generic_runtime_idle;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001019 genpd->domain.ops.prepare = pm_genpd_prepare;
1020 genpd->domain.ops.suspend = pm_genpd_suspend;
1021 genpd->domain.ops.suspend_noirq = pm_genpd_suspend_noirq;
1022 genpd->domain.ops.resume_noirq = pm_genpd_resume_noirq;
1023 genpd->domain.ops.resume = pm_genpd_resume;
1024 genpd->domain.ops.freeze = pm_genpd_freeze;
1025 genpd->domain.ops.freeze_noirq = pm_genpd_freeze_noirq;
1026 genpd->domain.ops.thaw_noirq = pm_genpd_thaw_noirq;
1027 genpd->domain.ops.thaw = pm_genpd_thaw;
1028 genpd->domain.ops.poweroff = pm_genpd_dev_poweroff;
1029 genpd->domain.ops.poweroff_noirq = pm_genpd_dev_poweroff_noirq;
1030 genpd->domain.ops.restore_noirq = pm_genpd_restore_noirq;
1031 genpd->domain.ops.restore = pm_genpd_restore;
1032 genpd->domain.ops.complete = pm_genpd_complete;
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001033}