[PATCH] Remove all ifdefs for local/io apic
[sfrench/cifs-2.6.git] / 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 unsigned long long monotonic_clock(void)
280 {
281         unsigned long seq;
282         u32 last_offset, this_offset, offset;
283         unsigned long long base;
284
285         if (vxtime.mode == VXTIME_HPET) {
286                 do {
287                         seq = read_seqbegin(&xtime_lock);
288
289                         last_offset = vxtime.last;
290                         base = monotonic_base;
291                         this_offset = hpet_readl(HPET_COUNTER);
292                 } while (read_seqretry(&xtime_lock, seq));
293                 offset = (this_offset - last_offset);
294                 offset *= NSEC_PER_TICK / hpet_tick;
295         } else {
296                 do {
297                         seq = read_seqbegin(&xtime_lock);
298
299                         last_offset = vxtime.last_tsc;
300                         base = monotonic_base;
301                 } while (read_seqretry(&xtime_lock, seq));
302                 this_offset = get_cycles_sync();
303                 /* FIXME: 1000 or 1000000? */
304                 offset = (this_offset - last_offset)*1000 / cpu_khz;
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                 /* FIXME: 1000 or 1000000? */
409                 monotonic_base += (tsc - vxtime.last_tsc) * 1000000 / cpu_khz;
410
411                 vxtime.last_tsc = tsc - vxtime.quot * delay / vxtime.tsc_quot;
412
413                 if ((((tsc - vxtime.last_tsc) *
414                       vxtime.tsc_quot) >> US_SCALE) < offset)
415                         vxtime.last_tsc = tsc -
416                                 (((long) offset << US_SCALE) / vxtime.tsc_quot) - 1;
417         }
418
419         if (lost > 0) {
420                 handle_lost_ticks(lost, regs);
421                 jiffies += lost;
422         }
423
424 /*
425  * Do the timer stuff.
426  */
427
428         do_timer(regs);
429 #ifndef CONFIG_SMP
430         update_process_times(user_mode(regs));
431 #endif
432
433 /*
434  * In the SMP case we use the local APIC timer interrupt to do the profiling,
435  * except when we simulate SMP mode on a uniprocessor system, in that case we
436  * have to call the local interrupt handler.
437  */
438
439         if (!using_apic_timer)
440                 smp_local_timer_interrupt(regs);
441
442 /*
443  * If we have an externally synchronized Linux clock, then update CMOS clock
444  * accordingly every ~11 minutes. set_rtc_mmss() will be called in the jiffy
445  * closest to exactly 500 ms before the next second. If the update fails, we
446  * don't care, as it'll be updated on the next turn, and the problem (time way
447  * off) isn't likely to go away much sooner anyway.
448  */
449
450         if (ntp_synced() && xtime.tv_sec > rtc_update &&
451                 abs(xtime.tv_nsec - 500000000) <= tick_nsec / 2) {
452                 set_rtc_mmss(xtime.tv_sec);
453                 rtc_update = xtime.tv_sec + 660;
454         }
455  
456         write_sequnlock(&xtime_lock);
457 }
458
459 static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
460 {
461         if (apic_runs_main_timer > 1)
462                 return IRQ_HANDLED;
463         main_timer_handler(regs);
464         if (using_apic_timer)
465                 smp_send_timer_broadcast_ipi();
466         return IRQ_HANDLED;
467 }
468
469 static unsigned int cyc2ns_scale __read_mostly;
470
471 static inline void set_cyc2ns_scale(unsigned long cpu_khz)
472 {
473         cyc2ns_scale = (NSEC_PER_MSEC << NS_SCALE) / cpu_khz;
474 }
475
476 static inline unsigned long long cycles_2_ns(unsigned long long cyc)
477 {
478         return (cyc * cyc2ns_scale) >> NS_SCALE;
479 }
480
481 unsigned long long sched_clock(void)
482 {
483         unsigned long a = 0;
484
485 #if 0
486         /* Don't do a HPET read here. Using TSC always is much faster
487            and HPET may not be mapped yet when the scheduler first runs.
488            Disadvantage is a small drift between CPUs in some configurations,
489            but that should be tolerable. */
490         if (__vxtime.mode == VXTIME_HPET)
491                 return (hpet_readl(HPET_COUNTER) * vxtime.quot) >> US_SCALE;
492 #endif
493
494         /* Could do CPU core sync here. Opteron can execute rdtsc speculatively,
495            which means it is not completely exact and may not be monotonous between
496            CPUs. But the errors should be too small to matter for scheduling
497            purposes. */
498
499         rdtscll(a);
500         return cycles_2_ns(a);
501 }
502
503 static unsigned long get_cmos_time(void)
504 {
505         unsigned int year, mon, day, hour, min, sec;
506         unsigned long flags;
507         unsigned extyear = 0;
508
509         spin_lock_irqsave(&rtc_lock, flags);
510
511         do {
512                 sec = CMOS_READ(RTC_SECONDS);
513                 min = CMOS_READ(RTC_MINUTES);
514                 hour = CMOS_READ(RTC_HOURS);
515                 day = CMOS_READ(RTC_DAY_OF_MONTH);
516                 mon = CMOS_READ(RTC_MONTH);
517                 year = CMOS_READ(RTC_YEAR);
518 #ifdef CONFIG_ACPI
519                 if (acpi_fadt.revision >= FADT2_REVISION_ID &&
520                                         acpi_fadt.century)
521                         extyear = CMOS_READ(acpi_fadt.century);
522 #endif
523         } while (sec != CMOS_READ(RTC_SECONDS));
524
525         spin_unlock_irqrestore(&rtc_lock, flags);
526
527         /*
528          * We know that x86-64 always uses BCD format, no need to check the
529          * config register.
530          */
531
532         BCD_TO_BIN(sec);
533         BCD_TO_BIN(min);
534         BCD_TO_BIN(hour);
535         BCD_TO_BIN(day);
536         BCD_TO_BIN(mon);
537         BCD_TO_BIN(year);
538
539         if (extyear) {
540                 BCD_TO_BIN(extyear);
541                 year += extyear;
542                 printk(KERN_INFO "Extended CMOS year: %d\n", extyear);
543         } else { 
544                 /*
545                  * x86-64 systems only exists since 2002.
546                  * This will work up to Dec 31, 2100
547                  */
548                 year += 2000;
549         }
550
551         return mktime(year, mon, day, hour, min, sec);
552 }
553
554 #ifdef CONFIG_CPU_FREQ
555
556 /* Frequency scaling support. Adjust the TSC based timer when the cpu frequency
557    changes.
558    
559    RED-PEN: On SMP we assume all CPUs run with the same frequency.  It's
560    not that important because current Opteron setups do not support
561    scaling on SMP anyroads.
562
563    Should fix up last_tsc too. Currently gettimeofday in the
564    first tick after the change will be slightly wrong. */
565
566 #include <linux/workqueue.h>
567
568 static unsigned int cpufreq_delayed_issched = 0;
569 static unsigned int cpufreq_init = 0;
570 static struct work_struct cpufreq_delayed_get_work;
571
572 static void handle_cpufreq_delayed_get(void *v)
573 {
574         unsigned int cpu;
575         for_each_online_cpu(cpu) {
576                 cpufreq_get(cpu);
577         }
578         cpufreq_delayed_issched = 0;
579 }
580
581 /* if we notice lost ticks, schedule a call to cpufreq_get() as it tries
582  * to verify the CPU frequency the timing core thinks the CPU is running
583  * at is still correct.
584  */
585 static void cpufreq_delayed_get(void)
586 {
587         static int warned;
588         if (cpufreq_init && !cpufreq_delayed_issched) {
589                 cpufreq_delayed_issched = 1;
590                 if (!warned) {
591                         warned = 1;
592                         printk(KERN_DEBUG 
593         "Losing some ticks... checking if CPU frequency changed.\n");
594                 }
595                 schedule_work(&cpufreq_delayed_get_work);
596         }
597 }
598
599 static unsigned int  ref_freq = 0;
600 static unsigned long loops_per_jiffy_ref = 0;
601
602 static unsigned long cpu_khz_ref = 0;
603
604 static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
605                                  void *data)
606 {
607         struct cpufreq_freqs *freq = data;
608         unsigned long *lpj, dummy;
609
610         if (cpu_has(&cpu_data[freq->cpu], X86_FEATURE_CONSTANT_TSC))
611                 return 0;
612
613         lpj = &dummy;
614         if (!(freq->flags & CPUFREQ_CONST_LOOPS))
615 #ifdef CONFIG_SMP
616                 lpj = &cpu_data[freq->cpu].loops_per_jiffy;
617 #else
618                 lpj = &boot_cpu_data.loops_per_jiffy;
619 #endif
620
621         if (!ref_freq) {
622                 ref_freq = freq->old;
623                 loops_per_jiffy_ref = *lpj;
624                 cpu_khz_ref = cpu_khz;
625         }
626         if ((val == CPUFREQ_PRECHANGE  && freq->old < freq->new) ||
627             (val == CPUFREQ_POSTCHANGE && freq->old > freq->new) ||
628             (val == CPUFREQ_RESUMECHANGE)) {
629                 *lpj =
630                 cpufreq_scale(loops_per_jiffy_ref, ref_freq, freq->new);
631
632                 cpu_khz = cpufreq_scale(cpu_khz_ref, ref_freq, freq->new);
633                 if (!(freq->flags & CPUFREQ_CONST_LOOPS))
634                         vxtime.tsc_quot = (USEC_PER_MSEC << US_SCALE) / cpu_khz;
635         }
636         
637         set_cyc2ns_scale(cpu_khz_ref);
638
639         return 0;
640 }
641  
642 static struct notifier_block time_cpufreq_notifier_block = {
643          .notifier_call  = time_cpufreq_notifier
644 };
645
646 static int __init cpufreq_tsc(void)
647 {
648         INIT_WORK(&cpufreq_delayed_get_work, handle_cpufreq_delayed_get, NULL);
649         if (!cpufreq_register_notifier(&time_cpufreq_notifier_block,
650                                        CPUFREQ_TRANSITION_NOTIFIER))
651                 cpufreq_init = 1;
652         return 0;
653 }
654
655 core_initcall(cpufreq_tsc);
656
657 #endif
658
659 /*
660  * calibrate_tsc() calibrates the processor TSC in a very simple way, comparing
661  * it to the HPET timer of known frequency.
662  */
663
664 #define TICK_COUNT 100000000
665
666 static unsigned int __init hpet_calibrate_tsc(void)
667 {
668         int tsc_start, hpet_start;
669         int tsc_now, hpet_now;
670         unsigned long flags;
671
672         local_irq_save(flags);
673         local_irq_disable();
674
675         hpet_start = hpet_readl(HPET_COUNTER);
676         rdtscl(tsc_start);
677
678         do {
679                 local_irq_disable();
680                 hpet_now = hpet_readl(HPET_COUNTER);
681                 tsc_now = get_cycles_sync();
682                 local_irq_restore(flags);
683         } while ((tsc_now - tsc_start) < TICK_COUNT &&
684                  (hpet_now - hpet_start) < TICK_COUNT);
685
686         return (tsc_now - tsc_start) * 1000000000L
687                 / ((hpet_now - hpet_start) * hpet_period / 1000);
688 }
689
690
691 /*
692  * pit_calibrate_tsc() uses the speaker output (channel 2) of
693  * the PIT. This is better than using the timer interrupt output,
694  * because we can read the value of the speaker with just one inb(),
695  * where we need three i/o operations for the interrupt channel.
696  * We count how many ticks the TSC does in 50 ms.
697  */
698
699 static unsigned int __init pit_calibrate_tsc(void)
700 {
701         unsigned long start, end;
702         unsigned long flags;
703
704         spin_lock_irqsave(&i8253_lock, flags);
705
706         outb((inb(0x61) & ~0x02) | 0x01, 0x61);
707
708         outb(0xb0, 0x43);
709         outb((PIT_TICK_RATE / (1000 / 50)) & 0xff, 0x42);
710         outb((PIT_TICK_RATE / (1000 / 50)) >> 8, 0x42);
711         start = get_cycles_sync();
712         while ((inb(0x61) & 0x20) == 0);
713         end = get_cycles_sync();
714
715         spin_unlock_irqrestore(&i8253_lock, flags);
716         
717         return (end - start) / 50;
718 }
719
720 #ifdef  CONFIG_HPET
721 static __init int late_hpet_init(void)
722 {
723         struct hpet_data        hd;
724         unsigned int            ntimer;
725
726         if (!vxtime.hpet_address)
727                 return 0;
728
729         memset(&hd, 0, sizeof (hd));
730
731         ntimer = hpet_readl(HPET_ID);
732         ntimer = (ntimer & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT;
733         ntimer++;
734
735         /*
736          * Register with driver.
737          * Timer0 and Timer1 is used by platform.
738          */
739         hd.hd_phys_address = vxtime.hpet_address;
740         hd.hd_address = (void __iomem *)fix_to_virt(FIX_HPET_BASE);
741         hd.hd_nirqs = ntimer;
742         hd.hd_flags = HPET_DATA_PLATFORM;
743         hpet_reserve_timer(&hd, 0);
744 #ifdef  CONFIG_HPET_EMULATE_RTC
745         hpet_reserve_timer(&hd, 1);
746 #endif
747         hd.hd_irq[0] = HPET_LEGACY_8254;
748         hd.hd_irq[1] = HPET_LEGACY_RTC;
749         if (ntimer > 2) {
750                 struct hpet             *hpet;
751                 struct hpet_timer       *timer;
752                 int                     i;
753
754                 hpet = (struct hpet *) fix_to_virt(FIX_HPET_BASE);
755                 timer = &hpet->hpet_timers[2];
756                 for (i = 2; i < ntimer; timer++, i++)
757                         hd.hd_irq[i] = (timer->hpet_config &
758                                         Tn_INT_ROUTE_CNF_MASK) >>
759                                 Tn_INT_ROUTE_CNF_SHIFT;
760
761         }
762
763         hpet_alloc(&hd);
764         return 0;
765 }
766 fs_initcall(late_hpet_init);
767 #endif
768
769 static int hpet_timer_stop_set_go(unsigned long tick)
770 {
771         unsigned int cfg;
772
773 /*
774  * Stop the timers and reset the main counter.
775  */
776
777         cfg = hpet_readl(HPET_CFG);
778         cfg &= ~(HPET_CFG_ENABLE | HPET_CFG_LEGACY);
779         hpet_writel(cfg, HPET_CFG);
780         hpet_writel(0, HPET_COUNTER);
781         hpet_writel(0, HPET_COUNTER + 4);
782
783 /*
784  * Set up timer 0, as periodic with first interrupt to happen at hpet_tick,
785  * and period also hpet_tick.
786  */
787         if (hpet_use_timer) {
788                 hpet_writel(HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL |
789                     HPET_TN_32BIT, HPET_T0_CFG);
790                 hpet_writel(hpet_tick, HPET_T0_CMP); /* next interrupt */
791                 hpet_writel(hpet_tick, HPET_T0_CMP); /* period */
792                 cfg |= HPET_CFG_LEGACY;
793         }
794 /*
795  * Go!
796  */
797
798         cfg |= HPET_CFG_ENABLE;
799         hpet_writel(cfg, HPET_CFG);
800
801         return 0;
802 }
803
804 static int hpet_init(void)
805 {
806         unsigned int id;
807
808         if (!vxtime.hpet_address)
809                 return -1;
810         set_fixmap_nocache(FIX_HPET_BASE, vxtime.hpet_address);
811         __set_fixmap(VSYSCALL_HPET, vxtime.hpet_address, PAGE_KERNEL_VSYSCALL_NOCACHE);
812
813 /*
814  * Read the period, compute tick and quotient.
815  */
816
817         id = hpet_readl(HPET_ID);
818
819         if (!(id & HPET_ID_VENDOR) || !(id & HPET_ID_NUMBER))
820                 return -1;
821
822         hpet_period = hpet_readl(HPET_PERIOD);
823         if (hpet_period < 100000 || hpet_period > 100000000)
824                 return -1;
825
826         hpet_tick = (FSEC_PER_TICK + hpet_period / 2) / hpet_period;
827
828         hpet_use_timer = (id & HPET_ID_LEGSUP);
829
830         return hpet_timer_stop_set_go(hpet_tick);
831 }
832
833 static int hpet_reenable(void)
834 {
835         return hpet_timer_stop_set_go(hpet_tick);
836 }
837
838 #define PIT_MODE 0x43
839 #define PIT_CH0  0x40
840
841 static void __init __pit_init(int val, u8 mode)
842 {
843         unsigned long flags;
844
845         spin_lock_irqsave(&i8253_lock, flags);
846         outb_p(mode, PIT_MODE);
847         outb_p(val & 0xff, PIT_CH0);    /* LSB */
848         outb_p(val >> 8, PIT_CH0);      /* MSB */
849         spin_unlock_irqrestore(&i8253_lock, flags);
850 }
851
852 void __init pit_init(void)
853 {
854         __pit_init(LATCH, 0x34); /* binary, mode 2, LSB/MSB, ch 0 */
855 }
856
857 void __init pit_stop_interrupt(void)
858 {
859         __pit_init(0, 0x30); /* mode 0 */
860 }
861
862 void __init stop_timer_interrupt(void)
863 {
864         char *name;
865         if (vxtime.hpet_address) {
866                 name = "HPET";
867                 hpet_timer_stop_set_go(0);
868         } else {
869                 name = "PIT";
870                 pit_stop_interrupt();
871         }
872         printk(KERN_INFO "timer: %s interrupt stopped.\n", name);
873 }
874
875 int __init time_setup(char *str)
876 {
877         report_lost_ticks = 1;
878         return 1;
879 }
880
881 static struct irqaction irq0 = {
882         timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL
883 };
884
885 static int __cpuinit
886 time_cpu_notifier(struct notifier_block *nb, unsigned long action, void *hcpu)
887 {
888         unsigned cpu = (unsigned long) hcpu;
889         if (action == CPU_ONLINE)
890                 vsyscall_set_cpu(cpu);
891         return NOTIFY_DONE;
892 }
893
894 void __init time_init(void)
895 {
896         if (nohpet)
897                 vxtime.hpet_address = 0;
898
899         xtime.tv_sec = get_cmos_time();
900         xtime.tv_nsec = 0;
901
902         set_normalized_timespec(&wall_to_monotonic,
903                                 -xtime.tv_sec, -xtime.tv_nsec);
904
905         if (!hpet_init())
906                 vxtime_hz = (FSEC_PER_SEC + hpet_period / 2) / hpet_period;
907         else
908                 vxtime.hpet_address = 0;
909
910         if (hpet_use_timer) {
911                 /* set tick_nsec to use the proper rate for HPET */
912                 tick_nsec = TICK_NSEC_HPET;
913                 cpu_khz = hpet_calibrate_tsc();
914                 timename = "HPET";
915 #ifdef CONFIG_X86_PM_TIMER
916         } else if (pmtmr_ioport && !vxtime.hpet_address) {
917                 vxtime_hz = PM_TIMER_FREQUENCY;
918                 timename = "PM";
919                 pit_init();
920                 cpu_khz = pit_calibrate_tsc();
921 #endif
922         } else {
923                 pit_init();
924                 cpu_khz = pit_calibrate_tsc();
925                 timename = "PIT";
926         }
927
928         vxtime.mode = VXTIME_TSC;
929         vxtime.quot = (USEC_PER_SEC << US_SCALE) / vxtime_hz;
930         vxtime.tsc_quot = (USEC_PER_MSEC << US_SCALE) / cpu_khz;
931         vxtime.last_tsc = get_cycles_sync();
932         setup_irq(0, &irq0);
933
934         set_cyc2ns_scale(cpu_khz);
935
936         hotcpu_notifier(time_cpu_notifier, 0);
937         time_cpu_notifier(NULL, CPU_ONLINE, (void *)(long)smp_processor_id());
938
939 #ifndef CONFIG_SMP
940         time_init_gtod();
941 #endif
942 }
943
944 /*
945  * Make an educated guess if the TSC is trustworthy and synchronized
946  * over all CPUs.
947  */
948 __cpuinit int unsynchronized_tsc(void)
949 {
950 #ifdef CONFIG_SMP
951         if (apic_is_clustered_box())
952                 return 1;
953 #endif
954         /* Most intel systems have synchronized TSCs except for
955            multi node systems */
956         if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) {
957 #ifdef CONFIG_ACPI
958                 /* But TSC doesn't tick in C3 so don't use it there */
959                 if (acpi_fadt.length > 0 && acpi_fadt.plvl3_lat < 100)
960                         return 1;
961 #endif
962                 return 0;
963         }
964
965         /* Assume multi socket systems are not synchronized */
966         return num_present_cpus() > 1;
967 }
968
969 /*
970  * Decide what mode gettimeofday should use.
971  */
972 void time_init_gtod(void)
973 {
974         char *timetype;
975
976         if (unsynchronized_tsc())
977                 notsc = 1;
978
979         if (cpu_has(&boot_cpu_data, X86_FEATURE_RDTSCP))
980                 vgetcpu_mode = VGETCPU_RDTSCP;
981         else
982                 vgetcpu_mode = VGETCPU_LSL;
983
984         if (vxtime.hpet_address && notsc) {
985                 timetype = hpet_use_timer ? "HPET" : "PIT/HPET";
986                 if (hpet_use_timer)
987                         vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick;
988                 else
989                         vxtime.last = hpet_readl(HPET_COUNTER);
990                 vxtime.mode = VXTIME_HPET;
991                 do_gettimeoffset = do_gettimeoffset_hpet;
992 #ifdef CONFIG_X86_PM_TIMER
993         /* Using PM for gettimeofday is quite slow, but we have no other
994            choice because the TSC is too unreliable on some systems. */
995         } else if (pmtmr_ioport && !vxtime.hpet_address && notsc) {
996                 timetype = "PM";
997                 do_gettimeoffset = do_gettimeoffset_pm;
998                 vxtime.mode = VXTIME_PMTMR;
999                 sysctl_vsyscall = 0;
1000                 printk(KERN_INFO "Disabling vsyscall due to use of PM timer\n");
1001 #endif
1002         } else {
1003                 timetype = hpet_use_timer ? "HPET/TSC" : "PIT/TSC";
1004                 vxtime.mode = VXTIME_TSC;
1005         }
1006
1007         printk(KERN_INFO "time.c: Using %ld.%06ld MHz WALL %s GTOD %s timer.\n",
1008                vxtime_hz / 1000000, vxtime_hz % 1000000, timename, timetype);
1009         printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n",
1010                 cpu_khz / 1000, cpu_khz % 1000);
1011         vxtime.quot = (USEC_PER_SEC << US_SCALE) / vxtime_hz;
1012         vxtime.tsc_quot = (USEC_PER_MSEC << US_SCALE) / cpu_khz;
1013         vxtime.last_tsc = get_cycles_sync();
1014
1015         set_cyc2ns_scale(cpu_khz);
1016 }
1017
1018 __setup("report_lost_ticks", time_setup);
1019
1020 static long clock_cmos_diff;
1021 static unsigned long sleep_start;
1022
1023 /*
1024  * sysfs support for the timer.
1025  */
1026
1027 static int timer_suspend(struct sys_device *dev, pm_message_t state)
1028 {
1029         /*
1030          * Estimate time zone so that set_time can update the clock
1031          */
1032         long cmos_time =  get_cmos_time();
1033
1034         clock_cmos_diff = -cmos_time;
1035         clock_cmos_diff += get_seconds();
1036         sleep_start = cmos_time;
1037         return 0;
1038 }
1039
1040 static int timer_resume(struct sys_device *dev)
1041 {
1042         unsigned long flags;
1043         unsigned long sec;
1044         unsigned long ctime = get_cmos_time();
1045         unsigned long sleep_length = (ctime - sleep_start) * HZ;
1046
1047         if (vxtime.hpet_address)
1048                 hpet_reenable();
1049         else
1050                 i8254_timer_resume();
1051
1052         sec = ctime + clock_cmos_diff;
1053         write_seqlock_irqsave(&xtime_lock,flags);
1054         xtime.tv_sec = sec;
1055         xtime.tv_nsec = 0;
1056         if (vxtime.mode == VXTIME_HPET) {
1057                 if (hpet_use_timer)
1058                         vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick;
1059                 else
1060                         vxtime.last = hpet_readl(HPET_COUNTER);
1061 #ifdef CONFIG_X86_PM_TIMER
1062         } else if (vxtime.mode == VXTIME_PMTMR) {
1063                 pmtimer_resume();
1064 #endif
1065         } else
1066                 vxtime.last_tsc = get_cycles_sync();
1067         write_sequnlock_irqrestore(&xtime_lock,flags);
1068         jiffies += sleep_length;
1069         wall_jiffies += sleep_length;
1070         monotonic_base += sleep_length * (NSEC_PER_SEC/HZ);
1071         touch_softlockup_watchdog();
1072         return 0;
1073 }
1074
1075 static struct sysdev_class timer_sysclass = {
1076         .resume = timer_resume,
1077         .suspend = timer_suspend,
1078         set_kset_name("timer"),
1079 };
1080
1081 /* XXX this driverfs stuff should probably go elsewhere later -john */
1082 static struct sys_device device_timer = {
1083         .id     = 0,
1084         .cls    = &timer_sysclass,
1085 };
1086
1087 static int time_init_device(void)
1088 {
1089         int error = sysdev_class_register(&timer_sysclass);
1090         if (!error)
1091                 error = sysdev_register(&device_timer);
1092         return error;
1093 }
1094
1095 device_initcall(time_init_device);
1096
1097 #ifdef CONFIG_HPET_EMULATE_RTC
1098 /* HPET in LegacyReplacement Mode eats up RTC interrupt line. When, HPET
1099  * is enabled, we support RTC interrupt functionality in software.
1100  * RTC has 3 kinds of interrupts:
1101  * 1) Update Interrupt - generate an interrupt, every sec, when RTC clock
1102  *    is updated
1103  * 2) Alarm Interrupt - generate an interrupt at a specific time of day
1104  * 3) Periodic Interrupt - generate periodic interrupt, with frequencies
1105  *    2Hz-8192Hz (2Hz-64Hz for non-root user) (all freqs in powers of 2)
1106  * (1) and (2) above are implemented using polling at a frequency of
1107  * 64 Hz. The exact frequency is a tradeoff between accuracy and interrupt
1108  * overhead. (DEFAULT_RTC_INT_FREQ)
1109  * For (3), we use interrupts at 64Hz or user specified periodic
1110  * frequency, whichever is higher.
1111  */
1112 #include <linux/rtc.h>
1113
1114 #define DEFAULT_RTC_INT_FREQ    64
1115 #define RTC_NUM_INTS            1
1116
1117 static unsigned long UIE_on;
1118 static unsigned long prev_update_sec;
1119
1120 static unsigned long AIE_on;
1121 static struct rtc_time alarm_time;
1122
1123 static unsigned long PIE_on;
1124 static unsigned long PIE_freq = DEFAULT_RTC_INT_FREQ;
1125 static unsigned long PIE_count;
1126
1127 static unsigned long hpet_rtc_int_freq; /* RTC interrupt frequency */
1128 static unsigned int hpet_t1_cmp; /* cached comparator register */
1129
1130 int is_hpet_enabled(void)
1131 {
1132         return vxtime.hpet_address != 0;
1133 }
1134
1135 /*
1136  * Timer 1 for RTC, we do not use periodic interrupt feature,
1137  * even if HPET supports periodic interrupts on Timer 1.
1138  * The reason being, to set up a periodic interrupt in HPET, we need to
1139  * stop the main counter. And if we do that everytime someone diables/enables
1140  * RTC, we will have adverse effect on main kernel timer running on Timer 0.
1141  * So, for the time being, simulate the periodic interrupt in software.
1142  *
1143  * hpet_rtc_timer_init() is called for the first time and during subsequent
1144  * interuppts reinit happens through hpet_rtc_timer_reinit().
1145  */
1146 int hpet_rtc_timer_init(void)
1147 {
1148         unsigned int cfg, cnt;
1149         unsigned long flags;
1150
1151         if (!is_hpet_enabled())
1152                 return 0;
1153         /*
1154          * Set the counter 1 and enable the interrupts.
1155          */
1156         if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ))
1157                 hpet_rtc_int_freq = PIE_freq;
1158         else
1159                 hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;
1160
1161         local_irq_save(flags);
1162         cnt = hpet_readl(HPET_COUNTER);
1163         cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq);
1164         hpet_writel(cnt, HPET_T1_CMP);
1165         hpet_t1_cmp = cnt;
1166         local_irq_restore(flags);
1167
1168         cfg = hpet_readl(HPET_T1_CFG);
1169         cfg &= ~HPET_TN_PERIODIC;
1170         cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
1171         hpet_writel(cfg, HPET_T1_CFG);
1172
1173         return 1;
1174 }
1175
1176 static void hpet_rtc_timer_reinit(void)
1177 {
1178         unsigned int cfg, cnt;
1179
1180         if (unlikely(!(PIE_on | AIE_on | UIE_on))) {
1181                 cfg = hpet_readl(HPET_T1_CFG);
1182                 cfg &= ~HPET_TN_ENABLE;
1183                 hpet_writel(cfg, HPET_T1_CFG);
1184                 return;
1185         }
1186
1187         if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ))
1188                 hpet_rtc_int_freq = PIE_freq;
1189         else
1190                 hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;
1191
1192         /* It is more accurate to use the comparator value than current count.*/
1193         cnt = hpet_t1_cmp;
1194         cnt += hpet_tick*HZ/hpet_rtc_int_freq;
1195         hpet_writel(cnt, HPET_T1_CMP);
1196         hpet_t1_cmp = cnt;
1197 }
1198
1199 /*
1200  * The functions below are called from rtc driver.
1201  * Return 0 if HPET is not being used.
1202  * Otherwise do the necessary changes and return 1.
1203  */
1204 int hpet_mask_rtc_irq_bit(unsigned long bit_mask)
1205 {
1206         if (!is_hpet_enabled())
1207                 return 0;
1208
1209         if (bit_mask & RTC_UIE)
1210                 UIE_on = 0;
1211         if (bit_mask & RTC_PIE)
1212                 PIE_on = 0;
1213         if (bit_mask & RTC_AIE)
1214                 AIE_on = 0;
1215
1216         return 1;
1217 }
1218
1219 int hpet_set_rtc_irq_bit(unsigned long bit_mask)
1220 {
1221         int timer_init_reqd = 0;
1222
1223         if (!is_hpet_enabled())
1224                 return 0;
1225
1226         if (!(PIE_on | AIE_on | UIE_on))
1227                 timer_init_reqd = 1;
1228
1229         if (bit_mask & RTC_UIE) {
1230                 UIE_on = 1;
1231         }
1232         if (bit_mask & RTC_PIE) {
1233                 PIE_on = 1;
1234                 PIE_count = 0;
1235         }
1236         if (bit_mask & RTC_AIE) {
1237                 AIE_on = 1;
1238         }
1239
1240         if (timer_init_reqd)
1241                 hpet_rtc_timer_init();
1242
1243         return 1;
1244 }
1245
1246 int hpet_set_alarm_time(unsigned char hrs, unsigned char min, unsigned char sec)
1247 {
1248         if (!is_hpet_enabled())
1249                 return 0;
1250
1251         alarm_time.tm_hour = hrs;
1252         alarm_time.tm_min = min;
1253         alarm_time.tm_sec = sec;
1254
1255         return 1;
1256 }
1257
1258 int hpet_set_periodic_freq(unsigned long freq)
1259 {
1260         if (!is_hpet_enabled())
1261                 return 0;
1262
1263         PIE_freq = freq;
1264         PIE_count = 0;
1265
1266         return 1;
1267 }
1268
1269 int hpet_rtc_dropped_irq(void)
1270 {
1271         if (!is_hpet_enabled())
1272                 return 0;
1273
1274         return 1;
1275 }
1276
1277 irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1278 {
1279         struct rtc_time curr_time;
1280         unsigned long rtc_int_flag = 0;
1281         int call_rtc_interrupt = 0;
1282
1283         hpet_rtc_timer_reinit();
1284
1285         if (UIE_on | AIE_on) {
1286                 rtc_get_rtc_time(&curr_time);
1287         }
1288         if (UIE_on) {
1289                 if (curr_time.tm_sec != prev_update_sec) {
1290                         /* Set update int info, call real rtc int routine */
1291                         call_rtc_interrupt = 1;
1292                         rtc_int_flag = RTC_UF;
1293                         prev_update_sec = curr_time.tm_sec;
1294                 }
1295         }
1296         if (PIE_on) {
1297                 PIE_count++;
1298                 if (PIE_count >= hpet_rtc_int_freq/PIE_freq) {
1299                         /* Set periodic int info, call real rtc int routine */
1300                         call_rtc_interrupt = 1;
1301                         rtc_int_flag |= RTC_PF;
1302                         PIE_count = 0;
1303                 }
1304         }
1305         if (AIE_on) {
1306                 if ((curr_time.tm_sec == alarm_time.tm_sec) &&
1307                     (curr_time.tm_min == alarm_time.tm_min) &&
1308                     (curr_time.tm_hour == alarm_time.tm_hour)) {
1309                         /* Set alarm int info, call real rtc int routine */
1310                         call_rtc_interrupt = 1;
1311                         rtc_int_flag |= RTC_AF;
1312                 }
1313         }
1314         if (call_rtc_interrupt) {
1315                 rtc_int_flag |= (RTC_IRQF | (RTC_NUM_INTS << 8));
1316                 rtc_interrupt(rtc_int_flag, dev_id, regs);
1317         }
1318         return IRQ_HANDLED;
1319 }
1320 #endif
1321
1322 static int __init nohpet_setup(char *s) 
1323
1324         nohpet = 1;
1325         return 1;
1326
1327
1328 __setup("nohpet", nohpet_setup);
1329
1330 int __init notsc_setup(char *s)
1331 {
1332         notsc = 1;
1333         return 1;
1334 }
1335
1336 __setup("notsc", notsc_setup);