linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 01/44] kernel: Add support for poweroff handler call chain
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07  7:46   ` Philippe Rétornaz
                     ` (3 more replies)
  2014-10-07  5:28 ` [PATCH 02/44] memory: emif: Use API function to determine poweroff capability Guenter Roeck
                   ` (40 subsequent siblings)
  41 siblings, 4 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

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 scheme
to remove power is supported (at least if pm_power_off is used).
At least in theory there can be multiple means remove power, some of
which may be less desirable. For example, some mechanisms may only
power off the CPU or the CPU card, while another may power off the
entire system.  Others may really just execute a restart sequence
or drop into the ROM monitor. 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 poweroff 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 poweroff 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 poweroff functionality are expected to register with this call chain.
By using the priority field in the notifier block, callers can control
poweroff handler execution sequence and thus ensure that the poweroff
handler with the optimal capabilities to remove power for a given system
is called first.

Cc: Andrew Morton <akpm@linux-foundation.org>
cc: Heiko Stuebner <heiko@sntech.de>
Cc: Romain Perier <romain.perier@gmail.com>
Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Cc: Len Brown <len.brown@intel.com>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Alexander Graf <agraf@suse.de>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 include/linux/pm.h              |  13 +++
 kernel/power/Makefile           |   1 +
 kernel/power/poweroff_handler.c | 172 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 186 insertions(+)
 create mode 100644 kernel/power/poweroff_handler.c

diff --git a/include/linux/pm.h b/include/linux/pm.h
index 72c0fe0..45271b5 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -34,6 +34,19 @@
 extern void (*pm_power_off)(void);
 extern void (*pm_power_off_prepare)(void);
 
+/*
+ * Callbacks to manage poweroff handlers
+ */
+
+struct notifier_block;
+
+extern int register_poweroff_handler(struct notifier_block *);
+extern int register_poweroff_handler_simple(void (*function)(void),
+					    int priority);
+extern int unregister_poweroff_handler(struct notifier_block *);
+extern void do_kernel_poweroff(void);
+extern bool have_kernel_poweroff(void);
+
 struct device; /* we have a circular dep with device.h */
 #ifdef CONFIG_VT_CONSOLE_SLEEP
 extern void pm_vt_switch_required(struct device *dev, bool required);
diff --git a/kernel/power/Makefile b/kernel/power/Makefile
index 29472bf..4d9f0c7 100644
--- a/kernel/power/Makefile
+++ b/kernel/power/Makefile
@@ -2,6 +2,7 @@
 ccflags-$(CONFIG_PM_DEBUG)	:= -DDEBUG
 
 obj-y				+= qos.o
+obj-y				+= poweroff_handler.o
 obj-$(CONFIG_PM)		+= main.o
 obj-$(CONFIG_VT_CONSOLE_SLEEP)	+= console.o
 obj-$(CONFIG_FREEZER)		+= process.o
diff --git a/kernel/power/poweroff_handler.c b/kernel/power/poweroff_handler.c
new file mode 100644
index 0000000..ed99e5e
--- /dev/null
+++ b/kernel/power/poweroff_handler.c
@@ -0,0 +1,172 @@
+/*
+ * linux/kernel/power/poweroff_handler.c - Poweroff handling functions
+ *
+ * Copyright (c) 2014 Guenter Roeck
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#define pr_fmt(fmt)	"poweroff: " fmt
+
+#include <linux/ctype.h>
+#include <linux/export.h>
+#include <linux/kallsyms.h>
+#include <linux/notifier.h>
+#include <linux/pm.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+/*
+ *	Notifier list for kernel code which wants to be called
+ *	to power off the system.
+ */
+static ATOMIC_NOTIFIER_HEAD(poweroff_handler_list);
+
+/**
+ *	register_poweroff_handler - Register function to be called to power off
+ *				    the system
+ *	@nb: Info about handler function to be called
+ *	@nb->priority:	Handler priority. Handlers should follow the
+ *			following guidelines for setting priorities.
+ *			0:	Poweroff handler of last resort,
+ *				with limited poweroff capabilities,
+ *				such as poweroff handlers which
+ *				do not really power off the system
+ *				but loop forever or stop the CPU.
+ *			128:	Default poweroff handler; use if no other
+ *				poweroff handler is expected to be available,
+ *				and/or if poweroff functionality is
+ *				sufficient to power off the entire system
+ *			255:	Highest priority poweroff handler, will
+ *				preempt all other poweroff handlers
+ *
+ *	Registers a function with code to be called to power off the
+ *	system.
+ *
+ *	Registered functions will be called from machine_power_off as last
+ *	step of the poweroff sequence. Registered functions are expected
+ *	to power off the system immediately. If more than one function is
+ *	registered, the poweroff handler priority selects which function
+ *	will be called first.
+ *
+ *	Poweroff handlers may be registered from architecture code or from
+ *	drivers. A typical use case would be a system where power off
+ *	functionality is provided through a multi-function chip or through
+ *	a programmable power controller. Multiple poweroff handlers may exist;
+ *	for example, one poweroff handler might power off the entire system,
+ *	while another only powers off the CPU card. In such cases, the
+ *	poweroff handler which only powers off part of the hardware is
+ *	expected to register with low priority to ensure that it only
+ *	runs if no other means to power off the system are available.
+ *
+ *	Currently always returns zero, as atomic_notifier_chain_register()
+ *	always returns zero.
+ */
+int register_poweroff_handler(struct notifier_block *nb)
+{
+	return atomic_notifier_chain_register(&poweroff_handler_list, nb);
+}
+EXPORT_SYMBOL(register_poweroff_handler);
+
+/**
+ *	unregister_poweroff_handler - Unregister previously registered
+ *				      poweroff handler
+ *	@nb: Hook to be unregistered
+ *
+ *	Unregisters a previously registered poweroff handler function.
+ *
+ *	Returns zero on success, or %-ENOENT on failure.
+ */
+int unregister_poweroff_handler(struct notifier_block *nb)
+{
+	return atomic_notifier_chain_unregister(&poweroff_handler_list, nb);
+}
+EXPORT_SYMBOL(unregister_poweroff_handler);
+
+struct _poweroff_handler_data {
+	void (*handler)(void);
+	struct notifier_block poweroff_nb;
+};
+
+static int _poweroff_handler(struct notifier_block *this,
+			     unsigned long _unused1, void *_unused2)
+{
+	struct _poweroff_handler_data *poh =
+		container_of(this, struct _poweroff_handler_data, poweroff_nb);
+
+	poh->handler();
+
+	return NOTIFY_DONE;
+}
+
+static struct _poweroff_handler_data poweroff_handler_data;
+
+/**
+ *	register_poweroff_handler_simple - Register function to be called to power off
+ *					   the system
+ *	@handler:	Function to be called to power off the system
+ *	@priority:	Handler priority. For priority guidelines see
+ *			register_poweroff_handler.
+ *
+ *	This is a simplified version of register_poweroff_handler. It does not
+ *	take a notifier as argument, but a function pointer. The function
+ *	registers a poweroff handler with specified priority. Poweroff
+ *	handlers registered with this function can not be unregistered,
+ *	and only a single poweroff handler can be installed using it.
+ *
+ *	This function must not be called from modules and is therefore
+ *	not exported.
+ *
+ *	Returns -EBUSY if a poweroff handler has already been registered
+ *	using register_poweroff_handler_simple. Otherwise returns zero,
+ *	since atomic_notifier_chain_register() currently always returns zero.
+ */
+int register_poweroff_handler_simple(void (*handler)(void), int priority)
+{
+	char symname[KSYM_NAME_LEN];
+
+	if (poweroff_handler_data.handler) {
+		lookup_symbol_name((unsigned long)poweroff_handler_data.handler,
+				   symname);
+		pr_warn("Poweroff function already registered (%s)", symname);
+		lookup_symbol_name((unsigned long)handler, symname);
+		pr_cont(", cannot register %s\n", symname);
+		return -EBUSY;
+	}
+
+	poweroff_handler_data.handler = handler;
+	poweroff_handler_data.poweroff_nb.notifier_call = _poweroff_handler;
+	poweroff_handler_data.poweroff_nb.priority = priority;
+
+	return register_poweroff_handler(&poweroff_handler_data.poweroff_nb);
+}
+
+/**
+ *	do_kernel_poweroff - Execute kernel poweroff handler call chain
+ *
+ *	Calls functions registered with register_poweroff_handler.
+ *
+ *	Expected to be called from machine_power_off as last step of
+ *	the poweroff sequence.
+ *
+ *	Powers off the system immediately if a poweroff handler function
+ *	has been registered. Otherwise does nothing.
+ */
+void do_kernel_poweroff(void)
+{
+	atomic_notifier_call_chain(&poweroff_handler_list, 0, NULL);
+}
+
+/**
+ * have_kernel_poweroff() - Check if kernel poweroff handler is available
+ *
+ * Returns true is a kernel poweroff handler is available, false otherwise.
+ */
+bool have_kernel_poweroff(void)
+{
+	return pm_power_off != NULL || poweroff_handler_list.head != NULL;
+}
+EXPORT_SYMBOL(have_kernel_poweroff);
-- 
1.9.1

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

* [PATCH 02/44] memory: emif: Use API function to determine poweroff capability
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
  2014-10-07  5:28 ` [PATCH 01/44] kernel: Add support for poweroff handler call chain Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07  5:28 ` [PATCH 03/44] hibernate: Call have_kernel_poweroff instead of checking pm_power_off Guenter Roeck
                   ` (39 subsequent siblings)
  41 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Use have_kernel_poweroff() to determine if the kernel is able
to power off the system.

Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/memory/emif.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/memory/emif.c b/drivers/memory/emif.c
index 04644e7..acd830a 100644
--- a/drivers/memory/emif.c
+++ b/drivers/memory/emif.c
@@ -1053,10 +1053,10 @@ static irqreturn_t emif_threaded_isr(int irq, void *dev_id)
 		dev_emerg(emif->dev, "SDRAM temperature exceeds operating limit.. Needs shut down!!!\n");
 
 		/* If we have Power OFF ability, use it, else try restarting */
-		if (pm_power_off) {
+		if (have_kernel_poweroff()) {
 			kernel_power_off();
 		} else {
-			WARN(1, "FIXME: NO pm_power_off!!! trying restart\n");
+			WARN(1, "FIXME: NO kernel poweroff capability!!! trying restart\n");
 			kernel_restart("SDRAM Over-temp Emergency restart");
 		}
 		return IRQ_HANDLED;
-- 
1.9.1

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

* [PATCH 03/44] hibernate: Call have_kernel_poweroff instead of checking pm_power_off
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
  2014-10-07  5:28 ` [PATCH 01/44] kernel: Add support for poweroff handler call chain Guenter Roeck
  2014-10-07  5:28 ` [PATCH 02/44] memory: emif: Use API function to determine poweroff capability Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07 23:41   ` Rafael J. Wysocki
  2014-10-09 10:32   ` Pavel Machek
  2014-10-07  5:28 ` [PATCH 04/44] m68k: Replace mach_power_off with pm_power_off Guenter Roeck
                   ` (38 subsequent siblings)
  41 siblings, 2 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Poweroff handlers may now be installed with register_poweroff_handler.
Use the new API function have_kernel_poweroff to determine if a poweroff
handler has been installed.

Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Len Brown <len.brown@intel.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 kernel/power/hibernate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index a9dfa79..20353c5 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -602,7 +602,7 @@ static void power_down(void)
 	case HIBERNATION_PLATFORM:
 		hibernation_platform_enter();
 	case HIBERNATION_SHUTDOWN:
-		if (pm_power_off)
+		if (have_kernel_poweroff())
 			kernel_power_off();
 		break;
 #ifdef CONFIG_SUSPEND
-- 
1.9.1

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

* [PATCH 04/44] m68k: Replace mach_power_off with pm_power_off
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (2 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 03/44] hibernate: Call have_kernel_poweroff instead of checking pm_power_off Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07  8:29   ` Geert Uytterhoeven
  2014-10-07  5:28 ` [PATCH 05/44] mfd: as3722: Drop reference to pm_power_off from devicetree bindings Guenter Roeck
                   ` (37 subsequent siblings)
  41 siblings, 1 reply; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Replace mach_power_off with pm_power_off to simplify the subsequent
move of pm_power_off to generic code.

Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Greg Ungerer <gerg@uclinux.org>
Cc: Joshua Thompson <funaho@jurai.org>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 arch/m68k/emu/natfeat.c         | 3 ++-
 arch/m68k/include/asm/machdep.h | 1 -
 arch/m68k/kernel/process.c      | 5 +++--
 arch/m68k/kernel/setup_mm.c     | 1 -
 arch/m68k/kernel/setup_no.c     | 1 -
 arch/m68k/mac/config.c          | 3 ++-
 6 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/m68k/emu/natfeat.c b/arch/m68k/emu/natfeat.c
index 71b78ec..91e2ae7 100644
--- a/arch/m68k/emu/natfeat.c
+++ b/arch/m68k/emu/natfeat.c
@@ -15,6 +15,7 @@
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/pm.h>
 #include <linux/io.h>
 #include <asm/machdep.h>
 #include <asm/natfeat.h>
@@ -90,5 +91,5 @@ void __init nf_init(void)
 	pr_info("NatFeats found (%s, %lu.%lu)\n", buf, version >> 16,
 		version & 0xffff);
 
-	mach_power_off = nf_poweroff;
+	pm_power_off = nf_poweroff;
 }
diff --git a/arch/m68k/include/asm/machdep.h b/arch/m68k/include/asm/machdep.h
index 953ca21..f9fac51 100644
--- a/arch/m68k/include/asm/machdep.h
+++ b/arch/m68k/include/asm/machdep.h
@@ -24,7 +24,6 @@ extern int (*mach_set_rtc_pll)(struct rtc_pll_info *);
 extern int (*mach_set_clock_mmss)(unsigned long);
 extern void (*mach_reset)( void );
 extern void (*mach_halt)( void );
-extern void (*mach_power_off)( void );
 extern unsigned long (*mach_hd_init) (unsigned long, unsigned long);
 extern void (*mach_hd_setup)(char *, int *);
 extern long mach_max_dma_address;
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
index c55ff71..afe3d6e 100644
--- a/arch/m68k/kernel/process.c
+++ b/arch/m68k/kernel/process.c
@@ -22,6 +22,7 @@
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
 #include <linux/user.h>
+#include <linux/pm.h>
 #include <linux/reboot.h>
 #include <linux/init_task.h>
 #include <linux/mqueue.h>
@@ -77,8 +78,8 @@ void machine_halt(void)
 
 void machine_power_off(void)
 {
-	if (mach_power_off)
-		mach_power_off();
+	if (pm_power_off)
+		pm_power_off();
 	for (;;);
 }
 
diff --git a/arch/m68k/kernel/setup_mm.c b/arch/m68k/kernel/setup_mm.c
index 5b8ec4d..002fea6 100644
--- a/arch/m68k/kernel/setup_mm.c
+++ b/arch/m68k/kernel/setup_mm.c
@@ -96,7 +96,6 @@ EXPORT_SYMBOL(mach_get_rtc_pll);
 EXPORT_SYMBOL(mach_set_rtc_pll);
 void (*mach_reset)( void );
 void (*mach_halt)( void );
-void (*mach_power_off)( void );
 long mach_max_dma_address = 0x00ffffff; /* default set to the lower 16MB */
 #ifdef CONFIG_HEARTBEAT
 void (*mach_heartbeat) (int);
diff --git a/arch/m68k/kernel/setup_no.c b/arch/m68k/kernel/setup_no.c
index 88c27d9..1520156 100644
--- a/arch/m68k/kernel/setup_no.c
+++ b/arch/m68k/kernel/setup_no.c
@@ -55,7 +55,6 @@ int (*mach_hwclk) (int, struct rtc_time*);
 /* machine dependent reboot functions */
 void (*mach_reset)(void);
 void (*mach_halt)(void);
-void (*mach_power_off)(void);
 
 #ifdef CONFIG_M68000
 #if defined(CONFIG_M68328)
diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c
index a471eab..677913ff 100644
--- a/arch/m68k/mac/config.c
+++ b/arch/m68k/mac/config.c
@@ -16,6 +16,7 @@
 #include <linux/tty.h>
 #include <linux/console.h>
 #include <linux/interrupt.h>
+#include <linux/pm.h>
 /* keyb */
 #include <linux/random.h>
 #include <linux/delay.h>
@@ -159,7 +160,7 @@ void __init config_mac(void)
 	mach_set_clock_mmss = mac_set_clock_mmss;
 	mach_reset = mac_reset;
 	mach_halt = mac_poweroff;
-	mach_power_off = mac_poweroff;
+	pm_power_off = mac_poweroff;
 	mach_max_dma_address = 0xffffffff;
 #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE)
 	mach_beep = mac_mksound;
-- 
1.9.1

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

* [PATCH 05/44] mfd: as3722: Drop reference to pm_power_off from devicetree bindings
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (3 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 04/44] m68k: Replace mach_power_off with pm_power_off Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07 10:59   ` Mark Rutland
  2014-10-07 16:21   ` Rob Landley
  2014-10-07  5:28 ` [PATCH 06/44] gpio-poweroff: " Guenter Roeck
                   ` (36 subsequent siblings)
  41 siblings, 2 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Devicetree bindings are supposed to be operating system independent
and should thus not describe how a specific functionality is implemented
in Linux.

Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 Documentation/devicetree/bindings/mfd/as3722.txt | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/mfd/as3722.txt b/Documentation/devicetree/bindings/mfd/as3722.txt
index 4f64b2a..0b2a609 100644
--- a/Documentation/devicetree/bindings/mfd/as3722.txt
+++ b/Documentation/devicetree/bindings/mfd/as3722.txt
@@ -122,8 +122,7 @@ Following are properties of regulator subnode.
 
 Power-off:
 =========
-AS3722 supports the system power off by turning off all its rail. This
-is provided through pm_power_off.
+AS3722 supports the system power off by turning off all its rails.
 The device node should have the following properties to enable this
 functionality
 ams,system-power-controller: Boolean, to enable the power off functionality
-- 
1.9.1

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

* [PATCH 06/44] gpio-poweroff: Drop reference to pm_power_off from devicetree bindings
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (4 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 05/44] mfd: as3722: Drop reference to pm_power_off from devicetree bindings Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07 11:03   ` Mark Rutland
  2014-10-07 15:50   ` Andrew Lunn
  2014-10-07  5:28 ` [PATCH 07/44] qnap-poweroff: " Guenter Roeck
                   ` (35 subsequent siblings)
  41 siblings, 2 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

pm_power_off is an implementation detail. Replace it with a more generic
description of the driver's functionality.

Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 Documentation/devicetree/bindings/gpio/gpio-poweroff.txt | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/gpio/gpio-poweroff.txt b/Documentation/devicetree/bindings/gpio/gpio-poweroff.txt
index d4eab92..c95a1a6 100644
--- a/Documentation/devicetree/bindings/gpio/gpio-poweroff.txt
+++ b/Documentation/devicetree/bindings/gpio/gpio-poweroff.txt
@@ -2,12 +2,12 @@ Driver a GPIO line that can be used to turn the power off.
 
 The driver supports both level triggered and edge triggered power off.
 At driver load time, the driver will request the given gpio line and
-install a pm_power_off handler. If the optional properties 'input' is
-not found, the GPIO line will be driven in the inactive
+install a handler to power off the system. If the optional properties
+'input' is not found, the GPIO line will be driven in the inactive
 state. Otherwise its configured as an input.
 
-When the pm_power_off is called, the gpio is configured as an output,
-and drive active, so triggering a level triggered power off
+When the the poweroff handler is called, the gpio is configured as an
+output, and drive active, so triggering a level triggered power off
 condition. This will also cause an inactive->active edge condition, so
 triggering positive edge triggered power off. After a delay of 100ms,
 the GPIO is set to inactive, thus causing an active->inactive edge,
@@ -24,7 +24,7 @@ Required properties:
 
 Optional properties:
 - input : Initially configure the GPIO line as an input. Only reconfigure
-  it to an output when the pm_power_off function is called. If this optional
+  it to an output when the poweroff handler is called. If this optional
   property is not specified, the GPIO is initialized as an output in its
   inactive state.
 
-- 
1.9.1

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

* [PATCH 07/44] qnap-poweroff: Drop reference to pm_power_off from devicetree bindings
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (5 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 06/44] gpio-poweroff: " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07 11:02   ` Mark Rutland
  2014-10-07 15:51   ` Andrew Lunn
  2014-10-07  5:28 ` [PATCH 09/44] mfd: palmas: Register with kernel poweroff handler Guenter Roeck
                   ` (34 subsequent siblings)
  41 siblings, 2 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Replace reference to pm_power_off (which is an implementation detail)
and replace it with a more generic description of the driver's functionality.

Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 Documentation/devicetree/bindings/power_supply/qnap-poweroff.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/power_supply/qnap-poweroff.txt b/Documentation/devicetree/bindings/power_supply/qnap-poweroff.txt
index af25e77..1e2260a 100644
--- a/Documentation/devicetree/bindings/power_supply/qnap-poweroff.txt
+++ b/Documentation/devicetree/bindings/power_supply/qnap-poweroff.txt
@@ -3,8 +3,8 @@
 QNAP NAS devices have a microcontroller controlling the main power
 supply. This microcontroller is connected to UART1 of the Kirkwood and
 Orion5x SoCs. Sending the character 'A', at 19200 baud, tells the
-microcontroller to turn the power off. This driver adds a handler to
-pm_power_off which is called to turn the power off.
+microcontroller to turn the power off. This driver installs a handler
+to power off the system.
 
 Synology NAS devices use a similar scheme, but a different baud rate,
 9600, and a different character, '1'.
-- 
1.9.1

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

* [PATCH 09/44] mfd: palmas: Register with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (6 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 07/44] qnap-poweroff: " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07  5:28 ` [PATCH 10/44] mfd: axp20x: " Guenter Roeck
                   ` (33 subsequent siblings)
  41 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly. Register with a low priority value of 64 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>
---
 drivers/mfd/palmas.c       | 30 +++++++++++++++++-------------
 include/linux/mfd/palmas.h |  3 +++
 2 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c
index 28cb048..4d78847 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, poweroff_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,15 @@ 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) {
+			palmas->poweroff_nb.notifier_call = palmas_power_off;
+			palmas->poweroff_nb.priority = 64;
+			ret = register_poweroff_handler(&palmas->poweroff_nb);
+			if (ret) {
+				dev_err(palmas->dev,
+					"Failed to register poweroff handler");
+				ret = 0;
+			}
 		}
 	}
 
@@ -698,10 +705,7 @@ 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;
-	}
+	unregister_poweroff_handler(&palmas->poweroff_nb);
 
 	return 0;
 }
diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h
index fb0390a..4715057 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 poweroff_nb;
+
 	/* Stored chip id */
 	int id;
 
-- 
1.9.1

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

* [PATCH 10/44] mfd: axp20x: Register with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (7 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 09/44] mfd: palmas: Register with kernel poweroff handler Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07  5:28 ` [PATCH 11/44] mfd: retu: " Guenter Roeck
                   ` (32 subsequent siblings)
  41 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly. Register with a low priority value of 64 to reflect that
the original code only sets pm_power_off if it was not already set.

Cc: Lee Jones <lee.jones@linaro.org>
Cc: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/mfd/axp20x.c       | 30 +++++++++++++++++-------------
 include/linux/mfd/axp20x.h |  1 +
 2 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index dee6539..238db4c 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -17,7 +17,8 @@
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/pm_runtime.h>
+#include <linux/notifier.h>
+#include <linux/pm.h>
 #include <linux/regmap.h>
 #include <linux/slab.h>
 #include <linux/regulator/consumer.h>
@@ -161,11 +162,16 @@ static struct mfd_cell axp20x_cells[] = {
 	},
 };
 
-static struct axp20x_dev *axp20x_pm_power_off;
-static void axp20x_power_off(void)
+static int axp20x_power_off(struct notifier_block *this, unsigned long unused1,
+			    void *unused2)
+
 {
-	regmap_write(axp20x_pm_power_off->regmap, AXP20X_OFF_CTRL,
-		     AXP20X_OFF);
+	struct axp20x_dev *axp20x = container_of(this, struct axp20x_dev,
+						 poweroff_nb);
+
+	regmap_write(axp20x->regmap, AXP20X_OFF_CTRL, AXP20X_OFF);
+
+	return NOTIFY_DONE;
 }
 
 static int axp20x_i2c_probe(struct i2c_client *i2c,
@@ -215,10 +221,11 @@ static int axp20x_i2c_probe(struct i2c_client *i2c,
 		return ret;
 	}
 
-	if (!pm_power_off) {
-		axp20x_pm_power_off = axp20x;
-		pm_power_off = axp20x_power_off;
-	}
+	axp20x->poweroff_nb.notifier_call = axp20x_power_off;
+	axp20x->poweroff_nb.priority = 64;
+	ret = register_poweroff_handler(&axp20x->poweroff_nb);
+	if (ret)
+		dev_err(&i2c->dev, "failed to register poweroff handler\n");
 
 	dev_info(&i2c->dev, "AXP20X driver loaded\n");
 
@@ -229,10 +236,7 @@ static int axp20x_i2c_remove(struct i2c_client *i2c)
 {
 	struct axp20x_dev *axp20x = i2c_get_clientdata(i2c);
 
-	if (axp20x == axp20x_pm_power_off) {
-		axp20x_pm_power_off = NULL;
-		pm_power_off = NULL;
-	}
+	unregister_poweroff_handler(&axp20x->poweroff_nb);
 
 	mfd_remove_devices(axp20x->dev);
 	regmap_del_irq_chip(axp20x->i2c_client->irq, axp20x->regmap_irqc);
diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
index d0e31a2..8f23b39 100644
--- a/include/linux/mfd/axp20x.h
+++ b/include/linux/mfd/axp20x.h
@@ -175,6 +175,7 @@ struct axp20x_dev {
 	struct regmap			*regmap;
 	struct regmap_irq_chip_data	*regmap_irqc;
 	long				variant;
+	struct notifier_block		poweroff_nb;
 };
 
 #endif /* __LINUX_MFD_AXP20X_H */
-- 
1.9.1

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

* [PATCH 11/44] mfd: retu: Register with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (8 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 10/44] mfd: axp20x: " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07  5:28 ` [PATCH 12/44] mfd: ab8500-sysctrl: " Guenter Roeck
                   ` (31 subsequent siblings)
  41 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly. Register with a low priority value of 64 to reflect that
the original code only sets pm_power_off if it was not already set.

Cc: Lee Jones <lee.jones@linaro.org>
Cc: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/mfd/retu-mfd.c | 33 +++++++++++++++++++--------------
 1 file changed, 19 insertions(+), 14 deletions(-)

diff --git a/drivers/mfd/retu-mfd.c b/drivers/mfd/retu-mfd.c
index 663f8a3..64b60fa 100644
--- a/drivers/mfd/retu-mfd.c
+++ b/drivers/mfd/retu-mfd.c
@@ -22,6 +22,8 @@
 #include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/module.h>
+#include <linux/notifier.h>
+#include <linux/pm.h>
 #include <linux/regmap.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/retu.h>
@@ -43,6 +45,7 @@ struct retu_dev {
 	struct device			*dev;
 	struct mutex			mutex;
 	struct regmap_irq_chip_data	*irq_data;
+	struct notifier_block		poweroff_nb;
 };
 
 static struct resource retu_pwrbutton_res[] = {
@@ -81,9 +84,6 @@ static struct regmap_irq_chip retu_irq_chip = {
 	.ack_base	= RETU_REG_IDR,
 };
 
-/* Retu device registered for the power off. */
-static struct retu_dev *retu_pm_power_off;
-
 static struct resource tahvo_usb_res[] = {
 	{
 		.name	= "tahvo-usb",
@@ -165,12 +165,14 @@ int retu_write(struct retu_dev *rdev, u8 reg, u16 data)
 }
 EXPORT_SYMBOL_GPL(retu_write);
 
-static void retu_power_off(void)
+static int retu_power_off(struct notifier_block *this, unsigned long unused1,
+			  void *unused2)
 {
-	struct retu_dev *rdev = retu_pm_power_off;
+	struct retu_dev *rdev = container_of(this, struct retu_dev,
+					     poweroff_nb);
 	int reg;
 
-	mutex_lock(&retu_pm_power_off->mutex);
+	mutex_lock(&rdev->mutex);
 
 	/* Ignore power button state */
 	regmap_read(rdev->regmap, RETU_REG_CC1, &reg);
@@ -183,7 +185,9 @@ static void retu_power_off(void)
 	for (;;)
 		cpu_relax();
 
-	mutex_unlock(&retu_pm_power_off->mutex);
+	mutex_unlock(&rdev->mutex);
+
+	return NOTIFY_DONE;
 }
 
 static int retu_regmap_read(void *context, const void *reg, size_t reg_size,
@@ -279,9 +283,13 @@ static int retu_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
 		return ret;
 	}
 
-	if (i2c->addr == 1 && !pm_power_off) {
-		retu_pm_power_off = rdev;
-		pm_power_off	  = retu_power_off;
+	if (i2c->addr == 1) {
+		rdev->poweroff_nb.notifier_call = retu_power_off;
+		rdev->poweroff_nb.priority = 64;
+		ret = register_poweroff_handler(&rdev->poweroff_nb);
+		if (ret)
+			dev_err(rdev->dev,
+				"Failed to register poweroff handler\n");
 	}
 
 	return 0;
@@ -291,10 +299,7 @@ static int retu_remove(struct i2c_client *i2c)
 {
 	struct retu_dev *rdev = i2c_get_clientdata(i2c);
 
-	if (retu_pm_power_off == rdev) {
-		pm_power_off	  = NULL;
-		retu_pm_power_off = NULL;
-	}
+	unregister_poweroff_handler(&rdev->poweroff_nb);
 	mfd_remove_devices(rdev->dev);
 	regmap_del_irq_chip(i2c->irq, rdev->irq_data);
 
-- 
1.9.1

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

* [PATCH 12/44] mfd: ab8500-sysctrl: Register with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (9 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 11/44] mfd: retu: " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07  8:00   ` Lee Jones
  2014-10-07  5:28 ` [PATCH 13/44] mfd: max8907: " Guenter Roeck
                   ` (30 subsequent siblings)
  41 siblings, 1 reply; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly. Register with a low priority value of 64 to reflect that
the original code only sets pm_power_off if it was not already set.

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>
---
 drivers/mfd/ab8500-sysctrl.c | 26 +++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/drivers/mfd/ab8500-sysctrl.c b/drivers/mfd/ab8500-sysctrl.c
index 8e0dae5..677438f 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;
@@ -34,11 +36,6 @@ static void ab8500_power_off(void)
 	struct power_supply *psy;
 	int ret;
 
-	if (sysctrl_dev == NULL) {
-		pr_err("%s: sysctrl not initialized\n", __func__);
-		return;
-	}
-
 	/*
 	 * If we have a charger connected and we're powering off,
 	 * reboot into charge-only mode.
@@ -83,8 +80,15 @@ shutdown:
 					 AB8500_STW4500CTRL1_SWRESET4500N);
 		(void)sigprocmask(SIG_SETMASK, &old, NULL);
 	}
+
+	return NOTIFY_DONE;
 }
 
+static struct notifier_block ab8500_poweroff_nb = {
+	.notifier_call = ab8500_power_off,
+	.priority = 64,
+};
+
 /*
  * 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 +189,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 +198,9 @@ static int ab8500_sysctrl_probe(struct platform_device *pdev)
 
 	sysctrl_dev = &pdev->dev;
 
-	if (!pm_power_off)
-		pm_power_off = ab8500_power_off;
+	err = register_poweroff_handler(&ab8500_poweroff_nb);
+	if (err)
+		dev_err(&pdev->dev, "Failed to register poweroff handler\n");
 
 	pdata = plat->sysctrl;
 	if (pdata) {
@@ -226,11 +232,9 @@ static int ab8500_sysctrl_probe(struct platform_device *pdev)
 
 static int ab8500_sysctrl_remove(struct platform_device *pdev)
 {
+	unregister_poweroff_handler(&ab8500_poweroff_nb);
 	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] 91+ messages in thread

* [PATCH 13/44] mfd: max8907: Register with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (10 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 12/44] mfd: ab8500-sysctrl: " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07  5:28 ` [PATCH 14/44] mfd: tps80031: " Guenter Roeck
                   ` (29 subsequent siblings)
  41 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly. Register with a low priority value of 64 to reflect that
the original code only sets pm_power_off if it was not already set.

Note that this patch fixes a problem on driver unload as side effect:
The old code did not restore or clean up pm_power_off on remove,
meaning the pointer was left in an undefined state.

Cc: Lee Jones <lee.jones@linaro.org>
Cc: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/mfd/max8907.c       | 24 ++++++++++++++++++------
 include/linux/mfd/max8907.h |  2 ++
 2 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/mfd/max8907.c b/drivers/mfd/max8907.c
index 232749c..b8cddc1 100644
--- a/drivers/mfd/max8907.c
+++ b/drivers/mfd/max8907.c
@@ -19,6 +19,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/pm.h>
 #include <linux/regmap.h>
 #include <linux/slab.h>
 
@@ -177,11 +178,16 @@ static const struct regmap_irq_chip max8907_rtc_irq_chip = {
 	.num_irqs = ARRAY_SIZE(max8907_rtc_irqs),
 };
 
-static struct max8907 *max8907_pm_off;
-static void max8907_power_off(void)
+static int max8907_power_off(struct notifier_block *this, unsigned long unused1,
+			     void *unused2)
 {
-	regmap_update_bits(max8907_pm_off->regmap_gen, MAX8907_REG_RESET_CNFG,
+	struct max8907 *max8907 = container_of(this, struct max8907,
+					       poweroff_nb);
+
+	regmap_update_bits(max8907->regmap_gen, MAX8907_REG_RESET_CNFG,
 			MAX8907_MASK_POWER_OFF, MAX8907_MASK_POWER_OFF);
+
+	return NOTIFY_DONE;
 }
 
 static int max8907_i2c_probe(struct i2c_client *i2c,
@@ -267,9 +273,13 @@ static int max8907_i2c_probe(struct i2c_client *i2c,
 		goto err_add_devices;
 	}
 
-	if (pm_off && !pm_power_off) {
-		max8907_pm_off = max8907;
-		pm_power_off = max8907_power_off;
+	if (pm_off) {
+		max8907->poweroff_nb.notifier_call = max8907_power_off;
+		max8907->poweroff_nb.priority = 64;
+		ret = register_poweroff_handler(&max8907->poweroff_nb);
+		if (ret)
+			dev_err(&i2c->dev,
+				"Failed to register poweroff handler");
 	}
 
 	return 0;
@@ -293,6 +303,8 @@ static int max8907_i2c_remove(struct i2c_client *i2c)
 {
 	struct max8907 *max8907 = i2c_get_clientdata(i2c);
 
+	unregister_poweroff_handler(&max8907->poweroff_nb);
+
 	mfd_remove_devices(max8907->dev);
 
 	regmap_del_irq_chip(max8907->i2c_gen->irq, max8907->irqc_rtc);
diff --git a/include/linux/mfd/max8907.h b/include/linux/mfd/max8907.h
index b06f7a6..016428e 100644
--- a/include/linux/mfd/max8907.h
+++ b/include/linux/mfd/max8907.h
@@ -13,6 +13,7 @@
 #define __LINUX_MFD_MAX8907_H
 
 #include <linux/mutex.h>
+#include <linux/notifier.h>
 #include <linux/pm.h>
 
 #define MAX8907_GEN_I2C_ADDR		(0x78 >> 1)
@@ -247,6 +248,7 @@ struct max8907 {
 	struct regmap_irq_chip_data	*irqc_chg;
 	struct regmap_irq_chip_data	*irqc_on_off;
 	struct regmap_irq_chip_data	*irqc_rtc;
+	struct notifier_block		poweroff_nb;
 };
 
 #endif
-- 
1.9.1

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

* [PATCH 14/44] mfd: tps80031: Register with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (11 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 13/44] mfd: max8907: " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07  5:28 ` [PATCH 15/44] mfd: dm355evm_msp: " Guenter Roeck
                   ` (28 subsequent siblings)
  41 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly. Register with a low priority value of 64 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>
---
 drivers/mfd/tps80031.c       | 30 ++++++++++++++++++------------
 include/linux/mfd/tps80031.h |  2 ++
 2 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/drivers/mfd/tps80031.c b/drivers/mfd/tps80031.c
index ed6c5b0..24625a6 100644
--- a/drivers/mfd/tps80031.c
+++ b/drivers/mfd/tps80031.c
@@ -147,7 +147,6 @@ static const struct tps80031_pupd_data tps80031_pupds[] = {
 	[TPS80031_CTLI2C_SCL]		= PUPD_DATA(4, 0,	BIT(2)),
 	[TPS80031_CTLI2C_SDA]		= PUPD_DATA(4, 0,	BIT(3)),
 };
-static struct tps80031 *tps80031_power_off_dev;
 
 int tps80031_ext_power_req_config(struct device *dev,
 		unsigned long ext_ctrl_flag, int preq_bit,
@@ -209,11 +208,17 @@ int tps80031_ext_power_req_config(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(tps80031_ext_power_req_config);
 
-static void tps80031_power_off(void)
+static int tps80031_power_off(struct notifier_block *this,
+			      unsigned long unused1, void *unused2)
 {
-	dev_info(tps80031_power_off_dev->dev, "switching off PMU\n");
-	tps80031_write(tps80031_power_off_dev->dev, TPS80031_SLAVE_ID1,
-				TPS80031_PHOENIX_DEV_ON, TPS80031_DEVOFF);
+	struct tps80031 *tps80031 = container_of(this, struct tps80031,
+						 poweroff_nb);
+
+	dev_info(tps80031->dev, "switching off PMU\n");
+	tps80031_write(tps80031->dev, TPS80031_SLAVE_ID1,
+		       TPS80031_PHOENIX_DEV_ON, TPS80031_DEVOFF);
+
+	return NOTIFY_DONE;
 }
 
 static void tps80031_pupd_init(struct tps80031 *tps80031,
@@ -501,9 +506,13 @@ static int tps80031_probe(struct i2c_client *client,
 		goto fail_mfd_add;
 	}
 
-	if (pdata->use_power_off && !pm_power_off) {
-		tps80031_power_off_dev = tps80031;
-		pm_power_off = tps80031_power_off;
+	if (pdata->use_power_off) {
+		tps80031->poweroff_nb.notifier_call = tps80031_power_off;
+		tps80031->poweroff_nb.priority = 64;
+		ret = register_poweroff_handler(&tps80031->poweroff_nb);
+		if (ret)
+			dev_err(&client->dev,
+				"Failed to register poweroff handler\n");
 	}
 	return 0;
 
@@ -523,10 +532,7 @@ static int tps80031_remove(struct i2c_client *client)
 	struct tps80031 *tps80031 = i2c_get_clientdata(client);
 	int i;
 
-	if (tps80031_power_off_dev == tps80031) {
-		tps80031_power_off_dev = NULL;
-		pm_power_off = NULL;
-	}
+	unregister_poweroff_handler(&tps80031->poweroff_nb);
 
 	mfd_remove_devices(tps80031->dev);
 
diff --git a/include/linux/mfd/tps80031.h b/include/linux/mfd/tps80031.h
index 2c75c9c..49bc006 100644
--- a/include/linux/mfd/tps80031.h
+++ b/include/linux/mfd/tps80031.h
@@ -24,6 +24,7 @@
 #define __LINUX_MFD_TPS80031_H
 
 #include <linux/device.h>
+#include <linux/notifier.h>
 #include <linux/regmap.h>
 
 /* Pull-ups/Pull-downs */
@@ -513,6 +514,7 @@ struct tps80031 {
 	struct i2c_client	*clients[TPS80031_NUM_SLAVES];
 	struct regmap		*regmap[TPS80031_NUM_SLAVES];
 	struct regmap_irq_chip_data *irq_data;
+	struct notifier_block	poweroff_nb;
 };
 
 struct tps80031_pupd_init_data {
-- 
1.9.1

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

* [PATCH 15/44] mfd: dm355evm_msp: Register with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (12 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 14/44] mfd: tps80031: " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07  5:28 ` [PATCH 16/44] mfd: tps6586x: " Guenter Roeck
                   ` (27 subsequent siblings)
  41 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly. Register with a low priority value of 64 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>
---
 drivers/mfd/dm355evm_msp.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/mfd/dm355evm_msp.c b/drivers/mfd/dm355evm_msp.c
index 4c826f7..52a82f3 100644
--- a/drivers/mfd/dm355evm_msp.c
+++ b/drivers/mfd/dm355evm_msp.c
@@ -14,6 +14,8 @@
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/module.h>
+#include <linux/notifier.h>
+#include <linux/pm.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
 #include <linux/leds.h>
@@ -352,14 +354,22 @@ static void dm355evm_command(unsigned command)
 				command, status);
 }
 
-static void dm355evm_power_off(void)
+static int dm355evm_power_off(struct notifier_block *this,
+			      unsigned long unused1, void *unused2)
 {
 	dm355evm_command(MSP_COMMAND_POWEROFF);
+
+	return NOTIFY_DONE;
 }
 
+static struct notifier_block dm355evm_msp_poweroff_nb = {
+	.notifier_call = dm355evm_power_off,
+	.priority = 64,
+};
+
 static int dm355evm_msp_remove(struct i2c_client *client)
 {
-	pm_power_off = NULL;
+	unregister_poweroff_handler(&dm355evm_msp_poweroff_nb);
 	msp430 = NULL;
 	return 0;
 }
@@ -398,7 +408,9 @@ dm355evm_msp_probe(struct i2c_client *client, const struct i2c_device_id *id)
 		goto fail;
 
 	/* PM hookup */
-	pm_power_off = dm355evm_power_off;
+	status = register_poweroff_handler(&dm355evm_msp_poweroff_nb);
+	if (status)
+		dev_err(&client->dev, "Failed to register poweroff handler\n");
 
 	return 0;
 
-- 
1.9.1

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

* [PATCH 16/44] mfd: tps6586x: Register with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (13 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 15/44] mfd: dm355evm_msp: " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07  5:28 ` [PATCH 17/44] mfd: tps65910: " Guenter Roeck
                   ` (26 subsequent siblings)
  41 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly. Register with a low priority value of 64 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>
---
 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..bc14509 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	poweroff_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,
+						 poweroff_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->poweroff_nb.notifier_call = tps6586x_power_off;
+		tps6586x->poweroff_nb.priority = 64;
+		ret = register_poweroff_handler(&tps6586x->poweroff_nb);
+		if (ret)
+			dev_err(&client->dev,
+				"failed to register poweroff 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_poweroff_handler(&tps6586x->poweroff_nb);
+
 	tps6586x_remove_subdevs(tps6586x);
 	mfd_remove_devices(tps6586x->dev);
 	if (client->irq)
-- 
1.9.1

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

* [PATCH 17/44] mfd: tps65910: Register with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (14 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 16/44] mfd: tps6586x: " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07  5:28 ` [PATCH 18/44] mfd: twl4030-power: " Guenter Roeck
                   ` (25 subsequent siblings)
  41 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly. Register with a low priority value of 64 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>
---
 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 f243e75..0b114d3 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,
+						 poweroff_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,
@@ -500,9 +503,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->poweroff_nb.notifier_call = tps65910_power_off;
+		tps65910->poweroff_nb.priority = 64;
+		ret = register_poweroff_handler(&tps65910->poweroff_nb);
+		if (ret)
+			dev_err(&i2c->dev,
+				"failed to register poweroff handler\n");
 	}
 
 	ret = mfd_add_devices(tps65910->dev, -1,
@@ -522,6 +529,8 @@ static int tps65910_i2c_remove(struct i2c_client *i2c)
 {
 	struct tps65910 *tps65910 = i2c_get_clientdata(i2c);
 
+	unregister_poweroff_handler(&tps65910->poweroff_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..65cae2c 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;
+
+	/* Poweroff handling */
+	struct notifier_block poweroff_nb;
 };
 
 struct tps65910_platform_data {
-- 
1.9.1

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

* [PATCH 18/44] mfd: twl4030-power: Register with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (15 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 17/44] mfd: tps65910: " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07  7:52   ` Lee Jones
  2014-10-07  5:28 ` [PATCH 19/44] ipmi: " Guenter Roeck
                   ` (24 subsequent siblings)
  41 siblings, 1 reply; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly. Register with a low priority value of 64 to reflect that
the original code only sets pm_power_off if it was not already set.

Make twl4030_power_off static as it is only called from the twl4030-power
driver.

Cc: Samuel Ortiz <sameo@linux.intel.com>
Cc: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/mfd/twl4030-power.c | 25 +++++++++++++++++++++----
 include/linux/i2c/twl.h     |  1 -
 2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c
index 4d3ff37..bd6b830 100644
--- a/drivers/mfd/twl4030-power.c
+++ b/drivers/mfd/twl4030-power.c
@@ -25,9 +25,10 @@
  */
 
 #include <linux/module.h>
-#include <linux/pm.h>
+#include <linux/notifier.h>
 #include <linux/i2c/twl.h>
 #include <linux/platform_device.h>
+#include <linux/pm.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
 
@@ -611,7 +612,8 @@ twl4030_power_configure_resources(const struct twl4030_power_data *pdata)
  * After a successful execution, TWL shuts down the power to the SoC
  * and all peripherals connected to it.
  */
-void twl4030_power_off(void)
+static int twl4030_power_off(struct notifier_block *this, unsigned long unused1,
+			     void *unused2)
 {
 	int err;
 
@@ -619,8 +621,15 @@ void twl4030_power_off(void)
 			       TWL4030_PM_MASTER_P1_SW_EVENTS);
 	if (err)
 		pr_err("TWL4030 Unable to power off\n");
+
+	return NOTIFY_DONE;
 }
 
+static struct notifier_block twl4030_poweroff_nb = {
+	.notifier_call = twl4030_power_off,
+	.priority = 64,
+};
+
 static bool twl4030_power_use_poweroff(const struct twl4030_power_data *pdata,
 					struct device_node *node)
 {
@@ -836,7 +845,7 @@ static int twl4030_power_probe(struct platform_device *pdev)
 	}
 
 	/* Board has to be wired properly to use this feature */
-	if (twl4030_power_use_poweroff(pdata, node) && !pm_power_off) {
+	if (twl4030_power_use_poweroff(pdata, node)) {
 		/* Default for SEQ_OFFSYNC is set, lets ensure this */
 		err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &val,
 				      TWL4030_PM_MASTER_CFG_P123_TRANSITION);
@@ -853,7 +862,13 @@ static int twl4030_power_probe(struct platform_device *pdev)
 			}
 		}
 
-		pm_power_off = twl4030_power_off;
+		err = register_poweroff_handler(&twl4030_poweroff_nb);
+		if (err) {
+			dev_err(&pdev->dev,
+				"Failed to register poweroff handler\n");
+			/* Not a fatal error */
+			err = 0;
+		}
 	}
 
 relock:
@@ -869,6 +884,8 @@ relock:
 
 static int twl4030_power_remove(struct platform_device *pdev)
 {
+	unregister_poweroff_handler(&twl4030_poweroff_nb);
+
 	return 0;
 }
 
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
index 8cfb50f..f8544f1 100644
--- a/include/linux/i2c/twl.h
+++ b/include/linux/i2c/twl.h
@@ -680,7 +680,6 @@ struct twl4030_power_data {
 };
 
 extern int twl4030_remove_script(u8 flags);
-extern void twl4030_power_off(void);
 
 struct twl4030_codec_data {
 	unsigned int digimic_delay; /* in ms */
-- 
1.9.1

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

* [PATCH 19/44] ipmi: Register with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (16 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 18/44] mfd: twl4030-power: " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07  5:28 ` [PATCH 20/44] power/reset: restart-poweroff: " Guenter Roeck
                   ` (23 subsequent siblings)
  41 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly. Register with a high priority value of 192 to reflect that
the original code overwrites pm_power_off unconditionally.

Register poweroff handler after the ipmi system is ready, and unregister
it prior to cleanup. This avoids having to check for the ready variable
in the poweroff callback.

Cc: Corey Minyard <minyard@acm.org>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/char/ipmi/ipmi_poweroff.c | 30 +++++++++++++++++++-----------
 1 file changed, 19 insertions(+), 11 deletions(-)

diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c
index 9f2e3be..a942a41 100644
--- a/drivers/char/ipmi/ipmi_poweroff.c
+++ b/drivers/char/ipmi/ipmi_poweroff.c
@@ -36,6 +36,7 @@
 #include <linux/proc_fs.h>
 #include <linux/string.h>
 #include <linux/completion.h>
+#include <linux/notifier.h>
 #include <linux/pm.h>
 #include <linux/kdev_t.h>
 #include <linux/ipmi.h>
@@ -63,9 +64,6 @@ static ipmi_user_t ipmi_user;
 static int ipmi_ifnum;
 static void (*specific_poweroff_func)(ipmi_user_t user);
 
-/* Holds the old poweroff function so we can restore it on removal. */
-static void (*old_poweroff_func)(void);
-
 static int set_param_ifnum(const char *val, struct kernel_param *kp)
 {
 	int rv = param_set_int(val, kp);
@@ -544,15 +542,20 @@ static struct poweroff_function poweroff_functions[] = {
 
 
 /* Called on a powerdown request. */
-static void ipmi_poweroff_function(void)
+static int ipmi_poweroff_function(struct notifier_block *this,
+				  unsigned long unused1, void *unused2)
 {
-	if (!ready)
-		return;
-
 	/* Use run-to-completion mode, since interrupts may be off. */
 	specific_poweroff_func(ipmi_user);
+
+	return NOTIFY_DONE;
 }
 
+static struct notifier_block ipmi_poweroff_nb = {
+	.notifier_call = ipmi_poweroff_function,
+	.priority = 192,
+};
+
 /* Wait for an IPMI interface to be installed, the first one installed
    will be grabbed by this code and used to perform the powerdown. */
 static void ipmi_po_new_smi(int if_num, struct device *device)
@@ -631,9 +634,12 @@ static void ipmi_po_new_smi(int if_num, struct device *device)
 	printk(KERN_INFO PFX "Found a %s style poweroff function\n",
 	       poweroff_functions[i].platform_type);
 	specific_poweroff_func = poweroff_functions[i].poweroff_func;
-	old_poweroff_func = pm_power_off;
-	pm_power_off = ipmi_poweroff_function;
+
 	ready = 1;
+
+	rv = register_poweroff_handler(&ipmi_poweroff_nb);
+	if (rv)
+		pr_err(PFX "failed to register poweroff handler\n");
 }
 
 static void ipmi_po_smi_gone(int if_num)
@@ -644,9 +650,10 @@ static void ipmi_po_smi_gone(int if_num)
 	if (ipmi_ifnum != if_num)
 		return;
 
+	unregister_poweroff_handler(&ipmi_poweroff_nb);
+
 	ready = 0;
 	ipmi_destroy_user(ipmi_user);
-	pm_power_off = old_poweroff_func;
 }
 
 static struct ipmi_smi_watcher smi_watcher = {
@@ -732,12 +739,13 @@ static void __exit ipmi_poweroff_cleanup(void)
 
 	ipmi_smi_watcher_unregister(&smi_watcher);
 
+	unregister_poweroff_handler(&ipmi_poweroff_nb);
+
 	if (ready) {
 		rv = ipmi_destroy_user(ipmi_user);
 		if (rv)
 			printk(KERN_ERR PFX "could not cleanup the IPMI"
 			       " user: 0x%x\n", rv);
-		pm_power_off = old_poweroff_func;
 	}
 }
 module_exit(ipmi_poweroff_cleanup);
-- 
1.9.1

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

* [PATCH 20/44] power/reset: restart-poweroff: Register with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (17 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 19/44] ipmi: " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07 16:06   ` Andrew Lunn
  2014-10-07  5:28 ` [PATCH 21/44] power/reset: gpio-poweroff: " Guenter Roeck
                   ` (22 subsequent siblings)
  41 siblings, 1 reply; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of seting pm_power_off
directly.  Register as poweroff handler of last resort since the driver
does not really power off the system but executes a restart.

Cc: Sebastian Reichel <sre@kernel.org>
Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/power/reset/restart-poweroff.c | 25 ++++++++++++-------------
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/drivers/power/reset/restart-poweroff.c b/drivers/power/reset/restart-poweroff.c
index edd707e..5437697 100644
--- a/drivers/power/reset/restart-poweroff.c
+++ b/drivers/power/reset/restart-poweroff.c
@@ -12,35 +12,34 @@
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/notifier.h>
 #include <linux/platform_device.h>
 #include <linux/of_platform.h>
 #include <linux/module.h>
+#include <linux/pm.h>
 #include <linux/reboot.h>
-#include <asm/system_misc.h>
 
-static void restart_poweroff_do_poweroff(void)
+static int restart_poweroff_do_poweroff(struct notifier_block *this,
+					unsigned long unused1, void *unused2)
 {
 	reboot_mode = REBOOT_HARD;
 	machine_restart(NULL);
+
+	return NOTIFY_DONE;
 }
 
+static struct notifier_block restart_poweroff_handler = {
+	.notifier_call = restart_poweroff_do_poweroff,
+};
+
 static int restart_poweroff_probe(struct platform_device *pdev)
 {
-	/* If a pm_power_off function has already been added, leave it alone */
-	if (pm_power_off != NULL) {
-		dev_err(&pdev->dev,
-			"pm_power_off function already registered");
-		return -EBUSY;
-	}
-
-	pm_power_off = &restart_poweroff_do_poweroff;
-	return 0;
+	return register_poweroff_handler(&restart_poweroff_handler);
 }
 
 static int restart_poweroff_remove(struct platform_device *pdev)
 {
-	if (pm_power_off == &restart_poweroff_do_poweroff)
-		pm_power_off = NULL;
+	unregister_poweroff_handler(&restart_poweroff_handler);
 
 	return 0;
 }
-- 
1.9.1

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

* [PATCH 21/44] power/reset: gpio-poweroff: Register with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (18 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 20/44] power/reset: restart-poweroff: " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07 16:00   ` Andrew Lunn
  2014-10-07  5:28 ` [PATCH 22/44] power/reset: as3722-poweroff: " Guenter Roeck
                   ` (21 subsequent siblings)
  41 siblings, 1 reply; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly. Register with a low priority value of 64 to reflect that
the original code only sets pm_power_off if it was not already set.

Other changes:

Drop note that there can not be an additional instance of this driver.
The original reason no longer applies, it should be obvious that there
can only be one instance of the driver if static variables are used to
reflect its state, and support for multiple instances can now be added
easily if needed by avoiding static variables.

Do not create an error message if another poweroff handler has already been
registered. This is perfectly normal and acceptable.

Do not display a warning traceback if the poweroff handler fails to
power off the system. There may be other poweroff handlers.

Cc: Sebastian Reichel <sre@kernel.org>
Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/power/reset/gpio-poweroff.c | 36 ++++++++++++++++++------------------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/power/reset/gpio-poweroff.c b/drivers/power/reset/gpio-poweroff.c
index ce849bc..e95a7a1 100644
--- a/drivers/power/reset/gpio-poweroff.c
+++ b/drivers/power/reset/gpio-poweroff.c
@@ -14,18 +14,18 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/notifier.h>
+#include <linux/pm.h>
 #include <linux/platform_device.h>
 #include <linux/gpio/consumer.h>
 #include <linux/of_platform.h>
 #include <linux/module.h>
 
-/*
- * Hold configuration here, cannot be more than one instance of the driver
- * since pm_power_off itself is global.
- */
 static struct gpio_desc *reset_gpio;
 
-static void gpio_poweroff_do_poweroff(void)
+static int gpio_poweroff_do_poweroff(struct notifier_block *this,
+				     unsigned long unused1, void *unused2)
+
 {
 	BUG_ON(!reset_gpio);
 
@@ -42,20 +42,18 @@ static void gpio_poweroff_do_poweroff(void)
 	/* give it some time */
 	mdelay(3000);
 
-	WARN_ON(1);
+	return NOTIFY_DONE;
 }
 
+static struct notifier_block gpio_poweroff_nb = {
+	.notifier_call = gpio_poweroff_do_poweroff,
+	.priority = 64,
+};
+
 static int gpio_poweroff_probe(struct platform_device *pdev)
 {
 	bool input = false;
-
-	/* If a pm_power_off function has already been added, leave it alone */
-	if (pm_power_off != NULL) {
-		dev_err(&pdev->dev,
-			"%s: pm_power_off function already registered",
-		       __func__);
-		return -EBUSY;
-	}
+	int err;
 
 	reset_gpio = devm_gpiod_get(&pdev->dev, NULL);
 	if (IS_ERR(reset_gpio))
@@ -77,14 +75,16 @@ static int gpio_poweroff_probe(struct platform_device *pdev)
 		}
 	}
 
-	pm_power_off = &gpio_poweroff_do_poweroff;
-	return 0;
+	err = register_poweroff_handler(&gpio_poweroff_nb);
+	if (err)
+		dev_err(&pdev->dev, "Failed to register poweroff handler\n");
+
+	return err;
 }
 
 static int gpio_poweroff_remove(struct platform_device *pdev)
 {
-	if (pm_power_off == &gpio_poweroff_do_poweroff)
-		pm_power_off = NULL;
+	unregister_poweroff_handler(&gpio_poweroff_nb);
 
 	return 0;
 }
-- 
1.9.1

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

* [PATCH 22/44] power/reset: as3722-poweroff: Register with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (19 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 21/44] power/reset: gpio-poweroff: " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07  5:28 ` [PATCH 23/44] power/reset: qnap-poweroff: " Guenter Roeck
                   ` (20 subsequent siblings)
  41 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly. Register with a low priority value of 64 to reflect that
the original code only sets pm_power_off if it was not already set.

Cc: Sebastian Reichel <sre@kernel.org>
Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/power/reset/as3722-poweroff.c | 36 ++++++++++++++++++-----------------
 1 file changed, 19 insertions(+), 17 deletions(-)

diff --git a/drivers/power/reset/as3722-poweroff.c b/drivers/power/reset/as3722-poweroff.c
index 6849711..7ebaed9 100644
--- a/drivers/power/reset/as3722-poweroff.c
+++ b/drivers/power/reset/as3722-poweroff.c
@@ -17,32 +17,33 @@
 
 #include <linux/mfd/as3722.h>
 #include <linux/module.h>
+#include <linux/notifier.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
+#include <linux/pm.h>
 #include <linux/slab.h>
 
 struct as3722_poweroff {
 	struct device *dev;
 	struct as3722 *as3722;
+	struct notifier_block poweroff_nb;
 };
 
-static struct as3722_poweroff *as3722_pm_poweroff;
-
-static void as3722_pm_power_off(void)
+static int as3722_power_off(struct notifier_block *this, unsigned long unused1,
+			    void *unused2)
 {
+	struct as3722_poweroff *as3722_poweroff =
+		container_of(this, struct as3722_poweroff, poweroff_nb);
 	int ret;
 
-	if (!as3722_pm_poweroff) {
-		pr_err("AS3722 poweroff is not initialised\n");
-		return;
-	}
-
-	ret = as3722_update_bits(as3722_pm_poweroff->as3722,
+	ret = as3722_update_bits(as3722_poweroff->as3722,
 		AS3722_RESET_CONTROL_REG, AS3722_POWER_OFF, AS3722_POWER_OFF);
 	if (ret < 0)
-		dev_err(as3722_pm_poweroff->dev,
+		dev_err(as3722_poweroff->dev,
 			"RESET_CONTROL_REG update failed, %d\n", ret);
+
+	return NOTIFY_DONE;
 }
 
 static int as3722_poweroff_probe(struct platform_device *pdev)
@@ -63,18 +64,19 @@ static int as3722_poweroff_probe(struct platform_device *pdev)
 
 	as3722_poweroff->as3722 = dev_get_drvdata(pdev->dev.parent);
 	as3722_poweroff->dev = &pdev->dev;
-	as3722_pm_poweroff = as3722_poweroff;
-	if (!pm_power_off)
-		pm_power_off = as3722_pm_power_off;
+	as3722_poweroff->poweroff_nb.notifier_call = as3722_power_off;
+	as3722_poweroff->poweroff_nb.priority = 64;
 
-	return 0;
+	platform_set_drvdata(pdev, as3722_poweroff);
+
+	return register_poweroff_handler(&as3722_poweroff->poweroff_nb);
 }
 
 static int as3722_poweroff_remove(struct platform_device *pdev)
 {
-	if (pm_power_off == as3722_pm_power_off)
-		pm_power_off = NULL;
-	as3722_pm_poweroff = NULL;
+	struct as3722_poweroff *as3722_poweroff = platform_get_drvdata(pdev);
+
+	unregister_poweroff_handler(&as3722_poweroff->poweroff_nb);
 
 	return 0;
 }
-- 
1.9.1

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

* [PATCH 23/44] power/reset: qnap-poweroff: Register with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (20 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 22/44] power/reset: as3722-poweroff: " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07 16:02   ` Andrew Lunn
  2014-10-07  5:28 ` [PATCH 24/44] power/reset: msm-powroff: " Guenter Roeck
                   ` (19 subsequent siblings)
  41 siblings, 1 reply; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly. Register with default priority value of 128 to reflect that
the original code generates an error if another poweroff handler has
already been registered when the driver is loaded.

Cc: Sebastian Reichel <sre@kernel.org>
Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/power/reset/qnap-poweroff.c | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/power/reset/qnap-poweroff.c b/drivers/power/reset/qnap-poweroff.c
index a75db7f..c474980 100644
--- a/drivers/power/reset/qnap-poweroff.c
+++ b/drivers/power/reset/qnap-poweroff.c
@@ -16,7 +16,9 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/notifier.h>
 #include <linux/platform_device.h>
+#include <linux/pm.h>
 #include <linux/serial_reg.h>
 #include <linux/kallsyms.h>
 #include <linux/of.h>
@@ -55,7 +57,8 @@ static void __iomem *base;
 static unsigned long tclk;
 static const struct power_off_cfg *cfg;
 
-static void qnap_power_off(void)
+static int qnap_power_off(struct notifier_block *this, unsigned long unused1,
+			  void *unused2)
 {
 	const unsigned divisor = ((tclk + (8 * cfg->baud)) / (16 * cfg->baud));
 
@@ -72,14 +75,20 @@ static void qnap_power_off(void)
 
 	/* send the power-off command to PIC */
 	writel(cfg->cmd, UART1_REG(TX));
+
+	return NOTIFY_DONE;
 }
 
+static struct notifier_block qnap_poweroff_nb = {
+	.notifier_call = qnap_power_off,
+	.priority = 128,
+};
+
 static int qnap_power_off_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
 	struct resource *res;
 	struct clk *clk;
-	char symname[KSYM_NAME_LEN];
 
 	const struct of_device_id *match =
 		of_match_node(qnap_power_off_of_match_table, np);
@@ -106,22 +115,13 @@ static int qnap_power_off_probe(struct platform_device *pdev)
 
 	tclk = clk_get_rate(clk);
 
-	/* Check that nothing else has already setup a handler */
-	if (pm_power_off) {
-		lookup_symbol_name((ulong)pm_power_off, symname);
-		dev_err(&pdev->dev,
-			"pm_power_off already claimed %p %s",
-			pm_power_off, symname);
-		return -EBUSY;
-	}
-	pm_power_off = qnap_power_off;
-
-	return 0;
+	return register_poweroff_handler(&qnap_poweroff_nb);
 }
 
 static int qnap_power_off_remove(struct platform_device *pdev)
 {
-	pm_power_off = NULL;
+	unregister_poweroff_handler(&qnap_poweroff_nb);
+
 	return 0;
 }
 
-- 
1.9.1

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

* [PATCH 24/44] power/reset: msm-powroff: Register with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (21 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 23/44] power/reset: qnap-poweroff: " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07  5:28 ` [PATCH 25/44] power/reset: vexpress-poweroff: " Guenter Roeck
                   ` (18 subsequent siblings)
  41 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly. Select proprity 0 since the code does not really poweroff
the system.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/power/reset/msm-poweroff.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/power/reset/msm-poweroff.c b/drivers/power/reset/msm-poweroff.c
index 774f9a3..189bcd3 100644
--- a/drivers/power/reset/msm-poweroff.c
+++ b/drivers/power/reset/msm-poweroff.c
@@ -19,6 +19,7 @@
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/module.h>
+#include <linux/notifier.h>
 #include <linux/reboot.h>
 
 #include <asm/system_misc.h>
@@ -31,12 +32,19 @@ static void do_msm_restart(enum reboot_mode reboot_mode, const char *cmd)
 	mdelay(10000);
 }
 
-static void do_msm_poweroff(void)
+static int do_msm_poweroff(struct notifier_block *this,
+			   unsigned long unused1, void *unused2)
 {
 	/* TODO: Add poweroff capability */
 	do_msm_restart(REBOOT_HARD, NULL);
+
+	return NOTIFY_DONE;
 }
 
+static struct notifier_block msm_powroff_nb = {
+	.notifier_call = do_msm_poweroff,
+};
+
 static int msm_restart_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -47,7 +55,8 @@ static int msm_restart_probe(struct platform_device *pdev)
 	if (IS_ERR(msm_ps_hold))
 		return PTR_ERR(msm_ps_hold);
 
-	pm_power_off = do_msm_poweroff;
+	if (register_poweroff_handler(&msm_powroff_nb))
+		dev_err(&pdev->dev, "Failed to register poweroff handler\n");
 	arm_pm_restart = do_msm_restart;
 	return 0;
 }
-- 
1.9.1

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

* [PATCH 25/44] power/reset: vexpress-poweroff: Register with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (22 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 24/44] power/reset: msm-powroff: " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07  5:28 ` [PATCH 26/44] x86: iris: " Guenter Roeck
                   ` (17 subsequent siblings)
  41 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/power/reset/vexpress-poweroff.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/power/reset/vexpress-poweroff.c b/drivers/power/reset/vexpress-poweroff.c
index 4dc102e2..060c55d 100644
--- a/drivers/power/reset/vexpress-poweroff.c
+++ b/drivers/power/reset/vexpress-poweroff.c
@@ -12,6 +12,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/notifier.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
@@ -36,11 +37,19 @@ static void vexpress_reset_do(struct device *dev, const char *what)
 
 static struct device *vexpress_power_off_device;
 
-static void vexpress_power_off(void)
+static int vexpress_power_off(struct notifier_block *this,
+			      unsigned long unused1, void *unused2)
 {
 	vexpress_reset_do(vexpress_power_off_device, "power off");
+
+	return NOTIFY_DONE;
 }
 
+static struct notifier_block vexpress_poweroff_nb = {
+	.notifier_call = vexpress_power_off,
+	.priority = 128,
+};
+
 static struct device *vexpress_restart_device;
 
 static void vexpress_restart(enum reboot_mode reboot_mode, const char *cmd)
@@ -92,6 +101,7 @@ static int vexpress_reset_probe(struct platform_device *pdev)
 	const struct of_device_id *match =
 			of_match_device(vexpress_reset_of_match, &pdev->dev);
 	struct regmap *regmap;
+	int ret;
 
 	if (match)
 		func = (enum vexpress_reset_func)match->data;
@@ -106,7 +116,12 @@ static int vexpress_reset_probe(struct platform_device *pdev)
 	switch (func) {
 	case FUNC_SHUTDOWN:
 		vexpress_power_off_device = &pdev->dev;
-		pm_power_off = vexpress_power_off;
+		ret = register_poweroff_handler(&vexpress_poweroff_nb);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"Failed to register poweroff handler\n");
+			return ret;
+		}
 		break;
 	case FUNC_RESET:
 		if (!vexpress_restart_device)
-- 
1.9.1

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

* [PATCH 26/44] x86: iris: Register with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (23 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 25/44] power/reset: vexpress-poweroff: " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07  5:28 ` [PATCH 27/44] x86: apm: " Guenter Roeck
                   ` (16 subsequent siblings)
  41 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly. Register with high priority value of 192 to reflect that
the original code overwrites existing poweroff handlers.

Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 arch/x86/platform/iris/iris.c | 25 +++++++++++++++++++------
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/arch/x86/platform/iris/iris.c b/arch/x86/platform/iris/iris.c
index 4d171e8..662c4e8 100644
--- a/arch/x86/platform/iris/iris.c
+++ b/arch/x86/platform/iris/iris.c
@@ -23,6 +23,7 @@
 
 #include <linux/moduleparam.h>
 #include <linux/module.h>
+#include <linux/notifier.h>
 #include <linux/platform_device.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -47,15 +48,21 @@ static bool force;
 module_param(force, bool, 0);
 MODULE_PARM_DESC(force, "Set to one to force poweroff handler installation.");
 
-static void (*old_pm_power_off)(void);
-
-static void iris_power_off(void)
+static int iris_power_off(struct notifier_block *this, unsigned long unused1,
+			  void *unused2)
 {
 	outb(IRIS_GIO_PULSE, IRIS_GIO_OUTPUT);
 	msleep(850);
 	outb(IRIS_GIO_REST, IRIS_GIO_OUTPUT);
+
+	return NOTIFY_DONE;
 }
 
+static struct notifier_block iris_poweroff_nb = {
+	.notifier_call = iris_power_off,
+	.priority = 192,
+};
+
 /*
  * Before installing the power_off handler, try to make sure the OS is
  * running on an Iris.  Since Iris does not support DMI, this is done
@@ -65,20 +72,26 @@ static void iris_power_off(void)
 static int iris_probe(struct platform_device *pdev)
 {
 	unsigned char status = inb(IRIS_GIO_INPUT);
+	int ret;
+
 	if (status == IRIS_GIO_NODEV) {
 		printk(KERN_ERR "This machine does not seem to be an Iris. "
 			"Power off handler not installed.\n");
 		return -ENODEV;
 	}
-	old_pm_power_off = pm_power_off;
-	pm_power_off = &iris_power_off;
+
+	ret = register_poweroff_handler(&iris_poweroff_nb);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to register poweroff handler\n");
+		return ret;
+	}
 	printk(KERN_INFO "Iris power_off handler installed.\n");
 	return 0;
 }
 
 static int iris_remove(struct platform_device *pdev)
 {
-	pm_power_off = old_pm_power_off;
+	unregister_poweroff_handler(&iris_poweroff_nb);
 	printk(KERN_INFO "Iris power_off handler uninstalled.\n");
 	return 0;
 }
-- 
1.9.1

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

* [PATCH 27/44] x86: apm: Register with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (24 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 26/44] x86: iris: " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07  5:28 ` [PATCH 28/44] x86: olpc: Register xo1 poweroff handler " Guenter Roeck
                   ` (15 subsequent siblings)
  41 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly. Register with high priority value of 192 to reflect that
the original code overwrites existing poweroff handlers.

Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Jiri Kosina <jkosina@suse.cz>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 arch/x86/kernel/apm_32.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index 5848744..84566a6 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -219,6 +219,7 @@
 #include <linux/init.h>
 #include <linux/time.h>
 #include <linux/sched.h>
+#include <linux/notifier.h>
 #include <linux/pm.h>
 #include <linux/capability.h>
 #include <linux/device.h>
@@ -981,7 +982,8 @@ recalc:
  *	on their first cpu.
  */
 
-static void apm_power_off(void)
+static int apm_power_off(struct notifier_block *this, unsigned long unused1,
+			 void *unused2)
 {
 	/* Some bioses don't like being called from CPU != 0 */
 	if (apm_info.realmode_power_off) {
@@ -990,8 +992,14 @@ static void apm_power_off(void)
 	} else {
 		(void)set_system_power_state(APM_STATE_OFF);
 	}
+	return NOTIFY_DONE;
 }
 
+static struct notifier_block apm_poweroff_nb = {
+	.notifier_call = apm_power_off,
+	.priority = 192,
+};
+
 #ifdef CONFIG_APM_DO_ENABLE
 
 /**
@@ -1847,8 +1855,11 @@ static int apm(void *unused)
 	}
 
 	/* Install our power off handler.. */
-	if (power_off)
-		pm_power_off = apm_power_off;
+	if (power_off) {
+		error = register_poweroff_handler(&apm_poweroff_nb);
+		if (error)
+			pr_err("apm: Failed to register poweroff handler\n");
+	}
 
 	if (num_online_cpus() == 1 || smp) {
 #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
@@ -2408,9 +2419,8 @@ static void __exit apm_exit(void)
 			apm_error("disengage power management", error);
 	}
 	misc_deregister(&apm_device);
+	unregister_poweroff_handler(&apm_poweroff_nb);
 	remove_proc_entry("apm", NULL);
-	if (power_off)
-		pm_power_off = NULL;
 	if (kapmd_task) {
 		kthread_stop(kapmd_task);
 		kapmd_task = NULL;
-- 
1.9.1

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

* [PATCH 28/44] x86: olpc: Register xo1 poweroff handler with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (25 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 27/44] x86: apm: " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07  5:28 ` [PATCH 29/44] staging: nvec: Register " Guenter Roeck
                   ` (14 subsequent siblings)
  41 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly. Register with high priority value of 192 to reflect that
the driver explicitly wants to override default poweroff handlers.

Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 arch/x86/platform/olpc/olpc-xo1-pm.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/arch/x86/platform/olpc/olpc-xo1-pm.c b/arch/x86/platform/olpc/olpc-xo1-pm.c
index a9acde7..96fba36 100644
--- a/arch/x86/platform/olpc/olpc-xo1-pm.c
+++ b/arch/x86/platform/olpc/olpc-xo1-pm.c
@@ -15,6 +15,7 @@
 #include <linux/cs5535.h>
 #include <linux/platform_device.h>
 #include <linux/export.h>
+#include <linux/notifier.h>
 #include <linux/pm.h>
 #include <linux/mfd/core.h>
 #include <linux/suspend.h>
@@ -92,7 +93,8 @@ asmlinkage __visible int xo1_do_sleep(u8 sleep_state)
 	return 0;
 }
 
-static void xo1_power_off(void)
+static int xo1_power_off(struct notifier_block *this, unsigned long unused1,
+			 void *unused2)
 {
 	printk(KERN_INFO "OLPC XO-1 power off sequence...\n");
 
@@ -108,8 +110,15 @@ static void xo1_power_off(void)
 
 	/* Write SLP_EN bit to start the machinery */
 	outl(0x00002000, acpi_base + CS5536_PM1_CNT);
+
+	return NOTIFY_DONE;
 }
 
+static struct notifier_block xo1_poweroff_nb = {
+	.notifier_call = xo1_power_off,
+	.priority = 192,
+};
+
 static int xo1_power_state_valid(suspend_state_t pm_state)
 {
 	/* suspend-to-RAM only */
@@ -146,8 +155,12 @@ static int xo1_pm_probe(struct platform_device *pdev)
 
 	/* If we have both addresses, we can override the poweroff hook */
 	if (pms_base && acpi_base) {
+		err = register_poweroff_handler(&xo1_poweroff_nb);
+		if (err) {
+			dev_err(&pdev->dev, "Failed to register poweroff handler\n");
+			return err;
+		}
 		suspend_set_ops(&xo1_suspend_ops);
-		pm_power_off = xo1_power_off;
 		printk(KERN_INFO "OLPC XO-1 support registered\n");
 	}
 
@@ -158,12 +171,13 @@ static int xo1_pm_remove(struct platform_device *pdev)
 {
 	mfd_cell_disable(pdev);
 
+	unregister_poweroff_handler(&xo1_poweroff_nb);
+
 	if (strcmp(pdev->name, "cs5535-pms") == 0)
 		pms_base = 0;
 	else if (strcmp(pdev->name, "olpc-xo1-pm-acpi") == 0)
 		acpi_base = 0;
 
-	pm_power_off = NULL;
 	return 0;
 }
 
-- 
1.9.1

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

* [PATCH 29/44] staging: nvec: Register with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (26 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 28/44] x86: olpc: Register xo1 poweroff handler " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07 16:23   ` Greg Kroah-Hartman
  2014-10-08 18:51   ` Marc Dietrich
  2014-10-07  5:28 ` [PATCH 30/44] acpi: Register poweroff handler " Guenter Roeck
                   ` (13 subsequent siblings)
  41 siblings, 2 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly. Register with default priority value of 128 since we don't know
any better.

Cc: Julian Andres Klode <jak@jak-linux.org>
Cc: Marc Dietrich <marvin24@gmx.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/staging/nvec/nvec.c | 24 +++++++++++++++---------
 drivers/staging/nvec/nvec.h |  2 ++
 2 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c
index a93208a..33d406c 100644
--- a/drivers/staging/nvec/nvec.c
+++ b/drivers/staging/nvec/nvec.c
@@ -33,6 +33,7 @@
 #include <linux/mfd/core.h>
 #include <linux/mutex.h>
 #include <linux/notifier.h>
+#include <linux/pm.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/workqueue.h>
@@ -80,8 +81,6 @@ enum nvec_sleep_subcmds {
 #define LID_SWITCH BIT(1)
 #define PWR_BUTTON BIT(15)
 
-static struct nvec_chip *nvec_power_handle;
-
 static const struct mfd_cell nvec_devices[] = {
 	{
 		.name = "nvec-kbd",
@@ -759,12 +758,17 @@ static void nvec_disable_i2c_slave(struct nvec_chip *nvec)
 }
 #endif
 
-static void nvec_power_off(void)
+static int nvec_power_off(struct notifier_block *this, unsigned long unused1,
+			  void *unused2)
 {
+	struct nvec_chip *nvec = container_of(this, struct nvec_chip,
+					      poweroff_nb);
 	char ap_pwr_down[] = { NVEC_SLEEP, AP_PWR_DOWN };
 
-	nvec_toggle_global_events(nvec_power_handle, false);
-	nvec_write_async(nvec_power_handle, ap_pwr_down, 2);
+	nvec_toggle_global_events(nvec, false);
+	nvec_write_async(nvec, ap_pwr_down, 2);
+
+	return NOTIFY_DONE;
 }
 
 /*
@@ -878,8 +882,11 @@ static int tegra_nvec_probe(struct platform_device *pdev)
 	nvec->nvec_status_notifier.notifier_call = nvec_status_notifier;
 	nvec_register_notifier(nvec, &nvec->nvec_status_notifier, 0);
 
-	nvec_power_handle = nvec;
-	pm_power_off = nvec_power_off;
+	nvec->poweroff_nb.notifier_call = nvec_power_off;
+	nvec->poweroff_nb.priority = 128;
+	ret = register_poweroff_handler(&nvec->poweroff_nb);
+	if (ret)
+		dev_err(nvec->dev, "Failed to register poweroff handler\n");
 
 	/* Get Firmware Version */
 	msg = nvec_write_sync(nvec, get_firmware_version, 2);
@@ -914,13 +921,12 @@ static int tegra_nvec_remove(struct platform_device *pdev)
 {
 	struct nvec_chip *nvec = platform_get_drvdata(pdev);
 
+	unregister_poweroff_handler(&nvec->poweroff_nb);
 	nvec_toggle_global_events(nvec, false);
 	mfd_remove_devices(nvec->dev);
 	nvec_unregister_notifier(nvec, &nvec->nvec_status_notifier);
 	cancel_work_sync(&nvec->rx_work);
 	cancel_work_sync(&nvec->tx_work);
-	/* FIXME: needs check wether nvec is responsible for power off */
-	pm_power_off = NULL;
 
 	return 0;
 }
diff --git a/drivers/staging/nvec/nvec.h b/drivers/staging/nvec/nvec.h
index e271375..e5ee2af 100644
--- a/drivers/staging/nvec/nvec.h
+++ b/drivers/staging/nvec/nvec.h
@@ -163,6 +163,8 @@ struct nvec_chip {
 	struct nvec_msg *last_sync_msg;
 
 	int state;
+
+	struct notifier_block poweroff_nb;
 };
 
 extern int nvec_write_async(struct nvec_chip *nvec, const unsigned char *data,
-- 
1.9.1

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

* [PATCH 30/44] acpi: Register poweroff handler with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (27 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 29/44] staging: nvec: Register " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07  5:28 ` [PATCH 32/44] arm64: psci: Register " Guenter Roeck
                   ` (12 subsequent siblings)
  41 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly. Register with high priority value of 192 to reflect that
the driver explicitly overrides existing poweroff handlers.

Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Cc: Len Brown <lenb@kernel.org>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/acpi/sleep.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 54da4a3..25aad22 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -15,6 +15,8 @@
 #include <linux/dmi.h>
 #include <linux/device.h>
 #include <linux/suspend.h>
+#include <linux/notifier.h>
+#include <linux/pm.h>
 #include <linux/reboot.h>
 #include <linux/acpi.h>
 #include <linux/module.h>
@@ -811,14 +813,22 @@ static void acpi_power_off_prepare(void)
 	acpi_disable_all_gpes();
 }
 
-static void acpi_power_off(void)
+static int acpi_power_off(struct notifier_block *this,
+			  unsigned long unused1, void *unused2)
 {
 	/* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */
 	printk(KERN_DEBUG "%s called\n", __func__);
 	local_irq_disable();
 	acpi_enter_sleep_state(ACPI_STATE_S5);
+
+	return NOTIFY_DONE;
 }
 
+static struct notifier_block acpi_poweroff_nb = {
+	.notifier_call = acpi_power_off,
+	.priority = 192,
+};
+
 int __init acpi_sleep_init(void)
 {
 	char supported[ACPI_S_STATE_COUNT * 3 + 1];
@@ -835,7 +845,8 @@ int __init acpi_sleep_init(void)
 	if (acpi_sleep_state_supported(ACPI_STATE_S5)) {
 		sleep_states[ACPI_STATE_S5] = 1;
 		pm_power_off_prepare = acpi_power_off_prepare;
-		pm_power_off = acpi_power_off;
+		if (register_poweroff_handler(&acpi_poweroff_nb))
+			pr_err("acpi: Failed to register poweroff handler\n");
 	}
 
 	supported[0] = 0;
-- 
1.9.1

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

* [PATCH 32/44] arm64: psci: Register with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (28 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 30/44] acpi: Register poweroff handler " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-09 10:41   ` Catalin Marinas
  2014-10-07  5:28 ` [PATCH 33/44] avr32: atngw100: " Guenter Roeck
                   ` (11 subsequent siblings)
  41 siblings, 1 reply; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly.

Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 arch/arm64/kernel/psci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
index 5539547..c1f3d09 100644
--- a/arch/arm64/kernel/psci.c
+++ b/arch/arm64/kernel/psci.c
@@ -286,7 +286,7 @@ static int __init psci_0_2_init(struct device_node *np)
 
 	arm_pm_restart = psci_sys_reset;
 
-	pm_power_off = psci_sys_poweroff;
+	register_poweroff_handler_simple(psci_sys_poweroff, 128);
 
 out_put_node:
 	of_node_put(np);
-- 
1.9.1

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

* [PATCH 33/44] avr32: atngw100: Register with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (29 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 32/44] arm64: psci: Register " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-11-01 10:16   ` Hans-Christian Egtvedt
  2014-10-07  5:28 ` [PATCH 34/44] ia64: " Guenter Roeck
                   ` (10 subsequent siblings)
  41 siblings, 1 reply; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly.

Cc: Haavard Skinnemoen <hskinnemoen@gmail.com>
Cc: Hans-Christian Egtvedt <egtvedt@samfundet.no>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 arch/avr32/boards/atngw100/mrmt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/avr32/boards/atngw100/mrmt.c b/arch/avr32/boards/atngw100/mrmt.c
index 91146b4..54d0c27 100644
--- a/arch/avr32/boards/atngw100/mrmt.c
+++ b/arch/avr32/boards/atngw100/mrmt.c
@@ -274,7 +274,7 @@ static int __init mrmt1_init(void)
 {
 	gpio_set_value( PIN_PWR_ON, 1 );	/* Ensure PWR_ON is enabled */
 
-	pm_power_off = mrmt_power_off;
+	register_poweroff_handler_simple(mrmt_power_off, 128);
 
 	/* Setup USARTS (other than console) */
 	at32_map_usart(2, 1, 0);	/* USART 2: /dev/ttyS1, RMT1:DB9M */
-- 
1.9.1

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

* [PATCH 34/44] ia64: Register with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (30 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 33/44] avr32: atngw100: " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07  5:28 ` [PATCH 35/44] m68k: " Guenter Roeck
                   ` (9 subsequent siblings)
  41 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly. Register with lower priority of 64 to reflect that the call
is expected to be replaced at some point.

Cc: Tony Luck <tony.luck@intel.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 arch/ia64/sn/kernel/setup.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
index 36182c8..6c83425 100644
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -488,12 +488,12 @@ void __init sn_setup(char **cmdline_p)
 	sn_timer_init();
 
 	/*
-	 * set pm_power_off to a SAL call to allow
+	 * set poweroff handler to a SAL call to allow
 	 * sn machines to power off. The SAL call can be replaced
 	 * by an ACPI interface call when ACPI is fully implemented
 	 * for sn.
 	 */
-	pm_power_off = ia64_sn_power_down;
+	register_poweroff_handler_simple(ia64_sn_power_down, 64);
 	current->thread.flags |= IA64_THREAD_MIGRATION;
 }
 
-- 
1.9.1

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

* [PATCH 35/44] m68k: Register with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (31 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 34/44] ia64: " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07  9:19   ` Geert Uytterhoeven
  2014-10-07  5:28 ` [PATCH 36/44] mips: " Guenter Roeck
                   ` (8 subsequent siblings)
  41 siblings, 1 reply; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly.

Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Joshua Thompson <funaho@jurai.org>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 arch/m68k/emu/natfeat.c | 2 +-
 arch/m68k/mac/config.c  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/m68k/emu/natfeat.c b/arch/m68k/emu/natfeat.c
index 91e2ae7..c4d5bd8 100644
--- a/arch/m68k/emu/natfeat.c
+++ b/arch/m68k/emu/natfeat.c
@@ -91,5 +91,5 @@ void __init nf_init(void)
 	pr_info("NatFeats found (%s, %lu.%lu)\n", buf, version >> 16,
 		version & 0xffff);
 
-	pm_power_off = nf_poweroff;
+	register_poweroff_handler_simple(nf_poweroff, 128);
 }
diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c
index 677913ff..5d8e2e6 100644
--- a/arch/m68k/mac/config.c
+++ b/arch/m68k/mac/config.c
@@ -160,7 +160,7 @@ void __init config_mac(void)
 	mach_set_clock_mmss = mac_set_clock_mmss;
 	mach_reset = mac_reset;
 	mach_halt = mac_poweroff;
-	pm_power_off = mac_poweroff;
+	register_poweroff_handler_simple(mac_poweroff, 128);
 	mach_max_dma_address = 0xffffffff;
 #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE)
 	mach_beep = mac_mksound;
-- 
1.9.1

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

* [PATCH 36/44] mips: Register with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (32 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 35/44] m68k: " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07  5:28 ` [PATCH 37/44] sh: " Guenter Roeck
                   ` (7 subsequent siblings)
  41 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly.

If there is an indication that there can be more than one poweroff handler,
use register_poweroff_handler, otherwise use register_poweroff_handler_simple
to register the poweroff handler.

If the poweroff handler only resets or stops the system, select a priority of
0 to indicate that the poweroff handler is one of last resort. If the poweroff
handler powers off the system, select a priority of 128, unless the poweroff
handler installation code suggests that there can be more than one poweroff
handler and the new handler is only installed conditionally. In this case,
select a priority of 64.

Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Maciej W. Rozycki <macro@linux-mips.org>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 arch/mips/alchemy/board-gpr.c          |  2 +-
 arch/mips/alchemy/board-mtx1.c         |  2 +-
 arch/mips/alchemy/board-xxs1500.c      |  2 +-
 arch/mips/alchemy/devboards/platform.c | 17 +++++++++++++++--
 arch/mips/ar7/setup.c                  |  2 +-
 arch/mips/ath79/setup.c                |  2 +-
 arch/mips/bcm47xx/setup.c              |  2 +-
 arch/mips/bcm63xx/setup.c              |  2 +-
 arch/mips/cobalt/setup.c               |  2 +-
 arch/mips/dec/setup.c                  |  2 +-
 arch/mips/emma/markeins/setup.c        |  2 +-
 arch/mips/jz4740/reset.c               |  2 +-
 arch/mips/lantiq/falcon/reset.c        |  2 +-
 arch/mips/lantiq/xway/reset.c          |  2 +-
 arch/mips/lasat/reset.c                |  2 +-
 arch/mips/loongson/common/reset.c      |  2 +-
 arch/mips/loongson1/common/reset.c     |  2 +-
 arch/mips/mti-malta/malta-reset.c      |  2 +-
 arch/mips/mti-sead3/sead3-reset.c      |  2 +-
 arch/mips/netlogic/xlp/setup.c         |  2 +-
 arch/mips/netlogic/xlr/setup.c         |  2 +-
 arch/mips/pmcs-msp71xx/msp_setup.c     |  2 +-
 arch/mips/pnx833x/common/setup.c       |  2 +-
 arch/mips/ralink/reset.c               |  2 +-
 arch/mips/rb532/setup.c                |  2 +-
 arch/mips/sgi-ip22/ip22-reset.c        |  2 +-
 arch/mips/sgi-ip27/ip27-reset.c        |  2 +-
 arch/mips/sgi-ip32/ip32-reset.c        |  2 +-
 arch/mips/sibyte/common/cfe.c          |  2 +-
 arch/mips/sni/setup.c                  |  2 +-
 arch/mips/txx9/generic/setup.c         |  2 +-
 arch/mips/vr41xx/common/pmu.c          |  2 +-
 32 files changed, 46 insertions(+), 33 deletions(-)

diff --git a/arch/mips/alchemy/board-gpr.c b/arch/mips/alchemy/board-gpr.c
index acf9a2a..56190a3 100644
--- a/arch/mips/alchemy/board-gpr.c
+++ b/arch/mips/alchemy/board-gpr.c
@@ -89,7 +89,7 @@ void __init board_setup(void)
 {
 	printk(KERN_INFO "Trapeze ITS GPR board\n");
 
-	pm_power_off = gpr_power_off;
+	register_poweroff_handler_simple(gpr_power_off, 0);
 	_machine_halt = gpr_power_off;
 	_machine_restart = gpr_reset;
 
diff --git a/arch/mips/alchemy/board-mtx1.c b/arch/mips/alchemy/board-mtx1.c
index 1e3b102..e2b06b5 100644
--- a/arch/mips/alchemy/board-mtx1.c
+++ b/arch/mips/alchemy/board-mtx1.c
@@ -98,7 +98,7 @@ void __init board_setup(void)
 	alchemy_gpio_direction_output(211, 1);	/* green on */
 	alchemy_gpio_direction_output(212, 0);	/* red off */
 
-	pm_power_off = mtx1_power_off;
+	register_poweroff_handler_simple(mtx1_power_off, 0);
 	_machine_halt = mtx1_power_off;
 	_machine_restart = mtx1_reset;
 
diff --git a/arch/mips/alchemy/board-xxs1500.c b/arch/mips/alchemy/board-xxs1500.c
index 0fc53e0..aaa5f5f 100644
--- a/arch/mips/alchemy/board-xxs1500.c
+++ b/arch/mips/alchemy/board-xxs1500.c
@@ -79,7 +79,7 @@ void __init board_setup(void)
 {
 	u32 pin_func;
 
-	pm_power_off = xxs1500_power_off;
+	register_poweroff_handler_simple(xxs1500_power_off, 0);
 	_machine_halt = xxs1500_power_off;
 	_machine_restart = xxs1500_reset;
 
diff --git a/arch/mips/alchemy/devboards/platform.c b/arch/mips/alchemy/devboards/platform.c
index 8df86eb..1734f72 100644
--- a/arch/mips/alchemy/devboards/platform.c
+++ b/arch/mips/alchemy/devboards/platform.c
@@ -6,6 +6,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/physmap.h>
+#include <linux/notifier.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
@@ -61,10 +62,22 @@ static void db1x_reset(char *c)
 	bcsr_write(BCSR_SYSTEM, 0);
 }
 
+static int db1x_power_off_notify(struct notifier *this,
+				 unsigned long unused1, void *unused2)
+{
+	db1x_power_off();
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block db1x_poweroff_nb = {
+	.notifier_call = db1x_power_off_notify,
+	.priority = 64,
+}
+
 static int __init db1x_late_setup(void)
 {
-	if (!pm_power_off)
-		pm_power_off = db1x_power_off;
+	if (register_poweroff_handler(&db1x_poweroff_nb))
+		pr_err("dbx1: Failed to register poweroff handler\n");
 	if (!_machine_halt)
 		_machine_halt = db1x_power_off;
 	if (!_machine_restart)
diff --git a/arch/mips/ar7/setup.c b/arch/mips/ar7/setup.c
index 820b7a3..464067e 100644
--- a/arch/mips/ar7/setup.c
+++ b/arch/mips/ar7/setup.c
@@ -91,7 +91,7 @@ void __init plat_mem_setup(void)
 
 	_machine_restart = ar7_machine_restart;
 	_machine_halt = ar7_machine_halt;
-	pm_power_off = ar7_machine_power_off;
+	register_poweroff_handler_simple(ar7_machine_power_off, 128);
 
 	io_base = (unsigned long)ioremap(AR7_REGS_BASE, 0x10000);
 	if (!io_base)
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c
index 64807a4..ce9754e 100644
--- a/arch/mips/ath79/setup.c
+++ b/arch/mips/ath79/setup.c
@@ -203,7 +203,7 @@ void __init plat_mem_setup(void)
 
 	_machine_restart = ath79_restart;
 	_machine_halt = ath79_halt;
-	pm_power_off = ath79_halt;
+	register_poweroff_handler_simple(ath79_halt, 0);
 }
 
 void __init plat_time_init(void)
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c
index ad439c2..d0841f6 100644
--- a/arch/mips/bcm47xx/setup.c
+++ b/arch/mips/bcm47xx/setup.c
@@ -242,7 +242,7 @@ void __init plat_mem_setup(void)
 
 	_machine_restart = bcm47xx_machine_restart;
 	_machine_halt = bcm47xx_machine_halt;
-	pm_power_off = bcm47xx_machine_halt;
+	register_poweroff_handler_simple(bcm47xx_machine_halt, 0);
 	bcm47xx_board_detect();
 	mips_set_machine_name(bcm47xx_board_get_name());
 }
diff --git a/arch/mips/bcm63xx/setup.c b/arch/mips/bcm63xx/setup.c
index 6660c7d..80a5893 100644
--- a/arch/mips/bcm63xx/setup.c
+++ b/arch/mips/bcm63xx/setup.c
@@ -149,7 +149,7 @@ void __init plat_mem_setup(void)
 
 	_machine_halt = bcm63xx_machine_halt;
 	_machine_restart = __bcm63xx_machine_reboot;
-	pm_power_off = bcm63xx_machine_halt;
+	register_poweroff_handler_simple(bcm63xx_machine_halt, 0);
 
 	set_io_port_base(0);
 	ioport_resource.start = 0;
diff --git a/arch/mips/cobalt/setup.c b/arch/mips/cobalt/setup.c
index 9a8c2fe..146406f 100644
--- a/arch/mips/cobalt/setup.c
+++ b/arch/mips/cobalt/setup.c
@@ -78,7 +78,7 @@ void __init plat_mem_setup(void)
 
 	_machine_restart = cobalt_machine_restart;
 	_machine_halt = cobalt_machine_halt;
-	pm_power_off = cobalt_machine_halt;
+	register_poweroff_handler_simple(cobalt_machine_halt, 0);
 
 	set_io_port_base(CKSEG1ADDR(GT_DEF_PCI0_IO_BASE));
 
diff --git a/arch/mips/dec/setup.c b/arch/mips/dec/setup.c
index 41bbffd..8aea997 100644
--- a/arch/mips/dec/setup.c
+++ b/arch/mips/dec/setup.c
@@ -158,7 +158,7 @@ void __init plat_mem_setup(void)
 
 	_machine_restart = dec_machine_restart;
 	_machine_halt = dec_machine_halt;
-	pm_power_off = dec_machine_power_off;
+	register_poweroff_handler_simple(dec_machine_power_off, 128);
 
 	ioport_resource.start = ~0UL;
 	ioport_resource.end = 0UL;
diff --git a/arch/mips/emma/markeins/setup.c b/arch/mips/emma/markeins/setup.c
index 9100122..e2ec2e5 100644
--- a/arch/mips/emma/markeins/setup.c
+++ b/arch/mips/emma/markeins/setup.c
@@ -103,7 +103,7 @@ void __init plat_mem_setup(void)
 
 	_machine_restart = markeins_machine_restart;
 	_machine_halt = markeins_machine_halt;
-	pm_power_off = markeins_machine_power_off;
+	register_poweroff_handler_simple(markeins_machine_power_off, 0);
 
 	/* setup resource limits */
 	ioport_resource.start = EMMA2RH_PCI_IO_BASE;
diff --git a/arch/mips/jz4740/reset.c b/arch/mips/jz4740/reset.c
index b6c6343..3659e62 100644
--- a/arch/mips/jz4740/reset.c
+++ b/arch/mips/jz4740/reset.c
@@ -114,5 +114,5 @@ void jz4740_reset_init(void)
 {
 	_machine_restart = jz4740_restart;
 	_machine_halt = jz4740_halt;
-	pm_power_off = jz4740_power_off;
+	register_poweroff_handler_simple(jz4740_power_off, 128);
 }
diff --git a/arch/mips/lantiq/falcon/reset.c b/arch/mips/lantiq/falcon/reset.c
index 5682482..efd4ee2 100644
--- a/arch/mips/lantiq/falcon/reset.c
+++ b/arch/mips/lantiq/falcon/reset.c
@@ -83,7 +83,7 @@ static int __init mips_reboot_setup(void)
 {
 	_machine_restart = machine_restart;
 	_machine_halt = machine_halt;
-	pm_power_off = machine_power_off;
+	register_poweroff_handler_simple(machine_power_off, 0);
 	return 0;
 }
 
diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c
index 1fa0f17..b698032 100644
--- a/arch/mips/lantiq/xway/reset.c
+++ b/arch/mips/lantiq/xway/reset.c
@@ -157,7 +157,7 @@ static int __init mips_reboot_setup(void)
 
 	_machine_restart = ltq_machine_restart;
 	_machine_halt = ltq_machine_halt;
-	pm_power_off = ltq_machine_power_off;
+	register_poweroff_handler_simple(ltq_machine_power_off, 0);
 
 	return 0;
 }
diff --git a/arch/mips/lasat/reset.c b/arch/mips/lasat/reset.c
index e21f0b9..9a07a88 100644
--- a/arch/mips/lasat/reset.c
+++ b/arch/mips/lasat/reset.c
@@ -56,5 +56,5 @@ void lasat_reboot_setup(void)
 {
 	_machine_restart = lasat_machine_restart;
 	_machine_halt = lasat_machine_halt;
-	pm_power_off = lasat_machine_halt;
+	register_poweroff_handler_simple(lasat_machine_halt, 0);
 }
diff --git a/arch/mips/loongson/common/reset.c b/arch/mips/loongson/common/reset.c
index a60715e..e251519 100644
--- a/arch/mips/loongson/common/reset.c
+++ b/arch/mips/loongson/common/reset.c
@@ -84,7 +84,7 @@ static int __init mips_reboot_setup(void)
 {
 	_machine_restart = loongson_restart;
 	_machine_halt = loongson_halt;
-	pm_power_off = loongson_poweroff;
+	register_poweroff_handler_simple(loongson_poweroff, 128);
 
 	return 0;
 }
diff --git a/arch/mips/loongson1/common/reset.c b/arch/mips/loongson1/common/reset.c
index 547f34b..fbb563a 100644
--- a/arch/mips/loongson1/common/reset.c
+++ b/arch/mips/loongson1/common/reset.c
@@ -38,7 +38,7 @@ static int __init ls1x_reboot_setup(void)
 {
 	_machine_restart = ls1x_restart;
 	_machine_halt = ls1x_halt;
-	pm_power_off = ls1x_power_off;
+	register_poweroff_handler_simple(ls1x_power_off, 0);
 
 	return 0;
 }
diff --git a/arch/mips/mti-malta/malta-reset.c b/arch/mips/mti-malta/malta-reset.c
index 2fd2cc2..632ce7c 100644
--- a/arch/mips/mti-malta/malta-reset.c
+++ b/arch/mips/mti-malta/malta-reset.c
@@ -40,7 +40,7 @@ static int __init mips_reboot_setup(void)
 {
 	_machine_restart = mips_machine_restart;
 	_machine_halt = mips_machine_halt;
-	pm_power_off = mips_machine_power_off;
+	register_poweroff_handler_simple(mips_machine_power_off, 128);
 
 	return 0;
 }
diff --git a/arch/mips/mti-sead3/sead3-reset.c b/arch/mips/mti-sead3/sead3-reset.c
index e6fb244..d1df04f 100644
--- a/arch/mips/mti-sead3/sead3-reset.c
+++ b/arch/mips/mti-sead3/sead3-reset.c
@@ -33,7 +33,7 @@ static int __init mips_reboot_setup(void)
 {
 	_machine_restart = mips_machine_restart;
 	_machine_halt = mips_machine_halt;
-	pm_power_off = mips_machine_halt;
+	register_poweroff_handler_simple(mips_machine_halt, 0);
 
 	return 0;
 }
diff --git a/arch/mips/netlogic/xlp/setup.c b/arch/mips/netlogic/xlp/setup.c
index 4fdd9fd..4982302 100644
--- a/arch/mips/netlogic/xlp/setup.c
+++ b/arch/mips/netlogic/xlp/setup.c
@@ -106,7 +106,7 @@ void __init plat_mem_setup(void)
 #endif
 	_machine_restart = (void (*)(char *))nlm_linux_exit;
 	_machine_halt	= nlm_linux_exit;
-	pm_power_off	= nlm_linux_exit;
+	register_poweroff_handler_simple(nlm_linux_exit, 0);
 
 	/* memory and bootargs from DT */
 	xlp_early_init_devtree();
diff --git a/arch/mips/netlogic/xlr/setup.c b/arch/mips/netlogic/xlr/setup.c
index d118b9a..5149dd4 100644
--- a/arch/mips/netlogic/xlr/setup.c
+++ b/arch/mips/netlogic/xlr/setup.c
@@ -75,7 +75,7 @@ void __init plat_mem_setup(void)
 {
 	_machine_restart = (void (*)(char *))nlm_linux_exit;
 	_machine_halt	= nlm_linux_exit;
-	pm_power_off	= nlm_linux_exit;
+	register_poweroff_handler_simple(nlm_linux_exit, 0);
 }
 
 const char *get_system_type(void)
diff --git a/arch/mips/pmcs-msp71xx/msp_setup.c b/arch/mips/pmcs-msp71xx/msp_setup.c
index 4f925e0..67699e30 100644
--- a/arch/mips/pmcs-msp71xx/msp_setup.c
+++ b/arch/mips/pmcs-msp71xx/msp_setup.c
@@ -144,7 +144,7 @@ void __init plat_mem_setup(void)
 {
 	_machine_restart = msp_restart;
 	_machine_halt = msp_halt;
-	pm_power_off = msp_power_off;
+	register_poweroff_handler_simple(msp_power_off, 0);
 }
 
 void __init prom_init(void)
diff --git a/arch/mips/pnx833x/common/setup.c b/arch/mips/pnx833x/common/setup.c
index 99b4d94..7c12665 100644
--- a/arch/mips/pnx833x/common/setup.c
+++ b/arch/mips/pnx833x/common/setup.c
@@ -51,7 +51,7 @@ int __init plat_mem_setup(void)
 
 	_machine_restart = pnx833x_machine_restart;
 	_machine_halt = pnx833x_machine_halt;
-	pm_power_off = pnx833x_machine_power_off;
+	register_poweroff_handler_simple(pnx833x_machine_power_off, 128);
 
 	/* IO/MEM resources. */
 	set_io_port_base(KSEG1);
diff --git a/arch/mips/ralink/reset.c b/arch/mips/ralink/reset.c
index 55c7ec5..e640e9e 100644
--- a/arch/mips/ralink/reset.c
+++ b/arch/mips/ralink/reset.c
@@ -98,7 +98,7 @@ static int __init mips_reboot_setup(void)
 {
 	_machine_restart = ralink_restart;
 	_machine_halt = ralink_halt;
-	pm_power_off = ralink_halt;
+	register_poweroff_handler_simple(ralink_halt, 0);
 
 	return 0;
 }
diff --git a/arch/mips/rb532/setup.c b/arch/mips/rb532/setup.c
index d0c64e7..c71a623 100644
--- a/arch/mips/rb532/setup.c
+++ b/arch/mips/rb532/setup.c
@@ -44,7 +44,7 @@ void __init plat_mem_setup(void)
 
 	_machine_restart = rb_machine_restart;
 	_machine_halt = rb_machine_halt;
-	pm_power_off = rb_machine_halt;
+	register_poweroff_handler-simple(rb_machine_halt, 0);
 
 	set_io_port_base(KSEG1);
 
diff --git a/arch/mips/sgi-ip22/ip22-reset.c b/arch/mips/sgi-ip22/ip22-reset.c
index 063c2dd..466e710 100644
--- a/arch/mips/sgi-ip22/ip22-reset.c
+++ b/arch/mips/sgi-ip22/ip22-reset.c
@@ -188,7 +188,7 @@ static int __init reboot_setup(void)
 
 	_machine_restart = sgi_machine_restart;
 	_machine_halt = sgi_machine_halt;
-	pm_power_off = sgi_machine_power_off;
+	register_poweroff_handler_simple(sgi_machine_power_off, 128);
 
 	res = request_irq(SGI_PANEL_IRQ, panel_int, 0, "Front Panel", NULL);
 	if (res) {
diff --git a/arch/mips/sgi-ip27/ip27-reset.c b/arch/mips/sgi-ip27/ip27-reset.c
index ac37e54..c26f04a 100644
--- a/arch/mips/sgi-ip27/ip27-reset.c
+++ b/arch/mips/sgi-ip27/ip27-reset.c
@@ -76,5 +76,5 @@ void ip27_reboot_setup(void)
 {
 	_machine_restart = ip27_machine_restart;
 	_machine_halt = ip27_machine_halt;
-	pm_power_off = ip27_machine_power_off;
+	register_poweroff_handler_simple(ip27_machine_power_off, 0);
 }
diff --git a/arch/mips/sgi-ip32/ip32-reset.c b/arch/mips/sgi-ip32/ip32-reset.c
index 1f823da..88d8692 100644
--- a/arch/mips/sgi-ip32/ip32-reset.c
+++ b/arch/mips/sgi-ip32/ip32-reset.c
@@ -189,7 +189,7 @@ static __init int ip32_reboot_setup(void)
 
 	_machine_restart = ip32_machine_restart;
 	_machine_halt = ip32_machine_halt;
-	pm_power_off = ip32_machine_power_off;
+	register_poweroff_handler_simple(ip32_machine_power_off, 0);
 
 	init_timer(&blink_timer);
 	blink_timer.function = blink_timeout;
diff --git a/arch/mips/sibyte/common/cfe.c b/arch/mips/sibyte/common/cfe.c
index 588e180..069de27 100644
--- a/arch/mips/sibyte/common/cfe.c
+++ b/arch/mips/sibyte/common/cfe.c
@@ -245,7 +245,7 @@ void __init prom_init(void)
 
 	_machine_restart   = cfe_linux_restart;
 	_machine_halt	   = cfe_linux_halt;
-	pm_power_off = cfe_linux_halt;
+	register_poweroff_handler_simple(cfe_linux_halt, 0);
 
 	/*
 	 * Check if a loader was used; if NOT, the 4 arguments are
diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c
index efad85c..5242bd9 100644
--- a/arch/mips/sni/setup.c
+++ b/arch/mips/sni/setup.c
@@ -225,7 +225,7 @@ void __init plat_mem_setup(void)
 	}
 
 	_machine_restart = sni_machine_restart;
-	pm_power_off = sni_machine_power_off;
+	register_poweroff_handler_simple(sni_machine_power_off, 128);
 
 	sni_display_setup();
 	sni_console_setup();
diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c
index 9ff200a..c429a4f 100644
--- a/arch/mips/txx9/generic/setup.c
+++ b/arch/mips/txx9/generic/setup.c
@@ -555,7 +555,7 @@ void __init plat_mem_setup(void)
 	/* fallback restart/halt routines */
 	_machine_restart = (void (*)(char *))txx9_machine_halt;
 	_machine_halt = txx9_machine_halt;
-	pm_power_off = txx9_machine_halt;
+	register_poweroff_handler_simple(txx9_machine_halt, 0);
 
 #ifdef CONFIG_PCI
 	pcibios_plat_setup = txx9_pcibios_setup;
diff --git a/arch/mips/vr41xx/common/pmu.c b/arch/mips/vr41xx/common/pmu.c
index d7f7558..4d947ab 100644
--- a/arch/mips/vr41xx/common/pmu.c
+++ b/arch/mips/vr41xx/common/pmu.c
@@ -127,7 +127,7 @@ static int __init vr41xx_pmu_init(void)
 	cpu_wait = vr41xx_cpu_wait;
 	_machine_restart = vr41xx_restart;
 	_machine_halt = vr41xx_halt;
-	pm_power_off = vr41xx_halt;
+	register_poweroff_handler_simple(vr41xx_halt, 0);
 
 	return 0;
 }
-- 
1.9.1

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

* [PATCH 37/44] sh: Register with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (33 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 36/44] mips: " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07  5:28 ` [PATCH 38/44] x86: lguest: " Guenter Roeck
                   ` (6 subsequent siblings)
  41 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 arch/sh/boards/board-sh7785lcr.c       | 2 +-
 arch/sh/boards/board-urquell.c         | 2 +-
 arch/sh/boards/mach-highlander/setup.c | 2 +-
 arch/sh/boards/mach-landisk/setup.c    | 2 +-
 arch/sh/boards/mach-r2d/setup.c        | 2 +-
 arch/sh/boards/mach-sdk7786/setup.c    | 2 +-
 6 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/sh/boards/board-sh7785lcr.c b/arch/sh/boards/board-sh7785lcr.c
index 2c4771e..c092402 100644
--- a/arch/sh/boards/board-sh7785lcr.c
+++ b/arch/sh/boards/board-sh7785lcr.c
@@ -332,7 +332,7 @@ static void __init sh7785lcr_setup(char **cmdline_p)
 
 	printk(KERN_INFO "Renesas Technology Corp. R0P7785LC0011RL support.\n");
 
-	pm_power_off = sh7785lcr_power_off;
+	register_poweroff_handler_simple(sh7785lcr_power_off, 128);
 
 	/* sm501 DRAM configuration */
 	sm501_reg = ioremap_nocache(SM107_REG_ADDR, SM501_DRAM_CONTROL);
diff --git a/arch/sh/boards/board-urquell.c b/arch/sh/boards/board-urquell.c
index b52abcc..b3fa56f 100644
--- a/arch/sh/boards/board-urquell.c
+++ b/arch/sh/boards/board-urquell.c
@@ -204,7 +204,7 @@ static void __init urquell_setup(char **cmdline_p)
 {
 	printk(KERN_INFO "Renesas Technology Corp. Urquell support.\n");
 
-	pm_power_off = urquell_power_off;
+	register_poweroff_handler_simple(urquell_power_off, 128);
 
 	register_smp_ops(&shx3_smp_ops);
 }
diff --git a/arch/sh/boards/mach-highlander/setup.c b/arch/sh/boards/mach-highlander/setup.c
index 4a52590..998f1a5 100644
--- a/arch/sh/boards/mach-highlander/setup.c
+++ b/arch/sh/boards/mach-highlander/setup.c
@@ -385,7 +385,7 @@ static void __init highlander_setup(char **cmdline_p)
 
 	__raw_writew(__raw_readw(PA_IVDRCTL) | 0x01, PA_IVDRCTL);	/* Si13112 */
 
-	pm_power_off = r7780rp_power_off;
+	register_poweroff_handler_simple(r7780rp_power_off, 128);
 }
 
 static unsigned char irl2irq[HL_NR_IRL];
diff --git a/arch/sh/boards/mach-landisk/setup.c b/arch/sh/boards/mach-landisk/setup.c
index f1147ca..c817d80 100644
--- a/arch/sh/boards/mach-landisk/setup.c
+++ b/arch/sh/boards/mach-landisk/setup.c
@@ -89,7 +89,7 @@ static void __init landisk_setup(char **cmdline_p)
 	__raw_writeb(__raw_readb(PA_LED) | 0x03, PA_LED);
 
 	printk(KERN_INFO "I-O DATA DEVICE, INC. \"LANDISK Series\" support.\n");
-	pm_power_off = landisk_power_off;
+	register_poweroff_handler_simple(landisk_power_off, 128);
 }
 
 /*
diff --git a/arch/sh/boards/mach-r2d/setup.c b/arch/sh/boards/mach-r2d/setup.c
index 4b98a52..a759d39 100644
--- a/arch/sh/boards/mach-r2d/setup.c
+++ b/arch/sh/boards/mach-r2d/setup.c
@@ -279,7 +279,7 @@ static void __init rts7751r2d_setup(char **cmdline_p)
 					(ver >> 4) & 0xf, ver & 0xf);
 
 	__raw_writew(0x0000, PA_OUTPORT);
-	pm_power_off = rts7751r2d_power_off;
+	register_poweroff_handler_simple(rts7751r2d_power_off, 128);
 
 	/* sm501 dram configuration:
 	 * ColSizeX = 11 - External Memory Column Size: 256 words.
diff --git a/arch/sh/boards/mach-sdk7786/setup.c b/arch/sh/boards/mach-sdk7786/setup.c
index c29268b..cb26336 100644
--- a/arch/sh/boards/mach-sdk7786/setup.c
+++ b/arch/sh/boards/mach-sdk7786/setup.c
@@ -252,7 +252,7 @@ static void __init sdk7786_setup(char **cmdline_p)
 	pr_info("\tPCB revision:\t%d\n", fpga_read_reg(PCBRR) & 0xf);
 
 	machine_ops.restart = sdk7786_restart;
-	pm_power_off = sdk7786_power_off;
+	register_poweroff_handler_simple(sdk7786_power_off, 128);
 
 	register_smp_ops(&shx3_smp_ops);
 }
-- 
1.9.1

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

* [PATCH 38/44] x86: lguest: Register with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (34 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 37/44] sh: " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07  5:28 ` [PATCH 39/44] x86: ce4100: " Guenter Roeck
                   ` (5 subsequent siblings)
  41 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly.

Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 arch/x86/lguest/boot.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index aae9413..083a999 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -1441,7 +1441,7 @@ __init void lguest_init(void)
 	 * the Guest routine to power off, and the reboot hook to our restart
 	 * routine.
 	 */
-	pm_power_off = lguest_power_off;
+	register_poweroff_handler_simple(lguest_power_off, 128);
 	machine_ops.restart = lguest_restart;
 
 	/*
-- 
1.9.1

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

* [PATCH 39/44] x86: ce4100: Register with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (35 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 38/44] x86: lguest: " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07  5:28 ` [PATCH 40/44] x86: intel-mid: Drop registration of dummy poweroff handlers Guenter Roeck
                   ` (4 subsequent siblings)
  41 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly.

Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 arch/x86/platform/ce4100/ce4100.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/platform/ce4100/ce4100.c b/arch/x86/platform/ce4100/ce4100.c
index 701fd58..4a7f3d6 100644
--- a/arch/x86/platform/ce4100/ce4100.c
+++ b/arch/x86/platform/ce4100/ce4100.c
@@ -164,5 +164,5 @@ void __init x86_ce4100_early_setup(void)
 	 */
 	reboot_type = BOOT_KBD;
 
-	pm_power_off = ce4100_power_off;
+	register_poweroff_handler_simple(ce4100_power_off, 128);
 }
-- 
1.9.1

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

* [PATCH 40/44] x86: intel-mid: Drop registration of dummy poweroff handlers
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (36 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 39/44] x86: ce4100: " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07  5:28 ` [PATCH 41/44] x86: pmc_atom: Register poweroff handler with kernel poweroff handler Guenter Roeck
                   ` (3 subsequent siblings)
  41 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

A dummy poweroff handler does not serve any purpose. Drop it.

Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 arch/x86/platform/intel-mid/intel-mid.c | 5 -----
 arch/x86/platform/intel-mid/mfld.c      | 5 -----
 2 files changed, 10 deletions(-)

diff --git a/arch/x86/platform/intel-mid/intel-mid.c b/arch/x86/platform/intel-mid/intel-mid.c
index 1bbedc4..4b70666 100644
--- a/arch/x86/platform/intel-mid/intel-mid.c
+++ b/arch/x86/platform/intel-mid/intel-mid.c
@@ -67,10 +67,6 @@ static void *(*get_intel_mid_ops[])(void) = INTEL_MID_OPS_INIT;
 enum intel_mid_cpu_type __intel_mid_cpu_chip;
 EXPORT_SYMBOL_GPL(__intel_mid_cpu_chip);
 
-static void intel_mid_power_off(void)
-{
-};
-
 static void intel_mid_reboot(void)
 {
 	intel_scu_ipc_simple_command(IPCMSG_COLD_BOOT, 0);
@@ -183,7 +179,6 @@ void __init x86_intel_mid_early_setup(void)
 
 	legacy_pic = &null_legacy_pic;
 
-	pm_power_off = intel_mid_power_off;
 	machine_ops.emergency_restart  = intel_mid_reboot;
 
 	/* Avoid searching for BIOS MP tables */
diff --git a/arch/x86/platform/intel-mid/mfld.c b/arch/x86/platform/intel-mid/mfld.c
index 23381d2..cf6842f 100644
--- a/arch/x86/platform/intel-mid/mfld.c
+++ b/arch/x86/platform/intel-mid/mfld.c
@@ -23,10 +23,6 @@ static struct intel_mid_ops penwell_ops = {
 	.arch_setup = penwell_arch_setup,
 };
 
-static void mfld_power_off(void)
-{
-}
-
 static unsigned long __init mfld_calibrate_tsc(void)
 {
 	unsigned long fast_calibrate;
@@ -61,7 +57,6 @@ static unsigned long __init mfld_calibrate_tsc(void)
 static void __init penwell_arch_setup(void)
 {
 	x86_platform.calibrate_tsc = mfld_calibrate_tsc;
-	pm_power_off = mfld_power_off;
 }
 
 void *get_penwell_ops(void)
-- 
1.9.1

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

* [PATCH 41/44] x86: pmc_atom: Register poweroff handler with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (37 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 40/44] x86: intel-mid: Drop registration of dummy poweroff handlers Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07  5:28 ` [PATCH 42/44] efi: " Guenter Roeck
                   ` (2 subsequent siblings)
  41 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly. Register with a low priority value of 64 to reflect that
the original code only sets pm_power_off if it was not already set.

Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 arch/x86/kernel/pmc_atom.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/pmc_atom.c b/arch/x86/kernel/pmc_atom.c
index 0c424a6..79331a2 100644
--- a/arch/x86/kernel/pmc_atom.c
+++ b/arch/x86/kernel/pmc_atom.c
@@ -20,6 +20,8 @@
 #include <linux/pci.h>
 #include <linux/device.h>
 #include <linux/debugfs.h>
+#include <linux/notifier.h>
+#include <linux/pm.h>
 #include <linux/seq_file.h>
 #include <linux/io.h>
 
@@ -92,7 +94,8 @@ static inline void pmc_reg_write(struct pmc_dev *pmc, int reg_offset, u32 val)
 	writel(val, pmc->regmap + reg_offset);
 }
 
-static void pmc_power_off(void)
+static int pmc_power_off(struct notifier_block *this, unsigned long unused1,
+			 void *unused2)
 {
 	u16	pm1_cnt_port;
 	u32	pm1_cnt_value;
@@ -107,8 +110,15 @@ static void pmc_power_off(void)
 	pm1_cnt_value |= SLEEP_ENABLE;
 
 	outl(pm1_cnt_value, pm1_cnt_port);
+
+	return NOTIFY_DONE;
 }
 
+static struct notifier_block pmc_poweroff_nb = {
+	.notifier_call = pmc_power_off,
+	.priority = 64,
+};
+
 static void pmc_hw_reg_setup(struct pmc_dev *pmc)
 {
 	/*
@@ -247,8 +257,12 @@ static int pmc_setup_dev(struct pci_dev *pdev)
 	acpi_base_addr &= ACPI_BASE_ADDR_MASK;
 
 	/* Install power off function */
-	if (acpi_base_addr != 0 && pm_power_off == NULL)
-		pm_power_off = pmc_power_off;
+	if (acpi_base_addr != 0) {
+		ret = register_poweroff_handler(&pmc_poweroff_nb);
+		if (ret)
+			dev_err(&pdev->dev,
+				"Failed to install poweroff handler\n");
+	}
 
 	pci_read_config_dword(pdev, PMC_BASE_ADDR_OFFSET, &pmc->base_addr);
 	pmc->base_addr &= PMC_BASE_ADDR_MASK;
-- 
1.9.1

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

* [PATCH 42/44] efi: Register poweroff handler with kernel poweroff handler
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (38 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 41/44] x86: pmc_atom: Register poweroff handler with kernel poweroff handler Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-16 14:59   ` Matt Fleming
  2014-10-07  5:28 ` [PATCH 43/44] hwmon: (ab8500) Call kernel_power_off instead of pm_power_off Guenter Roeck
  2014-10-07  5:28 ` [PATCH 44/44] kernel: Remove pm_power_off Guenter Roeck
  41 siblings, 1 reply; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Register with kernel poweroff handler instead of setting pm_power_off
