Commit cd59abfcc441b2abb4cf2cd62c1eb0f02a60e8dd

Authored by Alan Stern
Committed by Greg Kroah-Hartman
1 parent 6d66f5cd26

PM: merge device power-management source files

This patch (as993) merges the suspend.c and resume.c files in
drivers/base/power into main.c, making some public symbols private.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Acked-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

Showing 5 changed files with 343 additions and 394 deletions Side-by-side Diff

drivers/base/power/Makefile
1 1 obj-y := shutdown.o
2   -obj-$(CONFIG_PM_SLEEP) += main.o suspend.o resume.o sysfs.o
  2 +obj-$(CONFIG_PM_SLEEP) += main.o sysfs.o
3 3 obj-$(CONFIG_PM_TRACE) += trace.o
4 4  
5 5 ifeq ($(CONFIG_DEBUG_DRIVER),y)
drivers/base/power/main.c
... ... @@ -20,19 +20,24 @@
20 20 */
21 21  
22 22 #include <linux/device.h>
  23 +#include <linux/kallsyms.h>
23 24 #include <linux/mutex.h>
  25 +#include <linux/pm.h>
  26 +#include <linux/resume-trace.h>
24 27  
  28 +#include "../base.h"
25 29 #include "power.h"
26 30  
27 31 LIST_HEAD(dpm_active);
28   -LIST_HEAD(dpm_off);
29   -LIST_HEAD(dpm_off_irq);
  32 +static LIST_HEAD(dpm_off);
  33 +static LIST_HEAD(dpm_off_irq);
30 34  
31   -DEFINE_MUTEX(dpm_mtx);
32   -DEFINE_MUTEX(dpm_list_mtx);
  35 +static DEFINE_MUTEX(dpm_mtx);
  36 +static DEFINE_MUTEX(dpm_list_mtx);
33 37  
34 38 int (*platform_enable_wakeup)(struct device *dev, int is_on);
35 39  
  40 +
36 41 int device_pm_add(struct device *dev)
37 42 {
38 43 int error;
... ... @@ -59,4 +64,337 @@
59 64 list_del_init(&dev->power.entry);
60 65 mutex_unlock(&dpm_list_mtx);
61 66 }
  67 +
  68 +
  69 +/*------------------------- Resume routines -------------------------*/
  70 +
  71 +/**
  72 + * resume_device - Restore state for one device.
  73 + * @dev: Device.
  74 + *
  75 + */
  76 +
  77 +static int resume_device(struct device * dev)
  78 +{
  79 + int error = 0;
  80 +
  81 + TRACE_DEVICE(dev);
  82 + TRACE_RESUME(0);
  83 +
  84 + down(&dev->sem);
  85 +
  86 + if (dev->bus && dev->bus->resume) {
  87 + dev_dbg(dev,"resuming\n");
  88 + error = dev->bus->resume(dev);
  89 + }
  90 +
  91 + if (!error && dev->type && dev->type->resume) {
  92 + dev_dbg(dev,"resuming\n");
  93 + error = dev->type->resume(dev);
  94 + }
  95 +
  96 + if (!error && dev->class && dev->class->resume) {
  97 + dev_dbg(dev,"class resume\n");
  98 + error = dev->class->resume(dev);
  99 + }
  100 +
  101 + up(&dev->sem);
  102 +
  103 + TRACE_RESUME(error);
  104 + return error;
  105 +}
  106 +
  107 +
  108 +static int resume_device_early(struct device * dev)
  109 +{
  110 + int error = 0;
  111 +
  112 + TRACE_DEVICE(dev);
  113 + TRACE_RESUME(0);
  114 + if (dev->bus && dev->bus->resume_early) {
  115 + dev_dbg(dev,"EARLY resume\n");
  116 + error = dev->bus->resume_early(dev);
  117 + }
  118 + TRACE_RESUME(error);
  119 + return error;
  120 +}
  121 +
  122 +/*
  123 + * Resume the devices that have either not gone through
  124 + * the late suspend, or that did go through it but also
  125 + * went through the early resume
  126 + */
  127 +static void dpm_resume(void)
  128 +{
  129 + mutex_lock(&dpm_list_mtx);
  130 + while(!list_empty(&dpm_off)) {
  131 + struct list_head * entry = dpm_off.next;
  132 + struct device * dev = to_device(entry);
  133 +
  134 + get_device(dev);
  135 + list_move_tail(entry, &dpm_active);
  136 +
  137 + mutex_unlock(&dpm_list_mtx);
  138 + resume_device(dev);
  139 + mutex_lock(&dpm_list_mtx);
  140 + put_device(dev);
  141 + }
  142 + mutex_unlock(&dpm_list_mtx);
  143 +}
  144 +
  145 +
  146 +/**
  147 + * device_resume - Restore state of each device in system.
  148 + *
  149 + * Walk the dpm_off list, remove each entry, resume the device,
  150 + * then add it to the dpm_active list.
  151 + */
  152 +
  153 +void device_resume(void)
  154 +{
  155 + might_sleep();
  156 + mutex_lock(&dpm_mtx);
  157 + dpm_resume();
  158 + mutex_unlock(&dpm_mtx);
  159 +}
  160 +
  161 +EXPORT_SYMBOL_GPL(device_resume);
  162 +
  163 +
  164 +/**
  165 + * dpm_power_up - Power on some devices.
  166 + *
  167 + * Walk the dpm_off_irq list and power each device up. This
  168 + * is used for devices that required they be powered down with
  169 + * interrupts disabled. As devices are powered on, they are moved
  170 + * to the dpm_active list.
  171 + *
  172 + * Interrupts must be disabled when calling this.
  173 + */
  174 +
  175 +static void dpm_power_up(void)
  176 +{
  177 + while(!list_empty(&dpm_off_irq)) {
  178 + struct list_head * entry = dpm_off_irq.next;
  179 + struct device * dev = to_device(entry);
  180 +
  181 + list_move_tail(entry, &dpm_off);
  182 + resume_device_early(dev);
  183 + }
  184 +}
  185 +
  186 +
  187 +/**
  188 + * device_power_up - Turn on all devices that need special attention.
  189 + *
  190 + * Power on system devices then devices that required we shut them down
  191 + * with interrupts disabled.
  192 + * Called with interrupts disabled.
  193 + */
  194 +
  195 +void device_power_up(void)
  196 +{
  197 + sysdev_resume();
  198 + dpm_power_up();
  199 +}
  200 +
  201 +EXPORT_SYMBOL_GPL(device_power_up);
  202 +
  203 +
  204 +/*------------------------- Suspend routines -------------------------*/
  205 +
  206 +/*
  207 + * The entries in the dpm_active list are in a depth first order, simply
  208 + * because children are guaranteed to be discovered after parents, and
  209 + * are inserted at the back of the list on discovery.
  210 + *
  211 + * All list on the suspend path are done in reverse order, so we operate
  212 + * on the leaves of the device tree (or forests, depending on how you want
  213 + * to look at it ;) first. As nodes are removed from the back of the list,
  214 + * they are inserted into the front of their destintation lists.
  215 + *
  216 + * Things are the reverse on the resume path - iterations are done in
  217 + * forward order, and nodes are inserted at the back of their destination
  218 + * lists. This way, the ancestors will be accessed before their descendents.
  219 + */
  220 +
  221 +static inline char *suspend_verb(u32 event)
  222 +{
  223 + switch (event) {
  224 + case PM_EVENT_SUSPEND: return "suspend";
  225 + case PM_EVENT_FREEZE: return "freeze";
  226 + case PM_EVENT_PRETHAW: return "prethaw";
  227 + default: return "(unknown suspend event)";
  228 + }
  229 +}
  230 +
  231 +
  232 +static void
  233 +suspend_device_dbg(struct device *dev, pm_message_t state, char *info)
  234 +{
  235 + dev_dbg(dev, "%s%s%s\n", info, suspend_verb(state.event),
  236 + ((state.event == PM_EVENT_SUSPEND) && device_may_wakeup(dev)) ?
  237 + ", may wakeup" : "");
  238 +}
  239 +
  240 +/**
  241 + * suspend_device - Save state of one device.
  242 + * @dev: Device.
  243 + * @state: Power state device is entering.
  244 + */
  245 +
  246 +static int suspend_device(struct device * dev, pm_message_t state)
  247 +{
  248 + int error = 0;
  249 +
  250 + down(&dev->sem);
  251 + if (dev->power.power_state.event) {
  252 + dev_dbg(dev, "PM: suspend %d-->%d\n",
  253 + dev->power.power_state.event, state.event);
  254 + }
  255 +
  256 + if (dev->class && dev->class->suspend) {
  257 + suspend_device_dbg(dev, state, "class ");
  258 + error = dev->class->suspend(dev, state);
  259 + suspend_report_result(dev->class->suspend, error);
  260 + }
  261 +
  262 + if (!error && dev->type && dev->type->suspend) {
  263 + suspend_device_dbg(dev, state, "type ");
  264 + error = dev->type->suspend(dev, state);
  265 + suspend_report_result(dev->type->suspend, error);
  266 + }
  267 +
  268 + if (!error && dev->bus && dev->bus->suspend) {
  269 + suspend_device_dbg(dev, state, "");
  270 + error = dev->bus->suspend(dev, state);
  271 + suspend_report_result(dev->bus->suspend, error);
  272 + }
  273 + up(&dev->sem);
  274 + return error;
  275 +}
  276 +
  277 +
  278 +/*
  279 + * This is called with interrupts off, only a single CPU
  280 + * running. We can't acquire a mutex or semaphore (and we don't
  281 + * need the protection)
  282 + */
  283 +static int suspend_device_late(struct device *dev, pm_message_t state)
  284 +{
  285 + int error = 0;
  286 +
  287 + if (dev->bus && dev->bus->suspend_late) {
  288 + suspend_device_dbg(dev, state, "LATE ");
  289 + error = dev->bus->suspend_late(dev, state);
  290 + suspend_report_result(dev->bus->suspend_late, error);
  291 + }
  292 + return error;
  293 +}
  294 +
  295 +/**
  296 + * device_suspend - Save state and stop all devices in system.
  297 + * @state: Power state to put each device in.
  298 + *
  299 + * Walk the dpm_active list, call ->suspend() for each device, and move
  300 + * it to the dpm_off list.
  301 + *
  302 + * (For historical reasons, if it returns -EAGAIN, that used to mean
  303 + * that the device would be called again with interrupts disabled.
  304 + * These days, we use the "suspend_late()" callback for that, so we
  305 + * print a warning and consider it an error).
  306 + *
  307 + * If we get a different error, try and back out.
  308 + *
  309 + * If we hit a failure with any of the devices, call device_resume()
  310 + * above to bring the suspended devices back to life.
  311 + *
  312 + */
  313 +
  314 +int device_suspend(pm_message_t state)
  315 +{
  316 + int error = 0;
  317 +
  318 + might_sleep();
  319 + mutex_lock(&dpm_mtx);
  320 + mutex_lock(&dpm_list_mtx);
  321 + while (!list_empty(&dpm_active) && error == 0) {
  322 + struct list_head * entry = dpm_active.prev;
  323 + struct device * dev = to_device(entry);
  324 +
  325 + get_device(dev);
  326 + mutex_unlock(&dpm_list_mtx);
  327 +
  328 + error = suspend_device(dev, state);
  329 +
  330 + mutex_lock(&dpm_list_mtx);
  331 +
  332 + /* Check if the device got removed */
  333 + if (!list_empty(&dev->power.entry)) {
  334 + /* Move it to the dpm_off list */
  335 + if (!error)
  336 + list_move(&dev->power.entry, &dpm_off);
  337 + }
  338 + if (error)
  339 + printk(KERN_ERR "Could not suspend device %s: "
  340 + "error %d%s\n",
  341 + kobject_name(&dev->kobj), error,
  342 + error == -EAGAIN ? " (please convert to suspend_late)" : "");
  343 + put_device(dev);
  344 + }
  345 + mutex_unlock(&dpm_list_mtx);
  346 + if (error)
  347 + dpm_resume();
  348 +
  349 + mutex_unlock(&dpm_mtx);
  350 + return error;
  351 +}
  352 +
  353 +EXPORT_SYMBOL_GPL(device_suspend);
  354 +
  355 +/**
  356 + * device_power_down - Shut down special devices.
  357 + * @state: Power state to enter.
  358 + *
  359 + * Walk the dpm_off_irq list, calling ->power_down() for each device that
  360 + * couldn't power down the device with interrupts enabled. When we're
  361 + * done, power down system devices.
  362 + */
  363 +
  364 +int device_power_down(pm_message_t state)
  365 +{
  366 + int error = 0;
  367 + struct device * dev;
  368 +
  369 + while (!list_empty(&dpm_off)) {
  370 + struct list_head * entry = dpm_off.prev;
  371 +
  372 + dev = to_device(entry);
  373 + error = suspend_device_late(dev, state);
  374 + if (error)
  375 + goto Error;
  376 + list_move(&dev->power.entry, &dpm_off_irq);
  377 + }
  378 +
  379 + error = sysdev_suspend(state);
  380 + Done:
  381 + return error;
  382 + Error:
  383 + printk(KERN_ERR "Could not power down device %s: "
  384 + "error %d\n", kobject_name(&dev->kobj), error);
  385 + dpm_power_up();
  386 + goto Done;
  387 +}
  388 +
  389 +EXPORT_SYMBOL_GPL(device_power_down);
  390 +
  391 +void __suspend_report_result(const char *function, void *fn, int ret)
  392 +{
  393 + if (ret) {
  394 + printk(KERN_ERR "%s(): ", function);
  395 + print_fn_descriptor_symbol("%s() returns ", (unsigned long)fn);
  396 + printk("%d\n", ret);
  397 + }
  398 +}
  399 +EXPORT_SYMBOL_GPL(__suspend_report_result);
drivers/base/power/power.h
... ... @@ -11,32 +11,11 @@
11 11 * main.c
12 12 */
13 13  
14   -/*
15   - * Used to synchronize global power management operations.
16   - */
17   -extern struct mutex dpm_mtx;
  14 +extern struct list_head dpm_active; /* The active device list */
18 15  
19   -/*
20   - * Used to serialize changes to the dpm_* lists.
21   - */
22   -extern struct mutex dpm_list_mtx;
23   -
24   -/*
25   - * The PM lists.
26   - */
27   -extern struct list_head dpm_active;
28   -extern struct list_head dpm_off;
29   -extern struct list_head dpm_off_irq;
30   -
31   -
32   -static inline struct dev_pm_info * to_pm_info(struct list_head * entry)
33   -{
34   - return container_of(entry, struct dev_pm_info, entry);
35   -}
36   -
37 16 static inline struct device * to_device(struct list_head * entry)
38 17 {
39   - return container_of(to_pm_info(entry), struct device, power);
  18 + return container_of(entry, struct device, power.entry);
40 19 }
41 20  
42 21 extern int device_pm_add(struct device *);
... ... @@ -48,13 +27,6 @@
48 27  
49 28 extern int dpm_sysfs_add(struct device *);
50 29 extern void dpm_sysfs_remove(struct device *);
51   -
52   -/*
53   - * resume.c
54   - */
55   -
56   -extern void dpm_resume(void);
57   -extern void dpm_power_up(void);
58 30  
59 31 #else /* CONFIG_PM_SLEEP */
60 32  
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 <linux/resume-trace.h>
13   -#include "../base.h"
14   -#include "power.h"
15   -
16   -
17   -/**
18   - * resume_device - Restore state for one device.
19   - * @dev: Device.
20   - *
21   - */
22   -
23   -static int resume_device(struct device * dev)
24   -{
25   - int error = 0;
26   -
27   - TRACE_DEVICE(dev);
28   - TRACE_RESUME(0);
29   -
30   - down(&dev->sem);
31   -
32   - if (dev->bus && dev->bus->resume) {
33   - dev_dbg(dev,"resuming\n");
34   - error = dev->bus->resume(dev);
35   - }
36   -
37   - if (!error && dev->type && dev->type->resume) {
38   - dev_dbg(dev,"resuming\n");
39   - error = dev->type->resume(dev);
40   - }
41   -
42   - if (!error && dev->class && dev->class->resume) {
43   - dev_dbg(dev,"class resume\n");
44   - error = dev->class->resume(dev);
45   - }
46   -
47   - up(&dev->sem);
48   -
49   - TRACE_RESUME(error);
50   - return error;
51   -}
52   -
53   -
54   -static int resume_device_early(struct device * dev)
55   -{
56   - int error = 0;
57   -
58   - TRACE_DEVICE(dev);
59   - TRACE_RESUME(0);
60   - if (dev->bus && dev->bus->resume_early) {
61   - dev_dbg(dev,"EARLY resume\n");
62   - error = dev->bus->resume_early(dev);
63   - }
64   - TRACE_RESUME(error);
65   - return error;
66   -}
67   -
68   -/*
69   - * Resume the devices that have either not gone through
70   - * the late suspend, or that did go through it but also
71   - * went through the early resume
72   - */
73   -void dpm_resume(void)
74   -{
75   - mutex_lock(&dpm_list_mtx);
76   - while(!list_empty(&dpm_off)) {
77   - struct list_head * entry = dpm_off.next;
78   - struct device * dev = to_device(entry);
79   -
80   - get_device(dev);
81   - list_move_tail(entry, &dpm_active);
82   -
83   - mutex_unlock(&dpm_list_mtx);
84   - resume_device(dev);
85   - mutex_lock(&dpm_list_mtx);
86   - put_device(dev);
87   - }
88   - mutex_unlock(&dpm_list_mtx);
89   -}
90   -
91   -
92   -/**
93   - * device_resume - Restore state of each device in system.
94   - *
95   - * Walk the dpm_off list, remove each entry, resume the device,
96   - * then add it to the dpm_active list.
97   - */
98   -
99   -void device_resume(void)
100   -{
101   - might_sleep();
102   - mutex_lock(&dpm_mtx);
103   - dpm_resume();
104   - mutex_unlock(&dpm_mtx);
105   -}
106   -
107   -EXPORT_SYMBOL_GPL(device_resume);
108   -
109   -
110   -/**
111   - * dpm_power_up - Power on some devices.
112   - *
113   - * Walk the dpm_off_irq list and power each device up. This
114   - * is used for devices that required they be powered down with
115   - * interrupts disabled. As devices are powered on, they are moved
116   - * to the dpm_active list.
117   - *
118   - * Interrupts must be disabled when calling this.
119   - */
120   -
121   -void dpm_power_up(void)
122   -{
123   - while(!list_empty(&dpm_off_irq)) {
124   - struct list_head * entry = dpm_off_irq.next;
125   - struct device * dev = to_device(entry);
126   -
127   - list_move_tail(entry, &dpm_off);
128   - resume_device_early(dev);
129   - }
130   -}
131   -
132   -
133   -/**
134   - * device_power_up - Turn on all devices that need special attention.
135   - *
136   - * Power on system devices then devices that required we shut them down
137   - * with interrupts disabled.
138   - * Called with interrupts disabled.
139   - */
140   -
141   -void device_power_up(void)
142   -{
143   - sysdev_resume();
144   - dpm_power_up();
145   -}
146   -
147   -EXPORT_SYMBOL_GPL(device_power_up);
drivers/base/power/suspend.c
1   -/*
2   - * suspend.c - Functions for putting devices to sleep.
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 <linux/kallsyms.h>
13   -#include <linux/pm.h>
14   -#include "../base.h"
15   -#include "power.h"
16   -
17   -/*
18   - * The entries in the dpm_active list are in a depth first order, simply
19   - * because children are guaranteed to be discovered after parents, and
20   - * are inserted at the back of the list on discovery.
21   - *
22   - * All list on the suspend path are done in reverse order, so we operate
23   - * on the leaves of the device tree (or forests, depending on how you want
24   - * to look at it ;) first. As nodes are removed from the back of the list,
25   - * they are inserted into the front of their destintation lists.
26   - *
27   - * Things are the reverse on the resume path - iterations are done in
28   - * forward order, and nodes are inserted at the back of their destination
29   - * lists. This way, the ancestors will be accessed before their descendents.
30   - */
31   -
32   -static inline char *suspend_verb(u32 event)
33   -{
34   - switch (event) {
35   - case PM_EVENT_SUSPEND: return "suspend";
36   - case PM_EVENT_FREEZE: return "freeze";
37   - case PM_EVENT_PRETHAW: return "prethaw";
38   - default: return "(unknown suspend event)";
39   - }
40   -}
41   -
42   -
43   -static void
44   -suspend_device_dbg(struct device *dev, pm_message_t state, char *info)
45   -{
46   - dev_dbg(dev, "%s%s%s\n", info, suspend_verb(state.event),
47   - ((state.event == PM_EVENT_SUSPEND) && device_may_wakeup(dev)) ?
48   - ", may wakeup" : "");
49   -}
50   -
51   -/**
52   - * suspend_device - Save state of one device.
53   - * @dev: Device.
54   - * @state: Power state device is entering.
55   - */
56   -
57   -static int suspend_device(struct device * dev, pm_message_t state)
58   -{
59   - int error = 0;
60   -
61   - down(&dev->sem);
62   - if (dev->power.power_state.event) {
63   - dev_dbg(dev, "PM: suspend %d-->%d\n",
64   - dev->power.power_state.event, state.event);
65   - }
66   -
67   - if (dev->class && dev->class->suspend) {
68   - suspend_device_dbg(dev, state, "class ");
69   - error = dev->class->suspend(dev, state);
70   - suspend_report_result(dev->class->suspend, error);
71   - }
72   -
73   - if (!error && dev->type && dev->type->suspend) {
74   - suspend_device_dbg(dev, state, "type ");
75   - error = dev->type->suspend(dev, state);
76   - suspend_report_result(dev->type->suspend, error);
77   - }
78   -
79   - if (!error && dev->bus && dev->bus->suspend) {
80   - suspend_device_dbg(dev, state, "");
81   - error = dev->bus->suspend(dev, state);
82   - suspend_report_result(dev->bus->suspend, error);
83   - }
84   - up(&dev->sem);
85   - return error;
86   -}
87   -
88   -
89   -/*
90   - * This is called with interrupts off, only a single CPU
91   - * running. We can't acquire a mutex or semaphore (and we don't
92   - * need the protection)
93   - */
94   -static int suspend_device_late(struct device *dev, pm_message_t state)
95   -{
96   - int error = 0;
97   -
98   - if (dev->bus && dev->bus->suspend_late) {
99   - suspend_device_dbg(dev, state, "LATE ");
100   - error = dev->bus->suspend_late(dev, state);
101   - suspend_report_result(dev->bus->suspend_late, error);
102   - }
103   - return error;
104   -}
105   -
106   -/**
107   - * device_suspend - Save state and stop all devices in system.
108   - * @state: Power state to put each device in.
109   - *
110   - * Walk the dpm_active list, call ->suspend() for each device, and move
111   - * it to the dpm_off list.
112   - *
113   - * (For historical reasons, if it returns -EAGAIN, that used to mean
114   - * that the device would be called again with interrupts disabled.
115   - * These days, we use the "suspend_late()" callback for that, so we
116   - * print a warning and consider it an error).
117   - *
118   - * If we get a different error, try and back out.
119   - *
120   - * If we hit a failure with any of the devices, call device_resume()
121   - * above to bring the suspended devices back to life.
122   - *
123   - */
124   -
125   -int device_suspend(pm_message_t state)
126   -{
127   - int error = 0;
128   -
129   - might_sleep();
130   - mutex_lock(&dpm_mtx);
131   - mutex_lock(&dpm_list_mtx);
132   - while (!list_empty(&dpm_active) && error == 0) {
133   - struct list_head * entry = dpm_active.prev;
134   - struct device * dev = to_device(entry);
135   -
136   - get_device(dev);
137   - mutex_unlock(&dpm_list_mtx);
138   -
139   - error = suspend_device(dev, state);
140   -
141   - mutex_lock(&dpm_list_mtx);
142   -
143   - /* Check if the device got removed */
144   - if (!list_empty(&dev->power.entry)) {
145   - /* Move it to the dpm_off list */
146   - if (!error)
147   - list_move(&dev->power.entry, &dpm_off);
148   - }
149   - if (error)
150   - printk(KERN_ERR "Could not suspend device %s: "
151   - "error %d%s\n",
152   - kobject_name(&dev->kobj), error,
153   - error == -EAGAIN ? " (please convert to suspend_late)" : "");
154   - put_device(dev);
155   - }
156   - mutex_unlock(&dpm_list_mtx);
157   - if (error)
158   - dpm_resume();
159   -
160   - mutex_unlock(&dpm_mtx);
161   - return error;
162   -}
163   -
164   -EXPORT_SYMBOL_GPL(device_suspend);
165   -
166   -/**
167   - * device_power_down - Shut down special devices.
168   - * @state: Power state to enter.
169   - *
170   - * Walk the dpm_off_irq list, calling ->power_down() for each device that
171   - * couldn't power down the device with interrupts enabled. When we're
172   - * done, power down system devices.
173   - */
174   -
175   -int device_power_down(pm_message_t state)
176   -{
177   - int error = 0;
178   - struct device * dev;
179   -
180   - while (!list_empty(&dpm_off)) {
181   - struct list_head * entry = dpm_off.prev;
182   -
183   - dev = to_device(entry);
184   - error = suspend_device_late(dev, state);
185   - if (error)
186   - goto Error;
187   - list_move(&dev->power.entry, &dpm_off_irq);
188   - }
189   -
190   - error = sysdev_suspend(state);
191   - Done:
192   - return error;
193   - Error:
194   - printk(KERN_ERR "Could not power down device %s: "
195   - "error %d\n", kobject_name(&dev->kobj), error);
196   - dpm_power_up();
197   - goto Done;
198   -}
199   -
200   -EXPORT_SYMBOL_GPL(device_power_down);
201   -
202   -void __suspend_report_result(const char *function, void *fn, int ret)
203   -{
204   - if (ret) {
205   - printk(KERN_ERR "%s(): ", function);
206   - print_fn_descriptor_symbol("%s() returns ", (unsigned long)fn);
207   - printk("%d\n", ret);
208   - }
209   -}
210   -EXPORT_SYMBOL_GPL(__suspend_report_result);