linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 08/47] kernel: Move pm_power_off to common code
       [not found] <1414425354-10359-1-git-send-email-linux@roeck-us.net>
@ 2014-10-27 15:55 ` Guenter Roeck
  2014-10-27 15:55 ` [PATCH v3 12/47] mfd: ab8500-sysctrl: Register with kernel power-off handler Guenter Roeck
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Guenter Roeck @ 2014-10-27 15:55 UTC (permalink / raw)
  To: linux-arm-kernel

pm_power_off is defined for all architectures. Move it to common code.

Have all architectures call do_kernel_power_off instead of pm_power_off.
Some architectures point pm_power_off to machine_power_off. For those,
call do_kernel_power_off from machine_power_off instead.

Acked-by: David Vrabel <david.vrabel@citrix.com>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Hirokazu Takata <takata@linux-m32r.org>
Acked-by: James Hogan <james.hogan@imgtec.com>
Acked-by: Jesper Nilsson <jesper.nilsson@axis.com>
Acked-by: Max Filippov <jcmvbkbc@gmail.com>
Acked-by: Rafael J. Wysocki <rjw@rjwysocki.net>
Acked-by: Richard Weinberger <richard@nod.at>
Acked-by: Xuetao Guan <gxt@mprc.pku.edu.cn>
Acked-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v3:
- Replace poweroff in all newly introduced variables and in text
  with power_off or power-off as appropriate
v2:
- do_kernel_poweroff -> do_kernel_power_off
- have_kernel_poweroff -> have_kernel_power_off

 arch/alpha/kernel/process.c        |  9 +++------
 arch/arc/kernel/reset.c            |  5 +----
 arch/arm/kernel/process.c          |  5 +----
 arch/arm64/kernel/process.c        |  5 +----
 arch/avr32/kernel/process.c        |  6 +-----
 arch/blackfin/kernel/process.c     |  3 ---
 arch/blackfin/kernel/reboot.c      |  2 ++
 arch/c6x/kernel/process.c          |  9 +--------
 arch/cris/kernel/process.c         |  4 +---
 arch/frv/kernel/process.c          |  5 ++---
 arch/hexagon/kernel/reset.c        |  5 ++---
 arch/ia64/kernel/process.c         |  5 +----
 arch/m32r/kernel/process.c         |  8 ++++----
 arch/m68k/kernel/process.c         |  6 +-----
 arch/metag/kernel/process.c        |  6 +-----
 arch/microblaze/kernel/process.c   |  3 ---
 arch/microblaze/kernel/reset.c     |  1 +
 arch/mips/kernel/reset.c           |  6 +-----
 arch/mn10300/kernel/process.c      |  8 ++------
 arch/openrisc/kernel/process.c     |  8 +++++---
 arch/parisc/kernel/process.c       |  8 ++++----
 arch/powerpc/kernel/setup-common.c |  6 +++---
 arch/s390/kernel/setup.c           |  8 ++------
 arch/score/kernel/process.c        |  8 ++++----
 arch/sh/kernel/reboot.c            |  6 +-----
 arch/sparc/kernel/process_32.c     | 10 ++--------
 arch/sparc/kernel/reboot.c         |  8 ++------
 arch/tile/kernel/reboot.c          |  7 +++----
 arch/um/kernel/reboot.c            |  2 --
 arch/unicore32/kernel/process.c    |  9 +--------
 arch/x86/kernel/reboot.c           | 11 +++--------
 arch/x86/xen/enlighten.c           |  3 +--
 arch/xtensa/kernel/process.c       |  4 ----
 drivers/parisc/power.c             |  3 +--
 kernel/power/power_off_handler.c   |  8 ++++++++
 kernel/reboot.c                    |  4 ++--
 36 files changed, 68 insertions(+), 146 deletions(-)

diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index 1941a07..81c43f8 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -24,6 +24,7 @@
 #include <linux/vt.h>
 #include <linux/mman.h>
 #include <linux/elfcore.h>
+#include <linux/pm.h>
 #include <linux/reboot.h>
 #include <linux/tty.h>
 #include <linux/console.h>
@@ -40,12 +41,6 @@
 #include "proto.h"
 #include "pci_impl.h"
 
-/*
- * Power off function, if any
- */
-void (*pm_power_off)(void) = machine_power_off;
-EXPORT_SYMBOL(pm_power_off);
-
 #ifdef CONFIG_ALPHA_WTINT
 /*
  * Sleep the CPU.
@@ -184,6 +179,8 @@ machine_halt(void)
 void
 machine_power_off(void)
 {
+	do_kernel_power_off();
+
 	common_shutdown(LINUX_REBOOT_CMD_POWER_OFF, NULL);
 }
 
diff --git a/arch/arc/kernel/reset.c b/arch/arc/kernel/reset.c
index 2768fa1..0758d9d 100644
--- a/arch/arc/kernel/reset.c
+++ b/arch/arc/kernel/reset.c
@@ -26,9 +26,6 @@ void machine_restart(char *__unused)
 
 void machine_power_off(void)
 {
-	/* FIXME ::  power off ??? */
+	do_kernel_power_off();
 	machine_halt();
 }
-
-void (*pm_power_off) (void) = NULL;
-EXPORT_SYMBOL(pm_power_off);
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index fe972a2..aa3f656 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -117,8 +117,6 @@ void soft_restart(unsigned long addr)
 /*
  * Function pointers to optional machine specific functions
  */
-void (*pm_power_off)(void);
-EXPORT_SYMBOL(pm_power_off);
 
 void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
 
@@ -205,8 +203,7 @@ void machine_power_off(void)
 	local_irq_disable();
 	smp_send_stop();
 
-	if (pm_power_off)
-		pm_power_off();
+	do_kernel_power_off();
 }
 
 /*
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index fde9923..6f623a0 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -68,8 +68,6 @@ void soft_restart(unsigned long addr)
 /*
  * Function pointers to optional machine specific functions
  */
-void (*pm_power_off)(void);
-EXPORT_SYMBOL_GPL(pm_power_off);
 
 void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
 
@@ -129,8 +127,7 @@ void machine_power_off(void)
 {
 	local_irq_disable();
 	smp_send_stop();
-	if (pm_power_off)
-		pm_power_off();
+	do_kernel_power_off();
 }
 
 /*
diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c
index 42a53e74..529c1f6 100644
--- a/arch/avr32/kernel/process.c
+++ b/arch/avr32/kernel/process.c
@@ -23,9 +23,6 @@
 
 #include <mach/pm.h>
 
-void (*pm_power_off)(void);
-EXPORT_SYMBOL(pm_power_off);
-
 /*
  * This file handles the architecture-dependent parts of process handling..
  */
@@ -48,8 +45,7 @@ void machine_halt(void)
 
 void machine_power_off(void)
 {
-	if (pm_power_off)
-		pm_power_off();
+	do_kernel_power_off();
 }
 
 void machine_restart(char *cmd)
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c
index 4aa5545..812dd83 100644
--- a/arch/blackfin/kernel/process.c
+++ b/arch/blackfin/kernel/process.c
@@ -39,9 +39,6 @@ int nr_l1stack_tasks;
 void *l1_stack_base;
 unsigned long l1_stack_len;
 
-void (*pm_power_off)(void) = NULL;
-EXPORT_SYMBOL(pm_power_off);
-
 /*
  * The idle loop on BFIN
  */
diff --git a/arch/blackfin/kernel/reboot.c b/arch/blackfin/kernel/reboot.c
index c4f50a3..387d610 100644
--- a/arch/blackfin/kernel/reboot.c
+++ b/arch/blackfin/kernel/reboot.c
@@ -7,6 +7,7 @@
  */
 
 #include <linux/interrupt.h>
+#include <linux/pm.h>
 #include <asm/bfin-global.h>
 #include <asm/reboot.h>
 #include <asm/bfrom.h>
@@ -106,6 +107,7 @@ void machine_halt(void)
 __attribute__((weak))
 void native_machine_power_off(void)
 {
+	do_kernel_power_off();
 	idle_with_irq_disabled();
 }
 
diff --git a/arch/c6x/kernel/process.c b/arch/c6x/kernel/process.c
index 57d2ea8..edf7e5a 100644
--- a/arch/c6x/kernel/process.c
+++ b/arch/c6x/kernel/process.c
@@ -27,12 +27,6 @@ void	(*c6x_halt)(void);
 extern asmlinkage void ret_from_fork(void);
 extern asmlinkage void ret_from_kernel_thread(void);
 
-/*
- * power off function, if any
- */
-void (*pm_power_off)(void);
-EXPORT_SYMBOL(pm_power_off);
-
 void arch_cpu_idle(void)
 {
 	unsigned long tmp;
@@ -73,8 +67,7 @@ void machine_halt(void)
 
 void machine_power_off(void)
 {
-	if (pm_power_off)
-		pm_power_off();
+	do_kernel_power_off();
 	halt_loop();
 }
 
diff --git a/arch/cris/kernel/process.c b/arch/cris/kernel/process.c
index b78498e..9ebd76b 100644
--- a/arch/cris/kernel/process.c
+++ b/arch/cris/kernel/process.c
@@ -31,9 +31,6 @@
 
 extern void default_idle(void);
 
-void (*pm_power_off)(void);
-EXPORT_SYMBOL(pm_power_off);
-
 void arch_cpu_idle(void)
 {
 	default_idle();
@@ -60,6 +57,7 @@ void machine_halt(void)
 
 void machine_power_off(void)
 {
+	do_kernel_power_off();
 }
 
 /*
diff --git a/arch/frv/kernel/process.c b/arch/frv/kernel/process.c
index 5d40aeb77..502dabb 100644
--- a/arch/frv/kernel/process.c
+++ b/arch/frv/kernel/process.c
@@ -42,9 +42,6 @@ asmlinkage void ret_from_kernel_thread(void);
 
 #include <asm/pgalloc.h>
 
-void (*pm_power_off)(void);
-EXPORT_SYMBOL(pm_power_off);
-
 static void core_sleep_idle(void)
 {
 #ifdef LED_DEBUG_SLEEP
@@ -107,6 +104,8 @@ void machine_power_off(void)
 	gdbstub_exit(0);
 #endif
 
+	do_kernel_power_off();
+
 	for (;;);
 }
 
diff --git a/arch/hexagon/kernel/reset.c b/arch/hexagon/kernel/reset.c
index 76483c1..6f607b6 100644
--- a/arch/hexagon/kernel/reset.c
+++ b/arch/hexagon/kernel/reset.c
@@ -16,11 +16,13 @@
  * 02110-1301, USA.
  */
 
+#include <linux/pm.h>
 #include <linux/smp.h>
 #include <asm/hexagon_vm.h>
 
 void machine_power_off(void)
 {
+	do_kernel_power_off();
 	smp_send_stop();
 	__vmstop();
 }
@@ -32,6 +34,3 @@ void machine_halt(void)
 void machine_restart(char *cmd)
 {
 }
-
-void (*pm_power_off)(void) = NULL;
-EXPORT_SYMBOL(pm_power_off);
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index b515149..88121a2 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -57,8 +57,6 @@ void (*ia64_mark_idle)(int);
 
 unsigned long boot_option_idle_override = IDLE_NO_OVERRIDE;
 EXPORT_SYMBOL(boot_option_idle_override);
-void (*pm_power_off) (void);
-EXPORT_SYMBOL(pm_power_off);
 
 void
 ia64_do_show_stack (struct unw_frame_info *info, void *arg)
@@ -675,8 +673,7 @@ machine_halt (void)
 void
 machine_power_off (void)
 {
-	if (pm_power_off)
-		pm_power_off();
+	do_kernel_power_off();
 	machine_halt();
 }
 
diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c
index e69221d..65a037e 100644
--- a/arch/m32r/kernel/process.c
+++ b/arch/m32r/kernel/process.c
@@ -23,6 +23,7 @@
 #include <linux/fs.h>
 #include <linux/slab.h>
 #include <linux/module.h>
+#include <linux/pm.h>
 #include <linux/ptrace.h>
 #include <linux/unistd.h>
 #include <linux/hardirq.h>
@@ -44,9 +45,6 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
 	return tsk->thread.lr;
 }
 
-void (*pm_power_off)(void) = NULL;
-EXPORT_SYMBOL(pm_power_off);
-
 void machine_restart(char *__unused)
 {
 #if defined(CONFIG_PLAT_MAPPI3)
@@ -67,7 +65,9 @@ void machine_halt(void)
 
 void machine_power_off(void)
 {
-	/* M32R_FIXME */
+	do_kernel_power_off();
+	for (;;)
+		;
 }
 
 void show_regs(struct pt_regs * regs)
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
index afe3d6e..bbc0a63 100644
--- a/arch/m68k/kernel/process.c
+++ b/arch/m68k/kernel/process.c
@@ -78,14 +78,10 @@ void machine_halt(void)
 
 void machine_power_off(void)
 {
-	if (pm_power_off)
-		pm_power_off();
+	do_kernel_power_off();
 	for (;;);
 }
 
-void (*pm_power_off)(void) = machine_power_off;
-EXPORT_SYMBOL(pm_power_off);
-
 void show_regs(struct pt_regs * regs)
 {
 	printk("\n");
diff --git a/arch/metag/kernel/process.c b/arch/metag/kernel/process.c
index 483dff9..8d95773 100644
--- a/arch/metag/kernel/process.c
+++ b/arch/metag/kernel/process.c
@@ -67,9 +67,6 @@ void arch_cpu_idle_dead(void)
 }
 #endif
 
-void (*pm_power_off)(void);
-EXPORT_SYMBOL(pm_power_off);
-
 void (*soc_restart)(char *cmd);
 void (*soc_halt)(void);
 
@@ -90,8 +87,7 @@ void machine_halt(void)
 
 void machine_power_off(void)
 {
-	if (pm_power_off)
-		pm_power_off();
+	do_kernel_power_off();
 	smp_send_stop();
 	hard_processor_halt(HALT_OK);
 }
diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c
index b2dd371..0ebca36 100644
--- a/arch/microblaze/kernel/process.c
+++ b/arch/microblaze/kernel/process.c
@@ -44,9 +44,6 @@ void show_regs(struct pt_regs *regs)
 				regs->msr, regs->ear, regs->esr, regs->fsr);
 }
 
-void (*pm_power_off)(void) = NULL;
-EXPORT_SYMBOL(pm_power_off);
-
 void flush_thread(void)
 {
 }
diff --git a/arch/microblaze/kernel/reset.c b/arch/microblaze/kernel/reset.c
index fbe58c6..2c6b32c 100644
--- a/arch/microblaze/kernel/reset.c
+++ b/arch/microblaze/kernel/reset.c
@@ -103,6 +103,7 @@ void machine_halt(void)
 void machine_power_off(void)
 {
 	pr_notice("Machine power off...\n");
+	do_kernel_power_off();
 	while (1)
 		;
 }
diff --git a/arch/mips/kernel/reset.c b/arch/mips/kernel/reset.c
index 07fc524..09e74d2 100644
--- a/arch/mips/kernel/reset.c
+++ b/arch/mips/kernel/reset.c
@@ -21,9 +21,6 @@
  */
 void (*_machine_restart)(char *command);
 void (*_machine_halt)(void);
-void (*pm_power_off)(void);
-
-EXPORT_SYMBOL(pm_power_off);
 
 void machine_restart(char *command)
 {
@@ -39,6 +36,5 @@ void machine_halt(void)
 
 void machine_power_off(void)
 {
-	if (pm_power_off)
-		pm_power_off();
+	do_kernel_power_off();
 }
diff --git a/arch/mn10300/kernel/process.c b/arch/mn10300/kernel/process.c
index 3707da5..c78b2eb 100644
--- a/arch/mn10300/kernel/process.c
+++ b/arch/mn10300/kernel/process.c
@@ -20,6 +20,7 @@
 #include <linux/user.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/pm.h>
 #include <linux/reboot.h>
 #include <linux/percpu.h>
 #include <linux/err.h>
@@ -45,12 +46,6 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
 }
 
 /*
- * power off function, if any
- */
-void (*pm_power_off)(void);
-EXPORT_SYMBOL(pm_power_off);
-
-/*
  * On SMP it's slightly faster (but much more power-consuming!)
  * to poll the ->work.need_resched flag instead of waiting for the
  * cross-CPU IPI to arrive. Use this option with caution.
@@ -93,6 +88,7 @@ void machine_power_off(void)
 #ifdef CONFIG_KERNEL_DEBUGGER
 	gdbstub_exit(0);
 #endif
+	do_kernel_power_off();
 }
 
 void show_regs(struct pt_regs *regs)
diff --git a/arch/openrisc/kernel/process.c b/arch/openrisc/kernel/process.c
index 386af25..494afd2 100644
--- a/arch/openrisc/kernel/process.c
+++ b/arch/openrisc/kernel/process.c
@@ -25,6 +25,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/mm.h>
+#include <linux/pm.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
@@ -51,7 +52,7 @@
  */
 struct thread_info *current_thread_info_set[NR_CPUS] = { &init_thread_info, };
 
-void machine_restart(void)
+void machine_restart(char *cmd)
 {
 	printk(KERN_INFO "*** MACHINE RESTART ***\n");
 	__asm__("l.nop 1");
@@ -72,11 +73,12 @@ void machine_halt(void)
 void machine_power_off(void)
 {
 	printk(KERN_INFO "*** MACHINE POWER OFF ***\n");
+
+	do_kernel_power_off();
+
 	__asm__("l.nop 1");
 }
 
-void (*pm_power_off) (void) = machine_power_off;
-
 /*
  * When a process does an "exec", machine state like FPU and debug
  * registers need to be reset.  This is a hook function for that.
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index 0bbbf0d..3f5d14a 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -41,6 +41,7 @@
 #include <linux/fs.h>
 #include <linux/module.h>
 #include <linux/personality.h>
+#include <linux/pm.h>
 #include <linux/ptrace.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
@@ -133,7 +134,9 @@ void machine_power_off(void)
 	pdc_soft_power_button(0);
 	
 	pdc_chassis_send_status(PDC_CHASSIS_DIRECT_SHUTDOWN);
-		
+
+	do_kernel_power_off();
+
 	/* It seems we have no way to power the system off via
 	 * software. The user has to press the button himself. */
 
@@ -141,9 +144,6 @@ void machine_power_off(void)
 	       "Please power this system off now.");
 }
 
-void (*pm_power_off)(void) = machine_power_off;
-EXPORT_SYMBOL(pm_power_off);
-
 /*
  * Free current thread data structures etc..
  */
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 1362cd6..5b7a851 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -141,6 +141,9 @@ void machine_power_off(void)
 	machine_shutdown();
 	if (ppc_md.power_off)
 		ppc_md.power_off();
+
+	do_kernel_power_off();
+
 #ifdef CONFIG_SMP
 	smp_send_stop();
 #endif
@@ -151,9 +154,6 @@ void machine_power_off(void)
 /* Used by the G5 thermal driver */
 EXPORT_SYMBOL_GPL(machine_power_off);
 
-void (*pm_power_off)(void) = machine_power_off;
-EXPORT_SYMBOL_GPL(pm_power_off);
-
 void machine_halt(void)
 {
 	machine_shutdown();
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index e80d9ff..267e025 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -263,13 +263,9 @@ void machine_power_off(void)
 		 */
 		console_unblank();
 	_machine_power_off();
-}
 
-/*
- * Dummy power off function.
- */
-void (*pm_power_off)(void) = machine_power_off;
-EXPORT_SYMBOL_GPL(pm_power_off);
+	do_kernel_power_off();
+}
 
 static int __init early_parse_mem(char *p)
 {
diff --git a/arch/score/kernel/process.c b/arch/score/kernel/process.c
index a1519ad3..b76ea67 100644
--- a/arch/score/kernel/process.c
+++ b/arch/score/kernel/process.c
@@ -29,9 +29,6 @@
 #include <linux/pm.h>
 #include <linux/rcupdate.h>
 
-void (*pm_power_off)(void);
-EXPORT_SYMBOL(pm_power_off);
-
 /* If or when software machine-restart is implemented, add code here. */
 void machine_restart(char *command) {}
 
@@ -39,7 +36,10 @@ void machine_restart(char *command) {}
 void machine_halt(void) {}
 
 /* If or when software machine-power-off is implemented, add code here. */
-void machine_power_off(void) {}
+void machine_power_off(void)
+{
+	do_kernel_power_off();
+}
 
 void ret_from_fork(void);
 void ret_from_kernel_thread(void);
diff --git a/arch/sh/kernel/reboot.c b/arch/sh/kernel/reboot.c
index 04afe5b..065de12 100644
--- a/arch/sh/kernel/reboot.c
+++ b/arch/sh/kernel/reboot.c
@@ -11,9 +11,6 @@
 #include <asm/tlbflush.h>
 #include <asm/traps.h>
 
-void (*pm_power_off)(void);
-EXPORT_SYMBOL(pm_power_off);
-
 #ifdef CONFIG_SUPERH32
 static void watchdog_trigger_immediate(void)
 {
@@ -51,8 +48,7 @@ static void native_machine_shutdown(void)
 
 static void native_machine_power_off(void)
 {
-	if (pm_power_off)
-		pm_power_off();
+	do_kernel_power_off();
 }
 
 static void native_machine_halt(void)
diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c
index 50e7b62..cb8148a 100644
--- a/arch/sparc/kernel/process_32.c
+++ b/arch/sparc/kernel/process_32.c
@@ -48,14 +48,6 @@
  */
 void (*sparc_idle)(void);
 
-/* 
- * Power-off handler instantiation for pm.h compliance
- * This is done via auxio, but could be used as a fallback
- * handler when auxio is not present-- unused for now...
- */
-void (*pm_power_off)(void) = machine_power_off;
-EXPORT_SYMBOL(pm_power_off);
-
 /*
  * sysctl - toggle power-off restriction for serial console 
  * systems in machine_power_off()
@@ -112,6 +104,8 @@ void machine_power_off(void)
 		sbus_writeb(power_register, auxio_power_register);
 	}
 
+	do_kernel_power_off();
+
 	machine_halt();
 }
 
diff --git a/arch/sparc/kernel/reboot.c b/arch/sparc/kernel/reboot.c
index eba7d91..3c0bb03 100644
--- a/arch/sparc/kernel/reboot.c
+++ b/arch/sparc/kernel/reboot.c
@@ -16,17 +16,13 @@
  */
 int scons_pwroff = 1;
 
-/* This isn't actually used, it exists merely to satisfy the
- * reference in kernel/sys.c
- */
-void (*pm_power_off)(void) = machine_power_off;
-EXPORT_SYMBOL(pm_power_off);
-
 void machine_power_off(void)
 {
 	if (strcmp(of_console_device->type, "serial") || scons_pwroff)
 		prom_halt_power_off();
 
+	do_kernel_power_off();
+
 	prom_halt();
 }
 
diff --git a/arch/tile/kernel/reboot.c b/arch/tile/kernel/reboot.c
index 6c5d2c0..8ff4a7f 100644
--- a/arch/tile/kernel/reboot.c
+++ b/arch/tile/kernel/reboot.c
@@ -36,6 +36,9 @@ void machine_power_off(void)
 {
 	arch_local_irq_disable_all();
 	smp_send_stop();
+
+	do_kernel_power_off();
+
 	hv_power_off();
 }
 
@@ -45,7 +48,3 @@ void machine_restart(char *cmd)
 	smp_send_stop();
 	hv_restart((HV_VirtAddr) "vmlinux", (HV_VirtAddr) cmd);
 }
-
-/* No interesting distinction to be made here. */
-void (*pm_power_off)(void) = NULL;
-EXPORT_SYMBOL(pm_power_off);
diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c
index ced8903..a82ef28 100644
--- a/arch/um/kernel/reboot.c
+++ b/arch/um/kernel/reboot.c
@@ -11,8 +11,6 @@
 #include <os.h>
 #include <skas.h>
 
-void (*pm_power_off)(void);
-
 static void kill_off_processes(void)
 {
 	if (proc_mm)
diff --git a/arch/unicore32/kernel/process.c b/arch/unicore32/kernel/process.c
index b008e99..9490dd5 100644
--- a/arch/unicore32/kernel/process.c
+++ b/arch/unicore32/kernel/process.c
@@ -56,16 +56,9 @@ void machine_halt(void)
 	gpio_set_value(GPO_SOFT_OFF, 0);
 }
 
-/*
- * Function pointers to optional machine specific functions
- */
-void (*pm_power_off)(void) = NULL;
-EXPORT_SYMBOL(pm_power_off);
-
 void machine_power_off(void)
 {
-	if (pm_power_off)
-		pm_power_off();
+	do_kernel_power_off();
 	machine_halt();
 }
 
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index 17962e6..5c09e28 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -30,12 +30,6 @@
 #include <asm/x86_init.h>
 #include <asm/efi.h>
 
-/*
- * Power off function, if any
- */
-void (*pm_power_off)(void);
-EXPORT_SYMBOL(pm_power_off);
-
 static const struct desc_ptr no_idt = {};
 
 /*
@@ -647,11 +641,12 @@ static void native_machine_halt(void)
 
 static void native_machine_power_off(void)
 {
-	if (pm_power_off) {
+	if (have_kernel_power_off()) {
 		if (!reboot_force)
 			machine_shutdown();
-		pm_power_off();
+		do_kernel_power_off();
 	}
+
 	/* A fallback in case there is no PM info available */
 	tboot_shutdown(TB_SHUTDOWN_HALT);
 }
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index fac5e4f..bc08998 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -1320,8 +1320,7 @@ static void xen_machine_halt(void)
 
 static void xen_machine_power_off(void)
 {
-	if (pm_power_off)
-		pm_power_off();
+	do_kernel_power_off();
 	xen_reboot(SHUTDOWN_poweroff);
 }
 
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c
index 1c85323..c487296 100644
--- a/arch/xtensa/kernel/process.c
+++ b/arch/xtensa/kernel/process.c
@@ -49,10 +49,6 @@ extern void ret_from_kernel_thread(void);
 
 struct task_struct *current_set[NR_CPUS] = {&init_task, };
 
-void (*pm_power_off)(void) = NULL;
-EXPORT_SYMBOL(pm_power_off);
-
-
 #if XTENSA_HAVE_COPROCESSORS
 
 void coprocessor_release_all(struct thread_info *ti)
diff --git a/drivers/parisc/power.c b/drivers/parisc/power.c
index ef31b77..f10cf92 100644
--- a/drivers/parisc/power.c
+++ b/drivers/parisc/power.c
@@ -95,8 +95,7 @@ static void process_shutdown(void)
 		/* send kill signal */
 		if (kill_cad_pid(SIGINT, 1)) {
 			/* just in case killing init process failed */
-			if (pm_power_off)
-				pm_power_off();
+			kernel_power_off();
 		}
 	}
 }
diff --git a/kernel/power/power_off_handler.c b/kernel/power/power_off_handler.c
index f838e63..97b7163 100644
--- a/kernel/power/power_off_handler.c
+++ b/kernel/power/power_off_handler.c
@@ -22,6 +22,12 @@
 #include <linux/types.h>
 
 /*
+ * If set, calling this function will power off the system immediately.
+ */
+void (*pm_power_off)(void);
+EXPORT_SYMBOL(pm_power_off);
+
+/*
  *	Notifier list for kernel code which wants to be called
  *	to power off the system.
  */
@@ -253,6 +259,8 @@ void do_kernel_power_off(void)
 	 * removed while the call chain is traversed, but we'll have to carry
 	 * that risk.
 	 */
+	if (pm_power_off)
+		pm_power_off();
 	raw_notifier_call_chain(&power_off_handler_list, 0, NULL);
 }
 
diff --git a/kernel/reboot.c b/kernel/reboot.c
index 5925f5a..d87d921 100644
--- a/kernel/reboot.c
+++ b/kernel/reboot.c
@@ -306,9 +306,9 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
 		return ret;
 
 	/* Instead of trying to make the power_off code look like
-	 * halt when pm_power_off is not set do it the easy way.
+	 * halt when no power-off handler exists do it the easy way.
 	 */
-	if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
+	if (cmd == LINUX_REBOOT_CMD_POWER_OFF && !have_kernel_power_off())
 		cmd = LINUX_REBOOT_CMD_HALT;
 
 	mutex_lock(&reboot_mutex);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 12/47] mfd: ab8500-sysctrl: Register with kernel power-off handler
       [not found] <1414425354-10359-1-git-send-email-linux@roeck-us.net>
  2014-10-27 15:55 ` [PATCH v3 08/47] kernel: Move pm_power_off to common code Guenter Roeck
@ 2014-10-27 15:55 ` Guenter Roeck
  2014-11-03 17:55   ` Lee Jones
  2014-10-27 15:55 ` [PATCH v3 35/47] arm: " Guenter Roeck
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 15+ messages in thread
From: Guenter Roeck @ 2014-10-27 15:55 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel power-off handler instead of setting pm_power_off
directly. Register with low priority to reflect that the original code
only sets pm_power_off if it was not already set.

sysctrl_dev is set prior to power-off handler registration, and the
power-off handler is unregistered prior to clearing sysrctrl_dev.
It is therefore not necessary to check if sysctrl_dev is NULL in the
power-off handler, and the check was removed. Setting sysctrl_dev to NULL
in the remove function was also removed as unnecessary. With those changes,
devm_register_power_off_handler can be used to register the poeroff handler.
The now empty remove function was retained since the ab8500_restart function,
which is currently unused, would likely need some cleanup if it was ever used.

Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Lee Jones <lee.jones@linaro.org>
Cc: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v3:
- Replace poweroff in all newly introduced variables and in text
  with power_off or power-off as appropriate
- Replace POWEROFF_PRIORITY_xxx with POWER_OFF_PRIORITY_xxx
v2:
- Use define to specify poweroff handler priority
- Use devm_register_power_off_handler
- Use dev_warn instead of dev_err
- Since we use devm_register_power_off_handler,
  we need to check if sysctrl_dev in the poweroff handler to avoid
  a race condition on unload, so this check is no longer removed

 drivers/mfd/ab8500-sysctrl.c | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/drivers/mfd/ab8500-sysctrl.c b/drivers/mfd/ab8500-sysctrl.c
index 8e0dae5..c49ecaf 100644
--- a/drivers/mfd/ab8500-sysctrl.c
+++ b/drivers/mfd/ab8500-sysctrl.c
@@ -6,6 +6,7 @@
 
 #include <linux/err.h>
 #include <linux/module.h>
+#include <linux/notifier.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
 #include <linux/reboot.h>
@@ -23,7 +24,8 @@
 
 static struct device *sysctrl_dev;
 
-static void ab8500_power_off(void)
+static int ab8500_power_off(struct notifier_block *this, unsigned long unused1,
+			    void *unused2)
 {
 	sigset_t old;
 	sigset_t all;
@@ -36,7 +38,7 @@ static void ab8500_power_off(void)
 
 	if (sysctrl_dev == NULL) {
 		pr_err("%s: sysctrl not initialized\n", __func__);
-		return;
+		return NOTIFY_DONE;
 	}
 
 	/*
@@ -83,8 +85,15 @@ shutdown:
 					 AB8500_STW4500CTRL1_SWRESET4500N);
 		(void)sigprocmask(SIG_SETMASK, &old, NULL);
 	}
+
+	return NOTIFY_DONE;
 }
 
+static struct notifier_block ab8500_power_off_nb = {
+	.notifier_call = ab8500_power_off,
+	.priority = POWER_OFF_PRIORITY_LOW,
+};
+
 /*
  * Use the AB WD to reset the platform. It will perform a hard
  * reset instead of a soft reset. Write the reset reason to
@@ -185,6 +194,7 @@ static int ab8500_sysctrl_probe(struct platform_device *pdev)
 	struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
 	struct ab8500_platform_data *plat;
 	struct ab8500_sysctrl_platform_data *pdata;
+	int err;
 
 	plat = dev_get_platdata(pdev->dev.parent);
 
@@ -193,8 +203,10 @@ static int ab8500_sysctrl_probe(struct platform_device *pdev)
 
 	sysctrl_dev = &pdev->dev;
 
-	if (!pm_power_off)
-		pm_power_off = ab8500_power_off;
+	err = devm_register_power_off_handler(sysctrl_dev,
+					      &ab8500_power_off_nb);
+	if (err)
+		dev_warn(&pdev->dev, "Failed to register power-off handler\n");
 
 	pdata = plat->sysctrl;
 	if (pdata) {
@@ -228,9 +240,6 @@ static int ab8500_sysctrl_remove(struct platform_device *pdev)
 {
 	sysctrl_dev = NULL;
 
-	if (pm_power_off == ab8500_power_off)
-		pm_power_off = NULL;
-
 	return 0;
 }
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 35/47] arm: Register with kernel power-off handler
       [not found] <1414425354-10359-1-git-send-email-linux@roeck-us.net>
  2014-10-27 15:55 ` [PATCH v3 08/47] kernel: Move pm_power_off to common code Guenter Roeck
  2014-10-27 15:55 ` [PATCH v3 12/47] mfd: ab8500-sysctrl: Register with kernel power-off handler Guenter Roeck
@ 2014-10-27 15:55 ` Guenter Roeck
  2014-10-27 15:55 ` [PATCH v3 36/47] arm64: psci: " Guenter Roeck
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Guenter Roeck @ 2014-10-27 15:55 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel power-off handler instead of setting pm_power_off
directly. Always use register_power_off_handler_simple as there is no
indication that more than one power-off handler is registered.

If the power-off handler only resets the system or puts the CPU in sleep mode,
select the fallback priority to indicate that the power-off handler is one
of last resort. If the power-off handler powers off the system, select the
default priority.

Cc: Russell King <linux@arm.linux.org.uk>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v3:
- Replace poweroff in all newly introduced variables and in text
  with power_off or power-off as appropriate
- Replace POWEROFF_PRIORITY_xxx with POWER_OFF_PRIORITY_xxx
v2:
- Use defines to specify poweroff handler priorities
- Drop changes in arch/arm/mach-at91/setup.c (file removed upstream)

 arch/arm/kernel/psci.c                         | 3 ++-
 arch/arm/mach-at91/board-gsia18s.c             | 3 ++-
 arch/arm/mach-bcm/board_bcm2835.c              | 3 ++-
 arch/arm/mach-cns3xxx/cns3420vb.c              | 3 ++-
 arch/arm/mach-cns3xxx/core.c                   | 3 ++-
 arch/arm/mach-highbank/highbank.c              | 3 ++-
 arch/arm/mach-imx/mach-mx31moboard.c           | 3 ++-
 arch/arm/mach-iop32x/em7210.c                  | 3 ++-
 arch/arm/mach-iop32x/glantank.c                | 3 ++-
 arch/arm/mach-iop32x/iq31244.c                 | 3 ++-
 arch/arm/mach-iop32x/n2100.c                   | 3 ++-
 arch/arm/mach-ixp4xx/dsmg600-setup.c           | 3 ++-
 arch/arm/mach-ixp4xx/nas100d-setup.c           | 3 ++-
 arch/arm/mach-ixp4xx/nslu2-setup.c             | 3 ++-
 arch/arm/mach-omap2/board-omap3touchbook.c     | 3 ++-
 arch/arm/mach-orion5x/board-mss2.c             | 3 ++-
 arch/arm/mach-orion5x/dns323-setup.c           | 9 ++++++---
 arch/arm/mach-orion5x/kurobox_pro-setup.c      | 3 ++-
 arch/arm/mach-orion5x/ls-chl-setup.c           | 3 ++-
 arch/arm/mach-orion5x/ls_hgl-setup.c           | 3 ++-
 arch/arm/mach-orion5x/lsmini-setup.c           | 3 ++-
 arch/arm/mach-orion5x/mv2120-setup.c           | 3 ++-
 arch/arm/mach-orion5x/net2big-setup.c          | 3 ++-
 arch/arm/mach-orion5x/terastation_pro2-setup.c | 3 ++-
 arch/arm/mach-orion5x/ts209-setup.c            | 3 ++-
 arch/arm/mach-orion5x/ts409-setup.c            | 3 ++-
 arch/arm/mach-pxa/corgi.c                      | 3 ++-
 arch/arm/mach-pxa/mioa701.c                    | 3 ++-
 arch/arm/mach-pxa/poodle.c                     | 3 ++-
 arch/arm/mach-pxa/spitz.c                      | 3 ++-
 arch/arm/mach-pxa/tosa.c                       | 3 ++-
 arch/arm/mach-pxa/viper.c                      | 3 ++-
 arch/arm/mach-pxa/z2.c                         | 7 ++++---
 arch/arm/mach-pxa/zeus.c                       | 7 ++++---
 arch/arm/mach-s3c24xx/mach-gta02.c             | 3 ++-
 arch/arm/mach-s3c24xx/mach-jive.c              | 3 ++-
 arch/arm/mach-s3c24xx/mach-vr1000.c            | 3 ++-
 arch/arm/mach-s3c64xx/mach-smartq.c            | 3 ++-
 arch/arm/mach-sa1100/generic.c                 | 3 ++-
 arch/arm/mach-sa1100/simpad.c                  | 3 ++-
 arch/arm/mach-u300/regulator.c                 | 3 ++-
 arch/arm/mach-vt8500/vt8500.c                  | 3 ++-
 arch/arm/xen/enlighten.c                       | 3 ++-
 43 files changed, 94 insertions(+), 49 deletions(-)

diff --git a/arch/arm/kernel/psci.c b/arch/arm/kernel/psci.c
index f73891b..a7a2b4a 100644
--- a/arch/arm/kernel/psci.c
+++ b/arch/arm/kernel/psci.c
@@ -264,7 +264,8 @@ static int psci_0_2_init(struct device_node *np)
 
 	arm_pm_restart = psci_sys_reset;
 
-	pm_power_off = psci_sys_poweroff;
+	register_power_off_handler_simple(psci_sys_poweroff,
+					  POWER_OFF_PRIORITY_DEFAULT);
 
 out_put_node:
 	of_node_put(np);
diff --git a/arch/arm/mach-at91/board-gsia18s.c b/arch/arm/mach-at91/board-gsia18s.c
index bf5cc55..e628c4a 100644
--- a/arch/arm/mach-at91/board-gsia18s.c
+++ b/arch/arm/mach-at91/board-gsia18s.c
@@ -521,7 +521,8 @@ static void gsia18s_power_off(void)
 
 static int __init gsia18s_power_off_init(void)
 {
-	pm_power_off = gsia18s_power_off;
+	register_power_off_handler_simple(gsia18s_power_off,
+					  POWER_OFF_PRIORITY_DEFAULT);
 	return 0;
 }
 
diff --git a/arch/arm/mach-bcm/board_bcm2835.c b/arch/arm/mach-bcm/board_bcm2835.c
index 70f2f39..1d75c76 100644
--- a/arch/arm/mach-bcm/board_bcm2835.c
+++ b/arch/arm/mach-bcm/board_bcm2835.c
@@ -111,7 +111,8 @@ static void __init bcm2835_init(void)
 
 	bcm2835_setup_restart();
 	if (wdt_regs)
-		pm_power_off = bcm2835_power_off;
+		register_power_off_handler_simple(bcm2835_power_off,
+						  POWER_OFF_PRIORITY_FALLBACK);
 
 	bcm2835_init_clocks();
 
diff --git a/arch/arm/mach-cns3xxx/cns3420vb.c b/arch/arm/mach-cns3xxx/cns3420vb.c
index 6428bcc7..5c50461 100644
--- a/arch/arm/mach-cns3xxx/cns3420vb.c
+++ b/arch/arm/mach-cns3xxx/cns3420vb.c
@@ -224,7 +224,8 @@ static void __init cns3420_init(void)
 	cns3xxx_ahci_init();
 	cns3xxx_sdhci_init();
 
-	pm_power_off = cns3xxx_power_off;
+	register_power_off_handler_simple(cns3xxx_power_off,
+					  POWER_OFF_PRIORITY_DEFAULT);
 }
 
 static struct map_desc cns3420_io_desc[] __initdata = {
diff --git a/arch/arm/mach-cns3xxx/core.c b/arch/arm/mach-cns3xxx/core.c
index 4e9837d..9c214cf 100644
--- a/arch/arm/mach-cns3xxx/core.c
+++ b/arch/arm/mach-cns3xxx/core.c
@@ -386,7 +386,8 @@ static void __init cns3xxx_init(void)
 		cns3xxx_pwr_soft_rst(CNS3XXX_PWR_SOFTWARE_RST(SDIO));
 	}
 
-	pm_power_off = cns3xxx_power_off;
+	register_power_off_handler_simple(cns3xxx_power_off,
+					  POWER_OFF_PRIORITY_DEFAULT);
 
 	of_platform_populate(NULL, of_default_bus_match_table,
                         cns3xxx_auxdata, NULL);
diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c
index 07a0957..6fbdc01 100644
--- a/arch/arm/mach-highbank/highbank.c
+++ b/arch/arm/mach-highbank/highbank.c
@@ -155,7 +155,8 @@ static void __init highbank_init(void)
 	sregs_base = of_iomap(np, 0);
 	WARN_ON(!sregs_base);
 
-	pm_power_off = highbank_power_off;
+	register_power_off_handler_simple(highbank_power_off,
+					  POWER_OFF_PRIORITY_FALLBACK);
 	highbank_pm_init();
 
 	bus_register_notifier(&platform_bus_type, &highbank_platform_nb);
diff --git a/arch/arm/mach-imx/mach-mx31moboard.c b/arch/arm/mach-imx/mach-mx31moboard.c
index bb6f8a5..3001b14 100644
--- a/arch/arm/mach-imx/mach-mx31moboard.c
+++ b/arch/arm/mach-imx/mach-mx31moboard.c
@@ -559,7 +559,8 @@ static void __init mx31moboard_init(void)
 
 	imx_add_platform_device("imx_mc13783", 0, NULL, 0, NULL, 0);
 
-	pm_power_off = mx31moboard_poweroff;
+	register_power_off_handler_simple(mx31moboard_poweroff,
+					  POWER_OFF_PRIORITY_DEFAULT);
 
 	switch (mx31moboard_baseboard) {
 	case MX31NOBOARD:
diff --git a/arch/arm/mach-iop32x/em7210.c b/arch/arm/mach-iop32x/em7210.c
index 77e1ff0..fd3ad09 100644
--- a/arch/arm/mach-iop32x/em7210.c
+++ b/arch/arm/mach-iop32x/em7210.c
@@ -201,7 +201,8 @@ static int __init em7210_request_gpios(void)
 		return 0;
 	}
 
-	pm_power_off = em7210_power_off;
+	register_power_off_handler_simple(em7210_power_off,
+					  POWER_OFF_PRIORITY_DEFAULT);
 
 	return 0;
 }
diff --git a/arch/arm/mach-iop32x/glantank.c b/arch/arm/mach-iop32x/glantank.c
index 547b234..9298ea0 100644
--- a/arch/arm/mach-iop32x/glantank.c
+++ b/arch/arm/mach-iop32x/glantank.c
@@ -199,7 +199,8 @@ static void __init glantank_init_machine(void)
 	i2c_register_board_info(0, glantank_i2c_devices,
 		ARRAY_SIZE(glantank_i2c_devices));
 
-	pm_power_off = glantank_power_off;
+	register_power_off_handler_simple(glantank_power_off,
+					  POWER_OFF_PRIORITY_DEFAULT);
 }
 
 MACHINE_START(GLANTANK, "GLAN Tank")
diff --git a/arch/arm/mach-iop32x/iq31244.c b/arch/arm/mach-iop32x/iq31244.c
index 0e1392b..50ba54b 100644
--- a/arch/arm/mach-iop32x/iq31244.c
+++ b/arch/arm/mach-iop32x/iq31244.c
@@ -293,7 +293,8 @@ static void __init iq31244_init_machine(void)
 	platform_device_register(&iop3xx_dma_1_channel);
 
 	if (is_ep80219())
-		pm_power_off = ep80219_power_off;
+		register_power_off_handler_simple(ep80219_power_off,
+						  POWER_OFF_PRIORITY_DEFAULT);
 
 	if (!is_80219())
 		platform_device_register(&iop3xx_aau_channel);
diff --git a/arch/arm/mach-iop32x/n2100.c b/arch/arm/mach-iop32x/n2100.c
index c1cd80e..734a092 100644
--- a/arch/arm/mach-iop32x/n2100.c
+++ b/arch/arm/mach-iop32x/n2100.c
@@ -356,7 +356,8 @@ static void __init n2100_init_machine(void)
 	i2c_register_board_info(0, n2100_i2c_devices,
 		ARRAY_SIZE(n2100_i2c_devices));
 
-	pm_power_off = n2100_power_off;
+	register_power_off_handler_simple(n2100_power_off,
+					  POWER_OFF_PRIORITY_DEFAULT);
 }
 
 MACHINE_START(N2100, "Thecus N2100")
diff --git a/arch/arm/mach-ixp4xx/dsmg600-setup.c b/arch/arm/mach-ixp4xx/dsmg600-setup.c
index 43ee06d..f34564d 100644
--- a/arch/arm/mach-ixp4xx/dsmg600-setup.c
+++ b/arch/arm/mach-ixp4xx/dsmg600-setup.c
@@ -281,7 +281,8 @@ static void __init dsmg600_init(void)
 
 	platform_add_devices(dsmg600_devices, ARRAY_SIZE(dsmg600_devices));
 
-	pm_power_off = dsmg600_power_off;
+	register_power_off_handler_simple(dsmg600_power_off,
+					  POWER_OFF_PRIORITY_DEFAULT);
 }
 
 MACHINE_START(DSMG600, "D-Link DSM-G600 RevA")
diff --git a/arch/arm/mach-ixp4xx/nas100d-setup.c b/arch/arm/mach-ixp4xx/nas100d-setup.c
index 4e0f762..43a9333 100644
--- a/arch/arm/mach-ixp4xx/nas100d-setup.c
+++ b/arch/arm/mach-ixp4xx/nas100d-setup.c
@@ -292,7 +292,8 @@ static void __init nas100d_init(void)
 
 	platform_add_devices(nas100d_devices, ARRAY_SIZE(nas100d_devices));
 
-	pm_power_off = nas100d_power_off;
+	register_power_off_handler_simple(nas100d_power_off,
+					  POWER_OFF_PRIORITY_DEFAULT);
 
 	if (request_irq(gpio_to_irq(NAS100D_RB_GPIO), &nas100d_reset_handler,
 		IRQF_TRIGGER_LOW, "NAS100D reset button", NULL) < 0) {
diff --git a/arch/arm/mach-ixp4xx/nslu2-setup.c b/arch/arm/mach-ixp4xx/nslu2-setup.c
index 88c025f..e094d5f 100644
--- a/arch/arm/mach-ixp4xx/nslu2-setup.c
+++ b/arch/arm/mach-ixp4xx/nslu2-setup.c
@@ -262,7 +262,8 @@ static void __init nslu2_init(void)
 
 	platform_add_devices(nslu2_devices, ARRAY_SIZE(nslu2_devices));
 
-	pm_power_off = nslu2_power_off;
+	register_power_off_handler_simple(nslu2_power_off,
+					  POWER_OFF_PRIORITY_DEFAULT);
 
 	if (request_irq(gpio_to_irq(NSLU2_RB_GPIO), &nslu2_reset_handler,
 		IRQF_TRIGGER_LOW, "NSLU2 reset button", NULL) < 0) {
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
index a01993e..8abce2c 100644
--- a/arch/arm/mach-omap2/board-omap3touchbook.c
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -344,7 +344,8 @@ static void __init omap3_touchbook_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
 
-	pm_power_off = omap3_touchbook_poweroff;
+	register_power_off_handler_simple(omap3_touchbook_poweroff,
+					  POWER_OFF_PRIORITY_DEFAULT);
 
 	if (system_rev >= 0x20 && system_rev <= 0x34301000) {
 		omap_mux_init_gpio(23, OMAP_PIN_INPUT);
diff --git a/arch/arm/mach-orion5x/board-mss2.c b/arch/arm/mach-orion5x/board-mss2.c
index 66f9c3b..cac2793 100644
--- a/arch/arm/mach-orion5x/board-mss2.c
+++ b/arch/arm/mach-orion5x/board-mss2.c
@@ -86,5 +86,6 @@ static void mss2_power_off(void)
 void __init mss2_init(void)
 {
 	/* register mss2 specific power-off method */
-	pm_power_off = mss2_power_off;
+	register_power_off_handler_simple(mss2_power_off,
+					  POWER_OFF_PRIORITY_FALLBACK);
 }
