Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

PM: Introduce pm_power_off_prepare

Introduce the pm_power_off_prepare() callback that can be registered by the
interested platforms in analogy with pm_idle() and pm_power_off(), used for
preparing the system to power off (needed by ACPI).

This allows us to drop acpi_sysclass and device_acpi that are only defined in
order to register the ACPI power off preparation callback, which is needed by
pm_power_off() registered in a much different way.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Rafael J. Wysocki and committed by
Linus Torvalds
bd804eba d7372cdf

+19 -29
+9 -29
drivers/acpi/sleep/poweroff.c
··· 39 39 40 40 #ifdef CONFIG_PM 41 41 42 - void acpi_power_off(void) 42 + static void acpi_power_off_prepare(void) 43 + { 44 + /* Prepare to power off the system */ 45 + acpi_sleep_prepare(ACPI_STATE_S5); 46 + } 47 + 48 + static void acpi_power_off(void) 43 49 { 44 50 /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ 45 51 printk("%s called\n", __FUNCTION__); ··· 53 47 /* Some SMP machines only can poweroff in boot CPU */ 54 48 acpi_enter_sleep_state(ACPI_STATE_S5); 55 49 } 56 - 57 - static int acpi_shutdown(struct sys_device *x) 58 - { 59 - switch (system_state) { 60 - case SYSTEM_POWER_OFF: 61 - /* Prepare to power off the system */ 62 - return acpi_sleep_prepare(ACPI_STATE_S5); 63 - default: 64 - return 0; 65 - } 66 - } 67 - 68 - static struct sysdev_class acpi_sysclass = { 69 - set_kset_name("acpi"), 70 - .shutdown = acpi_shutdown 71 - }; 72 - 73 - static struct sys_device device_acpi = { 74 - .id = 0, 75 - .cls = &acpi_sysclass, 76 - }; 77 50 78 51 static int acpi_poweroff_init(void) 79 52 { ··· 63 78 status = 64 79 acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b); 65 80 if (ACPI_SUCCESS(status)) { 66 - int error; 67 - error = sysdev_class_register(&acpi_sysclass); 68 - if (!error) 69 - error = sysdev_register(&device_acpi); 70 - if (!error) 71 - pm_power_off = acpi_power_off; 72 - return error; 81 + pm_power_off_prepare = acpi_power_off_prepare; 82 + pm_power_off = acpi_power_off; 73 83 } 74 84 } 75 85 return 0;
+1
include/linux/pm.h
··· 101 101 */ 102 102 extern void (*pm_idle)(void); 103 103 extern void (*pm_power_off)(void); 104 + extern void (*pm_power_off_prepare)(void); 104 105 105 106 typedef int __bitwise suspend_state_t; 106 107
+9
kernel/sys.c
··· 100 100 EXPORT_SYMBOL(cad_pid); 101 101 102 102 /* 103 + * If set, this is used for preparing the system to power off. 104 + */ 105 + 106 + void (*pm_power_off_prepare)(void); 107 + EXPORT_SYMBOL(pm_power_off_prepare); 108 + 109 + /* 103 110 * Notifier list for kernel code which wants to be called 104 111 * at shutdown. This is used to stop any idling DMA operations 105 112 * and the like. ··· 874 867 void kernel_power_off(void) 875 868 { 876 869 kernel_shutdown_prepare(SYSTEM_POWER_OFF); 870 + if (pm_power_off_prepare) 871 + pm_power_off_prepare(); 877 872 printk(KERN_EMERG "Power down.\n"); 878 873 machine_power_off(); 879 874 }