PM: Split up sysdev_[suspend|resume] from device_power_[down|up]

Move the sysdev_suspend/resume from the callee to the callers, with
no real change in semantics, so that we can rework the disabling of
interrupts during suspend/hibernation.

This is based on an earlier patch from Linus.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by Rafael J. Wysocki and committed by Linus Torvalds 770824bd 936577c6

+38 -7
+4
arch/x86/kernel/apm_32.c
··· 1192 1192 device_suspend(PMSG_SUSPEND); 1193 1193 local_irq_disable(); 1194 1194 device_power_down(PMSG_SUSPEND); 1195 + sysdev_suspend(PMSG_SUSPEND); 1195 1196 1196 1197 local_irq_enable(); 1197 1198 ··· 1209 1208 if (err != APM_SUCCESS) 1210 1209 apm_error("suspend", err); 1211 1210 err = (err == APM_SUCCESS) ? 0 : -EIO; 1211 + sysdev_resume(); 1212 1212 device_power_up(PMSG_RESUME); 1213 1213 local_irq_enable(); 1214 1214 device_resume(PMSG_RESUME); ··· 1230 1228 1231 1229 local_irq_disable(); 1232 1230 device_power_down(PMSG_SUSPEND); 1231 + sysdev_suspend(PMSG_SUSPEND); 1233 1232 local_irq_enable(); 1234 1233 1235 1234 err = set_system_power_state(APM_STATE_STANDBY); ··· 1238 1235 apm_error("standby", err); 1239 1236 1240 1237 local_irq_disable(); 1238 + sysdev_resume(); 1241 1239 device_power_up(PMSG_RESUME); 1242 1240 local_irq_enable(); 1243 1241 }
-2
drivers/base/base.h
··· 88 88 extern int driver_probe_device(struct device_driver *drv, struct device *dev); 89 89 90 90 extern void sysdev_shutdown(void); 91 - extern int sysdev_suspend(pm_message_t state); 92 - extern int sysdev_resume(void); 93 91 94 92 extern char *make_class_name(const char *name, struct kobject *kobj); 95 93
-3
drivers/base/power/main.c
··· 333 333 */ 334 334 void device_power_up(pm_message_t state) 335 335 { 336 - sysdev_resume(); 337 336 dpm_power_up(state); 338 337 } 339 338 EXPORT_SYMBOL_GPL(device_power_up); ··· 576 577 } 577 578 dev->power.status = DPM_OFF_IRQ; 578 579 } 579 - if (!error) 580 - error = sysdev_suspend(state); 581 580 if (error) 582 581 dpm_power_up(resume_event(state)); 583 582 return error;
+8
drivers/xen/manage.c
··· 45 45 err); 46 46 return err; 47 47 } 48 + err = sysdev_suspend(PMSG_SUSPEND); 49 + if (err) { 50 + printk(KERN_ERR "xen_suspend: sysdev_suspend failed: %d\n", 51 + err); 52 + device_power_up(PMSG_RESUME); 53 + return err; 54 + } 48 55 49 56 xen_mm_pin_all(); 50 57 gnttab_suspend(); ··· 68 61 gnttab_resume(); 69 62 xen_mm_unpin_all(); 70 63 64 + sysdev_resume(); 71 65 device_power_up(PMSG_RESUME); 72 66 73 67 if (!*cancelled) {
+2
include/linux/pm.h
··· 381 381 382 382 #ifdef CONFIG_PM_SLEEP 383 383 extern void device_pm_lock(void); 384 + extern int sysdev_resume(void); 384 385 extern void device_power_up(pm_message_t state); 385 386 extern void device_resume(pm_message_t state); 386 387 387 388 extern void device_pm_unlock(void); 389 + extern int sysdev_suspend(pm_message_t state); 388 390 extern int device_power_down(pm_message_t state); 389 391 extern int device_suspend(pm_message_t state); 390 392 extern int device_prepare_suspend(pm_message_t state);
+7
kernel/kexec.c
··· 1465 1465 error = device_power_down(PMSG_FREEZE); 1466 1466 if (error) 1467 1467 goto Enable_irqs; 1468 + 1469 + /* Suspend system devices */ 1470 + error = sysdev_suspend(PMSG_FREEZE); 1471 + if (error) 1472 + goto Power_up_devices; 1468 1473 } else 1469 1474 #endif 1470 1475 { ··· 1482 1477 1483 1478 #ifdef CONFIG_KEXEC_JUMP 1484 1479 if (kexec_image->preserve_context) { 1480 + sysdev_resume(); 1481 + Power_up_devices: 1485 1482 device_power_up(PMSG_RESTORE); 1486 1483 Enable_irqs: 1487 1484 local_irq_enable();
+11
kernel/power/disk.c
··· 227 227 "aborting hibernation\n"); 228 228 goto Enable_irqs; 229 229 } 230 + sysdev_suspend(PMSG_FREEZE); 231 + if (error) { 232 + printk(KERN_ERR "PM: Some devices failed to power down, " 233 + "aborting hibernation\n"); 234 + goto Power_up_devices; 235 + } 230 236 231 237 if (hibernation_test(TEST_CORE)) 232 238 goto Power_up; ··· 248 242 if (!in_suspend) 249 243 platform_leave(platform_mode); 250 244 Power_up: 245 + sysdev_resume(); 251 246 /* NOTE: device_power_up() is just a resume() for devices 252 247 * that suspended with irqs off ... no overall powerup. 253 248 */ 249 + Power_up_devices: 254 250 device_power_up(in_suspend ? 255 251 (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE); 256 252 Enable_irqs: ··· 343 335 "aborting resume\n"); 344 336 goto Enable_irqs; 345 337 } 338 + sysdev_suspend(PMSG_QUIESCE); 346 339 /* We'll ignore saved state, but this gets preempt count (etc) right */ 347 340 save_processor_state(); 348 341 error = restore_highmem(); ··· 366 357 swsusp_free(); 367 358 restore_processor_state(); 368 359 touch_softlockup_watchdog(); 360 + sysdev_resume(); 369 361 device_power_up(PMSG_RECOVER); 370 362 Enable_irqs: 371 363 local_irq_enable(); ··· 450 440 local_irq_disable(); 451 441 error = device_power_down(PMSG_HIBERNATE); 452 442 if (!error) { 443 + sysdev_suspend(PMSG_HIBERNATE); 453 444 hibernation_ops->enter(); 454 445 /* We should never get here */ 455 446 while (1);
+6 -2
kernel/power/main.c
··· 298 298 goto Done; 299 299 } 300 300 301 - if (!suspend_test(TEST_CORE)) 302 - error = suspend_ops->enter(state); 301 + error = sysdev_suspend(PMSG_SUSPEND); 302 + if (!error) { 303 + if (!suspend_test(TEST_CORE)) 304 + error = suspend_ops->enter(state); 305 + sysdev_resume(); 306 + } 303 307 304 308 device_power_up(PMSG_RESUME); 305 309 Done: