Commit dc30f7c3 authored by Arnd Bergmann's avatar Arnd Bergmann

Merge tag 'samsung-cleanup-1' of...

Merge tag 'samsung-cleanup-1' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung into next/cleanup

From Kukjin Kim:

- Consolidate uncompress subroutines and s5p64x0-uncompress
- Cleanup watchdog support on Samsung to support multiplatform

* tag 'samsung-cleanup-1' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung:
  ARM: SAMSUNG: Remove unused plat/regs-watchdog.h header
  ARM: SAMSUNG: Remove legacy watchdog reset code
  ARM: SAMSUNG: Let platforms use the new watchdog reset driver
  ARM: SAMSUNG: Add watchdog reset driver
  ARM: SAMSUNG: Use local definitions of watchdog registers
  watchdog: s3c2410_wdt: Use local register definitions
  ARM: S5P64X0: Use common uncompress.h part for plat-samsung
  ARM: SAMSUNG: Consolidate uncompress subroutine
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents 3c373f99 db3824e6
...@@ -729,6 +729,7 @@ config ARCH_S3C64XX ...@@ -729,6 +729,7 @@ config ARCH_S3C64XX
select SAMSUNG_CLKSRC select SAMSUNG_CLKSRC
select SAMSUNG_GPIOLIB_4BIT select SAMSUNG_GPIOLIB_4BIT
select SAMSUNG_IRQ_VIC_TIMER select SAMSUNG_IRQ_VIC_TIMER
select SAMSUNG_WDT_RESET
select USB_ARCH_HAS_OHCI select USB_ARCH_HAS_OHCI
help help
Samsung S3C64XX series based systems Samsung S3C64XX series based systems
...@@ -744,6 +745,7 @@ config ARCH_S5P64X0 ...@@ -744,6 +745,7 @@ config ARCH_S5P64X0
select HAVE_S3C2410_WATCHDOG if WATCHDOG select HAVE_S3C2410_WATCHDOG if WATCHDOG
select HAVE_S3C_RTC if RTC_CLASS select HAVE_S3C_RTC if RTC_CLASS
select NEED_MACH_GPIO_H select NEED_MACH_GPIO_H
select SAMSUNG_WDT_RESET
help help
Samsung S5P64X0 CPU based systems, such as the Samsung SMDK6440, Samsung S5P64X0 CPU based systems, such as the Samsung SMDK6440,
SMDK6450. SMDK6450.
...@@ -760,6 +762,7 @@ config ARCH_S5PC100 ...@@ -760,6 +762,7 @@ config ARCH_S5PC100
select HAVE_S3C2410_WATCHDOG if WATCHDOG select HAVE_S3C2410_WATCHDOG if WATCHDOG
select HAVE_S3C_RTC if RTC_CLASS select HAVE_S3C_RTC if RTC_CLASS
select NEED_MACH_GPIO_H select NEED_MACH_GPIO_H
select SAMSUNG_WDT_RESET
help help
Samsung S5PC100 series based systems Samsung S5PC100 series based systems
......
...@@ -15,9 +15,6 @@ ...@@ -15,9 +15,6 @@
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <mach/map.h> #include <mach/map.h>
volatile u8 *uart_base;
#include <plat/uncompress.h> #include <plat/uncompress.h>
static unsigned int __raw_readl(unsigned int ptr) static unsigned int __raw_readl(unsigned int ptr)
......
...@@ -31,6 +31,7 @@ config CPU_S3C2410 ...@@ -31,6 +31,7 @@ config CPU_S3C2410
select S3C2410_CPUFREQ if CPU_FREQ_S3C24XX select S3C2410_CPUFREQ if CPU_FREQ_S3C24XX
select S3C2410_PM if PM select S3C2410_PM if PM
select SAMSUNG_HRT select SAMSUNG_HRT
select SAMSUNG_WDT_RESET
help help
Support for S3C2410 and S3C2410A family from the S3C24XX line Support for S3C2410 and S3C2410A family from the S3C24XX line
of Samsung Mobile CPUs. of Samsung Mobile CPUs.
...@@ -81,6 +82,7 @@ config CPU_S3C2442 ...@@ -81,6 +82,7 @@ config CPU_S3C2442
config CPU_S3C244X config CPU_S3C244X
def_bool y def_bool y
depends on CPU_S3C2440 || CPU_S3C2442 depends on CPU_S3C2440 || CPU_S3C2442
select SAMSUNG_WDT_RESET
config CPU_S3C2443 config CPU_S3C2443
bool "SAMSUNG S3C2443" bool "SAMSUNG S3C2443"
......
...@@ -49,6 +49,9 @@ static void arch_detect_cpu(void) ...@@ -49,6 +49,9 @@ static void arch_detect_cpu(void)
fifo_mask = S3C2410_UFSTAT_TXMASK; fifo_mask = S3C2410_UFSTAT_TXMASK;
fifo_max = 15 << S3C2410_UFSTAT_TXSHIFT; fifo_max = 15 << S3C2410_UFSTAT_TXSHIFT;
} }
uart_base = (volatile u8 *) S3C_PA_UART +
(S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT);
} }
#endif /* __ASM_ARCH_UNCOMPRESS_H */ #endif /* __ASM_ARCH_UNCOMPRESS_H */
...@@ -138,6 +138,7 @@ void __init s3c2410_init_clocks(int xtal) ...@@ -138,6 +138,7 @@ void __init s3c2410_init_clocks(int xtal)
s3c2410_baseclk_add(); s3c2410_baseclk_add();
s3c24xx_register_clock(&s3c2410_armclk); s3c24xx_register_clock(&s3c2410_armclk);
clkdev_add_table(s3c2410_clk_lookup, ARRAY_SIZE(s3c2410_clk_lookup)); clkdev_add_table(s3c2410_clk_lookup, ARRAY_SIZE(s3c2410_clk_lookup));
samsung_wdt_reset_init(S3C24XX_VA_WATCHDOG);
} }
struct bus_type s3c2410_subsys = { struct bus_type s3c2410_subsys = {
...@@ -201,7 +202,7 @@ void s3c2410_restart(char mode, const char *cmd) ...@@ -201,7 +202,7 @@ void s3c2410_restart(char mode, const char *cmd)
soft_restart(0); soft_restart(0);
} }
arch_wdt_reset(); samsung_wdt_reset();
/* we'll take a jump through zero as a poor second */ /* we'll take a jump through zero as a poor second */
soft_restart(0); soft_restart(0);
......
...@@ -133,6 +133,7 @@ void __init s3c244x_init_clocks(int xtal) ...@@ -133,6 +133,7 @@ void __init s3c244x_init_clocks(int xtal)
s3c24xx_register_baseclocks(xtal); s3c24xx_register_baseclocks(xtal);
s3c244x_setup_clocks(); s3c244x_setup_clocks();
s3c2410_baseclk_add(); s3c2410_baseclk_add();
samsung_wdt_reset_init(S3C24XX_VA_WATCHDOG);
} }
/* Since the S3C2442 and S3C2440 share items, put both subsystems here */ /* Since the S3C2442 and S3C2440 share items, put both subsystems here */
...@@ -202,7 +203,7 @@ void s3c244x_restart(char mode, const char *cmd) ...@@ -202,7 +203,7 @@ void s3c244x_restart(char mode, const char *cmd)
if (mode == 's') if (mode == 's')
soft_restart(0); soft_restart(0);
arch_wdt_reset(); samsung_wdt_reset();
/* we'll take a jump through zero as a poor second */ /* we'll take a jump through zero as a poor second */
soft_restart(0); soft_restart(0);
......
...@@ -183,6 +183,12 @@ core_initcall(s3c64xx_dev_init); ...@@ -183,6 +183,12 @@ core_initcall(s3c64xx_dev_init);
void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid) void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid)
{ {
/*
* FIXME: there is no better place to put this at the moment
* (samsung_wdt_reset_init needs clocks)
*/
samsung_wdt_reset_init(S3C_VA_WATCHDOG);
printk(KERN_DEBUG "%s: initialising interrupts\n", __func__); printk(KERN_DEBUG "%s: initialising interrupts\n", __func__);
/* initialise the pair of VICs */ /* initialise the pair of VICs */
...@@ -378,7 +384,7 @@ arch_initcall(s3c64xx_init_irq_eint); ...@@ -378,7 +384,7 @@ arch_initcall(s3c64xx_init_irq_eint);
void s3c64xx_restart(char mode, const char *cmd) void s3c64xx_restart(char mode, const char *cmd)
{ {
if (mode != 's') if (mode != 's')
arch_wdt_reset(); samsung_wdt_reset();
/* if all else fails, or mode was for soft, jump to 0 */ /* if all else fails, or mode was for soft, jump to 0 */
soft_restart(0); soft_restart(0);
......
...@@ -23,6 +23,9 @@ static void arch_detect_cpu(void) ...@@ -23,6 +23,9 @@ static void arch_detect_cpu(void)
/* we do not need to do any cpu detection here at the moment. */ /* we do not need to do any cpu detection here at the moment. */
fifo_mask = S3C2440_UFSTAT_TXMASK; fifo_mask = S3C2440_UFSTAT_TXMASK;
fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT; fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT;
uart_base = (volatile u8 *)S3C_PA_UART +
(S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT);
} }
#endif /* __ASM_ARCH_UNCOMPRESS_H */ #endif /* __ASM_ARCH_UNCOMPRESS_H */
...@@ -173,6 +173,8 @@ void __init s5p64x0_init_io(struct map_desc *mach_desc, int size) ...@@ -173,6 +173,8 @@ void __init s5p64x0_init_io(struct map_desc *mach_desc, int size)
s5p_init_cpu(S5P64X0_SYS_ID); s5p_init_cpu(S5P64X0_SYS_ID);
s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids)); s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
samsung_wdt_reset_init(S3C_VA_WATCHDOG);
} }
void __init s5p6440_map_io(void) void __init s5p6440_map_io(void)
...@@ -440,7 +442,7 @@ arch_initcall(s5p64x0_init_irq_eint); ...@@ -440,7 +442,7 @@ arch_initcall(s5p64x0_init_irq_eint);
void s5p64x0_restart(char mode, const char *cmd) void s5p64x0_restart(char mode, const char *cmd)
{ {
if (mode != 's') if (mode != 's')
arch_wdt_reset(); samsung_wdt_reset();
soft_restart(0); soft_restart(0);
} }
...@@ -14,171 +14,21 @@ ...@@ -14,171 +14,21 @@
#define __ASM_ARCH_UNCOMPRESS_H #define __ASM_ARCH_UNCOMPRESS_H
#include <mach/map.h> #include <mach/map.h>
#include <plat/uncompress.h>
/* static void arch_detect_cpu(void)
* cannot use commonly <plat/uncompress.h>
* because uart base of S5P6440 and S5P6450 is different
*/
typedef unsigned int upf_t; /* cannot include linux/serial_core.h */
/* uart setup */
unsigned int fifo_mask;
unsigned int fifo_max;
/* forward declerations */
static void arch_detect_cpu(void);
/* defines for UART registers */
#include <plat/regs-serial.h>
#include <plat/regs-watchdog.h>
/* working in physical space... */
#undef S3C2410_WDOGREG
#define S3C2410_WDOGREG(x) ((S3C24XX_PA_WATCHDOG + (x)))
/* how many bytes we allow into the FIFO at a time in FIFO mode */
#define FIFO_MAX (14)
unsigned long uart_base;
static __inline__ void get_uart_base(void)
{ {
unsigned int chipid; unsigned int chipid;
chipid = *(const volatile unsigned int __force *) 0xE0100118; chipid = *(const volatile unsigned int __force *) 0xE0100118;
uart_base = S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT;
if ((chipid & 0xff000) == 0x50000) if ((chipid & 0xff000) == 0x50000)
uart_base += 0xEC800000; uart_base = S5P6450_PA_UART(CONFIG_S3C_LOWLEVEL_UART_PORT);
else else
uart_base += 0xEC000000; uart_base = S5P6440_PA_UART(CONFIG_S3C_LOWLEVEL_UART_PORT);
}
static __inline__ void uart_wr(unsigned int reg, unsigned int val)
{
volatile unsigned int *ptr;
get_uart_base();
ptr = (volatile unsigned int *)(reg + uart_base);
*ptr = val;
}
static __inline__ unsigned int uart_rd(unsigned int reg)
{
volatile unsigned int *ptr;
get_uart_base();
ptr = (volatile unsigned int *)(reg + uart_base);
return *ptr;
}
/*
* we can deal with the case the UARTs are being run
* in FIFO mode, so that we don't hold up our execution
* waiting for tx to happen...
*/
static void putc(int ch)
{
if (uart_rd(S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE) {
int level;
while (1) {
level = uart_rd(S3C2410_UFSTAT);
level &= fifo_mask;
if (level < fifo_max)
break;
}
} else {
/* not using fifos */
while ((uart_rd(S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE) != S3C2410_UTRSTAT_TXE)
barrier();
}
/* write byte to transmission register */ fifo_mask = S3C2440_UFSTAT_TXMASK;
uart_wr(S3C2410_UTXH, ch); fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT;
}
static inline void flush(void)
{
}
#define __raw_writel(d, ad) \
do { \
*((volatile unsigned int __force *)(ad)) = (d); \
} while (0)
#ifdef CONFIG_S3C_BOOT_ERROR_RESET
static void arch_decomp_error(const char *x)
{
putstr("\n\n");
putstr(x);
putstr("\n\n -- System resetting\n");
__raw_writel(0x4000, S3C2410_WTDAT);
__raw_writel(0x4000, S3C2410_WTCNT);
__raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x40), S3C2410_WTCON);
while(1);
}
#define arch_error arch_decomp_error
#endif
#ifdef CONFIG_S3C_BOOT_UART_FORCE_FIFO
static inline void arch_enable_uart_fifo(void)
{
u32 fifocon = uart_rd(S3C2410_UFCON);
if (!(fifocon & S3C2410_UFCON_FIFOMODE)) {
fifocon |= S3C2410_UFCON_RESETBOTH;
uart_wr(S3C2410_UFCON, fifocon);
/* wait for fifo reset to complete */
while (1) {
fifocon = uart_rd(S3C2410_UFCON);
if (!(fifocon & S3C2410_UFCON_RESETBOTH))
break;
}
}
}
#else
#define arch_enable_uart_fifo() do { } while(0)
#endif
static void arch_decomp_setup(void)
{
/*
* we may need to setup the uart(s) here if we are not running
* on an BAST... the BAST will have left the uarts configured
* after calling linux.
*/
arch_detect_cpu();
/*
* Enable the UART FIFOs if they where not enabled and our
* configuration says we should turn them on.
*/
arch_enable_uart_fifo();
}
static void arch_detect_cpu(void)
{
/* we do not need to do any cpu detection here at the moment. */
} }
#endif /* __ASM_ARCH_UNCOMPRESS_H */ #endif /* __ASM_ARCH_UNCOMPRESS_H */
...@@ -178,6 +178,7 @@ void __init s5pc100_init_clocks(int xtal) ...@@ -178,6 +178,7 @@ void __init s5pc100_init_clocks(int xtal)
s5p_register_clocks(xtal); s5p_register_clocks(xtal);
s5pc100_register_clocks(); s5pc100_register_clocks();
s5pc100_setup_clocks(); s5pc100_setup_clocks();
samsung_wdt_reset_init(S3C_VA_WATCHDOG);
} }
void __init s5pc100_init_irq(void) void __init s5pc100_init_irq(void)
...@@ -219,7 +220,7 @@ void __init s5pc100_init_uarts(struct s3c2410_uartcfg *cfg, int no) ...@@ -219,7 +220,7 @@ void __init s5pc100_init_uarts(struct s3c2410_uartcfg *cfg, int no)
void s5pc100_restart(char mode, const char *cmd) void s5pc100_restart(char mode, const char *cmd)
{ {
if (mode != 's') if (mode != 's')
arch_wdt_reset(); samsung_wdt_reset();
soft_restart(0); soft_restart(0);
} }
...@@ -23,6 +23,8 @@ static void arch_detect_cpu(void) ...@@ -23,6 +23,8 @@ static void arch_detect_cpu(void)
/* we do not need to do any cpu detection here at the moment. */ /* we do not need to do any cpu detection here at the moment. */
fifo_mask = S3C2440_UFSTAT_TXMASK; fifo_mask = S3C2440_UFSTAT_TXMASK;
fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT; fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT;
uart_base = (volatile u8 *)S5P_PA_UART(CONFIG_S3C_LOWLEVEL_UART_PORT);
} }
#endif /* __ASM_ARCH_UNCOMPRESS_H */ #endif /* __ASM_ARCH_UNCOMPRESS_H */
...@@ -21,6 +21,8 @@ static void arch_detect_cpu(void) ...@@ -21,6 +21,8 @@ static void arch_detect_cpu(void)
/* we do not need to do any cpu detection here at the moment. */ /* we do not need to do any cpu detection here at the moment. */
fifo_mask = S5PV210_UFSTAT_TXMASK; fifo_mask = S5PV210_UFSTAT_TXMASK;
fifo_max = 63 << S5PV210_UFSTAT_TXSHIFT; fifo_max = 63 << S5PV210_UFSTAT_TXSHIFT;
uart_base = (volatile u8 *)S5P_PA_UART(CONFIG_S3C_LOWLEVEL_UART_PORT);
} }
#endif /* __ASM_ARCH_UNCOMPRESS_H */ #endif /* __ASM_ARCH_UNCOMPRESS_H */
...@@ -475,6 +475,12 @@ config SAMSUNG_WAKEMASK ...@@ -475,6 +475,12 @@ config SAMSUNG_WAKEMASK
and above. This code allows a set of interrupt to wakeup-mask and above. This code allows a set of interrupt to wakeup-mask
mappings. See <plat/wakeup-mask.h> mappings. See <plat/wakeup-mask.h>
config SAMSUNG_WDT_RESET
bool
help
Compile support for system restart by triggering watchdog reset.
Used on SoCs that do not provide dedicated reset control.
config S5P_PM config S5P_PM
bool bool
help help
......
...@@ -56,6 +56,7 @@ obj-$(CONFIG_PM) += pm-gpio.o ...@@ -56,6 +56,7 @@ obj-$(CONFIG_PM) += pm-gpio.o
obj-$(CONFIG_SAMSUNG_PM_CHECK) += pm-check.o obj-$(CONFIG_SAMSUNG_PM_CHECK) += pm-check.o
obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o
obj-$(CONFIG_SAMSUNG_WDT_RESET) += watchdog-reset.o
obj-$(CONFIG_S5P_PM) += s5p-pm.o s5p-irq-pm.o obj-$(CONFIG_S5P_PM) += s5p-pm.o s5p-irq-pm.o
obj-$(CONFIG_S5P_SLEEP) += s5p-sleep.o obj-$(CONFIG_S5P_SLEEP) += s5p-sleep.o
/* arch/arm/mach-s3c2410/include/mach/regs-watchdog.h
*
* Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
* http://www.simtec.co.uk/products/SWLINUX/
*
* 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.
*
* S3C2410 Watchdog timer control
*/
#ifndef __ASM_ARCH_REGS_WATCHDOG_H
#define __ASM_ARCH_REGS_WATCHDOG_H
#define S3C_WDOGREG(x) ((x) + S3C_VA_WATCHDOG)
#define S3C2410_WTCON S3C_WDOGREG(0x00)
#define S3C2410_WTDAT S3C_WDOGREG(0x04)
#define S3C2410_WTCNT S3C_WDOGREG(0x08)
/* the watchdog can either generate a reset pulse, or an
* interrupt.
*/
#define S3C2410_WTCON_RSTEN (0x01)
#define S3C2410_WTCON_INTEN (1<<2)
#define S3C2410_WTCON_ENABLE (1<<5)
#define S3C2410_WTCON_DIV16 (0<<3)
#define S3C2410_WTCON_DIV32 (1<<3)
#define S3C2410_WTCON_DIV64 (2<<3)
#define S3C2410_WTCON_DIV128 (3<<3)
#define S3C2410_WTCON_PRESCALE(x) ((x) << 8)
#define S3C2410_WTCON_PRESCALE_MASK (0xff00)
#endif /* __ASM_ARCH_REGS_WATCHDOG_H */
...@@ -21,6 +21,8 @@ typedef unsigned int upf_t; /* cannot include linux/serial_core.h */ ...@@ -21,6 +21,8 @@ typedef unsigned int upf_t; /* cannot include linux/serial_core.h */
unsigned int fifo_mask; unsigned int fifo_mask;
unsigned int fifo_max; unsigned int fifo_max;
volatile u8 *uart_base;
/* forward declerations */ /* forward declerations */
static void arch_detect_cpu(void); static void arch_detect_cpu(void);
...@@ -28,19 +30,24 @@ static void arch_detect_cpu(void); ...@@ -28,19 +30,24 @@ static void arch_detect_cpu(void);
/* defines for UART registers */ /* defines for UART registers */
#include <plat/regs-serial.h> #include <plat/regs-serial.h>
#include <plat/regs-watchdog.h>
/* working in physical space... */ /* working in physical space... */
#undef S3C2410_WDOGREG #define S3C_WDOGREG(x) ((S3C_PA_WDT + (x)))
#define S3C2410_WDOGREG(x) ((S3C24XX_PA_WATCHDOG + (x)))
#define S3C2410_WTCON S3C_WDOGREG(0x00)
#define S3C2410_WTDAT S3C_WDOGREG(0x04)
#define S3C2410_WTCNT S3C_WDOGREG(0x08)
#define S3C2410_WTCON_RSTEN (1 << 0)
#define S3C2410_WTCON_ENABLE (1 << 5)
#define S3C2410_WTCON_DIV128 (3 << 3)
#define S3C2410_WTCON_PRESCALE(x) ((x) << 8)
/* how many bytes we allow into the FIFO at a time in FIFO mode */ /* how many bytes we allow into the FIFO at a time in FIFO mode */
#define FIFO_MAX (14) #define FIFO_MAX (14)
#ifdef S3C_PA_UART
#define uart_base S3C_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT)
#endif
static __inline__ void static __inline__ void
uart_wr(unsigned int reg, unsigned int val) uart_wr(unsigned int reg, unsigned int val)
{ {
......
...@@ -10,37 +10,11 @@ ...@@ -10,37 +10,11 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#include <plat/clock.h> #ifndef __PLAT_SAMSUNG_WATCHDOG_RESET_H
#include <plat/regs-watchdog.h> #define __PLAT_SAMSUNG_WATCHDOG_RESET_H
#include <mach/map.h>
#include <linux/clk.h> extern void samsung_wdt_reset(void);
#include <linux/err.h> extern void samsung_wdt_reset_of_init(void);
#include <linux/io.h> extern void samsung_wdt_reset_init(void __iomem *base);
#include <linux/delay.h>
static inline void arch_wdt_reset(void) #endif /* __PLAT_SAMSUNG_WATCHDOG_RESET_H */
{
printk("arch_reset: attempting watchdog reset\n");
__raw_writel(0, S3C2410_WTCON); /* disable watchdog, to be safe */
if (!IS_ERR(s3c2410_wdtclk))
clk_enable(s3c2410_wdtclk);
/* put initial values into count and data */
__raw_writel(0x80, S3C2410_WTCNT);
__raw_writel(0x80, S3C2410_WTDAT);
/* set the watchdog to go and reset... */
__raw_writel(S3C2410_WTCON_ENABLE|S3C2410_WTCON_DIV16|S3C2410_WTCON_RSTEN |
S3C2410_WTCON_PRESCALE(0x20), S3C2410_WTCON);
/* wait for reset to assert... */
mdelay(500);
printk(KERN_ERR "Watchdog reset failed to assert reset\n");
/* delay to allow the serial port to show the message */
mdelay(50);
}
/* arch/arm/plat-samsung/watchdog-reset.c
*
* Copyright (c) 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* Coyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
*
* Watchdog reset support for Samsung SoCs.
*
* 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.
*/
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/of.h>
#include <linux/of_address.h>
#define S3C2410_WTCON 0x00
#define S3C2410_WTDAT 0x04
#define S3C2410_WTCNT 0x08
#define S3C2410_WTCON_ENABLE (1 << 5)
#define S3C2410_WTCON_DIV16 (0 << 3)
#define S3C2410_WTCON_RSTEN (1 << 0)
#define S3C2410_WTCON_PRESCALE(x) ((x) << 8)
static void __iomem *wdt_base;
static struct clk *wdt_clock;
void samsung_wdt_reset(void)
{
if (!wdt_base) {
pr_err("%s: wdt reset not initialized\n", __func__);
/* delay to allow the serial port to show the message */
mdelay(50);
return;
}
if (!IS_ERR(wdt_clock))
clk_prepare_enable(wdt_clock);
/* disable watchdog, to be safe */
__raw_writel(0, wdt_base + S3C2410_WTCON);
/* put initial values into count and data */
__raw_writel(0x80, wdt_base + S3C2410_WTCNT);
__raw_writel(0x80, wdt_base + S3C2410_WTDAT);
/* set the watchdog to go and reset... */
__raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV16 |
S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x20),
wdt_base + S3C2410_WTCON);
/* wait for reset to assert... */
mdelay(500);
pr_err("Watchdog reset failed to assert reset\n");
/* delay to allow the serial port to show the message */
mdelay(50);
}
#ifdef CONFIG_OF
static const struct of_device_id s3c2410_wdt_match[] = {
{ .compatible = "samsung,s3c2410-wdt" },
{},
};
void __init samsung_wdt_reset_of_init(void)
{
struct device_node *np;
np = of_find_matching_node(NULL, s3c2410_wdt_match);
if (!np) {
pr_err("%s: failed to find watchdog node\n", __func__);
return;
}
wdt_base = of_iomap(np, 0);
if (!wdt_base) {
pr_err("%s: failed to map watchdog registers\n", __func__);
return;
}
wdt_clock = of_clk_get(np, 0);
}
#endif
void __init samsung_wdt_reset_init(void __iomem *base)
{
wdt_base = base;
wdt_clock = clk_get(NULL, "watchdog");
}
...@@ -42,12 +42,21 @@ ...@@ -42,12 +42,21 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/of.h> #include <linux/of.h>
#include <mach/map.h> #define S3C2410_WTCON 0x00
#define S3C2410_WTDAT 0x04
#define S3C2410_WTCNT 0x08
#undef S3C_VA_WATCHDOG #define S3C2410_WTCON_RSTEN (1 << 0)
#define S3C_VA_WATCHDOG (0) #define S3C2410_WTCON_INTEN (1 << 2)
#define S3C2410_WTCON_ENABLE (1 << 5)
#include <plat/regs-watchdog.h> #define S3C2410_WTCON_DIV16 (0 << 3)
#define S3C2410_WTCON_DIV32 (1 << 3)
#define S3C2410_WTCON_DIV64 (2 << 3)
#define S3C2410_WTCON_DIV128 (3 << 3)
#define S3C2410_WTCON_PRESCALE(x) ((x) << 8)
#define S3C2410_WTCON_PRESCALE_MASK (0xff << 8)
#define CONFIG_S3C2410_WATCHDOG_ATBOOT (0) #define CONFIG_S3C2410_WATCHDOG_ATBOOT (0)
#define CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME (15) #define CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME (15)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment