PM: Remove pm_parent from struct dev_pm_info
[linux-2.6-block.git] / drivers / base / power / resume.c
CommitLineData
1da177e4
LT
1/*
2 * resume.c - Functions for waking devices up.
3 *
4 * Copyright (c) 2003 Patrick Mochel
5 * Copyright (c) 2003 Open Source Development Labs
6 *
7 * This file is released under the GPLv2
8 *
9 */
10
11#include <linux/device.h>
d02f40e8 12#include <linux/resume-trace.h>
f67d115f 13#include "../base.h"
1da177e4
LT
14#include "power.h"
15
1da177e4
LT
16
17/**
18 * resume_device - Restore state for one device.
19 * @dev: Device.
20 *
21 */
22
23int resume_device(struct device * dev)
24{
af70316a 25 int error = 0;
26
d02f40e8
LT
27 TRACE_DEVICE(dev);
28 TRACE_RESUME(0);
f89cbc39 29
af70316a 30 down(&dev->sem);
f89cbc39 31
9cddad77 32 if (dev->parent && dev->parent->power.power_state.event) {
82428b62 33 dev_err(dev, "PM: resume from %d, parent %s still %d\n",
ca078bae 34 dev->power.power_state.event,
9cddad77
RW
35 dev->parent->bus_id,
36 dev->parent->power.power_state.event);
82428b62 37 }
f89cbc39 38
82428b62
DB
39 if (dev->bus && dev->bus->resume) {
40 dev_dbg(dev,"resuming\n");
af70316a 41 error = dev->bus->resume(dev);
82428b62 42 }
f89cbc39
DT
43
44 if (!error && dev->type && dev->type->resume) {
45 dev_dbg(dev,"resuming\n");
46 error = dev->type->resume(dev);
47 }
48
49 if (!error && dev->class && dev->class->resume) {
7c8265f5
LT
50 dev_dbg(dev,"class resume\n");
51 error = dev->class->resume(dev);
52 }
f89cbc39 53
af70316a 54 up(&dev->sem);
f89cbc39 55
d02f40e8 56 TRACE_RESUME(error);
af70316a 57 return error;
1da177e4
LT
58}
59
60
7c8265f5
LT
61static int resume_device_early(struct device * dev)
62{
63 int error = 0;
1da177e4 64
7c8265f5
LT
65 TRACE_DEVICE(dev);
66 TRACE_RESUME(0);
67 if (dev->bus && dev->bus->resume_early) {
68 dev_dbg(dev,"EARLY resume\n");
69 error = dev->bus->resume_early(dev);
70 }
71 TRACE_RESUME(error);
72 return error;
73}
74
75/*
76 * Resume the devices that have either not gone through
77 * the late suspend, or that did go through it but also
78 * went through the early resume
79 */
1da177e4
LT
80void dpm_resume(void)
81{
11048dcf 82 mutex_lock(&dpm_list_mtx);
1da177e4
LT
83 while(!list_empty(&dpm_off)) {
84 struct list_head * entry = dpm_off.next;
85 struct device * dev = to_device(entry);
86
87 get_device(dev);
1bfba4e8 88 list_move_tail(entry, &dpm_active);
1da177e4 89
11048dcf 90 mutex_unlock(&dpm_list_mtx);
ca078bae 91 if (!dev->power.prev_state.event)
1da177e4 92 resume_device(dev);
11048dcf 93 mutex_lock(&dpm_list_mtx);
1da177e4
LT
94 put_device(dev);
95 }
11048dcf 96 mutex_unlock(&dpm_list_mtx);
1da177e4
LT
97}
98
99
100/**
101 * device_resume - Restore state of each device in system.
102 *
103 * Walk the dpm_off list, remove each entry, resume the device,
104 * then add it to the dpm_active list.
105 */
106
107void device_resume(void)
108{
bb84c89f 109 might_sleep();
11048dcf 110 mutex_lock(&dpm_mtx);
1da177e4 111 dpm_resume();
11048dcf 112 mutex_unlock(&dpm_mtx);
1da177e4
LT
113}
114
115EXPORT_SYMBOL_GPL(device_resume);
116
117
118/**
9de72ee5 119 * dpm_power_up - Power on some devices.
1da177e4
LT
120 *
121 * Walk the dpm_off_irq list and power each device up. This
122 * is used for devices that required they be powered down with
9de72ee5
DT
123 * interrupts disabled. As devices are powered on, they are moved
124 * to the dpm_active list.
1da177e4
LT
125 *
126 * Interrupts must be disabled when calling this.
127 */
128
129void dpm_power_up(void)
130{
131 while(!list_empty(&dpm_off_irq)) {
132 struct list_head * entry = dpm_off_irq.next;
133 struct device * dev = to_device(entry);
134
7c8265f5
LT
135 list_move_tail(entry, &dpm_off);
136 resume_device_early(dev);
1da177e4
LT
137 }
138}
139
140
141/**
9de72ee5 142 * device_power_up - Turn on all devices that need special attention.
1da177e4
LT
143 *
144 * Power on system devices then devices that required we shut them down
145 * with interrupts disabled.
146 * Called with interrupts disabled.
147 */
148
149void device_power_up(void)
150{
151 sysdev_resume();
152 dpm_power_up();
153}
154
155EXPORT_SYMBOL_GPL(device_power_up);
156
157