directly. Register with low priority value of 64 since the efi code
states that this is a poweroff handler of last resort.

Cc: Matt Fleming <matt.fleming@intel.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/firmware/efi/reboot.c | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/firmware/efi/reboot.c b/drivers/firmware/efi/reboot.c
index 9c59d1c..c082439 100644
--- a/drivers/firmware/efi/reboot.c
+++ b/drivers/firmware/efi/reboot.c
@@ -3,6 +3,8 @@
  * Copyright (c) 2014 Red Hat, Inc., Mark Salter <msalter@redhat.com>
  */
 #include <linux/efi.h>
+#include <linux/notifier.h>
+#include <linux/pm.h>
 #include <linux/reboot.h>
 
 int efi_reboot_quirk_mode = -1;
@@ -38,19 +40,32 @@ bool __weak efi_poweroff_required(void)
 	return false;
 }
 
-static void efi_power_off(void)
+static int efi_power_off(struct notifier_block *this,
+			 unsigned long unused1, void *unused2)
 {
 	efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL);
+
+	return NOTIFY_DONE;
 }
 
+static struct notifier_block efi_poweroff_nb = {
+	.notifier_call = efi_power_off,
+	.priority = 64,
+};
+
 static int __init efi_shutdown_init(void)
 {
+	int ret = 0;
+
 	if (!efi_enabled(EFI_RUNTIME_SERVICES))
 		return -ENODEV;
 
-	if (efi_poweroff_required())
-		pm_power_off = efi_power_off;
+	if (efi_poweroff_required()) {
+		ret = register_poweroff_handler(&efi_poweroff_nb);
+		if (ret)
+			pr_err("efi: Failed to register poweroff handler\n");
+	}
 
-	return 0;
+	return ret;
 }
 late_initcall(efi_shutdown_init);
-- 
1.9.1

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

* [PATCH 43/44] hwmon: (ab8500) Call kernel_power_off instead of pm_power_off
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (39 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 42/44] efi: " Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07  5:28 ` [PATCH 44/44] kernel: Remove pm_power_off Guenter Roeck
  41 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

Drivers should not call pm_power_off directly; it is not guaranteed
to be non-NULL. Call kernel_power_off instead.

Cc: Jean Delvare <jdelvare@suse.de>
Reviewed-by: Jean Delvare <jdelvare@suse.de>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/hwmon/ab8500.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/hwmon/ab8500.c b/drivers/hwmon/ab8500.c
index d844dc8..8b6a4f4 100644
--- a/drivers/hwmon/ab8500.c
+++ b/drivers/hwmon/ab8500.c
@@ -6,7 +6,7 @@
  *
  * When the AB8500 thermal warning temperature is reached (threshold cannot
  * be changed by SW), an interrupt is set, and if no further action is taken
- * within a certain time frame, pm_power off will be called.
+ * within a certain time frame, kernel_power_off will be called.
  *
  * When AB8500 thermal shutdown temperature is reached a hardware shutdown of
  * the AB8500 will occur.
@@ -21,6 +21,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/power/ab8500.h>
+#include <linux/reboot.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
 #include "abx500.h"
@@ -106,7 +107,7 @@ static void ab8500_thermal_power_off(struct work_struct *work)
 
 	dev_warn(&abx500_data->pdev->dev, "Power off due to critical temp\n");
 
-	pm_power_off();
+	kernel_power_off();
 }
 
 static ssize_t ab8500_show_name(struct device *dev,
-- 
1.9.1

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

* [PATCH 44/44] kernel: Remove pm_power_off
       [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
                   ` (40 preceding siblings ...)
  2014-10-07  5:28 ` [PATCH 43/44] hwmon: (ab8500) Call kernel_power_off instead of pm_power_off Guenter Roeck
@ 2014-10-07  5:28 ` Guenter Roeck
  2014-10-07 23:43   ` Rafael J. Wysocki
  41 siblings, 1 reply; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07  5:28 UTC (permalink / raw)
  To: linux-arm-kernel

No users of pm_power_off are left, so it is safe to remove the function.

Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Len Brown <len.brown@intel.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 include/linux/pm.h              |  1 -
 kernel/power/poweroff_handler.c | 10 +---------
 2 files changed, 1 insertion(+), 10 deletions(-)

diff --git a/include/linux/pm.h b/include/linux/pm.h
index 45271b5..fce7645 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -31,7 +31,6 @@
 /*
  * Callbacks for platform drivers to implement.
  */
-extern void (*pm_power_off)(void);
 extern void (*pm_power_off_prepare)(void);
 
 /*
diff --git a/kernel/power/poweroff_handler.c b/kernel/power/poweroff_handler.c
index 96f59ef..01a3a39 100644
--- a/kernel/power/poweroff_handler.c
+++ b/kernel/power/poweroff_handler.c
@@ -20,12 +20,6 @@
 #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.
  */
@@ -163,8 +157,6 @@ int register_poweroff_handler_simple(void (*handler)(void), int priority)
  */
 void do_kernel_poweroff(void)
 {
-	if (pm_power_off)
-		pm_power_off();
 	atomic_notifier_call_chain(&poweroff_handler_list, 0, NULL);
 }
 
@@ -175,6 +167,6 @@ void do_kernel_poweroff(void)
  */
 bool have_kernel_poweroff(void)
 {
-	return pm_power_off != NULL || poweroff_handler_list.head != NULL;
+	return poweroff_handler_list.head != NULL;
 }
 EXPORT_SYMBOL(have_kernel_poweroff);
-- 
1.9.1

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

* [PATCH 01/44] kernel: Add support for poweroff handler call chain
  2014-10-07  5:28 ` [PATCH 01/44] kernel: Add support for poweroff handler call chain Guenter Roeck
@ 2014-10-07  7:46   ` Philippe Rétornaz
  2014-10-09 10:31   ` Pavel Machek
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 91+ messages in thread
From: Philippe Rétornaz @ 2014-10-07  7:46 UTC (permalink / raw)
  To: linux-arm-kernel

Hello

This seems exactly what I would need on the mc13783 to handle cleanly 
the poweroff,
but after reading this patchset I have the following question:

[...]

> +/*
> + *	Notifier list for kernel code which wants to be called
> + *	to power off the system.
> + */
> +static ATOMIC_NOTIFIER_HEAD(poweroff_handler_list);

[...]

> +void do_kernel_poweroff(void)
> +{
> +	atomic_notifier_call_chain(&poweroff_handler_list, 0, NULL);
> +}
> +

It seems that the poweroff callback needs to be atomic as per
_atomic_notifier_call_chain documentation:

	"Calls each function in a notifier chain in turn.  The functions
	 run in an atomic context"

But this is a problem for many MFD (mc13783, twl4030 etc ...) which are
accessible on only a blocking bus (SPI, I2C).

What I am missing here ?

Thanks,

Philippe

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

* [PATCH 18/44] mfd: twl4030-power: Register with kernel poweroff handler
  2014-10-07  5:28 ` [PATCH 18/44] mfd: twl4030-power: " Guenter Roeck
@ 2014-10-07  7:52   ` Lee Jones
  0 siblings, 0 replies; 91+ messages in thread
From: Lee Jones @ 2014-10-07  7:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 06 Oct 2014, Guenter Roeck wrote:

> Register with kernel poweroff handler instead of setting pm_power_off
> directly. Register with a low priority value of 64 to reflect that
> the original code only sets pm_power_off if it was not already set.
> 
> Make twl4030_power_off static as it is only called from the twl4030-power
> driver.
> 
> Cc: Samuel Ortiz <sameo@linux.intel.com>
> Cc: Lee Jones <lee.jones@linaro.org>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> ---
>  drivers/mfd/twl4030-power.c | 25 +++++++++++++++++++++----
>  include/linux/i2c/twl.h     |  1 -
>  2 files changed, 21 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c
> index 4d3ff37..bd6b830 100644
> --- a/drivers/mfd/twl4030-power.c
> +++ b/drivers/mfd/twl4030-power.c
> @@ -25,9 +25,10 @@
>   */
>  
>  #include <linux/module.h>
> -#include <linux/pm.h>
> +#include <linux/notifier.h>
>  #include <linux/i2c/twl.h>
>  #include <linux/platform_device.h>
> +#include <linux/pm.h>
>  #include <linux/of.h>
>  #include <linux/of_device.h>
>  
> @@ -611,7 +612,8 @@ twl4030_power_configure_resources(const struct twl4030_power_data *pdata)
>   * After a successful execution, TWL shuts down the power to the SoC
>   * and all peripherals connected to it.
>   */
> -void twl4030_power_off(void)
> +static int twl4030_power_off(struct notifier_block *this, unsigned long unused1,
> +			     void *unused2)
>  {
>  	int err;
>  
> @@ -619,8 +621,15 @@ void twl4030_power_off(void)
>  			       TWL4030_PM_MASTER_P1_SW_EVENTS);
>  	if (err)
>  		pr_err("TWL4030 Unable to power off\n");
> +
> +	return NOTIFY_DONE;
>  }
>  
> +static struct notifier_block twl4030_poweroff_nb = {
> +	.notifier_call = twl4030_power_off,
> +	.priority = 64,

64 out of what?  How is this calculated?  Wouldn't it be better to
define these?

> +};
> +
>  static bool twl4030_power_use_poweroff(const struct twl4030_power_data *pdata,
>  					struct device_node *node)
>  {
> @@ -836,7 +845,7 @@ static int twl4030_power_probe(struct platform_device *pdev)
>  	}
>  
>  	/* Board has to be wired properly to use this feature */
> -	if (twl4030_power_use_poweroff(pdata, node) && !pm_power_off) {
> +	if (twl4030_power_use_poweroff(pdata, node)) {
>  		/* Default for SEQ_OFFSYNC is set, lets ensure this */
>  		err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &val,
>  				      TWL4030_PM_MASTER_CFG_P123_TRANSITION);
> @@ -853,7 +862,13 @@ static int twl4030_power_probe(struct platform_device *pdev)
>  			}
>  		}
>  
> -		pm_power_off = twl4030_power_off;
> +		err = register_poweroff_handler(&twl4030_poweroff_nb);
> +		if (err) {
> +			dev_err(&pdev->dev,
> +				"Failed to register poweroff handler\n");

If this is not fatal, you should issue a dev_warn() instead.

> +			/* Not a fatal error */
> +			err = 0;

How about using your own variable for this?  Then you don't have to
worry about resetting it.

> +		}
>  	}
>  
>  relock:
> @@ -869,6 +884,8 @@ relock:
>  
>  static int twl4030_power_remove(struct platform_device *pdev)
>  {
> +	unregister_poweroff_handler(&twl4030_poweroff_nb);

Perhaps a naive question, but is there any way you can do this using
devres (devm_* managed resources)?

>  	return 0;
>  }
>  
> diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
> index 8cfb50f..f8544f1 100644
> --- a/include/linux/i2c/twl.h
> +++ b/include/linux/i2c/twl.h
> @@ -680,7 +680,6 @@ struct twl4030_power_data {
>  };
>  
>  extern int twl4030_remove_script(u8 flags);
> -extern void twl4030_power_off(void);
>  
>  struct twl4030_codec_data {
>  	unsigned int digimic_delay; /* in ms */

-- 
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] 91+ messages in thread

* [PATCH 12/44] mfd: ab8500-sysctrl: Register with kernel poweroff handler
  2014-10-07  5:28 ` [PATCH 12/44] mfd: ab8500-sysctrl: " Guenter Roeck
@ 2014-10-07  8:00   ` Lee Jones
  2014-10-09 10:36     ` Catalin Marinas
  0 siblings, 1 reply; 91+ messages in thread
From: Lee Jones @ 2014-10-07  8:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 06 Oct 2014, Guenter Roeck wrote:

> Register with kernel poweroff handler instead of setting pm_power_off
> directly. Register with a low priority value of 64 to reflect that
> the original code only sets pm_power_off if it was not already set.
> 
> 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>
> ---
>  drivers/mfd/ab8500-sysctrl.c | 26 +++++++++++++++-----------
>  1 file changed, 15 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/mfd/ab8500-sysctrl.c b/drivers/mfd/ab8500-sysctrl.c
> index 8e0dae5..677438f 100644
> --- a/drivers/mfd/ab8500-sysctrl.c
> +++ b/drivers/mfd/ab8500-sysctrl.c
> @@ -6,6 +6,7 @@

[...]

> +static int ab8500_power_off(struct notifier_block *this, unsigned long unused1,
> +			    void *unused2)
>  {
>  	sigset_t old;
>  	sigset_t all;
> @@ -34,11 +36,6 @@ static void ab8500_power_off(void)
>  	struct power_supply *psy;
>  	int ret;
>  
> -	if (sysctrl_dev == NULL) {
> -		pr_err("%s: sysctrl not initialized\n", __func__);
> -		return;
> -	}

Can you explain the purpose of this change please?

>  	/*
>  	 * If we have a charger connected and we're powering off,
>  	 * reboot into charge-only mode.
> @@ -83,8 +80,15 @@ shutdown:
>  					 AB8500_STW4500CTRL1_SWRESET4500N);
>  		(void)sigprocmask(SIG_SETMASK, &old, NULL);
>  	}
> +
> +	return NOTIFY_DONE;
>  }

-- 
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] 91+ messages in thread

* [PATCH 04/44] m68k: Replace mach_power_off with pm_power_off
  2014-10-07  5:28 ` [PATCH 04/44] m68k: Replace mach_power_off with pm_power_off Guenter Roeck
@ 2014-10-07  8:29   ` Geert Uytterhoeven
  0 siblings, 0 replies; 91+ messages in thread
From: Geert Uytterhoeven @ 2014-10-07  8:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 7, 2014 at 7:28 AM, Guenter Roeck <linux@roeck-us.net> wrote:
> Replace mach_power_off with pm_power_off to simplify the subsequent
> move of pm_power_off to generic code.

Thanks!

> Cc: Geert Uytterhoeven <geert@linux-m68k.org>
> Cc: Greg Ungerer <gerg@uclinux.org>
> Cc: Joshua Thompson <funaho@jurai.org>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>

Looks OK, so since you said it builds ;-)

Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* [PATCH 35/44] m68k: Register with kernel poweroff handler
  2014-10-07  5:28 ` [PATCH 35/44] m68k: " Guenter Roeck
@ 2014-10-07  9:19   ` Geert Uytterhoeven
  0 siblings, 0 replies; 91+ messages in thread
From: Geert Uytterhoeven @ 2014-10-07  9:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 7, 2014 at 7:28 AM, Guenter Roeck <linux@roeck-us.net> wrote:
> Register with kernel poweroff handler instead of setting pm_power_off
> directly.
>
> Cc: Geert Uytterhoeven <geert@linux-m68k.org>
> Cc: Joshua Thompson <funaho@jurai.org>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>

As someone already mentioned, having #defines instead of hardcoded
numbers for the priorities would be nice.

Apart from that:

Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>

> +       register_poweroff_handler_simple(nf_poweroff, 128);

> +       register_poweroff_handler_simple(mac_poweroff, 128);

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* [PATCH 05/44] mfd: as3722: Drop reference to pm_power_off from devicetree bindings
  2014-10-07  5:28 ` [PATCH 05/44] mfd: as3722: Drop reference to pm_power_off from devicetree bindings Guenter Roeck
@ 2014-10-07 10:59   ` Mark Rutland
  2014-10-07 16:21   ` Rob Landley
  1 sibling, 0 replies; 91+ messages in thread
From: Mark Rutland @ 2014-10-07 10:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 07, 2014 at 06:28:07AM +0100, Guenter Roeck wrote:
> Devicetree bindings are supposed to be operating system independent
> and should thus not describe how a specific functionality is implemented
> in Linux.
> 
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Pawel Moll <pawel.moll@arm.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> ---
>  Documentation/devicetree/bindings/mfd/as3722.txt | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)

Thanks for the fix-up!

Acked-by: Mark Rutland <mark.rutland@arm.com>

Mark.

> 
> diff --git a/Documentation/devicetree/bindings/mfd/as3722.txt b/Documentation/devicetree/bindings/mfd/as3722.txt
> index 4f64b2a..0b2a609 100644
> --- a/Documentation/devicetree/bindings/mfd/as3722.txt
> +++ b/Documentation/devicetree/bindings/mfd/as3722.txt
> @@ -122,8 +122,7 @@ Following are properties of regulator subnode.
>  
>  Power-off:
>  =========
> -AS3722 supports the system power off by turning off all its rail. This
> -is provided through pm_power_off.
> +AS3722 supports the system power off by turning off all its rails.
>  The device node should have the following properties to enable this
>  functionality
>  ams,system-power-controller: Boolean, to enable the power off functionality
> -- 
> 1.9.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

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

* [PATCH 07/44] qnap-poweroff: Drop reference to pm_power_off from devicetree bindings
  2014-10-07  5:28 ` [PATCH 07/44] qnap-poweroff: " Guenter Roeck
@ 2014-10-07 11:02   ` Mark Rutland
  2014-10-07 15:57     ` Guenter Roeck
  2014-10-07 15:51   ` Andrew Lunn
  1 sibling, 1 reply; 91+ messages in thread
From: Mark Rutland @ 2014-10-07 11:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 07, 2014 at 06:28:09AM +0100, Guenter Roeck wrote:
> Replace reference to pm_power_off (which is an implementation detail)
> and replace it with a more generic description of the driver's functionality.
> 
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Pawel Moll <pawel.moll@arm.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> ---
>  Documentation/devicetree/bindings/power_supply/qnap-poweroff.txt | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/power_supply/qnap-poweroff.txt b/Documentation/devicetree/bindings/power_supply/qnap-poweroff.txt
> index af25e77..1e2260a 100644
> --- a/Documentation/devicetree/bindings/power_supply/qnap-poweroff.txt
> +++ b/Documentation/devicetree/bindings/power_supply/qnap-poweroff.txt
> @@ -3,8 +3,8 @@
>  QNAP NAS devices have a microcontroller controlling the main power
>  supply. This microcontroller is connected to UART1 of the Kirkwood and
>  Orion5x SoCs. Sending the character 'A', at 19200 baud, tells the
> -microcontroller to turn the power off. This driver adds a handler to
> -pm_power_off which is called to turn the power off.
> +microcontroller to turn the power off. This driver installs a handler
> +to power off the system.

I'd remove the last sentence -- the driver is also independent of the
HW, and the description of how the power off works at the HW level is
sufficient.

With that:

Acked-by: Mark Rutland <mark.rutland@arm.com>

Thanks,
Mark.

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

* [PATCH 06/44] gpio-poweroff: Drop reference to pm_power_off from devicetree bindings
  2014-10-07  5:28 ` [PATCH 06/44] gpio-poweroff: " Guenter Roeck
@ 2014-10-07 11:03   ` Mark Rutland
  2014-10-07 15:50   ` Andrew Lunn
  1 sibling, 0 replies; 91+ messages in thread
From: Mark Rutland @ 2014-10-07 11:03 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 07, 2014 at 06:28:08AM +0100, Guenter Roeck wrote:
> pm_power_off is an implementation detail. Replace it with a more generic
> description of the driver's functionality.
> 
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Pawel Moll <pawel.moll@arm.com>
> Cc: Mark Rutland <mark.rutland@arm.com>

Acked-by: Mark Rutland <mark.rutland@arm.com>

> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> ---
>  Documentation/devicetree/bindings/gpio/gpio-poweroff.txt | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/gpio/gpio-poweroff.txt b/Documentation/devicetree/bindings/gpio/gpio-poweroff.txt
> index d4eab92..c95a1a6 100644
> --- a/Documentation/devicetree/bindings/gpio/gpio-poweroff.txt
> +++ b/Documentation/devicetree/bindings/gpio/gpio-poweroff.txt
> @@ -2,12 +2,12 @@ Driver a GPIO line that can be used to turn the power off.
>  
>  The driver supports both level triggered and edge triggered power off.
>  At driver load time, the driver will request the given gpio line and
> -install a pm_power_off handler. If the optional properties 'input' is
> -not found, the GPIO line will be driven in the inactive
> +install a handler to power off the system. If the optional properties
> +'input' is not found, the GPIO line will be driven in the inactive
>  state. Otherwise its configured as an input.
>  
> -When the pm_power_off is called, the gpio is configured as an output,
> -and drive active, so triggering a level triggered power off
> +When the the poweroff handler is called, the gpio is configured as an
> +output, and drive active, so triggering a level triggered power off
>  condition. This will also cause an inactive->active edge condition, so
>  triggering positive edge triggered power off. After a delay of 100ms,
>  the GPIO is set to inactive, thus causing an active->inactive edge,
> @@ -24,7 +24,7 @@ Required properties:
>  
>  Optional properties:
>  - input : Initially configure the GPIO line as an input. Only reconfigure
> -  it to an output when the pm_power_off function is called. If this optional
> +  it to an output when the poweroff handler is called. If this optional
>    property is not specified, the GPIO is initialized as an output in its
>    inactive state.
>  
> -- 
> 1.9.1
> 
> 

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

* [PATCH 06/44] gpio-poweroff: Drop reference to pm_power_off from devicetree bindings
  2014-10-07  5:28 ` [PATCH 06/44] gpio-poweroff: " Guenter Roeck
  2014-10-07 11:03   ` Mark Rutland
@ 2014-10-07 15:50   ` Andrew Lunn
  1 sibling, 0 replies; 91+ messages in thread
From: Andrew Lunn @ 2014-10-07 15:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Oct 06, 2014 at 10:28:08PM -0700, Guenter Roeck wrote:
> pm_power_off is an implementation detail. Replace it with a more generic
> description of the driver's functionality.
> 
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Pawel Moll <pawel.moll@arm.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>

Acked-by: Andrew Lunn <andrew@lunn.ch>

Thanks
	Andrew
> ---
>  Documentation/devicetree/bindings/gpio/gpio-poweroff.txt | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/gpio/gpio-poweroff.txt b/Documentation/devicetree/bindings/gpio/gpio-poweroff.txt
> index d4eab92..c95a1a6 100644
> --- a/Documentation/devicetree/bindings/gpio/gpio-poweroff.txt
> +++ b/Documentation/devicetree/bindings/gpio/gpio-poweroff.txt
> @@ -2,12 +2,12 @@ Driver a GPIO line that can be used to turn the power off.
>  
>  The driver supports both level triggered and edge triggered power off.
>  At driver load time, the driver will request the given gpio line and
> -install a pm_power_off handler. If the optional properties 'input' is
> -not found, the GPIO line will be driven in the inactive
> +install a handler to power off the system. If the optional properties
> +'input' is not found, the GPIO line will be driven in the inactive
>  state. Otherwise its configured as an input.
>  
> -When the pm_power_off is called, the gpio is configured as an output,
> -and drive active, so triggering a level triggered power off
> +When the the poweroff handler is called, the gpio is configured as an
> +output, and drive active, so triggering a level triggered power off
>  condition. This will also cause an inactive->active edge condition, so
>  triggering positive edge triggered power off. After a delay of 100ms,
>  the GPIO is set to inactive, thus causing an active->inactive edge,
> @@ -24,7 +24,7 @@ Required properties:
>  
>  Optional properties:
>  - input : Initially configure the GPIO line as an input. Only reconfigure
> -  it to an output when the pm_power_off function is called. If this optional
> +  it to an output when the poweroff handler is called. If this optional
>    property is not specified, the GPIO is initialized as an output in its
>    inactive state.
>  
> -- 
> 1.9.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 07/44] qnap-poweroff: Drop reference to pm_power_off from devicetree bindings
  2014-10-07  5:28 ` [PATCH 07/44] qnap-poweroff: " Guenter Roeck
  2014-10-07 11:02   ` Mark Rutland
@ 2014-10-07 15:51   ` Andrew Lunn
  1 sibling, 0 replies; 91+ messages in thread
From: Andrew Lunn @ 2014-10-07 15:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Oct 06, 2014 at 10:28:09PM -0700, Guenter Roeck wrote:
> Replace reference to pm_power_off (which is an implementation detail)
> and replace it with a more generic description of the driver's functionality.

Acked-by: Andrew Lunn <andrew@lunn.ch>

Thanks
	Andrew

> 
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Pawel Moll <pawel.moll@arm.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> ---
>  Documentation/devicetree/bindings/power_supply/qnap-poweroff.txt | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/power_supply/qnap-poweroff.txt b/Documentation/devicetree/bindings/power_supply/qnap-poweroff.txt
> index af25e77..1e2260a 100644
> --- a/Documentation/devicetree/bindings/power_supply/qnap-poweroff.txt
> +++ b/Documentation/devicetree/bindings/power_supply/qnap-poweroff.txt
> @@ -3,8 +3,8 @@
>  QNAP NAS devices have a microcontroller controlling the main power
>  supply. This microcontroller is connected to UART1 of the Kirkwood and
>  Orion5x SoCs. Sending the character 'A', at 19200 baud, tells the
> -microcontroller to turn the power off. This driver adds a handler to
> -pm_power_off which is called to turn the power off.
> +microcontroller to turn the power off. This driver installs a handler
> +to power off the system.
>  
>  Synology NAS devices use a similar scheme, but a different baud rate,
>  9600, and a different character, '1'.
> -- 
> 1.9.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 07/44] qnap-poweroff: Drop reference to pm_power_off from devicetree bindings
  2014-10-07 11:02   ` Mark Rutland
@ 2014-10-07 15:57     ` Guenter Roeck
  0 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07 15:57 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 07, 2014 at 12:02:19PM +0100, Mark Rutland wrote:
> On Tue, Oct 07, 2014 at 06:28:09AM +0100, Guenter Roeck wrote:
> > Replace reference to pm_power_off (which is an implementation detail)
> > and replace it with a more generic description of the driver's functionality.
> > 
> > Cc: Rob Herring <robh+dt@kernel.org>
> > Cc: Pawel Moll <pawel.moll@arm.com>
> > Cc: Mark Rutland <mark.rutland@arm.com>
> > Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> > ---
> >  Documentation/devicetree/bindings/power_supply/qnap-poweroff.txt | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/power_supply/qnap-poweroff.txt b/Documentation/devicetree/bindings/power_supply/qnap-poweroff.txt
> > index af25e77..1e2260a 100644
> > --- a/Documentation/devicetree/bindings/power_supply/qnap-poweroff.txt
> > +++ b/Documentation/devicetree/bindings/power_supply/qnap-poweroff.txt
> > @@ -3,8 +3,8 @@
> >  QNAP NAS devices have a microcontroller controlling the main power
> >  supply. This microcontroller is connected to UART1 of the Kirkwood and
> >  Orion5x SoCs. Sending the character 'A', at 19200 baud, tells the
> > -microcontroller to turn the power off. This driver adds a handler to
> > -pm_power_off which is called to turn the power off.
> > +microcontroller to turn the power off. This driver installs a handler
> > +to power off the system.
> 
> I'd remove the last sentence -- the driver is also independent of the
> HW, and the description of how the power off works at the HW level is
> sufficient.
> 
Done.

> With that:
> 
> Acked-by: Mark Rutland <mark.rutland@arm.com>
> 
Thanks!

Guenter

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

* [PATCH 21/44] power/reset: gpio-poweroff: Register with kernel poweroff handler
  2014-10-07  5:28 ` [PATCH 21/44] power/reset: gpio-poweroff: " Guenter Roeck
@ 2014-10-07 16:00   ` Andrew Lunn
  0 siblings, 0 replies; 91+ messages in thread
From: Andrew Lunn @ 2014-10-07 16:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Oct 06, 2014 at 10:28:23PM -0700, Guenter Roeck wrote:
> Register with kernel poweroff handler instead of setting pm_power_off
> directly. Register with a low priority value of 64 to reflect that
> the original code only sets pm_power_off if it was not already set.
> 
> Other changes:
> 
> Drop note that there can not be an additional instance of this driver.
> The original reason no longer applies, it should be obvious that there
> can only be one instance of the driver if static variables are used to
> reflect its state, and support for multiple instances can now be added
> easily if needed by avoiding static variables.
> 
> Do not create an error message if another poweroff handler has already been
> registered. This is perfectly normal and acceptable.
> 
> Do not display a warning traceback if the poweroff handler fails to
> power off the system. There may be other poweroff handlers.

I would prefer to keep the warning traceback. We found on some
hardware the GPIO transitions were too fast and it failed to power
off. Seeing the traceback gives an idea where to go look for the
problem.

Other than that,

Acked-by: Andrew Lunn <andrew@lunn.ch>

> 
> Cc: Sebastian Reichel <sre@kernel.org>
> Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> Cc: David Woodhouse <dwmw2@infradead.org>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> ---
>  drivers/power/reset/gpio-poweroff.c | 36 ++++++++++++++++++------------------
>  1 file changed, 18 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/power/reset/gpio-poweroff.c b/drivers/power/reset/gpio-poweroff.c
> index ce849bc..e95a7a1 100644
> --- a/drivers/power/reset/gpio-poweroff.c
> +++ b/drivers/power/reset/gpio-poweroff.c
> @@ -14,18 +14,18 @@
>  #include <linux/kernel.h>
>  #include <linux/init.h>
>  #include <linux/delay.h>
> +#include <linux/notifier.h>
> +#include <linux/pm.h>
>  #include <linux/platform_device.h>
>  #include <linux/gpio/consumer.h>
>  #include <linux/of_platform.h>
>  #include <linux/module.h>
>  
> -/*
> - * Hold configuration here, cannot be more than one instance of the driver
> - * since pm_power_off itself is global.
> - */
>  static struct gpio_desc *reset_gpio;
>  
> -static void gpio_poweroff_do_poweroff(void)
> +static int gpio_poweroff_do_poweroff(struct notifier_block *this,
> +				     unsigned long unused1, void *unused2)
> +
>  {
>  	BUG_ON(!reset_gpio);
>  
> @@ -42,20 +42,18 @@ static void gpio_poweroff_do_poweroff(void)
>  	/* give it some time */
>  	mdelay(3000);
>  
> -	WARN_ON(1);
> +	return NOTIFY_DONE;
>  }
>  
> +static struct notifier_block gpio_poweroff_nb = {
> +	.notifier_call = gpio_poweroff_do_poweroff,
> +	.priority = 64,
> +};
> +
>  static int gpio_poweroff_probe(struct platform_device *pdev)
>  {
>  	bool input = false;
> -
> -	/* If a pm_power_off function has already been added, leave it alone */
> -	if (pm_power_off != NULL) {
> -		dev_err(&pdev->dev,
> -			"%s: pm_power_off function already registered",
> -		       __func__);
> -		return -EBUSY;
> -	}
> +	int err;
>  
>  	reset_gpio = devm_gpiod_get(&pdev->dev, NULL);
>  	if (IS_ERR(reset_gpio))
> @@ -77,14 +75,16 @@ static int gpio_poweroff_probe(struct platform_device *pdev)
>  		}
>  	}
>  
> -	pm_power_off = &gpio_poweroff_do_poweroff;
> -	return 0;
> +	err = register_poweroff_handler(&gpio_poweroff_nb);
> +	if (err)
> +		dev_err(&pdev->dev, "Failed to register poweroff handler\n");
> +
> +	return err;
>  }
>  
>  static int gpio_poweroff_remove(struct platform_device *pdev)
>  {
> -	if (pm_power_off == &gpio_poweroff_do_poweroff)
> -		pm_power_off = NULL;
> +	unregister_poweroff_handler(&gpio_poweroff_nb);
>  
>  	return 0;
>  }
> -- 
> 1.9.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 23/44] power/reset: qnap-poweroff: Register with kernel poweroff handler
  2014-10-07  5:28 ` [PATCH 23/44] power/reset: qnap-poweroff: " Guenter Roeck
@ 2014-10-07 16:02   ` Andrew Lunn
  0 siblings, 0 replies; 91+ messages in thread
From: Andrew Lunn @ 2014-10-07 16:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Oct 06, 2014 at 10:28:25PM -0700, Guenter Roeck wrote:
> Register with kernel poweroff handler instead of setting pm_power_off
> directly. Register with default priority value of 128 to reflect that
> the original code generates an error if another poweroff handler has
> already been registered when the driver is loaded.
> 
> Cc: Sebastian Reichel <sre@kernel.org>
> Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> Cc: David Woodhouse <dwmw2@infradead.org>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>

Acked-by: Andrew Lunn <andrew@lunn.ch>

Thanks
	Andrew

> ---
>  drivers/power/reset/qnap-poweroff.c | 28 ++++++++++++++--------------
>  1 file changed, 14 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/power/reset/qnap-poweroff.c b/drivers/power/reset/qnap-poweroff.c
> index a75db7f..c474980 100644
> --- a/drivers/power/reset/qnap-poweroff.c
> +++ b/drivers/power/reset/qnap-poweroff.c
> @@ -16,7 +16,9 @@
>  
>  #include <linux/kernel.h>
>  #include <linux/module.h>
> +#include <linux/notifier.h>
>  #include <linux/platform_device.h>
> +#include <linux/pm.h>
>  #include <linux/serial_reg.h>
>  #include <linux/kallsyms.h>
>  #include <linux/of.h>
> @@ -55,7 +57,8 @@ static void __iomem *base;
>  static unsigned long tclk;
>  static const struct power_off_cfg *cfg;
>  
> -static void qnap_power_off(void)
> +static int qnap_power_off(struct notifier_block *this, unsigned long unused1,
> +			  void *unused2)
>  {
>  	const unsigned divisor = ((tclk + (8 * cfg->baud)) / (16 * cfg->baud));
>  
> @@ -72,14 +75,20 @@ static void qnap_power_off(void)
>  
>  	/* send the power-off command to PIC */
>  	writel(cfg->cmd, UART1_REG(TX));
> +
> +	return NOTIFY_DONE;
>  }
>  
> +static struct notifier_block qnap_poweroff_nb = {
> +	.notifier_call = qnap_power_off,
> +	.priority = 128,
> +};
> +
>  static int qnap_power_off_probe(struct platform_device *pdev)
>  {
>  	struct device_node *np = pdev->dev.of_node;
>  	struct resource *res;
>  	struct clk *clk;
> -	char symname[KSYM_NAME_LEN];
>  
>  	const struct of_device_id *match =
>  		of_match_node(qnap_power_off_of_match_table, np);
> @@ -106,22 +115,13 @@ static int qnap_power_off_probe(struct platform_device *pdev)
>  
>  	tclk = clk_get_rate(clk);
>  
> -	/* Check that nothing else has already setup a handler */
> -	if (pm_power_off) {
> -		lookup_symbol_name((ulong)pm_power_off, symname);
> -		dev_err(&pdev->dev,
> -			"pm_power_off already claimed %p %s",
> -			pm_power_off, symname);
> -		return -EBUSY;
> -	}
> -	pm_power_off = qnap_power_off;
> -
> -	return 0;
> +	return register_poweroff_handler(&qnap_poweroff_nb);
>  }
>  
>  static int qnap_power_off_remove(struct platform_device *pdev)
>  {
> -	pm_power_off = NULL;
> +	unregister_poweroff_handler(&qnap_poweroff_nb);
> +
>  	return 0;
>  }
>  
> -- 
> 1.9.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 20/44] power/reset: restart-poweroff: Register with kernel poweroff handler
  2014-10-07  5:28 ` [PATCH 20/44] power/reset: restart-poweroff: " Guenter Roeck
@ 2014-10-07 16:06   ` Andrew Lunn
  0 siblings, 0 replies; 91+ messages in thread
From: Andrew Lunn @ 2014-10-07 16:06 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Oct 06, 2014 at 10:28:22PM -0700, Guenter Roeck wrote:
> Register with kernel poweroff handler instead of seting pm_power_off
> directly.  Register as poweroff handler of last resort since the driver
> does not really power off the system but executes a restart.

I would not say last resort, this is how it is designed to work. There
is no way to turn the power off from with linux, it is designed that
u-boot will put the hardware into minimal power consumption until the
"power" button is pressed.

Other than that, 

Acked-by: Andrew Lunn <andrew@lunn.ch>

Thanks
	Andrew

> 
> Cc: Sebastian Reichel <sre@kernel.org>
> Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> Cc: David Woodhouse <dwmw2@infradead.org>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> ---
>  drivers/power/reset/restart-poweroff.c | 25 ++++++++++++-------------
>  1 file changed, 12 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/power/reset/restart-poweroff.c b/drivers/power/reset/restart-poweroff.c
> index edd707e..5437697 100644
> --- a/drivers/power/reset/restart-poweroff.c
> +++ b/drivers/power/reset/restart-poweroff.c
> @@ -12,35 +12,34 @@
>   */
>  #include <linux/kernel.h>
>  #include <linux/init.h>
> +#include <linux/notifier.h>
>  #include <linux/platform_device.h>
>  #include <linux/of_platform.h>
>  #include <linux/module.h>
> +#include <linux/pm.h>
>  #include <linux/reboot.h>
> -#include <asm/system_misc.h>
>  
> -static void restart_poweroff_do_poweroff(void)
> +static int restart_poweroff_do_poweroff(struct notifier_block *this,
> +					unsigned long unused1, void *unused2)
>  {
>  	reboot_mode = REBOOT_HARD;
>  	machine_restart(NULL);
> +
> +	return NOTIFY_DONE;
>  }
>  
> +static struct notifier_block restart_poweroff_handler = {
> +	.notifier_call = restart_poweroff_do_poweroff,
> +};
> +
>  static int restart_poweroff_probe(struct platform_device *pdev)
>  {
> -	/* If a pm_power_off function has already been added, leave it alone */
> -	if (pm_power_off != NULL) {
> -		dev_err(&pdev->dev,
> -			"pm_power_off function already registered");
> -		return -EBUSY;
> -	}
> -
> -	pm_power_off = &restart_poweroff_do_poweroff;
> -	return 0;
> +	return register_poweroff_handler(&restart_poweroff_handler);
>  }
>  
>  static int restart_poweroff_remove(struct platform_device *pdev)
>  {
> -	if (pm_power_off == &restart_poweroff_do_poweroff)
> -		pm_power_off = NULL;
> +	unregister_poweroff_handler(&restart_poweroff_handler);
>  
>  	return 0;
>  }
> -- 
> 1.9.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 05/44] mfd: as3722: Drop reference to pm_power_off from devicetree bindings
  2014-10-07  5:28 ` [PATCH 05/44] mfd: as3722: Drop reference to pm_power_off from devicetree bindings Guenter Roeck
  2014-10-07 10:59   ` Mark Rutland
@ 2014-10-07 16:21   ` Rob Landley
  2014-10-07 16:31     ` Guenter Roeck
  2014-10-07 16:58     ` Mark Rutland
  1 sibling, 2 replies; 91+ messages in thread
From: Rob Landley @ 2014-10-07 16:21 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/07/14 00:28, Guenter Roeck wrote:
> Devicetree bindings are supposed to be operating system independent
> and should thus not describe how a specific functionality is implemented
> in Linux.

So your argument is that linux/Documentation/devicetree/bindings should
not be specific to Linux. Merely hosted in the Linux kernel source
repository.

Well that's certainly a point of view.

Rob

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

* [PATCH 29/44] staging: nvec: Register with kernel poweroff handler
  2014-10-07  5:28 ` [PATCH 29/44] staging: nvec: Register " Guenter Roeck
@ 2014-10-07 16:23   ` Greg Kroah-Hartman
  2014-10-08 18:51   ` Marc Dietrich
  1 sibling, 0 replies; 91+ messages in thread
From: Greg Kroah-Hartman @ 2014-10-07 16:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Oct 06, 2014 at 10:28:31PM -0700, Guenter Roeck wrote:
> Register with kernel poweroff handler instead of setting pm_power_off
> directly. Register with default priority value of 128 since we don't know
> any better.
> 
> Cc: Julian Andres Klode <jak@jak-linux.org>
> Cc: Marc Dietrich <marvin24@gmx.de>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> ---
>  drivers/staging/nvec/nvec.c | 24 +++++++++++++++---------
>  drivers/staging/nvec/nvec.h |  2 ++
>  2 files changed, 17 insertions(+), 9 deletions(-)

Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

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

* [PATCH 05/44] mfd: as3722: Drop reference to pm_power_off from devicetree bindings
  2014-10-07 16:21   ` Rob Landley
@ 2014-10-07 16:31     ` Guenter Roeck
  2014-10-07 16:59       ` David Daney
  2014-10-07 16:58     ` Mark Rutland
  1 sibling, 1 reply; 91+ messages in thread
From: Guenter Roeck @ 2014-10-07 16:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 07, 2014 at 11:21:11AM -0500, Rob Landley wrote:
> On 10/07/14 00:28, Guenter Roeck wrote:
> > Devicetree bindings are supposed to be operating system independent
> > and should thus not describe how a specific functionality is implemented
> > in Linux.
> 
> So your argument is that linux/Documentation/devicetree/bindings should
> not be specific to Linux. Merely hosted in the Linux kernel source
> repository.
> 
> Well that's certainly a point of view.
> 
Not specifically my argument, really, and nothing new either. But, yes, I do
think that devicetree bindings descriptions should not include implementation
details, especially since those may change over time (as is the case here).

Thanks,
Guenter

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

* [PATCH 05/44] mfd: as3722: Drop reference to pm_power_off from devicetree bindings
  2014-10-07 16:21   ` Rob Landley
  2014-10-07 16:31     ` Guenter Roeck
@ 2014-10-07 16:58     ` Mark Rutland
  1 sibling, 0 replies; 91+ messages in thread
From: Mark Rutland @ 2014-10-07 16:58 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 07, 2014 at 05:21:11PM +0100, Rob Landley wrote:
> On 10/07/14 00:28, Guenter Roeck wrote:
> > Devicetree bindings are supposed to be operating system independent
> > and should thus not describe how a specific functionality is implemented
> > in Linux.
> 
> So your argument is that linux/Documentation/devicetree/bindings should
> not be specific to Linux. Merely hosted in the Linux kernel source
> repository.

Precisely. If nothing else as a general guideline this keeps us honest,
and prevents us from embedding arbitrary implementation details into
bidnings that cause pain later when we want to change things at either
end.

There are already otehr users of these bindings, so we can't really
claim they're strictly Linux-specific anyhow.

> Well that's certainly a point of view.

As far as I am aware, it's the point of view shared by the device tree
maintainers, and it's been that way for a while.

I don't really follow your concern. For one thing were this followed
more strictly this file wouldn't need patching at all to correct for
this Linux-internal rework...

Thanks,
Mark.

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

* [PATCH 05/44] mfd: as3722: Drop reference to pm_power_off from devicetree bindings
  2014-10-07 16:31     ` Guenter Roeck
@ 2014-10-07 16:59       ` David Daney
  2014-10-07 17:10         ` Rob Landley
  0 siblings, 1 reply; 91+ messages in thread
From: David Daney @ 2014-10-07 16:59 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/07/2014 09:31 AM, Guenter Roeck wrote:
> On Tue, Oct 07, 2014 at 11:21:11AM -0500, Rob Landley wrote:
>> On 10/07/14 00:28, Guenter Roeck wrote:
>>> Devicetree bindings are supposed to be operating system independent
>>> and should thus not describe how a specific functionality is implemented
>>> in Linux.
>>
>> So your argument is that linux/Documentation/devicetree/bindings should
>> not be specific to Linux. Merely hosted in the Linux kernel source
>> repository.
>>
>> Well that's certainly a point of view.
>>
> Not specifically my argument, really, and nothing new either. But, yes, I do
> think that devicetree bindings descriptions should not include implementation
> details, especially since those may change over time (as is the case here).
>

I fully agree.

Many device trees come from outside the kernel (i.e. they are supplied 
by the system boot environment).  Obviously these device trees cannot be 
changed at the whim of kernel developers, *and* it is perfectly 
reasonable to think that software other than the Linux kernel will run 
on this type of system too.

So yes, it is really true, device trees are not a Linux kernel private 
implementation detail, they are really an external ABI that, although 
documented in the kernel source tree, cannot be changed in incompatible 
ways as time progresses.

David Daney

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

* [PATCH 05/44] mfd: as3722: Drop reference to pm_power_off from devicetree bindings
  2014-10-07 16:59       ` David Daney
@ 2014-10-07 17:10         ` Rob Landley
  0 siblings, 0 replies; 91+ messages in thread
From: Rob Landley @ 2014-10-07 17:10 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/07/14 11:59, David Daney wrote:
> On 10/07/2014 09:31 AM, Guenter Roeck wrote:
>> On Tue, Oct 07, 2014 at 11:21:11AM -0500, Rob Landley wrote:
>>> On 10/07/14 00:28, Guenter Roeck wrote:
>>>> Devicetree bindings are supposed to be operating system independent
>>>> and should thus not describe how a specific functionality is
>>>> implemented
>>>> in Linux.
>>>
>>> So your argument is that linux/Documentation/devicetree/bindings should
>>> not be specific to Linux. Merely hosted in the Linux kernel source
>>> repository.
>>>
>>> Well that's certainly a point of view.
>>>
>> Not specifically my argument, really, and nothing new either. But,
>> yes, I do
>> think that devicetree bindings descriptions should not include
>> implementation
>> details, especially since those may change over time (as is the case
>> here).
>>
> 
> I fully agree.
> 
> Many device trees come from outside the kernel (i.e. they are supplied
> by the system boot environment).  Obviously these device trees cannot be
> changed at the whim of kernel developers, *and* it is perfectly
> reasonable to think that software other than the Linux kernel will run
> on this type of system too.
> 
> So yes, it is really true, device trees are not a Linux kernel private
> implementation detail, they are really an external ABI that, although
> documented in the kernel source tree, cannot be changed in incompatible
> ways as time progresses.

Ah. Existing thing with backstory among the in-crowd, so I'll assume
"git subtree" was previously suggested and you had that discussion
already and decided against it.

Carry on,

Rob

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

* [PATCH 03/44] hibernate: Call have_kernel_poweroff instead of checking pm_power_off
  2014-10-07  5:28 ` [PATCH 03/44] hibernate: Call have_kernel_poweroff instead of checking pm_power_off Guenter Roeck
@ 2014-10-07 23:41   ` Rafael J. Wysocki
  2014-10-09 10:32   ` Pavel Machek
  1 sibling, 0 replies; 91+ messages in thread
From: Rafael J. Wysocki @ 2014-10-07 23:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday, October 06, 2014 10:28:05 PM Guenter Roeck wrote:
> Poweroff handlers may now be installed with register_poweroff_handler.
> Use the new API function have_kernel_poweroff to determine if a poweroff
> handler has been installed.
> 
> Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
> Cc: Pavel Machek <pavel@ucw.cz>
> Cc: Len Brown <len.brown@intel.com>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>

ACK

> ---
>  kernel/power/hibernate.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
> index a9dfa79..20353c5 100644
> --- a/kernel/power/hibernate.c
> +++ b/kernel/power/hibernate.c
> @@ -602,7 +602,7 @@ static void power_down(void)
>  	case HIBERNATION_PLATFORM:
>  		hibernation_platform_enter();
>  	case HIBERNATION_SHUTDOWN:
> -		if (pm_power_off)
> +		if (have_kernel_poweroff())
>  			kernel_power_off();
>  		break;
>  #ifdef CONFIG_SUSPEND
> 

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* [PATCH 44/44] kernel: Remove pm_power_off
  2014-10-07  5:28 ` [PATCH 44/44] kernel: Remove pm_power_off Guenter Roeck
@ 2014-10-07 23:43   ` Rafael J. Wysocki
  0 siblings, 0 replies; 91+ messages in thread
From: Rafael J. Wysocki @ 2014-10-07 23:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday, October 06, 2014 10:28:46 PM Guenter Roeck wrote:
> No users of pm_power_off are left, so it is safe to remove the function.
> 
> Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
> Cc: Pavel Machek <pavel@ucw.cz>
> Cc: Len Brown <len.brown@intel.com>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>

ACK

> ---
>  include/linux/pm.h              |  1 -
>  kernel/power/poweroff_handler.c | 10 +---------
>  2 files changed, 1 insertion(+), 10 deletions(-)
> 
> diff --git a/include/linux/pm.h b/include/linux/pm.h
> index 45271b5..fce7645 100644
> --- a/include/linux/pm.h
> +++ b/include/linux/pm.h
> @@ -31,7 +31,6 @@
>  /*
>   * Callbacks for platform drivers to implement.
>   */
> -extern void (*pm_power_off)(void);
>  extern void (*pm_power_off_prepare)(void);
>  
>  /*
> diff --git a/kernel/power/poweroff_handler.c b/kernel/power/poweroff_handler.c
> index 96f59ef..01a3a39 100644
> --- a/kernel/power/poweroff_handler.c
> +++ b/kernel/power/poweroff_handler.c
> @@ -20,12 +20,6 @@
>  #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.
>   */
> @@ -163,8 +157,6 @@ int register_poweroff_handler_simple(void (*handler)(void), int priority)
>   */
>  void do_kernel_poweroff(void)
>  {
> -	if (pm_power_off)
> -		pm_power_off();
>  	atomic_notifier_call_chain(&poweroff_handler_list, 0, NULL);
>  }
>  
> @@ -175,6 +167,6 @@ void do_kernel_poweroff(void)
>   */
>  bool have_kernel_poweroff(void)
>  {
> -	return pm_power_off != NULL || poweroff_handler_list.head != NULL;
> +	return poweroff_handler_list.head != NULL;
>  }
>  EXPORT_SYMBOL(have_kernel_poweroff);
> 

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* [PATCH 29/44] staging: nvec: Register with kernel poweroff handler
  2014-10-07  5:28 ` [PATCH 29/44] staging: nvec: Register " Guenter Roeck
  2014-10-07 16:23   ` Greg Kroah-Hartman
@ 2014-10-08 18:51   ` Marc Dietrich
  1 sibling, 0 replies; 91+ messages in thread
From: Marc Dietrich @ 2014-10-08 18:51 UTC (permalink / raw)
  To: linux-arm-kernel

Am Montag 06 Oktober 2014, 22:28:31 schrieb Guenter Roeck:
> Register with kernel poweroff handler instead of setting pm_power_off
> directly. Register with default priority value of 128 since we don't know
> any better.

I just tested this change and it seems to break power off. What the driver 
does it to queue the power off request and execute it sometime later. The 
command is send via i2c to an embedded controller (mfd device) which is 
responsible for removing the power.

I haven't analyzed further, but I guess this could be related with the atomic 
discussion brought up in some other thread of this patch series.

Marc

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

* [PATCH 01/44] kernel: Add support for poweroff handler call chain
  2014-10-07  5:28 ` [PATCH 01/44] kernel: Add support for poweroff handler call chain Guenter Roeck
  2014-10-07  7:46   ` Philippe Rétornaz
@ 2014-10-09 10:31   ` Pavel Machek
  2014-10-09 15:38     ` Guenter Roeck
  2014-10-09 11:31   ` Geert Uytterhoeven
  2015-06-18  1:04   ` Stephen Boyd
  3 siblings, 1 reply; 91+ messages in thread
From: Pavel Machek @ 2014-10-09 10:31 UTC (permalink / raw)
  To: linux-arm-kernel

Hi!

> +/**
> + *	register_poweroff_handler_simple - Register function to be called to power off
> + *					   the system
> + *	@handler:	Function to be called to power off the system
> + *	@priority:	Handler priority. For priority guidelines see
> + *			register_poweroff_handler.
> + *
> + *	This is a simplified version of register_poweroff_handler. It does not
> + *	take a notifier as argument, but a function pointer. The function
> + *	registers a poweroff handler with specified priority. Poweroff
> + *	handlers registered with this function can not be unregistered,
> + *	and only a single poweroff handler can be installed using it.
> + *
> + *	This function must not be called from modules and is therefore
> + *	not exported.
> + *
> + *	Returns -EBUSY if a poweroff handler has already been registered
> + *	using register_poweroff_handler_simple. Otherwise returns zero,
> + *	since atomic_notifier_chain_register() currently always returns zero.
> + */
> +int register_poweroff_handler_simple(void (*handler)(void), int priority)
> +{
> +	char symname[KSYM_NAME_LEN];
> +
> +	if (poweroff_handler_data.handler) {
> +		lookup_symbol_name((unsigned long)poweroff_handler_data.handler,
> +				   symname);
> +		pr_warn("Poweroff function already registered (%s)", symname);
> +		lookup_symbol_name((unsigned long)handler, symname);
> +		pr_cont(", cannot register %s\n", symname);
> +		return -EBUSY;
> +	}

Dunno, are you maybe overdoing the debugging infrastructure a bit?
This is not going to happen in production, and if it does happen,
developer can look the symbol name himself.
									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

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

* [PATCH 03/44] hibernate: Call have_kernel_poweroff instead of checking pm_power_off
  2014-10-07  5:28 ` [PATCH 03/44] hibernate: Call have_kernel_poweroff instead of checking pm_power_off Guenter Roeck
  2014-10-07 23:41   ` Rafael J. Wysocki
@ 2014-10-09 10:32   ` Pavel Machek
  2014-10-09 13:24     ` Guenter Roeck
  1 sibling, 1 reply; 91+ messages in thread
From: Pavel Machek @ 2014-10-09 10:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon 2014-10-06 22:28:05, Guenter Roeck wrote:
> Poweroff handlers may now be installed with register_poweroff_handler.
> Use the new API function have_kernel_poweroff to determine if a poweroff
> handler has been installed.
> 
> Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
> Cc: Pavel Machek <pavel@ucw.cz>
> Cc: Len Brown <len.brown@intel.com>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> ---
>  kernel/power/hibernate.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
> index a9dfa79..20353c5 100644
> --- a/kernel/power/hibernate.c
> +++ b/kernel/power/hibernate.c
> @@ -602,7 +602,7 @@ static void power_down(void)
>  	case HIBERNATION_PLATFORM:
>  		hibernation_platform_enter();
>  	case HIBERNATION_SHUTDOWN:
> -		if (pm_power_off)
> +		if (have_kernel_poweroff())
>  			kernel_power_off();
>  		break;

poweroff -> power_off.

But if you are playing with this, anyway... does it make sense to
introduce kernel_power_off() that just works, no need to check
have_..?
									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

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

* [PATCH 12/44] mfd: ab8500-sysctrl: Register with kernel poweroff handler
  2014-10-07  8:00   ` Lee Jones
@ 2014-10-09 10:36     ` Catalin Marinas
  2014-10-09 10:49       ` Lee Jones
  0 siblings, 1 reply; 91+ messages in thread
From: Catalin Marinas @ 2014-10-09 10:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 07, 2014 at 09:00:48AM +0100, Lee Jones wrote:
> On Mon, 06 Oct 2014, Guenter Roeck wrote:
> > --- a/drivers/mfd/ab8500-sysctrl.c
> > +++ b/drivers/mfd/ab8500-sysctrl.c
> > @@ -6,6 +6,7 @@
> 
> [...]
> 
> > +static int ab8500_power_off(struct notifier_block *this, unsigned long unused1,
> > +			    void *unused2)
> >  {
> >  	sigset_t old;
> >  	sigset_t all;
> > @@ -34,11 +36,6 @@ static void ab8500_power_off(void)
> >  	struct power_supply *psy;
> >  	int ret;
> >  
> > -	if (sysctrl_dev == NULL) {
> > -		pr_err("%s: sysctrl not initialized\n", __func__);
> > -		return;
> > -	}
> 
> Can you explain the purpose of this change please?

I guess it's because the sysctrl_dev is already initialised when
registering the power_off handler, so there isn't a way to call the
above function with a NULL sysctrl_dev. Probably even with the original
code you didn't need this check (after some race fix in
ab8500_sysctrl_remove but races is one of the things Guenter's patches
try to address).

-- 
Catalin

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

* [PATCH 32/44] arm64: psci: Register with kernel poweroff handler
  2014-10-07  5:28 ` [PATCH 32/44] arm64: psci: Register " Guenter Roeck
@ 2014-10-09 10:41   ` Catalin Marinas
  0 siblings, 0 replies; 91+ messages in thread
From: Catalin Marinas @ 2014-10-09 10:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 07, 2014 at 06:28:34AM +0100, Guenter Roeck wrote:
> Register with kernel poweroff handler instead of setting pm_power_off
> directly.
> 
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> ---
>  arch/arm64/kernel/psci.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
> index 5539547..c1f3d09 100644
> --- a/arch/arm64/kernel/psci.c
> +++ b/arch/arm64/kernel/psci.c
> @@ -286,7 +286,7 @@ static int __init psci_0_2_init(struct device_node *np)
>  
>  	arm_pm_restart = psci_sys_reset;
>  
> -	pm_power_off = psci_sys_poweroff;
> +	register_poweroff_handler_simple(psci_sys_poweroff, 128);
>  
>  out_put_node:
>  	of_node_put(np);

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

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

* [PATCH 12/44] mfd: ab8500-sysctrl: Register with kernel poweroff handler
  2014-10-09 10:36     ` Catalin Marinas
@ 2014-10-09 10:49       ` Lee Jones
  2014-10-09 13:26         ` Guenter Roeck
  2014-10-09 15:54         ` Guenter Roeck
  0 siblings, 2 replies; 91+ messages in thread
From: Lee Jones @ 2014-10-09 10:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 09 Oct 2014, Catalin Marinas wrote:

> On Tue, Oct 07, 2014 at 09:00:48AM +0100, Lee Jones wrote:
> > On Mon, 06 Oct 2014, Guenter Roeck wrote:
> > > --- a/drivers/mfd/ab8500-sysctrl.c
> > > +++ b/drivers/mfd/ab8500-sysctrl.c
> > > @@ -6,6 +6,7 @@
> > 
> > [...]
> > 
> > > +static int ab8500_power_off(struct notifier_block *this, unsigned long unused1,
> > > +			    void *unused2)
> > >  {
> > >  	sigset_t old;
> > >  	sigset_t all;
> > > @@ -34,11 +36,6 @@ static void ab8500_power_off(void)
> > >  	struct power_supply *psy;
> > >  	int ret;
> > >  
> > > -	if (sysctrl_dev == NULL) {
> > > -		pr_err("%s: sysctrl not initialized\n", __func__);
> > > -		return;
> > > -	}
> > 
> > Can you explain the purpose of this change please?
> 
> I guess it's because the sysctrl_dev is already initialised when
> registering the power_off handler, so there isn't a way to call the
> above function with a NULL sysctrl_dev. Probably even with the original
> code you didn't need this check (after some race fix in
> ab8500_sysctrl_remove but races is one of the things Guenter's patches
> try to address).

Sounds reasonable, although I think this change should be part of
another patch.

-- 
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] 91+ messages in thread

* [PATCH 01/44] kernel: Add support for poweroff handler call chain
  2014-10-07  5:28 ` [PATCH 01/44] kernel: Add support for poweroff handler call chain Guenter Roeck
  2014-10-07  7:46   ` Philippe Rétornaz
  2014-10-09 10:31   ` Pavel Machek
@ 2014-10-09 11:31   ` Geert Uytterhoeven
  2014-10-09 13:25     ` Guenter Roeck
  2015-06-18  1:04   ` Stephen Boyd
  3 siblings, 1 reply; 91+ messages in thread
From: Geert Uytterhoeven @ 2014-10-09 11:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 7, 2014 at 7:28 AM, Guenter Roeck <linux@roeck-us.net> wrote:
> +int register_poweroff_handler_simple(void (*handler)(void), int priority)
> +{
> +       char symname[KSYM_NAME_LEN];
> +
> +       if (poweroff_handler_data.handler) {
> +               lookup_symbol_name((unsigned long)poweroff_handler_data.handler,
> +                                  symname);
> +               pr_warn("Poweroff function already registered (%s)", symname);
> +               lookup_symbol_name((unsigned long)handler, symname);
> +               pr_cont(", cannot register %s\n", symname);

Doesn't %ps work to look up symbols?

pr_warn("Poweroff function already registered (%ps), cannot register
%ps\n", poweroff_handler_data.handler, handler);

> +               return -EBUSY;
> +       }

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* [PATCH 03/44] hibernate: Call have_kernel_poweroff instead of checking pm_power_off
  2014-10-09 10:32   ` Pavel Machek
@ 2014-10-09 13:24     ` Guenter Roeck
  0 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-09 13:24 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/09/2014 03:32 AM, Pavel Machek wrote:
> On Mon 2014-10-06 22:28:05, Guenter Roeck wrote:
>> Poweroff handlers may now be installed with register_poweroff_handler.
>> Use the new API function have_kernel_poweroff to determine if a poweroff
>> handler has been installed.
>>
>> Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
>> Cc: Pavel Machek <pavel@ucw.cz>
>> Cc: Len Brown <len.brown@intel.com>
>> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
>> ---
>>   kernel/power/hibernate.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
>> index a9dfa79..20353c5 100644
>> --- a/kernel/power/hibernate.c
>> +++ b/kernel/power/hibernate.c
>> @@ -602,7 +602,7 @@ static void power_down(void)
>>   	case HIBERNATION_PLATFORM:
>>   		hibernation_platform_enter();
>>   	case HIBERNATION_SHUTDOWN:
>> -		if (pm_power_off)
>> +		if (have_kernel_poweroff())
>>   			kernel_power_off();
>>   		break;
>
> poweroff -> power_off.
>
As mentioned in my other reply, that was on purpose to distinguish
existing functions from poweroff handler functions.

> But if you are playing with this, anyway... does it make sense to
> introduce kernel_power_off() that just works, no need to check
> have_..?
> 									Pavel

I am trying not to change existing behavior.

kernel_power_off is an existing function which does some cleanup
before calling machine_power_off which in turn calls do_kernel_poweroff
(or currently pm_power_off and may do some other machine specific stuff.

Sure, poweroff handling could be unified further. We could decide to
enter an endless loop if machine_power_off() returns, or we could decide
to dump a warning or panic in this case. But that is all separate from
the issue I am trying to solve here, which is to provide a capability to
register more than one poweroff handler. It would also not be that simple,
since some architectures call machine_power_off() directly from various
places.

Guenter

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

* [PATCH 01/44] kernel: Add support for poweroff handler call chain
  2014-10-09 11:31   ` Geert Uytterhoeven
@ 2014-10-09 13:25     ` Guenter Roeck
  0 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-09 13:25 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/09/2014 04:31 AM, Geert Uytterhoeven wrote:
> On Tue, Oct 7, 2014 at 7:28 AM, Guenter Roeck <linux@roeck-us.net> wrote:
>> +int register_poweroff_handler_simple(void (*handler)(void), int priority)
>> +{
>> +       char symname[KSYM_NAME_LEN];
>> +
>> +       if (poweroff_handler_data.handler) {
>> +               lookup_symbol_name((unsigned long)poweroff_handler_data.handler,
>> +                                  symname);
>> +               pr_warn("Poweroff function already registered (%s)", symname);
>> +               lookup_symbol_name((unsigned long)handler, symname);
>> +               pr_cont(", cannot register %s\n", symname);
>
> Doesn't %ps work to look up symbols?
>
> pr_warn("Poweroff function already registered (%ps), cannot register
> %ps\n", poweroff_handler_data.handler, handler);
>

Hi Geert,

That is great. One never stops learning. I'll use that.

Thanks!

Guenter

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

* [PATCH 12/44] mfd: ab8500-sysctrl: Register with kernel poweroff handler
  2014-10-09 10:49       ` Lee Jones
@ 2014-10-09 13:26         ` Guenter Roeck
  2014-10-09 13:33           ` Lee Jones
  2014-10-09 15:54         ` Guenter Roeck
  1 sibling, 1 reply; 91+ messages in thread
From: Guenter Roeck @ 2014-10-09 13:26 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/09/2014 03:49 AM, Lee Jones wrote:
> On Thu, 09 Oct 2014, Catalin Marinas wrote:
>
>> On Tue, Oct 07, 2014 at 09:00:48AM +0100, Lee Jones wrote:
>>> On Mon, 06 Oct 2014, Guenter Roeck wrote:
>>>> --- a/drivers/mfd/ab8500-sysctrl.c
>>>> +++ b/drivers/mfd/ab8500-sysctrl.c
>>>> @@ -6,6 +6,7 @@
>>>
>>> [...]
>>>
>>>> +static int ab8500_power_off(struct notifier_block *this, unsigned long unused1,
>>>> +			    void *unused2)
>>>>   {
>>>>   	sigset_t old;
>>>>   	sigset_t all;
>>>> @@ -34,11 +36,6 @@ static void ab8500_power_off(void)
>>>>   	struct power_supply *psy;
>>>>   	int ret;
>>>>
>>>> -	if (sysctrl_dev == NULL) {
>>>> -		pr_err("%s: sysctrl not initialized\n", __func__);
>>>> -		return;
>>>> -	}
>>>
>>> Can you explain the purpose of this change please?
>>
>> I guess it's because the sysctrl_dev is already initialised when
>> registering the power_off handler, so there isn't a way to call the
>> above function with a NULL sysctrl_dev. Probably even with the original
>> code you didn't need this check (after some race fix in
>> ab8500_sysctrl_remove but races is one of the things Guenter's patches
>> try to address).
>
> Sounds reasonable, although I think this change should be part of
> another patch.
>
Sure, no problem. I'll split this into two patches.

Since we are at it, any idea what to do with the restart function
in the same file ? It is not used anywhere.

Guenter

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

* [PATCH 12/44] mfd: ab8500-sysctrl: Register with kernel poweroff handler
  2014-10-09 13:26         ` Guenter Roeck
@ 2014-10-09 13:33           ` Lee Jones
  2014-10-09 15:45             ` Guenter Roeck
  0 siblings, 1 reply; 91+ messages in thread
From: Lee Jones @ 2014-10-09 13:33 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 09 Oct 2014, Guenter Roeck wrote:

> On 10/09/2014 03:49 AM, Lee Jones wrote:
> >On Thu, 09 Oct 2014, Catalin Marinas wrote:
> >
> >>On Tue, Oct 07, 2014 at 09:00:48AM +0100, Lee Jones wrote:
> >>>On Mon, 06 Oct 2014, Guenter Roeck wrote:
> >>>>--- a/drivers/mfd/ab8500-sysctrl.c
> >>>>+++ b/drivers/mfd/ab8500-sysctrl.c
> >>>>@@ -6,6 +6,7 @@
> >>>
> >>>[...]
> >>>
> >>>>+static int ab8500_power_off(struct notifier_block *this, unsigned long unused1,
> >>>>+			    void *unused2)
> >>>>  {
> >>>>  	sigset_t old;
> >>>>  	sigset_t all;
> >>>>@@ -34,11 +36,6 @@ static void ab8500_power_off(void)
> >>>>  	struct power_supply *psy;
> >>>>  	int ret;
> >>>>
> >>>>-	if (sysctrl_dev == NULL) {
> >>>>-		pr_err("%s: sysctrl not initialized\n", __func__);
> >>>>-		return;
> >>>>-	}
> >>>
> >>>Can you explain the purpose of this change please?
> >>
> >>I guess it's because the sysctrl_dev is already initialised when
> >>registering the power_off handler, so there isn't a way to call the
> >>above function with a NULL sysctrl_dev. Probably even with the original
> >>code you didn't need this check (after some race fix in
> >>ab8500_sysctrl_remove but races is one of the things Guenter's patches
> >>try to address).
> >
> >Sounds reasonable, although I think this change should be part of
> >another patch.
> >
> Sure, no problem. I'll split this into two patches.
> 
> Since we are at it, any idea what to do with the restart function
> in the same file ? It is not used anywhere.

You can strip it out with Linus Walleij's Ack.  Or I'll be happy to do
it?

-- 
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] 91+ messages in thread

* [PATCH 01/44] kernel: Add support for poweroff handler call chain
  2014-10-09 10:31   ` Pavel Machek
@ 2014-10-09 15:38     ` Guenter Roeck
  0 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-09 15:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 09, 2014 at 12:31:43PM +0200, Pavel Machek wrote:
> Hi!
> 
> > +/**
> > + *	register_poweroff_handler_simple - Register function to be called to power off
> > + *					   the system
> > + *	@handler:	Function to be called to power off the system
> > + *	@priority:	Handler priority. For priority guidelines see
> > + *			register_poweroff_handler.
> > + *
> > + *	This is a simplified version of register_poweroff_handler. It does not
> > + *	take a notifier as argument, but a function pointer. The function
> > + *	registers a poweroff handler with specified priority. Poweroff
> > + *	handlers registered with this function can not be unregistered,
> > + *	and only a single poweroff handler can be installed using it.
> > + *
> > + *	This function must not be called from modules and is therefore
> > + *	not exported.
> > + *
> > + *	Returns -EBUSY if a poweroff handler has already been registered
> > + *	using register_poweroff_handler_simple. Otherwise returns zero,
> > + *	since atomic_notifier_chain_register() currently always returns zero.
> > + */
> > +int register_poweroff_handler_simple(void (*handler)(void), int priority)
> > +{
> > +	char symname[KSYM_NAME_LEN];
> > +
> > +	if (poweroff_handler_data.handler) {
> > +		lookup_symbol_name((unsigned long)poweroff_handler_data.handler,
> > +				   symname);
> > +		pr_warn("Poweroff function already registered (%s)", symname);
> > +		lookup_symbol_name((unsigned long)handler, symname);
> > +		pr_cont(", cannot register %s\n", symname);
> > +		return -EBUSY;
> > +	}
> 
> Dunno, are you maybe overdoing the debugging infrastructure a bit?
> This is not going to happen in production, and if it does happen,
> developer can look the symbol name himself.

On the other side, I don't think it hurts to have that message.
Anyway, I'll use %ps as suggested by Geert.

Guenter

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

* [PATCH 12/44] mfd: ab8500-sysctrl: Register with kernel poweroff handler
  2014-10-09 13:33           ` Lee Jones
@ 2014-10-09 15:45             ` Guenter Roeck
  0 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-09 15:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 09, 2014 at 02:33:55PM +0100, Lee Jones wrote:
> On Thu, 09 Oct 2014, Guenter Roeck wrote:
> 
> > On 10/09/2014 03:49 AM, Lee Jones wrote:
> > >On Thu, 09 Oct 2014, Catalin Marinas wrote:
> > >
> > >>On Tue, Oct 07, 2014 at 09:00:48AM +0100, Lee Jones wrote:
> > >>>On Mon, 06 Oct 2014, Guenter Roeck wrote:
> > >>>>--- a/drivers/mfd/ab8500-sysctrl.c
> > >>>>+++ b/drivers/mfd/ab8500-sysctrl.c
> > >>>>@@ -6,6 +6,7 @@
> > >>>
> > >>>[...]
> > >>>
> > >>>>+static int ab8500_power_off(struct notifier_block *this, unsigned long unused1,
> > >>>>+			    void *unused2)
> > >>>>  {
> > >>>>  	sigset_t old;
> > >>>>  	sigset_t all;
> > >>>>@@ -34,11 +36,6 @@ static void ab8500_power_off(void)
> > >>>>  	struct power_supply *psy;
> > >>>>  	int ret;
> > >>>>
> > >>>>-	if (sysctrl_dev == NULL) {
> > >>>>-		pr_err("%s: sysctrl not initialized\n", __func__);
> > >>>>-		return;
> > >>>>-	}
> > >>>
> > >>>Can you explain the purpose of this change please?
> > >>
> > >>I guess it's because the sysctrl_dev is already initialised when
> > >>registering the power_off handler, so there isn't a way to call the
> > >>above function with a NULL sysctrl_dev. Probably even with the original
> > >>code you didn't need this check (after some race fix in
> > >>ab8500_sysctrl_remove but races is one of the things Guenter's patches
> > >>try to address).
> > >
> > >Sounds reasonable, although I think this change should be part of
> > >another patch.
> > >
> > Sure, no problem. I'll split this into two patches.
> > 
> > Since we are at it, any idea what to do with the restart function
> > in the same file ? It is not used anywhere.
> 
> You can strip it out with Linus Walleij's Ack.  Or I'll be happy to do
> it?
> 
I'll strip it out in a 3rd patch.

Guenter

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

* [PATCH 12/44] mfd: ab8500-sysctrl: Register with kernel poweroff handler
  2014-10-09 10:49       ` Lee Jones
  2014-10-09 13:26         ` Guenter Roeck
@ 2014-10-09 15:54         ` Guenter Roeck
  1 sibling, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-09 15:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 09, 2014 at 11:49:27AM +0100, Lee Jones wrote:
> On Thu, 09 Oct 2014, Catalin Marinas wrote:
> 
> > On Tue, Oct 07, 2014 at 09:00:48AM +0100, Lee Jones wrote:
> > > On Mon, 06 Oct 2014, Guenter Roeck wrote:
> > > > --- a/drivers/mfd/ab8500-sysctrl.c
> > > > +++ b/drivers/mfd/ab8500-sysctrl.c
> > > > @@ -6,6 +6,7 @@
> > > 
> > > [...]
> > > 
> > > > +static int ab8500_power_off(struct notifier_block *this, unsigned long unused1,
> > > > +			    void *unused2)
> > > >  {
> > > >  	sigset_t old;
> > > >  	sigset_t all;
> > > > @@ -34,11 +36,6 @@ static void ab8500_power_off(void)
> > > >  	struct power_supply *psy;
> > > >  	int ret;
> > > >  
> > > > -	if (sysctrl_dev == NULL) {
> > > > -		pr_err("%s: sysctrl not initialized\n", __func__);
> > > > -		return;
> > > > -	}
> > > 
> > > Can you explain the purpose of this change please?
> > 
> > I guess it's because the sysctrl_dev is already initialised when
> > registering the power_off handler, so there isn't a way to call the
> > above function with a NULL sysctrl_dev. Probably even with the original
> > code you didn't need this check (after some race fix in
> > ab8500_sysctrl_remove but races is one of the things Guenter's patches
> > try to address).
> 
> Sounds reasonable, although I think this change should be part of
> another patch.
> 
Turns out the options are to either drop the check or to use the device
managed function to register the poweroff handler. I decided to keep
the check and use the device managed function.

Guenter

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

* [PATCH 42/44] efi: Register poweroff handler with kernel poweroff handler
  2014-10-07  5:28 ` [PATCH 42/44] efi: " Guenter Roeck
@ 2014-10-16 14:59   ` Matt Fleming
  2014-10-16 15:24     ` Mark Salter
  0 siblings, 1 reply; 91+ messages in thread
From: Matt Fleming @ 2014-10-16 14:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 06 Oct, at 10:28:44PM, Guenter Roeck wrote:
> Register with kernel poweroff handler instead of setting pm_power_off
> directly. Register with low priority value of 64 since the efi code
> states that this is a poweroff handler of last resort.
> 
> Cc: Matt Fleming <matt.fleming@intel.com>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> ---
>  drivers/firmware/efi/reboot.c | 23 +++++++++++++++++++----
>  1 file changed, 19 insertions(+), 4 deletions(-)
 
Looks OK to me. Mark?

> diff --git a/drivers/firmware/efi/reboot.c b/drivers/firmware/efi/reboot.c
> index 9c59d1c..c082439 100644
> --- a/drivers/firmware/efi/reboot.c
> +++ b/drivers/firmware/efi/reboot.c
> @@ -3,6 +3,8 @@
>   * Copyright (c) 2014 Red Hat, Inc., Mark Salter <msalter@redhat.com>
>   */
>  #include <linux/efi.h>
> +#include <linux/notifier.h>
> +#include <linux/pm.h>
>  #include <linux/reboot.h>
>  
>  int efi_reboot_quirk_mode = -1;
> @@ -38,19 +40,32 @@ bool __weak efi_poweroff_required(void)
>  	return false;
>  }
>  
> -static void efi_power_off(void)
> +static int efi_power_off(struct notifier_block *this,
> +			 unsigned long unused1, void *unused2)
>  {
>  	efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL);
> +
> +	return NOTIFY_DONE;
>  }
>  
> +static struct notifier_block efi_poweroff_nb = {
> +	.notifier_call = efi_power_off,
> +	.priority = 64,
> +};
> +
>  static int __init efi_shutdown_init(void)
>  {
> +	int ret = 0;
> +
>  	if (!efi_enabled(EFI_RUNTIME_SERVICES))
>  		return -ENODEV;
>  
> -	if (efi_poweroff_required())
> -		pm_power_off = efi_power_off;
> +	if (efi_poweroff_required()) {
> +		ret = register_poweroff_handler(&efi_poweroff_nb);
> +		if (ret)
> +			pr_err("efi: Failed to register poweroff handler\n");
> +	}
>  
> -	return 0;
> +	return ret;
>  }
>  late_initcall(efi_shutdown_init);
> -- 
> 1.9.1


-- 
Matt Fleming, Intel Open Source Technology Center

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

* [PATCH 42/44] efi: Register poweroff handler with kernel poweroff handler
  2014-10-16 14:59   ` Matt Fleming
@ 2014-10-16 15:24     ` Mark Salter
  2014-10-16 17:27       ` Guenter Roeck
  0 siblings, 1 reply; 91+ messages in thread
From: Mark Salter @ 2014-10-16 15:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 2014-10-16 at 15:59 +0100, Matt Fleming wrote:
> On Mon, 06 Oct, at 10:28:44PM, Guenter Roeck wrote:
> > Register with kernel poweroff handler instead of setting pm_power_off
> > directly. Register with low priority value of 64 since the efi code
> > states that this is a poweroff handler of last resort.
> > 
> > Cc: Matt Fleming <matt.fleming@intel.com>
> > Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> > ---
> >  drivers/firmware/efi/reboot.c | 23 +++++++++++++++++++----
> >  1 file changed, 19 insertions(+), 4 deletions(-)
>  
> Looks OK to me. Mark?

Me too.

Acked-by: Mark Salter <msalter@redhat.com>

> 
> > diff --git a/drivers/firmware/efi/reboot.c b/drivers/firmware/efi/reboot.c
> > index 9c59d1c..c082439 100644
> > --- a/drivers/firmware/efi/reboot.c
> > +++ b/drivers/firmware/efi/reboot.c
> > @@ -3,6 +3,8 @@
> >   * Copyright (c) 2014 Red Hat, Inc., Mark Salter <msalter@redhat.com>
> >   */
> >  #include <linux/efi.h>
> > +#include <linux/notifier.h>
> > +#include <linux/pm.h>
> >  #include <linux/reboot.h>
> >  
> >  int efi_reboot_quirk_mode = -1;
> > @@ -38,19 +40,32 @@ bool __weak efi_poweroff_required(void)
> >  	return false;
> >  }
> >  
> > -static void efi_power_off(void)
> > +static int efi_power_off(struct notifier_block *this,
> > +			 unsigned long unused1, void *unused2)
> >  {
> >  	efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL);
> > +
> > +	return NOTIFY_DONE;
> >  }
> >  
> > +static struct notifier_block efi_poweroff_nb = {
> > +	.notifier_call = efi_power_off,
> > +	.priority = 64,
> > +};
> > +
> >  static int __init efi_shutdown_init(void)
> >  {
> > +	int ret = 0;
> > +
> >  	if (!efi_enabled(EFI_RUNTIME_SERVICES))
> >  		return -ENODEV;
> >  
> > -	if (efi_poweroff_required())
> > -		pm_power_off = efi_power_off;
> > +	if (efi_poweroff_required()) {
> > +		ret = register_poweroff_handler(&efi_poweroff_nb);
> > +		if (ret)
> > +			pr_err("efi: Failed to register poweroff handler\n");
> > +	}
> >  
> > -	return 0;
> > +	return ret;
> >  }
> >  late_initcall(efi_shutdown_init);
> > -- 
> > 1.9.1
> 
> 

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

* [PATCH 42/44] efi: Register poweroff handler with kernel poweroff handler
  2014-10-16 15:24     ` Mark Salter
@ 2014-10-16 17:27       ` Guenter Roeck
  2014-10-16 17:46         ` Matt Fleming
  0 siblings, 1 reply; 91+ messages in thread
From: Guenter Roeck @ 2014-10-16 17:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 16, 2014 at 11:24:53AM -0400, Mark Salter wrote:
> On Thu, 2014-10-16 at 15:59 +0100, Matt Fleming wrote:
> > On Mon, 06 Oct, at 10:28:44PM, Guenter Roeck wrote:
> > > Register with kernel poweroff handler instead of setting pm_power_off
> > > directly. Register with low priority value of 64 since the efi code
> > > states that this is a poweroff handler of last resort.
> > > 
> > > Cc: Matt Fleming <matt.fleming@intel.com>
> > > Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> > > ---
> > >  drivers/firmware/efi/reboot.c | 23 +++++++++++++++++++----
> > >  1 file changed, 19 insertions(+), 4 deletions(-)
> >  
> > Looks OK to me. Mark?
> 
> Me too.
> 
> Acked-by: Mark Salter <msalter@redhat.com>
> 
Great, thanks a lot for the feedback.

Matt, is it ok for me to add your Acked-by: ?

Thanks,
Guenter

> > 
> > > diff --git a/drivers/firmware/efi/reboot.c b/drivers/firmware/efi/reboot.c
> > > index 9c59d1c..c082439 100644
> > > --- a/drivers/firmware/efi/reboot.c
> > > +++ b/drivers/firmware/efi/reboot.c
> > > @@ -3,6 +3,8 @@
> > >   * Copyright (c) 2014 Red Hat, Inc., Mark Salter <msalter@redhat.com>
> > >   */
> > >  #include <linux/efi.h>
> > > +#include <linux/notifier.h>
> > > +#include <linux/pm.h>
> > >  #include <linux/reboot.h>
> > >  
> > >  int efi_reboot_quirk_mode = -1;
> > > @@ -38,19 +40,32 @@ bool __weak efi_poweroff_required(void)
> > >  	return false;
> > >  }
> > >  
> > > -static void efi_power_off(void)
> > > +static int efi_power_off(struct notifier_block *this,
> > > +			 unsigned long unused1, void *unused2)
> > >  {
> > >  	efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL);
> > > +
> > > +	return NOTIFY_DONE;
> > >  }
> > >  
> > > +static struct notifier_block efi_poweroff_nb = {
> > > +	.notifier_call = efi_power_off,
> > > +	.priority = 64,
> > > +};
> > > +
> > >  static int __init efi_shutdown_init(void)
> > >  {
> > > +	int ret = 0;
> > > +
> > >  	if (!efi_enabled(EFI_RUNTIME_SERVICES))
> > >  		return -ENODEV;
> > >  
> > > -	if (efi_poweroff_required())
> > > -		pm_power_off = efi_power_off;
> > > +	if (efi_poweroff_required()) {
> > > +		ret = register_poweroff_handler(&efi_poweroff_nb);
> > > +		if (ret)
> > > +			pr_err("efi: Failed to register poweroff handler\n");
> > > +	}
> > >  
> > > -	return 0;
> > > +	return ret;
> > >  }
> > >  late_initcall(efi_shutdown_init);
> > > -- 
> > > 1.9.1
> > 
> > 
> 
> 

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

* [PATCH 42/44] efi: Register poweroff handler with kernel poweroff handler
  2014-10-16 17:27       ` Guenter Roeck
@ 2014-10-16 17:46         ` Matt Fleming
  2014-10-16 18:27           ` Guenter Roeck
  0 siblings, 1 reply; 91+ messages in thread
From: Matt Fleming @ 2014-10-16 17:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 16 Oct, at 10:27:22AM, Guenter Roeck wrote:
> Great, thanks a lot for the feedback.
> 
> Matt, is it ok for me to add your Acked-by: ?

Sorry, yes.

Acked-by: Matt Fleming <matt.fleming@intel.com>

-- 
Matt Fleming, Intel Open Source Technology Center

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

* [PATCH 42/44] efi: Register poweroff handler with kernel poweroff handler
  2014-10-16 17:46         ` Matt Fleming
@ 2014-10-16 18:27           ` Guenter Roeck
  0 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-10-16 18:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 16, 2014 at 06:46:19PM +0100, Matt Fleming wrote:
> On Thu, 16 Oct, at 10:27:22AM, Guenter Roeck wrote:
> > Great, thanks a lot for the feedback.
> > 
> > Matt, is it ok for me to add your Acked-by: ?
> 
> Sorry, yes.
> 
> Acked-by: Matt Fleming <matt.fleming@intel.com>
> 
No worries. Thanks a lot!

Guenter

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

* [PATCH 33/44] avr32: atngw100: Register with kernel poweroff handler
  2014-10-07  5:28 ` [PATCH 33/44] avr32: atngw100: " Guenter Roeck
@ 2014-11-01 10:16   ` Hans-Christian Egtvedt
  2014-11-01 17:02     ` Guenter Roeck
  0 siblings, 1 reply; 91+ messages in thread
From: Hans-Christian Egtvedt @ 2014-11-01 10:16 UTC (permalink / raw)
  To: linux-arm-kernel

Around Mon 06 Oct 2014 22:28:35 -0700 or thereabout, Guenter Roeck wrote:
> Register with kernel poweroff handler instead of setting pm_power_off
> directly.
> 
> Cc: Haavard Skinnemoen <hskinnemoen@gmail.com>
> Cc: Hans-Christian Egtvedt <egtvedt@samfundet.no>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>

Acked-by: Hans-Christian Egtvedt <egtvedt@samfundet.no>

> ---
>  arch/avr32/boards/atngw100/mrmt.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/avr32/boards/atngw100/mrmt.c b/arch/avr32/boards/atngw100/mrmt.c
> index 91146b4..54d0c27 100644
> --- a/arch/avr32/boards/atngw100/mrmt.c
> +++ b/arch/avr32/boards/atngw100/mrmt.c
> @@ -274,7 +274,7 @@ static int __init mrmt1_init(void)
>  {
>  	gpio_set_value( PIN_PWR_ON, 1 );	/* Ensure PWR_ON is enabled */
>  
> -	pm_power_off = mrmt_power_off;
> +	register_poweroff_handler_simple(mrmt_power_off, 128);
>  
>  	/* Setup USARTS (other than console) */
>  	at32_map_usart(2, 1, 0);	/* USART 2: /dev/ttyS1, RMT1:DB9M */
-- 
mvh
Hans-Christian Egtvedt

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

* [PATCH 33/44] avr32: atngw100: Register with kernel poweroff handler
  2014-11-01 10:16   ` Hans-Christian Egtvedt
@ 2014-11-01 17:02     ` Guenter Roeck
  0 siblings, 0 replies; 91+ messages in thread
From: Guenter Roeck @ 2014-11-01 17:02 UTC (permalink / raw)
  To: linux-arm-kernel

On 11/01/2014 03:16 AM, Hans-Christian Egtvedt wrote:
> Around Mon 06 Oct 2014 22:28:35 -0700 or thereabout, Guenter Roeck wrote:
>> Register with kernel poweroff handler instead of setting pm_power_off
>> directly.
>>
>> Cc: Haavard Skinnemoen <hskinnemoen@gmail.com>
>> Cc: Hans-Christian Egtvedt <egtvedt@samfundet.no>
>> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
>
> Acked-by: Hans-Christian Egtvedt <egtvedt@samfundet.no>
>

Thanks!

Guenter

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

* [PATCH 01/44] kernel: Add support for poweroff handler call chain
  2014-10-07  5:28 ` [PATCH 01/44] kernel: Add support for poweroff handler call chain Guenter Roeck
                     ` (2 preceding siblings ...)
  2014-10-09 11:31   ` Geert Uytterhoeven
@ 2015-06-18  1:04   ` Stephen Boyd
  2015-06-18  6:53     ` Frans Klaver
  2015-06-18 15:30     ` Guenter Roeck
  3 siblings, 2 replies; 91+ messages in thread
From: Stephen Boyd @ 2015-06-18  1:04 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/06/2014 10:28 PM, 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 scheme
> to remove power is supported (at least if pm_power_off is used).
> At least in theory there can be multiple means remove power, some of
> which may be less desirable. For example, some mechanisms may only
> power off the CPU or the CPU card, while another may power off the
> entire system.  Others may really just execute a restart sequence
> or drop into the ROM monitor. 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 poweroff 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 poweroff 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 poweroff functionality are expected to register with this call chain.
> By using the priority field in the notifier block, callers can control
> poweroff handler execution sequence and thus ensure that the poweroff
> handler with the optimal capabilities to remove power for a given system
> is called first.

What happened to this series? I want to add shutdown support to my
platform and I need to write a register on the PMIC in one driver to
configure it for shutdown instead of restart and then write an MMIO
register to tell the PMIC to actually do the shutdown in another driver.
It seems that the notifier solves this case for me, albeit with the
slight complication that I need to order the two with some priority.

I'm also considering putting the PMIC configuration part into the reboot
notifier chain, because it only does things to change the configuration
and not actually any shutdown/restart itself. That removes any
requirement to get the priority of notifiers right. This series will
still be useful for the MMIO register that needs to be toggled though.
Right now I have to assign pm_power_off or hook the reboot notifier with
a different priority to make this work.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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

* [PATCH 01/44] kernel: Add support for poweroff handler call chain
  2015-06-18  1:04   ` Stephen Boyd
@ 2015-06-18  6:53     ` Frans Klaver
  2015-06-18 11:54       ` Guenter Roeck
  2015-06-18 15:30     ` Guenter Roeck
  1 sibling, 1 reply; 91+ messages in thread
From: Frans Klaver @ 2015-06-18  6:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jun 18, 2015 at 3:04 AM, Stephen Boyd <sboyd@codeaurora.org> wrote:
> On 10/06/2014 10:28 PM, 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 scheme
>> to remove power is supported (at least if pm_power_off is used).
>> At least in theory there can be multiple means remove power, some of
>> which may be less desirable. For example, some mechanisms may only
>> power off the CPU or the CPU card, while another may power off the
>> entire system.  Others may really just execute a restart sequence
>> or drop into the ROM monitor. 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 poweroff 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 poweroff 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 poweroff functionality are expected to register with this call chain.
>> By using the priority field in the notifier block, callers can control
>> poweroff handler execution sequence and thus ensure that the poweroff
>> handler with the optimal capabilities to remove power for a given system
>> is called first.
>
> What happened to this series? I want to add shutdown support to my
> platform and I need to write a register on the PMIC in one driver to
> configure it for shutdown instead of restart and then write an MMIO
> register to tell the PMIC to actually do the shutdown in another driver.
> It seems that the notifier solves this case for me, albeit with the
> slight complication that I need to order the two with some priority.

I was wondering the same thing. I did find out that things kind of
stalled after Linus cast doubt on the chosen path [1]. I'm not sure
there's any consensus on what would be best to do instead.

Frans

[1] https://lkml.org/lkml/2014/11/6/641

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

* [PATCH 01/44] kernel: Add support for poweroff handler call chain
  2015-06-18  6:53     ` Frans Klaver
@ 2015-06-18 11:54       ` Guenter Roeck
  2015-06-18 12:14         ` Frans Klaver
  0 siblings, 1 reply; 91+ messages in thread
From: Guenter Roeck @ 2015-06-18 11:54 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/17/2015 11:53 PM, Frans Klaver wrote:
> On Thu, Jun 18, 2015 at 3:04 AM, Stephen Boyd <sboyd@codeaurora.org> wrote:
>> On 10/06/2014 10:28 PM, 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 scheme
>>> to remove power is supported (at least if pm_power_off is used).
>>> At least in theory there can be multiple means remove power, some of
>>> which may be less desirable. For example, some mechanisms may only
>>> power off the CPU or the CPU card, while another may power off the
>>> entire system.  Others may really just execute a restart sequence
>>> or drop into the ROM monitor. 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 poweroff 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 poweroff 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 poweroff functionality are expected to register with this call chain.
>>> By using the priority field in the notifier block, callers can control
>>> poweroff handler execution sequence and thus ensure that the poweroff
>>> handler with the optimal capabilities to remove power for a given system
>>> is called first.
>>
>> What happened to this series? I want to add shutdown support to my
>> platform and I need to write a register on the PMIC in one driver to
>> configure it for shutdown instead of restart and then write an MMIO
>> register to tell the PMIC to actually do the shutdown in another driver.
>> It seems that the notifier solves this case for me, albeit with the
>> slight complication that I need to order the two with some priority.
>
> I was wondering the same thing. I did find out that things kind of
> stalled after Linus cast doubt on the chosen path [1]. I'm not sure
> there's any consensus on what would be best to do instead.
>

Linus cast doubt on it, then the maintainers started picking it apart.
At the end, trying not to use notifier callbacks made the code so
complicated that even I didn't understand it anymore. With no consensus
in sight, I abandoned it.

Problem is really that the notifier call chain would be perfect to solve
the problem, yet Linus didn't like priorities (which are essential),
and the power maintainers didn't like that a call chain is supposed
to execute _all_ callbacks, which would not be the case here. If I were
to start again, I would insist to use notifiers. However, I don't see
a chance to get that accepted, so I won't. Feel free to pick it up and
give it a try yourself.

Thanks,
Guenter

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

* [PATCH 01/44] kernel: Add support for poweroff handler call chain
  2015-06-18 11:54       ` Guenter Roeck
@ 2015-06-18 12:14         ` Frans Klaver
  0 siblings, 0 replies; 91+ messages in thread
From: Frans Klaver @ 2015-06-18 12:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jun 18, 2015 at 1:54 PM, Guenter Roeck <linux@roeck-us.net> wrote:
> On 06/17/2015 11:53 PM, Frans Klaver wrote:
>>
>> On Thu, Jun 18, 2015 at 3:04 AM, Stephen Boyd <sboyd@codeaurora.org>
>> wrote:
>>>
>>> On 10/06/2014 10:28 PM, 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 scheme
>>>> to remove power is supported (at least if pm_power_off is used).
>>>> At least in theory there can be multiple means remove power, some of
>>>> which may be less desirable. For example, some mechanisms may only
>>>> power off the CPU or the CPU card, while another may power off the
>>>> entire system.  Others may really just execute a restart sequence
>>>> or drop into the ROM monitor. 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 poweroff 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 poweroff 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 poweroff functionality are expected to register with this call
>>>> chain.
>>>> By using the priority field in the notifier block, callers can control
>>>> poweroff handler execution sequence and thus ensure that the poweroff
>>>> handler with the optimal capabilities to remove power for a given system
>>>> is called first.
>>>
>>>
>>> What happened to this series? I want to add shutdown support to my
>>> platform and I need to write a register on the PMIC in one driver to
>>> configure it for shutdown instead of restart and then write an MMIO
>>> register to tell the PMIC to actually do the shutdown in another driver.
>>> It seems that the notifier solves this case for me, albeit with the
>>> slight complication that I need to order the two with some priority.
>>
>>
>> I was wondering the same thing. I did find out that things kind of
>> stalled after Linus cast doubt on the chosen path [1]. I'm not sure
>> there's any consensus on what would be best to do instead.
>>
>
> Linus cast doubt on it, then the maintainers started picking it apart.
> At the end, trying not to use notifier callbacks made the code so
> complicated that even I didn't understand it anymore. With no consensus
> in sight, I abandoned it.
>
> Problem is really that the notifier call chain would be perfect to solve
> the problem, yet Linus didn't like priorities (which are essential),
> and the power maintainers didn't like that a call chain is supposed
> to execute _all_ callbacks, which would not be the case here. If I were
> to start again, I would insist to use notifiers. However, I don't see
> a chance to get that accepted, so I won't. Feel free to pick it up and
> give it a try yourself.

How about having two phases? One where all interested parts of the
system get notified, one that does the final shutdown. It's a slightly
different approach than you took, but does use the notifier chains as
expected, and can be used to prepare peripherals for shutdown, if
there's a use case for it.

The two-stage approach does keep the single place to power down. I
expect it would become more obvious that it would be silly to have
more than one actual system power down sequence and hiding
pm_power_off and unifying setting of it should become more straight
forward as well.

Thoughts?

Thanks,
Frans

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

* [PATCH 01/44] kernel: Add support for poweroff handler call chain
  2015-06-18  1:04   ` Stephen Boyd
  2015-06-18  6:53     ` Frans Klaver
@ 2015-06-18 15:30     ` Guenter Roeck
  2015-06-18 21:40       ` Stephen Boyd
  1 sibling, 1 reply; 91+ messages in thread
From: Guenter Roeck @ 2015-06-18 15:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jun 17, 2015 at 06:04:54PM -0700, Stephen Boyd wrote:
[ ... ]
> 
> What happened to this series? I want to add shutdown support to my
> platform and I need to write a register on the PMIC in one driver to
> configure it for shutdown instead of restart and then write an MMIO
> register to tell the PMIC to actually do the shutdown in another driver.
> It seems that the notifier solves this case for me, albeit with the
> slight complication that I need to order the two with some priority.
> 
Can you use the .shutdown driver callback instead ?

I see other drivers use that, and check for system_state == SYSTEM_POWER_OFF
to power off the hardware.

Guenter

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

* [PATCH 01/44] kernel: Add support for poweroff handler call chain
  2015-06-18 15:30     ` Guenter Roeck
@ 2015-06-18 21:40       ` Stephen Boyd
  0 siblings, 0 replies; 91+ messages in thread
From: Stephen Boyd @ 2015-06-18 21:40 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/18/2015 08:30 AM, Guenter Roeck wrote:
> On Wed, Jun 17, 2015 at 06:04:54PM -0700, Stephen Boyd wrote:
> [ ... ]
>> What happened to this series? I want to add shutdown support to my
>> platform and I need to write a register on the PMIC in one driver to
>> configure it for shutdown instead of restart and then write an MMIO
>> register to tell the PMIC to actually do the shutdown in another driver.
>> It seems that the notifier solves this case for me, albeit with the
>> slight complication that I need to order the two with some priority.
>>
> Can you use the .shutdown driver callback instead ?
>
> I see other drivers use that, and check for system_state == SYSTEM_POWER_OFF
> to power off the hardware.
>

Yes I think that will work. I'll still have to hook pm_power_off() for
the mmio register, but I guess that's ok and I don't need to worry about
this series then.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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

end of thread, other threads:[~2015-06-18 21:40 UTC | newest]

Thread overview: 91+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <1412659726-29957-1-git-send-email-linux@roeck-us.net>
2014-10-07  5:28 ` [PATCH 01/44] kernel: Add support for poweroff handler call chain Guenter Roeck
2014-10-07  7:46   ` Philippe Rétornaz
2014-10-09 10:31   ` Pavel Machek
2014-10-09 15:38     ` Guenter Roeck
2014-10-09 11:31   ` Geert Uytterhoeven
2014-10-09 13:25     ` Guenter Roeck
2015-06-18  1:04   ` Stephen Boyd
2015-06-18  6:53     ` Frans Klaver
2015-06-18 11:54       ` Guenter Roeck
2015-06-18 12:14         ` Frans Klaver
2015-06-18 15:30     ` Guenter Roeck
2015-06-18 21:40       ` Stephen Boyd
2014-10-07  5:28 ` [PATCH 02/44] memory: emif: Use API function to determine poweroff capability Guenter Roeck
2014-10-07  5:28 ` [PATCH 03/44] hibernate: Call have_kernel_poweroff instead of checking pm_power_off Guenter Roeck
2014-10-07 23:41   ` Rafael J. Wysocki
2014-10-09 10:32   ` Pavel Machek
2014-10-09 13:24     ` Guenter Roeck
2014-10-07  5:28 ` [PATCH 04/44] m68k: Replace mach_power_off with pm_power_off Guenter Roeck
2014-10-07  8:29   ` Geert Uytterhoeven
2014-10-07  5:28 ` [PATCH 05/44] mfd: as3722: Drop reference to pm_power_off from devicetree bindings Guenter Roeck
2014-10-07 10:59   ` Mark Rutland
2014-10-07 16:21   ` Rob Landley
2014-10-07 16:31     ` Guenter Roeck
2014-10-07 16:59       ` David Daney
2014-10-07 17:10         ` Rob Landley
2014-10-07 16:58     ` Mark Rutland
2014-10-07  5:28 ` [PATCH 06/44] gpio-poweroff: " Guenter Roeck
2014-10-07 11:03   ` Mark Rutland
2014-10-07 15:50   ` Andrew Lunn
2014-10-07  5:28 ` [PATCH 07/44] qnap-poweroff: " Guenter Roeck
2014-10-07 11:02   ` Mark Rutland
2014-10-07 15:57     ` Guenter Roeck
2014-10-07 15:51   ` Andrew Lunn
2014-10-07  5:28 ` [PATCH 09/44] mfd: palmas: Register with kernel poweroff handler Guenter Roeck
2014-10-07  5:28 ` [PATCH 10/44] mfd: axp20x: " Guenter Roeck
2014-10-07  5:28 ` [PATCH 11/44] mfd: retu: " Guenter Roeck
2014-10-07  5:28 ` [PATCH 12/44] mfd: ab8500-sysctrl: " Guenter Roeck
2014-10-07  8:00   ` Lee Jones
2014-10-09 10:36     ` Catalin Marinas
2014-10-09 10:49       ` Lee Jones
2014-10-09 13:26         ` Guenter Roeck
2014-10-09 13:33           ` Lee Jones
2014-10-09 15:45             ` Guenter Roeck
2014-10-09 15:54         ` Guenter Roeck
2014-10-07  5:28 ` [PATCH 13/44] mfd: max8907: " Guenter Roeck
2014-10-07  5:28 ` [PATCH 14/44] mfd: tps80031: " Guenter Roeck
2014-10-07  5:28 ` [PATCH 15/44] mfd: dm355evm_msp: " Guenter Roeck
2014-10-07  5:28 ` [PATCH 16/44] mfd: tps6586x: " Guenter Roeck
2014-10-07  5:28 ` [PATCH 17/44] mfd: tps65910: " Guenter Roeck
2014-10-07  5:28 ` [PATCH 18/44] mfd: twl4030-power: " Guenter Roeck
2014-10-07  7:52   ` Lee Jones
2014-10-07  5:28 ` [PATCH 19/44] ipmi: " Guenter Roeck
2014-10-07  5:28 ` [PATCH 20/44] power/reset: restart-poweroff: " Guenter Roeck
2014-10-07 16:06   ` Andrew Lunn
2014-10-07  5:28 ` [PATCH 21/44] power/reset: gpio-poweroff: " Guenter Roeck
2014-10-07 16:00   ` Andrew Lunn
2014-10-07  5:28 ` [PATCH 22/44] power/reset: as3722-poweroff: " Guenter Roeck
2014-10-07  5:28 ` [PATCH 23/44] power/reset: qnap-poweroff: " Guenter Roeck
2014-10-07 16:02   ` Andrew Lunn
2014-10-07  5:28 ` [PATCH 24/44] power/reset: msm-powroff: " Guenter Roeck
2014-10-07  5:28 ` [PATCH 25/44] power/reset: vexpress-poweroff: " Guenter Roeck
2014-10-07  5:28 ` [PATCH 26/44] x86: iris: " Guenter Roeck
2014-10-07  5:28 ` [PATCH 27/44] x86: apm: " Guenter Roeck
2014-10-07  5:28 ` [PATCH 28/44] x86: olpc: Register xo1 poweroff handler " Guenter Roeck
2014-10-07  5:28 ` [PATCH 29/44] staging: nvec: Register " Guenter Roeck
2014-10-07 16:23   ` Greg Kroah-Hartman
2014-10-08 18:51   ` Marc Dietrich
2014-10-07  5:28 ` [PATCH 30/44] acpi: Register poweroff handler " Guenter Roeck
2014-10-07  5:28 ` [PATCH 32/44] arm64: psci: Register " Guenter Roeck
2014-10-09 10:41   ` Catalin Marinas
2014-10-07  5:28 ` [PATCH 33/44] avr32: atngw100: " Guenter Roeck
2014-11-01 10:16   ` Hans-Christian Egtvedt
2014-11-01 17:02     ` Guenter Roeck
2014-10-07  5:28 ` [PATCH 34/44] ia64: " Guenter Roeck
2014-10-07  5:28 ` [PATCH 35/44] m68k: " Guenter Roeck
2014-10-07  9:19   ` Geert Uytterhoeven
2014-10-07  5:28 ` [PATCH 36/44] mips: " Guenter Roeck
2014-10-07  5:28 ` [PATCH 37/44] sh: " Guenter Roeck
2014-10-07  5:28 ` [PATCH 38/44] x86: lguest: " Guenter Roeck
2014-10-07  5:28 ` [PATCH 39/44] x86: ce4100: " Guenter Roeck
2014-10-07  5:28 ` [PATCH 40/44] x86: intel-mid: Drop registration of dummy poweroff handlers Guenter Roeck
2014-10-07  5:28 ` [PATCH 41/44] x86: pmc_atom: Register poweroff handler with kernel poweroff handler Guenter Roeck
2014-10-07  5:28 ` [PATCH 42/44] efi: " Guenter Roeck
2014-10-16 14:59   ` Matt Fleming
2014-10-16 15:24     ` Mark Salter
2014-10-16 17:27       ` Guenter Roeck
2014-10-16 17:46         ` Matt Fleming
2014-10-16 18:27           ` Guenter Roeck
2014-10-07  5:28 ` [PATCH 43/44] hwmon: (ab8500) Call kernel_power_off instead of pm_power_off Guenter Roeck
2014-10-07  5:28 ` [PATCH 44/44] kernel: Remove pm_power_off Guenter Roeck
2014-10-07 23:43   ` Rafael J. Wysocki

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).