diff options
-rw-r--r-- | drivers/base/power/resume.c | 13 | ||||
-rw-r--r-- | drivers/base/power/suspend.c | 12 | ||||
-rw-r--r-- | include/linux/device.h | 2 |
3 files changed, 26 insertions, 1 deletions
diff --git a/drivers/base/power/resume.c b/drivers/base/power/resume.c index 020be36705a6..a2c64188d713 100644 --- a/drivers/base/power/resume.c +++ b/drivers/base/power/resume.c | |||
@@ -26,7 +26,9 @@ int resume_device(struct device * dev) | |||
26 | 26 | ||
27 | TRACE_DEVICE(dev); | 27 | TRACE_DEVICE(dev); |
28 | TRACE_RESUME(0); | 28 | TRACE_RESUME(0); |
29 | |||
29 | down(&dev->sem); | 30 | down(&dev->sem); |
31 | |||
30 | if (dev->power.pm_parent | 32 | if (dev->power.pm_parent |
31 | && dev->power.pm_parent->power.power_state.event) { | 33 | && dev->power.pm_parent->power.power_state.event) { |
32 | dev_err(dev, "PM: resume from %d, parent %s still %d\n", | 34 | dev_err(dev, "PM: resume from %d, parent %s still %d\n", |
@@ -34,15 +36,24 @@ int resume_device(struct device * dev) | |||
34 | dev->power.pm_parent->bus_id, | 36 | dev->power.pm_parent->bus_id, |
35 | dev->power.pm_parent->power.power_state.event); | 37 | dev->power.pm_parent->power.power_state.event); |
36 | } | 38 | } |
39 | |||
37 | if (dev->bus && dev->bus->resume) { | 40 | if (dev->bus && dev->bus->resume) { |
38 | dev_dbg(dev,"resuming\n"); | 41 | dev_dbg(dev,"resuming\n"); |
39 | error = dev->bus->resume(dev); | 42 | error = dev->bus->resume(dev); |
40 | } | 43 | } |
41 | if (dev->class && dev->class->resume) { | 44 | |
45 | if (!error && dev->type && dev->type->resume) { | ||
46 | dev_dbg(dev,"resuming\n"); | ||
47 | error = dev->type->resume(dev); | ||
48 | } | ||
49 | |||
50 | if (!error && dev->class && dev->class->resume) { | ||
42 | dev_dbg(dev,"class resume\n"); | 51 | dev_dbg(dev,"class resume\n"); |
43 | error = dev->class->resume(dev); | 52 | error = dev->class->resume(dev); |
44 | } | 53 | } |
54 | |||
45 | up(&dev->sem); | 55 | up(&dev->sem); |
56 | |||
46 | TRACE_RESUME(error); | 57 | TRACE_RESUME(error); |
47 | return error; | 58 | return error; |
48 | } | 59 | } |
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c index ece136bf97e3..42d2b86ba765 100644 --- a/drivers/base/power/suspend.c +++ b/drivers/base/power/suspend.c | |||
@@ -78,6 +78,18 @@ int suspend_device(struct device * dev, pm_message_t state) | |||
78 | suspend_report_result(dev->class->suspend, error); | 78 | suspend_report_result(dev->class->suspend, error); |
79 | } | 79 | } |
80 | 80 | ||
81 | if (!error && dev->type && dev->type->suspend && !dev->power.power_state.event) { | ||
82 | dev_dbg(dev, "%s%s\n", | ||
83 | suspend_verb(state.event), | ||
84 | ((state.event == PM_EVENT_SUSPEND) | ||
85 | && device_may_wakeup(dev)) | ||
86 | ? ", may wakeup" | ||
87 | : "" | ||
88 | ); | ||
89 | error = dev->type->suspend(dev, state); | ||
90 | suspend_report_result(dev->type->suspend, error); | ||
91 | } | ||
92 | |||
81 | if (!error && dev->bus && dev->bus->suspend && !dev->power.power_state.event) { | 93 | if (!error && dev->bus && dev->bus->suspend && !dev->power.power_state.event) { |
82 | dev_dbg(dev, "%s%s\n", | 94 | dev_dbg(dev, "%s%s\n", |
83 | suspend_verb(state.event), | 95 | suspend_verb(state.event), |
diff --git a/include/linux/device.h b/include/linux/device.h index c9dc458e8e50..af603a137690 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -344,6 +344,8 @@ struct device_type { | |||
344 | int (*uevent)(struct device *dev, char **envp, int num_envp, | 344 | int (*uevent)(struct device *dev, char **envp, int num_envp, |
345 | char *buffer, int buffer_size); | 345 | char *buffer, int buffer_size); |
346 | void (*release)(struct device *dev); | 346 | void (*release)(struct device *dev); |
347 | int (*suspend)(struct device * dev, pm_message_t state); | ||
348 | int (*resume)(struct device * dev); | ||
347 | }; | 349 | }; |
348 | 350 | ||
349 | /* interface for exporting device attributes */ | 351 | /* interface for exporting device attributes */ |