Am Montag, den 02.04.2007, 13:34 +0200 schrieb Richard Cochran: > > Then you have to implement it like I described. > > > > Take a look at the implementation for integrator-platforms. > > (Timer with wraparound) > > Well, as I said, the IXP425 one-shot timer mode does _not_ wrap around. > It just stops. > I'm not sure how (or why) to account for the clock ticks that transpire > during the interrupt handler. > > There are no clock ticks lost in __ipipe_mach_get_tsc, since this gets the > value of a free-flowing timer. > > Previously you wrote, > > > These lost-ticks should be added to the global time-stamp (returned by > > get_tsc) and should mentioned at the linux-gettimeoffset-function also. > > Can you be more specific? What is the "linux-gettimeoffset-function" of > which you speak? Linux gettimeoffset calls a march-specific function (ixp4xx_gettimeoffset) which delivers the time in us since the last timer-tick (timer-interrupt). > > Lost-ticks could sum up to a bothering time-error. > > But in the plain-old Linux code, no such adjustment is made (using a > periodic timer, see below). In this implementation a time-stamp register is used. Excuse me, I misunderstood your mail before... Forget what i said. It's quite simpler to use such a timer for adeos. Gilles Chanteperdrix is right. > > Does the Linux IXP4xx timer code have a bug? > > Richard > > > linux-2.6.19/arch/arm/mach-ixp4xx/common.c, from line 223: > > /************************************************************************* > * IXP4xx timer tick > * We use OS timer1 on the CPU for the timer tick and the timestamp > * counter as a source of real clock ticks to account for missed jiffies. > *************************************************************************/ > > static unsigned volatile last_jiffy_time; > > #define CLOCK_TICKS_PER_USEC ((CLOCK_TICK_RATE + USEC_PER_SEC/2) / USEC_PER_SEC) > > static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id) > { > write_seqlock(&xtime_lock); > > /* Clear Pending Interrupt by writing '1' to it */ > *IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND; > > /* > * Catch up with the real idea of time > */ > while ((signed long)(*IXP4XX_OSTS - last_jiffy_time) >= LATCH) { > timer_tick(); > last_jiffy_time += LATCH; > } > > write_sequnlock(&xtime_lock); > > return IRQ_HANDLED; > } > > static struct irqaction ixp4xx_timer_irq = { > .name = "IXP4xx Timer Tick", > .flags = IRQF_DISABLED | IRQF_TIMER, > .handler = ixp4xx_timer_interrupt, > }; > > static void __init ixp4xx_timer_init(void) > { > /* Clear Pending Interrupt by writing '1' to it */ > *IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND; > > /* Setup the Timer counter value */ > *IXP4XX_OSRT1 = (LATCH & ~IXP4XX_OST_RELOAD_MASK) | IXP4XX_OST_ENABLE; > > /* Reset time-stamp counter */ > *IXP4XX_OSTS = 0; > last_jiffy_time = 0; > > /* Connect the interrupt handler and enable the interrupt */ > setup_irq(IRQ_IXP4XX_TIMER1, &ixp4xx_timer_irq); > } > > > > > > > - Manfred Schlaegl > > - Manfred Schlaegl