* [PATCH v2] poweroff: Allow to register poweroff handlers
@ 2017-03-13 11:05 Oleksij Rempel
2017-03-14 7:17 ` Sascha Hauer
0 siblings, 1 reply; 2+ messages in thread
From: Oleksij Rempel @ 2017-03-13 11:05 UTC (permalink / raw)
To: barebox; +Cc: Oleksij Rempel
From: Sascha Hauer <s.hauer@pengutronix.de>
Allow to register handlers for poweroff. This allows to have multiple
poweroff implementations in a single binary. The implementation is close
to the restart handlers.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
arch/arm/Kconfig | 2 -
arch/arm/boards/mioa701/gpio0_poweroff.c | 3 +-
arch/arm/mach-highbank/reset.c | 20 +++---
arch/arm/mach-pxa/pxa2xx.c | 15 +++-
arch/arm/mach-pxa/pxa3xx.c | 13 +++-
arch/mips/mach-xburst/Kconfig | 1 -
arch/mips/mach-xburst/reset-jz4750.c | 13 +++-
commands/Kconfig | 5 --
commands/poweroff.c | 3 +-
common/Makefile | 1 +
common/poweroff.c | 114 +++++++++++++++++++++++++++++++
include/common.h | 3 -
include/poweroff.h | 21 ++++++
13 files changed, 186 insertions(+), 28 deletions(-)
create mode 100644 common/poweroff.c
create mode 100644 include/poweroff.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 3e8ccf766..eedc2b4e9 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -98,7 +98,6 @@ config ARCH_EP93XX
config ARCH_HIGHBANK
bool "Calxeda Highbank"
select HAS_DEBUG_LL
- select HAS_POWEROFF
select ARCH_HAS_L2X0
select CPU_V7
select ARM_AMBA
@@ -158,7 +157,6 @@ config ARCH_OMAP
config ARCH_PXA
bool "Intel/Marvell PXA based"
select GENERIC_GPIO
- select HAS_POWEROFF
config ARCH_ROCKCHIP
bool "Rockchip RX3xxx"
diff --git a/arch/arm/boards/mioa701/gpio0_poweroff.c b/arch/arm/boards/mioa701/gpio0_poweroff.c
index 2054548aa..01a5d0cc6 100644
--- a/arch/arm/boards/mioa701/gpio0_poweroff.c
+++ b/arch/arm/boards/mioa701/gpio0_poweroff.c
@@ -19,6 +19,7 @@
#include <clock.h>
#include <common.h>
#include <init.h>
+#include <poweroff.h>
#include <gpio.h>
#include <poller.h>
@@ -45,7 +46,7 @@ static void try_poweroff(void)
gpio_set_value(GPIO115_LED_nKeyboard, 0);
mdelay(2000);
- poweroff();
+ poweroff_machine();
}
static void gpio0_poller_fn(struct poller_struct *poller)
diff --git a/arch/arm/mach-highbank/reset.c b/arch/arm/mach-highbank/reset.c
index 929ded595..b60f34452 100644
--- a/arch/arm/mach-highbank/reset.c
+++ b/arch/arm/mach-highbank/reset.c
@@ -6,6 +6,7 @@
#include <common.h>
#include <io.h>
+#include <poweroff.h>
#include <restart.h>
#include <init.h>
@@ -20,15 +21,7 @@ static void __noreturn highbank_restart_soc(struct restart_handler *rst)
hang();
}
-static int restart_register_feature(void)
-{
- restart_handler_register_fn(highbank_restart_soc);
-
- return 0;
-}
-coredevice_initcall(restart_register_feature);
-
-void __noreturn poweroff()
+void __noreturn highbank_poweroff(struct poweroff_handler *handler)
{
shutdown_barebox();
@@ -37,3 +30,12 @@ void __noreturn poweroff()
while(1);
}
+
+static int highbank_init(void)
+{
+ restart_handler_register_fn(highbank_restart_soc);
+ poweroff_handler_register_fn(highbank_poweroff);
+
+ return 0;
+}
+coredevice_initcall(highbank_init);
diff --git a/arch/arm/mach-pxa/pxa2xx.c b/arch/arm/mach-pxa/pxa2xx.c
index b712b388c..e28378e6d 100644
--- a/arch/arm/mach-pxa/pxa2xx.c
+++ b/arch/arm/mach-pxa/pxa2xx.c
@@ -14,6 +14,7 @@
#include <common.h>
#include <init.h>
+#include <poweroff.h>
#include <reset_source.h>
#include <mach/hardware.h>
#include <mach/pxa-regs.h>
@@ -46,9 +47,7 @@ void pxa_clear_reset_source(void)
RCSR = RCSR_GPR | RCSR_SMR | RCSR_WDR | RCSR_HWR;
}
-device_initcall(pxa_detect_reset_source);
-
-void __noreturn poweroff(void)
+static void __noreturn pxa2xx_poweroff(struct poweroff_handler *handler)
{
shutdown_barebox();
@@ -57,3 +56,13 @@ void __noreturn poweroff(void)
pxa_suspend(PWRMODE_DEEPSLEEP);
unreachable();
}
+
+static int pxa2xx_init(void)
+{
+ poweroff_handler_register_fn(pxa2xx_poweroff);
+
+ pxa_detect_reset_source();
+
+ return 0;
+}
+device_initcall(pxa2xx_init);
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index 86ca63b16..ccfd952b5 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -14,6 +14,7 @@
#include <common.h>
#include <init.h>
+#include <poweroff.h>
#include <reset_source.h>
#include <mach/hardware.h>
#include <mach/pxa-regs.h>
@@ -48,7 +49,7 @@ void pxa_clear_reset_source(void)
device_initcall(pxa_detect_reset_source);
-void __noreturn poweroff(void)
+static void __noreturn pxa3xx_poweroff(struct poweroff_handler *handler)
{
shutdown_barebox();
@@ -57,3 +58,13 @@ void __noreturn poweroff(void)
pxa3xx_suspend(PXA3xx_PM_S3D4C4);
unreachable();
}
+
+static int pxa3xx_init(void)
+{
+ poweroff_handler_register_fn(pxa3xx_poweroff);
+
+ pxa_detect_reset_source();
+
+ return 0;
+}
+device_initcall(pxa3xx_init);
diff --git a/arch/mips/mach-xburst/Kconfig b/arch/mips/mach-xburst/Kconfig
index fd106fefe..ee79ff616 100644
--- a/arch/mips/mach-xburst/Kconfig
+++ b/arch/mips/mach-xburst/Kconfig
@@ -21,7 +21,6 @@ choice
config BOARD_RZX50
bool "Ritmix RZX-50"
- select HAS_POWEROFF
select CPU_JZ4755
config BOARD_CI20
diff --git a/arch/mips/mach-xburst/reset-jz4750.c b/arch/mips/mach-xburst/reset-jz4750.c
index 25830f130..e1e88e2bf 100644
--- a/arch/mips/mach-xburst/reset-jz4750.c
+++ b/arch/mips/mach-xburst/reset-jz4750.c
@@ -22,6 +22,8 @@
#include <common.h>
#include <io.h>
+#include <init.h>
+#include <poweroff.h>
#include <mach/jz4750d_regs.h>
static void __noreturn jz4750d_halt(void)
@@ -37,7 +39,7 @@ static void __noreturn jz4750d_halt(void)
unreachable();
}
-void __noreturn poweroff()
+static void __noreturn jz4750_poweroff(struct poweroff_handler *handler)
{
u32 ctrl;
@@ -50,4 +52,11 @@ void __noreturn poweroff()
writel(RTC_HCR_PD, (u32 *)RTC_HCR);
jz4750d_halt();
}
-EXPORT_SYMBOL(poweroff);
+
+static int jz4750_init(void)
+{
+ restart_handler_register_fn(jz4750_poweroff);
+
+ return 0;
+}
+coredevice_initcall(jz4750_init);
\ No newline at end of file
diff --git a/commands/Kconfig b/commands/Kconfig
index 21d921268..5a709a900 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -6,10 +6,6 @@ config COMMAND_SUPPORT
depends on !SHELL_NONE
default y
-config HAS_POWEROFF
- bool
- default n
-
if COMMAND_SUPPORT
config COMPILE_HASH
@@ -1848,7 +1844,6 @@ config CMD_NAND_BITFLIP
config CMD_POWEROFF
tristate
- depends on HAS_POWEROFF
prompt "poweroff"
help
Turn the power off.
diff --git a/commands/poweroff.c b/commands/poweroff.c
index e8c726a7f..bbafa13bd 100644
--- a/commands/poweroff.c
+++ b/commands/poweroff.c
@@ -19,10 +19,11 @@
#include <common.h>
#include <command.h>
+#include <poweroff.h>
static int cmd_poweroff(int argc, char *argv[])
{
- poweroff();
+ poweroff_machine();
/* Not reached */
return 1;
diff --git a/common/Makefile b/common/Makefile
index 869b15a92..572bf0578 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -9,6 +9,7 @@ obj-pbl-y += memsize.o
obj-y += resource.o
obj-y += bootsource.o
obj-y += restart.o
+obj-y += poweroff.o
obj-$(CONFIG_AUTO_COMPLETE) += complete.o
obj-$(CONFIG_BANNER) += version.o
obj-$(CONFIG_BAREBOX_UPDATE) += bbu.o
diff --git a/common/poweroff.c b/common/poweroff.c
new file mode 100644
index 000000000..32a78280d
--- /dev/null
+++ b/common/poweroff.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2015 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ */
+#define pr_fmt(fmt) "poweroff: " fmt
+
+#include <common.h>
+#include <poweroff.h>
+#include <malloc.h>
+#include <of.h>
+
+static LIST_HEAD(poweroff_handler_list);
+
+/**
+ * poweroff_handler_register() - register a handler for poweroffing the system
+ * @rst: The handler struct
+ *
+ * This adds @rst to the list of registered poweroff handlers.
+ *
+ * return: 0 for success or negative error code
+ */
+int poweroff_handler_register(struct poweroff_handler *handler)
+{
+ if (!handler->name)
+ handler->name = POWEROFF_DEFAULT_NAME;
+ if (!handler->priority)
+ handler->priority = POWEROFF_DEFAULT_PRIORITY;
+
+ list_add_tail(&handler->list, &poweroff_handler_list);
+
+ pr_debug("registering poweroff handler \"%s\" with priority %d\n",
+ handler->name, handler->priority);
+
+ return 0;
+}
+
+/**
+ * poweroff_handler_register_fn() - register a handler function
+ * @poweroff_fn: The poweroff function
+ *
+ * convenience wrapper for poweroff_handler_register() to register a handler
+ * with given function and default values otherwise.
+ *
+ * return: 0 for success or negative error code
+ */
+int poweroff_handler_register_fn(void (*poweroff_fn)(struct poweroff_handler *))
+{
+ struct poweroff_handler *handler;
+ int ret;
+
+ handler = xzalloc(sizeof(*handler));
+
+ handler->poweroff = poweroff_fn;
+
+ ret = poweroff_handler_register(handler);
+
+ if (ret)
+ free(handler);
+
+ return ret;
+}
+
+/**
+ * poweroff_machine() - power off the machine
+ */
+void __noreturn poweroff_machine(void)
+{
+ struct poweroff_handler *handler = NULL, *tmp;
+ unsigned int priority = 0;
+
+ list_for_each_entry(tmp, &poweroff_handler_list, list) {
+ if (tmp->priority > priority) {
+ priority = tmp->priority;
+ handler = tmp;
+ }
+ }
+
+ if (handler) {
+ pr_debug("using poweroff handler %s\n", handler->name);
+ console_flush();
+ handler->poweroff(handler);
+ } else {
+ pr_err("No poweroff handler found!\n");
+ }
+
+ hang();
+}
+
+/**
+ * of_get_poweroff_priority() - get the desired poweroff priority from device tree
+ * @node: The device_node to read the property from
+ *
+ * return: The priority
+ */
+unsigned int of_get_poweroff_priority(struct device_node *node)
+{
+ unsigned int priority = POWEROFF_DEFAULT_PRIORITY;
+
+ of_property_read_u32(node, "poweroff-priority", &priority);
+
+ return priority;
+}
diff --git a/include/common.h b/include/common.h
index 680a0affb..dd7445e9b 100644
--- a/include/common.h
+++ b/include/common.h
@@ -66,9 +66,6 @@ int readline (const char *prompt, char *buf, int len);
/* common/memsize.c */
long get_ram_size (volatile long *, long);
-/* $(CPU)/cpu.c */
-void __noreturn poweroff(void);
-
/* common/console.c */
int ctrlc (void);
diff --git a/include/poweroff.h b/include/poweroff.h
new file mode 100644
index 000000000..ae9557db5
--- /dev/null
+++ b/include/poweroff.h
@@ -0,0 +1,21 @@
+#ifndef __INCLUDE_POWEROFF_H
+#define __INCLUDE_POWEROFF_H
+
+void __noreturn poweroff_machine(void);
+
+struct poweroff_handler {
+ void (*poweroff)(struct poweroff_handler *);
+ int priority;
+ const char *name;
+ struct list_head list;
+};
+
+int poweroff_handler_register(struct poweroff_handler *);
+int poweroff_handler_register_fn(void (*poweroff_fn)(struct poweroff_handler *));
+
+#define POWEROFF_DEFAULT_PRIORITY 100
+#define POWEROFF_DEFAULT_NAME "default"
+
+unsigned int of_get_poweroff_priority(struct device_node *node);
+
+#endif /* __INCLUDE_POWEROFF_H */
--
2.11.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH v2] poweroff: Allow to register poweroff handlers
2017-03-13 11:05 [PATCH v2] poweroff: Allow to register poweroff handlers Oleksij Rempel
@ 2017-03-14 7:17 ` Sascha Hauer
0 siblings, 0 replies; 2+ messages in thread
From: Sascha Hauer @ 2017-03-14 7:17 UTC (permalink / raw)
To: Oleksij Rempel; +Cc: barebox
On Mon, Mar 13, 2017 at 12:05:23PM +0100, Oleksij Rempel wrote:
> From: Sascha Hauer <s.hauer@pengutronix.de>
>
> Allow to register handlers for poweroff. This allows to have multiple
> poweroff implementations in a single binary. The implementation is close
> to the restart handlers.
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
Applied, thanks
Sascha
> ---
> arch/arm/Kconfig | 2 -
> arch/arm/boards/mioa701/gpio0_poweroff.c | 3 +-
> arch/arm/mach-highbank/reset.c | 20 +++---
> arch/arm/mach-pxa/pxa2xx.c | 15 +++-
> arch/arm/mach-pxa/pxa3xx.c | 13 +++-
> arch/mips/mach-xburst/Kconfig | 1 -
> arch/mips/mach-xburst/reset-jz4750.c | 13 +++-
> commands/Kconfig | 5 --
> commands/poweroff.c | 3 +-
> common/Makefile | 1 +
> common/poweroff.c | 114 +++++++++++++++++++++++++++++++
> include/common.h | 3 -
> include/poweroff.h | 21 ++++++
> 13 files changed, 186 insertions(+), 28 deletions(-)
> create mode 100644 common/poweroff.c
> create mode 100644 include/poweroff.h
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 3e8ccf766..eedc2b4e9 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -98,7 +98,6 @@ config ARCH_EP93XX
> config ARCH_HIGHBANK
> bool "Calxeda Highbank"
> select HAS_DEBUG_LL
> - select HAS_POWEROFF
> select ARCH_HAS_L2X0
> select CPU_V7
> select ARM_AMBA
> @@ -158,7 +157,6 @@ config ARCH_OMAP
> config ARCH_PXA
> bool "Intel/Marvell PXA based"
> select GENERIC_GPIO
> - select HAS_POWEROFF
>
> config ARCH_ROCKCHIP
> bool "Rockchip RX3xxx"
> diff --git a/arch/arm/boards/mioa701/gpio0_poweroff.c b/arch/arm/boards/mioa701/gpio0_poweroff.c
> index 2054548aa..01a5d0cc6 100644
> --- a/arch/arm/boards/mioa701/gpio0_poweroff.c
> +++ b/arch/arm/boards/mioa701/gpio0_poweroff.c
> @@ -19,6 +19,7 @@
> #include <clock.h>
> #include <common.h>
> #include <init.h>
> +#include <poweroff.h>
> #include <gpio.h>
> #include <poller.h>
>
> @@ -45,7 +46,7 @@ static void try_poweroff(void)
>
> gpio_set_value(GPIO115_LED_nKeyboard, 0);
> mdelay(2000);
> - poweroff();
> + poweroff_machine();
> }
>
> static void gpio0_poller_fn(struct poller_struct *poller)
> diff --git a/arch/arm/mach-highbank/reset.c b/arch/arm/mach-highbank/reset.c
> index 929ded595..b60f34452 100644
> --- a/arch/arm/mach-highbank/reset.c
> +++ b/arch/arm/mach-highbank/reset.c
> @@ -6,6 +6,7 @@
>
> #include <common.h>
> #include <io.h>
> +#include <poweroff.h>
> #include <restart.h>
> #include <init.h>
>
> @@ -20,15 +21,7 @@ static void __noreturn highbank_restart_soc(struct restart_handler *rst)
> hang();
> }
>
> -static int restart_register_feature(void)
> -{
> - restart_handler_register_fn(highbank_restart_soc);
> -
> - return 0;
> -}
> -coredevice_initcall(restart_register_feature);
> -
> -void __noreturn poweroff()
> +void __noreturn highbank_poweroff(struct poweroff_handler *handler)
> {
> shutdown_barebox();
>
> @@ -37,3 +30,12 @@ void __noreturn poweroff()
>
> while(1);
> }
> +
> +static int highbank_init(void)
> +{
> + restart_handler_register_fn(highbank_restart_soc);
> + poweroff_handler_register_fn(highbank_poweroff);
> +
> + return 0;
> +}
> +coredevice_initcall(highbank_init);
> diff --git a/arch/arm/mach-pxa/pxa2xx.c b/arch/arm/mach-pxa/pxa2xx.c
> index b712b388c..e28378e6d 100644
> --- a/arch/arm/mach-pxa/pxa2xx.c
> +++ b/arch/arm/mach-pxa/pxa2xx.c
> @@ -14,6 +14,7 @@
>
> #include <common.h>
> #include <init.h>
> +#include <poweroff.h>
> #include <reset_source.h>
> #include <mach/hardware.h>
> #include <mach/pxa-regs.h>
> @@ -46,9 +47,7 @@ void pxa_clear_reset_source(void)
> RCSR = RCSR_GPR | RCSR_SMR | RCSR_WDR | RCSR_HWR;
> }
>
> -device_initcall(pxa_detect_reset_source);
> -
> -void __noreturn poweroff(void)
> +static void __noreturn pxa2xx_poweroff(struct poweroff_handler *handler)
> {
> shutdown_barebox();
>
> @@ -57,3 +56,13 @@ void __noreturn poweroff(void)
> pxa_suspend(PWRMODE_DEEPSLEEP);
> unreachable();
> }
> +
> +static int pxa2xx_init(void)
> +{
> + poweroff_handler_register_fn(pxa2xx_poweroff);
> +
> + pxa_detect_reset_source();
> +
> + return 0;
> +}
> +device_initcall(pxa2xx_init);
> diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
> index 86ca63b16..ccfd952b5 100644
> --- a/arch/arm/mach-pxa/pxa3xx.c
> +++ b/arch/arm/mach-pxa/pxa3xx.c
> @@ -14,6 +14,7 @@
>
> #include <common.h>
> #include <init.h>
> +#include <poweroff.h>
> #include <reset_source.h>
> #include <mach/hardware.h>
> #include <mach/pxa-regs.h>
> @@ -48,7 +49,7 @@ void pxa_clear_reset_source(void)
>
> device_initcall(pxa_detect_reset_source);
>
> -void __noreturn poweroff(void)
> +static void __noreturn pxa3xx_poweroff(struct poweroff_handler *handler)
> {
> shutdown_barebox();
>
> @@ -57,3 +58,13 @@ void __noreturn poweroff(void)
> pxa3xx_suspend(PXA3xx_PM_S3D4C4);
> unreachable();
> }
> +
> +static int pxa3xx_init(void)
> +{
> + poweroff_handler_register_fn(pxa3xx_poweroff);
> +
> + pxa_detect_reset_source();
> +
> + return 0;
> +}
> +device_initcall(pxa3xx_init);
> diff --git a/arch/mips/mach-xburst/Kconfig b/arch/mips/mach-xburst/Kconfig
> index fd106fefe..ee79ff616 100644
> --- a/arch/mips/mach-xburst/Kconfig
> +++ b/arch/mips/mach-xburst/Kconfig
> @@ -21,7 +21,6 @@ choice
>
> config BOARD_RZX50
> bool "Ritmix RZX-50"
> - select HAS_POWEROFF
> select CPU_JZ4755
>
> config BOARD_CI20
> diff --git a/arch/mips/mach-xburst/reset-jz4750.c b/arch/mips/mach-xburst/reset-jz4750.c
> index 25830f130..e1e88e2bf 100644
> --- a/arch/mips/mach-xburst/reset-jz4750.c
> +++ b/arch/mips/mach-xburst/reset-jz4750.c
> @@ -22,6 +22,8 @@
>
> #include <common.h>
> #include <io.h>
> +#include <init.h>
> +#include <poweroff.h>
> #include <mach/jz4750d_regs.h>
>
> static void __noreturn jz4750d_halt(void)
> @@ -37,7 +39,7 @@ static void __noreturn jz4750d_halt(void)
> unreachable();
> }
>
> -void __noreturn poweroff()
> +static void __noreturn jz4750_poweroff(struct poweroff_handler *handler)
> {
> u32 ctrl;
>
> @@ -50,4 +52,11 @@ void __noreturn poweroff()
> writel(RTC_HCR_PD, (u32 *)RTC_HCR);
> jz4750d_halt();
> }
> -EXPORT_SYMBOL(poweroff);
> +
> +static int jz4750_init(void)
> +{
> + restart_handler_register_fn(jz4750_poweroff);
> +
> + return 0;
> +}
> +coredevice_initcall(jz4750_init);
> \ No newline at end of file
> diff --git a/commands/Kconfig b/commands/Kconfig
> index 21d921268..5a709a900 100644
> --- a/commands/Kconfig
> +++ b/commands/Kconfig
> @@ -6,10 +6,6 @@ config COMMAND_SUPPORT
> depends on !SHELL_NONE
> default y
>
> -config HAS_POWEROFF
> - bool
> - default n
> -
> if COMMAND_SUPPORT
>
> config COMPILE_HASH
> @@ -1848,7 +1844,6 @@ config CMD_NAND_BITFLIP
>
> config CMD_POWEROFF
> tristate
> - depends on HAS_POWEROFF
> prompt "poweroff"
> help
> Turn the power off.
> diff --git a/commands/poweroff.c b/commands/poweroff.c
> index e8c726a7f..bbafa13bd 100644
> --- a/commands/poweroff.c
> +++ b/commands/poweroff.c
> @@ -19,10 +19,11 @@
>
> #include <common.h>
> #include <command.h>
> +#include <poweroff.h>
>
> static int cmd_poweroff(int argc, char *argv[])
> {
> - poweroff();
> + poweroff_machine();
>
> /* Not reached */
> return 1;
> diff --git a/common/Makefile b/common/Makefile
> index 869b15a92..572bf0578 100644
> --- a/common/Makefile
> +++ b/common/Makefile
> @@ -9,6 +9,7 @@ obj-pbl-y += memsize.o
> obj-y += resource.o
> obj-y += bootsource.o
> obj-y += restart.o
> +obj-y += poweroff.o
> obj-$(CONFIG_AUTO_COMPLETE) += complete.o
> obj-$(CONFIG_BANNER) += version.o
> obj-$(CONFIG_BAREBOX_UPDATE) += bbu.o
> diff --git a/common/poweroff.c b/common/poweroff.c
> new file mode 100644
> index 000000000..32a78280d
> --- /dev/null
> +++ b/common/poweroff.c
> @@ -0,0 +1,114 @@
> +/*
> + * Copyright (c) 2015 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2
> + * as published by the Free Software Foundation.
> + *
> + * 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.
> + *
> + */
> +#define pr_fmt(fmt) "poweroff: " fmt
> +
> +#include <common.h>
> +#include <poweroff.h>
> +#include <malloc.h>
> +#include <of.h>
> +
> +static LIST_HEAD(poweroff_handler_list);
> +
> +/**
> + * poweroff_handler_register() - register a handler for poweroffing the system
> + * @rst: The handler struct
> + *
> + * This adds @rst to the list of registered poweroff handlers.
> + *
> + * return: 0 for success or negative error code
> + */
> +int poweroff_handler_register(struct poweroff_handler *handler)
> +{
> + if (!handler->name)
> + handler->name = POWEROFF_DEFAULT_NAME;
> + if (!handler->priority)
> + handler->priority = POWEROFF_DEFAULT_PRIORITY;
> +
> + list_add_tail(&handler->list, &poweroff_handler_list);
> +
> + pr_debug("registering poweroff handler \"%s\" with priority %d\n",
> + handler->name, handler->priority);
> +
> + return 0;
> +}
> +
> +/**
> + * poweroff_handler_register_fn() - register a handler function
> + * @poweroff_fn: The poweroff function
> + *
> + * convenience wrapper for poweroff_handler_register() to register a handler
> + * with given function and default values otherwise.
> + *
> + * return: 0 for success or negative error code
> + */
> +int poweroff_handler_register_fn(void (*poweroff_fn)(struct poweroff_handler *))
> +{
> + struct poweroff_handler *handler;
> + int ret;
> +
> + handler = xzalloc(sizeof(*handler));
> +
> + handler->poweroff = poweroff_fn;
> +
> + ret = poweroff_handler_register(handler);
> +
> + if (ret)
> + free(handler);
> +
> + return ret;
> +}
> +
> +/**
> + * poweroff_machine() - power off the machine
> + */
> +void __noreturn poweroff_machine(void)
> +{
> + struct poweroff_handler *handler = NULL, *tmp;
> + unsigned int priority = 0;
> +
> + list_for_each_entry(tmp, &poweroff_handler_list, list) {
> + if (tmp->priority > priority) {
> + priority = tmp->priority;
> + handler = tmp;
> + }
> + }
> +
> + if (handler) {
> + pr_debug("using poweroff handler %s\n", handler->name);
> + console_flush();
> + handler->poweroff(handler);
> + } else {
> + pr_err("No poweroff handler found!\n");
> + }
> +
> + hang();
> +}
> +
> +/**
> + * of_get_poweroff_priority() - get the desired poweroff priority from device tree
> + * @node: The device_node to read the property from
> + *
> + * return: The priority
> + */
> +unsigned int of_get_poweroff_priority(struct device_node *node)
> +{
> + unsigned int priority = POWEROFF_DEFAULT_PRIORITY;
> +
> + of_property_read_u32(node, "poweroff-priority", &priority);
> +
> + return priority;
> +}
> diff --git a/include/common.h b/include/common.h
> index 680a0affb..dd7445e9b 100644
> --- a/include/common.h
> +++ b/include/common.h
> @@ -66,9 +66,6 @@ int readline (const char *prompt, char *buf, int len);
> /* common/memsize.c */
> long get_ram_size (volatile long *, long);
>
> -/* $(CPU)/cpu.c */
> -void __noreturn poweroff(void);
> -
> /* common/console.c */
> int ctrlc (void);
>
> diff --git a/include/poweroff.h b/include/poweroff.h
> new file mode 100644
> index 000000000..ae9557db5
> --- /dev/null
> +++ b/include/poweroff.h
> @@ -0,0 +1,21 @@
> +#ifndef __INCLUDE_POWEROFF_H
> +#define __INCLUDE_POWEROFF_H
> +
> +void __noreturn poweroff_machine(void);
> +
> +struct poweroff_handler {
> + void (*poweroff)(struct poweroff_handler *);
> + int priority;
> + const char *name;
> + struct list_head list;
> +};
> +
> +int poweroff_handler_register(struct poweroff_handler *);
> +int poweroff_handler_register_fn(void (*poweroff_fn)(struct poweroff_handler *));
> +
> +#define POWEROFF_DEFAULT_PRIORITY 100
> +#define POWEROFF_DEFAULT_NAME "default"
> +
> +unsigned int of_get_poweroff_priority(struct device_node *node);
> +
> +#endif /* __INCLUDE_POWEROFF_H */
> --
> 2.11.0
>
>
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2017-03-14 7:18 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-13 11:05 [PATCH v2] poweroff: Allow to register poweroff handlers Oleksij Rempel
2017-03-14 7:17 ` Sascha Hauer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox