- Consolidate uncompress subroutines and s5p64x0-uncompress

- Cleanup watchdog support on Samsung to support multiplatform
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.11 (GNU/Linux)
 
 iQIcBAABAgAGBQJRwKUiAAoJEA0Cl+kVi2xqRMMP/j9Ml+uPgh1NNF/kYOaZB5kl
 oDaSTUK34TXIN2MCPGPf3Yck9dtt3P92kXpJPaSkqoc5ioY4h/nTEBFPxc6zcnh0
 xCg9+4m7NTzxSSfbxwVBSCZFcGto0lb9d8IzB38czXENMpKOKgfQ0X7KeFmXkOXY
 j2iJzAuAGkCt+qEpsGL+GoAdu+vMAScvD9Z5oT+IV0Jc9xFacgCArm8kOla5zPtt
 /I7li+D3QjKytft8Av6fmSICr+gs14IQuz+ZqaxiwDhMosyzzHarAOLZnE8oJCdt
 VAE6turEyI0c4uAKfJrBaq6m+NNOa1mAqyCRQsjHtt7YFpxXdjFcnMH6PrwyeVsr
 Z9XkrRwTJOdlVIzE1IpF55cptBCqZu33gRBfyfbztPn0X96CES3lSZOY780NUOH1
 4yTA3Bb1cCStXhusjdz/sRj8qhBsR5TT/LI9igVUQeW+07TTGkw44/5xJmB+VOM2
 fwdKplXWWrZV7oe8I8b8GR/AeZvCOGKLIrtqDD0D3bm8fPq/ByMif3PZ58weFKBV
 B6Ts6YwvRqhovXu2gvU0WQVnBjye8cOen2+Nlny5J+lML4C19qSOsgxy2WPN4PHC
 nEFYaM8CCQ7wf3bClZVX8Fg/SewG/A84vORhlAcV9C4Ezk/x3sGDmv7bsuUM+g+F
 ajLhIC1GZVkyX4qfYSxm
 =zkPJ
 -----END PGP SIGNATURE-----

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: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Arnd Bergmann 2013-06-20 16:51:39 +02:00
commit dc30f7c3ac
20 changed files with 174 additions and 248 deletions

View File

@ -729,6 +729,7 @@ config ARCH_S3C64XX
select SAMSUNG_CLKSRC
select SAMSUNG_GPIOLIB_4BIT
select SAMSUNG_IRQ_VIC_TIMER
select SAMSUNG_WDT_RESET
select USB_ARCH_HAS_OHCI
help
Samsung S3C64XX series based systems
@ -744,6 +745,7 @@ config ARCH_S5P64X0
select HAVE_S3C2410_WATCHDOG if WATCHDOG
select HAVE_S3C_RTC if RTC_CLASS
select NEED_MACH_GPIO_H
select SAMSUNG_WDT_RESET
help
Samsung S5P64X0 CPU based systems, such as the Samsung SMDK6440,
SMDK6450.
@ -760,6 +762,7 @@ config ARCH_S5PC100
select HAVE_S3C2410_WATCHDOG if WATCHDOG
select HAVE_S3C_RTC if RTC_CLASS
select NEED_MACH_GPIO_H
select SAMSUNG_WDT_RESET
help
Samsung S5PC100 series based systems

View File

@ -15,9 +15,6 @@
#include <asm/mach-types.h>
#include <mach/map.h>
volatile u8 *uart_base;
#include <plat/uncompress.h>
static unsigned int __raw_readl(unsigned int ptr)

View File

@ -31,6 +31,7 @@ config CPU_S3C2410
select S3C2410_CPUFREQ if CPU_FREQ_S3C24XX
select S3C2410_PM if PM
select SAMSUNG_HRT
select SAMSUNG_WDT_RESET
help
Support for S3C2410 and S3C2410A family from the S3C24XX line
of Samsung Mobile CPUs.
@ -81,6 +82,7 @@ config CPU_S3C2442
config CPU_S3C244X
def_bool y
depends on CPU_S3C2440 || CPU_S3C2442
select SAMSUNG_WDT_RESET
config CPU_S3C2443
bool "SAMSUNG S3C2443"

View File

@ -49,6 +49,9 @@ static void arch_detect_cpu(void)
fifo_mask = S3C2410_UFSTAT_TXMASK;
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 */

View File

@ -138,6 +138,7 @@ void __init s3c2410_init_clocks(int xtal)
s3c2410_baseclk_add();
s3c24xx_register_clock(&s3c2410_armclk);
clkdev_add_table(s3c2410_clk_lookup, ARRAY_SIZE(s3c2410_clk_lookup));
samsung_wdt_reset_init(S3C24XX_VA_WATCHDOG);
}
struct bus_type s3c2410_subsys = {
@ -201,7 +202,7 @@ void s3c2410_restart(char mode, const char *cmd)
soft_restart(0);
}
arch_wdt_reset();
samsung_wdt_reset();
/* we'll take a jump through zero as a poor second */
soft_restart(0);

View File

@ -133,6 +133,7 @@ void __init s3c244x_init_clocks(int xtal)
s3c24xx_register_baseclocks(xtal);
s3c244x_setup_clocks();
s3c2410_baseclk_add();
samsung_wdt_reset_init(S3C24XX_VA_WATCHDOG);
}
/* Since the S3C2442 and S3C2440 share items, put both subsystems here */
@ -202,7 +203,7 @@ void s3c244x_restart(char mode, const char *cmd)
if (mode == 's')
soft_restart(0);
arch_wdt_reset();
samsung_wdt_reset();
/* we'll take a jump through zero as a poor second */
soft_restart(0);

