blob: 7e6cc8a5ce5b5d3ac4807a377ce429c3715a4f82 [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. Wysockif7218892011-07-01 22:12:45 +0200216 * pm_genpd_poweroff - Remove power from a given PM domain.
217 * @genpd: PM domain to power down.
218 *
219 * If all of the @genpd's devices have been suspended and all of its subdomains
220 * have been powered down, run the runtime suspend callbacks provided by all of
221 * the @genpd's devices' drivers and remove power from @genpd.
222 */
223static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200224 __releases(&genpd->lock) __acquires(&genpd->lock)
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200225{
226 struct generic_pm_domain *parent;
227 struct dev_list_entry *dle;
228 unsigned int not_suspended;
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200229 int ret = 0;
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200230
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200231 start:
232 /*
233 * Do not try to power off the domain in the following situations:
234 * (1) The domain is already in the "power off" state.
235 * (2) System suspend is in progress.
236 * (3) One of the domain's devices is being resumed right now.
237 */
238 if (genpd->status == GPD_STATE_POWER_OFF || genpd->prepared_count > 0
239 || genpd->resume_count > 0)
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200240 return 0;
241
242 if (genpd->sd_count > 0)
243 return -EBUSY;
244
245 not_suspended = 0;
246 list_for_each_entry(dle, &genpd->dev_list, node)
247 if (dle->dev->driver && !pm_runtime_suspended(dle->dev))
248 not_suspended++;
249
250 if (not_suspended > genpd->in_progress)
251 return -EBUSY;
252
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200253 if (genpd->poweroff_task) {
254 /*
255 * Another instance of pm_genpd_poweroff() is executing
256 * callbacks, so tell it to start over and return.
257 */
258 genpd->status = GPD_STATE_REPEAT;
259 return 0;
260 }
261
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200262 if (genpd->gov && genpd->gov->power_down_ok) {
263 if (!genpd->gov->power_down_ok(&genpd->domain))
264 return -EAGAIN;
265 }
266
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200267 genpd->status = GPD_STATE_BUSY;
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200268 genpd->poweroff_task = current;
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200269
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200270 list_for_each_entry_reverse(dle, &genpd->dev_list, node) {
271 ret = __pm_genpd_save_device(dle, genpd);
272 if (ret)
273 goto err_dev;
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200274
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200275 if (genpd_abort_poweroff(genpd))
276 goto out;
277
278 if (genpd->status == GPD_STATE_REPEAT) {
279 genpd->poweroff_task = NULL;
280 goto start;
281 }
282 }
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200283
284 parent = genpd->parent;
285 if (parent) {
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200286 mutex_unlock(&genpd->lock);
287
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200288 genpd_acquire_lock(parent);
289 mutex_lock_nested(&genpd->lock, SINGLE_DEPTH_NESTING);
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200290
291 if (genpd_abort_poweroff(genpd)) {
292 genpd_release_lock(parent);
293 goto out;
294 }
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200295 }
296
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200297 if (genpd->power_off)
298 genpd->power_off(genpd);
299
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200300 genpd->status = GPD_STATE_POWER_OFF;
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200301
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200302 if (parent) {
303 genpd_sd_counter_dec(parent);
304 if (parent->sd_count == 0)
305 queue_work(pm_wq, &parent->power_off_work);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200306
307 genpd_release_lock(parent);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200308 }
309
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200310 out:
311 genpd->poweroff_task = NULL;
312 wake_up_all(&genpd->status_wait_queue);
313 return ret;
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200314
315 err_dev:
316 list_for_each_entry_continue(dle, &genpd->dev_list, node)
317 __pm_genpd_restore_device(dle, genpd);
318
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200319 genpd_set_active(genpd);
320 goto out;
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200321}
322
323/**
324 * genpd_power_off_work_fn - Power off PM domain whose subdomain count is 0.
325 * @work: Work structure used for scheduling the execution of this function.
326 */
327static void genpd_power_off_work_fn(struct work_struct *work)
328{
329 struct generic_pm_domain *genpd;
330
331 genpd = container_of(work, struct generic_pm_domain, power_off_work);
332
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200333 genpd_acquire_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200334 pm_genpd_poweroff(genpd);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200335 genpd_release_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200336}
337
338/**
339 * pm_genpd_runtime_suspend - Suspend a device belonging to I/O PM domain.
340 * @dev: Device to suspend.
341 *
342 * Carry out a runtime suspend of a device under the assumption that its
343 * pm_domain field points to the domain member of an object of type
344 * struct generic_pm_domain representing a PM domain consisting of I/O devices.
345 */
346static int pm_genpd_runtime_suspend(struct device *dev)
347{
348 struct generic_pm_domain *genpd;
349
350 dev_dbg(dev, "%s()\n", __func__);
351
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200352 genpd = dev_to_genpd(dev);
353 if (IS_ERR(genpd))
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200354 return -EINVAL;
355
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200356 if (genpd->stop_device) {
357 int ret = genpd->stop_device(dev);
358 if (ret)
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200359 return ret;
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200360 }
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200361
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200362 mutex_lock(&genpd->lock);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200363 genpd->in_progress++;
364 pm_genpd_poweroff(genpd);
365 genpd->in_progress--;
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200366 mutex_unlock(&genpd->lock);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200367
368 return 0;
369}
370
371/**
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200372 * __pm_genpd_runtime_resume - Resume a device belonging to I/O PM domain.
373 * @dev: Device to resume.
374 * @genpd: PM domain the device belongs to.
375 */
376static void __pm_genpd_runtime_resume(struct device *dev,
377 struct generic_pm_domain *genpd)
378{
379 struct dev_list_entry *dle;
380
381 list_for_each_entry(dle, &genpd->dev_list, node) {
382 if (dle->dev == dev) {
383 __pm_genpd_restore_device(dle, genpd);
384 break;
385 }
386 }
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200387}
388
389/**
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200390 * pm_genpd_runtime_resume - Resume a device belonging to I/O PM domain.
391 * @dev: Device to resume.
392 *
393 * Carry out a runtime resume of a device under the assumption that its
394 * pm_domain field points to the domain member of an object of type
395 * struct generic_pm_domain representing a PM domain consisting of I/O devices.
396 */
397static int pm_genpd_runtime_resume(struct device *dev)
398{
399 struct generic_pm_domain *genpd;
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200400 DEFINE_WAIT(wait);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200401 int ret;
402
403 dev_dbg(dev, "%s()\n", __func__);
404
Rafael J. Wysocki52480512011-07-01 22:13:10 +0200405 genpd = dev_to_genpd(dev);
406 if (IS_ERR(genpd))
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200407 return -EINVAL;
408
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200409 ret = pm_genpd_poweron(genpd);
410 if (ret)
411 return ret;
412
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200413 mutex_lock(&genpd->lock);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200414 genpd->status = GPD_STATE_BUSY;
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200415 genpd->resume_count++;
416 for (;;) {
417 prepare_to_wait(&genpd->status_wait_queue, &wait,
418 TASK_UNINTERRUPTIBLE);
419 /*
420 * If current is the powering off task, we have been called
421 * reentrantly from one of the device callbacks, so we should
422 * not wait.
423 */
424 if (!genpd->poweroff_task || genpd->poweroff_task == current)
425 break;
426 mutex_unlock(&genpd->lock);
427
428 schedule();
429
430 mutex_lock(&genpd->lock);
431 }
432 finish_wait(&genpd->status_wait_queue, &wait);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200433 __pm_genpd_runtime_resume(dev, genpd);
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200434 genpd->resume_count--;
435 genpd_set_active(genpd);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200436 wake_up_all(&genpd->status_wait_queue);
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +0200437 mutex_unlock(&genpd->lock);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200438
439 if (genpd->start_device)
440 genpd->start_device(dev);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200441
442 return 0;
443}
444
445#else
446
447static inline void genpd_power_off_work_fn(struct work_struct *work) {}
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200448static inline void __pm_genpd_runtime_resume(struct device *dev,
449 struct generic_pm_domain *genpd) {}
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200450
451#define pm_genpd_runtime_suspend NULL
452#define pm_genpd_runtime_resume NULL
453
454#endif /* CONFIG_PM_RUNTIME */
455
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200456#ifdef CONFIG_PM_SLEEP
457
458/**
459 * pm_genpd_sync_poweroff - Synchronously power off a PM domain and its parents.
460 * @genpd: PM domain to power off, if possible.
461 *
462 * Check if the given PM domain can be powered off (during system suspend or
463 * hibernation) and do that if so. Also, in that case propagate to its parent.
464 *
465 * This function is only called in "noirq" stages of system power transitions,
466 * so it need not acquire locks (all of the "noirq" callbacks are executed
467 * sequentially, so it is guaranteed that it will never run twice in parallel).
468 */
469static void pm_genpd_sync_poweroff(struct generic_pm_domain *genpd)
470{
471 struct generic_pm_domain *parent = genpd->parent;
472
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200473 if (genpd->status == GPD_STATE_POWER_OFF)
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200474 return;
475
476 if (genpd->suspended_count != genpd->device_count || genpd->sd_count > 0)
477 return;
478
479 if (genpd->power_off)
480 genpd->power_off(genpd);
481
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200482 genpd->status = GPD_STATE_POWER_OFF;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200483 if (parent) {
484 genpd_sd_counter_dec(parent);
485 pm_genpd_sync_poweroff(parent);
486 }
487}
488
489/**
490 * pm_genpd_prepare - Start power transition of a device in a PM domain.
491 * @dev: Device to start the transition of.
492 *
493 * Start a power transition of a device (during a system-wide power transition)
494 * under the assumption that its pm_domain field points to the domain member of
495 * an object of type struct generic_pm_domain representing a PM domain
496 * consisting of I/O devices.
497 */
498static int pm_genpd_prepare(struct device *dev)
499{
500 struct generic_pm_domain *genpd;
Rafael J. Wysockib6c10c82011-07-12 00:39:21 +0200501 int ret;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200502
503 dev_dbg(dev, "%s()\n", __func__);
504
505 genpd = dev_to_genpd(dev);
506 if (IS_ERR(genpd))
507 return -EINVAL;
508
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200509 /*
510 * If a wakeup request is pending for the device, it should be woken up
511 * at this point and a system wakeup event should be reported if it's
512 * set up to wake up the system from sleep states.
513 */
514 pm_runtime_get_noresume(dev);
515 if (pm_runtime_barrier(dev) && device_may_wakeup(dev))
516 pm_wakeup_event(dev, 0);
517
518 if (pm_wakeup_pending()) {
519 pm_runtime_put_sync(dev);
520 return -EBUSY;
521 }
522
523 genpd_acquire_lock(genpd);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200524
525 if (genpd->prepared_count++ == 0)
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200526 genpd->suspend_power_off = genpd->status == GPD_STATE_POWER_OFF;
527
528 genpd_release_lock(genpd);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200529
530 if (genpd->suspend_power_off) {
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200531 pm_runtime_put_noidle(dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200532 return 0;
533 }
534
535 /*
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200536 * The PM domain must be in the GPD_STATE_ACTIVE state at this point,
537 * so pm_genpd_poweron() will return immediately, but if the device
538 * is suspended (e.g. it's been stopped by .stop_device()), we need
539 * to make it operational.
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200540 */
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200541 pm_runtime_resume(dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200542 __pm_runtime_disable(dev, false);
543
Rafael J. Wysockib6c10c82011-07-12 00:39:21 +0200544 ret = pm_generic_prepare(dev);
545 if (ret) {
546 mutex_lock(&genpd->lock);
547
548 if (--genpd->prepared_count == 0)
549 genpd->suspend_power_off = false;
550
551 mutex_unlock(&genpd->lock);
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200552 pm_runtime_enable(dev);
Rafael J. Wysockib6c10c82011-07-12 00:39:21 +0200553 }
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200554
555 pm_runtime_put_sync(dev);
Rafael J. Wysockib6c10c82011-07-12 00:39:21 +0200556 return ret;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200557}
558
559/**
560 * pm_genpd_suspend - Suspend a device belonging to an I/O PM domain.
561 * @dev: Device to suspend.
562 *
563 * Suspend a device under the assumption that its pm_domain field points to the
564 * domain member of an object of type struct generic_pm_domain representing
565 * a PM domain consisting of I/O devices.
566 */
567static int pm_genpd_suspend(struct device *dev)
568{
569 struct generic_pm_domain *genpd;
570
571 dev_dbg(dev, "%s()\n", __func__);
572
573 genpd = dev_to_genpd(dev);
574 if (IS_ERR(genpd))
575 return -EINVAL;
576
577 return genpd->suspend_power_off ? 0 : pm_generic_suspend(dev);
578}
579
580/**
581 * pm_genpd_suspend_noirq - Late suspend of a device from an I/O PM domain.
582 * @dev: Device to suspend.
583 *
584 * Carry out a late suspend of a device under the assumption that its
585 * pm_domain field points to the domain member of an object of type
586 * struct generic_pm_domain representing a PM domain consisting of I/O devices.
587 */
588static int pm_genpd_suspend_noirq(struct device *dev)
589{
590 struct generic_pm_domain *genpd;
591 int ret;
592
593 dev_dbg(dev, "%s()\n", __func__);
594
595 genpd = dev_to_genpd(dev);
596 if (IS_ERR(genpd))
597 return -EINVAL;
598
599 if (genpd->suspend_power_off)
600 return 0;
601
602 ret = pm_generic_suspend_noirq(dev);
603 if (ret)
604 return ret;
605
Rafael J. Wysockid4f2d872011-07-01 22:13:29 +0200606 if (device_may_wakeup(dev)
607 && genpd->active_wakeup && genpd->active_wakeup(dev))
608 return 0;
609
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200610 if (genpd->stop_device)
611 genpd->stop_device(dev);
612
613 /*
614 * Since all of the "noirq" callbacks are executed sequentially, it is
615 * guaranteed that this function will never run twice in parallel for
616 * the same PM domain, so it is not necessary to use locking here.
617 */
618 genpd->suspended_count++;
619 pm_genpd_sync_poweroff(genpd);
620
621 return 0;
622}
623
624/**
625 * pm_genpd_resume_noirq - Early resume of a device from an I/O power domain.
626 * @dev: Device to resume.
627 *
628 * Carry out an early resume of a device under the assumption that its
629 * pm_domain field points to the domain member of an object of type
630 * struct generic_pm_domain representing a power domain consisting of I/O
631 * devices.
632 */
633static int pm_genpd_resume_noirq(struct device *dev)
634{
635 struct generic_pm_domain *genpd;
636
637 dev_dbg(dev, "%s()\n", __func__);
638
639 genpd = dev_to_genpd(dev);
640 if (IS_ERR(genpd))
641 return -EINVAL;
642
643 if (genpd->suspend_power_off)
644 return 0;
645
646 /*
647 * Since all of the "noirq" callbacks are executed sequentially, it is
648 * guaranteed that this function will never run twice in parallel for
649 * the same PM domain, so it is not necessary to use locking here.
650 */
651 pm_genpd_poweron(genpd);
652 genpd->suspended_count--;
653 if (genpd->start_device)
654 genpd->start_device(dev);
655
656 return pm_generic_resume_noirq(dev);
657}
658
659/**
660 * pm_genpd_resume - Resume a device belonging to an I/O power domain.
661 * @dev: Device to resume.
662 *
663 * Resume a device under the assumption that its pm_domain field points to the
664 * domain member of an object of type struct generic_pm_domain representing
665 * a power domain consisting of I/O devices.
666 */
667static int pm_genpd_resume(struct device *dev)
668{
669 struct generic_pm_domain *genpd;
670
671 dev_dbg(dev, "%s()\n", __func__);
672
673 genpd = dev_to_genpd(dev);
674 if (IS_ERR(genpd))
675 return -EINVAL;
676
677 return genpd->suspend_power_off ? 0 : pm_generic_resume(dev);
678}
679
680/**
681 * pm_genpd_freeze - Freeze a device belonging to an I/O power domain.
682 * @dev: Device to freeze.
683 *
684 * Freeze a device under the assumption that its pm_domain field points to the
685 * domain member of an object of type struct generic_pm_domain representing
686 * a power domain consisting of I/O devices.
687 */
688static int pm_genpd_freeze(struct device *dev)
689{
690 struct generic_pm_domain *genpd;
691
692 dev_dbg(dev, "%s()\n", __func__);
693
694 genpd = dev_to_genpd(dev);
695 if (IS_ERR(genpd))
696 return -EINVAL;
697
698 return genpd->suspend_power_off ? 0 : pm_generic_freeze(dev);
699}
700
701/**
702 * pm_genpd_freeze_noirq - Late freeze of a device from an I/O power domain.
703 * @dev: Device to freeze.
704 *
705 * Carry out a late freeze of a device under the assumption that its
706 * pm_domain field points to the domain member of an object of type
707 * struct generic_pm_domain representing a power domain consisting of I/O
708 * devices.
709 */
710static int pm_genpd_freeze_noirq(struct device *dev)
711{
712 struct generic_pm_domain *genpd;
713 int ret;
714
715 dev_dbg(dev, "%s()\n", __func__);
716
717 genpd = dev_to_genpd(dev);
718 if (IS_ERR(genpd))
719 return -EINVAL;
720
721 if (genpd->suspend_power_off)
722 return 0;
723
724 ret = pm_generic_freeze_noirq(dev);
725 if (ret)
726 return ret;
727
728 if (genpd->stop_device)
729 genpd->stop_device(dev);
730
731 return 0;
732}
733
734/**
735 * pm_genpd_thaw_noirq - Early thaw of a device from an I/O power domain.
736 * @dev: Device to thaw.
737 *
738 * Carry out an early thaw of a device under the assumption that its
739 * pm_domain field points to the domain member of an object of type
740 * struct generic_pm_domain representing a power domain consisting of I/O
741 * devices.
742 */
743static int pm_genpd_thaw_noirq(struct device *dev)
744{
745 struct generic_pm_domain *genpd;
746
747 dev_dbg(dev, "%s()\n", __func__);
748
749 genpd = dev_to_genpd(dev);
750 if (IS_ERR(genpd))
751 return -EINVAL;
752
753 if (genpd->suspend_power_off)
754 return 0;
755
756 if (genpd->start_device)
757 genpd->start_device(dev);
758
759 return pm_generic_thaw_noirq(dev);
760}
761
762/**
763 * pm_genpd_thaw - Thaw a device belonging to an I/O power domain.
764 * @dev: Device to thaw.
765 *
766 * Thaw a device under the assumption that its pm_domain field points to the
767 * domain member of an object of type struct generic_pm_domain representing
768 * a power domain consisting of I/O devices.
769 */
770static int pm_genpd_thaw(struct device *dev)
771{
772 struct generic_pm_domain *genpd;
773
774 dev_dbg(dev, "%s()\n", __func__);
775
776 genpd = dev_to_genpd(dev);
777 if (IS_ERR(genpd))
778 return -EINVAL;
779
780 return genpd->suspend_power_off ? 0 : pm_generic_thaw(dev);
781}
782
783/**
784 * pm_genpd_dev_poweroff - Power off a device belonging to an I/O PM domain.
785 * @dev: Device to suspend.
786 *
787 * Power off a device under the assumption that its pm_domain field points to
788 * the domain member of an object of type struct generic_pm_domain representing
789 * a PM domain consisting of I/O devices.
790 */
791static int pm_genpd_dev_poweroff(struct device *dev)
792{
793 struct generic_pm_domain *genpd;
794
795 dev_dbg(dev, "%s()\n", __func__);
796
797 genpd = dev_to_genpd(dev);
798 if (IS_ERR(genpd))
799 return -EINVAL;
800
801 return genpd->suspend_power_off ? 0 : pm_generic_poweroff(dev);
802}
803
804/**
805 * pm_genpd_dev_poweroff_noirq - Late power off of a device from a PM domain.
806 * @dev: Device to suspend.
807 *
808 * Carry out a late powering off of a device under the assumption that its
809 * pm_domain field points to the domain member of an object of type
810 * struct generic_pm_domain representing a PM domain consisting of I/O devices.
811 */
812static int pm_genpd_dev_poweroff_noirq(struct device *dev)
813{
814 struct generic_pm_domain *genpd;
815 int ret;
816
817 dev_dbg(dev, "%s()\n", __func__);
818
819 genpd = dev_to_genpd(dev);
820 if (IS_ERR(genpd))
821 return -EINVAL;
822
823 if (genpd->suspend_power_off)
824 return 0;
825
826 ret = pm_generic_poweroff_noirq(dev);
827 if (ret)
828 return ret;
829
Rafael J. Wysockid4f2d872011-07-01 22:13:29 +0200830 if (device_may_wakeup(dev)
831 && genpd->active_wakeup && genpd->active_wakeup(dev))
832 return 0;
833
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200834 if (genpd->stop_device)
835 genpd->stop_device(dev);
836
837 /*
838 * Since all of the "noirq" callbacks are executed sequentially, it is
839 * guaranteed that this function will never run twice in parallel for
840 * the same PM domain, so it is not necessary to use locking here.
841 */
842 genpd->suspended_count++;
843 pm_genpd_sync_poweroff(genpd);
844
845 return 0;
846}
847
848/**
849 * pm_genpd_restore_noirq - Early restore of a device from an I/O power domain.
850 * @dev: Device to resume.
851 *
852 * Carry out an early restore of a device under the assumption that its
853 * pm_domain field points to the domain member of an object of type
854 * struct generic_pm_domain representing a power domain consisting of I/O
855 * devices.
856 */
857static int pm_genpd_restore_noirq(struct device *dev)
858{
859 struct generic_pm_domain *genpd;
860
861 dev_dbg(dev, "%s()\n", __func__);
862
863 genpd = dev_to_genpd(dev);
864 if (IS_ERR(genpd))
865 return -EINVAL;
866
867 /*
868 * Since all of the "noirq" callbacks are executed sequentially, it is
869 * guaranteed that this function will never run twice in parallel for
870 * the same PM domain, so it is not necessary to use locking here.
871 */
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200872 genpd->status = GPD_STATE_POWER_OFF;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200873 if (genpd->suspend_power_off) {
874 /*
875 * The boot kernel might put the domain into the power on state,
876 * so make sure it really is powered off.
877 */
878 if (genpd->power_off)
879 genpd->power_off(genpd);
880 return 0;
881 }
882
883 pm_genpd_poweron(genpd);
884 genpd->suspended_count--;
885 if (genpd->start_device)
886 genpd->start_device(dev);
887
888 return pm_generic_restore_noirq(dev);
889}
890
891/**
892 * pm_genpd_restore - Restore a device belonging to an I/O power domain.
893 * @dev: Device to resume.
894 *
895 * Restore 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_restore(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_restore(dev);
910}
911
912/**
913 * pm_genpd_complete - Complete power transition of a device in a power domain.
914 * @dev: Device to complete the transition of.
915 *
916 * Complete a power transition of a device (during a system-wide power
917 * transition) under the assumption that its pm_domain field points to the
918 * domain member of an object of type struct generic_pm_domain representing
919 * a power domain consisting of I/O devices.
920 */
921static void pm_genpd_complete(struct device *dev)
922{
923 struct generic_pm_domain *genpd;
924 bool run_complete;
925
926 dev_dbg(dev, "%s()\n", __func__);
927
928 genpd = dev_to_genpd(dev);
929 if (IS_ERR(genpd))
930 return;
931
932 mutex_lock(&genpd->lock);
933
934 run_complete = !genpd->suspend_power_off;
935 if (--genpd->prepared_count == 0)
936 genpd->suspend_power_off = false;
937
938 mutex_unlock(&genpd->lock);
939
940 if (run_complete) {
941 pm_generic_complete(dev);
Rafael J. Wysocki6f00ff72011-07-12 00:39:10 +0200942 pm_runtime_set_active(dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200943 pm_runtime_enable(dev);
Rafael J. Wysocki6f00ff72011-07-12 00:39:10 +0200944 pm_runtime_idle(dev);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200945 }
946}
947
948#else
949
950#define pm_genpd_prepare NULL
951#define pm_genpd_suspend NULL
952#define pm_genpd_suspend_noirq NULL
953#define pm_genpd_resume_noirq NULL
954#define pm_genpd_resume NULL
955#define pm_genpd_freeze NULL
956#define pm_genpd_freeze_noirq NULL
957#define pm_genpd_thaw_noirq NULL
958#define pm_genpd_thaw NULL
959#define pm_genpd_dev_poweroff_noirq NULL
960#define pm_genpd_dev_poweroff NULL
961#define pm_genpd_restore_noirq NULL
962#define pm_genpd_restore NULL
963#define pm_genpd_complete NULL
964
965#endif /* CONFIG_PM_SLEEP */
966
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200967/**
968 * pm_genpd_add_device - Add a device to an I/O PM domain.
969 * @genpd: PM domain to add the device to.
970 * @dev: Device to be added.
971 */
972int pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev)
973{
974 struct dev_list_entry *dle;
975 int ret = 0;
976
977 dev_dbg(dev, "%s()\n", __func__);
978
979 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev))
980 return -EINVAL;
981
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200982 genpd_acquire_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200983
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +0200984 if (genpd->status == GPD_STATE_POWER_OFF) {
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200985 ret = -EINVAL;
986 goto out;
987 }
988
Rafael J. Wysocki596ba342011-07-01 22:13:19 +0200989 if (genpd->prepared_count > 0) {
990 ret = -EAGAIN;
991 goto out;
992 }
993
Rafael J. Wysockif7218892011-07-01 22:12:45 +0200994 list_for_each_entry(dle, &genpd->dev_list, node)
995 if (dle->dev == dev) {
996 ret = -EINVAL;
997 goto out;
998 }
999
1000 dle = kzalloc(sizeof(*dle), GFP_KERNEL);
1001 if (!dle) {
1002 ret = -ENOMEM;
1003 goto out;
1004 }
1005
1006 dle->dev = dev;
1007 dle->need_restore = false;
1008 list_add_tail(&dle->node, &genpd->dev_list);
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001009 genpd->device_count++;
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001010
1011 spin_lock_irq(&dev->power.lock);
1012 dev->pm_domain = &genpd->domain;
1013 spin_unlock_irq(&dev->power.lock);
1014
1015 out:
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001016 genpd_release_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001017
1018 return ret;
1019}
1020
1021/**
1022 * pm_genpd_remove_device - Remove a device from an I/O PM domain.
1023 * @genpd: PM domain to remove the device from.
1024 * @dev: Device to be removed.
1025 */
1026int pm_genpd_remove_device(struct generic_pm_domain *genpd,
1027 struct device *dev)
1028{
1029 struct dev_list_entry *dle;
1030 int ret = -EINVAL;
1031
1032 dev_dbg(dev, "%s()\n", __func__);
1033
1034 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev))
1035 return -EINVAL;
1036
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001037 genpd_acquire_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001038
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001039 if (genpd->prepared_count > 0) {
1040 ret = -EAGAIN;
1041 goto out;
1042 }
1043
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001044 list_for_each_entry(dle, &genpd->dev_list, node) {
1045 if (dle->dev != dev)
1046 continue;
1047
1048 spin_lock_irq(&dev->power.lock);
1049 dev->pm_domain = NULL;
1050 spin_unlock_irq(&dev->power.lock);
1051
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001052 genpd->device_count--;
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001053 list_del(&dle->node);
1054 kfree(dle);
1055
1056 ret = 0;
1057 break;
1058 }
1059
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001060 out:
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001061 genpd_release_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001062
1063 return ret;
1064}
1065
1066/**
1067 * pm_genpd_add_subdomain - Add a subdomain to an I/O PM domain.
1068 * @genpd: Master PM domain to add the subdomain to.
1069 * @new_subdomain: Subdomain to be added.
1070 */
1071int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
1072 struct generic_pm_domain *new_subdomain)
1073{
1074 struct generic_pm_domain *subdomain;
1075 int ret = 0;
1076
1077 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(new_subdomain))
1078 return -EINVAL;
1079
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001080 start:
1081 genpd_acquire_lock(genpd);
1082 mutex_lock_nested(&new_subdomain->lock, SINGLE_DEPTH_NESTING);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001083
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001084 if (new_subdomain->status != GPD_STATE_POWER_OFF
1085 && new_subdomain->status != GPD_STATE_ACTIVE) {
1086 mutex_unlock(&new_subdomain->lock);
1087 genpd_release_lock(genpd);
1088 goto start;
1089 }
1090
1091 if (genpd->status == GPD_STATE_POWER_OFF
1092 && new_subdomain->status != GPD_STATE_POWER_OFF) {
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001093 ret = -EINVAL;
1094 goto out;
1095 }
1096
1097 list_for_each_entry(subdomain, &genpd->sd_list, sd_node) {
1098 if (subdomain == new_subdomain) {
1099 ret = -EINVAL;
1100 goto out;
1101 }
1102 }
1103
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001104 list_add_tail(&new_subdomain->sd_node, &genpd->sd_list);
1105 new_subdomain->parent = genpd;
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001106 if (subdomain->status != GPD_STATE_POWER_OFF)
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001107 genpd->sd_count++;
1108
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001109 out:
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001110 mutex_unlock(&new_subdomain->lock);
1111 genpd_release_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001112
1113 return ret;
1114}
1115
1116/**
1117 * pm_genpd_remove_subdomain - Remove a subdomain from an I/O PM domain.
1118 * @genpd: Master PM domain to remove the subdomain from.
1119 * @target: Subdomain to be removed.
1120 */
1121int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
1122 struct generic_pm_domain *target)
1123{
1124 struct generic_pm_domain *subdomain;
1125 int ret = -EINVAL;
1126
1127 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(target))
1128 return -EINVAL;
1129
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001130 start:
1131 genpd_acquire_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001132
1133 list_for_each_entry(subdomain, &genpd->sd_list, sd_node) {
1134 if (subdomain != target)
1135 continue;
1136
1137 mutex_lock_nested(&subdomain->lock, SINGLE_DEPTH_NESTING);
1138
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001139 if (subdomain->status != GPD_STATE_POWER_OFF
1140 && subdomain->status != GPD_STATE_ACTIVE) {
1141 mutex_unlock(&subdomain->lock);
1142 genpd_release_lock(genpd);
1143 goto start;
1144 }
1145
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001146 list_del(&subdomain->sd_node);
1147 subdomain->parent = NULL;
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001148 if (subdomain->status != GPD_STATE_POWER_OFF)
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001149 genpd_sd_counter_dec(genpd);
1150
1151 mutex_unlock(&subdomain->lock);
1152
1153 ret = 0;
1154 break;
1155 }
1156
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001157 genpd_release_lock(genpd);
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001158
1159 return ret;
1160}
1161
1162/**
1163 * pm_genpd_init - Initialize a generic I/O PM domain object.
1164 * @genpd: PM domain object to initialize.
1165 * @gov: PM domain governor to associate with the domain (may be NULL).
1166 * @is_off: Initial value of the domain's power_is_off field.
1167 */
1168void pm_genpd_init(struct generic_pm_domain *genpd,
1169 struct dev_power_governor *gov, bool is_off)
1170{
1171 if (IS_ERR_OR_NULL(genpd))
1172 return;
1173
1174 INIT_LIST_HEAD(&genpd->sd_node);
1175 genpd->parent = NULL;
1176 INIT_LIST_HEAD(&genpd->dev_list);
1177 INIT_LIST_HEAD(&genpd->sd_list);
1178 mutex_init(&genpd->lock);
1179 genpd->gov = gov;
1180 INIT_WORK(&genpd->power_off_work, genpd_power_off_work_fn);
1181 genpd->in_progress = 0;
1182 genpd->sd_count = 0;
Rafael J. Wysocki17b75ec2011-07-12 00:39:29 +02001183 genpd->status = is_off ? GPD_STATE_POWER_OFF : GPD_STATE_ACTIVE;
1184 init_waitqueue_head(&genpd->status_wait_queue);
Rafael J. Wysockic6d22b32011-07-12 00:39:36 +02001185 genpd->poweroff_task = NULL;
1186 genpd->resume_count = 0;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001187 genpd->device_count = 0;
1188 genpd->suspended_count = 0;
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001189 genpd->domain.ops.runtime_suspend = pm_genpd_runtime_suspend;
1190 genpd->domain.ops.runtime_resume = pm_genpd_runtime_resume;
1191 genpd->domain.ops.runtime_idle = pm_generic_runtime_idle;
Rafael J. Wysocki596ba342011-07-01 22:13:19 +02001192 genpd->domain.ops.prepare = pm_genpd_prepare;
1193 genpd->domain.ops.suspend = pm_genpd_suspend;
1194 genpd->domain.ops.suspend_noirq = pm_genpd_suspend_noirq;
1195 genpd->domain.ops.resume_noirq = pm_genpd_resume_noirq;
1196 genpd->domain.ops.resume = pm_genpd_resume;
1197 genpd->domain.ops.freeze = pm_genpd_freeze;
1198 genpd->domain.ops.freeze_noirq = pm_genpd_freeze_noirq;
1199 genpd->domain.ops.thaw_noirq = pm_genpd_thaw_noirq;
1200 genpd->domain.ops.thaw = pm_genpd_thaw;
1201 genpd->domain.ops.poweroff = pm_genpd_dev_poweroff;
1202 genpd->domain.ops.poweroff_noirq = pm_genpd_dev_poweroff_noirq;
1203 genpd->domain.ops.restore_noirq = pm_genpd_restore_noirq;
1204 genpd->domain.ops.restore = pm_genpd_restore;
1205 genpd->domain.ops.complete = pm_genpd_complete;
Rafael J. Wysockif7218892011-07-01 22:12:45 +02001206}