Message ID | 1485511145-31425-2-git-send-email-p.pisati@gmail.com |
---|---|
State | Changes Requested |
Delegated to: | Tom Rini |
Headers | show |
On Freitag, 27. Januar 2017 10:59:05 CET Paolo Pisati wrote: > Signed-off-by: Paolo Pisati <p.pisati@gmail.com> > --- > arch/arm/mach-bcm283x/reset.c | 21 ++++++++++++++++++--- > board/raspberrypi/rpi/rpi.c | 4 ++++ > drivers/watchdog/Makefile | 1 + > drivers/watchdog/bcm2835_wdt.c | 34 ++++++++++++++++++++++++++++++++++ > include/configs/rpi.h | 3 +++ > scripts/config_whitelist.txt | 1 + > 6 files changed, 61 insertions(+), 3 deletions(-) > create mode 100644 drivers/watchdog/bcm2835_wdt.c > > diff --git a/arch/arm/mach-bcm283x/reset.c b/arch/arm/mach-bcm283x/reset.c > index 685815c..b62cb8a 100644 > --- a/arch/arm/mach-bcm283x/reset.c > +++ b/arch/arm/mach-bcm283x/reset.c > @@ -21,18 +21,33 @@ > */ > #define BCM2835_WDOG_RSTS_RASPBERRYPI_HALT 0x555 > > +/* max ticks timeout */ > +#define BCM2835_WDOG_MAX_TIMEOUT 0x000fffff > + > +#ifdef CONFIG_BCM2835_WDT > +extern void hw_watchdog_disable(void); > +#else > +void hw_watchdog_disable(void) {} > +#endif > + > __efi_runtime_data struct bcm2835_wdog_regs *wdog_regs = > (struct bcm2835_wdog_regs *)BCM2835_WDOG_PHYSADDR; > > -void __efi_runtime reset_cpu(ulong addr) > +void __efi_runtime reset_cpu(ulong ticks) > { > - uint32_t rstc; > + uint32_t rstc, timeout; > + > + if (ticks == 0) { > + hw_watchdog_disable(); > + timeout = RESET_TIMEOUT; This is wrong. The efi runtime reset function calls this as reset_cpu(0), and then tries to call hw_watchdog_disable, which is not marked as __efi_runtime. Actually, I can see no reason the watchdog setup piggybacks on the reset_cpu funtion. > + } else > + timeout = ticks & BCM2835_WDOG_MAX_TIMEOUT; > > rstc = readl(&wdog_regs->rstc); > rstc &= ~BCM2835_WDOG_RSTC_WRCFG_MASK; > rstc |= BCM2835_WDOG_RSTC_WRCFG_FULL_RESET; > > - writel(BCM2835_WDOG_PASSWORD | RESET_TIMEOUT, &wdog_regs->wdog); > + writel(BCM2835_WDOG_PASSWORD | timeout, &wdog_regs->wdog); > writel(BCM2835_WDOG_PASSWORD | rstc, &wdog_regs->rstc); > } > > diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c > index 22e87a2..106e518 100644 > --- a/board/raspberrypi/rpi/rpi.c > +++ b/board/raspberrypi/rpi/rpi.c [...] > --- a/scripts/config_whitelist.txt > +++ b/scripts/config_whitelist.txt > @@ -294,6 +294,7 @@ CONFIG_BCH_CONST_M > CONFIG_BCH_CONST_PARAMS > CONFIG_BCH_CONST_T > CONFIG_BCM2835_GPIO > +CONFIG_BCM2835_WDT > CONFIG_BCM283X_MU_SERIAL > CONFIG_BCM_SF2_ETH > CONFIG_BCM_SF2_ETH_DEFAULT_PORT I think the rule is no new CONFIG_xxx options, but appropriate options in KConfig. Kind regards, Stefan
On Fri, Jan 27, 2017 at 04:20:10PM +0000, Brüns, Stefan wrote: > > ... > > + > > __efi_runtime_data struct bcm2835_wdog_regs *wdog_regs = > > (struct bcm2835_wdog_regs *)BCM2835_WDOG_PHYSADDR; > > > > -void __efi_runtime reset_cpu(ulong addr) > > +void __efi_runtime reset_cpu(ulong ticks) > > { > > - uint32_t rstc; > > + uint32_t rstc, timeout; > > + > > + if (ticks == 0) { > > + hw_watchdog_disable(); > > + timeout = RESET_TIMEOUT; > > This is wrong. The efi runtime reset function calls this as reset_cpu(0), and > then tries to call hw_watchdog_disable, which is not marked as __efi_runtime. Ok. > Actually, I can see no reason the watchdog setup piggybacks on the reset_cpu > funtion. Because there's a window after reset_cpu() is called but before real reset happens, and if hw_watchdog_reset() is called in between, it breaks the reset procedure. There must be a mechanism for reset_cpu() to disable the watchdog driver so it won't interfere. > > I think the rule is no new CONFIG_xxx options, but appropriate options in > KConfig. I'll send a V2.
diff --git a/arch/arm/mach-bcm283x/reset.c b/arch/arm/mach-bcm283x/reset.c index 685815c..b62cb8a 100644 --- a/arch/arm/mach-bcm283x/reset.c +++ b/arch/arm/mach-bcm283x/reset.c @@ -21,18 +21,33 @@ */ #define BCM2835_WDOG_RSTS_RASPBERRYPI_HALT 0x555 +/* max ticks timeout */ +#define BCM2835_WDOG_MAX_TIMEOUT 0x000fffff + +#ifdef CONFIG_BCM2835_WDT +extern void hw_watchdog_disable(void); +#else +void hw_watchdog_disable(void) {} +#endif + __efi_runtime_data struct bcm2835_wdog_regs *wdog_regs = (struct bcm2835_wdog_regs *)BCM2835_WDOG_PHYSADDR; -void __efi_runtime reset_cpu(ulong addr) +void __efi_runtime reset_cpu(ulong ticks) { - uint32_t rstc; + uint32_t rstc, timeout; + + if (ticks == 0) { + hw_watchdog_disable(); + timeout = RESET_TIMEOUT; + } else + timeout = ticks & BCM2835_WDOG_MAX_TIMEOUT; rstc = readl(&wdog_regs->rstc); rstc &= ~BCM2835_WDOG_RSTC_WRCFG_MASK; rstc |= BCM2835_WDOG_RSTC_WRCFG_FULL_RESET; - writel(BCM2835_WDOG_PASSWORD | RESET_TIMEOUT, &wdog_regs->wdog); + writel(BCM2835_WDOG_PASSWORD | timeout, &wdog_regs->wdog); writel(BCM2835_WDOG_PASSWORD | rstc, &wdog_regs->rstc); } diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c index 22e87a2..106e518 100644 --- a/board/raspberrypi/rpi/rpi.c +++ b/board/raspberrypi/rpi/rpi.c @@ -22,6 +22,7 @@ #ifdef CONFIG_ARM64 #include <asm/armv8/mmu.h> #endif +#include <watchdog.h> DECLARE_GLOBAL_DATA_PTR; @@ -478,6 +479,9 @@ static void rpi_disable_inactive_uart(void) int board_init(void) { +#ifdef CONFIG_HW_WATCHDOG + hw_watchdog_init(); +#endif #ifndef CONFIG_PL01X_SERIAL rpi_disable_inactive_uart(); #endif diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index a007ae8..3b328ec 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -15,3 +15,4 @@ obj-$(CONFIG_XILINX_TB_WATCHDOG) += xilinx_tb_wdt.o obj-$(CONFIG_BFIN_WATCHDOG) += bfin_wdt.o obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o obj-$(CONFIG_DESIGNWARE_WATCHDOG) += designware_wdt.o +obj-$(CONFIG_BCM2835_WDT) += bcm2835_wdt.o diff --git a/drivers/watchdog/bcm2835_wdt.c b/drivers/watchdog/bcm2835_wdt.c new file mode 100644 index 0000000..c76b164 --- /dev/null +++ b/drivers/watchdog/bcm2835_wdt.c @@ -0,0 +1,34 @@ +/* + * Watchdog driver for Broadcom BCM2835 + * + * Copyright (C) 2017 Paolo Pisati <p.pisati@gmail.com> + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/wdog.h> + +#define SECS_TO_WDOG_TICKS(x) ((x) << 16) +#define MAX_TIMEOUT 0xf /* ~15s */ + +bool enabled = true; + +extern void reset_cpu(ulong ticks); + +void hw_watchdog_reset(void) +{ + if (enabled) + reset_cpu(SECS_TO_WDOG_TICKS(MAX_TIMEOUT)); +} + +void hw_watchdog_init(void) +{ + hw_watchdog_reset(); +} + +void hw_watchdog_disable(void) +{ + enabled = false; +} diff --git a/include/configs/rpi.h b/include/configs/rpi.h index 45d8824..c34c84b 100644 --- a/include/configs/rpi.h +++ b/include/configs/rpi.h @@ -107,6 +107,9 @@ #define CONFIG_CONS_INDEX 0 #define CONFIG_BAUDRATE 115200 +/* Watchdog support */ +#define CONFIG_BCM2835_WDT + /* Console configuration */ #define CONFIG_SYS_CBSIZE 1024 #define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index 00ee3f1..eb6cb8a 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -294,6 +294,7 @@ CONFIG_BCH_CONST_M CONFIG_BCH_CONST_PARAMS CONFIG_BCH_CONST_T CONFIG_BCM2835_GPIO +CONFIG_BCM2835_WDT CONFIG_BCM283X_MU_SERIAL CONFIG_BCM_SF2_ETH CONFIG_BCM_SF2_ETH_DEFAULT_PORT
Signed-off-by: Paolo Pisati <p.pisati@gmail.com> --- arch/arm/mach-bcm283x/reset.c | 21 ++++++++++++++++++--- board/raspberrypi/rpi/rpi.c | 4 ++++ drivers/watchdog/Makefile | 1 + drivers/watchdog/bcm2835_wdt.c | 34 ++++++++++++++++++++++++++++++++++ include/configs/rpi.h | 3 +++ scripts/config_whitelist.txt | 1 + 6 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 drivers/watchdog/bcm2835_wdt.c