View File

@ -183,6 +183,12 @@ core_initcall(s3c64xx_dev_init);
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__);
/* initialise the pair of VICs */
@ -378,7 +384,7 @@ arch_initcall(s3c64xx_init_irq_eint);
void s3c64xx_restart(char mode, const char *cmd)
{
if (mode != 's')
arch_wdt_reset();
samsung_wdt_reset();
/* if all else fails, or mode was for soft, jump to 0 */
soft_restart(0);

View File

@ -23,6 +23,9 @@ static void arch_detect_cpu(void)
/* we do not need to do any cpu detection here at the moment. */
fifo_mask = S3C2440_UFSTAT_TXMASK;
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 */

View File

@ -173,6 +173,8 @@ void __init s5p64x0_init_io(struct map_desc *mach_desc, int size)
s5p_init_cpu(S5P64X0_SYS_ID);
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)
@ -440,7 +442,7 @@ arch_initcall(s5p64x0_init_irq_eint);
void s5p64x0_restart(char mode, const char *cmd)
{
if (mode != 's')
arch_wdt_reset();
samsung_wdt_reset();
soft_restart(0);
}

View File

@ -14,171 +14,21 @@
#define __ASM_ARCH_UNCOMPRESS_H
#include <mach/map.h>
#include <plat/uncompress.h>
/*
* 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)
static void arch_detect_cpu(void)
{
unsigned int chipid;
chipid = *(const volatile unsigned int __force *) 0xE0100118;
uart_base = S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT;
if ((chipid & 0xff000) == 0x50000)
uart_base += 0xEC800000;
uart_base = S5P6450_PA_UART(CONFIG_S3C_LOWLEVEL_UART_PORT);
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 */
uart_wr(S3C2410_UTXH, ch);
}
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. */
fifo_mask = S3C2440_UFSTAT_TXMASK;
fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT;
}
#endif /* __ASM_ARCH_UNCOMPRESS_H */

View File

@ -178,6 +178,7 @@ void __init s5pc100_init_clocks(int xtal)
s5p_register_clocks(xtal);
s5pc100_register_clocks();
s5pc100_setup_clocks();
samsung_wdt_reset_init(S3C_VA_WATCHDOG);
}
void __init s5pc100_init_irq(void)
@ -219,7 +220,7 @@ void __init s5pc100_init_uarts(struct s3c2410_uartcfg *cfg, int no)
void s5pc100_restart(char mode, const char *cmd)
{
if (mode != 's')
arch_wdt_reset();
samsung_wdt_reset();
soft_restart(0);
}

View File

@ -23,6 +23,8 @@ static void arch_detect_cpu(void)
/* we do not need to do any cpu detection here at the moment. */
fifo_mask = S3C2440_UFSTAT_TXMASK;
fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT;
uart_base = (volatile u8 *)S5P_PA_UART(CONFIG_S3C_LOWLEVEL_UART_PORT);
}
#endif /* __ASM_ARCH_UNCOMPRESS_H */

View File

@ -21,6 +21,8 @@ static void arch_detect_cpu(void)
/* we do not need to do any cpu detection here at the moment. */
fifo_mask = S5PV210_UFSTAT_TXMASK;
fifo_max = 63 << S5PV210_UFSTAT_TXSHIFT;
uart_base = (volatile u8 *)S5P_PA_UART(CONFIG_S3C_LOWLEVEL_UART_PORT);
}
#endif /* __ASM_ARCH_UNCOMPRESS_H */

View File

@ -475,6 +475,12 @@ config SAMSUNG_WAKEMASK
and above. This code allows a set of interrupt to wakeup-mask
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
bool
help

View File

@ -56,6 +56,7 @@ obj-$(CONFIG_PM) += pm-gpio.o
obj-$(CONFIG_SAMSUNG_PM_CHECK) += pm-check.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_SLEEP) += s5p-sleep.o

View File

@ -1,41 +0,0 @@
/* 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 */

View File

@ -21,6 +21,8 @@ typedef unsigned int upf_t; /* cannot include linux/serial_core.h */
unsigned int fifo_mask;
unsigned int fifo_max;
volatile u8 *uart_base;
/* forward declerations */
static void arch_detect_cpu(void);
@ -28,19 +30,24 @@ 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)))
#define S3C_WDOGREG(x) ((S3C_PA_WDT + (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 */
#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
uart_wr(unsigned int reg, unsigned int val)
{

View File

@ -10,37 +10,11 @@
* published by the Free Software Foundation.
*/
#include <plat/clock.h>
#include <plat/regs-watchdog.h>
#include <mach/map.h>
#ifndef __PLAT_SAMSUNG_WATCHDOG_RESET_H
#define __PLAT_SAMSUNG_WATCHDOG_RESET_H
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/delay.h>
extern void samsung_wdt_reset(void);
extern void samsung_wdt_reset_of_init(void);
extern void samsung_wdt_reset_init(void __iomem *base);
static inline void arch_wdt_reset(void)
{
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);
}
#endif /* __PLAT_SAMSUNG_WATCHDOG_RESET_H */

View File

@ -0,0 +1,97 @@
/* 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");
}

View File

@ -42,12 +42,21 @@
#include <linux/err.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 S3C_VA_WATCHDOG (0)
#define S3C2410_WTCON_RSTEN (1 << 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_DEFAULT_TIME (15)