Merge branch 'for-next/reset-source'
This commit is contained in:
commit
2935411dea
|
@ -1,4 +1,5 @@
|
||||||
obj-y += clocksource.o gpio.o
|
obj-y += clocksource.o gpio.o
|
||||||
|
obj-$(CONFIG_RESET_SOURCE) += reset_source.o
|
||||||
obj-$(CONFIG_ARCH_IMX1) += speed-imx1.o imx1.o iomux-v1.o
|
obj-$(CONFIG_ARCH_IMX1) += speed-imx1.o imx1.o iomux-v1.o
|
||||||
obj-$(CONFIG_ARCH_IMX25) += speed-imx25.o imx25.o iomux-v3.o
|
obj-$(CONFIG_ARCH_IMX25) += speed-imx25.o imx25.o iomux-v3.o
|
||||||
obj-$(CONFIG_ARCH_IMX21) += speed-imx21.o imx21.o iomux-v1.o
|
obj-$(CONFIG_ARCH_IMX21) += speed-imx21.o imx21.o iomux-v1.o
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* (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 <io.h>
|
||||||
|
#include <reset_source.h>
|
||||||
|
#include <mach/imx-regs.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARCH_IMX1
|
||||||
|
# define IMX_RESET_SRC_WDOG (1 << 1)
|
||||||
|
# define IMX_RESET_SRC_HRDRESET (1 << 0)
|
||||||
|
/* let the compiler sort out useless code on this arch */
|
||||||
|
# define IMX_RESET_SRC_WARMSTART 0
|
||||||
|
# define IMX_RESET_SRC_COLDSTART 0
|
||||||
|
#else
|
||||||
|
/* WRSR checked for i.MX25, i.MX27, i.MX31, i.MX35 and i.MX51 */
|
||||||
|
# define WDOG_WRSR 0x04
|
||||||
|
/* valid for i.MX25, i.MX27, i.MX31, i.MX35, i.MX51 */
|
||||||
|
# define IMX_RESET_SRC_WARMSTART (1 << 0)
|
||||||
|
/* valid for i.MX25, i.MX27, i.MX31, i.MX35, i.MX51 */
|
||||||
|
# define IMX_RESET_SRC_WDOG (1 << 1)
|
||||||
|
/* valid for i.MX27, i.MX31, always '0' on i.MX25, i.MX35, i.MX51 */
|
||||||
|
# define IMX_RESET_SRC_HRDRESET (1 << 3)
|
||||||
|
/* valid for i.MX27, i.MX31, always '0' on i.MX25, i.MX35, i.MX51 */
|
||||||
|
# define IMX_RESET_SRC_COLDSTART (1 << 4)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static unsigned read_detection_register(void)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_ARCH_IMX1
|
||||||
|
return readl(IMX_SYSCTRL_BASE);
|
||||||
|
#else
|
||||||
|
return readw(IMX_WDT_BASE + WDOG_WRSR);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static int imx_detect_reset_source(void)
|
||||||
|
{
|
||||||
|
unsigned reg = read_detection_register();
|
||||||
|
|
||||||
|
if (reg & IMX_RESET_SRC_COLDSTART) {
|
||||||
|
set_reset_source(RESET_POR);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reg & (IMX_RESET_SRC_HRDRESET | IMX_RESET_SRC_WARMSTART)) {
|
||||||
|
set_reset_source(RESET_RST);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reg & IMX_RESET_SRC_WDOG) {
|
||||||
|
set_reset_source(RESET_WDG);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* else keep the default 'unknown' state */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
device_initcall(imx_detect_reset_source);
|
|
@ -1,4 +1,5 @@
|
||||||
obj-y += s3c-timer.o generic.o
|
obj-y += s3c-timer.o generic.o
|
||||||
|
obj-$(CONFIG_RESET_SOURCE) += reset_source.o
|
||||||
obj-lowlevel-$(CONFIG_ARCH_S3C24xx) += lowlevel-s3c24x0.o
|
obj-lowlevel-$(CONFIG_ARCH_S3C24xx) += lowlevel-s3c24x0.o
|
||||||
obj-lowlevel-$(CONFIG_ARCH_S5PCxx) += lowlevel-s5pcxx.o
|
obj-lowlevel-$(CONFIG_ARCH_S5PCxx) += lowlevel-s5pcxx.o
|
||||||
obj-$(CONFIG_ARCH_S3C24xx) += gpio-s3c24x0.o s3c24xx-clocks.o mem-s3c24x0.o
|
obj-$(CONFIG_ARCH_S3C24xx) += gpio-s3c24x0.o s3c24xx-clocks.o mem-s3c24x0.o
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* (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 <io.h>
|
||||||
|
#include <reset_source.h>
|
||||||
|
#include <mach/s3c-iomap.h>
|
||||||
|
|
||||||
|
/* S3C2440 relevant */
|
||||||
|
#define S3C2440_GSTATUS2 0xb4
|
||||||
|
# define S3C2440_GSTATUS2_PWRST (1 << 0)
|
||||||
|
# define S3C2440_GSTATUS2_SLEEPRST (1 << 1)
|
||||||
|
# define S3C2440_GSTATUS2_WDRST (1 << 2)
|
||||||
|
|
||||||
|
static int s3c_detect_reset_source(void)
|
||||||
|
{
|
||||||
|
u32 reg = readl(S3C_GPIO_BASE + S3C2440_GSTATUS2);
|
||||||
|
|
||||||
|
if (reg & S3C2440_GSTATUS2_PWRST) {
|
||||||
|
set_reset_source(RESET_POR);
|
||||||
|
writel(S3C2440_GSTATUS2_PWRST,
|
||||||
|
S3C_GPIO_BASE + S3C2440_GSTATUS2);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reg & S3C2440_GSTATUS2_SLEEPRST) {
|
||||||
|
set_reset_source(RESET_WKE);
|
||||||
|
writel(S3C2440_GSTATUS2_SLEEPRST,
|
||||||
|
S3C_GPIO_BASE + S3C2440_GSTATUS2);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reg & S3C2440_GSTATUS2_WDRST) {
|
||||||
|
set_reset_source(RESET_WDG);
|
||||||
|
writel(S3C2440_GSTATUS2_WDRST,
|
||||||
|
S3C_GPIO_BASE + S3C2440_GSTATUS2);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* else keep the default 'unknown' state */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
device_initcall(s3c_detect_reset_source);
|
|
@ -559,6 +559,14 @@ config BAREBOXENV_TARGET
|
||||||
config POLLER
|
config POLLER
|
||||||
bool "generic polling infrastructure"
|
bool "generic polling infrastructure"
|
||||||
|
|
||||||
|
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
|
endmenu
|
||||||
|
|
||||||
menu "Debugging "
|
menu "Debugging "
|
||||||
|
|
|
@ -30,6 +30,7 @@ obj-y += startup.o
|
||||||
obj-y += misc.o
|
obj-y += misc.o
|
||||||
obj-y += memsize.o
|
obj-y += memsize.o
|
||||||
obj-$(CONFIG_GLOBALVAR) += globalvar.o
|
obj-$(CONFIG_GLOBALVAR) += globalvar.o
|
||||||
|
obj-$(CONFIG_RESET_SOURCE) += reset_source.o
|
||||||
obj-$(CONFIG_FILETYPE) += filetype.o
|
obj-$(CONFIG_FILETYPE) += filetype.o
|
||||||
obj-y += resource.o
|
obj-y += resource.o
|
||||||
obj-$(CONFIG_MENU) += menu.o
|
obj-$(CONFIG_MENU) += menu.o
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* (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",
|
||||||
|
};
|
||||||
|
|
||||||
|
void set_reset_source(enum reset_src_type st)
|
||||||
|
{
|
||||||
|
setenv("global.system.reset", reset_src_names[st]);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(set_reset_source);
|
||||||
|
|
||||||
|
/* ensure this runs after the 'global' device is already registerd */
|
||||||
|
static int init_reset_source(void)
|
||||||
|
{
|
||||||
|
globalvar_add_simple("system.reset");
|
||||||
|
set_reset_source(RESET_UKWN);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
coredevice_initcall(init_reset_source);
|
|
@ -21,6 +21,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <watchdog.h>
|
#include <watchdog.h>
|
||||||
|
#include <reset_source.h>
|
||||||
|
|
||||||
#define MXS_RTC_CTRL 0x0
|
#define MXS_RTC_CTRL 0x0
|
||||||
#define MXS_RTC_SET_ADDR 0x4
|
#define MXS_RTC_SET_ADDR 0x4
|
||||||
|
@ -73,6 +74,27 @@ static int imx28_watchdog_set_timeout(struct watchdog *wd, unsigned timeout)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __maybe_unused imx28_detect_reset_source(const struct imx28_wd *p)
|
||||||
|
{
|
||||||
|
u32 reg;
|
||||||
|
|
||||||
|
reg = readl(p->regs + MXS_RTC_PERSISTENT0);
|
||||||
|
if (reg & MXS_RTC_PERSISTENT0_EXT_RST) {
|
||||||
|
writel(MXS_RTC_PERSISTENT0_EXT_RST,
|
||||||
|
p->regs + MXS_RTC_PERSISTENT0 + MXS_RTC_CLR_ADDR);
|
||||||
|
set_reset_source(RESET_POR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (reg & MXS_RTC_PERSISTENT0_THM_RST) {
|
||||||
|
writel(MXS_RTC_PERSISTENT0_THM_RST,
|
||||||
|
p->regs + MXS_RTC_PERSISTENT0 + MXS_RTC_CLR_ADDR);
|
||||||
|
set_reset_source(RESET_RST);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_reset_source(RESET_RST);
|
||||||
|
}
|
||||||
|
|
||||||
static int imx28_wd_probe(struct device_d *dev)
|
static int imx28_wd_probe(struct device_d *dev)
|
||||||
{
|
{
|
||||||
struct imx28_wd *priv;
|
struct imx28_wd *priv;
|
||||||
|
@ -94,6 +116,9 @@ static int imx28_wd_probe(struct device_d *dev)
|
||||||
if (rc != 0)
|
if (rc != 0)
|
||||||
goto on_error;
|
goto on_error;
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_RESET_SOURCE))
|
||||||
|
imx28_detect_reset_source(priv);
|
||||||
|
|
||||||
dev->priv = priv;
|
dev->priv = priv;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __INCLUDE_RESET_SOURCE_H
|
||||||
|
# define __INCLUDE_RESET_SOURCE_H
|
||||||
|
|
||||||
|
enum reset_src_type {
|
||||||
|
RESET_UKWN, /* maybe the SoC cannot detect the reset source */
|
||||||
|
RESET_POR, /* Power On Reset (cold start) */
|
||||||
|
RESET_RST, /* generic ReSeT (warm start) */
|
||||||
|
RESET_WDG, /* watchdog */
|
||||||
|
RESET_WKE, /* wake-up (some SoCs can handle this) */
|
||||||
|
RESET_JTAG, /* JTAG reset */
|
||||||
|
};
|
||||||
|
|
||||||
|
void set_reset_source(enum reset_src_type);
|
||||||
|
|
||||||
|
#endif /* __INCLUDE_RESET_SOURCE_H */
|
Loading…
Reference in New Issue