Power off handling.

From: David Woodhouse (dwmw2@infradead.org)
Date: Mon Jan 10 2000 - 10:54:47 EST


This patch uses a notifier chain to register a list of functions which ought
to be able to power the machine down, and provides a generic
machine_power_off() routine which calls them in turn until one of them
succeeds.

This means that when both acpi and apm are present on a machine, it can
attempt both ways to power down.

It removes the unnecessary sysrq_power_off pointer, and sysrq-o now calls
machine_power_off instead.

Index: arch/alpha/kernel/process.c
===================================================================
RCS file: /cvs/linux/arch/alpha/kernel/process.c,v
retrieving revision 1.3.2.6
diff -u -r1.3.2.6 process.c
--- arch/alpha/kernel/process.c 1999/12/17 17:22:28 1.3.2.6
+++ arch/alpha/kernel/process.c 2000/01/10 15:37:55
@@ -173,7 +173,7 @@
 }
 
 void
-machine_power_off(void)
+alpha_power_off(void)
 {
         common_shutdown(LINUX_REBOOT_CMD_POWER_OFF, NULL);
 }
Index: arch/alpha/kernel/setup.c
===================================================================
RCS file: /cvs/linux/arch/alpha/kernel/setup.c,v
retrieving revision 1.2.2.5
diff -u -r1.2.2.5 setup.c
--- arch/alpha/kernel/setup.c 1999/12/17 17:22:28 1.2.2.5
+++ arch/alpha/kernel/setup.c 2000/01/10 15:37:56
@@ -29,6 +29,7 @@
 #include <linux/string.h>
 #include <linux/ioport.h>
 #include <linux/bootmem.h>
+#include <linux/notifier.h>
 
 #ifdef CONFIG_RTC
 #include <linux/timex.h>
@@ -96,7 +97,14 @@
         orig_video_points: 16
 };
 
+extern void alpha_power_off(void);
 
+static struct notifier_block alpha_poweroff_block = {
+ alpha_power_off,
+ NULL,
+ 0
+};
+
 /*
  * Declare all of the machine vectors.
  */
@@ -505,6 +513,8 @@
 #ifdef __SMP__
         setup_smp();
 #endif
+
+ register_poweroff_handler(&alpha_poweroff_block);
 }
 
 static char sys_unknown[] = "Unknown";
Index: arch/arm/kernel/process.c
===================================================================
RCS file: /cvs/linux/arch/arm/kernel/process.c,v
retrieving revision 1.2.2.6
diff -u -r1.2.2.6 process.c
--- arch/arm/kernel/process.c 1999/12/17 17:22:29 1.2.2.6
+++ arch/arm/kernel/process.c 2000/01/10 15:37:56
@@ -112,10 +112,6 @@
 {
 }
 
-void machine_power_off(void)
-{
-}
-
 void show_regs(struct pt_regs * regs)
 {
         unsigned long flags;
Index: arch/i386/kernel/acpi.c
===================================================================
RCS file: /cvs/linux/arch/i386/kernel/Attic/acpi.c,v
retrieving revision 1.1.2.3
diff -u -r1.1.2.3 acpi.c
--- arch/i386/kernel/acpi.c 2000/01/09 16:38:12 1.1.2.3
+++ arch/i386/kernel/acpi.c 2000/01/10 15:37:56
@@ -40,6 +40,7 @@
 #include <linux/sysctl.h>
 #include <linux/delay.h>
 #include <linux/acpi.h>
+#include <linux/notifier.h>
 
 /*
  * Defines for 2.2.x
@@ -886,6 +887,13 @@
         acpi_enter_sx(ACPI_S5);
 }
 
+static struct notifier_block acpi_power_off_handler_block =
+{
+ acpi_power_off_handler,
+ NULL,
+ 0
+};
+
 /*
  * Claim ACPI I/O ports
  */
@@ -1211,9 +1219,8 @@
         pid = kernel_thread(acpi_control_thread,
                             NULL,
                             CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
-
- acpi_power_off = acpi_power_off_handler;
 
+ register_poweroff_handler(&acpi_power_off_handler_block);
         acpi_active = 1;
 
         /*
@@ -1238,7 +1245,7 @@
 static void __exit acpi_exit(void)
 {
         acpi_idle = NULL;
- acpi_power_off = NULL;
+ unregister_poweroff_handler(&acpi_power_off_handler_block);
 
         unregister_sysctl_table(acpi_sysctl);
         acpi_disable(acpi_facp);
Index: arch/i386/kernel/apm.c
===================================================================
RCS file: /cvs/linux/arch/i386/kernel/apm.c,v
retrieving revision 1.1.1.5.2.14
diff -u -r1.1.1.5.2.14 apm.c
--- arch/i386/kernel/apm.c 2000/01/09 16:28:52 1.1.1.5.2.14
+++ arch/i386/kernel/apm.c 2000/01/10 15:37:56
@@ -145,6 +145,7 @@
 #include <linux/apm_bios.h>
 #include <linux/init.h>
 #include <linux/sched.h>
+#include <linux/notifier.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -161,9 +162,6 @@
 extern unsigned long get_cmos_time(void);
 extern void machine_real_restart(unsigned char *, int);
 
-#ifdef CONFIG_MAGIC_SYSRQ
-extern void (*sysrq_power_off)(void);
-#endif
 #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
 extern int (*console_blank_hook)(int);
 #endif
@@ -557,7 +555,7 @@
 }
 #endif
 
-static void apm_power_off(void)
+static void apm_power_off_handler(void)
 {
         /*
          * smp_hack == 2 means that we would have enabled APM support
@@ -586,6 +584,13 @@
         }
 }
 
+static struct notifier_block apm_power_off_handler_block =
+{
+ apm_power_off_handler,
+ NULL,
+ 0
+};
+
 #ifdef CONFIG_APM_DO_ENABLE
 static int __init apm_enable_power_management(void)
 {
@@ -1373,10 +1378,8 @@
 
         /* Install our power off handler.. */
         if (power_off_enabled)
- acpi_power_off = apm_power_off;
-#ifdef CONFIG_MAGIC_SYSRQ
- sysrq_power_off = apm_power_off;
-#endif
+ register_poweroff_handler(&apm_power_off_handler_block);
+
 #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
         console_blank_hook = apm_console_blank;
 #endif
@@ -1491,13 +1494,6 @@
                 APM_INIT_ERROR_RETURN;
         }
 
-#ifdef CONFIG_ACPI
- if (acpi_active) {
- printk(KERN_NOTICE "apm: overridden by ACPI.\n");
- APM_INIT_ERROR_RETURN;
- }
-#endif
-
         /*
          * Set up a segment that references the real mode segment 0x40
          * that extends up to the end of page zero (that we have reserved).
@@ -1544,11 +1540,24 @@
 #ifdef CONFIG_SMP
         if (smp_num_cpus > 1) {
                 printk(KERN_NOTICE "apm: disabled - APM is not SMP safe.\n");
- if (smp_hack)
+ if (smp_hack) {
                         smp_hack = 2;
+ register_poweroff_handler(&apm_power_off_handler_block);
+ }
                 APM_INIT_ERROR_RETURN;
         }
 #endif
+#ifdef CONFIG_ACPI
+ if (acpi_active) {
+ printk(KERN_NOTICE "apm: overridden by ACPI.\n");
+
+ /* Let the poweroff handler remain - sometimes the ACPI
+ * one doesn't work */
+ register_poweroff_handler(&apm_power_off_handler_block);
+ APM_INIT_ERROR_RETURN;
+ }
+#endif
+
 
         create_proc_info_entry("apm", 0, 0, apm_get_info);
 
Index: arch/i386/kernel/i386_ksyms.c
===================================================================
RCS file: /cvs/linux/arch/i386/kernel/i386_ksyms.c,v
retrieving revision 1.2.2.10
diff -u -r1.2.2.10 i386_ksyms.c
--- arch/i386/kernel/i386_ksyms.c 2000/01/09 16:28:52 1.2.2.10
+++ arch/i386/kernel/i386_ksyms.c 2000/01/10 15:37:56
@@ -50,7 +50,6 @@
 EXPORT_SYMBOL(disable_irq_nosync);
 EXPORT_SYMBOL(kernel_thread);
 EXPORT_SYMBOL(acpi_idle);
-EXPORT_SYMBOL(acpi_power_off);
 
 EXPORT_SYMBOL_NOVERS(__down_failed);
 EXPORT_SYMBOL_NOVERS(__down_failed_interruptible);
Index: arch/i386/kernel/process.c
===================================================================
RCS file: /cvs/linux/arch/i386/kernel/process.c,v
retrieving revision 1.2.2.10
diff -u -r1.2.2.10 process.c
--- arch/i386/kernel/process.c 2000/01/05 17:07:37 1.2.2.10
+++ arch/i386/kernel/process.c 2000/01/10 15:37:56
@@ -64,11 +64,6 @@
 void (*acpi_idle)(void) = NULL;
 
 /*
- * Power off function, if any
- */
-void (*acpi_power_off)(void) = NULL;
-
-/*
  * We use this if we don't have any better
  * idle routine..
  */
@@ -325,13 +320,6 @@
 void machine_halt(void)
 {
 }
-
-void machine_power_off(void)
-{
- if (acpi_power_off)
- acpi_power_off();
-}
-
 
 void show_regs(struct pt_regs * regs)
 {
Index: arch/m68k/kernel/process.c
===================================================================
RCS file: /cvs/linux/arch/m68k/kernel/process.c,v
retrieving revision 1.3.2.4
diff -u -r1.3.2.4 process.c
--- arch/m68k/kernel/process.c 1999/11/12 15:30:37 1.3.2.4
+++ arch/m68k/kernel/process.c 2000/01/10 15:37:57
@@ -100,13 +100,6 @@
         for (;;);
 }
 
