time.c (712cba5d87a6c0e980ee5fad45734e189c4d7151) | time.c (43b1f6abd59063a088416a0df042b36450f91f75) |
---|---|
1/* 2 * linux/arch/parisc/kernel/time.c 3 * 4 * Copyright (C) 1991, 1992, 1995 Linus Torvalds 5 * Modifications for ARM (C) 1994, 1995, 1996,1997 Russell King 6 * Copyright (C) 1999 SuSE GmbH, (Philipp Rumpf, prumpf@tux.org) 7 * 8 * 1994-07-02 Alan Modra 9 * fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime 10 * 1998-12-20 Updated NTP code according to technical memorandum Jan '96 11 * "A Kernel Model for Precision Timekeeping" by Dave Mills 12 */ 13#include <linux/errno.h> 14#include <linux/module.h> 15#include <linux/rtc.h> 16#include <linux/sched.h> | 1/* 2 * linux/arch/parisc/kernel/time.c 3 * 4 * Copyright (C) 1991, 1992, 1995 Linus Torvalds 5 * Modifications for ARM (C) 1994, 1995, 1996,1997 Russell King 6 * Copyright (C) 1999 SuSE GmbH, (Philipp Rumpf, prumpf@tux.org) 7 * 8 * 1994-07-02 Alan Modra 9 * fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime 10 * 1998-12-20 Updated NTP code according to technical memorandum Jan '96 11 * "A Kernel Model for Precision Timekeeping" by Dave Mills 12 */ 13#include <linux/errno.h> 14#include <linux/module.h> 15#include <linux/rtc.h> 16#include <linux/sched.h> |
17#include <linux/sched_clock.h> |
|
17#include <linux/kernel.h> 18#include <linux/param.h> 19#include <linux/string.h> 20#include <linux/mm.h> 21#include <linux/interrupt.h> 22#include <linux/time.h> 23#include <linux/init.h> 24#include <linux/smp.h> --- 9 unchanged lines hidden (view full) --- 34#include <asm/param.h> 35#include <asm/pdc.h> 36#include <asm/led.h> 37 38#include <linux/timex.h> 39 40static unsigned long clocktick __read_mostly; /* timer cycles per tick */ 41 | 18#include <linux/kernel.h> 19#include <linux/param.h> 20#include <linux/string.h> 21#include <linux/mm.h> 22#include <linux/interrupt.h> 23#include <linux/time.h> 24#include <linux/init.h> 25#include <linux/smp.h> --- 9 unchanged lines hidden (view full) --- 35#include <asm/param.h> 36#include <asm/pdc.h> 37#include <asm/led.h> 38 39#include <linux/timex.h> 40 41static unsigned long clocktick __read_mostly; /* timer cycles per tick */ 42 |
42#ifndef CONFIG_64BIT | |
43/* | 43/* |
44 * The processor-internal cycle counter (Control Register 16) is used as time 45 * source for the sched_clock() function. This register is 64bit wide on a 46 * 64-bit kernel and 32bit on a 32-bit kernel. Since sched_clock() always 47 * requires a 64bit counter we emulate on the 32-bit kernel the higher 32bits 48 * with a per-cpu variable which we increase every time the counter 49 * wraps-around (which happens every ~4 secounds). 50 */ 51static DEFINE_PER_CPU(unsigned long, cr16_high_32_bits); 52#endif 53 54/* | |
55 * We keep time on PA-RISC Linux by using the Interval Timer which is 56 * a pair of registers; one is read-only and one is write-only; both 57 * accessed through CR16. The read-only register is 32 or 64 bits wide, 58 * and increments by 1 every CPU clock tick. The architecture only 59 * guarantees us a rate between 0.5 and 2, but all implementations use a 60 * rate of 1. The write-only register is 32-bits wide. When the lowest 61 * 32 bits of the read-only register compare equal to the write-only 62 * register, it raises a maskable external interrupt. Each processor has --- 53 unchanged lines hidden (view full) --- 116 117 cpuinfo->it_value = next_tick; 118 119 /* Program the IT when to deliver the next interrupt. 120 * Only bottom 32-bits of next_tick are writable in CR16! 121 */ 122 mtctl(next_tick, 16); 123 | 44 * We keep time on PA-RISC Linux by using the Interval Timer which is 45 * a pair of registers; one is read-only and one is write-only; both 46 * accessed through CR16. The read-only register is 32 or 64 bits wide, 47 * and increments by 1 every CPU clock tick. The architecture only 48 * guarantees us a rate between 0.5 and 2, but all implementations use a 49 * rate of 1. The write-only register is 32-bits wide. When the lowest 50 * 32 bits of the read-only register compare equal to the write-only 51 * register, it raises a maskable external interrupt. Each processor has --- 53 unchanged lines hidden (view full) --- 105 106 cpuinfo->it_value = next_tick; 107 108 /* Program the IT when to deliver the next interrupt. 109 * Only bottom 32-bits of next_tick are writable in CR16! 110 */ 111 mtctl(next_tick, 16); 112 |
124#if !defined(CONFIG_64BIT) 125 /* check for overflow on a 32bit kernel (every ~4 seconds). */ 126 if (unlikely(next_tick < now)) 127 this_cpu_inc(cr16_high_32_bits); 128#endif 129 | |
130 /* Skip one clocktick on purpose if we missed next_tick. 131 * The new CR16 must be "later" than current CR16 otherwise 132 * itimer would not fire until CR16 wrapped - e.g 4 seconds 133 * later on a 1Ghz processor. We'll account for the missed 134 * tick on the next timer interrupt. 135 * 136 * "next_tick - now" will always give the difference regardless 137 * if one or the other wrapped. If "now" is "bigger" we'll end up --- 65 unchanged lines hidden (view full) --- 203 204 return pc; 205} 206EXPORT_SYMBOL(profile_pc); 207 208 209/* clock source code */ 210 | 113 /* Skip one clocktick on purpose if we missed next_tick. 114 * The new CR16 must be "later" than current CR16 otherwise 115 * itimer would not fire until CR16 wrapped - e.g 4 seconds 116 * later on a 1Ghz processor. We'll account for the missed 117 * tick on the next timer interrupt. 118 * 119 * "next_tick - now" will always give the difference regardless 120 * if one or the other wrapped. If "now" is "bigger" we'll end up --- 65 unchanged lines hidden (view full) --- 186 187 return pc; 188} 189EXPORT_SYMBOL(profile_pc); 190 191 192/* clock source code */ 193 |
211static cycle_t read_cr16(struct clocksource *cs) | 194static cycle_t notrace read_cr16(struct clocksource *cs) |
212{ 213 return get_cycles(); 214} 215 216static struct clocksource clocksource_cr16 = { 217 .name = "cr16", 218 .rating = 300, 219 .read = read_cr16, --- 62 unchanged lines hidden (view full) --- 282 } else { 283 printk(KERN_ERR "Error reading tod clock\n"); 284 ts->tv_sec = 0; 285 ts->tv_nsec = 0; 286 } 287} 288 289 | 195{ 196 return get_cycles(); 197} 198 199static struct clocksource clocksource_cr16 = { 200 .name = "cr16", 201 .rating = 300, 202 .read = read_cr16, --- 62 unchanged lines hidden (view full) --- 265 } else { 266 printk(KERN_ERR "Error reading tod clock\n"); 267 ts->tv_sec = 0; 268 ts->tv_nsec = 0; 269 } 270} 271 272 |
290/* 291 * sched_clock() framework 292 */ 293 294static u32 cyc2ns_mul __read_mostly; 295static u32 cyc2ns_shift __read_mostly; 296 297u64 sched_clock(void) | 273static u64 notrace read_cr16_sched_clock(void) |
298{ | 274{ |
299 u64 now; 300 301 /* Get current cycle counter (Control Register 16). */ 302#ifdef CONFIG_64BIT 303 now = mfctl(16); 304#else 305 now = mfctl(16) + (((u64) this_cpu_read(cr16_high_32_bits)) << 32); 306#endif 307 308 /* return the value in ns (cycles_2_ns) */ 309 return mul_u64_u32_shr(now, cyc2ns_mul, cyc2ns_shift); | 275 return get_cycles(); |
310} 311 312 313/* 314 * timer interrupt and sched_clock() initialization 315 */ 316 317void __init time_init(void) 318{ | 276} 277 278 279/* 280 * timer interrupt and sched_clock() initialization 281 */ 282 283void __init time_init(void) 284{ |
319 unsigned long current_cr16_khz; | 285 unsigned long cr16_hz; |
320 | 286 |
321 current_cr16_khz = PAGE0->mem_10msec/10; /* kHz */ | |
322 clocktick = (100 * PAGE0->mem_10msec) / HZ; | 287 clocktick = (100 * PAGE0->mem_10msec) / HZ; |
323 324 /* calculate mult/shift values for cr16 */ 325 clocks_calc_mult_shift(&cyc2ns_mul, &cyc2ns_shift, current_cr16_khz, 326 NSEC_PER_MSEC, 0); 327 | |
328 start_cpu_itimer(); /* get CPU 0 started */ 329 | 288 start_cpu_itimer(); /* get CPU 0 started */ 289 |
290 cr16_hz = 100 * PAGE0->mem_10msec; /* Hz */ 291 |
|
330 /* register at clocksource framework */ | 292 /* register at clocksource framework */ |
331 clocksource_register_khz(&clocksource_cr16, current_cr16_khz); | 293 clocksource_register_hz(&clocksource_cr16, cr16_hz); 294 295 /* register as sched_clock source */ 296 sched_clock_register(read_cr16_sched_clock, BITS_PER_LONG, cr16_hz); |
332} | 297} |