From mboxrd@z Thu Jan 1 00:00:00 1970 Return-path: Received: from metis.ext.pengutronix.de ([2001:67c:670:201:290:27ff:fe1d:cc33]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1cngin-0000ic-IB for barebox@lists.infradead.org; Tue, 14 Mar 2017 07:18:20 +0000 Date: Tue, 14 Mar 2017 08:17:55 +0100 From: Sascha Hauer Message-ID: <20170314071755.vxwxfiiu4ihvolbq@pengutronix.de> References: <20170313110523.28408-1-o.rempel@pengutronix.de> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20170313110523.28408-1-o.rempel@pengutronix.de> List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "barebox" Errors-To: barebox-bounces+u.kleine-koenig=pengutronix.de@lists.infradead.org Subject: Re: [PATCH v2] poweroff: Allow to register poweroff handlers To: Oleksij Rempel Cc: barebox@lists.infradead.org On Mon, Mar 13, 2017 at 12:05:23PM +0100, Oleksij Rempel wrote: > From: Sascha Hauer > > 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 > Signed-off-by: Oleksij Rempel 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 > #include > #include > +#include > #include > #include > > @@ -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 > #include > +#include > #include > #include > > @@ -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 > #include > +#include > #include > #include > #include > @@ -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 > #include > +#include > #include > #include > #include > @@ -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 > #include > +#include > +#include > #include > > 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 > #include > +#include > > 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 , 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 > +#include > +#include > +#include > + > +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