From: Sascha Hauer <s.hauer@pengutronix.de>
To: Juergen Borleis <jbe@pengutronix.de>
Cc: barebox@lists.infradead.org
Subject: Re: [PATCH 1/5] Reset reason: add a scope value to the reset reason feature
Date: Wed, 24 Jun 2015 08:32:47 +0200 [thread overview]
Message-ID: <20150624063247.GR6325@pengutronix.de> (raw)
In-Reply-To: <1435064284-8015-2-git-send-email-jbe@pengutronix.de>
On Tue, Jun 23, 2015 at 02:58:00PM +0200, Juergen Borleis wrote:
> Some systems do have more than one source to detect the reason of a reset.
> In this case it depends on the initialization order which reason will be
> reported to barebox. To avoid this race, this change adds a scope to the
> function call to always accept settings with a wider scope and ignore
> all settings with a limited scope.
>
> This change is required to support systems where one reset reason source
> is more reliable than other sources. Examples are all i.MX SoCs with
> an internal reset reason detector and an external PMIC which has the same
> capabilities. For these systems the external PMIC provides the correct
> reset cause while the internal unit flags a POR only all the time. In order
> to support one binary for more than one machine we cannot just disable the
> internal reset reason detector, so we need this scope mechanism.
>
> Assumption in this change is, the reset cause sources with a wider scope are
> always reporting the correct reason and not vice versa.
>
> Signed-off-by: Juergen Borleis <jbe@pengutronix.de>
> ---
> Documentation/user/reset-reason.rst | 30 ++++++++++++++
> Documentation/user/system-reset.rst | 3 +-
> arch/arm/mach-imx/imx1.c | 8 ++--
> arch/arm/mach-omap/am33xx_generic.c | 14 +++----
> arch/arm/mach-pxa/pxa2xx.c | 12 +++---
> arch/arm/mach-pxa/pxa3xx.c | 12 +++---
> arch/arm/mach-samsung/reset_source.c | 8 ++--
> arch/arm/mach-tegra/tegra20-pmc.c | 14 +++----
> common/Kconfig | 8 ----
> common/Makefile | 2 +-
> common/reset_source.c | 56 ---------------------------
> common/restart.c | 73 +++++++++++++++++++++++++++++++++++
> drivers/watchdog/im28wd.c | 12 +++---
> drivers/watchdog/imxwd.c | 8 ++--
> include/{reset_source.h => restart.h} | 29 +++++++-------
> 15 files changed, 164 insertions(+), 125 deletions(-)
> delete mode 100644 common/reset_source.c
> create mode 100644 common/restart.c
> rename include/{reset_source.h => restart.h} (71%)
>
> diff --git a/Documentation/user/reset-reason.rst b/Documentation/user/reset-reason.rst
> index a4872fa..525ade2 100644
> --- a/Documentation/user/reset-reason.rst
> +++ b/Documentation/user/reset-reason.rst
> @@ -3,6 +3,9 @@
> Reset Reason
> ------------
>
> +Using the Reset Reason
> +~~~~~~~~~~~~~~~~~~~~~~
> +
> To handle a device in a secure and safty manner many applications are using
> a watchdog or other ways to reset a system to bring it back into life if it
> hangs or crashes somehow.
> @@ -45,3 +48,30 @@ The following values can help to detect the reason why the bootloader runs:
> It depends on your board/SoC and its features if the hardware is able to detect
> these reset reasons. Most of the time only ``POR`` and ``RST`` are supported
> but often ``WDG`` as well.
> +
> +.. _reset_reason_scope:
> +
> +Scope of Reset Reason
> +~~~~~~~~~~~~~~~~~~~~~
> +
> +Some machines can detect the reset reason via different devices, for example
> +via a SoC internal devices and an externally attached device. Both can provide
> +the correct reason - or not. If their reset reason point of view differ, you
> +need a ``scope`` to decide what reason is the correct one. Barebox provides
> +the reset reason scope via the global variable ``system.reset.scope`` and
> +the following values:
> +
> +* ``unknown``: the software can't define the scope of the reset reason.
> +* ``cpu``: the inner core CPU only point of view.
> +* ``soc``: the full SoC point of view.
> +* ``machine``: the full machine point of view
> +
> +The scopes are rated: lowest rate is ``unknown`` and ``cpu``. The highest
> +rate has the ``machine`` point of view. The ``soc`` point of view in inbetween.
> +
> +Why can the reset reason differ due to different scopes? Think about a SoC which
> +is powered by a PMIC: the reset reason detection inside the SoC has the ``soc``
> +scope, the PMIC's reset reason detection has the ``machine`` scope. In this case
> +the ``soc`` scope reset reason is always ``POR``, while the ``machine`` scope
> +reset reason is ``POR`` only on a real POR, ``RST`` due to an user
> +intervention and ``WDG`` because the system has failed somehow.
> diff --git a/Documentation/user/system-reset.rst b/Documentation/user/system-reset.rst
> index e76e3a2..e902026 100644
> --- a/Documentation/user/system-reset.rst
> +++ b/Documentation/user/system-reset.rst
> @@ -61,4 +61,5 @@ wide reset, like the POR is.
> Drawback of the PMIC solution is, you can't use the SoC's internal mechanisms to
> detect the :ref:`reset_reason` anymore. From the SoC point of view it is always
> a POR when the PMIC handles the system reset. If you are in luck the PMIC
> -instead can provide this information if you depend on it.
> +instead can provide this information if you depend on it. Refer
> +:ref:`reset_reason_scope` for further information.
> diff --git a/arch/arm/mach-imx/imx1.c b/arch/arm/mach-imx/imx1.c
> index 51bdcbf..a3759df 100644
> --- a/arch/arm/mach-imx/imx1.c
> +++ b/arch/arm/mach-imx/imx1.c
> @@ -18,7 +18,7 @@
> #include <mach/weim.h>
> #include <mach/iomux-v1.h>
> #include <mach/generic.h>
> -#include <reset_source.h>
> +#include <restart.h>
>
> #define MX1_RSR MX1_SCM_BASE_ADDR
> #define RSR_EXR (1 << 0)
> @@ -30,13 +30,13 @@ static void imx1_detect_reset_source(void)
>
> switch (val) {
> case RSR_EXR:
> - reset_source_set(RESET_RST);
> + reset_source_set(RESET_RST, FEATURE_SCOPE_SOC);
> return;
> case RSR_WDR:
> - reset_source_set(RESET_WDG);
> + reset_source_set(RESET_WDG, FEATURE_SCOPE_SOC);
> return;
> case 0:
> - reset_source_set(RESET_POR);
> + reset_source_set(RESET_POR, FEATURE_SCOPE_SOC);
> return;
> default:
> /* else keep the default 'unknown' state */
> diff --git a/arch/arm/mach-omap/am33xx_generic.c b/arch/arm/mach-omap/am33xx_generic.c
> index 7ce32f0..8ac1290 100644
> --- a/arch/arm/mach-omap/am33xx_generic.c
> +++ b/arch/arm/mach-omap/am33xx_generic.c
> @@ -26,7 +26,7 @@
> #include <mach/sys_info.h>
> #include <mach/am33xx-generic.h>
> #include <mach/gpmc.h>
> -#include <reset_source.h>
> +#include <restart.h>
>
> void __noreturn am33xx_reset_cpu(unsigned long addr)
> {
> @@ -167,23 +167,23 @@ static void am33xx_detect_reset_reason(void)
>
> switch (val) {
> case (1 << 9):
> - reset_source_set(RESET_JTAG);
> + reset_source_set(RESET_JTAG, FEATURE_SCOPE_SOC);
> break;
> case (1 << 5):
> - reset_source_set(RESET_EXT);
> + reset_source_set(RESET_EXT, FEATURE_SCOPE_SOC);
> break;
> case (1 << 4):
> case (1 << 3):
> - reset_source_set(RESET_WDG);
> + reset_source_set(RESET_WDG, FEATURE_SCOPE_SOC);
> break;
> case (1 << 1):
> - reset_source_set(RESET_RST);
> + reset_source_set(RESET_RST, FEATURE_SCOPE_SOC);
> break;
> case (1 << 0):
> - reset_source_set(RESET_POR);
> + reset_source_set(RESET_POR, FEATURE_SCOPE_SOC);
> break;
> default:
> - reset_source_set(RESET_UKWN);
> + reset_source_set(RESET_UKWN, FEATURE_SCOPE_SOC);
> break;
> }
> }
> diff --git a/arch/arm/mach-pxa/pxa2xx.c b/arch/arm/mach-pxa/pxa2xx.c
> index b712b38..973e394 100644
> --- a/arch/arm/mach-pxa/pxa2xx.c
> +++ b/arch/arm/mach-pxa/pxa2xx.c
> @@ -14,7 +14,7 @@
>
> #include <common.h>
> #include <init.h>
> -#include <reset_source.h>
> +#include <restart.h>
> #include <mach/hardware.h>
> #include <mach/pxa-regs.h>
>
> @@ -28,15 +28,15 @@ static int pxa_detect_reset_source(void)
> * Order is important, as many bits can be set together
> */
> if (reg & RCSR_GPR)
> - reset_source_set(RESET_RST);
> + reset_source_set(RESET_RST, FEATURE_SCOPE_SOC);
> else if (reg & RCSR_WDR)
> - reset_source_set(RESET_WDG);
> + reset_source_set(RESET_WDG, FEATURE_SCOPE_SOC);
> else if (reg & RCSR_HWR)
> - reset_source_set(RESET_POR);
> + reset_source_set(RESET_POR, FEATURE_SCOPE_SOC);
> else if (reg & RCSR_SMR)
> - reset_source_set(RESET_WKE);
> + reset_source_set(RESET_WKE, FEATURE_SCOPE_SOC);
> else
> - reset_source_set(RESET_UKWN);
> + reset_source_set(RESET_UKWN, FEATURE_SCOPE_SOC);
>
> return 0;
> }
> diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
> index 86ca63b..e273996 100644
> --- a/arch/arm/mach-pxa/pxa3xx.c
> +++ b/arch/arm/mach-pxa/pxa3xx.c
> @@ -14,7 +14,7 @@
>
> #include <common.h>
> #include <init.h>
> -#include <reset_source.h>
> +#include <restart.h>
> #include <mach/hardware.h>
> #include <mach/pxa-regs.h>
>
> @@ -28,15 +28,15 @@ static int pxa_detect_reset_source(void)
> * Order is important, as many bits can be set together
> */
> if (reg & ARSR_GPR)
> - reset_source_set(RESET_RST);
> + reset_source_set(RESET_RST, FEATURE_SCOPE_SOC);
> else if (reg & ARSR_WDT)
> - reset_source_set(RESET_WDG);
> + reset_source_set(RESET_WDG, FEATURE_SCOPE_SOC);
> else if (reg & ARSR_HWR)
> - reset_source_set(RESET_POR);
> + reset_source_set(RESET_POR, FEATURE_SCOPE_SOC);
> else if (reg & ARSR_LPMR)
> - reset_source_set(RESET_WKE);
> + reset_source_set(RESET_WKE, FEATURE_SCOPE_SOC);
> else
> - reset_source_set(RESET_UKWN);
> + reset_source_set(RESET_UKWN, FEATURE_SCOPE_SOC);
>
> return 0;
> }
> diff --git a/arch/arm/mach-samsung/reset_source.c b/arch/arm/mach-samsung/reset_source.c
> index c1365b2..e122909 100644
> --- a/arch/arm/mach-samsung/reset_source.c
> +++ b/arch/arm/mach-samsung/reset_source.c
> @@ -15,7 +15,7 @@
> #include <common.h>
> #include <init.h>
> #include <io.h>
> -#include <reset_source.h>
> +#include <restart.h>
> #include <mach/s3c-iomap.h>
>
> /* S3C2440 relevant */
> @@ -29,21 +29,21 @@ static int s3c_detect_reset_source(void)
> u32 reg = readl(S3C_GPIO_BASE + S3C2440_GSTATUS2);
>
> if (reg & S3C2440_GSTATUS2_PWRST) {
> - reset_source_set(RESET_POR);
> + reset_source_set(RESET_POR, FEATURE_SCOPE_SOC);
> writel(S3C2440_GSTATUS2_PWRST,
> S3C_GPIO_BASE + S3C2440_GSTATUS2);
> return 0;
> }
>
> if (reg & S3C2440_GSTATUS2_SLEEPRST) {
> - reset_source_set(RESET_WKE);
> + reset_source_set(RESET_WKE, FEATURE_SCOPE_SOC);
> writel(S3C2440_GSTATUS2_SLEEPRST,
> S3C_GPIO_BASE + S3C2440_GSTATUS2);
> return 0;
> }
>
> if (reg & S3C2440_GSTATUS2_WDRST) {
> - reset_source_set(RESET_WDG);
> + reset_source_set(RESET_WDG, FEATURE_SCOPE_SOC);
> writel(S3C2440_GSTATUS2_WDRST,
> S3C_GPIO_BASE + S3C2440_GSTATUS2);
> return 0;
> diff --git a/arch/arm/mach-tegra/tegra20-pmc.c b/arch/arm/mach-tegra/tegra20-pmc.c
> index eaa5ac7..6493eea 100644
> --- a/arch/arm/mach-tegra/tegra20-pmc.c
> +++ b/arch/arm/mach-tegra/tegra20-pmc.c
> @@ -28,7 +28,7 @@
> #include <linux/reset.h>
> #include <mach/lowlevel.h>
> #include <mach/tegra-powergate.h>
> -#include <reset_source.h>
> +#include <restart.h>
>
> #include <mach/tegra20-pmc.h>
>
> @@ -180,22 +180,22 @@ static void tegra20_pmc_detect_reset_cause(void)
> switch ((reg & PMC_RST_STATUS_RST_SRC_MASK) >>
> PMC_RST_STATUS_RST_SRC_SHIFT) {
> case PMC_RST_STATUS_RST_SRC_POR:
> - reset_source_set(RESET_POR);
> + reset_source_set(RESET_POR, FEATURE_SCOPE_SOC);
> break;
> case PMC_RST_STATUS_RST_SRC_WATCHDOG:
> - reset_source_set(RESET_WDG);
> + reset_source_set(RESET_WDG, FEATURE_SCOPE_SOC);
> break;
> case PMC_RST_STATUS_RST_SRC_LP0:
> - reset_source_set(RESET_WKE);
> + reset_source_set(RESET_WKE, FEATURE_SCOPE_SOC);
> break;
> case PMC_RST_STATUS_RST_SRC_SW_MAIN:
> - reset_source_set(RESET_RST);
> + reset_source_set(RESET_RST, FEATURE_SCOPE_SOC);
> break;
> case PMC_RST_STATUS_RST_SRC_SENSOR:
> - reset_source_set(RESET_THERM);
> + reset_source_set(RESET_THERM, FEATURE_SCOPE_SOC);
> break;
> default:
> - reset_source_set(RESET_UKWN);
> + reset_source_set(RESET_UKWN, FEATURE_SCOPE_SOC);
> break;
> }
> }
> diff --git a/common/Kconfig b/common/Kconfig
> index 3dfb5ac..f241482 100644
> --- a/common/Kconfig
> +++ b/common/Kconfig
> @@ -716,14 +716,6 @@ config STATE
> select OFTREE
> select PARAMETER
>
> -config RESET_SOURCE
> - bool "detect Reset cause"
> - depends on GLOBALVAR
> - help
> - Provide a global variable at runtine which reflects the possible cause
> - of the reset and why the bootloader is currently running. It can be
> - useful for any kind of system recovery or repair.
> -
> endmenu
>
> menu "Debugging"
> diff --git a/common/Makefile b/common/Makefile
> index 2738238..16e6690 100644
> --- a/common/Makefile
> +++ b/common/Makefile
> @@ -8,6 +8,7 @@ obj-y += misc.o
> obj-y += memsize.o
> obj-y += resource.o
> obj-y += bootsource.o
> +obj-y += restart.o
> obj-$(CONFIG_AUTO_COMPLETE) += complete.o
> obj-$(CONFIG_BANNER) += version.o
> obj-$(CONFIG_BAREBOX_UPDATE) += bbu.o
> @@ -40,7 +41,6 @@ obj-$(CONFIG_OFTREE) += oftree.o
> obj-$(CONFIG_PARTITION_DISK) += partitions.o partitions/
> obj-$(CONFIG_PASSWORD) += password.o
> obj-$(CONFIG_POLLER) += poller.o
> -obj-$(CONFIG_RESET_SOURCE) += reset_source.o
> obj-$(CONFIG_SHELL_HUSH) += hush.o
> obj-$(CONFIG_SHELL_SIMPLE) += parser.o
> obj-$(CONFIG_STATE) += state.o
> diff --git a/common/reset_source.c b/common/reset_source.c
> deleted file mode 100644
> index 80002a9..0000000
> --- a/common/reset_source.c
> +++ /dev/null
> @@ -1,56 +0,0 @@
> -/*
> - * (C) Copyright 2012 Juergen Beisert - <kernel@pengutronix.de>
> - *
> - * 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 <common.h>
> -#include <init.h>
> -#include <environment.h>
> -#include <globalvar.h>
> -#include <reset_source.h>
> -
> -static const char * const reset_src_names[] = {
> - [RESET_UKWN] = "unknown",
> - [RESET_POR] = "POR",
> - [RESET_RST] = "RST",
> - [RESET_WDG] = "WDG",
> - [RESET_WKE] = "WKE",
> - [RESET_JTAG] = "JTAG",
> - [RESET_THERM] = "THERM",
> - [RESET_EXT] = "EXT",
> -};
> -
> -static enum reset_src_type reset_source;
> -
> -enum reset_src_type reset_source_get(void)
> -{
> - return reset_source;
> -}
> -EXPORT_SYMBOL(reset_source_get);
> -
> -void reset_source_set(enum reset_src_type st)
> -{
> - reset_source = st;
> -
> - globalvar_add_simple("system.reset", reset_src_names[reset_source]);
> -}
> -EXPORT_SYMBOL(reset_source_set);
> -
> -/* ensure this runs after the 'global' device is already registerd */
> -static int reset_source_init(void)
> -{
> - reset_source_set(reset_source);
> -
> - return 0;
> -}
> -
> -coredevice_initcall(reset_source_init);
> diff --git a/common/restart.c b/common/restart.c
> new file mode 100644
> index 0000000..f73a9da
> --- /dev/null
> +++ b/common/restart.c
> @@ -0,0 +1,73 @@
> +/*
> + * (C) Copyright 2015 Juergen Borleis - <kernel@pengutronix.de>
> + *
> + * 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 <common.h>
> +#include <init.h>
> +#include <restart.h>
> +#include <globalvar.h>
> +
> +static const char * const scope_names[] = {
> + [FEATURE_SCOPE_UNKNOWN] = "unknown",
> + [FEATURE_SCOPE_CPU] = "cpu",
> + [FEATURE_SCOPE_SOC] = "soc",
> + [FEATURE_SCOPE_MACHINE] = "machine",
> +};
> +
> +static const char * const reset_src_names[] = {
> + [RESET_UKWN] = "unknown",
> + [RESET_POR] = "POR",
> + [RESET_RST] = "RST",
> + [RESET_WDG] = "WDG",
> + [RESET_WKE] = "WKE",
> + [RESET_JTAG] = "JTAG",
> + [RESET_THERM] = "THERM",
> + [RESET_EXT] = "EXT",
> +};
> +
> +/* handle reset cause detection feature */
> +
> +static int reset_source;
> +static int reset_source_scope;
> +
> +enum reset_src_type reset_source_get(void)
> +{
> + return reset_source;
> +}
> +EXPORT_SYMBOL(reset_source_get);
> +
> +static void reset_source_update_global_info(void)
> +{
> + globalvar_add_simple_enum("system.reset", &reset_source, reset_src_names,
> + ARRAY_SIZE(reset_src_names));
> + globalvar_add_simple_enum("system.reset.scope", &reset_source_scope,
> + scope_names, ARRAY_SIZE(scope_names));
> +}
> +
> +void reset_source_set(enum reset_src_type st, enum f_scope scope)
> +{
> + if ((int)scope <= reset_source_scope)
> + return; /* just ignore this setting */
> +
> + reset_source = (int)st;
> + reset_source_scope = (int)scope;
> + reset_source_update_global_info();
This call is unnecessary. You can call globalvar_add_simple_enum()
directly from the initcall.
Sascha
--
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
next prev parent reply other threads:[~2015-06-24 6:33 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-06-23 12:57 [PATCHv2] Change barebox regarding "machine-restart", "reset cause detection" und "watchdog usage" Juergen Borleis
2015-06-23 12:58 ` [PATCH 1/5] Reset reason: add a scope value to the reset reason feature Juergen Borleis
2015-06-24 6:32 ` Sascha Hauer [this message]
2015-06-24 7:35 ` Juergen Borleis
2015-06-23 12:58 ` [PATCH 2/5] System restart: add a scope value to the system restart feature Juergen Borleis
2015-06-24 6:42 ` Sascha Hauer
2015-06-23 12:58 ` [PATCH 3/5] Watchdog: add a scope value to the watchdog feature Juergen Borleis
2015-06-24 6:51 ` Sascha Hauer
2015-06-23 12:58 ` [PATCH 4/5] Watchdog/i.MX: make the watchdog driver a regular driver Juergen Borleis
2015-06-23 12:58 ` [PATCH 5/5] MFD/DA9053: da9053: add basic da9053 driver Juergen Borleis
2015-06-25 7:34 [PATCHv3] Change barebox regarding "machine-restart", "reset cause detection" und "watchdog usage" Juergen Borleis
2015-06-25 7:34 ` [PATCH 1/5] Reset reason: add a scope value to the reset reason feature Juergen Borleis
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150624063247.GR6325@pengutronix.de \
--to=s.hauer@pengutronix.de \
--cc=barebox@lists.infradead.org \
--cc=jbe@pengutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox