> From: Benjamin Herrenschmidt  
> > Things have changed a lot since I last delved deep into 
> > this to try to
> > ge an accurate freerunning clock (2.6.12).
> 
> Hrm... 2.6.18 doesn't have clock sources in the first place, 
> what kernel
> are you using ?
> 

2.6.18
And I'm starting at the clocksource code right now...

>From jiffies.c:
static int __init init_jiffies_clocksource(void)
{
        return clocksource_register(&clocksource_jiffies);
}

module_init(init_jiffies_clocksource);

from: kernel/timer.c
/*
 * update_wall_time - Uses the current clocksource to increment the wall
time
 *
 * Called from the timer interrupt, must hold a write on xtime_lock.
 */
static void update_wall_time(void)
{
        cycle_t offset;

        /* Make sure we're fully resumed: */
        if (unlikely(timekeeping_suspended))
                return;

#ifdef CONFIG_GENERIC_TIME
        offset = (clocksource_read(clock) - clock->cycle_last) &
clock->mask;
#else
        offset = clock->cycle_interval;
#endif
        clock->xtime_nsec += (s64)xtime.tv_nsec << clock->shift;

        /* normally this loop will run just once, however in the
         * case of lost or late ticks, it will accumulate correctly.
         */
        while (offset >= clock->cycle_interval) {
                /* accumulate one interval */
                clock->xtime_nsec += clock->xtime_interval;
                clock->cycle_last += clock->cycle_interval;
                offset -= clock->cycle_interval;

                if (clock->xtime_nsec >= (u64)NSEC_PER_SEC <<
clock->shift) {
                        clock->xtime_nsec -= (u64)NSEC_PER_SEC <<
clock->shift;
                        xtime.tv_sec++;
                        second_overflow();
                }

                /* interpolator bits */
                time_interpolator_update(clock->xtime_interval
                                                >> clock->shift);
                /* increment the NTP state machine */
                update_ntp_one_tick();

                /* accumulate error between NTP and clock interval */
                clock->error += current_tick_length();
                clock->error -= clock->xtime_interval <<
(TICK_LENGTH_SHIFT - clock->shift);
        }

        /* correct the clock when NTP error is too big */
        clocksource_adjust(clock, offset);

        /* store full nanoseconds into xtime */
        xtime.tv_nsec = (s64)clock->xtime_nsec >> clock->shift;
        clock->xtime_nsec -= (s64)xtime.tv_nsec << clock->shift;

        /* check to see if there is a new clocksource to use */
        if (change_clocksource()) {
                clock->error = 0;
                clock->xtime_nsec = 0;
                clocksource_calculate_interval(clock, tick_nsec);
        }
}
_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

Reply via email to