-void machine_power_off(void)
-{
- if (mach_power_off)
- mach_power_off();
- for (;;);
-}
-
 void show_regs(struct pt_regs * regs)
 {
         printk("\n");
Index: arch/m68k/kernel/setup.c
===================================================================
RCS file: /cvs/linux/arch/m68k/kernel/setup.c,v
retrieving revision 1.2.2.3
diff -u -r1.2.2.3 setup.c
--- arch/m68k/kernel/setup.c 1999/10/07 15:59:13 1.2.2.3
+++ arch/m68k/kernel/setup.c 2000/01/10 15:37:57
@@ -78,7 +78,6 @@
 int (*mach_set_clock_mmss) (unsigned long) = NULL;
 void (*mach_reset)( void );
 void (*mach_halt)( void ) = NULL;
-void (*mach_power_off)( void ) = NULL;
 long mach_max_dma_address = 0x00ffffff; /* default set to the lower 16MB */
 #if defined(CONFIG_AMIGA_FLOPPY) || defined(CONFIG_ATARI_FLOPPY) || defined(CONFIG_BLK_DEV_FD)
 void (*mach_floppy_setup) (char *, int *) __initdata = NULL;
Index: arch/m68k/mac/config.c
===================================================================
RCS file: /cvs/linux/arch/m68k/mac/config.c,v
retrieving revision 1.1.1.9.2.2
diff -u -r1.1.1.9.2.2 config.c
--- arch/m68k/mac/config.c 1999/10/07 15:59:13 1.1.1.9.2.2
+++ arch/m68k/mac/config.c 2000/01/10 15:37:57
@@ -17,6 +17,7 @@
 #include <linux/tty.h>
 #include <linux/console.h>
 #include <linux/interrupt.h>
+#include <linux/notifier.h>
 /* keyb */
 #include <linux/random.h>
 #include <linux/delay.h>
@@ -105,6 +106,13 @@
 extern void adb_poweroff(void);
 extern void adb_hwreset(void);
 
+static struct notifier_block mac_poweroff_block = {
+ mac_poweroff,
+ NULL,
+ 0
+};
+
+
 /* pram functions */
 extern __u32 via_read_time(void);
 extern void via_write_time(__u32);
@@ -423,7 +431,7 @@
 #endif
     mach_reset = mac_reset;
     mach_halt = mac_poweroff;
- mach_power_off = mac_poweroff;
+ register_poweroff_handler(&mac_poweroff_block);
     conswitchp = &dummy_con;
     mach_max_dma_address = 0xffffffff;
 #if 0
Index: arch/mips/baget/setup.c
===================================================================
RCS file: /cvs/linux/arch/mips/baget/setup.c,v
retrieving revision 1.3.2.2
diff -u -r1.3.2.2 setup.c
--- arch/mips/baget/setup.c 1999/10/07 15:43:09 1.3.2.2
+++ arch/mips/baget/setup.c 2000/01/10 15:37:58
@@ -474,7 +474,13 @@
 extern void baget_machine_restart(char *command);
 extern void baget_machine_halt(void);
 extern void baget_machine_power_off(void);
-
+
+static struct notifier_struct baget_poweroff_block = {
+ baget_machine_power_off,
+ NULL,
+ 0
+};
+
 void __init baget_setup(void)
 {
         printk("BT23/63-201n found.\n");
@@ -485,7 +491,7 @@
 
         _machine_restart = baget_machine_restart;
         _machine_halt = baget_machine_halt;
- _machine_power_off = baget_machine_power_off;
+ register_poweroff_handler(&baget_poweroff_block);
 
         vac_init();
         vic_init();
Index: arch/mips/dec/setup.c
===================================================================
RCS file: /cvs/linux/arch/mips/dec/setup.c,v
retrieving revision 1.3.2.2
diff -u -r1.3.2.2 setup.c
--- arch/mips/dec/setup.c 1999/10/07 15:43:09 1.3.2.2
+++ arch/mips/dec/setup.c 2000/01/10 15:37:58
@@ -14,6 +14,7 @@
 #include <asm/mipsregs.h>
 #include <asm/bootinfo.h>
 #include <linux/init.h>
+#include <linux/notifier.h>
 #include <asm/irq.h>
 #include <asm/reboot.h>
 
@@ -50,6 +51,12 @@
 extern void dec_machine_halt(void);
 extern void dec_machine_power_off(void);
 
+static struct notifier_struct dec_poweroff_block = {
+ dec_machine_power_off,
+ NULL,
+ 0
+};
+
 extern void wbflush_setup(void);
 
 extern struct rtc_ops dec_rtc_ops;
@@ -121,7 +128,7 @@
 
     _machine_restart = dec_machine_restart;
     _machine_halt = dec_machine_halt;
- _machine_power_off = dec_machine_power_off;
+ register_poweroff_handler(&dec_poweroff_block);
 
     rtc_ops = &dec_rtc_ops;
 }
Index: arch/mips/jazz/setup.c
===================================================================
RCS file: /cvs/linux/arch/mips/jazz/setup.c,v
retrieving revision 1.1.1.3.2.2
diff -u -r1.1.1.3.2.2 setup.c
--- arch/mips/jazz/setup.c 1999/10/07 15:43:09 1.1.1.3.2.2
+++ arch/mips/jazz/setup.c 2000/01/10 15:37:58
@@ -17,6 +17,7 @@
 #include <linux/mm.h>
 #include <linux/console.h>
 #include <linux/fb.h>
+#include <linux/notifier.h>
 #include <linux/mc146818rtc.h>
 #include <asm/bootinfo.h>
 #include <asm/keyboard.h>
@@ -44,6 +45,12 @@
 extern void jazz_machine_halt(void);
 extern void jazz_machine_power_off(void);
 
+static struct notifier_struct jazz_poweroff_block = {
+ jazz_machine_power_off,
+ NULL,
+ 0
+};
+
 extern struct ide_ops std_ide_ops;
 extern struct rtc_ops jazz_rtc_ops;
 extern struct kbd_ops jazz_kbd_ops;
@@ -97,7 +104,7 @@
 
         _machine_restart = jazz_machine_restart;
         _machine_halt = jazz_machine_halt;
- _machine_power_off = jazz_machine_power_off;
+ register_poweroff_handler(&jazz_poweroff_block);
 
 #ifdef CONFIG_BLK_DEV_IDE
         ide_ops = &std_ide_ops;
Index: arch/mips/kernel/reset.c
===================================================================
RCS file: /cvs/linux/arch/mips/kernel/reset.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 reset.c
--- arch/mips/kernel/reset.c 1998/10/28 21:24:22 1.1.1.1
+++ arch/mips/kernel/reset.c 2000/01/10 15:37:58
@@ -23,8 +23,3 @@
 {
         _machine_halt();
 }
-
-void machine_power_off(void)
-{
- _machine_power_off();
-}
Index: arch/mips/sni/setup.c
===================================================================
RCS file: /cvs/linux/arch/mips/sni/setup.c,v
retrieving revision 1.1.1.3.2.3
diff -u -r1.1.1.3.2.3 setup.c
--- arch/mips/sni/setup.c 1999/10/11 12:13:09 1.1.1.3.2.3
+++ arch/mips/sni/setup.c 2000/01/10 15:37:58
@@ -21,6 +21,7 @@
 #include <linux/console.h>
 #include <linux/fb.h>
 #include <linux/pc_keyb.h>
+#include <linux/notifier.h>
 
 #include <asm/bcache.h>
 #include <asm/bootinfo.h>
@@ -48,6 +49,12 @@
 extern void sni_machine_halt(void);
 extern void sni_machine_power_off(void);
 
+static struct notifier_struct sni_poweroff_block = {
+ sni_machine_power_off,
+ NULL,
+ 0
+};
+
 extern struct ide_ops std_ide_ops;
 extern struct rtc_ops std_rtc_ops;
 extern struct kbd_ops std_kbd_ops;
@@ -154,7 +161,7 @@
 
         _machine_restart = sni_machine_restart;
         _machine_halt = sni_machine_halt;
- _machine_power_off = sni_machine_power_off;
+ register_poweroff_handler(&sni_poweroff_block);
 
         aux_device_present = 0xaa;
 
Index: arch/ppc/kernel/apus_setup.c
===================================================================
RCS file: /cvs/linux/arch/ppc/kernel/apus_setup.c,v
retrieving revision 1.2.2.6
diff -u -r1.2.2.6 apus_setup.c
--- arch/ppc/kernel/apus_setup.c 1999/11/09 09:52:44 1.2.2.6
+++ arch/ppc/kernel/apus_setup.c 2000/01/10 15:37:59
@@ -640,12 +640,6 @@
 }
 
 void
-apus_power_off(void)
-{
- for (;;);
-}
-
-void
 apus_halt(void)
 {
    apus_restart(NULL);
@@ -962,7 +956,6 @@
         ppc_md.init = NULL;
 
         ppc_md.restart = apus_restart;
- ppc_md.power_off = apus_power_off;
         ppc_md.halt = apus_halt;
 
         ppc_md.time_init = NULL;
Index: arch/ppc/kernel/chrp_setup.c
===================================================================
RCS file: /cvs/linux/arch/ppc/kernel/chrp_setup.c,v
retrieving revision 1.2.2.11
diff -u -r1.2.2.11 chrp_setup.c
--- arch/ppc/kernel/chrp_setup.c 2000/01/05 17:25:10 1.2.2.11
+++ arch/ppc/kernel/chrp_setup.c 2000/01/10 15:37:59
@@ -36,6 +36,7 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/ide.h>
+#include <linux/notifier.h>
 
 #include <asm/mmu.h>
 #include <asm/processor.h>
@@ -332,9 +333,14 @@
         /* allow power on only with power button press */
         printk("RTAS power-off returned %d\n",
                call_rtas("power-off", 2, 1, NULL,0xffffffff,0xffffffff));
- for (;;);
 }
 
+static struct notifier_block chrp_poweroff_block = {
+ chrp_power_off,
+ NULL,
+ 0
+};
+
 void
 chrp_halt(void)
 {
@@ -566,7 +572,7 @@
         ppc_md.init = chrp_init2;
 
         ppc_md.restart = chrp_restart;
- ppc_md.power_off = chrp_power_off;
+ register_poweroff_handler(&chrp_poweroff_block);
         ppc_md.halt = chrp_halt;
 
         ppc_md.time_init = chrp_time_init;
Index: arch/ppc/kernel/gemini_setup.c
===================================================================
RCS file: /cvs/linux/arch/ppc/kernel/gemini_setup.c,v
retrieving revision 1.1.2.9
diff -u -r1.1.2.9 gemini_setup.c
--- arch/ppc/kernel/gemini_setup.c 2000/01/05 17:25:10 1.1.2.9
+++ arch/ppc/kernel/gemini_setup.c 2000/01/10 15:37:59
@@ -314,12 +314,6 @@
 }
 
 void
-gemini_power_off(void)
-{
- for(;;);
-}
-
-void
 gemini_halt(void)
 {
         gemini_restart(NULL);
@@ -550,7 +544,6 @@
         ppc_md.init = NULL;
 
         ppc_md.restart = gemini_restart;
- ppc_md.power_off = gemini_power_off;
         ppc_md.halt = gemini_halt;
 
         ppc_md.time_init = gemini_time_init;
Index: arch/ppc/kernel/m8xx_setup.c
===================================================================
RCS file: /cvs/linux/arch/ppc/kernel/Attic/m8xx_setup.c,v
retrieving revision 1.1.2.3
diff -u -r1.1.2.3 m8xx_setup.c
--- arch/ppc/kernel/m8xx_setup.c 2000/01/05 17:25:10 1.1.2.3
+++ arch/ppc/kernel/m8xx_setup.c 2000/01/10 15:37:59
@@ -34,6 +34,7 @@
 #include <linux/ioport.h>
 #include <linux/ide.h>
 #include <linux/bootmem.h>
+#include <linux/notifier.h>
 
 #include <asm/mmu.h>
 #include <asm/processor.h>
@@ -237,17 +238,16 @@
 }
 
 void
-m8xx_power_off(void)
-{
- m8xx_restart(NULL);
-}
-
-void
 m8xx_halt(void)
 {
    m8xx_restart(NULL);
 }
 
+static struct notifier_block m8xx_poweroff_block = {
+ m8xx_halt,
+ NULL,
+ 0
+};
 
 int m8xx_setup_residual(char *buffer)
 {
@@ -477,7 +477,7 @@
         ppc_md.init = NULL;
 
         ppc_md.restart = m8xx_restart;
- ppc_md.power_off = m8xx_power_off;
+ register_poweroff_handler(&m8xx_poweroff_block);
         ppc_md.halt = m8xx_halt;
 
         ppc_md.time_init = NULL;
Index: arch/ppc/kernel/oak_setup.c
===================================================================
RCS file: /cvs/linux/arch/ppc/kernel/Attic/oak_setup.c,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 oak_setup.c
--- arch/ppc/kernel/oak_setup.c 1999/12/17 17:22:30 1.1.2.1
+++ arch/ppc/kernel/oak_setup.c 2000/01/10 15:37:59
@@ -55,7 +55,6 @@
         ppc_md.init = NULL;
 
         ppc_md.restart = NULL;
- ppc_md.power_off = NULL;
         ppc_md.halt = NULL;
 
         ppc_md.time_init = NULL;
Index: arch/ppc/kernel/pmac_setup.c
===================================================================
RCS file: /cvs/linux/arch/ppc/kernel/pmac_setup.c,v
retrieving revision 1.2.2.11
diff -u -r1.2.2.11 pmac_setup.c
--- arch/ppc/kernel/pmac_setup.c 2000/01/09 16:38:13 1.2.2.11
+++ arch/ppc/kernel/pmac_setup.c 2000/01/10 15:37:59
@@ -46,6 +46,7 @@
 #include <linux/adb.h>
 #include <linux/cuda.h>
 #include <linux/pmu.h>
+#include <linux/notifier.h>
 
 #include <asm/init.h>
 #include <asm/prom.h>
@@ -521,6 +522,12 @@
         }
 }
 
+static struct notifier_block pmac_poweroff_block = {
+ pmac_power_off,
+ NULL,
+ 0
+};
+
 void
 pmac_halt(void)
 {
@@ -627,7 +634,7 @@
         ppc_md.init = pmac_init2;
 
         ppc_md.restart = pmac_restart;
- ppc_md.power_off = pmac_power_off;
+ register_poweroff_handler(&pmac_poweroff_block);
         ppc_md.halt = pmac_halt;
 
         ppc_md.time_init = NULL;
Index: arch/ppc/kernel/prep_setup.c
===================================================================
RCS file: /cvs/linux/arch/ppc/kernel/prep_setup.c,v
retrieving revision 1.2.2.10
diff -u -r1.2.2.10 prep_setup.c
--- arch/ppc/kernel/prep_setup.c 2000/01/05 17:25:10 1.2.2.10
+++ arch/ppc/kernel/prep_setup.c 2000/01/10 15:37:59
@@ -34,6 +34,7 @@
 #include <linux/pci.h>
 #include <linux/openpic.h>
 #include <linux/ide.h>
+#include <linux/notifier.h>
 
 #include <asm/init.h>
 #include <asm/mmu.h>
@@ -555,6 +556,12 @@
         prep_halt();
 }
 
+static struct notifier_block prep_poweroff_block = {
+ prep_power_off,
+ NULL,
+ 0
+};
+
 int __prep
 prep_setup_residual(char *buffer)
 {
@@ -770,7 +777,7 @@
         ppc_md.init = NULL;
 
         ppc_md.restart = prep_restart;
- ppc_md.power_off = prep_power_off;
+ register_poweroff_handler(&prep_poweroff_block);
         ppc_md.halt = prep_halt;
 
         ppc_md.time_init = NULL;
Index: arch/ppc/kernel/setup.c
===================================================================
RCS file: /cvs/linux/arch/ppc/kernel/setup.c,v
retrieving revision 1.2.2.13
diff -u -r1.2.2.13 setup.c
--- arch/ppc/kernel/setup.c 1999/12/17 17:22:30 1.2.2.13
+++ arch/ppc/kernel/setup.c 2000/01/10 15:37:59
@@ -149,11 +149,6 @@
         ppc_md.restart(cmd);
 }
   
-void machine_power_off(void)
-{
- ppc_md.power_off();
-}
-
 void machine_halt(void)
 {
         ppc_md.halt();
Index: arch/sh/kernel/process.c
===================================================================
RCS file: /cvs/linux/arch/sh/kernel/Attic/process.c,v
retrieving revision 1.1.2.4
diff -u -r1.1.2.4 process.c
--- arch/sh/kernel/process.c 1999/11/09 09:52:45 1.1.2.4
+++ arch/sh/kernel/process.c 2000/01/10 15:38:00
@@ -90,10 +90,6 @@
 {
 }
 
-void machine_power_off(void)
-{
-}
-
 void show_regs(struct pt_regs * regs)
 {
         printk("\n");
Index: arch/sparc/kernel/process.c
===================================================================
RCS file: /cvs/linux/arch/sparc/kernel/process.c,v
retrieving revision 1.3.2.5
diff -u -r1.3.2.5 process.c
--- arch/sparc/kernel/process.c 2000/01/05 17:36:13 1.3.2.5
+++ arch/sparc/kernel/process.c 2000/01/10 15:38:00
@@ -166,7 +166,7 @@
         panic("Reboot failed!");
 }
 
-void machine_power_off(void)
+void sparc_power_off(void)
 {
 #ifdef CONFIG_SUN_AUXIO
         if (auxio_power_register)
Index: arch/sparc/kernel/setup.c
===================================================================
RCS file: /cvs/linux/arch/sparc/kernel/setup.c,v
retrieving revision 1.2.2.5
diff -u -r1.2.2.5 setup.c
--- arch/sparc/kernel/setup.c 2000/01/05 17:25:10 1.2.2.5
+++ arch/sparc/kernel/setup.c 2000/01/10 15:38:00
@@ -27,6 +27,7 @@
 #include <linux/interrupt.h>
 #include <linux/console.h>
 #include <linux/spinlock.h>
+#include <linux/notifier.h>
 
 #include <asm/segment.h>
 #include <asm/system.h>
@@ -57,6 +58,14 @@
         16 /* orig-video-points */
 };
 
+extern void sparc_power_off(void);
+
+static struct notifier_block sparc_poweroff_block = {
+ sparc_power_off,
+ NULL,
+ 0
+};
+
 unsigned int phys_bytes_of_ram, end_of_phys_memory;
 
 /* Typing sync at the prom prompt calls the function pointed to by
@@ -491,6 +500,8 @@
 
         if (serial_console)
                 conswitchp = NULL;
+
+ register_poweroff_handler(&sparc_poweroff_block);
 }
 
 asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on)
Index: arch/sparc64/kernel/power.c
===================================================================
RCS file: /cvs/linux/arch/sparc64/kernel/power.c,v
retrieving revision 1.1.2.3
diff -u -r1.1.2.3 power.c
--- arch/sparc64/kernel/power.c 2000/01/05 17:25:11 1.1.2.3
+++ arch/sparc64/kernel/power.c 2000/01/10 15:38:00
@@ -35,7 +35,7 @@
 
 extern void machine_halt(void);
 
-void machine_power_off(void)
+void sparc64_power_off(void)
 {
 #ifdef CONFIG_PCI
         if (power_reg != 0UL) {
Index: arch/sparc64/kernel/setup.c
===================================================================
RCS file: /cvs/linux/arch/sparc64/kernel/setup.c,v
retrieving revision 1.2.2.4
diff -u -r1.2.2.4 setup.c
--- arch/sparc64/kernel/setup.c 2000/01/05 17:25:11 1.2.2.4
+++ arch/sparc64/kernel/setup.c 2000/01/10 15:38:01
@@ -27,6 +27,7 @@
 #include <linux/init.h>
 #include <linux/inet.h>
 #include <linux/console.h>
+#include <linux/notifier.h>
 
 #include <asm/segment.h>
 #include <asm/system.h>
@@ -56,6 +57,14 @@
         16 /* orig-video-points */
 };
 
+extern void sparc64_power_off(void);
+
+static struct notifier_block sparc64_poweroff_block = {
+ sparc64_power_off,
+ NULL,
+ 0
+};
+
 /* Typing sync at the prom prompt calls the function pointed to by
  * the sync callback which I set to the following function.
  * This should sync all filesystems and return, for now it just
@@ -587,6 +596,8 @@
 #endif
         if (serial_console)
                 conswitchp = NULL;
+
+ register_poweroff_handler(&sparc64_poweroff_block);
 }
 
 asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on)
Index: drivers/char/sysrq.c
===================================================================
RCS file: /cvs/linux/drivers/char/sysrq.c,v
retrieving revision 1.1.1.6.2.2
diff -u -r1.1.1.6.2.2 sysrq.c
--- drivers/char/sysrq.c 1999/11/09 09:52:47 1.1.1.6.2.2
+++ drivers/char/sysrq.c 2000/01/10 15:38:01
@@ -29,9 +29,6 @@
 extern int console_loglevel;
 extern struct vfsmount *vfsmntlist;
 
-/* Machine specific power off function */
-void (*sysrq_power_off)(void) = NULL;
-
 /* Send a signal to all user processes */
 
 static void send_sig_all(int sig, int even_init)
@@ -88,10 +85,8 @@
                 machine_restart(NULL);
                 break;
         case 'o': /* O -- power off */
- if (sysrq_power_off) {
- printk("Power off\n");
- sysrq_power_off();
- }
+ printk("Power off\n");
+ machine_power_off();
                 break;
         case 's': /* S -- emergency sync */
                 printk("Emergency Sync\n");
Index: include/linux/acpi.h
===================================================================
RCS file: /cvs/linux/include/linux/Attic/acpi.h,v
retrieving revision 1.1.2.11
diff -u -r1.1.2.11 acpi.h
--- include/linux/acpi.h 2000/01/09 16:28:56 1.1.2.11
+++ include/linux/acpi.h 2000/01/10 15:38:09
@@ -191,7 +191,6 @@
 #endif /* CONFIG_ACPI */
 
 extern void (*acpi_idle)(void);
-extern void (*acpi_power_off)(void);
 
 #endif /* __KERNEL__ */
 
Index: include/linux/reboot.h
===================================================================
RCS file: /cvs/linux/include/linux/reboot.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 reboot.h
--- include/linux/reboot.h 1998/10/28 21:23:47 1.1.1.1
+++ include/linux/reboot.h 2000/01/10 15:38:10
@@ -37,6 +37,9 @@
 extern struct notifier_block *reboot_notifier_list;
 extern int register_reboot_notifier(struct notifier_block *);
 extern int unregister_reboot_notifier(struct notifier_block *);
+extern struct notifier_block *poweroff_handler_list;
+extern int register_poweroff_handler(struct notifier_block *);
+extern int unregister_poweroff_handler(struct notifier_block *);
 
 
 /*
Index: kernel/sys.c
===================================================================
RCS file: /cvs/linux/kernel/sys.c,v
retrieving revision 1.1.1.6.2.6
diff -u -r1.1.1.6.2.6 sys.c
--- kernel/sys.c 1999/11/09 09:12:14 1.1.1.6.2.6
+++ kernel/sys.c 2000/01/10 15:38:14
@@ -30,6 +30,7 @@
  */
 
 struct notifier_block *reboot_notifier_list = NULL;
+struct notifier_block *poweroff_handler_list = NULL;
 
 int register_reboot_notifier(struct notifier_block * nb)
 {
@@ -41,6 +42,16 @@
         return notifier_chain_unregister(&reboot_notifier_list, nb);
 }
 
+int register_poweroff_handler(struct notifier_block * nb)
+{
+ return notifier_chain_register(&poweroff_handler_list, nb);
+}
+
+int unregister_poweroff_handler(struct notifier_block * nb)
+{
+ return notifier_chain_unregister(&poweroff_handler_list, nb);
+}
+
 asmlinkage long sys_ni_syscall(void)
 {
         return -ENOSYS;
@@ -228,7 +239,11 @@
         } else
                 kill_proc(1, SIGINT, 1);
 }
-
+
+void machine_power_off(void)
+{
+ notifier_call_chain(&poweroff_handler_list, 0, NULL);
+}
 
 /*
  * Unprivileged users may change the real gid to the effective gid

--
dwmw2

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sat Jan 15 2000 - 21:00:16 EST