blob: 94afaa2686a65aece53192174d366bda0a1328d0 [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. Wysockid5e4cbf2011-11-27 13:11:36 +010018#include <linux/export.h>
19
20#define GENPD_DEV_CALLBACK(genpd, type, callback, dev) \
21({ \
22 type (*__routine)(struct device *__d); \
23 type __ret = (type)0; \
24 \
25 __routine = genpd->dev_ops.callback; \
26 if (__routine) { \
27 __ret = __routine(dev); \
28 } else { \
29 __routine = dev_gpd_data(dev)->ops.callback; \
30 if (__routine) \
31 __ret = __routine(dev); \
32 } \
33 __ret; \
34})
Rafael J. Wysockif7218892011-07-01 22:12:45 +020035
Rafael J. Wysocki5125bbf382011-07-13 12:31:52 +020036static LIST_HEAD(gpd_list);
37static DEFINE_MUTEX(gpd_list_lock);
38
Rafael J. Wysocki52480512011-07-01 22:13:10 +020039#ifdef CONFIG_PM
40
41static struct generic_pm_domain *dev_to_genpd(struct device *dev)
42{
43 if (IS_ERR_OR_NULL(dev->pm_domain))
44 return ERR_PTR(-EINVAL);
45
Rafael J. Wysocki596ba342011-07-01 22:13:19 +020046 return pd_to_genpd(dev->pm_domain);
Rafael J. Wysocki52480512011-07-01 22:13:10 +020047}
Rafael J. Wysockif7218892011-07-01 22:12:45 +020048
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +010049static int genpd_stop_dev(struct generic_pm_domain *genpd, struct device *dev)
50{
51 return GENPD_DEV_CALLBACK(genpd, int, stop, dev);
52}
53
54static int genpd_start_dev(struct generic_pm_domain *genpd, struct device *dev)
55{
56 return GENPD_DEV_CALLBACK(genpd, int, start, dev);
57}
58
Rafael J. Wysockic4bb3162011-08-08 23:43:04 +020059static bool genpd_sd_counter_dec(struct generic_pm_domain *genpd)
Rafael J. Wysockif7218892011-07-01 22:12:45 +020060{
Rafael J. Wysockic4bb3162011-08-08 23:43:04 +020061 bool ret = false;
62
63 if (!WARN_ON(atomic_read(&genpd->sd_count) == 0))
64 ret = !!atomic_dec_and_test(&genpd->sd_count);
65
66 return ret;
67}
68
69static void genpd_sd_counter_inc(struct generic_pm_domain *genpd)
70{
71 atomic_inc(&genpd->sd_count);
72 smp_mb__after_atomic_inc();
Rafael J. Wysockif7218892011-07-01 22:12:45 +020073}
74
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +020075static void genpd_acquire_lock(struct generic_pm_domain *genpd)
76{
77 DEFINE_WAIT(wait);
78
79 mutex_lock(&genpd->lock);
80 /*
81 * Wait for the domain to transition into either the active,
82 * or the power off state.
83 */
84 for (;;) {
85 prepare_to_wait(&genpd->status_wait_queue, &wait,
86 TASK_UNINTERRUPTIBLE);
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +020087 if (genpd->status == GPD_STATE_ACTIVE
88 || genpd->status == GPD_STATE_POWER_OFF)
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +020089 break;
90 mutex_unlock(&genpd->lock);
91
92 schedule();
93
94 mutex_lock(&genpd->lock);
95 }
96 finish_wait(&genpd->status_wait_queue, &wait);
97}
98
99static void genpd_release_lock(struct generic_pm_domain *genpd)
100{
101 mutex_unlock(&genpd->lock);
102}
103
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200104static void genpd_set_active(struct generic_pm_domain *genpd)
105{
106 if (genpd->resume_count == 0)
107 genpd->status = GPD_STATE_ACTIVE;
108}
109
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200110/**
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200111 * __pm_genpd_poweron - Restore power to a given PM domain and its masters.
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200112 * @genpd: PM domain to power up.
113 *
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200114 * Restore power to @genpd and all of its masters so that it is possible to
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200115 * resume a device belonging to it.
116 */
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200117int __pm_genpd_poweron(struct generic_pm_domain *genpd)
118 __releases(&genpd->lock) __acquires(&genpd->lock)
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200119{
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200120 struct gpd_link *link;
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200121 DEFINE_WAIT(wait);
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200122 int ret = 0;
123
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200124 /* If the domain's master is being waited for, we have to wait too. */
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200125 for (;;) {
126 prepare_to_wait(&genpd->status_wait_queue, &wait,
127 TASK_UNINTERRUPTIBLE);
Rafael J. Wysocki17877eb2011-08-08 23:43:50 +0200128 if (genpd->status != GPD_STATE_WAIT_MASTER)
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200129 break;
130 mutex_unlock(&genpd->lock);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200131
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200132 schedule();
Rafael J. Wysocki9e08cf42011-08-08 23:43:22 +0200133
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200134 mutex_lock(&genpd->lock);
135 }
136 finish_wait(&genpd->status_wait_queue, &wait);
137
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200138 if (genpd->status == GPD_STATE_ACTIVE
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200139 || (genpd->prepared_count > 0 && genpd->suspend_power_off))
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200140 return 0;
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200141
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200142 if (genpd->status != GPD_STATE_POWER_OFF) {
143 genpd_set_active(genpd);
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200144 return 0;
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200145 }
146
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200147 /*
148 * The list is guaranteed not to change while the loop below is being
149 * executed, unless one of the masters' .power_on() callbacks fiddles
150 * with it.
151 */
152 list_for_each_entry(link, &genpd->slave_links, slave_node) {
153 genpd_sd_counter_inc(link->master);
Rafael J. Wysocki17877eb2011-08-08 23:43:50 +0200154 genpd->status = GPD_STATE_WAIT_MASTER;
Rafael J. Wysocki3c07cbc2011-08-08 23:43:14 +0200155
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200156 mutex_unlock(&genpd->lock);
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200157
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200158 ret = pm_genpd_poweron(link->master);
Rafael J. Wysocki9e08cf42011-08-08 23:43:22 +0200159
160 mutex_lock(&genpd->lock);
161
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200162 /*
163 * The "wait for parent" status is guaranteed not to change
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200164 * while the master is powering on.
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200165 */
166 genpd->status = GPD_STATE_POWER_OFF;
167 wake_up_all(&genpd->status_wait_queue);
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200168 if (ret) {
169 genpd_sd_counter_dec(link->master);
Rafael J. Wysocki9e08cf42011-08-08 23:43:22 +0200170 goto err;
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200171 }
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200172 }
173
Rafael J. Wysocki9e08cf42011-08-08 23:43:22 +0200174 if (genpd->power_on) {
Rafael J. Wysockife202fd2011-08-05 21:45:11 +0200175 ret = genpd->power_on(genpd);
Rafael J. Wysocki9e08cf42011-08-08 23:43:22 +0200176 if (ret)
177 goto err;
Rafael J. Wysocki3c07cbc2011-08-08 23:43:14 +0200178 }
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200179
Rafael J. Wysocki9e08cf42011-08-08 23:43:22 +0200180 genpd_set_active(genpd);
181
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200182 return 0;
Rafael J. Wysocki9e08cf42011-08-08 23:43:22 +0200183
184 err:
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200185 list_for_each_entry_continue_reverse(link, &genpd->slave_links, slave_node)
186 genpd_sd_counter_dec(link->master);
Rafael J. Wysocki9e08cf42011-08-08 23:43:22 +0200187
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200188 return ret;
189}
190
191/**
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200192 * pm_genpd_poweron - Restore power to a given PM domain and its masters.
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200193 * @genpd: PM domain to power up.
194 */
195int pm_genpd_poweron(struct generic_pm_domain *genpd)
196{
197 int ret;
198
199 mutex_lock(&genpd->lock);
200 ret = __pm_genpd_poweron(genpd);
201 mutex_unlock(&genpd->lock);
202 return ret;
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200203}
204
205#endif /* CONFIG_PM */
206
207#ifdef CONFIG_PM_RUNTIME
208
209/**
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200210 * __pm_genpd_save_device - Save the pre-suspend state of a device.
Rafael J. Wysocki4605ab62011-08-25 15:34:12 +0200211 * @pdd: Domain data of the device to save the state of.
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200212 * @genpd: PM domain the device belongs to.
213 */
Rafael J. Wysocki4605ab62011-08-25 15:34:12 +0200214static int __pm_genpd_save_device(struct pm_domain_data *pdd,
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200215 struct generic_pm_domain *genpd)
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200216 __releases(&genpd->lock) __acquires(&genpd->lock)
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200217{
Rafael J. Wysockicd0ea672011-09-26 20:22:02 +0200218 struct generic_pm_domain_data *gpd_data = to_gpd_data(pdd);
Rafael J. Wysocki4605ab62011-08-25 15:34:12 +0200219 struct device *dev = pdd->dev;
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200220 struct device_driver *drv = dev->driver;
221 int ret = 0;
222
Rafael J. Wysockicd0ea672011-09-26 20:22:02 +0200223 if (gpd_data->need_restore)
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200224 return 0;
225
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200226 mutex_unlock(&genpd->lock);
227
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200228 if (drv && drv->pm && drv->pm->runtime_suspend) {
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +0100229 genpd_start_dev(genpd, dev);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200230 ret = drv->pm->runtime_suspend(dev);
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +0100231 genpd_stop_dev(genpd, dev);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200232 }
233
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200234 mutex_lock(&genpd->lock);
235
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200236 if (!ret)
Rafael J. Wysockicd0ea672011-09-26 20:22:02 +0200237 gpd_data->need_restore = true;
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200238
239 return ret;
240}
241
242/**
243 * __pm_genpd_restore_device - Restore the pre-suspend state of a device.
Rafael J. Wysocki4605ab62011-08-25 15:34:12 +0200244 * @pdd: Domain data of the device to restore the state of.
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200245 * @genpd: PM domain the device belongs to.
246 */
Rafael J. Wysocki4605ab62011-08-25 15:34:12 +0200247static void __pm_genpd_restore_device(struct pm_domain_data *pdd,
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200248 struct generic_pm_domain *genpd)
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200249 __releases(&genpd->lock) __acquires(&genpd->lock)
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200250{
Rafael J. Wysockicd0ea672011-09-26 20:22:02 +0200251 struct generic_pm_domain_data *gpd_data = to_gpd_data(pdd);
Rafael J. Wysocki4605ab62011-08-25 15:34:12 +0200252 struct device *dev = pdd->dev;
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200253 struct device_driver *drv = dev->driver;
254
Rafael J. Wysockicd0ea672011-09-26 20:22:02 +0200255 if (!gpd_data->need_restore)
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200256 return;
257
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200258 mutex_unlock(&genpd->lock);
259
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200260 if (drv && drv->pm && drv->pm->runtime_resume) {
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +0100261 genpd_start_dev(genpd, dev);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200262 drv->pm->runtime_resume(dev);
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +0100263 genpd_stop_dev(genpd, dev);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200264 }
265
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200266 mutex_lock(&genpd->lock);
267
Rafael J. Wysockicd0ea672011-09-26 20:22:02 +0200268 gpd_data->need_restore = false;
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200269}
270
271/**
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200272 * genpd_abort_poweroff - Check if a PM domain power off should be aborted.
273 * @genpd: PM domain to check.
274 *
275 * Return true if a PM domain's status changed to GPD_STATE_ACTIVE during
276 * a "power off" operation, which means that a "power on" has occured in the
277 * meantime, or if its resume_count field is different from zero, which means
278 * that one of its devices has been resumed in the meantime.
279 */
280static bool genpd_abort_poweroff(struct generic_pm_domain *genpd)
281{
Rafael J. Wysocki17877eb2011-08-08 23:43:50 +0200282 return genpd->status == GPD_STATE_WAIT_MASTER
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200283 || genpd->status == GPD_STATE_ACTIVE || genpd->resume_count > 0;
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200284}
285
286/**
Rafael J. Wysocki56375fd2011-07-12 00:40:03 +0200287 * genpd_queue_power_off_work - Queue up the execution of pm_genpd_poweroff().
288 * @genpd: PM domait to power off.
289 *
290 * Queue up the execution of pm_genpd_poweroff() unless it's already been done
291 * before.
292 */
Rafael J. Wysocki0bc5b2d2011-07-14 20:59:07 +0200293void genpd_queue_power_off_work(struct generic_pm_domain *genpd)
Rafael J. Wysocki56375fd2011-07-12 00:40:03 +0200294{
295 if (!work_pending(&genpd->power_off_work))
296 queue_work(pm_wq, &genpd->power_off_work);
297}
298
299/**
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200300 * pm_genpd_poweroff - Remove power from a given PM domain.
301 * @genpd: PM domain to power down.
302 *
303 * If all of the @genpd's devices have been suspended and all of its subdomains
304 * have been powered down, run the runtime suspend callbacks provided by all of
305 * the @genpd's devices' drivers and remove power from @genpd.
306 */
307static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200308 __releases(&genpd->lock) __acquires(&genpd->lock)
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200309{
Rafael J. Wysocki4605ab62011-08-25 15:34:12 +0200310 struct pm_domain_data *pdd;
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200311 struct gpd_link *link;
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200312 unsigned int not_suspended;
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200313 int ret = 0;
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200314
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200315 start:
316 /*
317 * Do not try to power off the domain in the following situations:
318 * (1) The domain is already in the "power off" state.
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200319 * (2) The domain is waiting for its master to power up.
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200320 * (3) One of the domain's devices is being resumed right now.
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200321 * (4) System suspend is in progress.
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200322 */
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200323 if (genpd->status == GPD_STATE_POWER_OFF
Rafael J. Wysocki17877eb2011-08-08 23:43:50 +0200324 || genpd->status == GPD_STATE_WAIT_MASTER
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200325 || genpd->resume_count > 0 || genpd->prepared_count > 0)
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200326 return 0;
327
Rafael J. Wysockic4bb3162011-08-08 23:43:04 +0200328 if (atomic_read(&genpd->sd_count) > 0)
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200329 return -EBUSY;
330
331 not_suspended = 0;
Rafael J. Wysocki4605ab62011-08-25 15:34:12 +0200332 list_for_each_entry(pdd, &genpd->dev_list, list_node)
Rafael J. Wysocki0aa2a222011-08-25 15:37:04 +0200333 if (pdd->dev->driver && (!pm_runtime_suspended(pdd->dev)
334 || pdd->dev->power.irq_safe))
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200335 not_suspended++;
336
337 if (not_suspended > genpd->in_progress)
338 return -EBUSY;
339
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200340 if (genpd->poweroff_task) {
341 /*
342 * Another instance of pm_genpd_poweroff() is executing
343 * callbacks, so tell it to start over and return.
344 */
345 genpd->status = GPD_STATE_REPEAT;
346 return 0;
347 }
348
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200349 if (genpd->gov && genpd->gov->power_down_ok) {
350 if (!genpd->gov->power_down_ok(&genpd->domain))
351 return -EAGAIN;
352 }
353
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200354 genpd->status = GPD_STATE_BUSY;
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200355 genpd->poweroff_task = current;
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200356
Rafael J. Wysocki4605ab62011-08-25 15:34:12 +0200357 list_for_each_entry_reverse(pdd, &genpd->dev_list, list_node) {
Rafael J. Wysocki3c07cbc2011-08-08 23:43:14 +0200358 ret = atomic_read(&genpd->sd_count) == 0 ?
Rafael J. Wysocki4605ab62011-08-25 15:34:12 +0200359 __pm_genpd_save_device(pdd, genpd) : -EBUSY;
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200360
361 if (genpd_abort_poweroff(genpd))
362 goto out;
363
Rafael J. Wysocki697a7f32011-07-12 00:39:48 +0200364 if (ret) {
365 genpd_set_active(genpd);
366 goto out;
367 }
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200368
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200369 if (genpd->status == GPD_STATE_REPEAT) {
370 genpd->poweroff_task = NULL;
371 goto start;
372 }
373 }
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200374
Rafael J. Wysocki3c07cbc2011-08-08 23:43:14 +0200375 if (genpd->power_off) {
376 if (atomic_read(&genpd->sd_count) > 0) {
377 ret = -EBUSY;
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200378 goto out;
379 }
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200380
Rafael J. Wysocki3c07cbc2011-08-08 23:43:14 +0200381 /*
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200382 * If sd_count > 0 at this point, one of the subdomains hasn't
383 * managed to call pm_genpd_poweron() for the master yet after
Rafael J. Wysocki3c07cbc2011-08-08 23:43:14 +0200384 * incrementing it. In that case pm_genpd_poweron() will wait
385 * for us to drop the lock, so we can call .power_off() and let
386 * the pm_genpd_poweron() restore power for us (this shouldn't
387 * happen very often).
388 */
Rafael J. Wysockid2805402011-07-14 20:59:20 +0200389 ret = genpd->power_off(genpd);
390 if (ret == -EBUSY) {
391 genpd_set_active(genpd);
Rafael J. Wysockid2805402011-07-14 20:59:20 +0200392 goto out;
393 }
394 }
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200395
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200396 genpd->status = GPD_STATE_POWER_OFF;
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200397
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200398 list_for_each_entry(link, &genpd->slave_links, slave_node) {
399 genpd_sd_counter_dec(link->master);
400 genpd_queue_power_off_work(link->master);
401 }
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200402
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200403 out:
404 genpd->poweroff_task = NULL;
405 wake_up_all(&genpd->status_wait_queue);
406 return ret;
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200407}
408
409/**
410 * genpd_power_off_work_fn - Power off PM domain whose subdomain count is 0.
411 * @work: Work structure used for scheduling the execution of this function.
412 */
413static void genpd_power_off_work_fn(struct work_struct *work)
414{
415 struct generic_pm_domain *genpd;
416
417 genpd = container_of(work, struct generic_pm_domain, power_off_work);
418
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200419 genpd_acquire_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200420 pm_genpd_poweroff(genpd);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200421 genpd_release_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200422}
423
424/**
425 * pm_genpd_runtime_suspend - Suspend a device belonging to I/O PM domain.
426 * @dev: Device to suspend.
427 *
428 * Carry out a runtime suspend of a device under the assumption that its
429 * pm_domain field points to the domain member of an object of type
430 * struct generic_pm_domain representing a PM domain consisting of I/O devices.
431 */
432static int pm_genpd_runtime_suspend(struct device *dev)
433{
434 struct generic_pm_domain *genpd;
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +0100435 int ret;
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200436
437 dev_dbg(dev, "%s()\n", __func__);
438
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200439 genpd = dev_to_genpd(dev);
440 if (IS_ERR(genpd))
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200441 return -EINVAL;
442
Rafael J. Wysocki0aa2a222011-08-25 15:37:04 +0200443 might_sleep_if(!genpd->dev_irq_safe);
444
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +0100445 ret = genpd_stop_dev(genpd, dev);
446 if (ret)
447 return ret;
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200448
Rafael J. Wysocki0aa2a222011-08-25 15:37:04 +0200449 /*
450 * If power.irq_safe is set, this routine will be run with interrupts
451 * off, so it can't use mutexes.
452 */
453 if (dev->power.irq_safe)
454 return 0;
455
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200456 mutex_lock(&genpd->lock);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200457 genpd->in_progress++;
458 pm_genpd_poweroff(genpd);
459 genpd->in_progress--;
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200460 mutex_unlock(&genpd->lock);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200461
462 return 0;
463}
464
465/**
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200466 * pm_genpd_runtime_resume - Resume a device belonging to I/O PM domain.
467 * @dev: Device to resume.
468 *
469 * Carry out a runtime resume of a device under the assumption that its
470 * pm_domain field points to the domain member of an object of type
471 * struct generic_pm_domain representing a PM domain consisting of I/O devices.
472 */
473static int pm_genpd_runtime_resume(struct device *dev)
474{
475 struct generic_pm_domain *genpd;
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200476 DEFINE_WAIT(wait);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200477 int ret;
478
479 dev_dbg(dev, "%s()\n", __func__);
480
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200481 genpd = dev_to_genpd(dev);
482 if (IS_ERR(genpd))
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200483 return -EINVAL;
484
Rafael J. Wysocki0aa2a222011-08-25 15:37:04 +0200485 might_sleep_if(!genpd->dev_irq_safe);
486
487 /* If power.irq_safe, the PM domain is never powered off. */
488 if (dev->power.irq_safe)
489 goto out;
490
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200491 mutex_lock(&genpd->lock);
Rafael J. Wysocki3f241772011-08-08 23:43:29 +0200492 ret = __pm_genpd_poweron(genpd);
493 if (ret) {
494 mutex_unlock(&genpd->lock);
495 return ret;
496 }
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200497 genpd->status = GPD_STATE_BUSY;
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200498 genpd->resume_count++;
499 for (;;) {
500 prepare_to_wait(&genpd->status_wait_queue, &wait,
501 TASK_UNINTERRUPTIBLE);
502 /*
503 * If current is the powering off task, we have been called
504 * reentrantly from one of the device callbacks, so we should
505 * not wait.
506 */
507 if (!genpd->poweroff_task || genpd->poweroff_task == current)
508 break;
509 mutex_unlock(&genpd->lock);
510
511 schedule();
512
513 mutex_lock(&genpd->lock);
514 }
515 finish_wait(&genpd->status_wait_queue, &wait);
Rafael J. Wysockicd0ea672011-09-26 20:22:02 +0200516 __pm_genpd_restore_device(dev->power.subsys_data->domain_data, genpd);
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200517 genpd->resume_count--;
518 genpd_set_active(genpd);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200519 wake_up_all(&genpd->status_wait_queue);
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200520 mutex_unlock(&genpd->lock);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200521
Rafael J. Wysocki0aa2a222011-08-25 15:37:04 +0200522 out:
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +0100523 genpd_start_dev(genpd, dev);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200524
525 return 0;
526}
527
Rafael J. Wysocki17f2ae72011-08-14 13:34:31 +0200528/**
529 * pm_genpd_poweroff_unused - Power off all PM domains with no devices in use.
530 */
531void pm_genpd_poweroff_unused(void)
532{
533 struct generic_pm_domain *genpd;
534
535 mutex_lock(&gpd_list_lock);
536
537 list_for_each_entry(genpd, &gpd_list, gpd_list_node)
538 genpd_queue_power_off_work(genpd);
539
540 mutex_unlock(&gpd_list_lock);
541}
542
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200543#else
544
545static inline void genpd_power_off_work_fn(struct work_struct *work) {}
546
547#define pm_genpd_runtime_suspend NULL
548#define pm_genpd_runtime_resume NULL
549
550#endif /* CONFIG_PM_RUNTIME */
551
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200552#ifdef CONFIG_PM_SLEEP
553
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +0100554static bool genpd_dev_active_wakeup(struct generic_pm_domain *genpd,
555 struct device *dev)
556{
557 return GENPD_DEV_CALLBACK(genpd, bool, active_wakeup, dev);
558}
559
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200560/**
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200561 * pm_genpd_sync_poweroff - Synchronously power off a PM domain and its masters.
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200562 * @genpd: PM domain to power off, if possible.
563 *
564 * Check if the given PM domain can be powered off (during system suspend or
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200565 * hibernation) and do that if so. Also, in that case propagate to its masters.
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200566 *
567 * This function is only called in "noirq" stages of system power transitions,
568 * so it need not acquire locks (all of the "noirq" callbacks are executed
569 * sequentially, so it is guaranteed that it will never run twice in parallel).
570 */
571static void pm_genpd_sync_poweroff(struct generic_pm_domain *genpd)
572{
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200573 struct gpd_link *link;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200574
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200575 if (genpd->status == GPD_STATE_POWER_OFF)
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200576 return;
577
Rafael J. Wysockic4bb3162011-08-08 23:43:04 +0200578 if (genpd->suspended_count != genpd->device_count
579 || atomic_read(&genpd->sd_count) > 0)
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200580 return;
581
582 if (genpd->power_off)
583 genpd->power_off(genpd);
584
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200585 genpd->status = GPD_STATE_POWER_OFF;
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +0200586
587 list_for_each_entry(link, &genpd->slave_links, slave_node) {
588 genpd_sd_counter_dec(link->master);
589 pm_genpd_sync_poweroff(link->master);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200590 }
591}
592
593/**
Rafael J. Wysocki4ecd6e62011-07-12 00:39:57 +0200594 * resume_needed - Check whether to resume a device before system suspend.
595 * @dev: Device to check.
596 * @genpd: PM domain the device belongs to.
597 *
598 * There are two cases in which a device that can wake up the system from sleep
599 * states should be resumed by pm_genpd_prepare(): (1) if the device is enabled
600 * to wake up the system and it has to remain active for this purpose while the
601 * system is in the sleep state and (2) if the device is not enabled to wake up
602 * the system from sleep states and it generally doesn't generate wakeup signals
603 * by itself (those signals are generated on its behalf by other parts of the
604 * system). In the latter case it may be necessary to reconfigure the device's
605 * wakeup settings during system suspend, because it may have been set up to
606 * signal remote wakeup from the system's working state as needed by runtime PM.
607 * Return 'true' in either of the above cases.
608 */
609static bool resume_needed(struct device *dev, struct generic_pm_domain *genpd)
610{
611 bool active_wakeup;
612
613 if (!device_can_wakeup(dev))
614 return false;
615
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +0100616 active_wakeup = genpd_dev_active_wakeup(genpd, dev);
Rafael J. Wysocki4ecd6e62011-07-12 00:39:57 +0200617 return device_may_wakeup(dev) ? active_wakeup : !active_wakeup;
618}
619
620/**
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200621 * pm_genpd_prepare - Start power transition of a device in a PM domain.
622 * @dev: Device to start the transition of.
623 *
624 * Start a power transition of a device (during a system-wide power transition)
625 * under the assumption that its pm_domain field points to the domain member of
626 * an object of type struct generic_pm_domain representing a PM domain
627 * consisting of I/O devices.
628 */
629static int pm_genpd_prepare(struct device *dev)
630{
631 struct generic_pm_domain *genpd;
Rafael J. Wysockib6c10c82011-07-12 00:39:21 +0200632 int ret;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200633
634 dev_dbg(dev, "%s()\n", __func__);
635
636 genpd = dev_to_genpd(dev);
637 if (IS_ERR(genpd))
638 return -EINVAL;
639
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200640 /*
641 * If a wakeup request is pending for the device, it should be woken up
642 * at this point and a system wakeup event should be reported if it's
643 * set up to wake up the system from sleep states.
644 */
645 pm_runtime_get_noresume(dev);
646 if (pm_runtime_barrier(dev) && device_may_wakeup(dev))
647 pm_wakeup_event(dev, 0);
648
649 if (pm_wakeup_pending()) {
650 pm_runtime_put_sync(dev);
651 return -EBUSY;
652 }
653
Rafael J. Wysocki4ecd6e62011-07-12 00:39:57 +0200654 if (resume_needed(dev, genpd))
655 pm_runtime_resume(dev);
656
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200657 genpd_acquire_lock(genpd);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200658
659 if (genpd->prepared_count++ == 0)
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200660 genpd->suspend_power_off = genpd->status == GPD_STATE_POWER_OFF;
661
662 genpd_release_lock(genpd);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200663
664 if (genpd->suspend_power_off) {
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200665 pm_runtime_put_noidle(dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200666 return 0;
667 }
668
669 /*
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200670 * The PM domain must be in the GPD_STATE_ACTIVE state at this point,
671 * so pm_genpd_poweron() will return immediately, but if the device
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +0100672 * is suspended (e.g. it's been stopped by genpd_stop_dev()), we need
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200673 * to make it operational.
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200674 */
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200675 pm_runtime_resume(dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200676 __pm_runtime_disable(dev, false);
677
Rafael J. Wysockib6c10c82011-07-12 00:39:21 +0200678 ret = pm_generic_prepare(dev);
679 if (ret) {
680 mutex_lock(&genpd->lock);
681
682 if (--genpd->prepared_count == 0)
683 genpd->suspend_power_off = false;
684
685 mutex_unlock(&genpd->lock);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200686 pm_runtime_enable(dev);
Rafael J. Wysockib6c10c82011-07-12 00:39:21 +0200687 }
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200688
689 pm_runtime_put_sync(dev);
Rafael J. Wysockib6c10c82011-07-12 00:39:21 +0200690 return ret;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200691}
692
693/**
694 * pm_genpd_suspend - Suspend a device belonging to an I/O PM domain.
695 * @dev: Device to suspend.
696 *
697 * Suspend a device under the assumption that its pm_domain field points to the
698 * domain member of an object of type struct generic_pm_domain representing
699 * a PM domain consisting of I/O devices.
700 */
701static int pm_genpd_suspend(struct device *dev)
702{
703 struct generic_pm_domain *genpd;
704
705 dev_dbg(dev, "%s()\n", __func__);
706
707 genpd = dev_to_genpd(dev);
708 if (IS_ERR(genpd))
709 return -EINVAL;
710
711 return genpd->suspend_power_off ? 0 : pm_generic_suspend(dev);
712}
713
714/**
715 * pm_genpd_suspend_noirq - Late suspend of a device from an I/O PM domain.
716 * @dev: Device to suspend.
717 *
718 * Carry out a late suspend of a device under the assumption that its
719 * pm_domain field points to the domain member of an object of type
720 * struct generic_pm_domain representing a PM domain consisting of I/O devices.
721 */
722static int pm_genpd_suspend_noirq(struct device *dev)
723{
724 struct generic_pm_domain *genpd;
725 int ret;
726
727 dev_dbg(dev, "%s()\n", __func__);
728
729 genpd = dev_to_genpd(dev);
730 if (IS_ERR(genpd))
731 return -EINVAL;
732
733 if (genpd->suspend_power_off)
734 return 0;
735
736 ret = pm_generic_suspend_noirq(dev);
737 if (ret)
738 return ret;
739
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +0100740 if (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev))
Rafael J. Wysockid4f2d872011-07-01 22:13:29 +0200741 return 0;
742
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +0100743 genpd_stop_dev(genpd, dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200744
745 /*
746 * Since all of the "noirq" callbacks are executed sequentially, it is
747 * guaranteed that this function will never run twice in parallel for
748 * the same PM domain, so it is not necessary to use locking here.
749 */
750 genpd->suspended_count++;
751 pm_genpd_sync_poweroff(genpd);
752
753 return 0;
754}
755
756/**
757 * pm_genpd_resume_noirq - Early resume of a device from an I/O power domain.
758 * @dev: Device to resume.
759 *
760 * Carry out an early resume of a device under the assumption that its
761 * pm_domain field points to the domain member of an object of type
762 * struct generic_pm_domain representing a power domain consisting of I/O
763 * devices.
764 */
765static int pm_genpd_resume_noirq(struct device *dev)
766{
767 struct generic_pm_domain *genpd;
768
769 dev_dbg(dev, "%s()\n", __func__);
770
771 genpd = dev_to_genpd(dev);
772 if (IS_ERR(genpd))
773 return -EINVAL;
774
775 if (genpd->suspend_power_off)
776 return 0;
777
778 /*
779 * Since all of the "noirq" callbacks are executed sequentially, it is
780 * guaranteed that this function will never run twice in parallel for
781 * the same PM domain, so it is not necessary to use locking here.
782 */
783 pm_genpd_poweron(genpd);
784 genpd->suspended_count--;
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +0100785 genpd_start_dev(genpd, dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200786
787 return pm_generic_resume_noirq(dev);
788}
789
790/**
791 * pm_genpd_resume - Resume a device belonging to an I/O power domain.
792 * @dev: Device to resume.
793 *
794 * Resume a device under the assumption that its pm_domain field points to the
795 * domain member of an object of type struct generic_pm_domain representing
796 * a power domain consisting of I/O devices.
797 */
798static int pm_genpd_resume(struct device *dev)
799{
800 struct generic_pm_domain *genpd;
801
802 dev_dbg(dev, "%s()\n", __func__);
803
804 genpd = dev_to_genpd(dev);
805 if (IS_ERR(genpd))
806 return -EINVAL;
807
808 return genpd->suspend_power_off ? 0 : pm_generic_resume(dev);
809}
810
811/**
812 * pm_genpd_freeze - Freeze a device belonging to an I/O power domain.
813 * @dev: Device to freeze.
814 *
815 * Freeze a device under the assumption that its pm_domain field points to the
816 * domain member of an object of type struct generic_pm_domain representing
817 * a power domain consisting of I/O devices.
818 */
819static int pm_genpd_freeze(struct device *dev)
820{
821 struct generic_pm_domain *genpd;
822
823 dev_dbg(dev, "%s()\n", __func__);
824
825 genpd = dev_to_genpd(dev);
826 if (IS_ERR(genpd))
827 return -EINVAL;
828
829 return genpd->suspend_power_off ? 0 : pm_generic_freeze(dev);
830}
831
832/**
833 * pm_genpd_freeze_noirq - Late freeze of a device from an I/O power domain.
834 * @dev: Device to freeze.
835 *
836 * Carry out a late freeze of a device under the assumption that its
837 * pm_domain field points to the domain member of an object of type
838 * struct generic_pm_domain representing a power domain consisting of I/O
839 * devices.
840 */
841static int pm_genpd_freeze_noirq(struct device *dev)
842{
843 struct generic_pm_domain *genpd;
844 int ret;
845
846 dev_dbg(dev, "%s()\n", __func__);
847
848 genpd = dev_to_genpd(dev);
849 if (IS_ERR(genpd))
850 return -EINVAL;
851
852 if (genpd->suspend_power_off)
853 return 0;
854
855 ret = pm_generic_freeze_noirq(dev);
856 if (ret)
857 return ret;
858
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +0100859 genpd_stop_dev(genpd, dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200860
861 return 0;
862}
863
864/**
865 * pm_genpd_thaw_noirq - Early thaw of a device from an I/O power domain.
866 * @dev: Device to thaw.
867 *
868 * Carry out an early thaw of a device under the assumption that its
869 * pm_domain field points to the domain member of an object of type
870 * struct generic_pm_domain representing a power domain consisting of I/O
871 * devices.
872 */
873static int pm_genpd_thaw_noirq(struct device *dev)
874{
875 struct generic_pm_domain *genpd;
876
877 dev_dbg(dev, "%s()\n", __func__);
878
879 genpd = dev_to_genpd(dev);
880 if (IS_ERR(genpd))
881 return -EINVAL;
882
883 if (genpd->suspend_power_off)
884 return 0;
885
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +0100886 genpd_start_dev(genpd, dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200887
888 return pm_generic_thaw_noirq(dev);
889}
890
891/**
892 * pm_genpd_thaw - Thaw a device belonging to an I/O power domain.
893 * @dev: Device to thaw.
894 *
895 * Thaw a device under the assumption that its pm_domain field points to the
896 * domain member of an object of type struct generic_pm_domain representing
897 * a power domain consisting of I/O devices.
898 */
899static int pm_genpd_thaw(struct device *dev)
900{
901 struct generic_pm_domain *genpd;
902
903 dev_dbg(dev, "%s()\n", __func__);
904
905 genpd = dev_to_genpd(dev);
906 if (IS_ERR(genpd))
907 return -EINVAL;
908
909 return genpd->suspend_power_off ? 0 : pm_generic_thaw(dev);
910}
911
912/**
913 * pm_genpd_dev_poweroff - Power off a device belonging to an I/O PM domain.
914 * @dev: Device to suspend.
915 *
916 * Power off a device under the assumption that its pm_domain field points to
917 * the domain member of an object of type struct generic_pm_domain representing
918 * a PM domain consisting of I/O devices.
919 */
920static int pm_genpd_dev_poweroff(struct device *dev)
921{
922 struct generic_pm_domain *genpd;
923
924 dev_dbg(dev, "%s()\n", __func__);
925
926 genpd = dev_to_genpd(dev);
927 if (IS_ERR(genpd))
928 return -EINVAL;
929
930 return genpd->suspend_power_off ? 0 : pm_generic_poweroff(dev);
931}
932
933/**
934 * pm_genpd_dev_poweroff_noirq - Late power off of a device from a PM domain.
935 * @dev: Device to suspend.
936 *
937 * Carry out a late powering off of a device under the assumption that its
938 * pm_domain field points to the domain member of an object of type
939 * struct generic_pm_domain representing a PM domain consisting of I/O devices.
940 */
941static int pm_genpd_dev_poweroff_noirq(struct device *dev)
942{
943 struct generic_pm_domain *genpd;
944 int ret;
945
946 dev_dbg(dev, "%s()\n", __func__);
947
948 genpd = dev_to_genpd(dev);
949 if (IS_ERR(genpd))
950 return -EINVAL;
951
952 if (genpd->suspend_power_off)
953 return 0;
954
955 ret = pm_generic_poweroff_noirq(dev);
956 if (ret)
957 return ret;
958
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +0100959 if (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev))
Rafael J. Wysockid4f2d872011-07-01 22:13:29 +0200960 return 0;
961
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +0100962 genpd_stop_dev(genpd, dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200963
964 /*
965 * Since all of the "noirq" callbacks are executed sequentially, it is
966 * guaranteed that this function will never run twice in parallel for
967 * the same PM domain, so it is not necessary to use locking here.
968 */
969 genpd->suspended_count++;
970 pm_genpd_sync_poweroff(genpd);
971
972 return 0;
973}
974
975/**
976 * pm_genpd_restore_noirq - Early restore of a device from an I/O power domain.
977 * @dev: Device to resume.
978 *
979 * Carry out an early restore of a device under the assumption that its
980 * pm_domain field points to the domain member of an object of type
981 * struct generic_pm_domain representing a power domain consisting of I/O
982 * devices.
983 */
984static int pm_genpd_restore_noirq(struct device *dev)
985{
986 struct generic_pm_domain *genpd;
987
988 dev_dbg(dev, "%s()\n", __func__);
989
990 genpd = dev_to_genpd(dev);
991 if (IS_ERR(genpd))
992 return -EINVAL;
993
994 /*
995 * Since all of the "noirq" callbacks are executed sequentially, it is
996 * guaranteed that this function will never run twice in parallel for
997 * the same PM domain, so it is not necessary to use locking here.
998 */
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200999 genpd->status = GPD_STATE_POWER_OFF;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001000 if (genpd->suspend_power_off) {
1001 /*
1002 * The boot kernel might put the domain into the power on state,
1003 * so make sure it really is powered off.
1004 */
1005 if (genpd->power_off)
1006 genpd->power_off(genpd);
1007 return 0;
1008 }
1009
1010 pm_genpd_poweron(genpd);
1011 genpd->suspended_count--;
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +01001012 genpd_start_dev(genpd, dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001013
1014 return pm_generic_restore_noirq(dev);
1015}
1016
1017/**
1018 * pm_genpd_restore - Restore a device belonging to an I/O power domain.
1019 * @dev: Device to resume.
1020 *
1021 * Restore a device under the assumption that its pm_domain field points to the
1022 * domain member of an object of type struct generic_pm_domain representing
1023 * a power domain consisting of I/O devices.
1024 */
1025static int pm_genpd_restore(struct device *dev)
1026{
1027 struct generic_pm_domain *genpd;
1028
1029 dev_dbg(dev, "%s()\n", __func__);
1030
1031 genpd = dev_to_genpd(dev);
1032 if (IS_ERR(genpd))
1033 return -EINVAL;
1034
1035 return genpd->suspend_power_off ? 0 : pm_generic_restore(dev);
1036}
1037
1038/**
1039 * pm_genpd_complete - Complete power transition of a device in a power domain.
1040 * @dev: Device to complete the transition of.
1041 *
1042 * Complete a power transition of a device (during a system-wide power
1043 * transition) under the assumption that its pm_domain field points to the
1044 * domain member of an object of type struct generic_pm_domain representing
1045 * a power domain consisting of I/O devices.
1046 */
1047static void pm_genpd_complete(struct device *dev)
1048{
1049 struct generic_pm_domain *genpd;
1050 bool run_complete;
1051
1052 dev_dbg(dev, "%s()\n", __func__);
1053
1054 genpd = dev_to_genpd(dev);
1055 if (IS_ERR(genpd))
1056 return;
1057
1058 mutex_lock(&genpd->lock);
1059
1060 run_complete = !genpd->suspend_power_off;
1061 if (--genpd->prepared_count == 0)
1062 genpd->suspend_power_off = false;
1063
1064 mutex_unlock(&genpd->lock);
1065
1066 if (run_complete) {
1067 pm_generic_complete(dev);
Rafael J. Wysocki6f00ff72011-07-12 00:39:10 +02001068 pm_runtime_set_active(dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001069 pm_runtime_enable(dev);
Rafael J. Wysocki6f00ff72011-07-12 00:39:10 +02001070 pm_runtime_idle(dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001071 }
1072}
1073
1074#else
1075
1076#define pm_genpd_prepare NULL
1077#define pm_genpd_suspend NULL
1078#define pm_genpd_suspend_noirq NULL
1079#define pm_genpd_resume_noirq NULL
1080#define pm_genpd_resume NULL
1081#define pm_genpd_freeze NULL
1082#define pm_genpd_freeze_noirq NULL
1083#define pm_genpd_thaw_noirq NULL
1084#define pm_genpd_thaw NULL
1085#define pm_genpd_dev_poweroff_noirq NULL
1086#define pm_genpd_dev_poweroff NULL
1087#define pm_genpd_restore_noirq NULL
1088#define pm_genpd_restore NULL
1089#define pm_genpd_complete NULL
1090
1091#endif /* CONFIG_PM_SLEEP */
1092
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001093/**
1094 * pm_genpd_add_device - Add a device to an I/O PM domain.
1095 * @genpd: PM domain to add the device to.
1096 * @dev: Device to be added.
1097 */
1098int pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev)
1099{
Rafael J. Wysockicd0ea672011-09-26 20:22:02 +02001100 struct generic_pm_domain_data *gpd_data;
Rafael J. Wysocki4605ab62011-08-25 15:34:12 +02001101 struct pm_domain_data *pdd;
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001102 int ret = 0;
1103
1104 dev_dbg(dev, "%s()\n", __func__);
1105
1106 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev))
1107 return -EINVAL;
1108
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001109 genpd_acquire_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001110
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001111 if (genpd->status == GPD_STATE_POWER_OFF) {
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001112 ret = -EINVAL;
1113 goto out;
1114 }
1115
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001116 if (genpd->prepared_count > 0) {
1117 ret = -EAGAIN;
1118 goto out;
1119 }
1120
Rafael J. Wysocki4605ab62011-08-25 15:34:12 +02001121 list_for_each_entry(pdd, &genpd->dev_list, list_node)
1122 if (pdd->dev == dev) {
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001123 ret = -EINVAL;
1124 goto out;
1125 }
1126
Rafael J. Wysockicd0ea672011-09-26 20:22:02 +02001127 gpd_data = kzalloc(sizeof(*gpd_data), GFP_KERNEL);
1128 if (!gpd_data) {
1129 ret = -ENOMEM;
1130 goto out;
1131 }
1132
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001133 genpd->device_count++;
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001134
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001135 dev->pm_domain = &genpd->domain;
Rafael J. Wysocki4605ab62011-08-25 15:34:12 +02001136 dev_pm_get_subsys_data(dev);
Rafael J. Wysockicd0ea672011-09-26 20:22:02 +02001137 dev->power.subsys_data->domain_data = &gpd_data->base;
1138 gpd_data->base.dev = dev;
1139 gpd_data->need_restore = false;
1140 list_add_tail(&gpd_data->base.list_node, &genpd->dev_list);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001141
1142 out:
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001143 genpd_release_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001144
1145 return ret;
1146}
1147
1148/**
1149 * pm_genpd_remove_device - Remove a device from an I/O PM domain.
1150 * @genpd: PM domain to remove the device from.
1151 * @dev: Device to be removed.
1152 */
1153int pm_genpd_remove_device(struct generic_pm_domain *genpd,
1154 struct device *dev)
1155{
Rafael J. Wysocki4605ab62011-08-25 15:34:12 +02001156 struct pm_domain_data *pdd;
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001157 int ret = -EINVAL;
1158
1159 dev_dbg(dev, "%s()\n", __func__);
1160
1161 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev))
1162 return -EINVAL;
1163
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001164 genpd_acquire_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001165
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001166 if (genpd->prepared_count > 0) {
1167 ret = -EAGAIN;
1168 goto out;
1169 }
1170
Rafael J. Wysocki4605ab62011-08-25 15:34:12 +02001171 list_for_each_entry(pdd, &genpd->dev_list, list_node) {
1172 if (pdd->dev != dev)
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001173 continue;
1174
Rafael J. Wysocki4605ab62011-08-25 15:34:12 +02001175 list_del_init(&pdd->list_node);
1176 pdd->dev = NULL;
1177 dev_pm_put_subsys_data(dev);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001178 dev->pm_domain = NULL;
Rafael J. Wysockicd0ea672011-09-26 20:22:02 +02001179 kfree(to_gpd_data(pdd));
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001180
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001181 genpd->device_count--;
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001182
1183 ret = 0;
1184 break;
1185 }
1186
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001187 out:
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001188 genpd_release_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001189
1190 return ret;
1191}
1192
1193/**
1194 * pm_genpd_add_subdomain - Add a subdomain to an I/O PM domain.
1195 * @genpd: Master PM domain to add the subdomain to.
Rafael J. Wysockibc0403f2011-08-08 23:43:59 +02001196 * @subdomain: Subdomain to be added.
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001197 */
1198int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
Rafael J. Wysockibc0403f2011-08-08 23:43:59 +02001199 struct generic_pm_domain *subdomain)
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001200{
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +02001201 struct gpd_link *link;
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001202 int ret = 0;
1203
Rafael J. Wysockibc0403f2011-08-08 23:43:59 +02001204 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain))
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001205 return -EINVAL;
1206
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001207 start:
1208 genpd_acquire_lock(genpd);
Rafael J. Wysockibc0403f2011-08-08 23:43:59 +02001209 mutex_lock_nested(&subdomain->lock, SINGLE_DEPTH_NESTING);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001210
Rafael J. Wysockibc0403f2011-08-08 23:43:59 +02001211 if (subdomain->status != GPD_STATE_POWER_OFF
1212 && subdomain->status != GPD_STATE_ACTIVE) {
1213 mutex_unlock(&subdomain->lock);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001214 genpd_release_lock(genpd);
1215 goto start;
1216 }
1217
1218 if (genpd->status == GPD_STATE_POWER_OFF
Rafael J. Wysockibc0403f2011-08-08 23:43:59 +02001219 && subdomain->status != GPD_STATE_POWER_OFF) {
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001220 ret = -EINVAL;
1221 goto out;
1222 }
1223
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +02001224 list_for_each_entry(link, &genpd->slave_links, slave_node) {
Rafael J. Wysockibc0403f2011-08-08 23:43:59 +02001225 if (link->slave == subdomain && link->master == genpd) {
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001226 ret = -EINVAL;
1227 goto out;
1228 }
1229 }
1230
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +02001231 link = kzalloc(sizeof(*link), GFP_KERNEL);
1232 if (!link) {
1233 ret = -ENOMEM;
1234 goto out;
1235 }
1236 link->master = genpd;
1237 list_add_tail(&link->master_node, &genpd->master_links);
Rafael J. Wysockibc0403f2011-08-08 23:43:59 +02001238 link->slave = subdomain;
1239 list_add_tail(&link->slave_node, &subdomain->slave_links);
1240 if (subdomain->status != GPD_STATE_POWER_OFF)
Rafael J. Wysockic4bb3162011-08-08 23:43:04 +02001241 genpd_sd_counter_inc(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001242
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001243 out:
Rafael J. Wysockibc0403f2011-08-08 23:43:59 +02001244 mutex_unlock(&subdomain->lock);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001245 genpd_release_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001246
1247 return ret;
1248}
1249
1250/**
1251 * pm_genpd_remove_subdomain - Remove a subdomain from an I/O PM domain.
1252 * @genpd: Master PM domain to remove the subdomain from.
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +02001253 * @subdomain: Subdomain to be removed.
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001254 */
1255int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +02001256 struct generic_pm_domain *subdomain)
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001257{
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +02001258 struct gpd_link *link;
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001259 int ret = -EINVAL;
1260
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +02001261 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain))
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001262 return -EINVAL;
1263
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001264 start:
1265 genpd_acquire_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001266
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +02001267 list_for_each_entry(link, &genpd->master_links, master_node) {
1268 if (link->slave != subdomain)
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001269 continue;
1270
1271 mutex_lock_nested(&subdomain->lock, SINGLE_DEPTH_NESTING);
1272
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001273 if (subdomain->status != GPD_STATE_POWER_OFF
1274 && subdomain->status != GPD_STATE_ACTIVE) {
1275 mutex_unlock(&subdomain->lock);
1276 genpd_release_lock(genpd);
1277 goto start;
1278 }
1279
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +02001280 list_del(&link->master_node);
1281 list_del(&link->slave_node);
1282 kfree(link);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001283 if (subdomain->status != GPD_STATE_POWER_OFF)
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001284 genpd_sd_counter_dec(genpd);
1285
1286 mutex_unlock(&subdomain->lock);
1287
1288 ret = 0;
1289 break;
1290 }
1291
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001292 genpd_release_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001293
1294 return ret;
1295}
1296
1297/**
Rafael J. Wysockid5e4cbf2011-11-27 13:11:36 +01001298 * pm_genpd_add_callbacks - Add PM domain callbacks to a given device.
1299 * @dev: Device to add the callbacks to.
1300 * @ops: Set of callbacks to add.
1301 */
1302int pm_genpd_add_callbacks(struct device *dev, struct gpd_dev_ops *ops)
1303{
1304 struct pm_domain_data *pdd;
1305 int ret = 0;
1306
1307 if (!(dev && dev->power.subsys_data && ops))
1308 return -EINVAL;
1309
1310 pm_runtime_disable(dev);
1311 device_pm_lock();
1312
1313 pdd = dev->power.subsys_data->domain_data;
1314 if (pdd) {
1315 struct generic_pm_domain_data *gpd_data = to_gpd_data(pdd);
1316
1317 gpd_data->ops = *ops;
1318 } else {
1319 ret = -EINVAL;
1320 }
1321
1322 device_pm_unlock();
1323 pm_runtime_enable(dev);
1324
1325 return ret;
1326}
1327EXPORT_SYMBOL_GPL(pm_genpd_add_callbacks);
1328
1329/**
1330 * pm_genpd_remove_callbacks - Remove PM domain callbacks from a given device.
1331 * @dev: Device to remove the callbacks from.
1332 */
1333int pm_genpd_remove_callbacks(struct device *dev)
1334{
1335 struct pm_domain_data *pdd;
1336 int ret = 0;
1337
1338 if (!(dev && dev->power.subsys_data))
1339 return -EINVAL;
1340
1341 pm_runtime_disable(dev);
1342 device_pm_lock();
1343
1344 pdd = dev->power.subsys_data->domain_data;
1345 if (pdd) {
1346 struct generic_pm_domain_data *gpd_data = to_gpd_data(pdd);
1347
1348 gpd_data->ops = (struct gpd_dev_ops){ 0 };
1349 } else {
1350 ret = -EINVAL;
1351 }
1352
1353 device_pm_unlock();
1354 pm_runtime_enable(dev);
1355
1356 return ret;
1357}
1358EXPORT_SYMBOL_GPL(pm_genpd_remove_callbacks);
1359
1360/**
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001361 * pm_genpd_init - Initialize a generic I/O PM domain object.
1362 * @genpd: PM domain object to initialize.
1363 * @gov: PM domain governor to associate with the domain (may be NULL).
1364 * @is_off: Initial value of the domain's power_is_off field.
1365 */
1366void pm_genpd_init(struct generic_pm_domain *genpd,
1367 struct dev_power_governor *gov, bool is_off)
1368{
1369 if (IS_ERR_OR_NULL(genpd))
1370 return;
1371
Rafael J. Wysocki5063ce12011-08-08 23:43:40 +02001372 INIT_LIST_HEAD(&genpd->master_links);
1373 INIT_LIST_HEAD(&genpd->slave_links);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001374 INIT_LIST_HEAD(&genpd->dev_list);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001375 mutex_init(&genpd->lock);
1376 genpd->gov = gov;
1377 INIT_WORK(&genpd->power_off_work, genpd_power_off_work_fn);
1378 genpd->in_progress = 0;
Rafael J. Wysockic4bb3162011-08-08 23:43:04 +02001379 atomic_set(&genpd->sd_count, 0);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001380 genpd->status = is_off ? GPD_STATE_POWER_OFF : GPD_STATE_ACTIVE;
1381 init_waitqueue_head(&genpd->status_wait_queue);
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +02001382 genpd->poweroff_task = NULL;
1383 genpd->resume_count = 0;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001384 genpd->device_count = 0;
1385 genpd->suspended_count = 0;
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001386 genpd->domain.ops.runtime_suspend = pm_genpd_runtime_suspend;
1387 genpd->domain.ops.runtime_resume = pm_genpd_runtime_resume;
1388 genpd->domain.ops.runtime_idle = pm_generic_runtime_idle;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001389 genpd->domain.ops.prepare = pm_genpd_prepare;
1390 genpd->domain.ops.suspend = pm_genpd_suspend;
1391 genpd->domain.ops.suspend_noirq = pm_genpd_suspend_noirq;
1392 genpd->domain.ops.resume_noirq = pm_genpd_resume_noirq;
1393 genpd->domain.ops.resume = pm_genpd_resume;
1394 genpd->domain.ops.freeze = pm_genpd_freeze;
1395 genpd->domain.ops.freeze_noirq = pm_genpd_freeze_noirq;
1396 genpd->domain.ops.thaw_noirq = pm_genpd_thaw_noirq;
1397 genpd->domain.ops.thaw = pm_genpd_thaw;
1398 genpd->domain.ops.poweroff = pm_genpd_dev_poweroff;
1399 genpd->domain.ops.poweroff_noirq = pm_genpd_dev_poweroff_noirq;
1400 genpd->domain.ops.restore_noirq = pm_genpd_restore_noirq;
1401 genpd->domain.ops.restore = pm_genpd_restore;
1402 genpd->domain.ops.complete = pm_genpd_complete;
Rafael J. Wysocki5125bbf382011-07-13 12:31:52 +02001403 mutex_lock(&gpd_list_lock);
1404 list_add(&genpd->gpd_list_node, &gpd_list);
1405 mutex_unlock(&gpd_list_lock);
1406}