vserver 2.0 rc7
[linux-2.6.git] / drivers / base / power / resume.c
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>
12 #include "power.h"
13
14 extern int sysdev_resume(void);
15
16
17 /**
18  *      resume_device - Restore state for one device.
19  *      @dev:   Device.
20  *
21  */
22
23 int resume_device(struct device * dev)
24 {
25         if (dev->power.pm_parent
26                         && dev->power.pm_parent->power.power_state) {
27                 dev_err(dev, "PM: resume from %d, parent %s still %d\n",
28                         dev->power.power_state,
29                         dev->power.pm_parent->bus_id,
30                         dev->power.pm_parent->power.power_state);
31         }
32         if (dev->bus && dev->bus->resume) {
33                 dev_dbg(dev,"resuming\n");
34                 return dev->bus->resume(dev);
35         }
36         return 0;
37 }
38
39
40
41 void dpm_resume(void)
42 {
43         down(&dpm_list_sem);
44         while(!list_empty(&dpm_off)) {
45                 struct list_head * entry = dpm_off.next;
46                 struct device * dev = to_device(entry);
47
48                 get_device(dev);
49                 list_del_init(entry);
50                 list_add_tail(entry, &dpm_active);
51
52                 up(&dpm_list_sem);
53                 if (!dev->power.prev_state)
54                         resume_device(dev);
55                 down(&dpm_list_sem);
56                 put_device(dev);
57         }
58         up(&dpm_list_sem);
59 }
60
61
62 /**
63  *      device_resume - Restore state of each device in system.
64  *
65  *      Walk the dpm_off list, remove each entry, resume the device,
66  *      then add it to the dpm_active list.
67  */
68
69 void device_resume(void)
70 {
71         down(&dpm_sem);
72         dpm_resume();
73         up(&dpm_sem);
74 }
75
76 EXPORT_SYMBOL_GPL(device_resume);
77
78
79 /**
80  *      device_power_up_irq - Power on some devices.
81  *
82  *      Walk the dpm_off_irq list and power each device up. This
83  *      is used for devices that required they be powered down with
84  *      interrupts disabled. As devices are powered on, they are moved to
85  *      the dpm_suspended list.
86  *
87  *      Interrupts must be disabled when calling this.
88  */
89
90 void dpm_power_up(void)
91 {
92         while(!list_empty(&dpm_off_irq)) {
93                 struct list_head * entry = dpm_off_irq.next;
94                 struct device * dev = to_device(entry);
95
96                 get_device(dev);
97                 list_del_init(entry);
98                 list_add_tail(entry, &dpm_active);
99                 resume_device(dev);
100                 put_device(dev);
101         }
102 }
103
104
105 /**
106  *      device_pm_power_up - Turn on all devices that need special attention.
107  *
108  *      Power on system devices then devices that required we shut them down
109  *      with interrupts disabled.
110  *      Called with interrupts disabled.
111  */
112
113 void device_power_up(void)
114 {
115         sysdev_resume();
116         dpm_power_up();
117 }
118
119 EXPORT_SYMBOL_GPL(device_power_up);
120
121