Generic udelay() with watchdog support
authorIngo van Lil <inguin@gmx.de>
Tue, 24 Nov 2009 13:09:21 +0000 (14:09 +0100)
committerWolfgang Denk <wd@denx.de>
Sat, 5 Dec 2009 00:08:53 +0000 (01:08 +0100)
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: Ingo van Lil <inguin@gmx.de>
47 files changed:
board/armltd/integrator/timer.c
board/freescale/mpc8313erdb/sdram.c
cpu/arm1136/mx31/timer.c
cpu/arm1136/omap24xx/timer.c
cpu/arm1176/s3c64xx/timer.c
cpu/arm720t/interrupts.c
cpu/arm920t/at91rm9200/timer.c
cpu/arm920t/imx/timer.c
cpu/arm920t/ks8695/timer.c
cpu/arm920t/s3c24x0/timer.c
cpu/arm925t/timer.c
cpu/arm926ejs/at91/timer.c
cpu/arm926ejs/davinci/timer.c
cpu/arm926ejs/kirkwood/timer.c
cpu/arm926ejs/mx27/timer.c
cpu/arm926ejs/nomadik/timer.c
cpu/arm926ejs/omap/timer.c
cpu/arm926ejs/versatile/timer.c
cpu/arm_cortexa8/omap3/timer.c
cpu/arm_cortexa8/s5pc1xx/timer.c
cpu/at32ap/interrupts.c
cpu/blackfin/interrupts.c
cpu/i386/sc520/sc520_timer.c
cpu/ixp/start.S
cpu/ixp/timer.c
cpu/lh7a40x/timer.c
cpu/mcf547x_8x/slicetimer.c
cpu/pxa/timer.c
cpu/s3c44b0/timer.c
cpu/sa1100/timer.c
examples/api/Makefile
examples/api/libgenwrap.c
include/asm-blackfin/delay.h
include/common.h
include/exports.h
lib_generic/Makefile
lib_generic/time.c [new file with mode: 0644]
lib_i386/pcat_timer.c
lib_m68k/time.c
lib_microblaze/time.c
lib_mips/time.c
lib_nios/time.c
lib_nios2/time.c
lib_ppc/time.c
lib_sh/time.c
lib_sh/time_sh2.c
lib_sparc/time.c

index 087cf59..7562ffa 100644 (file)
@@ -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;
 
index cb13829..0c4fd68 100644 (file)
@@ -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;
index 29b484e..7972ba0 100644 (file)
@@ -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;
index 8dd8d7b..6754749 100644 (file)
@@ -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;
 
index 85ce9cd..9768319 100644 (file)
@@ -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;
index 91d552c..eb8d425 100644 (file)
@@ -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;
 
index 235d107..9c54bbe 100644 (file)
@@ -87,7 +87,7 @@ void set_timer (ulong t)
        timestamp = t;
 }
 
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
 {
        udelay_masked(usec);
 }
index 31ec588..b06b518 100644 (file)
@@ -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);
 }
index 22987bc..886e370 100644 (file)
@@ -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;
index cd06f6b..fcc6c0c 100644 (file)
@@ -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();
index c16ef25..7dfe2b5 100644 (file)
@@ -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);
index 811bb3c..7352b5c 100644 (file)
@@ -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;
index 7c2c208..9da7443 100644 (file)
@@ -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;
index 817ff42..2ec6a93 100644 (file)
@@ -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;
index 9011058..8f1d47b 100644 (file)
@@ -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;
index 16067c9..047b9e3 100644 (file)
@@ -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;
 
index 392b158..2ac38c4 100644 (file)
@@ -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;
 
index 50c1335..563db36 100755 (executable)
@@ -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;
 
index 12a16b3..401bfe6 100644 (file)
@@ -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);
index cdba5d9..c5df5c5 100644 (file)
@@ -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;
 
index 75cc39e..c6d8d16 100644 (file)
@@ -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;
index 19456e5..921bfe0 100644 (file)
@@ -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;
index 25c9a24..93b5b55 100644 (file)
@@ -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;
index 196ba5d..5ebce53 100644 (file)
@@ -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
index 6856149..edf341f 100644 (file)
@@ -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);
 }
index f9b5be0..2691315 100644 (file)
@@ -90,7 +90,7 @@ void set_timer (ulong t)
        timestamp = t;
 }
 
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
 {
        ulong tmo,tmp;
 
index 67e8189..8dc010a 100644 (file)
@@ -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;
index e2df3a5..8d0f826 100644 (file)
@@ -78,7 +78,7 @@ void set_timer (ulong t)
        /* nop */
 }
 
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
 {
        udelay_masked (usec);
 }
index 34184ab..6f1d8f6 100644 (file)
@@ -75,7 +75,7 @@ void set_timer (ulong t)
        timestamp = t;
 }
 
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
 {
        ulong tmo;
 
index 3f77e81..0207501 100644 (file)
@@ -49,7 +49,7 @@ void set_timer (ulong t)
        /* nop */
 }
 
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
 {
        udelay_masked (usec);
 }
index 04a270b..d4c5ca2 100644 (file)
@@ -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
index 2b62bad..2b107d9 100644 (file)
@@ -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);
 }
index ea0b366..3af6ad3 100644 (file)
@@ -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);
 }
index 30a4b7a..749d35c 100644 (file)
@@ -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
index 2e8fd8b..c3a5d2f 100644 (file)
@@ -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);
index 686601c..7291fa3 100644 (file)
@@ -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
diff --git a/lib_generic/time.c b/lib_generic/time.c
new file mode 100644 (file)
index 0000000..a309c26
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * (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);
+}
index c351b23..1373fd1 100644 (file)
@@ -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;
index 29269f6..7eaea5e 100644 (file)
@@ -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;
index cbb4341..da016a0 100644 (file)
 #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++);
index 07e356d..0e66441 100644 (file)
@@ -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;
 
index 25a233e..d5096ee 100644 (file)
 
 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);
 }
index 25a233e..d5096ee 100644 (file)
 
 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);
 }
index 173ffab..2909961 100644 (file)
 
 #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);
 }
 
 /* ------------------------------------------------------------------------- */
index 52dbcd0..9a8f89a 100644 (file)
@@ -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;
index 5c6c9d4..789b46f 100644 (file)
@@ -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;
 
index 433f3eb..82b2a3a 100644 (file)
@@ -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);