blob: 26468971ef5a7711179e87f0d500cdc680888157 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
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
14extern int sysdev_resume(void);
15
16
17/**
18 * resume_device - Restore state for one device.
19 * @dev: Device.
20 *
21 */
22
23int resume_device(struct device * dev)
24{
David Brownell82428b62005-05-09 08:07:00 -070025 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");
Linus Torvalds1da177e2005-04-16 15:20:36 -070034 return dev->bus->resume(dev);
David Brownell82428b62005-05-09 08:07:00 -070035 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070036 return 0;
37}
38
39
40
41void 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
69void device_resume(void)
70{
71 down(&dpm_sem);
72 dpm_resume();
73 up(&dpm_sem);
74}
75
76EXPORT_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
90void 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
113void device_power_up(void)
114{
115 sysdev_resume();
116 dpm_power_up();
117}
118
119EXPORT_SYMBOL_GPL(device_power_up);
120
121