Module Name: src
Committed By: nisimura
Date: Fri Feb 10 09:17:49 UTC 2012
Modified Files:
src/sys/arch/arm/s3c2xx0: s3c24x0_clk.c
Log Message:
- use a correct bit mask to pick SRCPND register indication.
- reading timer#4 possibly returns value '0'. Having the
'0' and a timer reload interrupt results in a too large
number, meaning the next get_timecounter() call will
return a smaller one than the previous, effectively kill
things. Handle this case.
ping(8) now shows better precisions. Fixes from Paul Fleischer.
Ok by releng.
To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 src/sys/arch/arm/s3c2xx0/s3c24x0_clk.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/arm/s3c2xx0/s3c24x0_clk.c
diff -u src/sys/arch/arm/s3c2xx0/s3c24x0_clk.c:1.13 src/sys/arch/arm/s3c2xx0/s3c24x0_clk.c:1.14
--- src/sys/arch/arm/s3c2xx0/s3c24x0_clk.c:1.13 Tue Feb 7 09:06:05 2012
+++ src/sys/arch/arm/s3c2xx0/s3c24x0_clk.c Fri Feb 10 09:17:49 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: s3c24x0_clk.c,v 1.13 2012/02/07 09:06:05 nisimura Exp $ */
+/* $NetBSD: s3c24x0_clk.c,v 1.14 2012/02/10 09:17:49 nisimura Exp $ */
/*
* Copyright (c) 2003 Genetec corporation. All rights reserved.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: s3c24x0_clk.c,v 1.13 2012/02/07 09:06:05 nisimura Exp $");
+__KERNEL_RCSID(0, "$NetBSD: s3c24x0_clk.c,v 1.14 2012/02/10 09:17:49 nisimura Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -53,9 +53,9 @@ __KERNEL_RCSID(0, "$NetBSD: s3c24x0_clk.
#define TIMER_FREQUENCY(pclk) ((pclk)/16) /* divider=1/16 */
-static unsigned int timer4_reload_value;
-static unsigned int timer4_prescaler;
-static unsigned int timer4_mseccount;
+static uint32_t timer4_reload_value;
+static uint32_t timer4_prescaler;
+static uint32_t timer4_mseccount;
#define usec_to_counter(t) \
((timer4_mseccount*(t))/1000)
@@ -68,7 +68,7 @@ static u_int s3c24x0_get_timecount(struc
static struct timecounter s3c24x0_timecounter = {
s3c24x0_get_timecount, /* get_timecount */
0, /* no poll_pps */
- 0xfff, /* counter_mask */
+ 0xffffffff, /* counter_mask */
0, /* frequency */
"s3c24x0", /* name */
100, /* quality */
@@ -83,21 +83,22 @@ s3c24x0_get_timecount(struct timecounter
{
struct s3c24x0_softc *sc = (struct s3c24x0_softc *) s3c2xx0_softc;
int save, int_pend0, int_pend1, count;
+ int int_pend;
save = disable_interrupts(I32_bit);
again:
- int_pend0 = S3C24X0_INT_TIMER4 &
- bus_space_read_4(sc->sc_sx.sc_iot, sc->sc_sx.sc_intctl_ioh,
+ int_pend = bus_space_read_4(sc->sc_sx.sc_iot, sc->sc_sx.sc_intctl_ioh,
INTCTL_SRCPND);
+ int_pend0 = (1<<S3C24X0_INT_TIMER4) & int_pend;
count = bus_space_read_2(sc->sc_sx.sc_iot, sc->sc_timer_ioh,
TIMER_TCNTO(4));
for (;;) {
- int_pend1 = S3C24X0_INT_TIMER4 &
- bus_space_read_4(sc->sc_sx.sc_iot, sc->sc_sx.sc_intctl_ioh,
- INTCTL_SRCPND);
+ int_pend1 = bus_space_read_4(sc->sc_sx.sc_iot,
+ sc->sc_sx.sc_intctl_ioh, INTCTL_SRCPND);
+ int_pend1 &= (1<<S3C24X0_INT_TIMER4);
if( int_pend0 == int_pend1 )
break;
@@ -122,11 +123,10 @@ s3c24x0_get_timecount(struct timecounter
restore_interrupts(save);
- if (int_pend1) {
+ if (int_pend1 && count > 0) {
count -= timer4_reload_value;
}
- //printf("delta: %u\n", (s3c24x0_base - count));
return s3c24x0_base - count;
}
@@ -250,7 +250,7 @@ cpu_initclocks(void)
calc_time_constant(h);
timer4_prescaler = prescaler;
- timer4_reload_value = TIMER_FREQUENCY(pclk) / hz / prescaler;
+ timer4_reload_value = (TIMER_FREQUENCY(pclk) / hz / prescaler) - 1;
timer4_mseccount = TIMER_FREQUENCY(pclk)/timer4_prescaler/1000 ;
bus_space_write_4(iot, ioh, TIMER_TCNTB(4),