diff --git a/arch/arm/mach-orion5x/dns323-setup.c b/arch/arm/mach-orion5x/dns323-setup.c
index 09d2a26..9876509 100644
--- a/arch/arm/mach-orion5x/dns323-setup.c
+++ b/arch/arm/mach-orion5x/dns323-setup.c
@@ -669,7 +669,8 @@ static void __init dns323_init(void)
 		if (gpio_request(DNS323_GPIO_POWER_OFF, "POWEROFF") != 0 ||
 		    gpio_direction_output(DNS323_GPIO_POWER_OFF, 0) != 0)
 			pr_err("DNS-323: failed to setup power-off GPIO\n");
-		pm_power_off = dns323a_power_off;
+		register_power_off_handler_simple(dns323a_power_off,
+						  POWER_OFF_PRIORITY_DEFAULT);
 		break;
 	case DNS323_REV_B1:
 		/* 5182 built-in SATA init */
@@ -686,7 +687,8 @@ static void __init dns323_init(void)
 		if (gpio_request(DNS323_GPIO_POWER_OFF, "POWEROFF") != 0 ||
 		    gpio_direction_output(DNS323_GPIO_POWER_OFF, 0) != 0)
 			pr_err("DNS-323: failed to setup power-off GPIO\n");
-		pm_power_off = dns323b_power_off;
+		register_power_off_handler_simple(dns323b_power_off,
+						  POWER_OFF_PRIORITY_DEFAULT);
 		break;
 	case DNS323_REV_C1:
 		/* 5182 built-in SATA init */
@@ -696,7 +698,8 @@ static void __init dns323_init(void)
 		if (gpio_request(DNS323C_GPIO_POWER_OFF, "POWEROFF") != 0 ||
 		    gpio_direction_output(DNS323C_GPIO_POWER_OFF, 0) != 0)
 			pr_err("DNS-323: failed to setup power-off GPIO\n");
-		pm_power_off = dns323c_power_off;
+		register_power_off_handler_simple(dns323c_power_off,
+						  POWER_OFF_PRIORITY_DEFAULT);
 
 		/* Now, -this- should theorically be done by the sata_mv driver
 		 * once I figure out what's going on there. Maybe the behaviour
diff --git a/arch/arm/mach-orion5x/kurobox_pro-setup.c b/arch/arm/mach-orion5x/kurobox_pro-setup.c
index fe6a48a..872d4fe 100644
--- a/arch/arm/mach-orion5x/kurobox_pro-setup.c
+++ b/arch/arm/mach-orion5x/kurobox_pro-setup.c
@@ -376,7 +376,8 @@ static void __init kurobox_pro_init(void)
 	i2c_register_board_info(0, &kurobox_pro_i2c_rtc, 1);
 
 	/* register Kurobox Pro specific power-off method */
-	pm_power_off = kurobox_pro_power_off;
+	register_power_off_handler_simple(kurobox_pro_power_off,
+					  POWER_OFF_PRIORITY_DEFAULT);
 }
 
 #ifdef CONFIG_MACH_KUROBOX_PRO
diff --git a/arch/arm/mach-orion5x/ls-chl-setup.c b/arch/arm/mach-orion5x/ls-chl-setup.c
index 028ea03..3f540d1 100644
--- a/arch/arm/mach-orion5x/ls-chl-setup.c
+++ b/arch/arm/mach-orion5x/ls-chl-setup.c
@@ -312,7 +312,8 @@ static void __init lschl_init(void)
 	gpio_set_value(LSCHL_GPIO_USB_POWER, 1);
 
 	/* register power-off method */
-	pm_power_off = lschl_power_off;
+	register_power_off_handler_simple(lschl_power_off,
+					  POWER_OFF_PRIORITY_FALLBACK);
 
 	pr_info("%s: finished\n", __func__);
 }
diff --git a/arch/arm/mach-orion5x/ls_hgl-setup.c b/arch/arm/mach-orion5x/ls_hgl-setup.c
index 32b7129..699a5a1 100644
--- a/arch/arm/mach-orion5x/ls_hgl-setup.c
+++ b/arch/arm/mach-orion5x/ls_hgl-setup.c
@@ -259,7 +259,8 @@ static void __init ls_hgl_init(void)
 	gpio_set_value(LS_HGL_GPIO_USB_POWER, 1);
 
 	/* register power-off method */
-	pm_power_off = ls_hgl_power_off;
+	register_power_off_handler_simple(ls_hgl_power_off,
+					  POWER_OFF_PRIORITY_FALLBACK);
 
 	pr_info("%s: finished\n", __func__);
 }
diff --git a/arch/arm/mach-orion5x/lsmini-setup.c b/arch/arm/mach-orion5x/lsmini-setup.c
index a6493e7..c5712ff 100644
--- a/arch/arm/mach-orion5x/lsmini-setup.c
+++ b/arch/arm/mach-orion5x/lsmini-setup.c
@@ -260,7 +260,8 @@ static void __init lsmini_init(void)
 	gpio_set_value(LSMINI_GPIO_USB_POWER, 1);
 
 	/* register power-off method */
-	pm_power_off = lsmini_power_off;
+	register_power_off_handler_simple(lsmini_power_off,
+					  POWER_OFF_PRIORITY_FALLBACK);
 
 	pr_info("%s: finished\n", __func__);
 }
diff --git a/arch/arm/mach-orion5x/mv2120-setup.c b/arch/arm/mach-orion5x/mv2120-setup.c
index e032f01..13efbec 100644
--- a/arch/arm/mach-orion5x/mv2120-setup.c
+++ b/arch/arm/mach-orion5x/mv2120-setup.c
@@ -225,7 +225,8 @@ static void __init mv2120_init(void)
 	if (gpio_request(MV2120_GPIO_POWER_OFF, "POWEROFF") != 0 ||
 	    gpio_direction_output(MV2120_GPIO_POWER_OFF, 1) != 0)
 		pr_err("mv2120: failed to setup power-off GPIO\n");
-	pm_power_off = mv2120_power_off;
+	register_power_off_handler_simple(mv2120_power_off,
+					  POWER_OFF_PRIORITY_DEFAULT);
 }
 
 /* Warning: HP uses a wrong mach-type (=526) in their bootloader */
diff --git a/arch/arm/mach-orion5x/net2big-setup.c b/arch/arm/mach-orion5x/net2big-setup.c
index ba73dc7..c7648f0 100644
--- a/arch/arm/mach-orion5x/net2big-setup.c
+++ b/arch/arm/mach-orion5x/net2big-setup.c
@@ -413,7 +413,8 @@ static void __init net2big_init(void)
 
 	if (gpio_request(NET2BIG_GPIO_POWER_OFF, "power-off") == 0 &&
 	    gpio_direction_output(NET2BIG_GPIO_POWER_OFF, 0) == 0)
-		pm_power_off = net2big_power_off;
+		register_power_off_handler_simple(net2big_power_off,
+						  POWER_OFF_PRIORITY_DEFAULT);
 	else
 		pr_err("net2big: failed to configure power-off GPIO\n");
 
diff --git a/arch/arm/mach-orion5x/terastation_pro2-setup.c b/arch/arm/mach-orion5x/terastation_pro2-setup.c
index 1208674..227ae91 100644
--- a/arch/arm/mach-orion5x/terastation_pro2-setup.c
+++ b/arch/arm/mach-orion5x/terastation_pro2-setup.c
@@ -353,7 +353,8 @@ static void __init tsp2_init(void)
 	i2c_register_board_info(0, &tsp2_i2c_rtc, 1);
 
 	/* register Terastation Pro II specific power-off method */
-	pm_power_off = tsp2_power_off;
+	register_power_off_handler_simple(tsp2_power_off,
+					  POWER_OFF_PRIORITY_DEFAULT);
 }
 
 MACHINE_START(TERASTATION_PRO2, "Buffalo Terastation Pro II/Live")
diff --git a/arch/arm/mach-orion5x/ts209-setup.c b/arch/arm/mach-orion5x/ts209-setup.c
index c725b7c..540e3f3 100644
--- a/arch/arm/mach-orion5x/ts209-setup.c
+++ b/arch/arm/mach-orion5x/ts209-setup.c
@@ -318,7 +318,8 @@ static void __init qnap_ts209_init(void)
 	i2c_register_board_info(0, &qnap_ts209_i2c_rtc, 1);
 
 	/* register tsx09 specific power-off method */
-	pm_power_off = qnap_tsx09_power_off;
+	register_power_off_handler_simple(qnap_tsx09_power_off,
+					  POWER_OFF_PRIORITY_DEFAULT);
 }
 
 MACHINE_START(TS209, "QNAP TS-109/TS-209")
diff --git a/arch/arm/mach-orion5x/ts409-setup.c b/arch/arm/mach-orion5x/ts409-setup.c
index cf2ab53..40cbdd7 100644
--- a/arch/arm/mach-orion5x/ts409-setup.c
+++ b/arch/arm/mach-orion5x/ts409-setup.c
@@ -307,7 +307,8 @@ static void __init qnap_ts409_init(void)
 	platform_device_register(&ts409_leds);
 
 	/* register tsx09 specific power-off method */
-	pm_power_off = qnap_tsx09_power_off;
+	register_power_off_handler_simple(qnap_tsx09_power_off,
+					  POWER_OFF_PRIORITY_DEFAULT);
 }
 
 MACHINE_START(TS409, "QNAP TS-409")
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 06022b2..93b73a1 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -718,7 +718,8 @@ static void corgi_restart(enum reboot_mode mode, const char *cmd)
 
 static void __init corgi_init(void)
 {
-	pm_power_off = corgi_poweroff;
+	register_power_off_handler_simple(corgi_poweroff,
+					  POWER_OFF_PRIORITY_FALLBACK);
 
 	/* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
 	PCFR |= PCFR_OPDE;
diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c
index 29997bd..5d318d4 100644
--- a/arch/arm/mach-pxa/mioa701.c
+++ b/arch/arm/mach-pxa/mioa701.c
@@ -750,7 +750,8 @@ static void __init mioa701_machine_init(void)
 	pxa_set_keypad_info(&mioa701_keypad_info);
 	pxa_set_udc_info(&mioa701_udc_info);
 	pxa_set_ac97_info(&mioa701_ac97_info);
-	pm_power_off = mioa701_poweroff;
+	register_power_off_handler_simple(mioa701_poweroff,
+					  POWER_OFF_PRIORITY_FALLBACK);
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 	gsm_init();
 
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 1319916..749d2af 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -432,7 +432,8 @@ static void __init poodle_init(void)
 {
 	int ret = 0;
 
-	pm_power_off = poodle_poweroff;
+	register_power_off_handler_simple(poodle_poweroff,
+					  POWER_OFF_PRIORITY_FALLBACK);
 
 	PCFR |= PCFR_OPDE;
 
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 840c3a4..ab25b6c 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -944,7 +944,8 @@ static void spitz_restart(enum reboot_mode mode, const char *cmd)
 static void __init spitz_init(void)
 {
 	init_gpio_reset(SPITZ_GPIO_ON_RESET, 1, 0);
-	pm_power_off = spitz_poweroff;
+	register_power_off_handler_simple(spitz_poweroff,
+					  POWER_OFF_PRIORITY_FALLBACK);
 
 	PMCR = 0x00;
 
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index c158a6e..8823448 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -940,7 +940,8 @@ static void __init tosa_init(void)
 
 	init_gpio_reset(TOSA_GPIO_ON_RESET, 0, 0);
 
-	pm_power_off = tosa_poweroff;
+	register_power_off_handler_simple(tosa_poweroff,
+					  POWER_OFF_PRIORITY_FALLBACK);
 
 	PCFR |= PCFR_OPDE;
 
diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c
index de3b080..6bb4de3 100644
--- a/arch/arm/mach-pxa/viper.c
+++ b/arch/arm/mach-pxa/viper.c
@@ -919,7 +919,8 @@ static void __init viper_init(void)
 {
 	u8 version;
 
-	pm_power_off = viper_power_off;
+	register_power_off_handler_simple(viper_power_off,
+					  POWER_OFF_PRIORITY_DEFAULT);
 
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(viper_pin_config));
 
diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c
index e1a121b..0d0a6ae 100644
--- a/arch/arm/mach-pxa/z2.c
+++ b/arch/arm/mach-pxa/z2.c
@@ -693,8 +693,6 @@ static void z2_power_off(void)
 	pxa27x_set_pwrmode(PWRMODE_DEEPSLEEP);
 	pxa27x_cpu_pm_enter(PM_SUSPEND_MEM);
 }
-#else
-#define z2_power_off   NULL
 #endif
 
 /******************************************************************************
@@ -719,7 +717,10 @@ static void __init z2_init(void)
 	z2_keys_init();
 	z2_pmic_init();
 
-	pm_power_off = z2_power_off;
+#ifdef CONFIG_PM
+	register_power_off_handler_simple(z2_power_off,
+					  POWER_OFF_PRIORITY_FALLBACK);
+#endif
 }
 
 MACHINE_START(ZIPIT2, "Zipit Z2")
diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c
index 205f9bf..457eed1 100644
--- a/arch/arm/mach-pxa/zeus.c
+++ b/arch/arm/mach-pxa/zeus.c
@@ -690,8 +690,6 @@ static void zeus_power_off(void)
 	local_irq_disable();
 	cpu_suspend(PWRMODE_DEEPSLEEP, pxa27x_finish_suspend);
 }
-#else
-#define zeus_power_off   NULL
 #endif
 
 #ifdef CONFIG_APM_EMULATION
@@ -847,7 +845,10 @@ static void __init zeus_init(void)
 	__raw_writel(msc0, MSC0);
 	__raw_writel(msc1, MSC1);
 
-	pm_power_off = zeus_power_off;
+#ifdef CONFIG_PM
+	register_power_off_handler_simple(zeus_power_off,
+					  POWER_OFF_PRIORITY_FALLBACK);
+#endif
 	zeus_setup_apm();
 
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(zeus_pin_config));
diff --git a/arch/arm/mach-s3c24xx/mach-gta02.c b/arch/arm/mach-s3c24xx/mach-gta02.c
index 6d1e0b9..8366b3e 100644
--- a/arch/arm/mach-s3c24xx/mach-gta02.c
+++ b/arch/arm/mach-s3c24xx/mach-gta02.c
@@ -579,7 +579,8 @@ static void __init gta02_machine_init(void)
 	i2c_register_board_info(0, gta02_i2c_devs, ARRAY_SIZE(gta02_i2c_devs));
 
 	platform_add_devices(gta02_devices, ARRAY_SIZE(gta02_devices));
-	pm_power_off = gta02_poweroff;
+	register_power_off_handler_simple(gta02_poweroff,
+					  POWER_OFF_PRIORITY_DEFAULT);
 
 	regulator_has_full_constraints();
 }
diff --git a/arch/arm/mach-s3c24xx/mach-jive.c b/arch/arm/mach-s3c24xx/mach-jive.c
index 7d99fe8..20beb39 100644
--- a/arch/arm/mach-s3c24xx/mach-jive.c
+++ b/arch/arm/mach-s3c24xx/mach-jive.c
@@ -657,7 +657,8 @@ static void __init jive_machine_init(void)
 	s3c_i2c0_set_platdata(&jive_i2c_cfg);
 	i2c_register_board_info(0, jive_i2c_devs, ARRAY_SIZE(jive_i2c_devs));
 
-	pm_power_off = jive_power_off;
+	register_power_off_handler_simple(jive_power_off,
+					  POWER_OFF_PRIORITY_DEFAULT);
 
 	platform_add_devices(jive_devices, ARRAY_SIZE(jive_devices));
 }
diff --git a/arch/arm/mach-s3c24xx/mach-vr1000.c b/arch/arm/mach-s3c24xx/mach-vr1000.c
index 89f32bd..1f32ba7 100644
--- a/arch/arm/mach-s3c24xx/mach-vr1000.c
+++ b/arch/arm/mach-s3c24xx/mach-vr1000.c
@@ -306,7 +306,8 @@ static void vr1000_power_off(void)
 
 static void __init vr1000_map_io(void)
 {
-	pm_power_off = vr1000_power_off;
+	register_power_off_handler_simple(vr1000_power_off,
+					  POWER_OFF_PRIORITY_DEFAULT);
 
 	s3c24xx_init_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc));
 	s3c24xx_init_uarts(vr1000_uartcfgs, ARRAY_SIZE(vr1000_uartcfgs));
diff --git a/arch/arm/mach-s3c64xx/mach-smartq.c b/arch/arm/mach-s3c64xx/mach-smartq.c
index b3d1353..b30906f 100644
--- a/arch/arm/mach-s3c64xx/mach-smartq.c
+++ b/arch/arm/mach-s3c64xx/mach-smartq.c
@@ -291,7 +291,8 @@ static int __init smartq_power_off_init(void)
 	/* leave power on */
 	gpio_direction_output(S3C64XX_GPK(15), 0);
 
-	pm_power_off = smartq_power_off;
+	register_power_off_handler_simple(smartq_power_off,
+					  POWER_OFF_PRIORITY_DEFAULT);
 
 	return ret;
 }
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index d4ea142..371bffe 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -311,7 +311,8 @@ static struct platform_device *sa11x0_devices[] __initdata = {
 
 static int __init sa1100_init(void)
 {
-	pm_power_off = sa1100_power_off;
+	register_power_off_handler_simple(sa1100_power_off,
+					  POWER_OFF_PRIORITY_FALLBACK);
 	return platform_add_devices(sa11x0_devices, ARRAY_SIZE(sa11x0_devices));
 }
 
diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c
index 41e476e..fb85730 100644
--- a/arch/arm/mach-sa1100/simpad.c
+++ b/arch/arm/mach-sa1100/simpad.c
@@ -373,7 +373,8 @@ static int __init simpad_init(void)
 	if (ret)
 		printk(KERN_WARNING "simpad: Unable to register cs3 GPIO device");
 
-	pm_power_off = simpad_power_off;
+	register_power_off_handler_simple(simpad_power_off,
+					  POWER_OFF_PRIORITY_FALLBACK);
 
 	sa11x0_ppc_configure_mcp();
 	sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources,
diff --git a/arch/arm/mach-u300/regulator.c b/arch/arm/mach-u300/regulator.c
index 0493a84..4ff09b0 100644
--- a/arch/arm/mach-u300/regulator.c
+++ b/arch/arm/mach-u300/regulator.c
@@ -98,7 +98,8 @@ static int __init __u300_init_boardpower(struct platform_device *pdev)
 			   U300_SYSCON_PMCR_DCON_ENABLE, 0);
 
 	/* Register globally exported PM poweroff hook */
-	pm_power_off = u300_pm_poweroff;
+	register_power_off_handler_simple(u300_pm_poweroff,
+					  POWER_OFF_PRIORITY_DEFAULT);
 
 	return 0;
 }
diff --git a/arch/arm/mach-vt8500/vt8500.c b/arch/arm/mach-vt8500/vt8500.c
index 3bc0dc9..48e4fbf 100644
--- a/arch/arm/mach-vt8500/vt8500.c
+++ b/arch/arm/mach-vt8500/vt8500.c
@@ -155,7 +155,8 @@ static void __init vt8500_init(void)
 			pr_err("%s:ioremap(power_off) failed\n", __func__);
 	}
 	if (pmc_base)
-		pm_power_off = &vt8500_power_off;
+		register_power_off_handler_simple(vt8500_power_off,
+						  POWER_OFF_PRIORITY_FALLBACK);
 	else
 		pr_err("%s: PMC Hibernation register could not be remapped, not enabling power off!\n", __func__);
 
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index 0e15f01..1c8bce0 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -336,7 +336,8 @@ static int __init xen_pm_init(void)
 	if (!xen_domain())
 		return -ENODEV;
 
-	pm_power_off = xen_power_off;
+	register_power_off_handler_simple(xen_power_off,
+					  POWER_OFF_PRIORITY_DEFAULT);
 	arm_pm_restart = xen_restart;
 
 	return 0;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 36/47] arm64: psci: Register with kernel power-off handler
       [not found] <1414425354-10359-1-git-send-email-linux@roeck-us.net>
                   ` (2 preceding siblings ...)
  2014-10-27 15:55 ` [PATCH v3 35/47] arm: " Guenter Roeck
@ 2014-10-27 15:55 ` Guenter Roeck
       [not found] ` <1414425354-10359-17-git-send-email-linux@roeck-us.net>
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Guenter Roeck @ 2014-10-27 15:55 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel power-off handler instead of setting pm_power_off
directly.

Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Tested-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v3:
- Replace poweroff in all newly introduced variables and in text
  with power_off or power-off as appropriate
- Replace POWEROFF_PRIORITY_xxx with POWER_OFF_PRIORITY_xxx
v2:
- Use define to specify poweroff handler priority

 arch/arm64/kernel/psci.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
index 866c1c8..5cab066 100644
--- a/arch/arm64/kernel/psci.c
+++ b/arch/arm64/kernel/psci.c
@@ -359,7 +359,8 @@ static int __init psci_0_2_init(struct device_node *np)
 
 	arm_pm_restart = psci_sys_reset;
 
-	pm_power_off = psci_sys_poweroff;
+	register_power_off_handler_simple(psci_sys_poweroff,
+					  POWER_OFF_PRIORITY_DEFAULT);
 
 out_put_node:
 	of_node_put(np);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 12/47] mfd: ab8500-sysctrl: Register with kernel power-off handler
  2014-10-27 15:55 ` [PATCH v3 12/47] mfd: ab8500-sysctrl: Register with kernel power-off handler Guenter Roeck
@ 2014-11-03 17:55   ` Lee Jones
  0 siblings, 0 replies; 15+ messages in thread
From: Lee Jones @ 2014-11-03 17:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 27 Oct 2014, Guenter Roeck wrote:

> Register with kernel power-off handler instead of setting pm_power_off
> directly. Register with low priority to reflect that the original code
> only sets pm_power_off if it was not already set.
> 
> sysctrl_dev is set prior to power-off handler registration, and the
> power-off handler is unregistered prior to clearing sysrctrl_dev.
> It is therefore not necessary to check if sysctrl_dev is NULL in the
> power-off handler, and the check was removed. Setting sysctrl_dev to NULL
> in the remove function was also removed as unnecessary. With those changes,
> devm_register_power_off_handler can be used to register the poeroff handler.
> The now empty remove function was retained since the ab8500_restart function,
> which is currently unused, would likely need some cleanup if it was ever used.
> 
> Cc: Linus Walleij <linus.walleij@linaro.org>
> Cc: Lee Jones <lee.jones@linaro.org>
> Cc: Samuel Ortiz <sameo@linux.intel.com>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> ---
> v3:
> - Replace poweroff in all newly introduced variables and in text
>   with power_off or power-off as appropriate
> - Replace POWEROFF_PRIORITY_xxx with POWER_OFF_PRIORITY_xxx
> v2:
> - Use define to specify poweroff handler priority
> - Use devm_register_power_off_handler
> - Use dev_warn instead of dev_err
> - Since we use devm_register_power_off_handler,
>   we need to check if sysctrl_dev in the poweroff handler to avoid
>   a race condition on unload, so this check is no longer removed
> 
>  drivers/mfd/ab8500-sysctrl.c | 23 ++++++++++++++++-------
>  1 file changed, 16 insertions(+), 7 deletions(-)

Acked-by: Lee Jones <lee.jones@linaro.org>

> diff --git a/drivers/mfd/ab8500-sysctrl.c b/drivers/mfd/ab8500-sysctrl.c
> index 8e0dae5..c49ecaf 100644
> --- a/drivers/mfd/ab8500-sysctrl.c
> +++ b/drivers/mfd/ab8500-sysctrl.c
> @@ -6,6 +6,7 @@
>  
>  #include <linux/err.h>
>  #include <linux/module.h>
> +#include <linux/notifier.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm.h>
>  #include <linux/reboot.h>
> @@ -23,7 +24,8 @@
>  
>  static struct device *sysctrl_dev;
>  
> -static void ab8500_power_off(void)
> +static int ab8500_power_off(struct notifier_block *this, unsigned long unused1,
> +			    void *unused2)
>  {
>  	sigset_t old;
>  	sigset_t all;
> @@ -36,7 +38,7 @@ static void ab8500_power_off(void)
>  
>  	if (sysctrl_dev == NULL) {
>  		pr_err("%s: sysctrl not initialized\n", __func__);
> -		return;
> +		return NOTIFY_DONE;
>  	}
>  
>  	/*
> @@ -83,8 +85,15 @@ shutdown:
>  					 AB8500_STW4500CTRL1_SWRESET4500N);
>  		(void)sigprocmask(SIG_SETMASK, &old, NULL);
>  	}
> +
> +	return NOTIFY_DONE;
>  }
>  
> +static struct notifier_block ab8500_power_off_nb = {
> +	.notifier_call = ab8500_power_off,
> +	.priority = POWER_OFF_PRIORITY_LOW,
> +};
> +
>  /*
>   * Use the AB WD to reset the platform. It will perform a hard
>   * reset instead of a soft reset. Write the reset reason to
> @@ -185,6 +194,7 @@ static int ab8500_sysctrl_probe(struct platform_device *pdev)
>  	struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
>  	struct ab8500_platform_data *plat;
>  	struct ab8500_sysctrl_platform_data *pdata;
> +	int err;
>  
>  	plat = dev_get_platdata(pdev->dev.parent);
>  
> @@ -193,8 +203,10 @@ static int ab8500_sysctrl_probe(struct platform_device *pdev)
>  
>  	sysctrl_dev = &pdev->dev;
>  
> -	if (!pm_power_off)
> -		pm_power_off = ab8500_power_off;
> +	err = devm_register_power_off_handler(sysctrl_dev,
> +					      &ab8500_power_off_nb);
> +	if (err)
> +		dev_warn(&pdev->dev, "Failed to register power-off handler\n");
>  
>  	pdata = plat->sysctrl;
>  	if (pdata) {
> @@ -228,9 +240,6 @@ static int ab8500_sysctrl_remove(struct platform_device *pdev)
>  {
>  	sysctrl_dev = NULL;
>  
> -	if (pm_power_off == ab8500_power_off)
> -		pm_power_off = NULL;
> -
>  	return 0;
>  }
>  

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v3 16/47] mfd: tps6586x: Register with kernel power-off handler
       [not found] ` <1414425354-10359-17-git-send-email-linux@roeck-us.net>
@ 2014-11-03 17:57   ` Felipe Balbi
  0 siblings, 0 replies; 15+ messages in thread
From: Felipe Balbi @ 2014-11-03 17:57 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Oct 27, 2014 at 08:55:23AM -0700, Guenter Roeck wrote:
> Register with kernel power-off handler instead of setting pm_power_off
> directly. Register with low priority to reflect that the original code
> only sets pm_power_off if it was not already set.
> 
> Cc: Samuel Ortiz <sameo@linux.intel.com>
> Cc: Lee Jones <lee.jones@linaro.org>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>

should be sent to linux-omap and lakml too

> ---
> v3:
> - Replace poweroff in all newly introduced variables and in text
>   with power_off or power-off as appropriate
> - Replace POWEROFF_PRIORITY_xxx with POWER_OFF_PRIORITY_xxx
> v2:
> - Use define to specify poweroff handler priority
> - Use dev_warn instead of dev_err
> 
>  drivers/mfd/tps6586x.c | 31 +++++++++++++++++++++++--------
>  1 file changed, 23 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c
> index 8e1dbc4..1e97478 100644
> --- a/drivers/mfd/tps6586x.c
> +++ b/drivers/mfd/tps6586x.c
> @@ -21,10 +21,12 @@
>  #include <linux/kernel.h>
>  #include <linux/module.h>
>  #include <linux/mutex.h>
> +#include <linux/notifier.h>
>  #include <linux/slab.h>
>  #include <linux/err.h>
>  #include <linux/i2c.h>
>  #include <linux/platform_device.h>
> +#include <linux/pm.h>
>  #include <linux/regmap.h>
>  #include <linux/of.h>
>  
> @@ -133,6 +135,8 @@ struct tps6586x {
>  	u32			irq_en;
>  	u8			mask_reg[5];
>  	struct irq_domain	*irq_domain;
> +
> +	struct notifier_block	power_off_nb;
>  };
>  
>  static inline struct tps6586x *dev_to_tps6586x(struct device *dev)
> @@ -472,13 +476,18 @@ static const struct regmap_config tps6586x_regmap_config = {
>  	.cache_type = REGCACHE_RBTREE,
>  };
>  
> -static struct device *tps6586x_dev;
> -static void tps6586x_power_off(void)
> +static int tps6586x_power_off(struct notifier_block *this,
> +			      unsigned long unused1, void *unused2)
>  {
> -	if (tps6586x_clr_bits(tps6586x_dev, TPS6586X_SUPPLYENE, EXITSLREQ_BIT))
> -		return;
> +	struct tps6586x *tps6586x = container_of(this, struct tps6586x,
> +						 power_off_nb);
> +
> +	if (tps6586x_clr_bits(tps6586x->dev, TPS6586X_SUPPLYENE, EXITSLREQ_BIT))
> +		return NOTIFY_DONE;
>  
> -	tps6586x_set_bits(tps6586x_dev, TPS6586X_SUPPLYENE, SLEEP_MODE_BIT);
> +	tps6586x_set_bits(tps6586x->dev, TPS6586X_SUPPLYENE, SLEEP_MODE_BIT);
> +
> +	return NOTIFY_DONE;
>  }
>  
>  static void tps6586x_print_version(struct i2c_client *client, int version)
> @@ -575,9 +584,13 @@ static int tps6586x_i2c_probe(struct i2c_client *client,
>  		goto err_add_devs;
>  	}
>  
> -	if (pdata->pm_off && !pm_power_off) {
> -		tps6586x_dev = &client->dev;
> -		pm_power_off = tps6586x_power_off;
> +	if (pdata->pm_off) {
> +		tps6586x->power_off_nb.notifier_call = tps6586x_power_off;
> +		tps6586x->power_off_nb.priority = POWER_OFF_PRIORITY_LOW;
> +		ret = register_power_off_handler(&tps6586x->power_off_nb);
> +		if (ret)
> +			dev_warn(&client->dev,
> +				 "failed to register power-off handler\n");
>  	}
>  
>  	return 0;
> @@ -594,6 +607,8 @@ static int tps6586x_i2c_remove(struct i2c_client *client)
>  {
>  	struct tps6586x *tps6586x = i2c_get_clientdata(client);
>  
> +	unregister_power_off_handler(&tps6586x->power_off_nb);
> +
>  	tps6586x_remove_subdevs(tps6586x);
>  	mfd_remove_devices(tps6586x->dev);
>  	if (client->irq)
> -- 
> 1.9.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20141103/8a95c2d7/attachment.sig>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v3 17/47] mfd: tps65910: Register with kernel power-off handler
       [not found] ` <1414425354-10359-18-git-send-email-linux@roeck-us.net>
@ 2014-11-03 17:57   ` Felipe Balbi
  0 siblings, 0 replies; 15+ messages in thread
From: Felipe Balbi @ 2014-11-03 17:57 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Oct 27, 2014 at 08:55:24AM -0700, Guenter Roeck wrote:
> Register with kernel power-off handler instead of setting pm_power_off
> directly. Register with low priority to reflect that the original code
> only sets pm_power_off if it was not already set.
> 
> Cc: Samuel Ortiz <sameo@linux.intel.com>
> Cc: Lee Jones <lee.jones@linaro.org>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>

missed lakml and linux-omap here too

> ---
> v3:
> - Replace poweroff in all newly introduced variables and in text
>   with power_off or power-off as appropriate
> - Replace POWEROFF_PRIORITY_xxx with POWER_OFF_PRIORITY_xxx
> v2:
> - Use define to specify poweroff handler priority
> - Use dev_warn instead of dev_err
> 
>  drivers/mfd/tps65910.c       | 27 ++++++++++++++++++---------
>  include/linux/mfd/tps65910.h |  3 +++
>  2 files changed, 21 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c
> index 7612d89..3c94dbf 100644
> --- a/drivers/mfd/tps65910.c
> +++ b/drivers/mfd/tps65910.c
> @@ -23,6 +23,8 @@
>  #include <linux/irq.h>
>  #include <linux/irqdomain.h>
>  #include <linux/mfd/core.h>
> +#include <linux/notifier.h>
> +#include <linux/pm.h>
>  #include <linux/regmap.h>
>  #include <linux/mfd/tps65910.h>
>  #include <linux/of.h>
> @@ -437,19 +439,20 @@ struct tps65910_board *tps65910_parse_dt(struct i2c_client *client,
>  }
>  #endif
>  
> -static struct i2c_client *tps65910_i2c_client;
> -static void tps65910_power_off(void)
> +static int tps65910_power_off(struct notifier_block *this,
> +			      unsigned long unused1, void *unused2)
>  {
> -	struct tps65910 *tps65910;
> -
> -	tps65910 = dev_get_drvdata(&tps65910_i2c_client->dev);
> +	struct tps65910 *tps65910 = container_of(this, struct tps65910,
> +						 power_off_nb);
>  
>  	if (tps65910_reg_set_bits(tps65910, TPS65910_DEVCTRL,
>  			DEVCTRL_PWR_OFF_MASK) < 0)
> -		return;
> +		return NOTIFY_DONE;
>  
>  	tps65910_reg_clear_bits(tps65910, TPS65910_DEVCTRL,
>  			DEVCTRL_DEV_ON_MASK);
> +
> +	return NOTIFY_DONE;
>  }
>  
>  static int tps65910_i2c_probe(struct i2c_client *i2c,
> @@ -505,9 +508,13 @@ static int tps65910_i2c_probe(struct i2c_client *i2c,
>  	tps65910_ck32k_init(tps65910, pmic_plat_data);
>  	tps65910_sleepinit(tps65910, pmic_plat_data);
>  
> -	if (pmic_plat_data->pm_off && !pm_power_off) {
> -		tps65910_i2c_client = i2c;
> -		pm_power_off = tps65910_power_off;
> +	if (pmic_plat_data->pm_off) {
> +		tps65910->power_off_nb.notifier_call = tps65910_power_off;
> +		tps65910->power_off_nb.priority = POWER_OFF_PRIORITY_LOW;
> +		ret = register_power_off_handler(&tps65910->power_off_nb);
> +		if (ret)
> +			dev_warn(&i2c->dev,
> +				 "failed to register power-off handler\n");
>  	}
>  
>  	ret = mfd_add_devices(tps65910->dev, -1,
> @@ -527,6 +534,8 @@ static int tps65910_i2c_remove(struct i2c_client *i2c)
>  {
>  	struct tps65910 *tps65910 = i2c_get_clientdata(i2c);
>  
> +	unregister_power_off_handler(&tps65910->power_off_nb);
> +
>  	tps65910_irq_exit(tps65910);
>  	mfd_remove_devices(tps65910->dev);
>  
> diff --git a/include/linux/mfd/tps65910.h b/include/linux/mfd/tps65910.h
> index 6483a6f..94876c4 100644
> --- a/include/linux/mfd/tps65910.h
> +++ b/include/linux/mfd/tps65910.h
> @@ -905,6 +905,9 @@ struct tps65910 {
>  	/* IRQ Handling */
>  	int chip_irq;
>  	struct regmap_irq_chip_data *irq_data;
> +
> +	/* Power-off handling */
> +	struct notifier_block power_off_nb;
>  };
>  
>  struct tps65910_platform_data {
> -- 
> 1.9.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20141103/0a98aedf/attachment.sig>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v3 00/47] kernel: Add support for power-off handler call chain
       [not found] <1414425354-10359-1-git-send-email-linux@roeck-us.net>
                   ` (5 preceding siblings ...)
       [not found] ` <1414425354-10359-18-git-send-email-linux@roeck-us.net>
@ 2014-11-03 17:59 ` Felipe Balbi
  2014-11-03 18:22   ` Guenter Roeck
       [not found] ` <1414425354-10359-10-git-send-email-linux@roeck-us.net>
  7 siblings, 1 reply; 15+ messages in thread
From: Felipe Balbi @ 2014-11-03 17:59 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Mon, Oct 27, 2014 at 08:55:07AM -0700, Guenter Roeck wrote:
> Various drivers implement architecture and/or device specific means to
> remove power from the system.  For the most part, those drivers set the
> global variable pm_power_off to point to a function within the driver.
> 
> This mechanism has a number of drawbacks.  Typically only one means
> to remove power is supported (at least if pm_power_off is used).
> At least in theory there can be multiple means to remove power, some of
> which may be less desirable.  For example, one mechanism might power off the
> entire system through an I/O port or gpio pin, while another might power off
> a board by disabling its power controller. Other mechanisms may really just
> execute a restart sequence or drop into the ROM monitor, or put the CPU into
> sleep mode.  Using pm_power_off can also be racy if the function pointer is
> set from a driver built as module, as the driver may be in the process of
> being unloaded when pm_power_off is called.  If there are multiple power-off
> handlers in the system, removing a module with such a handler may
> inadvertently reset the pointer to pm_power_off to NULL, leaving the system
> with no means to remove power.
> 
> Introduce a system power-off handler call chain to solve the described
> problems.  This call chain is expected to be executed from the architecture
> specific machine_power_off() function.  Drivers providing system power-off
> functionality are expected to register with this call chain.  By using the
> priority field in the notifier block, callers can control power-off handler
> execution sequence and thus ensure that the power-off handler with the
> optimal capabilities to remove power for a given system is called first.
> A call chain instead of a single call to the highest priority handler is
> used to provide fallback: If multiple power-off handlers are installed,
> all handlers will be called until one actually succeeds to power off the
> system.
> 
> Patch 01/47 implements the power-off handler API.
> 
> Patches 02/47 to 04/47 are cleanup patches to prepare for the move of
> pm_power_off to a common location.
> 
> Patches 05/47 to 07/47 remove references to pm_power_off from devicetree
> bindings descriptions.
> 
> Patch 08/47 moves the pm_power_off variable from architecture code to
> kernel/reboot.c. 
> 
> Patches 09/47 to 34/47 convert various drivers to register with the kernel
> power-off handler instead of setting pm_power_off directly.
> 
> Patches 35/47 to 46/47 do the same for architecture code.
> 
> Patch 47/47 finally removes pm_power_off.
> 
> For the most part, the individual patches include explanations why specific
> priorities were chosen, at least if the selected priority is not the default
> priority. Subsystem and architecture maintainers are encouraged to have a look
> at the selected priorities and suggest improvements.
> 
> I ran the final code through my normal build and qemu tests. Results are
> available at http://server.roeck-us.net:8010/builders in the 'poweroff-handler'
> column. I also built all available configurations for arm, mips, powerpc,
> m68k, and sh architectures.
> 
> The series is available in branch poweroff-handler of my repository at
> git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git.
> It is based on 3.18-rc2.
> 
> A note on Cc: In the initial submission I had way too many Cc:, causing the
> patchset to be treated as spam by many mailers and mailing list handlers,
> which of course defeated the purpose. This time around I am cutting down
> the distribution list down significantly. My apologies to anyone I may have
> failed to copy this time around.

you touch every single architecture with this patchset, but you didn't
care about Ccing any of the arch-specific mailing lists, like lakml ?

Please resend with proper people in Cc, IIRC RMK had a few very
important comments about the idea behind this series.

> Important changes since v2:
> - Rebased series to v3.18-rc2.
> - Do not hold any locks while executing the power-off call chain.
>   This ensures that power-off handlers are executed in the state
>   selected by the machine_power_off function for a given architecture,
>   ie without changing the current semantics of power-off callbacks and
>   machine_power_off functions.
>   Power-off handler registration and de-registration is handled in atomic
>   context with interrupts disabled to ensure that those functions are not
>   interrupted by code which powers off the system.
> - Use [xxx_]power_off[_xxx] instead of [xxx_]poweroff[_xxx] for newly
>   introduced function and variable names.
> - Use power-off instead of poweroff in descriptive text and comments.
> - Replace POWEROFF_PRIORITY_xxx with POWER_OFF_PRIORITY_xxx
> - Use ACPI: instead of acpi: for messages in acpi code.
> 
> Important changes since v1:
> - Rebased series to v3.18-rc1.
> - Use raw notifier with spinlock protection instead of atomic notifiers,
>   since some power-off handlers need to have interrupts enabled.
> - Renamed API functions from _poweroff to _power_off.
> - Added various Acks.
> - Build tested all configurations for arm, powerpc, and mips architectures.
> - Fixed two compile errors in mips patch.
> - Replaced dev_err and pr_err with dev_warn and pr_warn if an error is not
>   fatal.
> - Provide managed resources API and use where appropriate.
> - Provide and use definitions for standard priorities.
> - Added patches to convert newly introduced power-off handlers.
> - Various minor changes.
> 
> Important changes since RFC:
> - Move API to new file kernel/power/power_off_handler.c.
> - Move pm_power_off pointer to kernel/power/power_off_handler.c. Call
>   pm_power_off from do_kernel_power_off, and only call do_kernel_power_off
>   from architecture code instead of calling both pm_power_off and
>   do_kernel_power_off.
> - Provide additional API function register_power_off_handler_simple
>   to simplify conversion of architecture code.
> - Provide additional API function have_kernel_power_off to check if
>   a power-off handler was installed.
> - Convert all drivers and architecture code to use the new API.
> - Remove pm_power_off as last patch of the series.
> 
> Cc: Alan Cox <gnomes@lxorguk.ukuu.org.uk>
> Cc: Alexander Graf <agraf@suse.de>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Geert Uytterhoeven <geert@linux-m68k.org>
> cc: Heiko Stuebner <heiko@sntech.de>
> Cc: Lee Jones <lee.jones@linaro.org>
> Cc: Len Brown <len.brown@intel.com>
> Cc: Pavel Machek <pavel@ucw.cz>
> Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
> Cc: Romain Perier <romain.perier@gmail.com>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20141103/38ee0176/attachment.sig>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v3 09/47] mfd: palmas: Register with kernel power-off handler
       [not found]   ` <20141103175645.GT12011@x1>
@ 2014-11-03 17:59     ` Felipe Balbi
  2014-11-03 18:36       ` Guenter Roeck
  0 siblings, 1 reply; 15+ messages in thread
From: Felipe Balbi @ 2014-11-03 17:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 03, 2014 at 05:56:45PM +0000, Lee Jones wrote:
> On Mon, 27 Oct 2014, Guenter Roeck wrote:
> 
> > Register with kernel power-off handler instead of setting pm_power_off
> > directly. Register with low priority to reflect that the original code
> > only sets pm_power_off if it was not already set.
> > 
> > Cc: Samuel Ortiz <sameo@linux.intel.com>
> > Cc: Lee Jones <lee.jones@linaro.org>
> > Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> > ---
> > v3:
> > - Replace poweroff in all newly introduced variables and in text
> >   with power_off or power-off as appropriate
> > - Replace POWEROFF_PRIORITY_xxx with POWER_OFF_PRIORITY_xxx
> > v2:
> > - Use define to specify poweroff handler priority
> > - Use devm_register_power_off_handler
> > - Use dev_warn instead of dev_err
> > 
> >  drivers/mfd/palmas.c       | 31 +++++++++++++++++--------------
> >  include/linux/mfd/palmas.h |  3 +++
> >  2 files changed, 20 insertions(+), 14 deletions(-)
> 
> Acked-by: Lee Jones <lee.jones@linaro.org>

missed lakml and linux-omap.

> 
> > diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c
> > index 28cb048..99c488e 100644
> > --- a/drivers/mfd/palmas.c
> > +++ b/drivers/mfd/palmas.c
> > @@ -19,6 +19,7 @@
> >  #include <linux/i2c.h>
> >  #include <linux/interrupt.h>
> >  #include <linux/irq.h>
> > +#include <linux/pm.h>
> >  #include <linux/regmap.h>
> >  #include <linux/err.h>
> >  #include <linux/mfd/core.h>
> > @@ -425,20 +426,18 @@ static void palmas_dt_to_pdata(struct i2c_client *i2c,
> >  			"ti,system-power-controller");
> >  }
> >  
> > -static struct palmas *palmas_dev;
> > -static void palmas_power_off(void)
> > +static int palmas_power_off(struct notifier_block *this, unsigned long unused1,
> > +			    void *unused2)
> >  {
> > +	struct palmas *palmas = container_of(this, struct palmas, power_off_nb);
> >  	unsigned int addr;
> >  	int ret, slave;
> >  
> > -	if (!palmas_dev)
> > -		return;
> > -
> >  	slave = PALMAS_BASE_TO_SLAVE(PALMAS_PMU_CONTROL_BASE);
> >  	addr = PALMAS_BASE_TO_REG(PALMAS_PMU_CONTROL_BASE, PALMAS_DEV_CTRL);
> >  
> >  	ret = regmap_update_bits(
> > -			palmas_dev->regmap[slave],
> > +			palmas->regmap[slave],
> >  			addr,
> >  			PALMAS_DEV_CTRL_DEV_ON,
> >  			0);
> > @@ -446,6 +445,8 @@ static void palmas_power_off(void)
> >  	if (ret)
> >  		pr_err("%s: Unable to write to DEV_CTRL_DEV_ON: %d\n",
> >  				__func__, ret);
> > +
> > +	return NOTIFY_DONE;
> >  }
> >  
> >  static unsigned int palmas_features = PALMAS_PMIC_FEATURE_SMPS10_BOOST;
> > @@ -668,9 +669,16 @@ no_irq:
> >  		ret = of_platform_populate(node, NULL, NULL, &i2c->dev);
> >  		if (ret < 0) {
> >  			goto err_irq;
> > -		} else if (pdata->pm_off && !pm_power_off) {
> > -			palmas_dev = palmas;
> > -			pm_power_off = palmas_power_off;
> > +		} else if (pdata->pm_off) {
> > +			int ret2;
> > +
> > +			palmas->power_off_nb.notifier_call = palmas_power_off;
> > +			palmas->power_off_nb.priority = POWER_OFF_PRIORITY_LOW;
> > +			ret2 = devm_register_power_off_handler(palmas->dev,
> > +							&palmas->power_off_nb);
> > +			if (ret2)
> > +				dev_warn(palmas->dev,
> > +					 "Failed to register power-off handler");
> >  		}
> >  	}
> >  
> > @@ -698,11 +706,6 @@ static int palmas_i2c_remove(struct i2c_client *i2c)
> >  			i2c_unregister_device(palmas->i2c_clients[i]);
> >  	}
> >  
> > -	if (palmas == palmas_dev) {
> > -		pm_power_off = NULL;
> > -		palmas_dev = NULL;
> > -	}
> > -
> >  	return 0;
> >  }
> >  
> > diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h
> > index fb0390a..7dbfe24 100644
> > --- a/include/linux/mfd/palmas.h
> > +++ b/include/linux/mfd/palmas.h
> > @@ -18,6 +18,7 @@
> >  
> >  #include <linux/usb/otg.h>
> >  #include <linux/leds.h>
> > +#include <linux/notifier.h>
> >  #include <linux/regmap.h>
> >  #include <linux/regulator/driver.h>
> >  #include <linux/extcon.h>
> > @@ -68,6 +69,8 @@ struct palmas {
> >  	struct i2c_client *i2c_clients[PALMAS_NUM_CLIENTS];
> >  	struct regmap *regmap[PALMAS_NUM_CLIENTS];
> >  
> > +	struct notifier_block power_off_nb;
> > +
> >  	/* Stored chip id */
> >  	int id;
> >  
> 
> -- 
> Lee Jones
> Linaro STMicroelectronics Landing Team Lead
> Linaro.org ? Open source software for ARM SoCs
> Follow Linaro: Facebook | Twitter | Blog
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20141103/8e5a43da/attachment.sig>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v3 00/47] kernel: Add support for power-off handler call chain
  2014-11-03 17:59 ` [PATCH v3 00/47] kernel: Add support for power-off handler call chain Felipe Balbi
@ 2014-11-03 18:22   ` Guenter Roeck
  2014-11-03 18:28     ` Felipe Balbi
  0 siblings, 1 reply; 15+ messages in thread
From: Guenter Roeck @ 2014-11-03 18:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 03, 2014 at 11:59:35AM -0600, Felipe Balbi wrote:
> Hi,
> 
> On Mon, Oct 27, 2014 at 08:55:07AM -0700, Guenter Roeck wrote:
> > Various drivers implement architecture and/or device specific means to
> > remove power from the system.  For the most part, those drivers set the
> > global variable pm_power_off to point to a function within the driver.
> > 
> > This mechanism has a number of drawbacks.  Typically only one means
> > to remove power is supported (at least if pm_power_off is used).
> > At least in theory there can be multiple means to remove power, some of
> > which may be less desirable.  For example, one mechanism might power off the
> > entire system through an I/O port or gpio pin, while another might power off
> > a board by disabling its power controller. Other mechanisms may really just
> > execute a restart sequence or drop into the ROM monitor, or put the CPU into
> > sleep mode.  Using pm_power_off can also be racy if the function pointer is
> > set from a driver built as module, as the driver may be in the process of
> > being unloaded when pm_power_off is called.  If there are multiple power-off
> > handlers in the system, removing a module with such a handler may
> > inadvertently reset the pointer to pm_power_off to NULL, leaving the system
> > with no means to remove power.
> > 
> > Introduce a system power-off handler call chain to solve the described
> > problems.  This call chain is expected to be executed from the architecture
> > specific machine_power_off() function.  Drivers providing system power-off
> > functionality are expected to register with this call chain.  By using the
> > priority field in the notifier block, callers can control power-off handler
> > execution sequence and thus ensure that the power-off handler with the
> > optimal capabilities to remove power for a given system is called first.
> > A call chain instead of a single call to the highest priority handler is
> > used to provide fallback: If multiple power-off handlers are installed,
> > all handlers will be called until one actually succeeds to power off the
> > system.
> > 
> > Patch 01/47 implements the power-off handler API.
> > 
> > Patches 02/47 to 04/47 are cleanup patches to prepare for the move of
> > pm_power_off to a common location.
> > 
> > Patches 05/47 to 07/47 remove references to pm_power_off from devicetree
> > bindings descriptions.
> > 
> > Patch 08/47 moves the pm_power_off variable from architecture code to
> > kernel/reboot.c. 
> > 
> > Patches 09/47 to 34/47 convert various drivers to register with the kernel
> > power-off handler instead of setting pm_power_off directly.
> > 
> > Patches 35/47 to 46/47 do the same for architecture code.
> > 
> > Patch 47/47 finally removes pm_power_off.
> > 
> > For the most part, the individual patches include explanations why specific
> > priorities were chosen, at least if the selected priority is not the default
> > priority. Subsystem and architecture maintainers are encouraged to have a look
> > at the selected priorities and suggest improvements.
> > 
> > I ran the final code through my normal build and qemu tests. Results are
> > available at http://server.roeck-us.net:8010/builders in the 'poweroff-handler'
> > column. I also built all available configurations for arm, mips, powerpc,
> > m68k, and sh architectures.
> > 
> > The series is available in branch poweroff-handler of my repository at
> > git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git.
> > It is based on 3.18-rc2.
> > 
> > A note on Cc: In the initial submission I had way too many Cc:, causing the
> > patchset to be treated as spam by many mailers and mailing list handlers,
> > which of course defeated the purpose. This time around I am cutting down
> > the distribution list down significantly. My apologies to anyone I may have
> > failed to copy this time around.
> 
> you touch every single architecture with this patchset, but you didn't
> care about Ccing any of the arch-specific mailing lists, like lakml ?
> 
What is lakml ? linux-kernel at vger.kernel.org was copied, if that is what you
refer to. I don't find a reference to lakml anywhere, sorry. I'll be happy to
add it manually if you provide the address.

Architecture specific mailing lists were copied on individual patches as long
as those mailing lists are reported by the MAINTAINERS file.

> Please resend with proper people in Cc, IIRC RMK had a few very
> important comments about the idea behind this series.
> 
Felipe,

That doesn't work. I tried with rev 1. The result was that the patch series
was flagged as spam and got dropped by most mailing lists, as explained above,
and I got tagged as spammer by Google and several other mail servers,
preventing me from posting _anything_ for several days.

Please point me to the comments you refer to above in case I missed them.

Thanks,
Guenter

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v3 00/47] kernel: Add support for power-off handler call chain
  2014-11-03 18:22   ` Guenter Roeck
@ 2014-11-03 18:28     ` Felipe Balbi
  2014-11-03 18:49       ` Guenter Roeck
  0 siblings, 1 reply; 15+ messages in thread
From: Felipe Balbi @ 2014-11-03 18:28 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Mon, Nov 03, 2014 at 10:22:13AM -0800, Guenter Roeck wrote:
> On Mon, Nov 03, 2014 at 11:59:35AM -0600, Felipe Balbi wrote:
> > Hi,
> > 
> > On Mon, Oct 27, 2014 at 08:55:07AM -0700, Guenter Roeck wrote:
> > > Various drivers implement architecture and/or device specific means to
> > > remove power from the system.  For the most part, those drivers set the
> > > global variable pm_power_off to point to a function within the driver.
> > > 
> > > This mechanism has a number of drawbacks.  Typically only one means
> > > to remove power is supported (at least if pm_power_off is used).
> > > At least in theory there can be multiple means to remove power, some of
> > > which may be less desirable.  For example, one mechanism might power off the
> > > entire system through an I/O port or gpio pin, while another might power off
> > > a board by disabling its power controller. Other mechanisms may really just
> > > execute a restart sequence or drop into the ROM monitor, or put the CPU into
> > > sleep mode.  Using pm_power_off can also be racy if the function pointer is
> > > set from a driver built as module, as the driver may be in the process of
> > > being unloaded when pm_power_off is called.  If there are multiple power-off
> > > handlers in the system, removing a module with such a handler may
> > > inadvertently reset the pointer to pm_power_off to NULL, leaving the system
> > > with no means to remove power.
> > > 
> > > Introduce a system power-off handler call chain to solve the described
> > > problems.  This call chain is expected to be executed from the architecture
> > > specific machine_power_off() function.  Drivers providing system power-off
> > > functionality are expected to register with this call chain.  By using the
> > > priority field in the notifier block, callers can control power-off handler
> > > execution sequence and thus ensure that the power-off handler with the
> > > optimal capabilities to remove power for a given system is called first.
> > > A call chain instead of a single call to the highest priority handler is
> > > used to provide fallback: If multiple power-off handlers are installed,
> > > all handlers will be called until one actually succeeds to power off the
> > > system.
> > > 
> > > Patch 01/47 implements the power-off handler API.
> > > 
> > > Patches 02/47 to 04/47 are cleanup patches to prepare for the move of
> > > pm_power_off to a common location.
> > > 
> > > Patches 05/47 to 07/47 remove references to pm_power_off from devicetree
> > > bindings descriptions.
> > > 
> > > Patch 08/47 moves the pm_power_off variable from architecture code to
> > > kernel/reboot.c. 
> > > 
> > > Patches 09/47 to 34/47 convert various drivers to register with the kernel
> > > power-off handler instead of setting pm_power_off directly.
> > > 
> > > Patches 35/47 to 46/47 do the same for architecture code.
> > > 
> > > Patch 47/47 finally removes pm_power_off.
> > > 
> > > For the most part, the individual patches include explanations why specific
> > > priorities were chosen, at least if the selected priority is not the default
> > > priority. Subsystem and architecture maintainers are encouraged to have a look
> > > at the selected priorities and suggest improvements.
> > > 
> > > I ran the final code through my normal build and qemu tests. Results are
> > > available at http://server.roeck-us.net:8010/builders in the 'poweroff-handler'
> > > column. I also built all available configurations for arm, mips, powerpc,
> > > m68k, and sh architectures.
> > > 
> > > The series is available in branch poweroff-handler of my repository at
> > > git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git.
> > > It is based on 3.18-rc2.
> > > 
> > > A note on Cc: In the initial submission I had way too many Cc:, causing the
> > > patchset to be treated as spam by many mailers and mailing list handlers,
> > > which of course defeated the purpose. This time around I am cutting down
> > > the distribution list down significantly. My apologies to anyone I may have
> > > failed to copy this time around.
> > 
> > you touch every single architecture with this patchset, but you didn't
> > care about Ccing any of the arch-specific mailing lists, like lakml ?
> > 
> What is lakml ? linux-kernel at vger.kernel.org was copied, if that is what you

only the greatest mailing list of all time.

heh, Linux ARM Kernel Mailing List.

> refer to. I don't find a reference to lakml anywhere, sorry. I'll be happy to
> add it manually if you provide the address.
> 
> Architecture specific mailing lists were copied on individual patches as long
> as those mailing lists are reported by the MAINTAINERS file.
> 
> > Please resend with proper people in Cc, IIRC RMK had a few very
> > important comments about the idea behind this series.
> > 
> Felipe,
> 
> That doesn't work. I tried with rev 1. The result was that the patch series
> was flagged as spam and got dropped by most mailing lists, as explained above,
> and I got tagged as spammer by Google and several other mail servers,
> preventing me from posting _anything_ for several days.

heh, that sucks.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20141103/95fa263a/attachment.sig>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v3 09/47] mfd: palmas: Register with kernel power-off handler
  2014-11-03 17:59     ` [PATCH v3 09/47] mfd: palmas: Register with kernel power-off handler Felipe Balbi
@ 2014-11-03 18:36       ` Guenter Roeck
  2014-11-03 18:43         ` Felipe Balbi
  0 siblings, 1 reply; 15+ messages in thread
From: Guenter Roeck @ 2014-11-03 18:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 03, 2014 at 11:59:54AM -0600, Felipe Balbi wrote:
> On Mon, Nov 03, 2014 at 05:56:45PM +0000, Lee Jones wrote:
> > On Mon, 27 Oct 2014, Guenter Roeck wrote:
> > 
> > > Register with kernel power-off handler instead of setting pm_power_off
> > > directly. Register with low priority to reflect that the original code
> > > only sets pm_power_off if it was not already set.
> > > 
> > > Cc: Samuel Ortiz <sameo@linux.intel.com>
> > > Cc: Lee Jones <lee.jones@linaro.org>
> > > Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> > > ---
> > > v3:
> > > - Replace poweroff in all newly introduced variables and in text
> > >   with power_off or power-off as appropriate
> > > - Replace POWEROFF_PRIORITY_xxx with POWER_OFF_PRIORITY_xxx
> > > v2:
> > > - Use define to specify poweroff handler priority
> > > - Use devm_register_power_off_handler
> > > - Use dev_warn instead of dev_err
> > > 
> > >  drivers/mfd/palmas.c       | 31 +++++++++++++++++--------------
> > >  include/linux/mfd/palmas.h |  3 +++
> > >  2 files changed, 20 insertions(+), 14 deletions(-)
> > 
> > Acked-by: Lee Jones <lee.jones@linaro.org>
> 
> missed lakml and linux-omap.
> 
Felipe,

unfortunately, get_maintainer.pl doesn't give a hint that this and the
other affected patches should be sent to linux-omap. How am I supposed
to know ?

Note that linux-kernel at vger.kernel.org was copied on the entire series,
if that is what you mean with lakml. linux-pm at vger.kernel.org was also
copied on all patches. Additional mailing lists were only copied for
affected architectures to avoid for the patches to be tagged as spam.

If there is a list named lakml, I must have missed it, and I seem to be
unable to find a reference to it. If that is the case, my apologies,
and please provide a link to it.

Thanks,
Guenter

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v3 09/47] mfd: palmas: Register with kernel power-off handler
  2014-11-03 18:36       ` Guenter Roeck
@ 2014-11-03 18:43         ` Felipe Balbi
  2014-11-03 18:58           ` Guenter Roeck
  0 siblings, 1 reply; 15+ messages in thread
From: Felipe Balbi @ 2014-11-03 18:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 03, 2014 at 10:36:53AM -0800, Guenter Roeck wrote:
> On Mon, Nov 03, 2014 at 11:59:54AM -0600, Felipe Balbi wrote:
> > On Mon, Nov 03, 2014 at 05:56:45PM +0000, Lee Jones wrote:
> > > On Mon, 27 Oct 2014, Guenter Roeck wrote:
> > > 
> > > > Register with kernel power-off handler instead of setting pm_power_off
> > > > directly. Register with low priority to reflect that the original code
> > > > only sets pm_power_off if it was not already set.
> > > > 
> > > > Cc: Samuel Ortiz <sameo@linux.intel.com>
> > > > Cc: Lee Jones <lee.jones@linaro.org>
> > > > Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> > > > ---
> > > > v3:
> > > > - Replace poweroff in all newly introduced variables and in text
> > > >   with power_off or power-off as appropriate
> > > > - Replace POWEROFF_PRIORITY_xxx with POWER_OFF_PRIORITY_xxx
> > > > v2:
> > > > - Use define to specify poweroff handler priority
> > > > - Use devm_register_power_off_handler
> > > > - Use dev_warn instead of dev_err
> > > > 
> > > >  drivers/mfd/palmas.c       | 31 +++++++++++++++++--------------
> > > >  include/linux/mfd/palmas.h |  3 +++
> > > >  2 files changed, 20 insertions(+), 14 deletions(-)
> > > 
> > > Acked-by: Lee Jones <lee.jones@linaro.org>
> > 
> > missed lakml and linux-omap.
> > 
> Felipe,
> 
> unfortunately, get_maintainer.pl doesn't give a hint that this and the
> other affected patches should be sent to linux-omap. How am I supposed
> to know ?

yeah, just looked and nobody bothered to patch MAINTAINERS when those
files were added. I just sent a patch adding them under OMAP SUPPORT.

> Note that linux-kernel at vger.kernel.org was copied on the entire series,
> if that is what you mean with lakml. linux-pm at vger.kernel.org was also
> copied on all patches. Additional mailing lists were only copied for
> affected architectures to avoid for the patches to be tagged as spam.
> 
> If there is a list named lakml, I must have missed it, and I seem to be
> unable to find a reference to it. If that is the case, my apologies,
> and please provide a link to it.

here it is:

Linux ARM Kernel Mailing List <linux-arm-kernel@lists.infradead.org>

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20141103/054f402f/attachment.sig>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v3 00/47] kernel: Add support for power-off handler call chain
  2014-11-03 18:28     ` Felipe Balbi
@ 2014-11-03 18:49       ` Guenter Roeck
  0 siblings, 0 replies; 15+ messages in thread
From: Guenter Roeck @ 2014-11-03 18:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 03, 2014 at 12:28:29PM -0600, Felipe Balbi wrote:
> Hi,
> 
> On Mon, Nov 03, 2014 at 10:22:13AM -0800, Guenter Roeck wrote:
> > On Mon, Nov 03, 2014 at 11:59:35AM -0600, Felipe Balbi wrote:
> > > Hi,
> > > 
> > > On Mon, Oct 27, 2014 at 08:55:07AM -0700, Guenter Roeck wrote:
> > > > Various drivers implement architecture and/or device specific means to
> > > > remove power from the system.  For the most part, those drivers set the
> > > > global variable pm_power_off to point to a function within the driver.
> > > > 
> > > > This mechanism has a number of drawbacks.  Typically only one means
> > > > to remove power is supported (at least if pm_power_off is used).
> > > > At least in theory there can be multiple means to remove power, some of
> > > > which may be less desirable.  For example, one mechanism might power off the
> > > > entire system through an I/O port or gpio pin, while another might power off
> > > > a board by disabling its power controller. Other mechanisms may really just
> > > > execute a restart sequence or drop into the ROM monitor, or put the CPU into
> > > > sleep mode.  Using pm_power_off can also be racy if the function pointer is
> > > > set from a driver built as module, as the driver may be in the process of
> > > > being unloaded when pm_power_off is called.  If there are multiple power-off
> > > > handlers in the system, removing a module with such a handler may
> > > > inadvertently reset the pointer to pm_power_off to NULL, leaving the system
> > > > with no means to remove power.
> > > > 
> > > > Introduce a system power-off handler call chain to solve the described
> > > > problems.  This call chain is expected to be executed from the architecture
> > > > specific machine_power_off() function.  Drivers providing system power-off
> > > > functionality are expected to register with this call chain.  By using the
> > > > priority field in the notifier block, callers can control power-off handler
> > > > execution sequence and thus ensure that the power-off handler with the
> > > > optimal capabilities to remove power for a given system is called first.
> > > > A call chain instead of a single call to the highest priority handler is
> > > > used to provide fallback: If multiple power-off handlers are installed,
> > > > all handlers will be called until one actually succeeds to power off the
> > > > system.
> > > > 
> > > > Patch 01/47 implements the power-off handler API.
> > > > 
> > > > Patches 02/47 to 04/47 are cleanup patches to prepare for the move of
> > > > pm_power_off to a common location.
> > > > 
> > > > Patches 05/47 to 07/47 remove references to pm_power_off from devicetree
> > > > bindings descriptions.
> > > > 
> > > > Patch 08/47 moves the pm_power_off variable from architecture code to
> > > > kernel/reboot.c. 
> > > > 
> > > > Patches 09/47 to 34/47 convert various drivers to register with the kernel
> > > > power-off handler instead of setting pm_power_off directly.
> > > > 
> > > > Patches 35/47 to 46/47 do the same for architecture code.
> > > > 
> > > > Patch 47/47 finally removes pm_power_off.
> > > > 
> > > > For the most part, the individual patches include explanations why specific
> > > > priorities were chosen, at least if the selected priority is not the default
> > > > priority. Subsystem and architecture maintainers are encouraged to have a look
> > > > at the selected priorities and suggest improvements.
> > > > 
> > > > I ran the final code through my normal build and qemu tests. Results are
> > > > available at http://server.roeck-us.net:8010/builders in the 'poweroff-handler'
> > > > column. I also built all available configurations for arm, mips, powerpc,
> > > > m68k, and sh architectures.
> > > > 
> > > > The series is available in branch poweroff-handler of my repository at
> > > > git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git.
> > > > It is based on 3.18-rc2.
> > > > 
> > > > A note on Cc: In the initial submission I had way too many Cc:, causing the
> > > > patchset to be treated as spam by many mailers and mailing list handlers,
> > > > which of course defeated the purpose. This time around I am cutting down
> > > > the distribution list down significantly. My apologies to anyone I may have
> > > > failed to copy this time around.
> > > 
> > > you touch every single architecture with this patchset, but you didn't
> > > care about Ccing any of the arch-specific mailing lists, like lakml ?
> > > 
> > What is lakml ? linux-kernel at vger.kernel.org was copied, if that is what you
> 
> only the greatest mailing list of all time.
> 
> heh, Linux ARM Kernel Mailing List.
> 

Similar to linux-omap, linux-arm-kernel was copied on individual patches
if get_maintainer.pl suggested it. I'll be happy to add both lists manually
to the entire series for the next version of the patch set if the respective
maintainers (Tony and Russell) ask me to do so.

Note that this doesn't mean that the patches will actually be accepted by
those lists, especially if the lists are moderated for non-subscribers.

Guenter

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v3 09/47] mfd: palmas: Register with kernel power-off handler
  2014-11-03 18:43         ` Felipe Balbi
@ 2014-11-03 18:58           ` Guenter Roeck
  0 siblings, 0 replies; 15+ messages in thread
From: Guenter Roeck @ 2014-11-03 18:58 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 03, 2014 at 12:43:12PM -0600, Felipe Balbi wrote:
> On Mon, Nov 03, 2014 at 10:36:53AM -0800, Guenter Roeck wrote:
> > On Mon, Nov 03, 2014 at 11:59:54AM -0600, Felipe Balbi wrote:
> > > On Mon, Nov 03, 2014 at 05:56:45PM +0000, Lee Jones wrote:
> > > > On Mon, 27 Oct 2014, Guenter Roeck wrote:
> > > > 
> > > > > Register with kernel power-off handler instead of setting pm_power_off
> > > > > directly. Register with low priority to reflect that the original code
> > > > > only sets pm_power_off if it was not already set.
> > > > > 
> > > > > Cc: Samuel Ortiz <sameo@linux.intel.com>
> > > > > Cc: Lee Jones <lee.jones@linaro.org>
> > > > > Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> > > > > ---
> > > > > v3:
> > > > > - Replace poweroff in all newly introduced variables and in text
> > > > >   with power_off or power-off as appropriate
> > > > > - Replace POWEROFF_PRIORITY_xxx with POWER_OFF_PRIORITY_xxx
> > > > > v2:
> > > > > - Use define to specify poweroff handler priority
> > > > > - Use devm_register_power_off_handler
> > > > > - Use dev_warn instead of dev_err
> > > > > 
> > > > >  drivers/mfd/palmas.c       | 31 +++++++++++++++++--------------
> > > > >  include/linux/mfd/palmas.h |  3 +++
> > > > >  2 files changed, 20 insertions(+), 14 deletions(-)
> > > > 
> > > > Acked-by: Lee Jones <lee.jones@linaro.org>
> > > 
> > > missed lakml and linux-omap.
> > > 
> > Felipe,
> > 
> > unfortunately, get_maintainer.pl doesn't give a hint that this and the
> > other affected patches should be sent to linux-omap. How am I supposed
> > to know ?
> 
> yeah, just looked and nobody bothered to patch MAINTAINERS when those
> files were added. I just sent a patch adding them under OMAP SUPPORT.
> 
I'll add the omap list as Cc: to the affected patches directly for now.

> > Note that linux-kernel at vger.kernel.org was copied on the entire series,
> > if that is what you mean with lakml. linux-pm at vger.kernel.org was also
> > copied on all patches. Additional mailing lists were only copied for
> > affected architectures to avoid for the patches to be tagged as spam.
> > 
> > If there is a list named lakml, I must have missed it, and I seem to be
> > unable to find a reference to it. If that is the case, my apologies,
> > and please provide a link to it.
> 
> here it is:
> 
> Linux ARM Kernel Mailing List <linux-arm-kernel@lists.infradead.org>
> 
Same problem here, though. If there are any ARM specific patches where the arm
mailing list was not copied, that was because the dependency is not listed in
the MAINTAINERS file. As mentioned before, copying the entire series to all
lists touched by one of the patches in the series just doesn't work (and may
be considered severe noise by some subscribers of those lists).

Guenter

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2014-11-03 18:58 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <1414425354-10359-1-git-send-email-linux@roeck-us.net>
2014-10-27 15:55 ` [PATCH v3 08/47] kernel: Move pm_power_off to common code Guenter Roeck
2014-10-27 15:55 ` [PATCH v3 12/47] mfd: ab8500-sysctrl: Register with kernel power-off handler Guenter Roeck
2014-11-03 17:55   ` Lee Jones
2014-10-27 15:55 ` [PATCH v3 35/47] arm: " Guenter Roeck
2014-10-27 15:55 ` [PATCH v3 36/47] arm64: psci: " Guenter Roeck
     [not found] ` <1414425354-10359-17-git-send-email-linux@roeck-us.net>
2014-11-03 17:57   ` [PATCH v3 16/47] mfd: tps6586x: " Felipe Balbi
     [not found] ` <1414425354-10359-18-git-send-email-linux@roeck-us.net>
2014-11-03 17:57   ` [PATCH v3 17/47] mfd: tps65910: " Felipe Balbi
2014-11-03 17:59 ` [PATCH v3 00/47] kernel: Add support for power-off handler call chain Felipe Balbi
2014-11-03 18:22   ` Guenter Roeck
2014-11-03 18:28     ` Felipe Balbi
2014-11-03 18:49       ` Guenter Roeck
     [not found] ` <1414425354-10359-10-git-send-email-linux@roeck-us.net>
     [not found]   ` <20141103175645.GT12011@x1>
2014-11-03 17:59     ` [PATCH v3 09/47] mfd: palmas: Register with kernel power-off handler Felipe Balbi
2014-11-03 18:36       ` Guenter Roeck
2014-11-03 18:43         ` Felipe Balbi
2014-11-03 18:58           ` Guenter Roeck

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).