Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik...
[linux-2.6] / arch / x86_64 / kernel / time.c
1 /*
2  *  linux/arch/x86-64/kernel/time.c
3  *
4  *  "High Precision Event Timer" based timekeeping.
5  *
6  *  Copyright (c) 1991,1992,1995  Linus Torvalds
7  *  Copyright (c) 1994  Alan Modra
8  *  Copyright (c) 1995  Markus Kuhn
9  *  Copyright (c) 1996  Ingo Molnar
10  *  Copyright (c) 1998  Andrea Arcangeli
11  *  Copyright (c) 2002,2006  Vojtech Pavlik
12  *  Copyright (c) 2003  Andi Kleen
13  *  RTC support code taken from arch/i386/kernel/timers/time_hpet.c
14  */
15
16 #include <linux/kernel.h>
17 #include <linux/sched.h>
18 #include <linux/interrupt.h>
19 #include <linux/init.h>
20 #include <linux/mc146818rtc.h>
21 #include <linux/time.h>
22 #include <linux/ioport.h>
23 #include <linux/module.h>
24 #include <linux/device.h>
25 #include <linux/sysdev.h>
26 #include <linux/bcd.h>
27 #include <linux/notifier.h>
28 #include <linux/cpu.h>
29 #include <linux/kallsyms.h>
30 #include <linux/acpi.h>
31 #ifdef CONFIG_ACPI
32 #include <acpi/achware.h>       /* for PM timer frequency */
33 #include <acpi/acpi_bus.h>
34 #endif
35 #include <asm/8253pit.h>
36 #include <asm/pgtable.h>
37 #include <asm/vsyscall.h>
38 #include <asm/timex.h>
39 #include <asm/proto.h>
40 #include <asm/hpet.h>
41 #include <asm/sections.h>
42 #include <linux/cpufreq.h>
43 #include <linux/hpet.h>
44 #include <asm/apic.h>
45
46 #ifdef CONFIG_CPU_FREQ
47 static void cpufreq_delayed_get(void);
48 #endif
49 extern void i8254_timer_resume(void);
50 extern int using_apic_timer;
51
52 static char *timename = NULL;
53
54 DEFINE_SPINLOCK(rtc_lock);
55 EXPORT_SYMBOL(rtc_lock);
56 DEFINE_SPINLOCK(i8253_lock);
57
58 int nohpet __initdata = 0;
59 static int notsc __initdata = 0;
60
61 #define USEC_PER_TICK (USEC_PER_SEC / HZ)
62 #define NSEC_PER_TICK (NSEC_PER_SEC / HZ)
63 #define FSEC_PER_TICK (FSEC_PER_SEC / HZ)
64
65 #define NS_SCALE        10 /* 2^10, carefully chosen */
66 #define US_SCALE        32 /* 2^32, arbitralrily chosen */
67
68 unsigned int cpu_khz;                                   /* TSC clocks / usec, not used here */
69 EXPORT_SYMBOL(cpu_khz);
70 static unsigned long hpet_period;                       /* fsecs / HPET clock */
71 unsigned long hpet_tick;                                /* HPET clocks / interrupt */
72 int hpet_use_timer;                             /* Use counter of hpet for time keeping, otherwise PIT */
73 unsigned long vxtime_hz = PIT_TICK_RATE;
74 int report_lost_ticks;                          /* command line option */
75 unsigned long long monotonic_base;
76
77 struct vxtime_data __vxtime __section_vxtime;   /* for vsyscalls */
78
79 volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES;
80 unsigned long __wall_jiffies __section_wall_jiffies = INITIAL_JIFFIES;
81 struct timespec __xtime __section_xtime;
82 struct timezone __sys_tz __section_sys_tz;
83
84 /*
85  * do_gettimeoffset() returns microseconds since last timer interrupt was
86  * triggered by hardware. A memory read of HPET is slower than a register read
87  * of TSC, but much more reliable. It's also synchronized to the timer
88  * interrupt. Note that do_gettimeoffset() may return more than hpet_tick, if a
89  * timer interrupt has happened already, but vxtime.trigger wasn't updated yet.
90  * This is not a problem, because jiffies hasn't updated either. They are bound
91  * together by xtime_lock.
92  */
93
94 static inline unsigned int do_gettimeoffset_tsc(void)
95 {
96         unsigned long t;
97         unsigned long x;
98         t = get_cycles_sync();
99         if (t < vxtime.last_tsc) 
100                 t = vxtime.last_tsc; /* hack */
101         x = ((t - vxtime.last_tsc) * vxtime.tsc_quot) >> US_SCALE;
102         return x;
103 }
104
105 static inline unsigned int do_gettimeoffset_hpet(void)
106 {
107         /* cap counter read to one tick to avoid inconsistencies */
108         unsigned long counter = hpet_readl(HPET_COUNTER) - vxtime.last;
109         return (min(counter,hpet_tick) * vxtime.quot) >> US_SCALE;
110 }
111
112 unsigned int (*do_gettimeoffset)(void) = do_gettimeoffset_tsc;
113
114 /*
115  * This version of gettimeofday() has microsecond resolution and better than
116  * microsecond precision, as we're using at least a 10 MHz (usually 14.31818
117  * MHz) HPET timer.
118  */
119
120 void do_gettimeofday(struct timeval *tv)
121 {
122         unsigned long seq, t;
123         unsigned int sec, usec;
124
125         do {
126                 seq = read_seqbegin(&xtime_lock);
127
128                 sec = xtime.tv_sec;
129                 usec = xtime.tv_nsec / NSEC_PER_USEC;
130
131                 /* i386 does some correction here to keep the clock 
132                    monotonous even when ntpd is fixing drift.
133                    But they didn't work for me, there is a non monotonic
134                    clock anyways with ntp.
135                    I dropped all corrections now until a real solution can
136                    be found. Note when you fix it here you need to do the same
137                    in arch/x86_64/kernel/vsyscall.c and export all needed
138                    variables in vmlinux.lds. -AK */ 
139
140                 t = (jiffies - wall_jiffies) * USEC_PER_TICK +
141                         do_gettimeoffset();
142                 usec += t;
143
144         } while (read_seqretry(&xtime_lock, seq));
145
146         tv->tv_sec = sec + usec / USEC_PER_SEC;
147         tv->tv_usec = usec % USEC_PER_SEC;
148 }
149
150 EXPORT_SYMBOL(do_gettimeofday);
151
152 /*
153  * settimeofday() first undoes the correction that gettimeofday would do
154  * on the time, and then saves it. This is ugly, but has been like this for
155  * ages already.
156  */
157
158 int do_settimeofday(struct timespec *tv)
159 {
160         time_t wtm_sec, sec = tv->tv_sec;
161         long wtm_nsec, nsec = tv->tv_nsec;
162
163         if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
164                 return -EINVAL;
165
166         write_seqlock_irq(&xtime_lock);
167
168         nsec -= do_gettimeoffset() * NSEC_PER_USEC +
169                 (jiffies - wall_jiffies) * NSEC_PER_TICK;
170
171         wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
172         wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
173
174         set_normalized_timespec(&xtime, sec, nsec);
175         set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
176
177         ntp_clear();
178
179         write_sequnlock_irq(&xtime_lock);
180         clock_was_set();
181         return 0;
182 }
183
184 EXPORT_SYMBOL(do_settimeofday);
185
186 unsigned long profile_pc(struct pt_regs *regs)
187 {
188         unsigned long pc = instruction_pointer(regs);
189
190         /* Assume the lock function has either no stack frame or a copy
191            of eflags from PUSHF
192            Eflags always has bits 22 and up cleared unlike kernel addresses. */
193         if (!user_mode(regs) && in_lock_functions(pc)) {
194                 unsigned long *sp = (unsigned long *)regs->rsp;
195                 if (sp[0] >> 22)
196                         return sp[0];
197                 if (sp[1] >> 22)
198                         return sp[1];
199         }
200         return pc;
201 }
202 EXPORT_SYMBOL(profile_pc);
203
204 /*
205  * In order to set the CMOS clock precisely, set_rtc_mmss has to be called 500
206  * ms after the second nowtime has started, because when nowtime is written
207  * into the registers of the CMOS clock, it will jump to the next second
208  * precisely 500 ms later. Check the Motorola MC146818A or Dallas DS12887 data
209  * sheet for details.
210  */
211
212 static void set_rtc_mmss(unsigned long nowtime)
213 {
214         int real_seconds, real_minutes, cmos_minutes;
215         unsigned char control, freq_select;
216
217 /*
218  * IRQs are disabled when we're called from the timer interrupt,
219  * no need for spin_lock_irqsave()
220  */
221
222         spin_lock(&rtc_lock);
223
224 /*
225  * Tell the clock it's being set and stop it.
226  */
227
228         control = CMOS_READ(RTC_CONTROL);
229         CMOS_WRITE(control | RTC_SET, RTC_CONTROL);
230
231         freq_select = CMOS_READ(RTC_FREQ_SELECT);
232         CMOS_WRITE(freq_select | RTC_DIV_RESET2, RTC_FREQ_SELECT);
233
234         cmos_minutes = CMOS_READ(RTC_MINUTES);
235                 BCD_TO_BIN(cmos_minutes);
236
237 /*
238  * since we're only adjusting minutes and seconds, don't interfere with hour
239  * overflow. This avoids messing with unknown time zones but requires your RTC
240  * not to be off by more than 15 minutes. Since we're calling it only when
241  * our clock is externally synchronized using NTP, this shouldn't be a problem.
242  */
243
244         real_seconds = nowtime % 60;
245         real_minutes = nowtime / 60;
246         if (((abs(real_minutes - cmos_minutes) + 15) / 30) & 1)
247                 real_minutes += 30;             /* correct for half hour time zone */
248         real_minutes %= 60;
249
250         if (abs(real_minutes - cmos_minutes) >= 30) {
251                 printk(KERN_WARNING "time.c: can't update CMOS clock "
252                        "from %d to %d\n", cmos_minutes, real_minutes);
253         } else {
254                 BIN_TO_BCD(real_seconds);
255                 BIN_TO_BCD(real_minutes);
256                 CMOS_WRITE(real_seconds, RTC_SECONDS);
257                 CMOS_WRITE(real_minutes, RTC_MINUTES);
258         }
259
260 /*
261  * The following flags have to be released exactly in this order, otherwise the
262  * DS12887 (popular MC146818A clone with integrated battery and quartz) will
263  * not reset the oscillator and will not update precisely 500 ms later. You
264  * won't find this mentioned in the Dallas Semiconductor data sheets, but who
265  * believes data sheets anyway ... -- Markus Kuhn
266  */
267
268         CMOS_WRITE(control, RTC_CONTROL);
269         CMOS_WRITE(freq_select, RTC_FREQ_SELECT);
270
271         spin_unlock(&rtc_lock);
272 }
273
274
275 /* monotonic_clock(): returns # of nanoseconds passed since time_init()
276  *              Note: This function is required to return accurate
277  *              time even in the absence of multiple timer ticks.
278  */
279 static inline unsigned long long cycles_2_ns(unsigned long long cyc);
280 unsigned long long monotonic_clock(void)
281 {
282         unsigned long seq;
283         u32 last_offset, this_offset, offset;
284         unsigned long long base;
285
286         if (vxtime.mode == VXTIME_HPET) {
287                 do {
288                         seq = read_seqbegin(&xtime_lock);
289
290                         last_offset = vxtime.last;
291                         base = monotonic_base;
292                         this_offset = hpet_readl(HPET_COUNTER);
293                 } while (read_seqretry(&xtime_lock, seq));
294                 offset = (this_offset - last_offset);
295                 offset *= NSEC_PER_TICK / hpet_tick;
296         } else {
297                 do {
298                         seq = read_seqbegin(&xtime_lock);
299
300                         last_offset = vxtime.last_tsc;
301                         base = monotonic_base;
302                 } while (read_seqretry(&xtime_lock, seq));
303                 this_offset = get_cycles_sync();
304                 offset = cycles_2_ns(this_offset - last_offset);
305         }
306         return base + offset;
307 }
308 EXPORT_SYMBOL(monotonic_clock);
309
310 static noinline void handle_lost_ticks(int lost, struct pt_regs *regs)
311 {
312         static long lost_count;
313         static int warned;
314         if (report_lost_ticks) {
315                 printk(KERN_WARNING "time.c: Lost %d timer tick(s)! ", lost);
316                 print_symbol("rip %s)\n", regs->rip);
317         }
318
319         if (lost_count == 1000 && !warned) {
320                 printk(KERN_WARNING "warning: many lost ticks.\n"
321                        KERN_WARNING "Your time source seems to be instable or "
322                                 "some driver is hogging interupts\n");
323                 print_symbol("rip %s\n", regs->rip);
324                 if (vxtime.mode == VXTIME_TSC && vxtime.hpet_address) {
325                         printk(KERN_WARNING "Falling back to HPET\n");
326                         if (hpet_use_timer)
327                                 vxtime.last = hpet_readl(HPET_T0_CMP) - 
328                                                         hpet_tick;
329                         else
330                                 vxtime.last = hpet_readl(HPET_COUNTER);
331                         vxtime.mode = VXTIME_HPET;
332                         do_gettimeoffset = do_gettimeoffset_hpet;
333                 }
334                 /* else should fall back to PIT, but code missing. */
335                 warned = 1;
336         } else
337                 lost_count++;
338
339 #ifdef CONFIG_CPU_FREQ
340         /* In some cases the CPU can change frequency without us noticing
341            Give cpufreq a change to catch up. */
342         if ((lost_count+1) % 25 == 0)
343                 cpufreq_delayed_get();
344 #endif
345 }
346
347 void main_timer_handler(struct pt_regs *regs)
348 {
349         static unsigned long rtc_update = 0;
350         unsigned long tsc;
351         int delay = 0, offset = 0, lost = 0;
352
353 /*
354  * Here we are in the timer irq handler. We have irqs locally disabled (so we
355  * don't need spin_lock_irqsave()) but we don't know if the timer_bh is running
356  * on the other CPU, so we need a lock. We also need to lock the vsyscall
357  * variables, because both do_timer() and us change them -arca+vojtech
358  */
359
360         write_seqlock(&xtime_lock);
361
362         if (vxtime.hpet_address)
363                 offset = hpet_readl(HPET_COUNTER);
364
365         if (hpet_use_timer) {
366                 /* if we're using the hpet timer functionality,
367                  * we can more accurately know the counter value
368                  * when the timer interrupt occured.
369                  */
370                 offset = hpet_readl(HPET_T0_CMP) - hpet_tick;
371                 delay = hpet_readl(HPET_COUNTER) - offset;
372         } else if (!pmtmr_ioport) {
373                 spin_lock(&i8253_lock);
374                 outb_p(0x00, 0x43);
375                 delay = inb_p(0x40);
376                 delay |= inb(0x40) << 8;
377                 spin_unlock(&i8253_lock);
378                 delay = LATCH - 1 - delay;
379         }
380
381         tsc = get_cycles_sync();
382
383         if (vxtime.mode == VXTIME_HPET) {
384                 if (offset - vxtime.last > hpet_tick) {
385                         lost = (offset - vxtime.last) / hpet_tick - 1;
386                 }
387
388                 monotonic_base += 
389                         (offset - vxtime.last) * NSEC_PER_TICK / hpet_tick;
390
391                 vxtime.last = offset;
392 #ifdef CONFIG_X86_PM_TIMER
393         } else if (vxtime.mode == VXTIME_PMTMR) {
394                 lost = pmtimer_mark_offset();
395 #endif
396         } else {
397                 offset = (((tsc - vxtime.last_tsc) *
398                            vxtime.tsc_quot) >> US_SCALE) - USEC_PER_TICK;
399
400                 if (offset < 0)
401                         offset = 0;
402
403                 if (offset > USEC_PER_TICK) {
404                         lost = offset / USEC_PER_TICK;
405                         offset %= USEC_PER_TICK;
406                 }
407
408                 monotonic_base += cycles_2_ns(tsc - vxtime.last_tsc);
409
410                 vxtime.last_tsc = tsc - vxtime.quot * delay / vxtime.tsc_quot;
411
412                 if ((((tsc - vxtime.last_tsc) *
413                       vxtime.tsc_quot) >> US_SCALE) < offset)
414                         vxtime.last_tsc = tsc -
415                                 (((long) offset << US_SCALE) / vxtime.tsc_quot) - 1;
416         }
417
418         if (lost > 0) {
419                 handle_lost_ticks(lost, regs);
420                 jiffies += lost;
421         }
422
423 /*
424  * Do the timer stuff.
425  */
426
427         do_timer(regs);
428 #ifndef CONFIG_SMP
429         update_process_times(user_mode(regs));
430 #endif
431
432 /*
433  * In the SMP case we use the local APIC timer interrupt to do the profiling,
434  * except when we simulate SMP mode on a uniprocessor system, in that case we
435  * have to call the local interrupt handler.
436  */
437
438         if (!using_apic_timer)
439                 smp_local_timer_interrupt(regs);
440
441 /*
442  * If we have an externally synchronized Linux clock, then update CMOS clock
443  * accordingly every ~11 minutes. set_rtc_mmss() will be called in the jiffy
444  * closest to exactly 500 ms before the next second. If the update fails, we
445  * don't care, as it'll be updated on the next turn, and the problem (time way
446  * off) isn't likely to go away much sooner anyway.
447  */
448
449         if (ntp_synced() && xtime.tv_sec > rtc_update &&
450                 abs(xtime.tv_nsec - 500000000) <= tick_nsec / 2) {
451                 set_rtc_mmss(xtime.tv_sec);
452                 rtc_update = xtime.tv_sec + 660;
453         }
454  
455         write_sequnlock(&xtime_lock);
456 }
457
458 static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
459 {
460         if (apic_runs_main_timer > 1)
461                 return IRQ_HANDLED;
462         main_timer_handler(regs);
463         if (using_apic_timer)
464                 smp_send_timer_broadcast_ipi();
465         return IRQ_HANDLED;
466 }
467
468 static unsigned int cyc2ns_scale __read_mostly;
469
470 static inline void set_cyc2ns_scale(unsigned long cpu_khz)
471 {
472         cyc2ns_scale = (NSEC_PER_MSEC << NS_SCALE) / cpu_khz;
473 }
474
475 static inline unsigned long long cycles_2_ns(unsigned long long cyc)
476 {
477         return (cyc * cyc2ns_scale) >> NS_SCALE;
478 }
479
480 unsigned long long sched_clock(void)
481 {
482         unsigned long a = 0;
483
484 #if 0
485         /* Don't do a HPET read here. Using TSC always is much faster
486            and HPET may not be mapped yet when the scheduler first runs.
487            Disadvantage is a small drift between CPUs in some configurations,
488            but that should be tolerable. */
489         if (__vxtime.mode == VXTIME_HPET)
490                 return (hpet_readl(HPET_COUNTER) * vxtime.quot) >> US_SCALE;
491 #endif
492
493         /* Could do CPU core sync here. Opteron can execute rdtsc speculatively,
494            which means it is not completely exact and may not be monotonous between
495            CPUs. But the errors should be too small to matter for scheduling
496            purposes. */
497
498         rdtscll(a);
499         return cycles_2_ns(a);
500 }
501
502 static unsigned long get_cmos_time(void)
503 {
504         unsigned int year, mon, day, hour, min, sec;
505         unsigned long flags;
506         unsigned extyear = 0;
507
508         spin_lock_irqsave(&rtc_lock, flags);
509
510         do {
511                 sec = CMOS_READ(RTC_SECONDS);
512                 min = CMOS_READ(RTC_MINUTES);
513                 hour = CMOS_READ(RTC_HOURS);
514                 day = CMOS_READ(RTC_DAY_OF_MONTH);
515                 mon = CMOS_READ(RTC_MONTH);
516                 year = CMOS_READ(RTC_YEAR);
517 #ifdef CONFIG_ACPI
518                 if (acpi_fadt.revision >= FADT2_REVISION_ID &&
519                                         acpi_fadt.century)
520                         extyear = CMOS_READ(acpi_fadt.century);
521 #endif
522         } while (sec != CMOS_READ(RTC_SECONDS));
523
524         spin_unlock_irqrestore(&rtc_lock, flags);
525
526         /*
527          * We know that x86-64 always uses BCD format, no need to check the
528          * config register.
529          */
530
531         BCD_TO_BIN(sec);
532         BCD_TO_BIN(min);
533         BCD_TO_BIN(hour);
534         BCD_TO_BIN(day);
535         BCD_TO_BIN(mon);
536         BCD_TO_BIN(year);
537
538         if (extyear) {
539                 BCD_TO_BIN(extyear);
540                 year += extyear;
541                 printk(KERN_INFO "Extended CMOS year: %d\n", extyear);
542         } else { 
543                 /*
544                  * x86-64 systems only exists since 2002.
545                  * This will work up to Dec 31, 2100
546                  */
547                 year += 2000;
548         }
549
550         return mktime(year, mon, day, hour, min, sec);
551 }
552
553 #ifdef CONFIG_CPU_FREQ
554
555 /* Frequency scaling support. Adjust the TSC based timer when the cpu frequency
556    changes.
557    
558    RED-PEN: On SMP we assume all CPUs run with the same frequency.  It's
559    not that important because current Opteron setups do not support
560    scaling on SMP anyroads.
561
562    Should fix up last_tsc too. Currently gettimeofday in the
563    first tick after the change will be slightly wrong. */
564
565 #include <linux/workqueue.h>
566
567 static unsigned int cpufreq_delayed_issched = 0;
568 static unsigned int cpufreq_init = 0;
569 static struct work_struct cpufreq_delayed_get_work;
570
571 static void handle_cpufreq_delayed_get(void *v)
572 {
573         unsigned int cpu;
574         for_each_online_cpu(cpu) {
575                 cpufreq_get(cpu);
576         }
577         cpufreq_delayed_issched = 0;
578 }
579
580 /* if we notice lost ticks, schedule a call to cpufreq_get() as it tries
581  * to verify the CPU frequency the timing core thinks the CPU is running
582  * at is still correct.
583  */
584 static void cpufreq_delayed_get(void)
585 {
586         static int warned;
587         if (cpufreq_init && !cpufreq_delayed_issched) {
588                 cpufreq_delayed_issched = 1;
589                 if (!warned) {
590                         warned = 1;
591                         printk(KERN_DEBUG 
592         "Losing some ticks... checking if CPU frequency changed.\n");
593                 }
594                 schedule_work(&cpufreq_delayed_get_work);
595         }
596 }
597
598 static unsigned int  ref_freq = 0;
599 static unsigned long loops_per_jiffy_ref = 0;
600
601 static unsigned long cpu_khz_ref = 0;
602
603 static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
604                                  void *data)
605 {
606         struct cpufreq_freqs *freq = data;
607         unsigned long *lpj, dummy;
608
609         if (cpu_has(&cpu_data[freq->cpu], X86_FEATURE_CONSTANT_TSC))
610                 return 0;
611
612         lpj = &dummy;
613         if (!(freq->flags & CPUFREQ_CONST_LOOPS))
614 #ifdef CONFIG_SMP
615                 lpj = &cpu_data[freq->cpu].loops_per_jiffy;
616 #else
617                 lpj = &boot_cpu_data.loops_per_jiffy;
618 #endif
619
620         if (!ref_freq) {
621                 ref_freq = freq->old;
622                 loops_per_jiffy_ref = *lpj;
623                 cpu_khz_ref = cpu_khz;
624         }
625         if ((val == CPUFREQ_PRECHANGE  && freq->old < freq->new) ||
626             (val == CPUFREQ_POSTCHANGE && freq->old > freq->new) ||
627             (val == CPUFREQ_RESUMECHANGE)) {
628                 *lpj =
629                 cpufreq_scale(loops_per_jiffy_ref, ref_freq, freq->new);
630
631                 cpu_khz = cpufreq_scale(cpu_khz_ref, ref_freq, freq->new);
632                 if (!(freq->flags & CPUFREQ_CONST_LOOPS))
633                         vxtime.tsc_quot = (USEC_PER_MSEC << US_SCALE) / cpu_khz;
634         }
635         
636         set_cyc2ns_scale(cpu_khz_ref);
637
638         return 0;
639 }
640  
641 static struct notifier_block time_cpufreq_notifier_block = {
642          .notifier_call  = time_cpufreq_notifier
643 };
644
645 static int __init cpufreq_tsc(void)
646 {
647         INIT_WORK(&cpufreq_delayed_get_work, handle_cpufreq_delayed_get, NULL);
648         if (!cpufreq_register_notifier(&time_cpufreq_notifier_block,
649                                        CPUFREQ_TRANSITION_NOTIFIER))
650                 cpufreq_init = 1;
651         return 0;
652 }
653
654 core_initcall(cpufreq_tsc);
655
656 #endif
657
658 /*
659  * calibrate_tsc() calibrates the processor TSC in a very simple way, comparing
660  * it to the HPET timer of known frequency.
661  */
662
663 #define TICK_COUNT 100000000
664
665 static unsigned int __init hpet_calibrate_tsc(void)
666 {
667         int tsc_start, hpet_start;
668         int tsc_now, hpet_now;
669         unsigned long flags;
670
671         local_irq_save(flags);
672         local_irq_disable();
673
674         hpet_start = hpet_readl(HPET_COUNTER);
675         rdtscl(tsc_start);
676
677         do {
678                 local_irq_disable();
679                 hpet_now = hpet_readl(HPET_COUNTER);
680                 tsc_now = get_cycles_sync();
681                 local_irq_restore(flags);
682         } while ((tsc_now - tsc_start) < TICK_COUNT &&
683                  (hpet_now - hpet_start) < TICK_COUNT);
684
685         return (tsc_now - tsc_start) * 1000000000L
686                 / ((hpet_now - hpet_start) * hpet_period / 1000);
687 }
688
689
690 /*
691  * pit_calibrate_tsc() uses the speaker output (channel 2) of
692  * the PIT. This is better than using the timer interrupt output,
693  * because we can read the value of the speaker with just one inb(),
694  * where we need three i/o operations for the interrupt channel.
695  * We count how many ticks the TSC does in 50 ms.
696  */
697
698 static unsigned int __init pit_calibrate_tsc(void)
699 {
700         unsigned long start, end;
701         unsigned long flags;
702
703         spin_lock_irqsave(&i8253_lock, flags);
704
705         outb((inb(0x61) & ~0x02) | 0x01, 0x61);
706
707         outb(0xb0, 0x43);
708         outb((PIT_TICK_RATE / (1000 / 50)) & 0xff, 0x42);
709         outb((PIT_TICK_RATE / (1000 / 50)) >> 8, 0x42);
710         start = get_cycles_sync();
711         while ((inb(0x61) & 0x20) == 0);
712         end = get_cycles_sync();
713
714         spin_unlock_irqrestore(&i8253_lock, flags);
715         
716         return (end - start) / 50;
717 }
718
719 #ifdef  CONFIG_HPET
720 static __init int late_hpet_init(void)
721 {
722         struct hpet_data        hd;
723         unsigned int            ntimer;
724
725         if (!vxtime.hpet_address)
726                 return 0;
727
728         memset(&hd, 0, sizeof (hd));
729
730         ntimer = hpet_readl(HPET_ID);
731         ntimer = (ntimer & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT;
732         ntimer++;
733
734         /*
735          * Register with driver.
736          * Timer0 and Timer1 is used by platform.
737          */
738         hd.hd_phys_address = vxtime.hpet_address;
739         hd.hd_address = (void __iomem *)fix_to_virt(FIX_HPET_BASE);
740         hd.hd_nirqs = ntimer;
741         hd.hd_flags = HPET_DATA_PLATFORM;
742         hpet_reserve_timer(&hd, 0);
743 #ifdef  CONFIG_HPET_EMULATE_RTC
744         hpet_reserve_timer(&hd, 1);
745 #endif
746         hd.hd_irq[0] = HPET_LEGACY_8254;
747         hd.hd_irq[1] = HPET_LEGACY_RTC;
748         if (ntimer > 2) {
749                 struct hpet             *hpet;
750                 struct hpet_timer       *timer;
751                 int                     i;
752
753                 hpet = (struct hpet *) fix_to_virt(FIX_HPET_BASE);
754                 timer = &hpet->hpet_timers[2];
755                 for (i = 2; i < ntimer; timer++, i++)
756                         hd.hd_irq[i] = (timer->hpet_config &
757                                         Tn_INT_ROUTE_CNF_MASK) >>
758                                 Tn_INT_ROUTE_CNF_SHIFT;
759
760         }
761
762         hpet_alloc(&hd);
763         return 0;
764 }
765 fs_initcall(late_hpet_init);
766 #endif
767
768 static int hpet_timer_stop_set_go(unsigned long tick)
769 {
770         unsigned int cfg;
771
772 /*
773  * Stop the timers and reset the main counter.
774  */
775
776         cfg = hpet_readl(HPET_CFG);
777         cfg &= ~(HPET_CFG_ENABLE | HPET_CFG_LEGACY);
778         hpet_writel(cfg, HPET_CFG);
779         hpet_writel(0, HPET_COUNTER);
780         hpet_writel(0, HPET_COUNTER + 4);
781
782 /*
783  * Set up timer 0, as periodic with first interrupt to happen at hpet_tick,
784  * and period also hpet_tick.
785  */
786         if (hpet_use_timer) {
787                 hpet_writel(HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL |
788                     HPET_TN_32BIT, HPET_T0_CFG);
789                 hpet_writel(hpet_tick, HPET_T0_CMP); /* next interrupt */
790                 hpet_writel(hpet_tick, HPET_T0_CMP); /* period */
791                 cfg |= HPET_CFG_LEGACY;
792         }
793 /*
794  * Go!
795  */
796
797         cfg |= HPET_CFG_ENABLE;
798         hpet_writel(cfg, HPET_CFG);
799
800         return 0;
801 }
802
803 static int hpet_init(void)
804 {
805         unsigned int id;
806
807         if (!vxtime.hpet_address)
808                 return -1;
809         set_fixmap_nocache(FIX_HPET_BASE, vxtime.hpet_address);
810         __set_fixmap(VSYSCALL_HPET, vxtime.hpet_address, PAGE_KERNEL_VSYSCALL_NOCACHE);
811
812 /*
813  * Read the period, compute tick and quotient.
814  */
815
816         id = hpet_readl(HPET_ID);
817
818         if (!(id & HPET_ID_VENDOR) || !(id & HPET_ID_NUMBER))
819                 return -1;
820
821         hpet_period = hpet_readl(HPET_PERIOD);
822         if (hpet_period < 100000 || hpet_period > 100000000)
823                 return -1;
824
825         hpet_tick = (FSEC_PER_TICK + hpet_period / 2) / hpet_period;
826
827         hpet_use_timer = (id & HPET_ID_LEGSUP);
828
829         return hpet_timer_stop_set_go(hpet_tick);
830 }
831
832 static int hpet_reenable(void)
833 {
834         return hpet_timer_stop_set_go(hpet_tick);
835 }
836
837 #define PIT_MODE 0x43
838 #define PIT_CH0  0x40
839
840 static void __init __pit_init(int val, u8 mode)
841 {
842         unsigned long flags;
843
844         spin_lock_irqsave(&i8253_lock, flags);
845         outb_p(mode, PIT_MODE);
846         outb_p(val & 0xff, PIT_CH0);    /* LSB */
847         outb_p(val >> 8, PIT_CH0);      /* MSB */
848         spin_unlock_irqrestore(&i8253_lock, flags);
849 }
850
851 void __init pit_init(void)
852 {
853         __pit_init(LATCH, 0x34); /* binary, mode 2, LSB/MSB, ch 0 */
854 }
855
856 void __init pit_stop_interrupt(void)
857 {
858         __pit_init(0, 0x30); /* mode 0 */
859 }
860
861 void __init stop_timer_interrupt(void)
862 {
863         char *name;
864         if (vxtime.hpet_address) {
865                 name = "HPET";
866                 hpet_timer_stop_set_go(0);
867         } else {
868                 name = "PIT";
869                 pit_stop_interrupt();
870         }
871         printk(KERN_INFO "timer: %s interrupt stopped.\n", name);
872 }
873
874 int __init time_setup(char *str)
875 {
876         report_lost_ticks = 1;
877         return 1;
878 }
879
880 static struct irqaction irq0 = {
881         timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL
882 };
883
884 static int __cpuinit
885 time_cpu_notifier(struct notifier_block *nb, unsigned long action, void *hcpu)
886 {
887         unsigned cpu = (unsigned long) hcpu;
888         if (action == CPU_ONLINE)
889                 vsyscall_set_cpu(cpu);
890         return NOTIFY_DONE;
891 }
892
893 void __init time_init(void)
894 {
895         if (nohpet)
896                 vxtime.hpet_address = 0;
897
898         xtime.tv_sec = get_cmos_time();
899         xtime.tv_nsec = 0;
900
901         set_normalized_timespec(&wall_to_monotonic,
902                                 -xtime.tv_sec, -xtime.tv_nsec);
903
904         if (!hpet_init())
905                 vxtime_hz = (FSEC_PER_SEC + hpet_period / 2) / hpet_period;
906         else
907                 vxtime.hpet_address = 0;
908
909         if (hpet_use_timer) {
910                 /* set tick_nsec to use the proper rate for HPET */
911                 tick_nsec = TICK_NSEC_HPET;
912                 cpu_khz = hpet_calibrate_tsc();
913                 timename = "HPET";
914 #ifdef CONFIG_X86_PM_TIMER
915         } else if (pmtmr_ioport && !vxtime.hpet_address) {
916                 vxtime_hz = PM_TIMER_FREQUENCY;
917                 timename = "PM";
918                 pit_init();
919                 cpu_khz = pit_calibrate_tsc();
920 #endif
921         } else {
922                 pit_init();
923                 cpu_khz = pit_calibrate_tsc();
924                 timename = "PIT";
925         }
926
927         vxtime.mode = VXTIME_TSC;
928         vxtime.quot = (USEC_PER_SEC << US_SCALE) / vxtime_hz;
929         vxtime.tsc_quot = (USEC_PER_MSEC << US_SCALE) / cpu_khz;
930         vxtime.last_tsc = get_cycles_sync();
931         set_cyc2ns_scale(cpu_khz);
932         setup_irq(0, &irq0);
933         hotcpu_notifier(time_cpu_notifier, 0);
934         time_cpu_notifier(NULL, CPU_ONLINE, (void *)(long)smp_processor_id());
935
936 #ifndef CONFIG_SMP
937         time_init_gtod();
938 #endif
939 }
940
941 /*
942  * Make an educated guess if the TSC is trustworthy and synchronized
943  * over all CPUs.
944  */
945 __cpuinit int unsynchronized_tsc(void)
946 {
947 #ifdef CONFIG_SMP
948         if (apic_is_clustered_box())
949                 return 1;
950 #endif
951         /* Most intel systems have synchronized TSCs except for
952            multi node systems */
953         if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) {
954 #ifdef CONFIG_ACPI
955                 /* But TSC doesn't tick in C3 so don't use it there */
956                 if (acpi_fadt.length > 0 && acpi_fadt.plvl3_lat < 100)
957                         return 1;
958 #endif
959                 return 0;
960         }
961
962         /* Assume multi socket systems are not synchronized */
963         return num_present_cpus() > 1;
964 }
965
966 /*
967  * Decide what mode gettimeofday should use.
968  */
969 void time_init_gtod(void)
970 {
971         char *timetype;
972
973         if (unsynchronized_tsc())
974                 notsc = 1;
975
976         if (cpu_has(&boot_cpu_data, X86_FEATURE_RDTSCP))
977                 vgetcpu_mode = VGETCPU_RDTSCP;
978         else
979                 vgetcpu_mode = VGETCPU_LSL;
980
981         if (vxtime.hpet_address && notsc) {
982                 timetype = hpet_use_timer ? "HPET" : "PIT/HPET";
983                 if (hpet_use_timer)
984                         vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick;
985                 else
986                         vxtime.last = hpet_readl(HPET_COUNTER);
987                 vxtime.mode = VXTIME_HPET;
988                 do_gettimeoffset = do_gettimeoffset_hpet;
989 #ifdef CONFIG_X86_PM_TIMER
990         /* Using PM for gettimeofday is quite slow, but we have no other
991            choice because the TSC is too unreliable on some systems. */
992         } else if (pmtmr_ioport && !vxtime.hpet_address && notsc) {
993                 timetype = "PM";
994                 do_gettimeoffset = do_gettimeoffset_pm;
995                 vxtime.mode = VXTIME_PMTMR;
996                 sysctl_vsyscall = 0;
997                 printk(KERN_INFO "Disabling vsyscall due to use of PM timer\n");
998 #endif
999         } else {
1000                 timetype = hpet_use_timer ? "HPET/TSC" : "PIT/TSC";
1001                 vxtime.mode = VXTIME_TSC;
1002         }
1003
1004         printk(KERN_INFO "time.c: Using %ld.%06ld MHz WALL %s GTOD %s timer.\n",
1005                vxtime_hz / 1000000, vxtime_hz % 1000000, timename, timetype);
1006         printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n",
1007                 cpu_khz / 1000, cpu_khz % 1000);
1008         vxtime.quot = (USEC_PER_SEC << US_SCALE) / vxtime_hz;
1009         vxtime.tsc_quot = (USEC_PER_MSEC << US_SCALE) / cpu_khz;
1010         vxtime.last_tsc = get_cycles_sync();
1011
1012         set_cyc2ns_scale(cpu_khz);
1013 }
1014
1015 __setup("report_lost_ticks", time_setup);
1016
1017 static long clock_cmos_diff;
1018 static unsigned long sleep_start;
1019
1020 /*
1021  * sysfs support for the timer.
1022  */
1023
1024 static int timer_suspend(struct sys_device *dev, pm_message_t state)
1025 {
1026         /*
1027          * Estimate time zone so that set_time can update the clock
1028          */
1029         long cmos_time =  get_cmos_time();
1030
1031         clock_cmos_diff = -cmos_time;
1032         clock_cmos_diff += get_seconds();
1033         sleep_start = cmos_time;
1034         return 0;
1035 }
1036
1037 static int timer_resume(struct sys_device *dev)
1038 {
1039         unsigned long flags;
1040         unsigned long sec;
1041         unsigned long ctime = get_cmos_time();
1042         long sleep_length = (ctime - sleep_start) * HZ;
1043
1044         if (sleep_length < 0) {
1045                 printk(KERN_WARNING "Time skew detected in timer resume!\n");
1046                 /* The time after the resume must not be earlier than the time
1047                  * before the suspend or some nasty things will happen
1048                  */
1049                 sleep_length = 0;
1050                 ctime = sleep_start;
1051         }
1052         if (vxtime.hpet_address)
1053                 hpet_reenable();
1054         else
1055                 i8254_timer_resume();
1056
1057         sec = ctime + clock_cmos_diff;
1058         write_seqlock_irqsave(&xtime_lock,flags);
1059         xtime.tv_sec = sec;
1060         xtime.tv_nsec = 0;
1061         if (vxtime.mode == VXTIME_HPET) {
1062                 if (hpet_use_timer)
1063                         vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick;
1064                 else
1065                         vxtime.last = hpet_readl(HPET_COUNTER);
1066 #ifdef CONFIG_X86_PM_TIMER
1067         } else if (vxtime.mode == VXTIME_PMTMR) {
1068                 pmtimer_resume();
1069 #endif
1070         } else
1071                 vxtime.last_tsc = get_cycles_sync();
1072         write_sequnlock_irqrestore(&xtime_lock,flags);
1073         jiffies += sleep_length;
1074         wall_jiffies += sleep_length;
1075         monotonic_base += sleep_length * (NSEC_PER_SEC/HZ);
1076         touch_softlockup_watchdog();
1077         return 0;
1078 }
1079
1080 static struct sysdev_class timer_sysclass = {
1081         .resume = timer_resume,
1082         .suspend = timer_suspend,
1083         set_kset_name("timer"),
1084 };
1085
1086 /* XXX this driverfs stuff should probably go elsewhere later -john */
1087 static struct sys_device device_timer = {
1088         .id     = 0,
1089         .cls    = &timer_sysclass,
1090 };
1091
1092 static int time_init_device(void)
1093 {
1094         int error = sysdev_class_register(&timer_sysclass);
1095         if (!error)
1096                 error = sysdev_register(&device_timer);
1097         return error;
1098 }
1099
1100 device_initcall(time_init_device);
1101
1102 #ifdef CONFIG_HPET_EMULATE_RTC
1103 /* HPET in LegacyReplacement Mode eats up RTC interrupt line. When, HPET
1104  * is enabled, we support RTC interrupt functionality in software.
1105  * RTC has 3 kinds of interrupts:
1106  * 1) Update Interrupt - generate an interrupt, every sec, when RTC clock
1107  *    is updated
1108  * 2) Alarm Interrupt - generate an interrupt at a specific time of day
1109  * 3) Periodic Interrupt - generate periodic interrupt, with frequencies
1110  *    2Hz-8192Hz (2Hz-64Hz for non-root user) (all freqs in powers of 2)
1111  * (1) and (2) above are implemented using polling at a frequency of
1112  * 64 Hz. The exact frequency is a tradeoff between accuracy and interrupt
1113  * overhead. (DEFAULT_RTC_INT_FREQ)
1114  * For (3), we use interrupts at 64Hz or user specified periodic
1115  * frequency, whichever is higher.
1116  */
1117 #include <linux/rtc.h>
1118
1119 #define DEFAULT_RTC_INT_FREQ    64
1120 #define RTC_NUM_INTS            1
1121
1122 static unsigned long UIE_on;
1123 static unsigned long prev_update_sec;
1124
1125 static unsigned long AIE_on;
1126 static struct rtc_time alarm_time;
1127
1128 static unsigned long PIE_on;
1129 static unsigned long PIE_freq = DEFAULT_RTC_INT_FREQ;
1130 static unsigned long PIE_count;
1131
1132 static unsigned long hpet_rtc_int_freq; /* RTC interrupt frequency */
1133 static unsigned int hpet_t1_cmp; /* cached comparator register */
1134
1135 int is_hpet_enabled(void)
1136 {
1137         return vxtime.hpet_address != 0;
1138 }
1139
1140 /*
1141  * Timer 1 for RTC, we do not use periodic interrupt feature,
1142  * even if HPET supports periodic interrupts on Timer 1.
1143  * The reason being, to set up a periodic interrupt in HPET, we need to
1144  * stop the main counter. And if we do that everytime someone diables/enables
1145  * RTC, we will have adverse effect on main kernel timer running on Timer 0.
1146  * So, for the time being, simulate the periodic interrupt in software.
1147  *
1148  * hpet_rtc_timer_init() is called for the first time and during subsequent
1149  * interuppts reinit happens through hpet_rtc_timer_reinit().
1150  */
1151 int hpet_rtc_timer_init(void)
1152 {
1153         unsigned int cfg, cnt;
1154         unsigned long flags;
1155
1156         if (!is_hpet_enabled())
1157                 return 0;
1158         /*
1159          * Set the counter 1 and enable the interrupts.
1160          */
1161         if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ))
1162                 hpet_rtc_int_freq = PIE_freq;
1163         else
1164                 hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;
1165
1166         local_irq_save(flags);
1167
1168         cnt = hpet_readl(HPET_COUNTER);
1169         cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq);
1170         hpet_writel(cnt, HPET_T1_CMP);
1171         hpet_t1_cmp = cnt;
1172
1173         cfg = hpet_readl(HPET_T1_CFG);
1174         cfg &= ~HPET_TN_PERIODIC;
1175         cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
1176         hpet_writel(cfg, HPET_T1_CFG);
1177
1178         local_irq_restore(flags);
1179
1180         return 1;
1181 }
1182
1183 static void hpet_rtc_timer_reinit(void)
1184 {
1185         unsigned int cfg, cnt, ticks_per_int, lost_ints;
1186
1187         if (unlikely(!(PIE_on | AIE_on | UIE_on))) {
1188                 cfg = hpet_readl(HPET_T1_CFG);
1189                 cfg &= ~HPET_TN_ENABLE;
1190                 hpet_writel(cfg, HPET_T1_CFG);
1191                 return;
1192         }
1193
1194         if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ))
1195                 hpet_rtc_int_freq = PIE_freq;
1196         else
1197                 hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;
1198
1199         /* It is more accurate to use the comparator value than current count.*/
1200         ticks_per_int = hpet_tick * HZ / hpet_rtc_int_freq;
1201         hpet_t1_cmp += ticks_per_int;
1202         hpet_writel(hpet_t1_cmp, HPET_T1_CMP);
1203
1204         /*
1205          * If the interrupt handler was delayed too long, the write above tries
1206          * to schedule the next interrupt in the past and the hardware would
1207          * not interrupt until the counter had wrapped around.
1208          * So we have to check that the comparator wasn't set to a past time.
1209          */
1210         cnt = hpet_readl(HPET_COUNTER);
1211         if (unlikely((int)(cnt - hpet_t1_cmp) > 0)) {
1212                 lost_ints = (cnt - hpet_t1_cmp) / ticks_per_int + 1;
1213                 /* Make sure that, even with the time needed to execute
1214                  * this code, the next scheduled interrupt has been moved
1215                  * back to the future: */
1216                 lost_ints++;
1217
1218                 hpet_t1_cmp += lost_ints * ticks_per_int;
1219                 hpet_writel(hpet_t1_cmp, HPET_T1_CMP);
1220
1221                 if (PIE_on)
1222                         PIE_count += lost_ints;
1223
1224                 printk(KERN_WARNING "rtc: lost some interrupts at %ldHz.\n",
1225                        hpet_rtc_int_freq);
1226         }
1227 }
1228
1229 /*
1230  * The functions below are called from rtc driver.
1231  * Return 0 if HPET is not being used.
1232  * Otherwise do the necessary changes and return 1.
1233  */
1234 int hpet_mask_rtc_irq_bit(unsigned long bit_mask)
1235 {
1236         if (!is_hpet_enabled())
1237                 return 0;
1238
1239         if (bit_mask & RTC_UIE)
1240                 UIE_on = 0;
1241         if (bit_mask & RTC_PIE)
1242                 PIE_on = 0;
1243         if (bit_mask & RTC_AIE)
1244                 AIE_on = 0;
1245
1246         return 1;
1247 }
1248
1249 int hpet_set_rtc_irq_bit(unsigned long bit_mask)
1250 {
1251         int timer_init_reqd = 0;
1252
1253         if (!is_hpet_enabled())
1254                 return 0;
1255
1256         if (!(PIE_on | AIE_on | UIE_on))
1257                 timer_init_reqd = 1;
1258
1259         if (bit_mask & RTC_UIE) {
1260                 UIE_on = 1;
1261         }
1262         if (bit_mask & RTC_PIE) {
1263                 PIE_on = 1;
1264                 PIE_count = 0;
1265         }
1266         if (bit_mask & RTC_AIE) {
1267                 AIE_on = 1;
1268         }
1269
1270         if (timer_init_reqd)
1271                 hpet_rtc_timer_init();
1272
1273         return 1;
1274 }
1275
1276 int hpet_set_alarm_time(unsigned char hrs, unsigned char min, unsigned char sec)
1277 {
1278         if (!is_hpet_enabled())
1279                 return 0;
1280
1281         alarm_time.tm_hour = hrs;
1282         alarm_time.tm_min = min;
1283         alarm_time.tm_sec = sec;
1284
1285         return 1;
1286 }
1287
1288 int hpet_set_periodic_freq(unsigned long freq)
1289 {
1290         if (!is_hpet_enabled())
1291                 return 0;
1292
1293         PIE_freq = freq;
1294         PIE_count = 0;
1295
1296         return 1;
1297 }
1298
1299 int hpet_rtc_dropped_irq(void)
1300 {
1301         if (!is_hpet_enabled())
1302                 return 0;
1303
1304         return 1;
1305 }
1306
1307 irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1308 {
1309         struct rtc_time curr_time;
1310         unsigned long rtc_int_flag = 0;
1311         int call_rtc_interrupt = 0;
1312
1313         hpet_rtc_timer_reinit();
1314
1315         if (UIE_on | AIE_on) {
1316                 rtc_get_rtc_time(&curr_time);
1317         }
1318         if (UIE_on) {
1319                 if (curr_time.tm_sec != prev_update_sec) {
1320                         /* Set update int info, call real rtc int routine */
1321                         call_rtc_interrupt = 1;
1322                         rtc_int_flag = RTC_UF;
1323                         prev_update_sec = curr_time.tm_sec;
1324                 }
1325         }
1326         if (PIE_on) {
1327                 PIE_count++;
1328                 if (PIE_count >= hpet_rtc_int_freq/PIE_freq) {
1329                         /* Set periodic int info, call real rtc int routine */
1330                         call_rtc_interrupt = 1;
1331                         rtc_int_flag |= RTC_PF;
1332                         PIE_count = 0;
1333                 }
1334         }
1335         if (AIE_on) {
1336                 if ((curr_time.tm_sec == alarm_time.tm_sec) &&
1337                     (curr_time.tm_min == alarm_time.tm_min) &&
1338                     (curr_time.tm_hour == alarm_time.tm_hour)) {
1339                         /* Set alarm int info, call real rtc int routine */
1340                         call_rtc_interrupt = 1;
1341                         rtc_int_flag |= RTC_AF;
1342                 }
1343         }
1344         if (call_rtc_interrupt) {
1345                 rtc_int_flag |= (RTC_IRQF | (RTC_NUM_INTS << 8));
1346                 rtc_interrupt(rtc_int_flag, dev_id, regs);
1347         }
1348         return IRQ_HANDLED;
1349 }
1350 #endif
1351
1352 static int __init nohpet_setup(char *s) 
1353
1354         nohpet = 1;
1355         return 1;
1356
1357
1358 __setup("nohpet", nohpet_setup);
1359
1360 int __init notsc_setup(char *s)
1361 {
1362         notsc = 1;
1363         return 1;
1364 }
1365
1366 __setup("notsc", notsc_setup);