diff options
author | wdenk <wdenk> | 2005-04-04 12:08:28 +0000 |
---|---|---|
committer | wdenk <wdenk> | 2005-04-04 12:08:28 +0000 |
commit | 101e8dfa2a8b045c6655bf2b3d6fba8d378453cd (patch) | |
tree | 1c39acefbaf435ddc2e9f42540eb64ea267cb530 /cpu/arm926ejs/interrupts.c | |
parent | 50712ba16e7e469e90952a7f197efa46e2f8e311 (diff) | |
download | u-boot-imx-101e8dfa2a8b045c6655bf2b3d6fba8d378453cd.zip u-boot-imx-101e8dfa2a8b045c6655bf2b3d6fba8d378453cd.tar.gz u-boot-imx-101e8dfa2a8b045c6655bf2b3d6fba8d378453cd.tar.bz2 |
Fix timer code for ARM systems: make sure that udelay() does not
reset timers so it's save to use udelay() in timeout code.
Diffstat (limited to 'cpu/arm926ejs/interrupts.c')
-rw-r--r-- | cpu/arm926ejs/interrupts.c | 48 |
1 files changed, 26 insertions, 22 deletions
diff --git a/cpu/arm926ejs/interrupts.c b/cpu/arm926ejs/interrupts.c index 062515e..ae8082d 100644 --- a/cpu/arm926ejs/interrupts.c +++ b/cpu/arm926ejs/interrupts.c @@ -26,7 +26,7 @@ * * 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 + * 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 @@ -116,15 +116,15 @@ void show_regs (struct pt_regs *regs) flags = condition_codes (regs); - printf ("pc : [<%08lx>] lr : [<%08lx>]\n" - "sp : %08lx ip : %08lx fp : %08lx\n", + printf ("pc : [<%08lx>] lr : [<%08lx>]\n" + "sp : %08lx ip : %08lx fp : %08lx\n", instruction_pointer (regs), regs->ARM_lr, regs->ARM_sp, regs->ARM_ip, regs->ARM_fp); - printf ("r10: %08lx r9 : %08lx r8 : %08lx\n", + printf ("r10: %08lx r9 : %08lx r8 : %08lx\n", regs->ARM_r10, regs->ARM_r9, regs->ARM_r8); - printf ("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n", + printf ("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n", regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4); - printf ("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n", + printf ("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n", regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0); printf ("Flags: %c%c%c%c", flags & CC_N_BIT ? 'N' : 'n', @@ -242,17 +242,17 @@ void udelay (unsigned long usec) { ulong tmo, tmp; - if(usec >= 1000){ /* if "big" number, spread normalization to seconds */ - tmo = usec / 1000; /* start to normalize for usec to ticks per sec */ - tmo *= CFG_HZ; /* find number of "ticks" to wait to achieve target */ - tmo /= 1000; /* finish normalize. */ - }else{ /* else small number, don't kill it prior to HZ multiply */ + if(usec >= 1000){ /* if "big" number, spread normalization to seconds */ + tmo = usec / 1000; /* start to normalize for usec to ticks per sec */ + tmo *= CFG_HZ; /* find number of "ticks" to wait to achieve target */ + tmo /= 1000; /* finish normalize. */ + }else{ /* else small number, don't kill it prior to HZ multiply */ tmo = usec * CFG_HZ; tmo /= (1000*1000); } tmp = get_timer (0); /* get current timestamp */ - if( (tmo + tmp + 1) < tmp ) /* if setting this fordward will roll time stamp */ + if( (tmo + tmp + 1) < tmp ) /* if setting this fordward will roll time stamp */ reset_timer_masked (); /* reset "advancing" timestamp to 0, set lastdec value */ else tmo += tmp; /* else, set advancing stamp wake up time */ @@ -265,7 +265,7 @@ void reset_timer_masked (void) { /* reset time */ lastdec = READ_TIMER; /* capure current decrementer value time */ - timestamp = 0; /* start "advancing" time stamp from 0 */ + timestamp = 0; /* start "advancing" time stamp from 0 */ } ulong get_timer_masked (void) @@ -292,20 +292,24 @@ ulong get_timer_masked (void) void udelay_masked (unsigned long usec) { ulong tmo; - - if(usec >= 1000){ /* if "big" number, spread normalization to seconds */ - tmo = usec / 1000; /* start to normalize for usec to ticks per sec */ - tmo *= CFG_HZ; /* find number of "ticks" to wait to achieve target */ - tmo /= 1000; /* finish normalize. */ - }else{ /* else small number, don't kill it prior to HZ multiply */ + ulong endtime; + signed long diff; + + if (usec >= 1000) { /* if "big" number, spread normalization to seconds */ + tmo = usec / 1000; /* start to normalize for usec to ticks per sec */ + tmo *= CFG_HZ; /* find number of "ticks" to wait to achieve target */ + tmo /= 1000; /* finish normalize. */ + } else { /* else small number, don't kill it prior to HZ multiply */ tmo = usec * CFG_HZ; tmo /= (1000*1000); } - reset_timer_masked (); /* set "advancing" timestamp to 0, set lastdec vaule */ + endtime = get_timer_masked () + tmo; - while (get_timer_masked () < tmo) /* wait for time stamp to overtake tick number.*/ - /*NOP*/; + do { + ulong now = get_timer_masked (); + diff = endtime - now; + } while (diff >= 0); } /* |