X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fppc%2Fkernel%2Ftime.c;h=53ea723af60aa5fff91a1ff057986584098f7285;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=cfeff0479c2e6a972839a19e39c6bd536b51e0ca;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c index cfeff0479..53ea723af 100644 --- a/arch/ppc/kernel/time.c +++ b/arch/ppc/kernel/time.c @@ -58,7 +58,6 @@ #include #include -#include #include #include #include @@ -67,11 +66,6 @@ #include -/* XXX false sharing with below? */ -u64 jiffies_64 = INITIAL_JIFFIES; - -EXPORT_SYMBOL(jiffies_64); - unsigned long disarm_decr[NR_CPUS]; extern struct timezone sys_tz; @@ -89,9 +83,10 @@ unsigned long tb_to_ns_scale; extern unsigned long wall_jiffies; -static long time_offset; +/* used for timezone offset */ +static long timezone_offset; -spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; +DEFINE_SPINLOCK(rtc_lock); EXPORT_SYMBOL(rtc_lock); @@ -108,40 +103,26 @@ static inline int tb_delta(unsigned *jiffy_stamp) { return delta; } -extern char _stext; - -static inline void ppc_do_profile (struct pt_regs *regs) +#ifdef CONFIG_SMP +unsigned long profile_pc(struct pt_regs *regs) { - unsigned long nip; - extern unsigned long prof_cpu_mask; + unsigned long pc = instruction_pointer(regs); - profile_hook(regs); + if (in_lock_functions(pc)) + return regs->link; - if (user_mode(regs)) - return; - - if (!prof_buffer) - return; - - nip = instruction_pointer(regs); - - /* - * Only measure the CPUs specified by /proc/irq/prof_cpu_mask. - * (default is all CPUs.) - */ - if (!((1<>= prof_shift; - /* - * Don't ignore out-of-bounds EIP values silently, - * put them into the last histogram slot, so if - * present, they will show up as a sharp peak. +void wakeup_decrementer(void) +{ + set_dec(tb_ticks_per_jiffy); + /* No currently-supported powerbook has a 601, + * so use get_tbl, not native */ - if (nip > prof_len-1) - nip = prof_len-1; - atomic_inc((atomic_t *)&prof_buffer[nip]); + last_jiffy_stamp(0) = tb_last_stamp = get_tbl(); } /* @@ -161,10 +142,11 @@ void timer_interrupt(struct pt_regs * regs) irq_enter(); - while ((next_dec = tb_ticks_per_jiffy - tb_delta(&jiffy_stamp)) < 0) { + while ((next_dec = tb_ticks_per_jiffy - tb_delta(&jiffy_stamp)) <= 0) { jiffy_stamp += tb_ticks_per_jiffy; - ppc_do_profile(regs); + profile_tick(CPU_PROFILING, regs); + update_process_times(user_mode(regs)); if (smp_processor_id()) continue; @@ -190,11 +172,11 @@ void timer_interrupt(struct pt_regs * regs) * We should have an rtc call that only sets the minutes and * seconds like on Intel to avoid problems with non UTC clocks. */ - if ( ppc_md.set_rtc_time && (time_status & STA_UNSYNC) == 0 && + if ( ppc_md.set_rtc_time && ntp_synced() && xtime.tv_sec - last_rtc_update >= 659 && abs((xtime.tv_nsec / 1000) - (1000000-1000000/HZ)) < 500000/HZ && jiffies - wall_jiffies == 1) { - if (ppc_md.set_rtc_time(xtime.tv_sec+1 + time_offset) == 0) + if (ppc_md.set_rtc_time(xtime.tv_sec+1 + timezone_offset) == 0) last_rtc_update = xtime.tv_sec+1; else /* Try again one minute later */ @@ -206,10 +188,6 @@ void timer_interrupt(struct pt_regs * regs) set_dec(next_dec); last_jiffy_stamp(cpu) = jiffy_stamp; -#ifdef CONFIG_SMP - smp_local_timer_interrupt(regs); -#endif /* CONFIG_SMP */ - if (ppc_md.heartbeat && !ppc_md.heartbeat_count--) ppc_md.heartbeat(); @@ -296,11 +274,7 @@ int do_settimeofday(struct timespec *tv) */ last_rtc_update = new_sec - 658; - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_state = TIME_ERROR; /* p. 24, (a) */ - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; + ntp_clear(); write_sequnlock_irqrestore(&xtime_lock, flags); clock_was_set(); return 0; @@ -315,7 +289,7 @@ void __init time_init(void) unsigned old_stamp, stamp, elapsed; if (ppc_md.time_init != NULL) - time_offset = ppc_md.time_init(); + timezone_offset = ppc_md.time_init(); if (__USE_RTC()) { /* 601 processor: dec counts down by 128 every 128ns */ @@ -360,10 +334,10 @@ void __init time_init(void) set_dec(tb_ticks_per_jiffy); /* If platform provided a timezone (pmac), we correct the time */ - if (time_offset) { - sys_tz.tz_minuteswest = -time_offset / 60; + if (timezone_offset) { + sys_tz.tz_minuteswest = -timezone_offset / 60; sys_tz.tz_dsttime = 0; - xtime.tv_sec -= time_offset; + xtime.tv_sec -= timezone_offset; } set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec);