Commit 3eb90bad651fab39cffba750ec4421a9c01d60e7

Authored by Ingo van Lil
Committed by Wolfgang Denk
1 parent 1c409bc710

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: Ingo van Lil <inguin@gmx.de>

Showing 47 changed files with 98 additions and 62 deletions Side-by-side Diff

board/armltd/integrator/timer.c
... ... @@ -124,7 +124,7 @@
124 124 }
125 125  
126 126 /* delay usec useconds */
127   -void udelay (unsigned long usec)
  127 +void __udelay (unsigned long usec)
128 128 {
129 129 ulong tmo, tmp;
130 130  
board/freescale/mpc8313erdb/sdram.c
... ... @@ -72,7 +72,7 @@
72 72 * Erratum DDR3 requires a 50ms delay after clearing DDRCDR[DDR_cfg],
73 73 * or the DDR2 controller may fail to initialize correctly.
74 74 */
75   - udelay(50000);
  75 + __udelay(50000);
76 76  
77 77 im->ddr.csbnds[0].csbnds = (msize - 1) >> 24;
78 78 im->ddr.cs_config[0] = CONFIG_SYS_DDR_CONFIG;
cpu/arm1136/mx31/timer.c
... ... @@ -152,7 +152,7 @@
152 152 }
153 153  
154 154 /* delay x useconds AND perserve advance timstamp value */
155   -void udelay (unsigned long usec)
  155 +void __udelay (unsigned long usec)
156 156 {
157 157 unsigned long long tmp;
158 158 ulong tmo;
cpu/arm1136/omap24xx/timer.c
... ... @@ -74,7 +74,7 @@
74 74 }
75 75  
76 76 /* delay x useconds AND perserve advance timstamp value */
77   -void udelay (unsigned long usec)
  77 +void __udelay (unsigned long usec)
78 78 {
79 79 ulong tmo, tmp;
80 80  
cpu/arm1176/s3c64xx/timer.c
... ... @@ -164,7 +164,7 @@
164 164 timestamp = t * (timer_load_val / (100 * CONFIG_SYS_HZ));
165 165 }
166 166  
167   -void udelay(unsigned long usec)
  167 +void __udelay(unsigned long usec)
168 168 {
169 169 unsigned long long tmp;
170 170 ulong tmo;
cpu/arm720t/interrupts.c
... ... @@ -224,7 +224,7 @@
224 224 timestamp = t;
225 225 }
226 226  
227   -void udelay (unsigned long usec)
  227 +void __udelay (unsigned long usec)
228 228 {
229 229 ulong tmo;
230 230  
... ... @@ -296,7 +296,7 @@
296 296 return timestamp - base;
297 297 }
298 298  
299   -void udelay (unsigned long usec)
  299 +void __udelay (unsigned long usec)
300 300 {
301 301 u32 ticks;
302 302  
cpu/arm920t/at91rm9200/timer.c
... ... @@ -87,7 +87,7 @@
87 87 timestamp = t;
88 88 }
89 89  
90   -void udelay (unsigned long usec)
  90 +void __udelay (unsigned long usec)
91 91 {
92 92 udelay_masked(usec);
93 93 }
cpu/arm920t/imx/timer.c
... ... @@ -89,7 +89,7 @@
89 89 } while (diff >= 0);
90 90 }
91 91  
92   -void udelay (unsigned long usec)
  92 +void __udelay (unsigned long usec)
93 93 {
94 94 udelay_masked(usec);
95 95 }
cpu/arm920t/ks8695/timer.c
... ... @@ -81,7 +81,7 @@
81 81 timer_ticks = t;
82 82 }
83 83  
84   -void udelay(ulong usec)
  84 +void __udelay(ulong usec)
85 85 {
86 86 ulong start = get_timer_masked();
87 87 ulong end;
cpu/arm920t/s3c24x0/timer.c
... ... @@ -99,7 +99,7 @@
99 99 timestamp = t;
100 100 }
101 101  
102   -void udelay(unsigned long usec)
  102 +void __udelay (unsigned long usec)
103 103 {
104 104 ulong tmo;
105 105 ulong start = get_ticks();
... ... @@ -81,7 +81,7 @@
81 81 }
82 82  
83 83 /* delay x useconds AND preserve advance timestamp value */
84   -void udelay (unsigned long usec)
  84 +void __udelay (unsigned long usec)
85 85 {
86 86 int32_t tmo = usec * (TIMER_CLOCK / 1000) / 1000;
87 87 uint32_t now, last = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM);
cpu/arm926ejs/at91/timer.c
... ... @@ -105,7 +105,7 @@
105 105 return tick_to_time(get_ticks());
106 106 }
107 107  
108   -void udelay(unsigned long usec)
  108 +void __udelay(unsigned long usec)
109 109 {
110 110 unsigned long long tmp;
111 111 ulong tmo;
cpu/arm926ejs/davinci/timer.c
... ... @@ -112,7 +112,7 @@
112 112 timestamp = t;
113 113 }
114 114  
115   -void udelay(unsigned long usec)
  115 +void __udelay(unsigned long usec)
116 116 {
117 117 ulong tmo;
118 118 ulong endtime;
cpu/arm926ejs/kirkwood/timer.c
... ... @@ -125,7 +125,7 @@
125 125 timestamp = t;
126 126 }
127 127  
128   -void udelay(unsigned long usec)
  128 +void __udelay(unsigned long usec)
129 129 {
130 130 uint current;
131 131 ulong delayticks;
cpu/arm926ejs/mx27/timer.c
... ... @@ -177,7 +177,7 @@
177 177 }
178 178  
179 179 /* delay x useconds AND preserve advance timstamp value */
180   -void udelay (unsigned long usec)
  180 +void __udelay (unsigned long usec)
181 181 {
182 182 unsigned long long tmp;
183 183 ulong tmo;
cpu/arm926ejs/nomadik/timer.c
... ... @@ -59,7 +59,7 @@
59 59 }
60 60  
61 61 /* Delay x useconds */
62   -void udelay(unsigned long usec)
  62 +void __udelay(unsigned long usec)
63 63 {
64 64 ulong ini, end;
65 65  
cpu/arm926ejs/omap/timer.c
... ... @@ -80,7 +80,7 @@
80 80 }
81 81  
82 82 /* delay x useconds AND perserve advance timstamp value */
83   -void udelay (unsigned long usec)
  83 +void __udelay (unsigned long usec)
84 84 {
85 85 ulong tmo, tmp;
86 86  
cpu/arm926ejs/versatile/timer.c
... ... @@ -109,7 +109,7 @@
109 109 }
110 110  
111 111 /* delay x useconds AND perserve advance timstamp value */
112   -void udelay (unsigned long usec)
  112 +void __udelay (unsigned long usec)
113 113 {
114 114 ulong tmo, tmp;
115 115  
cpu/arm_cortexa8/omap3/timer.c
... ... @@ -82,7 +82,7 @@
82 82 }
83 83  
84 84 /* delay x useconds */
85   -void udelay(unsigned long usec)
  85 +void __udelay(unsigned long usec)
86 86 {
87 87 long tmo = usec * (TIMER_CLOCK / 1000) / 1000;
88 88 unsigned long now, last = readl(&timer_base->tcrr);
cpu/arm_cortexa8/s5pc1xx/timer.c
... ... @@ -115,7 +115,7 @@
115 115 }
116 116  
117 117 /* delay x useconds */
118   -void udelay(unsigned long usec)
  118 +void __udelay(unsigned long usec)
119 119 {
120 120 unsigned long tmo, tmp;
121 121  
cpu/at32ap/interrupts.c
... ... @@ -96,7 +96,7 @@
96 96 /*
97 97 * For short delays only. It will overflow after a few seconds.
98 98 */
99   -void udelay(unsigned long usec)
  99 +void __udelay(unsigned long usec)
100 100 {
101 101 unsigned long cycles;
102 102 unsigned long base;
cpu/blackfin/interrupts.c
... ... @@ -64,7 +64,7 @@
64 64 return 1;
65 65 }
66 66  
67   -void udelay(unsigned long usec)
  67 +void __udelay(unsigned long usec)
68 68 {
69 69 unsigned long delay, start, stop;
70 70 unsigned long cclk;
cpu/i386/sc520/sc520_timer.c
... ... @@ -68,7 +68,7 @@
68 68 return 0;
69 69 }
70 70  
71   -void udelay(unsigned long usec)
  71 +void __udelay(unsigned long usec)
72 72 {
73 73 int m = 0;
74 74 long u;
... ... @@ -505,8 +505,8 @@
505 505 /*
506 506 * 0 <= r0 <= 2000
507 507 */
508   -.globl udelay
509   -udelay:
  508 +.globl __udelay
  509 +__udelay:
510 510 mov r2, #0x6800
511 511 orr r2, r2, #0x00db
512 512 mul r0, r2, r0
... ... @@ -99,7 +99,7 @@
99 99 while (!(*IXP425_OSST & IXP425_OSST_TIMER_1_PEND));
100 100 }
101 101  
102   -void udelay (unsigned long usec)
  102 +void __udelay (unsigned long usec)
103 103 {
104 104 while (usec--) ixp425_udelay(1);
105 105 }
... ... @@ -90,7 +90,7 @@
90 90 timestamp = t;
91 91 }
92 92  
93   -void udelay (unsigned long usec)
  93 +void __udelay (unsigned long usec)
94 94 {
95 95 ulong tmo,tmp;
96 96  
cpu/mcf547x_8x/slicetimer.c
... ... @@ -40,7 +40,7 @@
40 40 #endif
41 41 extern void dtimer_intr_setup(void);
42 42  
43   -void udelay(unsigned long usec)
  43 +void __udelay(unsigned long usec)
44 44 {
45 45 volatile slt_t *timerp = (slt_t *) (CONFIG_SYS_UDELAY_BASE);
46 46 u32 now, freq;
... ... @@ -78,7 +78,7 @@
78 78 /* nop */
79 79 }
80 80  
81   -void udelay (unsigned long usec)
  81 +void __udelay (unsigned long usec)
82 82 {
83 83 udelay_masked (usec);
84 84 }
... ... @@ -75,7 +75,7 @@
75 75 timestamp = t;
76 76 }
77 77  
78   -void udelay (unsigned long usec)
  78 +void __udelay (unsigned long usec)
79 79 {
80 80 ulong tmo;
81 81  
... ... @@ -49,7 +49,7 @@
49 49 /* nop */
50 50 }
51 51  
52   -void udelay (unsigned long usec)
  52 +void __udelay (unsigned long usec)
53 53 {
54 54 udelay_masked (usec);
55 55 }
examples/api/Makefile
... ... @@ -44,6 +44,7 @@
44 44 EXT_COBJ_FILES-$(CONFIG_API) += lib_generic/ctype.o
45 45 EXT_COBJ_FILES-$(CONFIG_API) += lib_generic/div64.o
46 46 EXT_COBJ_FILES-$(CONFIG_API) += lib_generic/string.o
  47 +EXT_COBJ_FILES-$(CONFIG_API) += lib_generic/time.o
47 48 EXT_COBJ_FILES-$(CONFIG_API) += lib_generic/vsprintf.o
48 49 ifeq ($(ARCH),ppc)
49 50 EXT_SOBJ_FILES-$(CONFIG_API) += lib_ppc/ppcstring.o
examples/api/libgenwrap.c
... ... @@ -74,7 +74,7 @@
74 74 ub_putc(c);
75 75 }
76 76  
77   -void udelay(unsigned long usec)
  77 +void __udelay(unsigned long usec)
78 78 {
79 79 ub_udelay(usec);
80 80 }
include/asm-blackfin/delay.h
... ... @@ -47,7 +47,7 @@
47 47 * first constant multiplications gets optimized away if the delay is
48 48 * a constant)
49 49 */
50   -extern __inline__ void udelay(unsigned long usecs)
  50 +extern __inline__ void __udelay(unsigned long usecs)
51 51 {
52 52 __delay(usecs);
53 53 }
... ... @@ -607,10 +607,13 @@
607 607 void wait_ticks (unsigned long);
608 608  
609 609 /* lib_$(ARCH)/time.c */
610   -void udelay (unsigned long);
  610 +void __udelay (unsigned long);
611 611 ulong usec2ticks (unsigned long usec);
612 612 ulong ticks2usec (unsigned long ticks);
613 613 int init_timebase (void);
  614 +
  615 +/* lib_generic/time.c */
  616 +void udelay (unsigned long);
614 617  
615 618 /* lib_generic/vsprintf.c */
616 619 ulong simple_strtoul(const char *cp,char **endp,unsigned int base);
... ... @@ -16,7 +16,7 @@
16 16 void free_hdlr(int);
17 17 void *malloc(size_t);
18 18 void free(void*);
19   -void udelay(unsigned long);
  19 +void __udelay(unsigned long);
20 20 unsigned long get_timer(unsigned long);
21 21 void vprintf(const char *, va_list);
22 22 void do_reset (void);
lib_generic/Makefile
... ... @@ -44,6 +44,7 @@
44 44 COBJS-$(CONFIG_SHA256) += sha256.o
45 45 COBJS-y += string.o
46 46 COBJS-y += strmhz.o
  47 +COBJS-y += time.o
47 48 COBJS-y += vsprintf.o
48 49 COBJS-y += zlib.o
49 50 COBJS-$(CONFIG_RBTREE) += rbtree.o
  1 +/*
  2 + * (C) Copyright 2000-2009
  3 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4 + *
  5 + * See file CREDITS for list of people who contributed to this
  6 + * project.
  7 + *
  8 + * This program is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU General Public License as
  10 + * published by the Free Software Foundation; either version 2 of
  11 + * the License, or (at your option) any later version.
  12 + *
  13 + * This program is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 + * GNU General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU General Public License
  19 + * along with this program; if not, write to the Free Software
  20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 + * MA 02111-1307 USA
  22 + */
  23 +
  24 +#include <common.h>
  25 +#include <watchdog.h>
  26 +
  27 +#ifndef CONFIG_WD_PERIOD
  28 +# define CONFIG_WD_PERIOD (10 * 1000 * 1000) /* 10 seconds default*/
  29 +#endif
  30 +
  31 +/* ------------------------------------------------------------------------- */
  32 +
  33 +void udelay(unsigned long usec)
  34 +{
  35 + ulong kv;
  36 +
  37 + do {
  38 + WATCHDOG_RESET();
  39 + kv = usec > CONFIG_WD_PERIOD ? CONFIG_WD_PERIOD : usec;
  40 + __udelay (kv);
  41 + usec -= kv;
  42 + } while(usec);
  43 +}
lib_i386/pcat_timer.c
... ... @@ -71,7 +71,7 @@
71 71 }
72 72  
73 73 /* this is not very exact */
74   -void udelay (unsigned long usec)
  74 +void __udelay (unsigned long usec)
75 75 {
76 76 int counter;
77 77 int wraps;
... ... @@ -47,7 +47,7 @@
47 47 #endif
48 48 extern void dtimer_intr_setup(void);
49 49  
50   -void udelay(unsigned long usec)
  50 +void __udelay(unsigned long usec)
51 51 {
52 52 volatile dtmr_t *timerp = (dtmr_t *) (CONFIG_SYS_UDELAY_BASE);
53 53 uint start, now, tmp;
... ... @@ -139,7 +139,7 @@
139 139  
140 140 static unsigned short lastinc;
141 141  
142   -void udelay(unsigned long usec)
  142 +void __udelay(unsigned long usec)
143 143 {
144 144 volatile pit_t *timerp = (pit_t *) (CONFIG_SYS_UDELAY_BASE);
145 145 uint tmp;
lib_microblaze/time.c
... ... @@ -27,14 +27,14 @@
27 27 #include <common.h>
28 28  
29 29 #ifdef CONFIG_SYS_TIMER_0
30   -void udelay (unsigned long usec)
  30 +void __udelay (unsigned long usec)
31 31 {
32 32 int i;
33 33 i = get_timer (0);
34 34 while ((get_timer (0) - i) < (usec / 1000)) ;
35 35 }
36 36 #else
37   -void udelay (unsigned long usec)
  37 +void __udelay (unsigned long usec)
38 38 {
39 39 unsigned int i;
40 40 for (i = 0; i < (usec * CONFIG_XILINX_CLOCK_FREQ / 10000000); i++);
... ... @@ -70,7 +70,7 @@
70 70 write_c0_compare(read_c0_count() + CYCLES_PER_JIFFY);
71 71 }
72 72  
73   -void udelay(unsigned long usec)
  73 +void __udelay(unsigned long usec)
74 74 {
75 75 unsigned int tmo;
76 76  
... ... @@ -27,14 +27,13 @@
27 27  
28 28 extern void dly_clks( unsigned long ticks );
29 29  
30   -void udelay(unsigned long usec)
  30 +void __udelay(unsigned long usec)
31 31 {
32 32 /* The Nios core doesn't have a timebase, so we do our
33 33 * best for now and call a low-level loop that counts
34 34 * cpu clocks.
35 35 */
36 36 unsigned long cnt = (CONFIG_SYS_CLK_FREQ/1000000) * usec;
37   - WATCHDOG_RESET (); /* trigger watchdog if needed */
38 37 dly_clks (cnt);
39 38 }
... ... @@ -27,14 +27,13 @@
27 27  
28 28 extern void dly_clks( unsigned long ticks );
29 29  
30   -void udelay(unsigned long usec)
  30 +void __udelay(unsigned long usec)
31 31 {
32 32 /* The Nios core doesn't have a timebase, so we do our
33 33 * best for now and call a low-level loop that counts
34 34 * cpu clocks.
35 35 */
36 36 unsigned long cnt = (CONFIG_SYS_CLK_FREQ/1000000) * usec;
37   - WATCHDOG_RESET (); /* trigger watchdog if needed */
38 37 dly_clks (cnt);
39 38 }
... ... @@ -23,10 +23,6 @@
23 23  
24 24 #include <common.h>
25 25  
26   -#ifndef CONFIG_WD_PERIOD
27   -# define CONFIG_WD_PERIOD (10 * 1000 * 1000) /* 10 seconds default*/
28   -#endif
29   -
30 26 /* ------------------------------------------------------------------------- */
31 27  
32 28 /*
33 29  
... ... @@ -54,16 +50,10 @@
54 50 * microseconds to wait) into a number of time base ticks; then we
55 51 * watch the time base until it has incremented by that amount.
56 52 */
57   -void udelay(unsigned long usec)
  53 +void __udelay(unsigned long usec)
58 54 {
59   - ulong ticks, kv;
60   -
61   - do {
62   - kv = usec > CONFIG_WD_PERIOD ? CONFIG_WD_PERIOD : usec;
63   - ticks = usec2ticks (kv);
64   - wait_ticks (ticks);
65   - usec -= kv;
66   - } while(usec);
  55 + ulong ticks = usec2ticks (usec);
  56 + wait_ticks (ticks);
67 57 }
68 58  
69 59 /* ------------------------------------------------------------------------- */
... ... @@ -105,7 +105,7 @@
105 105 return 0 - readl(TCNT0);
106 106 }
107 107  
108   -void udelay (unsigned long usec)
  108 +void __udelay (unsigned long usec)
109 109 {
110 110 unsigned long long tmp;
111 111 ulong tmo;
... ... @@ -103,7 +103,7 @@
103 103 cmt_timer_start(0);
104 104 }
105 105  
106   -void udelay(unsigned long usec)
  106 +void __udelay(unsigned long usec)
107 107 {
108 108 unsigned long end = get_usec() + usec;
109 109  
... ... @@ -53,7 +53,7 @@
53 53 * microseconds to wait) into a number of time base ticks; then we
54 54 * watch the time base until it has incremented by that amount.
55 55 */
56   -void udelay(unsigned long usec)
  56 +void __udelay(unsigned long usec)
57 57 {
58 58 ulong ticks = usec2ticks(usec);
59 59