aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorWolfgang Denk <wd@denx.de>2010-06-29 21:37:44 +0200
committerWolfgang Denk <wd@denx.de>2010-06-29 21:37:44 +0200
commit8515f081e4d5e1f22ee7d12ae72e3bf22eb88a76 (patch)
tree4f737fd4b4204b96acb35d969f343a56782ecefa /arch
parent953b7e629198fe2eb0adf272fb9140f2a4a51826 (diff)
parent754613f740368f847a2261c5c41b034ff5c51b1c (diff)
Merge branch 'master' of git://git.denx.de/u-boot-sh into next
Diffstat (limited to 'arch')
-rw-r--r--arch/sh/cpu/sh2/watchdog.c8
-rw-r--r--arch/sh/cpu/sh3/watchdog.c7
-rw-r--r--arch/sh/cpu/sh4/watchdog.c4
-rw-r--r--arch/sh/include/asm/system.h12
-rw-r--r--arch/sh/lib/time.c20
5 files changed, 46 insertions, 5 deletions
diff --git a/arch/sh/cpu/sh2/watchdog.c b/arch/sh/cpu/sh2/watchdog.c
index de0254b44..0257d8d15 100644
--- a/arch/sh/cpu/sh2/watchdog.c
+++ b/arch/sh/cpu/sh2/watchdog.c
@@ -1,6 +1,6 @@
/*
- * Copyright (C) 2008 Nobuhiro Iwamatsu <iwamatsu.nobuhoro@renesas.com>
- * Copyright (C) 2008 Renesas Solutions Corp.
+ * Copyright (C) 2008,2010 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
+ * Copyright (C) 2008,2010 Renesas Solutions Corp.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -20,6 +20,7 @@
#include <common.h>
#include <asm/processor.h>
+#include <asm/system.h>
int watchdog_init(void)
{
@@ -28,6 +29,9 @@ int watchdog_init(void)
void reset_cpu(unsigned long ignored)
{
+ /* Address error with SR.BL=1 first. */
+ trigger_address_error();
+
while (1)
;
}
diff --git a/arch/sh/cpu/sh3/watchdog.c b/arch/sh/cpu/sh3/watchdog.c
index 92bea7471..90694f866 100644
--- a/arch/sh/cpu/sh3/watchdog.c
+++ b/arch/sh/cpu/sh3/watchdog.c
@@ -1,4 +1,7 @@
/*
+ * (C) Copyright 2010
+ * Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
+ *
* (C) Copyright 2007
* Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
*
@@ -20,6 +23,7 @@
#include <common.h>
#include <asm/processor.h>
+#include <asm/system.h>
int watchdog_init(void)
{
@@ -28,6 +32,9 @@ int watchdog_init(void)
void reset_cpu(unsigned long ignored)
{
+ /* Address error with SR.BL=1 first. */
+ trigger_address_error();
+
while (1)
;
}
diff --git a/arch/sh/cpu/sh4/watchdog.c b/arch/sh/cpu/sh4/watchdog.c
index f6924290f..d7e1703e6 100644
--- a/arch/sh/cpu/sh4/watchdog.c
+++ b/arch/sh/cpu/sh4/watchdog.c
@@ -17,6 +17,7 @@
#include <common.h>
#include <asm/processor.h>
+#include <asm/system.h>
#include <asm/io.h>
#define WDT_BASE WTCNT
@@ -66,6 +67,9 @@ int watchdog_disable(void)
void reset_cpu(unsigned long ignored)
{
+ /* Address error with SR.BL=1 first. */
+ trigger_address_error();
+
while (1)
;
}
diff --git a/arch/sh/include/asm/system.h b/arch/sh/include/asm/system.h
index a62c42261..56fd77ace 100644
--- a/arch/sh/include/asm/system.h
+++ b/arch/sh/include/asm/system.h
@@ -8,7 +8,7 @@
* from linux kernel code.
*/
-#include <linux/irqflags.h>
+#include <asm/irqflags.h>
#include <asm/types.h>
/*
@@ -272,4 +272,14 @@ void enable_hlt(void);
#define arch_align_stack(x) (x)
+static inline void trigger_address_error(void)
+{
+ __asm__ __volatile__ (
+ "ldc %0, sr\n\t"
+ "mov.l @%1, %0"
+ :
+ : "r" (0x10000000), "r" (0x80000001)
+ );
+}
+
#endif
diff --git a/arch/sh/lib/time.c b/arch/sh/lib/time.c
index 9a8f89aef..bc1656f73 100644
--- a/arch/sh/lib/time.c
+++ b/arch/sh/lib/time.c
@@ -2,7 +2,7 @@
* (C) Copyright 2009
* Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
*
- * (C) Copyright 2007-2008
+ * (C) Copyright 2007-2010
* Nobobuhiro Iwamatsu <iwamatsu@nigauri.org>
*
* (C) Copyright 2003
@@ -36,6 +36,8 @@
#define TMU_MAX_COUNTER (~0UL)
static ulong timer_freq;
+static unsigned long last_tcnt;
+static unsigned long long overflow_ticks;
static inline unsigned long long tick_to_time(unsigned long long tick)
{
@@ -97,12 +99,26 @@ int timer_init (void)
tmu_timer_stop(0);
tmu_timer_start(0);
+ last_tcnt = 0;
+ overflow_ticks = 0;
+
return 0;
}
unsigned long long get_ticks (void)
{
- return 0 - readl(TCNT0);
+ unsigned long tcnt = 0 - readl(TCNT0);
+ unsigned long ticks;
+
+ if (last_tcnt > tcnt) { /* overflow */
+ overflow_ticks++;
+ ticks = (0xffffffff - last_tcnt) + tcnt;
+ } else {
+ ticks = tcnt;
+ }
+ last_tcnt = tcnt;
+
+ return (overflow_ticks << 32) | tcnt;
}
void __udelay (unsigned long usec)