* [PATCH 01/11] machine-reset: platform generic handling
2013-10-31 6:27 [PATCH 00/11] RFC: Common machine reset handling Domenico Andreoli
@ 2013-10-31 6:27 ` Domenico Andreoli
2013-10-31 6:27 ` [PATCH 02/11] ARM: use the common machine reset handling Domenico Andreoli
` (11 subsequent siblings)
12 siblings, 0 replies; 21+ messages in thread
From: Domenico Andreoli @ 2013-10-31 6:27 UTC (permalink / raw)
To: linux-arch
Cc: linux-arm-kernel, linux-mips, Russell King, Arnd Bergmann,
Olof Johansson, Ralf Baechle, Catalin Marinas, Will Deacon,
Domenico Andreoli
[-- Attachment #1: machine-reset-handling.patch --]
[-- Type: text/plain, Size: 8834 bytes --]
From: Domenico Andreoli <domenico.andreoli@linux.com>
Code is not commented but it's really simple. The bulk is in
set_machine_reset(), the static data is hidden in get_descr(). The rest
is just a straightforward consequence with the intent to keep it simple.
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Olof Johansson <olof@lixom.net>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-arch@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-mips@lvger.kernel.org
Signed-off-by: Domenico Andreoli <domenico.andreoli@linux.com>
---
include/linux/machine_reset.h | 79 +++++++++++++++++++++++++
kernel/Makefile | 1 +
kernel/machine_reset.c | 131 ++++++++++++++++++++++++++++++++++++++++++
kernel/power/Kconfig | 4 +
kernel/reboot.c | 3 +
5 files changed, 218 insertions(+)
Index: b/include/linux/machine_reset.h
===================================================================
--- /dev/null
+++ b/include/linux/machine_reset.h
@@ -0,0 +1,79 @@
+/*
+ * Machine reset hooks management
+ *
+ * Copyright (C) 2013 Domenico Andreoli <domenico.andreoli@linux.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/reboot.h>
+
+enum reset_func {
+ RESET_RESTART = 0,
+ RESET_HALT,
+ RESET_POWER_OFF_PREPARE,
+ RESET_POWER_OFF,
+ RESET_CRASH_POWER_OFF,
+ RESET_NR_FUNCS,
+};
+
+struct reset_hook {
+ union {
+ void (*restart)(void *dev, enum reboot_mode, const char *cmd);
+ void (*halt)(void *dev);
+ void (*power_off_prepare)(void *dev);
+ void (*power_off)(void *dev);
+ void (*crash_power_off)(void *dev);
+ void (*handler)(void *dev);
+ };
+ void (*release)(void *dev);
+};
+
+static inline
+void reset_hook_init(struct reset_hook *hook)
+{
+ hook->handler = NULL;
+ hook->release = NULL;
+}
+
+#ifdef CONFIG_MACHINE_RESET
+
+void set_machine_reset(enum reset_func, const struct reset_hook *, void *dev);
+void unset_machine_reset(enum reset_func, const struct reset_hook *);
+int isset_machine_reset(enum reset_func, void *dev);
+
+void default_restart(enum reboot_mode, const char *cmd);
+void default_halt(void);
+void default_power_off_prepare(void);
+void default_power_off(void);
+void default_crash_power_off(void);
+
+#else /* CONFIG_MACHINE_RESET */
+
+static inline
+void set_machine_reset(enum reset_func func,
+ const struct reset_hook *hook, void *dev)
+{
+ if (hook->release)
+ hook->release(dev);
+}
+
+static inline void unset_machine_reset(enum reset_func _f,
+ const struct reset_hook *_h) {}
+static inline int isset_machine_reset(enum reset_func _f, void *_d) { return 0; }
+
+static inline void default_restart(enum reboot_mode _m, const char *_c) {}
+static inline void default_halt(void) {}
+static inline void default_power_off_prepare(void) {}
+static inline void default_power_off(void) {}
+static inline void default_crash_power_off(void) {}
+
+#endif /* CONFIG_MACHINE_RESET */
Index: b/kernel/Makefile
===================================================================
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -111,6 +111,7 @@ obj-$(CONFIG_PADATA) += padata.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_JUMP_LABEL) += jump_label.o
obj-$(CONFIG_CONTEXT_TRACKING) += context_tracking.o
+obj-$(CONFIG_MACHINE_RESET) += machine_reset.o
$(obj)/configs.o: $(obj)/config_data.h
Index: b/kernel/machine_reset.c
===================================================================
--- /dev/null
+++ b/kernel/machine_reset.c
@@ -0,0 +1,131 @@
+/*
+ * Machine reset hooks management
+ *
+ * Copyright (C) 2013 Domenico Andreoli <domenico.andreoli@linux.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/export.h>
+#include <linux/spinlock.h>
+#include <linux/reboot.h>
+#include <linux/machine_reset.h>
+
+struct reset_descr {
+ struct reset_hook hook;
+ void *dev;
+};
+static DEFINE_SPINLOCK(descr_lock);
+
+static struct reset_descr *get_descr(enum reset_func func)
+{
+ static struct reset_descr descr[RESET_NR_FUNCS];
+
+ BUG_ON(func >= RESET_NR_FUNCS);
+ spin_lock(&descr_lock);
+ return &descr[func];
+}
+
+static void put_descr(struct reset_descr *descr)
+{
+ spin_unlock(&descr_lock);
+}
+
+#define RESET_FUNC(_func, _member, _args...) \
+{ \
+ struct reset_descr *descr = get_descr(_func); \
+ typeof(descr->hook._member) member = descr->hook._member; \
+ if (member) { \
+ pr_debug("machine_reset: %s (%pf)\n", #_func, member); \
+ member(descr->dev , ##_args); \
+ } \
+ put_descr(descr); \
+ pr_emerg("machine_reset: %s: FAILED\n", #_func); \
+ while (1); \
+}
+
+void default_restart(enum reboot_mode reboot_mode, const char *cmd)
+{
+ RESET_FUNC(RESET_RESTART, restart, reboot_mode, cmd);
+}
+
+void default_halt(void)
+{
+ RESET_FUNC(RESET_HALT, halt);
+}
+
+void default_power_off_prepare(void)
+{
+ RESET_FUNC(RESET_POWER_OFF_PREPARE, power_off_prepare);
+}
+
+void default_power_off(void)
+{
+ RESET_FUNC(RESET_POWER_OFF, power_off);
+}
+
+void default_crash_power_off(void)
+{
+ RESET_FUNC(RESET_CRASH_POWER_OFF, crash_power_off);
+}
+
+void set_machine_reset(enum reset_func func,
+ const struct reset_hook *hook, void *new_dev)
+{
+ struct reset_descr *descr;
+ void (*new_handler)(void *) = hook ? hook->handler : NULL;
+ void (*new_release)(void *) = hook ? hook->release : NULL;
+ void (*old_release)(void *) = NULL;
+ void *old_dev;
+
+ descr = get_descr(func);
+ old_release = descr->hook.release;
+ old_dev = descr->dev;
+ reset_hook_init(&descr->hook);
+ descr->hook.handler = new_handler;
+ descr->hook.release = new_release;
+ descr->dev = new_dev;
+ put_descr(descr);
+
+ if (old_release)
+ old_release(old_dev);
+}
+EXPORT_SYMBOL_GPL(set_machine_reset);
+
+void unset_machine_reset(enum reset_func func, const struct reset_hook *hook)
+{
+ struct reset_descr *descr;
+ void (*old_release)(void *) = NULL;
+ void *old_dev;
+
+ BUG_ON(!hook || !hook->handler);
+
+ descr = get_descr(func);
+ if (descr->hook.handler == hook->handler) {
+ old_release = descr->hook.release;
+ old_dev = descr->dev;
+ reset_hook_init(&descr->hook);
+ }
+ put_descr(descr);
+
+ if (old_release)
+ old_release(old_dev);
+}
+EXPORT_SYMBOL_GPL(unset_machine_reset);
+
+int isset_machine_reset(enum reset_func func, void *dev)
+{
+ struct reset_descr *descr = get_descr(func);
+ int ret = descr->hook.handler && (!dev || descr->dev == dev);
+ put_descr(descr);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(isset_machine_reset);
Index: b/kernel/power/Kconfig
===================================================================
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -293,3 +293,7 @@ config PM_GENERIC_DOMAINS_RUNTIME
config CPU_PM
bool
depends on SUSPEND || CPU_IDLE
+
+config MACHINE_RESET
+ bool
+ default n
Index: b/kernel/reboot.c
===================================================================
--- a/kernel/reboot.c
+++ b/kernel/reboot.c
@@ -12,6 +12,7 @@
#include <linux/kmod.h>
#include <linux/kmsg_dump.h>
#include <linux/reboot.h>
+#include <linux/machine_reset.h>
#include <linux/suspend.h>
#include <linux/syscalls.h>
#include <linux/syscore_ops.h>
@@ -178,6 +179,8 @@ void kernel_power_off(void)
kernel_shutdown_prepare(SYSTEM_POWER_OFF);
if (pm_power_off_prepare)
pm_power_off_prepare();
+ else
+ default_power_off_prepare();
migrate_to_reboot_cpu();
syscore_shutdown();
pr_emerg("Power down\n");
^ permalink raw reply [flat|nested] 21+ messages in thread* [PATCH 02/11] ARM: use the common machine reset handling
2013-10-31 6:27 [PATCH 00/11] RFC: Common machine reset handling Domenico Andreoli
2013-10-31 6:27 ` [PATCH 01/11] machine-reset: platform generic handling Domenico Andreoli
@ 2013-10-31 6:27 ` Domenico Andreoli
2013-10-31 6:27 ` [PATCH 03/11] ARM64: " Domenico Andreoli
` (10 subsequent siblings)
12 siblings, 0 replies; 21+ messages in thread
From: Domenico Andreoli @ 2013-10-31 6:27 UTC (permalink / raw)
To: linux-arch
Cc: linux-arm-kernel, linux-mips, Russell King, Arnd Bergmann,
Olof Johansson, Ralf Baechle, Will Deacon, Domenico Andreoli
[-- Attachment #1: arm-machine-reset.patch --]
[-- Type: text/plain, Size: 2072 bytes --]
From: Domenico Andreoli <domenico.andreoli@linux.com>
Proof of concept: ARM as a consumer of the machine reset hooks.
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Olof Johansson <olof@lixom.net>
Cc: Will Deacon <will.deacon@arm.com>
Cc: linux-arch@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Signed-off-by: Domenico Andreoli <domenico.andreoli@linux.com>
---
arch/arm/kernel/process.c | 14 ++++++++------
kernel/power/Kconfig | 1 +
2 files changed, 9 insertions(+), 6 deletions(-)
Index: b/arch/arm/kernel/process.c
===================================================================
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -33,6 +33,7 @@
#include <linux/cpuidle.h>
#include <linux/leds.h>
#include <linux/reboot.h>
+#include <linux/machine_reset.h>
#include <asm/cacheflush.h>
#include <asm/idmap.h>
@@ -114,17 +115,13 @@ void soft_restart(unsigned long addr)
BUG();
}
-static void null_restart(enum reboot_mode reboot_mode, const char *cmd)
-{
-}
-
/*
* Function pointers to optional machine specific functions
*/
void (*pm_power_off)(void);
EXPORT_SYMBOL(pm_power_off);
-void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd) = null_restart;
+void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
EXPORT_SYMBOL_GPL(arm_pm_restart);
/*
@@ -217,6 +214,8 @@ void machine_power_off(void)
if (pm_power_off)
pm_power_off();
+ else
+ default_power_off();
}
/*
@@ -235,7 +234,10 @@ void machine_restart(char *cmd)
local_irq_disable();
smp_send_stop();
- arm_pm_restart(reboot_mode, cmd);
+ if (arm_pm_restart)
+ arm_pm_restart(reboot_mode, cmd);
+ else
+ default_restart(reboot_mode, cmd);
/* Give a grace period for failure to restart of 1s */
mdelay(1000);
Index: b/kernel/power/Kconfig
===================================================================
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -297,3 +297,4 @@ config CPU_PM
config MACHINE_RESET
bool
default n
+ depends on ARM
^ permalink raw reply [flat|nested] 21+ messages in thread* [PATCH 03/11] ARM64: use the common machine reset handling
2013-10-31 6:27 [PATCH 00/11] RFC: Common machine reset handling Domenico Andreoli
2013-10-31 6:27 ` [PATCH 01/11] machine-reset: platform generic handling Domenico Andreoli
2013-10-31 6:27 ` [PATCH 02/11] ARM: use the common machine reset handling Domenico Andreoli
@ 2013-10-31 6:27 ` Domenico Andreoli
2013-10-31 6:27 ` [PATCH 04/11] MIPS: " Domenico Andreoli
` (9 subsequent siblings)
12 siblings, 0 replies; 21+ messages in thread
From: Domenico Andreoli @ 2013-10-31 6:27 UTC (permalink / raw)
To: linux-arch
Cc: linux-arm-kernel, linux-mips, Russell King, Arnd Bergmann,
Olof Johansson, Ralf Baechle, Catalin Marinas, Will Deacon,
Domenico Andreoli
[-- Attachment #1: arm64-machine-reset.patch --]
[-- Type: text/plain, Size: 1584 bytes --]
From: Domenico Andreoli <domenico.andreoli@linux.com>
Proof of concept: ARM64 as a consumer of the machine reset hooks.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: linux-arch@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Signed-off-by: Domenico Andreoli <domenico.andreoli@linux.com>
---
arch/arm64/kernel/process.c | 5 +++++
kernel/power/Kconfig | 2 +-
2 files changed, 6 insertions(+), 1 deletion(-)
Index: b/kernel/power/Kconfig
===================================================================
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -297,4 +297,4 @@ config CPU_PM
config MACHINE_RESET
bool
default n
- depends on ARM
+ depends on ARM || ARM64
Index: b/arch/arm64/kernel/process.c
===================================================================
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -29,6 +29,7 @@
#include <linux/user.h>
#include <linux/delay.h>
#include <linux/reboot.h>
+#include <linux/machine_reset.h>
#include <linux/interrupt.h>
#include <linux/kallsyms.h>
#include <linux/init.h>
@@ -120,6 +121,8 @@ void machine_power_off(void)
machine_shutdown();
if (pm_power_off)
pm_power_off();
+ else
+ default_power_off();
}
void machine_restart(char *cmd)
@@ -133,6 +136,8 @@ void machine_restart(char *cmd)
/* Now call the architecture specific reboot code. */
if (arm_pm_restart)
arm_pm_restart(reboot_mode, cmd);
+ else
+ default_restart(reboot_mode, cmd);
/*
* Whoops - the architecture was unable to reboot.
^ permalink raw reply [flat|nested] 21+ messages in thread* [PATCH 04/11] MIPS: use the common machine reset handling
2013-10-31 6:27 [PATCH 00/11] RFC: Common machine reset handling Domenico Andreoli
` (2 preceding siblings ...)
2013-10-31 6:27 ` [PATCH 03/11] ARM64: " Domenico Andreoli
@ 2013-10-31 6:27 ` Domenico Andreoli
2013-11-01 5:11 ` Vineet Gupta
2013-10-31 6:27 ` [PATCH 05/11] ARM: vexpress: consolidate machine reset func Domenico Andreoli
` (8 subsequent siblings)
12 siblings, 1 reply; 21+ messages in thread
From: Domenico Andreoli @ 2013-10-31 6:27 UTC (permalink / raw)
To: linux-arch
Cc: linux-arm-kernel, linux-mips, Russell King, Arnd Bergmann,
Olof Johansson, Ralf Baechle, Domenico Andreoli
[-- Attachment #1: mips-machine-reset.patch --]
[-- Type: text/plain, Size: 1397 bytes --]
From: Domenico Andreoli <domenico.andreoli@linux.com>
Proof of concept: MIPS as a consumer of the machine reset hooks.
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-arch@vger.kernel.org
Cc: linux-mips@vger.kernel.org
Signed-off-by: Domenico Andreoli <domenico.andreoli@linux.com>
---
arch/mips/kernel/reset.c | 7 +++++++
kernel/power/Kconfig | 2 +-
2 files changed, 8 insertions(+), 1 deletion(-)
Index: b/arch/mips/kernel/reset.c
===================================================================
--- a/arch/mips/kernel/reset.c
+++ b/arch/mips/kernel/reset.c
@@ -11,6 +11,7 @@
#include <linux/pm.h>
#include <linux/types.h>
#include <linux/reboot.h>
+#include <linux/machine_reset.h>
#include <asm/reboot.h>
@@ -29,16 +30,22 @@ void machine_restart(char *command)
{
if (_machine_restart)
_machine_restart(command);
+ else
+ default_restart(reboot_mode, command);
}
void machine_halt(void)
{
if (_machine_halt)
_machine_halt();
+ else
+ default_halt();
}
void machine_power_off(void)
{
if (pm_power_off)
pm_power_off();
+ else
+ default_power_off();
}
Index: b/kernel/power/Kconfig
===================================================================
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -297,4 +297,4 @@ config CPU_PM
config MACHINE_RESET
bool
default n
- depends on ARM || ARM64
+ depends on ARM || ARM64 || MIPS
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH 04/11] MIPS: use the common machine reset handling
2013-10-31 6:27 ` [PATCH 04/11] MIPS: " Domenico Andreoli
@ 2013-11-01 5:11 ` Vineet Gupta
2013-11-01 5:26 ` Domenico Andreoli
0 siblings, 1 reply; 21+ messages in thread
From: Vineet Gupta @ 2013-11-01 5:11 UTC (permalink / raw)
To: Domenico Andreoli, linux-arch
Cc: linux-arm-kernel, linux-mips, Russell King, Arnd Bergmann,
Olof Johansson, Ralf Baechle
On 10/31/2013 11:57 AM, Domenico Andreoli wrote:
> From: Domenico Andreoli <domenico.andreoli@linux.com>
>
> Proof of concept: MIPS as a consumer of the machine reset hooks.
>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: linux-arch@vger.kernel.org
> Cc: linux-mips@vger.kernel.org
> Signed-off-by: Domenico Andreoli <domenico.andreoli@linux.com>
> ---
> arch/mips/kernel/reset.c | 7 +++++++
> kernel/power/Kconfig | 2 +-
> 2 files changed, 8 insertions(+), 1 deletion(-)
>
> Index: b/arch/mips/kernel/reset.c
> ===================================================================
> --- a/arch/mips/kernel/reset.c
> +++ b/arch/mips/kernel/reset.c
> @@ -11,6 +11,7 @@
> #include <linux/pm.h>
> #include <linux/types.h>
> #include <linux/reboot.h>
> +#include <linux/machine_reset.h>
>
> #include <asm/reboot.h>
>
> @@ -29,16 +30,22 @@ void machine_restart(char *command)
> {
> if (_machine_restart)
> _machine_restart(command);
> + else
> + default_restart(reboot_mode, command);
> }
>
> void machine_halt(void)
> {
> if (_machine_halt)
> _machine_halt();
> + else
> + default_halt();
> }
>
> void machine_power_off(void)
> {
> if (pm_power_off)
> pm_power_off();
> + else
> + default_power_off();
> }
> Index: b/kernel/power/Kconfig
> ===================================================================
> --- a/kernel/power/Kconfig
> +++ b/kernel/power/Kconfig
> @@ -297,4 +297,4 @@ config CPU_PM
> config MACHINE_RESET
> bool
> default n
> - depends on ARM || ARM64
> + depends on ARM || ARM64 || MIPS
This particular idiom is frowned upon for new code. As new arches get added this
list keeps getting bigger and then those who don't need the feature need to add
the anti dependency. Also in this particular case the dependency is trivial so you
can just "select" it in arch/*/Kconfig
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH 04/11] MIPS: use the common machine reset handling
2013-11-01 5:11 ` Vineet Gupta
@ 2013-11-01 5:26 ` Domenico Andreoli
0 siblings, 0 replies; 21+ messages in thread
From: Domenico Andreoli @ 2013-11-01 5:26 UTC (permalink / raw)
To: Vineet Gupta
Cc: Domenico Andreoli, linux-arch, Russell King, Arnd Bergmann,
Ralf Baechle, linux-mips, Olof Johansson, linux-arm-kernel
On Fri, Nov 01, 2013 at 10:41:54AM +0530, Vineet Gupta wrote:
> On 10/31/2013 11:57 AM, Domenico Andreoli wrote:
> > From: Domenico Andreoli <domenico.andreoli@linux.com>
> >
> > Proof of concept: MIPS as a consumer of the machine reset hooks.
> >
> > Cc: Ralf Baechle <ralf@linux-mips.org>
> > Cc: linux-arch@vger.kernel.org
> > Cc: linux-mips@vger.kernel.org
> > Signed-off-by: Domenico Andreoli <domenico.andreoli@linux.com>
> > ---
> > arch/mips/kernel/reset.c | 7 +++++++
> > kernel/power/Kconfig | 2 +-
> > 2 files changed, 8 insertions(+), 1 deletion(-)
> >
> > Index: b/arch/mips/kernel/reset.c
> > ===================================================================
> > --- a/arch/mips/kernel/reset.c
> > +++ b/arch/mips/kernel/reset.c
> > @@ -11,6 +11,7 @@
> > #include <linux/pm.h>
> > #include <linux/types.h>
> > #include <linux/reboot.h>
> > +#include <linux/machine_reset.h>
> >
> > #include <asm/reboot.h>
> >
> > @@ -29,16 +30,22 @@ void machine_restart(char *command)
> > {
> > if (_machine_restart)
> > _machine_restart(command);
> > + else
> > + default_restart(reboot_mode, command);
> > }
> >
> > void machine_halt(void)
> > {
> > if (_machine_halt)
> > _machine_halt();
> > + else
> > + default_halt();
> > }
> >
> > void machine_power_off(void)
> > {
> > if (pm_power_off)
> > pm_power_off();
> > + else
> > + default_power_off();
> > }
> > Index: b/kernel/power/Kconfig
> > ===================================================================
> > --- a/kernel/power/Kconfig
> > +++ b/kernel/power/Kconfig
> > @@ -297,4 +297,4 @@ config CPU_PM
> > config MACHINE_RESET
> > bool
> > default n
> > - depends on ARM || ARM64
> > + depends on ARM || ARM64 || MIPS
>
> This particular idiom is frowned upon for new code. As new arches get added this
> list keeps getting bigger and then those who don't need the feature need to add
> the anti dependency. Also in this particular case the dependency is trivial so you
> can just "select" it in arch/*/Kconfig
this dependency guarantees only that the option is available only on the
supported arches.
anyway I've not a strong opinion, I only picked the least invasive solution
I was able to think.
thanks,
Domenico
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 05/11] ARM: vexpress: consolidate machine reset func
2013-10-31 6:27 [PATCH 00/11] RFC: Common machine reset handling Domenico Andreoli
` (3 preceding siblings ...)
2013-10-31 6:27 ` [PATCH 04/11] MIPS: " Domenico Andreoli
@ 2013-10-31 6:27 ` Domenico Andreoli
2013-10-31 6:27 ` [PATCH 06/11] ARM: vexpress: use the common machine reset handling Domenico Andreoli
` (7 subsequent siblings)
12 siblings, 0 replies; 21+ messages in thread
From: Domenico Andreoli @ 2013-10-31 6:27 UTC (permalink / raw)
To: linux-arch
Cc: linux-arm-kernel, linux-mips, Russell King, Arnd Bergmann,
Olof Johansson, Ralf Baechle, Domenico Andreoli
[-- Attachment #1: arm-machine-reset-vexpress-enum.patch --]
[-- Type: text/plain, Size: 2877 bytes --]
From: Domenico Andreoli <domenico.andreoli@linux.com>
Proof of concept: vexpress as provider of reset hooks.
Enum consolidation.
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Olof Johansson <olof@lixom.net>
Cc: linux-arm-kernel@lists.infradead.org
Signed-off-by: Domenico Andreoli <domenico.andreoli@linux.com>
---
drivers/power/reset/vexpress-poweroff.c | 31 +++++++++++++------------------
1 file changed, 13 insertions(+), 18 deletions(-)
Index: b/drivers/power/reset/vexpress-poweroff.c
===================================================================
--- a/drivers/power/reset/vexpress-poweroff.c
+++ b/drivers/power/reset/vexpress-poweroff.c
@@ -17,6 +17,7 @@
#include <linux/platform_device.h>
#include <linux/stat.h>
#include <linux/vexpress.h>
+#include <linux/machine_reset.h>
#include <asm/system_misc.h>
@@ -75,58 +76,52 @@ DEVICE_ATTR(active, S_IRUGO | S_IWUSR, v
vexpress_reset_active_store);
-enum vexpress_reset_func { FUNC_RESET, FUNC_SHUTDOWN, FUNC_REBOOT };
-
static struct of_device_id vexpress_reset_of_match[] = {
{
.compatible = "arm,vexpress-reset",
- .data = (void *)FUNC_RESET,
+ .data = (void *) RESET_RESTART,
}, {
.compatible = "arm,vexpress-shutdown",
- .data = (void *)FUNC_SHUTDOWN
+ .data = (void *) RESET_POWER_OFF,
}, {
.compatible = "arm,vexpress-reboot",
- .data = (void *)FUNC_REBOOT
+ .data = (void *) RESET_RESTART,
},
{}
};
static int vexpress_reset_probe(struct platform_device *pdev)
{
- enum vexpress_reset_func func;
+ enum reset_func func;
const struct of_device_id *match =
of_match_device(vexpress_reset_of_match, &pdev->dev);
if (match)
- func = (enum vexpress_reset_func)match->data;
+ func = (enum reset_func) match->data;
else
func = pdev->id_entry->driver_data;
switch (func) {
- case FUNC_SHUTDOWN:
+ case RESET_POWER_OFF:
vexpress_power_off_device = &pdev->dev;
pm_power_off = vexpress_power_off;
break;
- case FUNC_RESET:
- if (!vexpress_restart_device)
- vexpress_restart_device = &pdev->dev;
- arm_pm_restart = vexpress_restart;
- device_create_file(&pdev->dev, &dev_attr_active);
- break;
- case FUNC_REBOOT:
+ case RESET_RESTART:
vexpress_restart_device = &pdev->dev;
arm_pm_restart = vexpress_restart;
device_create_file(&pdev->dev, &dev_attr_active);
break;
+ default:
+ return -EINVAL;
};
return 0;
}
static const struct platform_device_id vexpress_reset_id_table[] = {
- { .name = "vexpress-reset", .driver_data = FUNC_RESET, },
- { .name = "vexpress-shutdown", .driver_data = FUNC_SHUTDOWN, },
- { .name = "vexpress-reboot", .driver_data = FUNC_REBOOT, },
+ { .name = "vexpress-reset", .driver_data = RESET_RESTART, },
+ { .name = "vexpress-shutdown", .driver_data = RESET_POWER_OFF, },
+ { .name = "vexpress-reboot", .driver_data = RESET_RESTART, },
{}
};
^ permalink raw reply [flat|nested] 21+ messages in thread* [PATCH 06/11] ARM: vexpress: use the common machine reset handling
2013-10-31 6:27 [PATCH 00/11] RFC: Common machine reset handling Domenico Andreoli
` (4 preceding siblings ...)
2013-10-31 6:27 ` [PATCH 05/11] ARM: vexpress: consolidate machine reset func Domenico Andreoli
@ 2013-10-31 6:27 ` Domenico Andreoli
2013-10-31 6:27 ` [PATCH 07/11] ARM: bcm2835: " Domenico Andreoli
` (6 subsequent siblings)
12 siblings, 0 replies; 21+ messages in thread
From: Domenico Andreoli @ 2013-10-31 6:27 UTC (permalink / raw)
To: linux-arch
Cc: linux-arm-kernel, linux-mips, Russell King, Arnd Bergmann,
Olof Johansson, Ralf Baechle, Domenico Andreoli
[-- Attachment #1: arm-machine-reset-vexpress-hooks.patch --]
[-- Type: text/plain, Size: 4352 bytes --]
From: Domenico Andreoli <domenico.andreoli@linux.com>
Proof of concept: vexpress as provider of reset hooks.
Platform hooks implementation.
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Olof Johansson <olof@lixom.net>
Cc: linux-arm-kernel@lists.infradead.org
Signed-off-by: Domenico Andreoli <domenico.andreoli@linux.com>
---
drivers/power/reset/Kconfig | 1 +
drivers/power/reset/vexpress-poweroff.c | 54 +++++++++++++++++++++++---------
2 files changed, 39 insertions(+), 16 deletions(-)
Index: b/drivers/power/reset/Kconfig
===================================================================
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -41,6 +41,7 @@ config POWER_RESET_VEXPRESS
bool "ARM Versatile Express power-off and reset driver"
depends on ARM || ARM64
depends on POWER_RESET && VEXPRESS_CONFIG
+ select MACHINE_RESET
help
Power off and reset support for the ARM Ltd. Versatile
Express boards.
Index: b/drivers/power/reset/vexpress-poweroff.c
===================================================================
--- a/drivers/power/reset/vexpress-poweroff.c
+++ b/drivers/power/reset/vexpress-poweroff.c
@@ -19,7 +19,8 @@
#include <linux/vexpress.h>
#include <linux/machine_reset.h>
-#include <asm/system_misc.h>
+static enum reset_func vexpress_get_func(struct platform_device *pdev);
+static int vexpress_set_hook(struct platform_device *pdev);
static void vexpress_reset_do(struct device *dev, const char *what)
{
@@ -40,34 +41,40 @@ static void vexpress_reset_do(struct dev
dev_emerg(dev, "Unable to %s (%d)\n", what, err);
}
-static struct device *vexpress_power_off_device;
-
-static void vexpress_power_off(void)
+static void vexpress_power_off(void *dev)
{
- vexpress_reset_do(vexpress_power_off_device, "power off");
+ vexpress_reset_do(dev, "power off");
}
-static struct device *vexpress_restart_device;
-
-static void vexpress_restart(enum reboot_mode reboot_mode, const char *cmd)
+static void vexpress_restart(void *dev, enum reboot_mode reboot_mode,
+ const char *cmd)
{
- vexpress_reset_do(vexpress_restart_device, "restart");
+ vexpress_reset_do(dev, "restart");
}
static ssize_t vexpress_reset_active_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "%d\n", vexpress_restart_device == dev);
+ struct platform_device *pdev;
+ enum reset_func func;
+
+ pdev = container_of(dev, struct platform_device, dev);
+ func = vexpress_get_func(pdev);
+
+ return sprintf(buf, "%d\n", isset_machine_reset(func, dev));
}
static ssize_t vexpress_reset_active_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
long value;
+ struct platform_device *pdev;
int err = kstrtol(buf, 0, &value);
+ pdev = container_of(dev, struct platform_device, dev);
+
if (!err && value)
- vexpress_restart_device = dev;
+ vexpress_set_hook(pdev);
return err ? err : count;
}
@@ -90,7 +97,7 @@ static struct of_device_id vexpress_rese
{}
};
-static int vexpress_reset_probe(struct platform_device *pdev)
+static enum reset_func vexpress_get_func(struct platform_device *pdev)
{
enum reset_func func;
const struct of_device_id *match =
@@ -101,23 +108,38 @@ static int vexpress_reset_probe(struct p
else
func = pdev->id_entry->driver_data;
+ return func;
+}
+
+static int vexpress_set_hook(struct platform_device *pdev)
+{
+ enum reset_func func;
+ struct reset_hook hook;
+
+ func = vexpress_get_func(pdev);
+ reset_hook_init(&hook);
+
switch (func) {
case RESET_POWER_OFF:
- vexpress_power_off_device = &pdev->dev;
- pm_power_off = vexpress_power_off;
+ hook.power_off = vexpress_power_off;
break;
case RESET_RESTART:
- vexpress_restart_device = &pdev->dev;
- arm_pm_restart = vexpress_restart;
+ hook.restart = vexpress_restart;
device_create_file(&pdev->dev, &dev_attr_active);
break;
default:
return -EINVAL;
};
+ set_machine_reset(func, &hook, &pdev->dev);
return 0;
}
+static int vexpress_reset_probe(struct platform_device *pdev)
+{
+ return vexpress_set_hook(pdev);
+}
+
static const struct platform_device_id vexpress_reset_id_table[] = {
{ .name = "vexpress-reset", .driver_data = RESET_RESTART, },
{ .name = "vexpress-shutdown", .driver_data = RESET_POWER_OFF, },
^ permalink raw reply [flat|nested] 21+ messages in thread* [PATCH 07/11] ARM: bcm2835: use the common machine reset handling
2013-10-31 6:27 [PATCH 00/11] RFC: Common machine reset handling Domenico Andreoli
` (5 preceding siblings ...)
2013-10-31 6:27 ` [PATCH 06/11] ARM: vexpress: use the common machine reset handling Domenico Andreoli
@ 2013-10-31 6:27 ` Domenico Andreoli
2013-10-31 6:27 ` [PATCH 08/11] ARM: u300: " Domenico Andreoli
` (5 subsequent siblings)
12 siblings, 0 replies; 21+ messages in thread
From: Domenico Andreoli @ 2013-10-31 6:27 UTC (permalink / raw)
To: linux-arch
Cc: linux-arm-kernel, linux-mips, Russell King, Arnd Bergmann,
Olof Johansson, Ralf Baechle, Stephen Warren, Domenico Andreoli
[-- Attachment #1: arm-machine-reset-bcm2835.patch --]
[-- Type: text/plain, Size: 3733 bytes --]
From: Domenico Andreoli <domenico.andreoli@linux.com>
Proof of concept: bcm2835 as provider of reset hooks.
Cc: Stephen Warren <swarren@wwwdotorg.org>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Olof Johansson <olof@lixom.net>
Cc: linux-arm-kernel@lists.infradead.org
Signed-off-by: Domenico Andreoli <domenico.andreoli@linux.com>
---
arch/arm/mach-bcm2835/Kconfig | 1 +
arch/arm/mach-bcm2835/bcm2835.c | 30 ++++++++++++++++++------------
2 files changed, 19 insertions(+), 12 deletions(-)
Index: b/arch/arm/mach-bcm2835/Kconfig
===================================================================
--- a/arch/arm/mach-bcm2835/Kconfig
+++ b/arch/arm/mach-bcm2835/Kconfig
@@ -8,6 +8,7 @@ config ARCH_BCM2835
select CLKSRC_OF
select CPU_V6
select GENERIC_CLOCKEVENTS
+ select MACHINE_RESET
select PINCTRL
select PINCTRL_BCM2835
help
Index: b/arch/arm/mach-bcm2835/bcm2835.c
===================================================================
--- a/arch/arm/mach-bcm2835/bcm2835.c
+++ b/arch/arm/mach-bcm2835/bcm2835.c
@@ -19,6 +19,7 @@
#include <linux/of_platform.h>
#include <linux/clk/bcm2835.h>
#include <linux/clocksource.h>
+#include <linux/machine_reset.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -36,7 +37,8 @@
#define BCM2835_PERIPH_VIRT 0xf0000000
#define BCM2835_PERIPH_SIZE SZ_16M
-static void __iomem *wdt_regs;
+static void bcm2835_restart(void *dev, enum reboot_mode mode, const char *cmd);
+static void bcm2835_power_off(void *dev);
/*
* The machine restart method can be called from an atomic context so we won't
@@ -44,21 +46,28 @@ static void __iomem *wdt_regs;
*/
static void bcm2835_setup_restart(void)
{
+ struct reset_hook hook;
+ void __iomem *wdt_regs;
struct device_node *np = of_find_compatible_node(NULL, NULL,
"brcm,bcm2835-pm-wdt");
if (WARN(!np, "unable to setup watchdog restart"))
return;
wdt_regs = of_iomap(np, 0);
- WARN(!wdt_regs, "failed to remap watchdog regs");
+ if (WARN(!wdt_regs, "failed to remap watchdog regs"))
+ return;
+
+ reset_hook_init(&hook);
+ hook.restart = bcm2835_restart;
+ set_machine_reset(RESET_RESTART, &hook, wdt_regs);
+ hook.power_off = bcm2835_power_off;
+ set_machine_reset(RESET_POWER_OFF, &hook, wdt_regs);
}
-static void bcm2835_restart(enum reboot_mode mode, const char *cmd)
+static void bcm2835_restart(void *dev, enum reboot_mode mode, const char *cmd)
{
u32 val;
-
- if (!wdt_regs)
- return;
+ void __iomem *wdt_regs = dev;
/* use a timeout of 10 ticks (~150us) */
writel_relaxed(10 | PM_PASSWORD, wdt_regs + PM_WDOG);
@@ -76,9 +85,10 @@ static void bcm2835_restart(enum reboot_
* indicate to bootcode.bin not to reboot, then most of the chip will be
* powered off.
*/
-static void bcm2835_power_off(void)
+static void bcm2835_power_off(void *dev)
{
u32 val;
+ void __iomem *wdt_regs = dev;
/*
* We set the watchdog hard reset bit here to distinguish this reset
@@ -91,7 +101,7 @@ static void bcm2835_power_off(void)
writel_relaxed(val, wdt_regs + PM_RSTS);
/* Continue with normal reset mechanism */
- bcm2835_restart(REBOOT_HARD, "");
+ bcm2835_restart(dev, REBOOT_HARD, "");
}
static struct map_desc io_map __initdata = {
@@ -111,9 +121,6 @@ static void __init bcm2835_init(void)
int ret;
bcm2835_setup_restart();
- if (wdt_regs)
- pm_power_off = bcm2835_power_off;
-
bcm2835_init_clocks();
ret = of_platform_populate(NULL, of_default_bus_match_table, NULL,
@@ -135,6 +142,5 @@ DT_MACHINE_START(BCM2835, "BCM2835")
.handle_irq = bcm2835_handle_irq,
.init_machine = bcm2835_init,
.init_time = clocksource_of_init,
- .restart = bcm2835_restart,
.dt_compat = bcm2835_compat
MACHINE_END
^ permalink raw reply [flat|nested] 21+ messages in thread* [PATCH 08/11] ARM: u300: use the common machine reset handling
2013-10-31 6:27 [PATCH 00/11] RFC: Common machine reset handling Domenico Andreoli
` (6 preceding siblings ...)
2013-10-31 6:27 ` [PATCH 07/11] ARM: bcm2835: " Domenico Andreoli
@ 2013-10-31 6:27 ` Domenico Andreoli
2013-10-31 14:40 ` Linus Walleij
2013-10-31 6:27 ` [PATCH 09/11] ARM: tps65910: " Domenico Andreoli
` (4 subsequent siblings)
12 siblings, 1 reply; 21+ messages in thread
From: Domenico Andreoli @ 2013-10-31 6:27 UTC (permalink / raw)
To: linux-arch
Cc: linux-arm-kernel, linux-mips, Russell King, Arnd Bergmann,
Olof Johansson, Ralf Baechle, Linus Walleij, Domenico Andreoli
[-- Attachment #1: arm-machine-reset-u300.patch --]
[-- Type: text/plain, Size: 2870 bytes --]
From: Domenico Andreoli <domenico.andreoli@linux.com>
Proof of concept: u300 as provider of reset hooks.
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Olof Johansson <olof@lixom.net>
Cc: linux-arm-kernel@lists.infradead.org
Signed-off-by: Domenico Andreoli <domenico.andreoli@linux.com>
---
arch/arm/mach-u300/regulator.c | 23 ++++++++++++++---------
drivers/regulator/Kconfig | 1 +
2 files changed, 15 insertions(+), 9 deletions(-)
Index: b/drivers/regulator/Kconfig
===================================================================
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -106,6 +106,7 @@ config REGULATOR_AB3100
tristate "ST-Ericsson AB3100 Regulator functions"
depends on AB3100_CORE
default y if AB3100_CORE
+ select MACHINE_RESET
help
These regulators correspond to functionality in the
AB3100 analog baseband dealing with power regulators
Index: b/arch/arm/mach-u300/regulator.c
===================================================================
--- a/arch/arm/mach-u300/regulator.c
+++ b/arch/arm/mach-u300/regulator.c
@@ -17,6 +17,7 @@
#include <linux/regulator/consumer.h>
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
+#include <linux/machine_reset.h>
/* Power Management Control 16bit (R/W) */
#define U300_SYSCON_PMCR (0x50)
@@ -24,20 +25,14 @@
#define U300_SYSCON_PMCR_PWR_MGNT_ENABLE (0x0001)
/*
- * Regulators that power the board and chip and which are
- * not copuled to specific drivers are hogged in these
- * instances.
- */
-static struct regulator *main_power_15;
-
-/*
* This function is used from pm.h to shut down the system by
* resetting all regulators in turn and then disable regulator
* LDO D (main power).
*/
-void u300_pm_poweroff(void)
+void u300_pm_poweroff(void *dev)
{
sigset_t old, all;
+ struct regulator *main_power_15 = dev;
sigfillset(&all);
if (!sigprocmask(SIG_BLOCK, &all, &old)) {
@@ -51,6 +46,11 @@ void u300_pm_poweroff(void)
return;
}
+static void u300_reset_hook_release(void *dev)
+{
+ regulator_put(dev);
+}
+
/*
* Hog the regulators needed to power up the board.
*/
@@ -58,7 +58,9 @@ static int __init __u300_init_boardpower
{
struct device_node *np = pdev->dev.of_node;
struct device_node *syscon_np;
+ struct regulator *main_power_15;
struct regmap *regmap;
+ struct reset_hook hook;
int err;
pr_info("U300: setting up board power\n");
@@ -98,7 +100,10 @@ static int __init __u300_init_boardpower
U300_SYSCON_PMCR_DCON_ENABLE, 0);
/* Register globally exported PM poweroff hook */
- pm_power_off = u300_pm_poweroff;
+ reset_hook_init(&hook);
+ hook.power_off = u300_pm_poweroff;
+ hook.release = u300_reset_hook_release;
+ set_machine_reset(RESET_POWER_OFF, &hook, main_power_15);
return 0;
}
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH 08/11] ARM: u300: use the common machine reset handling
2013-10-31 6:27 ` [PATCH 08/11] ARM: u300: " Domenico Andreoli
@ 2013-10-31 14:40 ` Linus Walleij
2013-10-31 15:19 ` Domenico Andreoli
0 siblings, 1 reply; 21+ messages in thread
From: Linus Walleij @ 2013-10-31 14:40 UTC (permalink / raw)
To: Domenico Andreoli
Cc: linux-arch@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-mips, Russell King, Arnd Bergmann, Olof Johansson,
Ralf Baechle
On Wed, Oct 30, 2013 at 11:27 PM, Domenico Andreoli
<domenico.andreoli@linux.com> wrote:
> From: Domenico Andreoli <domenico.andreoli@linux.com>
>
> Proof of concept: u300 as provider of reset hooks.
Do you have a u300 to test this on or are you just guessing?
Anyway, concept looks correct, so Acked-by given that the
overall idea is accepted.
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 08/11] ARM: u300: use the common machine reset handling
2013-10-31 14:40 ` Linus Walleij
@ 2013-10-31 15:19 ` Domenico Andreoli
0 siblings, 0 replies; 21+ messages in thread
From: Domenico Andreoli @ 2013-10-31 15:19 UTC (permalink / raw)
To: Linus Walleij
Cc: Domenico Andreoli, linux-arch@vger.kernel.org, Russell King,
Arnd Bergmann, Ralf Baechle, linux-mips, Olof Johansson,
linux-arm-kernel@lists.infradead.org
On Thu, Oct 31, 2013 at 07:40:25AM -0700, Linus Walleij wrote:
> On Wed, Oct 30, 2013 at 11:27 PM, Domenico Andreoli
> <domenico.andreoli@linux.com> wrote:
>
> > From: Domenico Andreoli <domenico.andreoli@linux.com>
> >
> > Proof of concept: u300 as provider of reset hooks.
>
> Do you have a u300 to test this on or are you just guessing?
I don't have any u300, I picked it randomly. It's just to show some usage
and possibly discuss it. There are quite a lot of these hooks all around.
> Anyway, concept looks correct, so Acked-by given that the
> overall idea is accepted.
uhm.. don't see any general acceptance right now. maybe later..
thanks,
Domenico
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 09/11] ARM: tps65910: use the common machine reset handling
2013-10-31 6:27 [PATCH 00/11] RFC: Common machine reset handling Domenico Andreoli
` (7 preceding siblings ...)
2013-10-31 6:27 ` [PATCH 08/11] ARM: u300: " Domenico Andreoli
@ 2013-10-31 6:27 ` Domenico Andreoli
2013-10-31 6:27 ` [PATCH 10/11] max8907: " Domenico Andreoli
` (3 subsequent siblings)
12 siblings, 0 replies; 21+ messages in thread
From: Domenico Andreoli @ 2013-10-31 6:27 UTC (permalink / raw)
To: linux-arch
Cc: linux-arm-kernel, linux-mips, Russell King, Arnd Bergmann,
Olof Johansson, Ralf Baechle, Domenico Andreoli
[-- Attachment #1: tps65910-machine-reset.patch --]
[-- Type: text/plain, Size: 2241 bytes --]
From: Domenico Andreoli <domenico.andreoli@linux.com>
Proof of concept: tps65910 as provider of reset hooks.
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Olof Johansson <olof@lixom.net>
Cc: linux-arm-kernel@lists.infradead.org
Signed-off-by: Domenico Andreoli <domenico.andreoli@linux.com>
---
drivers/mfd/Kconfig | 1 +
drivers/mfd/tps65910.c | 16 ++++++++--------
2 files changed, 9 insertions(+), 8 deletions(-)
Index: b/drivers/mfd/Kconfig
===================================================================
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -769,6 +769,7 @@ config TPS65010
tristate "TI TPS6501x Power Management chips"
depends on I2C && GPIOLIB
default y if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_OSK
+ select MACHINE_RESET
help
If you say yes here you get support for the TPS6501x series of
Power Management chips. These include voltage regulators,
Index: b/drivers/mfd/tps65910.c
===================================================================
--- a/drivers/mfd/tps65910.c
+++ b/drivers/mfd/tps65910.c
@@ -26,6 +26,7 @@
#include <linux/regmap.h>
#include <linux/mfd/tps65910.h>
#include <linux/of_device.h>
+#include <linux/machine_reset.h>
static struct resource rtc_resources[] = {
{
@@ -438,12 +439,9 @@ struct tps65910_board *tps65910_parse_dt
}
#endif
-static struct i2c_client *tps65910_i2c_client;
-static void tps65910_power_off(void)
+static void tps65910_power_off(void *dev)
{
- struct tps65910 *tps65910;
-
- tps65910 = dev_get_drvdata(&tps65910_i2c_client->dev);
+ struct tps65910 *tps65910 = dev_get_drvdata(dev);
if (tps65910_reg_set_bits(tps65910, TPS65910_DEVCTRL,
DEVCTRL_PWR_OFF_MASK) < 0)
@@ -501,9 +499,11 @@ static int tps65910_i2c_probe(struct 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) {
+ struct reset_hook hook;
+ reset_hook_init(&hook);
+ hook.power_off = tps65910_power_off;
+ set_machine_reset(RESET_POWER_OFF, &hook, &i2c->dev);
}
ret = mfd_add_devices(tps65910->dev, -1,
^ permalink raw reply [flat|nested] 21+ messages in thread* [PATCH 10/11] max8907: use the common machine reset handling
2013-10-31 6:27 [PATCH 00/11] RFC: Common machine reset handling Domenico Andreoli
` (8 preceding siblings ...)
2013-10-31 6:27 ` [PATCH 09/11] ARM: tps65910: " Domenico Andreoli
@ 2013-10-31 6:27 ` Domenico Andreoli
2013-10-31 6:27 ` [PATCH 11/11] ARM: sp805: " Domenico Andreoli
` (2 subsequent siblings)
12 siblings, 0 replies; 21+ messages in thread
From: Domenico Andreoli @ 2013-10-31 6:27 UTC (permalink / raw)
To: linux-arch
Cc: linux-arm-kernel, linux-mips, Russell King, Arnd Bergmann,
Olof Johansson, Ralf Baechle, Domenico Andreoli
[-- Attachment #1: max8907-machine-reset.patch --]
[-- Type: text/plain, Size: 1953 bytes --]
From: Domenico Andreoli <domenico.andreoli@linux.com>
Proof of concept: max8907 as provider of reset hooks.
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Olof Johansson <olof@lixom.net>
Cc: linux-arm-kernel@lists.infradead.org
Signed-off-by: Domenico Andreoli <domenico.andreoli@linux.com>
---
drivers/mfd/Kconfig | 1 +
drivers/mfd/max8907.c | 13 ++++++++-----
2 files changed, 9 insertions(+), 5 deletions(-)
Index: b/drivers/mfd/Kconfig
===================================================================
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -339,6 +339,7 @@ config MFD_MAX8907
tristate "Maxim Semiconductor MAX8907 PMIC Support"
select MFD_CORE
depends on I2C=y
+ select MACHINE_RESET
select REGMAP_I2C
select REGMAP_IRQ
help
Index: b/drivers/mfd/max8907.c
===================================================================
--- a/drivers/mfd/max8907.c
+++ b/drivers/mfd/max8907.c
@@ -20,6 +20,7 @@
#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>
+#include <linux/machine_reset.h>
static struct mfd_cell max8907_cells[] = {
{ .name = "max8907-regulator", },
@@ -176,9 +177,9 @@ static const struct regmap_irq_chip max8
.num_irqs = ARRAY_SIZE(max8907_rtc_irqs),
};
-static struct max8907 *max8907_pm_off;
-static void max8907_power_off(void)
+static void max8907_power_off(void *dev)
{
+ struct max8907 *max8907_pm_off = dev;
regmap_update_bits(max8907_pm_off->regmap_gen, MAX8907_REG_RESET_CNFG,
MAX8907_MASK_POWER_OFF, MAX8907_MASK_POWER_OFF);
}
@@ -266,9 +267,11 @@ static int max8907_i2c_probe(struct i2c_
goto err_add_devices;
}
- if (pm_off && !pm_power_off) {
- max8907_pm_off = max8907;
- pm_power_off = max8907_power_off;
+ if (pm_off) {
+ struct reset_hook hook;
+ reset_hook_init(&hook);
+ hook.power_off = max8907_power_off;
+ set_machine_reset(RESET_POWER_OFF, &hook, max8907);
}
return 0;
^ permalink raw reply [flat|nested] 21+ messages in thread* [PATCH 11/11] ARM: sp805: use the common machine reset handling
2013-10-31 6:27 [PATCH 00/11] RFC: Common machine reset handling Domenico Andreoli
` (9 preceding siblings ...)
2013-10-31 6:27 ` [PATCH 10/11] max8907: " Domenico Andreoli
@ 2013-10-31 6:27 ` Domenico Andreoli
2013-10-31 10:21 ` [PATCH 00/11] RFC: Common " Russell King - ARM Linux
2013-10-31 21:49 ` Stephen Warren
12 siblings, 0 replies; 21+ messages in thread
From: Domenico Andreoli @ 2013-10-31 6:27 UTC (permalink / raw)
To: linux-arch
Cc: linux-arm-kernel, linux-mips, Russell King, Arnd Bergmann,
Olof Johansson, Ralf Baechle, Wim Van Sebroeck, Domenico Andreoli
[-- Attachment #1: sp805-machine-reset.patch --]
[-- Type: text/plain, Size: 4019 bytes --]
From: Domenico Andreoli <domenico.andreoli@linux.com>
Proof of concept: sp805 as provider of reset hooks.
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Olof Johansson <olof@lixom.net>
Cc: Wim Van Sebroeck <wim@iguana.be>
Cc: linux-arm-kernel@lists.infradead.org
Signed-off-by: Domenico Andreoli <domenico.andreoli@linux.com>
---
drivers/watchdog/Kconfig | 9 ++++++++
drivers/watchdog/sp805_wdt.c | 48 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 57 insertions(+)
Index: b/drivers/watchdog/Kconfig
===================================================================
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -110,11 +110,20 @@ config WM8350_WATCHDOG
config ARM_SP805_WATCHDOG
tristate "ARM SP805 Watchdog"
depends on ARM && ARM_AMBA
+ select MACHINE_RESET
select WATCHDOG_CORE
help
ARM Primecell SP805 Watchdog timer. This will reboot your system when
the timeout is reached.
+config ARM_SP805_WATCHDOG_RESTART_HOOK
+ bool "ARM SP805 system restart hook"
+ depends on ARM_SP805_WATCHDOG
+ help
+ Register hook to reboot the system based on the SP805 Watchdog.
+
+ This can be overriden with cmdline option restart_hook=0.
+
config AT91RM9200_WATCHDOG
tristate "AT91RM9200 watchdog"
depends on ARCH_AT91RM9200
Index: b/drivers/watchdog/sp805_wdt.c
===================================================================
--- a/drivers/watchdog/sp805_wdt.c
+++ b/drivers/watchdog/sp805_wdt.c
@@ -28,6 +28,8 @@
#include <linux/spinlock.h>
#include <linux/types.h>
#include <linux/watchdog.h>
+#include <linux/machine_reset.h>
+#include <linux/delay.h>
/* default timeout in seconds */
#define DEFAULT_TIMEOUT 60
@@ -77,6 +79,11 @@ module_param(nowayout, bool, 0);
MODULE_PARM_DESC(nowayout,
"Set to 1 to keep watchdog running after device release");
+static bool restart_hook = IS_ENABLED(CONFIG_ARM_SP805_WATCHDOG_RESTART_HOOK);
+module_param(restart_hook, bool, 0);
+MODULE_PARM_DESC(restart_hook,
+ "Set to 1 to install a machine restart handler based on this watchdog");
+
/* This routine finds load value that will reset system in required timout */
static int wdt_setload(struct watchdog_device *wdd, unsigned int timeout)
{
@@ -189,6 +196,33 @@ static int wdt_disable(struct watchdog_d
return 0;
}
+/* trigger watchdog timer */
+static void wdt_atomic_trigger(struct watchdog_device *wdd)
+{
+ struct sp805_wdt *wdt = watchdog_get_drvdata(wdd);
+
+ spin_lock(&wdt->lock);
+
+ writel_relaxed(UNLOCK, wdt->base + WDTLOCK);
+ writel_relaxed(0, wdt->base + WDTCONTROL);
+ udelay(20);
+ writel_relaxed(INT_MASK, wdt->base + WDTINTCLR);
+ udelay(20);
+
+ /* Expire after 5 cycles */
+ writel_relaxed(5, wdt->base + WDTLOAD);
+
+ writel_relaxed(INT_ENABLE | RESET_ENABLE, wdt->base + WDTCONTROL);
+ writel_relaxed(LOCK, wdt->base + WDTLOCK);
+
+ /* Flush posted writes. */
+ readl_relaxed(wdt->base + WDTLOCK);
+ spin_unlock(&wdt->lock);
+
+ /* Wait the bite */
+ udelay(400);
+}
+
static const struct watchdog_info wdt_info = {
.options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
.identity = MODULE_NAME,
@@ -201,8 +235,15 @@ static const struct watchdog_ops wdt_ops
.ping = wdt_ping,
.set_timeout = wdt_setload,
.get_timeleft = wdt_timeleft,
+/* .atomic_trigger = wdt_atomic_trigger, */
};
+static void sp805_wdt_machine_restart(void *wdd, enum reboot_mode mode,
+ const char *cmd)
+{
+ wdt_atomic_trigger(wdd);
+}
+
static int
sp805_wdt_probe(struct amba_device *adev, const struct amba_id *id)
{
@@ -247,6 +288,13 @@ sp805_wdt_probe(struct amba_device *adev
watchdog_set_drvdata(&wdt->wdd, wdt);
wdt_setload(&wdt->wdd, DEFAULT_TIMEOUT);
+ if (restart_hook) {
+ struct reset_hook hook;
+ reset_hook_init(&hook);
+ hook.restart = sp805_wdt_machine_restart;
+ set_machine_reset(RESET_RESTART, &hook, &wdt->wdd);
+ }
+
ret = watchdog_register_device(&wdt->wdd);
if (ret) {
dev_err(&adev->dev, "watchdog_register_device() failed: %d\n",
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH 00/11] RFC: Common machine reset handling
2013-10-31 6:27 [PATCH 00/11] RFC: Common machine reset handling Domenico Andreoli
` (10 preceding siblings ...)
2013-10-31 6:27 ` [PATCH 11/11] ARM: sp805: " Domenico Andreoli
@ 2013-10-31 10:21 ` Russell King - ARM Linux
2013-10-31 21:49 ` Stephen Warren
12 siblings, 0 replies; 21+ messages in thread
From: Russell King - ARM Linux @ 2013-10-31 10:21 UTC (permalink / raw)
To: Domenico Andreoli
Cc: linux-arch, linux-arm-kernel, linux-mips, Arnd Bergmann,
Olof Johansson, Ralf Baechle
On Thu, Oct 31, 2013 at 07:27:08AM +0100, Domenico Andreoli wrote:
> Hi,
>
> I've been looking for a solution to my bcm4760 watchdog based restart
> hook when I noticed that the kernel reboot/shutdown mechanism is having
> a few unaddressed issues.
>
> Those I identified are:
>
> 1) context pointer often needed by the reset hook
> (currently local static data is used for this pourpose)
I don't think that's a problem at all.
> I don't see these impressive diffstats but at least it's possible to free
> some static data along the way. Maybe there are some other desiderata that
> could be satisfied?
If that's the only benefit, then I don't think this is worth the churn,
sorry.
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH 00/11] RFC: Common machine reset handling
2013-10-31 6:27 [PATCH 00/11] RFC: Common machine reset handling Domenico Andreoli
` (11 preceding siblings ...)
2013-10-31 10:21 ` [PATCH 00/11] RFC: Common " Russell King - ARM Linux
@ 2013-10-31 21:49 ` Stephen Warren
2013-11-01 5:16 ` Domenico Andreoli
12 siblings, 1 reply; 21+ messages in thread
From: Stephen Warren @ 2013-10-31 21:49 UTC (permalink / raw)
To: Domenico Andreoli, linux-arch
Cc: Russell King, Arnd Bergmann, Ralf Baechle, linux-mips,
Olof Johansson, linux-arm-kernel
On 10/31/2013 12:27 AM, Domenico Andreoli wrote:
> Hi,
>
> I've been looking for a solution to my bcm4760 watchdog based restart
> hook when I noticed that the kernel reboot/shutdown mechanism is having
> a few unaddressed issues.
>
> Those I identified are:
>
> 1) context pointer often needed by the reset hook
> (currently local static data is used for this pourpose)
> 2) unclear ownership/policy in case of multiple reset hooks
> (currently almost nobody seems to care much)
I'm not sure how this patchset solves (2); even with the new API, it's
still the case that whichever code calls set_machine_reset() last wins,
just like before where whichever code wrote to pm_power_off won. I'm not
sure what this series attempts to solve.
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH 00/11] RFC: Common machine reset handling
2013-10-31 21:49 ` Stephen Warren
@ 2013-11-01 5:16 ` Domenico Andreoli
2013-11-01 15:58 ` Stephen Warren
0 siblings, 1 reply; 21+ messages in thread
From: Domenico Andreoli @ 2013-11-01 5:16 UTC (permalink / raw)
To: Stephen Warren
Cc: Domenico Andreoli, linux-arch, Russell King, Arnd Bergmann,
Ralf Baechle, linux-mips, Olof Johansson, linux-arm-kernel
On Thu, Oct 31, 2013 at 03:49:18PM -0600, Stephen Warren wrote:
> On 10/31/2013 12:27 AM, Domenico Andreoli wrote:
> > Hi,
> >
> > I've been looking for a solution to my bcm4760 watchdog based restart
> > hook when I noticed that the kernel reboot/shutdown mechanism is having
> > a few unaddressed issues.
> >
> > Those I identified are:
> >
> > 1) context pointer often needed by the reset hook
> > (currently local static data is used for this pourpose)
> > 2) unclear ownership/policy in case of multiple reset hooks
> > (currently almost nobody seems to care much)
>
> I'm not sure how this patchset solves (2); even with the new API, it's
> still the case that whichever code calls set_machine_reset() last wins,
> just like before where whichever code wrote to pm_power_off won. I'm not
> sure what this series attempts to solve.
That's right, the last wins. But the previous has a chance to know.
I only supposed there is somebody in charge of selecting the best handler
for the machine. Don't know how fancy this decision is but at least for
the vexpress there is also a sysfs way to configure different reset methods
from user-space.
So cleaning up things after the handler is replaced seemed a sensible
thing to do.
Another "problem" this patch would solve is the registration of the
reset handler in a architecture independent way. Now an otherwise platform
generic gpio HW reset driver would need to do different things on different
architectures.
thanks,
Domenico
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 00/11] RFC: Common machine reset handling
2013-11-01 5:16 ` Domenico Andreoli
@ 2013-11-01 15:58 ` Stephen Warren
2013-11-01 16:12 ` Russell King - ARM Linux
0 siblings, 1 reply; 21+ messages in thread
From: Stephen Warren @ 2013-11-01 15:58 UTC (permalink / raw)
To: Domenico Andreoli, linux-arch, Russell King, Arnd Bergmann,
Ralf Baechle, linux-mips, Olof Johansson, linux-arm-kernel
On 10/31/2013 11:16 PM, Domenico Andreoli wrote:
> On Thu, Oct 31, 2013 at 03:49:18PM -0600, Stephen Warren wrote:
>> On 10/31/2013 12:27 AM, Domenico Andreoli wrote:
>>> Hi,
>>>
>>> I've been looking for a solution to my bcm4760 watchdog based restart
>>> hook when I noticed that the kernel reboot/shutdown mechanism is having
>>> a few unaddressed issues.
>>>
>>> Those I identified are:
>>>
>>> 1) context pointer often needed by the reset hook
>>> (currently local static data is used for this pourpose)
>>> 2) unclear ownership/policy in case of multiple reset hooks
>>> (currently almost nobody seems to care much)
>>
>> I'm not sure how this patchset solves (2); even with the new API, it's
>> still the case that whichever code calls set_machine_reset() last wins,
>> just like before where whichever code wrote to pm_power_off won. I'm not
>> sure what this series attempts to solve.
>
> That's right, the last wins. But the previous has a chance to know.
>
> I only supposed there is somebody in charge of selecting the best handler
> for the machine. Don't know how fancy this decision is but at least for
> the vexpress there is also a sysfs way to configure different reset methods
> from user-space.
For PMICs that provide power off, we've been adding a property to DT to
indicate whether the PMIC is *the* system power off controller or not.
If the property is present, the PMIC registers itself in the poweroff
hook. If not, it doesn't. So, there really isn't an algorithm for
selecting the power off mechanism, but rather we designate one mechanism
ahead of time, and that's the only one that's relevant. We could
probably do the same for reset mechanisms.
I guess the vexpress situation is actually the same; there's a single
concept of a custom vexpress reset, it's just that sysfs is used to
select exactly what that does?
> So cleaning up things after the handler is replaced seemed a sensible
> thing to do.
Can't we avoid replacing handlers, but only registering a single handler?
> Another "problem" this patch would solve is the registration of the
> reset handler in a architecture independent way. Now an otherwise platform
> generic gpio HW reset driver would need to do different things on different
> architectures.
OK, if there are architecture differences in how the hooks are
registered, that seems like a good thing to fix.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 00/11] RFC: Common machine reset handling
2013-11-01 15:58 ` Stephen Warren
@ 2013-11-01 16:12 ` Russell King - ARM Linux
0 siblings, 0 replies; 21+ messages in thread
From: Russell King - ARM Linux @ 2013-11-01 16:12 UTC (permalink / raw)
To: Stephen Warren
Cc: Domenico Andreoli, linux-arch, Arnd Bergmann, Ralf Baechle,
linux-mips, Olof Johansson, linux-arm-kernel
On Fri, Nov 01, 2013 at 09:58:49AM -0600, Stephen Warren wrote:
> For PMICs that provide power off, we've been adding a property to DT to
> indicate whether the PMIC is *the* system power off controller or not.
> If the property is present, the PMIC registers itself in the poweroff
> hook. If not, it doesn't. So, there really isn't an algorithm for
> selecting the power off mechanism, but rather we designate one mechanism
> ahead of time, and that's the only one that's relevant. We could
> probably do the same for reset mechanisms.
>
> I guess the vexpress situation is actually the same; there's a single
> concept of a custom vexpress reset, it's just that sysfs is used to
> select exactly what that does?
I'm not aware of that. Vexpress has the following mechanisms:
- reset - this causes the system to be restarted without powering off.
- restart - this causes the system to be powered off and back on.
- poweroff - this causes the system to power off.
Obviously, poweroff is what needs to happen when someone issues the
poweroff command (or, when we get hibernate support, the power off
hook will also be called to power the system off after saving all
system state.) So, a power off callback really better power the
system off and not reboot it.
reset vs restart is a choice, and one of those should happen as a result
of the reboot command, or other similar event which ends up requesting
a system restart. That may be configurable.
Ultimately though, this should have no bearing on the hooking of poweroff
and restart callbacks; the only difference there is on Vexpress is the
function code passed to the system controller.
^ permalink raw reply [flat|nested] 21+ messages in thread