Commit 3eb90bad authored by Ingo van Lil's avatar Ingo van Lil Committed by Wolfgang Denk

Generic udelay() with watchdog support

According to the PPC reference implementation the udelay() function is
responsible for resetting the watchdog timer as frequently as needed.
Most other architectures do not meet that requirement, so long-running
operations might result in a watchdog reset.

This patch adds a generic udelay() function which takes care of
resetting the watchdog before calling an architecture-specific
__udelay().
Signed-off-by: default avatarIngo van Lil <inguin@gmx.de>
parent 1c409bc7
......@@ -124,7 +124,7 @@ void set_timer (ulong ticks)
}
/* delay usec useconds */
void udelay (unsigned long usec)
void __udelay (unsigned long usec)
{
ulong tmo, tmp;
......
......@@ -72,7 +72,7 @@ static long fixed_sdram(void)
* Erratum DDR3 requires a 50ms delay after clearing DDRCDR[DDR_cfg],
* or the DDR2 controller may fail to initialize correctly.
*/
udelay(50000);
__udelay(50000);
im->ddr.csbnds[0].csbnds = (msize - 1) >> 24;
im->ddr.cs_config[0] = CONFIG_SYS_DDR_CONFIG;
......
......@@ -152,7 +152,7 @@ void set_timer (ulong t)
}
/* delay x useconds AND perserve advance timstamp value */
void udelay (unsigned long usec)
void __udelay (unsigned long usec)
{
unsigned long long tmp;
ulong tmo;
......
......@@ -74,7 +74,7 @@ void set_timer (ulong t)
}
/* delay x useconds AND perserve advance timstamp value */
void udelay (unsigned long usec)
void __udelay (unsigned long usec)
{
ulong tmo, tmp;
......
......@@ -164,7 +164,7 @@ void set_timer(ulong t)
timestamp = t * (timer_load_val / (100 * CONFIG_SYS_HZ));
}
void udelay(unsigned long usec)
void __udelay(unsigned long usec)
{
unsigned long long tmp;
ulong tmo;
......
......@@ -224,7 +224,7 @@ void set_timer (ulong t)
timestamp = t;
}
void udelay (unsigned long usec)
void __udelay (unsigned long usec)
{
ulong tmo;
......@@ -296,7 +296,7 @@ ulong get_timer (ulong base)
return timestamp - base;
}
void udelay (unsigned long usec)
void __udelay (unsigned long usec)
{
u32 ticks;
......
......@@ -87,7 +87,7 @@ void set_timer (ulong t)
timestamp = t;
}
void udelay (unsigned long usec)
void __udelay (unsigned long usec)
{
udelay_masked(usec);
}
......
......@@ -89,7 +89,7 @@ void udelay_masked (unsigned long usec)
} while (diff >= 0);
}
void udelay (unsigned long usec)
void __udelay (unsigned long usec)
{
udelay_masked(usec);
}
......
......@@ -81,7 +81,7 @@ void set_timer(ulong t)
timer_ticks = t;
}
void udelay(ulong usec)
void __udelay(ulong usec)
{
ulong start = get_timer_masked();
ulong end;
......
......@@ -99,7 +99,7 @@ void set_timer(ulong t)
timestamp = t;
}
void udelay(unsigned long usec)
void __udelay (unsigned long usec)
{
ulong tmo;
ulong start = get_ticks();
......
......@@ -81,7 +81,7 @@ void set_timer (ulong t)
}
/* delay x useconds AND preserve advance timestamp value */
void udelay (unsigned long usec)
void __udelay (unsigned long usec)
{
int32_t tmo = usec * (TIMER_CLOCK / 1000) / 1000;
uint32_t now, last = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM);
......
......@@ -105,7 +105,7 @@ ulong get_timer_masked(void)
return tick_to_time(get_ticks());
}
void udelay(unsigned long usec)
void __udelay(unsigned long usec)
{
unsigned long long tmp;
ulong tmo;
......
......@@ -112,7 +112,7 @@ void set_timer(ulong t)
timestamp = t;
}
void udelay(unsigned long usec)
void __udelay(unsigned long usec)
{
ulong tmo;
ulong endtime;
......
......@@ -125,7 +125,7 @@ void set_timer(ulong t)
timestamp = t;
}
void udelay(unsigned long usec)
void __udelay(unsigned long usec)
{
uint current;
ulong delayticks;
......
......@@ -177,7 +177,7 @@ void set_timer (ulong t)
}
/* delay x useconds AND preserve advance timstamp value */
void udelay (unsigned long usec)
void __udelay (unsigned long usec)
{
unsigned long long tmp;
ulong tmo;
......
......@@ -59,7 +59,7 @@ ulong get_timer(ulong base)
}
/* Delay x useconds */
void udelay(unsigned long usec)
void __udelay(unsigned long usec)
{
ulong ini, end;
......
......@@ -80,7 +80,7 @@ void set_timer (ulong t)
}
/* delay x useconds AND perserve advance timstamp value */
void udelay (unsigned long usec)
void __udelay (unsigned long usec)
{
ulong tmo, tmp;
......
......@@ -109,7 +109,7 @@ void set_timer (ulong t)
}
/* delay x useconds AND perserve advance timstamp value */
void udelay (unsigned long usec)
void __udelay (unsigned long usec)
{
ulong tmo, tmp;
......
......@@ -82,7 +82,7 @@ void set_timer(ulong t)
}
/* delay x useconds */
void udelay(unsigned long usec)
void __udelay(unsigned long usec)
{
long tmo = usec * (TIMER_CLOCK / 1000) / 1000;
unsigned long now, last = readl(&timer_base->tcrr);
......
......@@ -115,7 +115,7 @@ void set_timer(unsigned long t)
}
/* delay x useconds */
void udelay(unsigned long usec)
void __udelay(unsigned long usec)
{
unsigned long tmo, tmp;
......
......@@ -96,7 +96,7 @@ void set_timer(unsigned long t)
/*
* For short delays only. It will overflow after a few seconds.
*/
void udelay(unsigned long usec)
void __udelay(unsigned long usec)
{
unsigned long cycles;
unsigned long base;
......
......@@ -64,7 +64,7 @@ int disable_interrupts(void)
return 1;
}
void udelay(unsigned long usec)
void __udelay(unsigned long usec)
{
unsigned long delay, start, stop;
unsigned long cclk;
......
......@@ -68,7 +68,7 @@ int timer_init(void)
return 0;
}
void udelay(unsigned long usec)
void __udelay(unsigned long usec)
{
int m = 0;
long u;
......
......@@ -505,8 +505,8 @@ reset_endless:
/*
* 0 <= r0 <= 2000
*/
.globl udelay
udelay:
.globl __udelay
__udelay:
mov r2, #0x6800
orr r2, r2, #0x00db
mul r0, r2, r0
......
......@@ -99,7 +99,7 @@ void ixp425_udelay(unsigned long usec)
while (!(*IXP425_OSST & IXP425_OSST_TIMER_1_PEND));
}
void udelay (unsigned long usec)
void __udelay (unsigned long usec)
{
while (usec--) ixp425_udelay(1);
}
......
......@@ -90,7 +90,7 @@ void set_timer (ulong t)
timestamp = t;
}
void udelay (unsigned long usec)
void __udelay (unsigned long usec)
{
ulong tmo,tmp;
......
......@@ -40,7 +40,7 @@ static ulong timestamp;
#endif
extern void dtimer_intr_setup(void);
void udelay(unsigned long usec)
void __udelay(unsigned long usec)
{
volatile slt_t *timerp = (slt_t *) (CONFIG_SYS_UDELAY_BASE);
u32 now, freq;
......
......@@ -78,7 +78,7 @@ void set_timer (ulong t)
/* nop */
}
void udelay (unsigned long usec)
void __udelay (unsigned long usec)
{
udelay_masked (usec);
}
......
......@@ -75,7 +75,7 @@ void set_timer (ulong t)
timestamp = t;
}
void udelay (unsigned long usec)
void __udelay (unsigned long usec)
{
ulong tmo;
......
......@@ -49,7 +49,7 @@ void set_timer (ulong t)
/* nop */
}
void udelay (unsigned long usec)
void __udelay (unsigned long usec)
{
udelay_masked (usec);
}
......
......@@ -44,6 +44,7 @@ EXT_COBJ_FILES-$(CONFIG_API) += lib_generic/crc32.o
EXT_COBJ_FILES-$(CONFIG_API) += lib_generic/ctype.o
EXT_COBJ_FILES-$(CONFIG_API) += lib_generic/div64.o
EXT_COBJ_FILES-$(CONFIG_API) += lib_generic/string.o
EXT_COBJ_FILES-$(CONFIG_API) += lib_generic/time.o
EXT_COBJ_FILES-$(CONFIG_API) += lib_generic/vsprintf.o
ifeq ($(ARCH),ppc)
EXT_SOBJ_FILES-$(CONFIG_API) += lib_ppc/ppcstring.o
......
......@@ -74,7 +74,7 @@ void putc (const char c)
ub_putc(c);
}
void udelay(unsigned long usec)
void __udelay(unsigned long usec)
{
ub_udelay(usec);
}
......
......@@ -47,7 +47,7 @@ extern __inline__ void __delay(unsigned long loops)
* first constant multiplications gets optimized away if the delay is
* a constant)
*/
extern __inline__ void udelay(unsigned long usecs)
extern __inline__ void __udelay(unsigned long usecs)
{
__delay(usecs);
}
......
......@@ -607,11 +607,14 @@ unsigned long long get_ticks(void);
void wait_ticks (unsigned long);
/* lib_$(ARCH)/time.c */
void udelay (unsigned long);
void __udelay (unsigned long);
ulong usec2ticks (unsigned long usec);
ulong ticks2usec (unsigned long ticks);
int init_timebase (void);
/* lib_generic/time.c */
void udelay (unsigned long);
/* lib_generic/vsprintf.c */
ulong simple_strtoul(const char *cp,char **endp,unsigned int base);
#ifdef CONFIG_SYS_64BIT_VSPRINTF
......
......@@ -16,7 +16,7 @@ void install_hdlr(int, interrupt_handler_t*, void*);
void free_hdlr(int);
void *malloc(size_t);
void free(void*);
void udelay(unsigned long);
void __udelay(unsigned long);
unsigned long get_timer(unsigned long);
void vprintf(const char *, va_list);
void do_reset (void);
......
......@@ -44,6 +44,7 @@ COBJS-y += sha1.o
COBJS-$(CONFIG_SHA256) += sha256.o
COBJS-y += string.o
COBJS-y += strmhz.o
COBJS-y += time.o
COBJS-y += vsprintf.o
COBJS-y += zlib.o
COBJS-$(CONFIG_RBTREE) += rbtree.o
......
/*
* (C) Copyright 2000-2009
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <watchdog.h>
#ifndef CONFIG_WD_PERIOD
# define CONFIG_WD_PERIOD (10 * 1000 * 1000) /* 10 seconds default*/
#endif
/* ------------------------------------------------------------------------- */
void udelay(unsigned long usec)
{
ulong kv;
do {
WATCHDOG_RESET();
kv = usec > CONFIG_WD_PERIOD ? CONFIG_WD_PERIOD : usec;
__udelay (kv);
usec -= kv;
} while(usec);
}
......@@ -71,7 +71,7 @@ static u16 read_pit(void)
}
/* this is not very exact */
void udelay (unsigned long usec)
void __udelay (unsigned long usec)
{
int counter;
int wraps;
......
......@@ -47,7 +47,7 @@ static volatile ulong timestamp = 0;
#endif
extern void dtimer_intr_setup(void);
void udelay(unsigned long usec)
void __udelay(unsigned long usec)
{
volatile dtmr_t *timerp = (dtmr_t *) (CONFIG_SYS_UDELAY_BASE);
uint start, now, tmp;
......@@ -139,7 +139,7 @@ void set_timer(ulong t)
static unsigned short lastinc;
void udelay(unsigned long usec)
void __udelay(unsigned long usec)
{
volatile pit_t *timerp = (pit_t *) (CONFIG_SYS_UDELAY_BASE);
uint tmp;
......
......@@ -27,14 +27,14 @@
#include <common.h>
#ifdef CONFIG_SYS_TIMER_0
void udelay (unsigned long usec)
void __udelay (unsigned long usec)
{
int i;
i = get_timer (0);
while ((get_timer (0) - i) < (usec / 1000)) ;
}
#else
void udelay (unsigned long usec)
void __udelay (unsigned long usec)
{
unsigned int i;
for (i = 0; i < (usec * CONFIG_XILINX_CLOCK_FREQ / 10000000); i++);
......
......@@ -70,7 +70,7 @@ void set_timer(ulong t)
write_c0_compare(read_c0_count() + CYCLES_PER_JIFFY);
}
void udelay(unsigned long usec)
void __udelay(unsigned long usec)
{
unsigned int tmo;
......
......@@ -27,13 +27,12 @@
extern void dly_clks( unsigned long ticks );
void udelay(unsigned long usec)
void __udelay(unsigned long usec)
{
/* The Nios core doesn't have a timebase, so we do our
* best for now and call a low-level loop that counts
* cpu clocks.
*/
unsigned long cnt = (CONFIG_SYS_CLK_FREQ/1000000) * usec;
WATCHDOG_RESET (); /* trigger watchdog if needed */
dly_clks (cnt);
}
......@@ -27,13 +27,12 @@
extern void dly_clks( unsigned long ticks );
void udelay(unsigned long usec)
void __udelay(unsigned long usec)
{
/* The Nios core doesn't have a timebase, so we do our
* best for now and call a low-level loop that counts
* cpu clocks.
*/
unsigned long cnt = (CONFIG_SYS_CLK_FREQ/1000000) * usec;
WATCHDOG_RESET (); /* trigger watchdog if needed */
dly_clks (cnt);
}
......@@ -23,10 +23,6 @@
#include <common.h>
#ifndef CONFIG_WD_PERIOD
# define CONFIG_WD_PERIOD (10 * 1000 * 1000) /* 10 seconds default*/
#endif
/* ------------------------------------------------------------------------- */
/*
......@@ -54,16 +50,10 @@ unsigned long usec2ticks(unsigned long usec)
* microseconds to wait) into a number of time base ticks; then we
* watch the time base until it has incremented by that amount.
*/
void udelay(unsigned long usec)
void __udelay(unsigned long usec)
{
ulong ticks, kv;
do {
kv = usec > CONFIG_WD_PERIOD ? CONFIG_WD_PERIOD : usec;
ticks = usec2ticks (kv);
wait_ticks (ticks);
usec -= kv;
} while(usec);
ulong ticks = usec2ticks (usec);
wait_ticks (ticks);
}
/* ------------------------------------------------------------------------- */
......
......@@ -105,7 +105,7 @@ unsigned long long get_ticks (void)
return 0 - readl(TCNT0);
}
void udelay (unsigned long usec)
void __udelay (unsigned long usec)
{
unsigned long long tmp;
ulong tmo;
......
......@@ -103,7 +103,7 @@ void reset_timer(void)
cmt_timer_start(0);
}
void udelay(unsigned long usec)
void __udelay(unsigned long usec)
{
unsigned long end = get_usec() + usec;
......
......@@ -53,7 +53,7 @@ unsigned long usec2ticks(unsigned long usec)
* microseconds to wait) into a number of time base ticks; then we
* watch the time base until it has incremented by that amount.
*/
void udelay(unsigned long usec)
void __udelay(unsigned long usec)
{
ulong ticks = usec2ticks(usec);
......
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