aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2012-01-29 14:38:41 -0500
committerRafael J. Wysocki <rjw@sisk.pl>2012-01-29 14:38:41 -0500
commite470d06655e00749f6f9372e4fa4f20cea7ed7c5 (patch)
tree63e56f01b27ee9693bfb9d9127e4763ba0937057 /drivers/base
parentcf579dfb82550e34de7ccf3ef090d8b834ccd3a9 (diff)
PM / Sleep: Introduce generic callbacks for new device PM phases
Introduce generic subsystem callbacks for the new phases of device suspend/resume during system power transitions: "late suspend", "early resume", "late freeze", "early thaw", "late poweroff", "early restore". Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/power/generic_ops.c157
1 files changed, 104 insertions, 53 deletions
diff --git a/drivers/base/power/generic_ops.c b/drivers/base/power/generic_ops.c
index 10bdd793f0bd..d03d290f31c2 100644
--- a/drivers/base/power/generic_ops.c
+++ b/drivers/base/power/generic_ops.c
@@ -92,59 +92,28 @@ int pm_generic_prepare(struct device *dev)
92} 92}
93 93
94/** 94/**
95 * __pm_generic_call - Generic suspend/freeze/poweroff/thaw subsystem callback. 95 * pm_generic_suspend_noirq - Generic suspend_noirq callback for subsystems.
96 * @dev: Device to handle. 96 * @dev: Device to suspend.
97 * @event: PM transition of the system under way.
98 * @bool: Whether or not this is the "noirq" stage.
99 *
100 * Execute the PM callback corresponding to @event provided by the driver of
101 * @dev, if defined, and return its error code. Return 0 if the callback is
102 * not present.
103 */ 97 */
104static int __pm_generic_call(struct device *dev, int event, bool noirq) 98int pm_generic_suspend_noirq(struct device *dev)
105{ 99{
106 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 100 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
107 int (*callback)(struct device *);
108
109 if (!pm)
110 return 0;
111
112 switch (event) {
113 case PM_EVENT_SUSPEND:
114 callback = noirq ? pm->suspend_noirq : pm->suspend;
115 break;
116 case PM_EVENT_FREEZE:
117 callback = noirq ? pm->freeze_noirq : pm->freeze;
118 break;
119 case PM_EVENT_HIBERNATE:
120 callback = noirq ? pm->poweroff_noirq : pm->poweroff;
121 break;
122 case PM_EVENT_RESUME:
123 callback = noirq ? pm->resume_noirq : pm->resume;
124 break;
125 case PM_EVENT_THAW:
126 callback = noirq ? pm->thaw_noirq : pm->thaw;
127 break;
128 case PM_EVENT_RESTORE:
129 callback = noirq ? pm->restore_noirq : pm->restore;
130 break;
131 default:
132 callback = NULL;
133 break;
134 }
135 101
136 return callback ? callback(dev) : 0; 102 return pm && pm->suspend_noirq ? pm->suspend_noirq(dev) : 0;
137} 103}
104EXPORT_SYMBOL_GPL(pm_generic_suspend_noirq);
138 105
139/** 106/**
140 * pm_generic_suspend_noirq - Generic suspend_noirq callback for subsystems. 107 * pm_generic_suspend_late - Generic suspend_late callback for subsystems.
141 * @dev: Device to suspend. 108 * @dev: Device to suspend.
142 */ 109 */
143int pm_generic_suspend_noirq(struct device *dev) 110int pm_generic_suspend_late(struct device *dev)
144{ 111{
145 return __pm_generic_call(dev, PM_EVENT_SUSPEND, true); 112 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
113
114 return pm && pm->suspend_late ? pm->suspend_late(dev) : 0;
146} 115}
147EXPORT_SYMBOL_GPL(pm_generic_suspend_noirq); 116EXPORT_SYMBOL_GPL(pm_generic_suspend_late);
148 117
149/** 118/**
150 * pm_generic_suspend - Generic suspend callback for subsystems. 119 * pm_generic_suspend - Generic suspend callback for subsystems.
@@ -152,7 +121,9 @@ EXPORT_SYMBOL_GPL(pm_generic_suspend_noirq);
152 */ 121 */
153int pm_generic_suspend(struct device *dev) 122int pm_generic_suspend(struct device *dev)
154{ 123{
155 return __pm_generic_call(dev, PM_EVENT_SUSPEND, false); 124 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
125
126 return pm && pm->suspend ? pm->suspend(dev) : 0;
156} 127}
157EXPORT_SYMBOL_GPL(pm_generic_suspend); 128EXPORT_SYMBOL_GPL(pm_generic_suspend);
158 129
@@ -162,17 +133,33 @@ EXPORT_SYMBOL_GPL(pm_generic_suspend);
162 */ 133 */
163int pm_generic_freeze_noirq(struct device *dev) 134int pm_generic_freeze_noirq(struct device *dev)
164{ 135{
165 return __pm_generic_call(dev, PM_EVENT_FREEZE, true); 136 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
137
138 return pm && pm->freeze_noirq ? pm->freeze_noirq(dev) : 0;
166} 139}
167EXPORT_SYMBOL_GPL(pm_generic_freeze_noirq); 140EXPORT_SYMBOL_GPL(pm_generic_freeze_noirq);
168 141
169/** 142/**
143 * pm_generic_freeze_late - Generic freeze_late callback for subsystems.
144 * @dev: Device to freeze.
145 */
146int pm_generic_freeze_late(struct device *dev)
147{
148 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
149
150 return pm && pm->freeze_late ? pm->freeze_late(dev) : 0;
151}
152EXPORT_SYMBOL_GPL(pm_generic_freeze_late);
153
154/**
170 * pm_generic_freeze - Generic freeze callback for subsystems. 155 * pm_generic_freeze - Generic freeze callback for subsystems.
171 * @dev: Device to freeze. 156 * @dev: Device to freeze.
172 */ 157 */
173int pm_generic_freeze(struct device *dev) 158int pm_generic_freeze(struct device *dev)
174{ 159{
175 return __pm_generic_call(dev, PM_EVENT_FREEZE, false); 160 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
161
162 return pm && pm->freeze ? pm->freeze(dev) : 0;
176} 163}
177EXPORT_SYMBOL_GPL(pm_generic_freeze); 164EXPORT_SYMBOL_GPL(pm_generic_freeze);
178 165
@@ -182,17 +169,33 @@ EXPORT_SYMBOL_GPL(pm_generic_freeze);
182 */ 169 */
183int pm_generic_poweroff_noirq(struct device *dev) 170int pm_generic_poweroff_noirq(struct device *dev)
184{ 171{
185 return __pm_generic_call(dev, PM_EVENT_HIBERNATE, true); 172 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
173
174 return pm && pm->poweroff_noirq ? pm->poweroff_noirq(dev) : 0;
186} 175}
187EXPORT_SYMBOL_GPL(pm_generic_poweroff_noirq); 176EXPORT_SYMBOL_GPL(pm_generic_poweroff_noirq);
188 177
189/** 178/**
179 * pm_generic_poweroff_late - Generic poweroff_late callback for subsystems.
180 * @dev: Device to handle.
181 */
182int pm_generic_poweroff_late(struct device *dev)
183{
184 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
185
186 return pm && pm->poweroff_late ? pm->poweroff_late(dev) : 0;
187}
188EXPORT_SYMBOL_GPL(pm_generic_poweroff_late);
189
190/**
190 * pm_generic_poweroff - Generic poweroff callback for subsystems. 191 * pm_generic_poweroff - Generic poweroff callback for subsystems.
191 * @dev: Device to handle. 192 * @dev: Device to handle.
192 */ 193 */
193int pm_generic_poweroff(struct device *dev) 194int pm_generic_poweroff(struct device *dev)
194{ 195{
195 return __pm_generic_call(dev, PM_EVENT_HIBERNATE, false); 196 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
197
198 return pm && pm->poweroff ? pm->poweroff(dev) : 0;
196} 199}
197EXPORT_SYMBOL_GPL(pm_generic_poweroff); 200EXPORT_SYMBOL_GPL(pm_generic_poweroff);
198 201
@@ -202,17 +205,33 @@ EXPORT_SYMBOL_GPL(pm_generic_poweroff);
202 */ 205 */
203int pm_generic_thaw_noirq(struct device *dev) 206int pm_generic_thaw_noirq(struct device *dev)
204{ 207{
205 return __pm_generic_call(dev, PM_EVENT_THAW, true); 208 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
209
210 return pm && pm->thaw_noirq ? pm->thaw_noirq(dev) : 0;
206} 211}
207EXPORT_SYMBOL_GPL(pm_generic_thaw_noirq); 212EXPORT_SYMBOL_GPL(pm_generic_thaw_noirq);
208 213
209/** 214/**
215 * pm_generic_thaw_early - Generic thaw_early callback for subsystems.
216 * @dev: Device to thaw.
217 */
218int pm_generic_thaw_early(struct device *dev)
219{
220 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
221
222 return pm && pm->thaw_early ? pm->thaw_early(dev) : 0;
223}
224EXPORT_SYMBOL_GPL(pm_generic_thaw_early);
225
226/**
210 * pm_generic_thaw - Generic thaw callback for subsystems. 227 * pm_generic_thaw - Generic thaw callback for subsystems.
211 * @dev: Device to thaw. 228 * @dev: Device to thaw.
212 */ 229 */
213int pm_generic_thaw(struct device *dev) 230int pm_generic_thaw(struct device *dev)
214{ 231{
215 return __pm_generic_call(dev, PM_EVENT_THAW, false); 232 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
233
234 return pm && pm->thaw ? pm->thaw(dev) : 0;
216} 235}
217EXPORT_SYMBOL_GPL(pm_generic_thaw); 236EXPORT_SYMBOL_GPL(pm_generic_thaw);
218 237
@@ -222,17 +241,33 @@ EXPORT_SYMBOL_GPL(pm_generic_thaw);
222 */ 241 */
223int pm_generic_resume_noirq(struct device *dev) 242int pm_generic_resume_noirq(struct device *dev)
224{ 243{
225 return __pm_generic_call(dev, PM_EVENT_RESUME, true); 244 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
245
246 return pm && pm->resume_noirq ? pm->resume_noirq(dev) : 0;
226} 247}
227EXPORT_SYMBOL_GPL(pm_generic_resume_noirq); 248EXPORT_SYMBOL_GPL(pm_generic_resume_noirq);
228 249
229/** 250/**
251 * pm_generic_resume_early - Generic resume_early callback for subsystems.
252 * @dev: Device to resume.
253 */
254int pm_generic_resume_early(struct device *dev)
255{
256 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
257
258 return pm && pm->resume_early ? pm->resume_early(dev) : 0;
259}
260EXPORT_SYMBOL_GPL(pm_generic_resume_early);
261
262/**
230 * pm_generic_resume - Generic resume callback for subsystems. 263 * pm_generic_resume - Generic resume callback for subsystems.
231 * @dev: Device to resume. 264 * @dev: Device to resume.
232 */ 265 */
233int pm_generic_resume(struct device *dev) 266int pm_generic_resume(struct device *dev)
234{ 267{
235 return __pm_generic_call(dev, PM_EVENT_RESUME, false); 268 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
269
270 return pm && pm->resume ? pm->resume(dev) : 0;
236} 271}
237EXPORT_SYMBOL_GPL(pm_generic_resume); 272EXPORT_SYMBOL_GPL(pm_generic_resume);
238 273
@@ -242,17 +277,33 @@ EXPORT_SYMBOL_GPL(pm_generic_resume);
242 */ 277 */
243int pm_generic_restore_noirq(struct device *dev) 278int pm_generic_restore_noirq(struct device *dev)
244{ 279{
245 return __pm_generic_call(dev, PM_EVENT_RESTORE, true); 280 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
281
282 return pm && pm->restore_noirq ? pm->restore_noirq(dev) : 0;
246} 283}
247EXPORT_SYMBOL_GPL(pm_generic_restore_noirq); 284EXPORT_SYMBOL_GPL(pm_generic_restore_noirq);
248 285
249/** 286/**
287 * pm_generic_restore_early - Generic restore_early callback for subsystems.
288 * @dev: Device to resume.
289 */
290int pm_generic_restore_early(struct device *dev)
291{
292 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
293
294 return pm && pm->restore_early ? pm->restore_early(dev) : 0;
295}
296EXPORT_SYMBOL_GPL(pm_generic_restore_early);
297
298/**
250 * pm_generic_restore - Generic restore callback for subsystems. 299 * pm_generic_restore - Generic restore callback for subsystems.
251 * @dev: Device to restore. 300 * @dev: Device to restore.
252 */ 301 */
253int pm_generic_restore(struct device *dev) 302int pm_generic_restore(struct device *dev)
254{ 303{
255 return __pm_generic_call(dev, PM_EVENT_RESTORE, false); 304 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
305
306 return pm && pm->restore ? pm->restore(dev) : 0;
256} 307}
257EXPORT_SYMBOL_GPL(pm_generic_restore); 308EXPORT_SYMBOL_GPL(pm_generic_restore);
258 309