[MIPS] time: Remove now unused local_timer_interrupt.
[linux-2.6] / arch / mips / kernel / time.c
1 /*
2  * Copyright 2001 MontaVista Software Inc.
3  * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
4  * Copyright (c) 2003, 2004  Maciej W. Rozycki
5  *
6  * Common time service routines for MIPS machines. See
7  * Documentation/mips/time.README.
8  *
9  * This program is free software; you can redistribute  it and/or modify it
10  * under  the terms of  the GNU General  Public License as published by the
11  * Free Software Foundation;  either version 2 of the  License, or (at your
12  * option) any later version.
13  */
14 #include <linux/bug.h>
15 #include <linux/clockchips.h>
16 #include <linux/types.h>
17 #include <linux/kernel.h>
18 #include <linux/init.h>
19 #include <linux/sched.h>
20 #include <linux/param.h>
21 #include <linux/profile.h>
22 #include <linux/time.h>
23 #include <linux/timex.h>
24 #include <linux/smp.h>
25 #include <linux/kernel_stat.h>
26 #include <linux/spinlock.h>
27 #include <linux/interrupt.h>
28 #include <linux/module.h>
29 #include <linux/kallsyms.h>
30
31 #include <asm/bootinfo.h>
32 #include <asm/cache.h>
33 #include <asm/compiler.h>
34 #include <asm/cpu.h>
35 #include <asm/cpu-features.h>
36 #include <asm/div64.h>
37 #include <asm/sections.h>
38 #include <asm/smtc_ipi.h>
39 #include <asm/time.h>
40
41 #include <irq.h>
42
43 /*
44  * forward reference
45  */
46 DEFINE_SPINLOCK(rtc_lock);
47 EXPORT_SYMBOL(rtc_lock);
48
49 int __weak rtc_mips_set_time(unsigned long sec)
50 {
51         return 0;
52 }
53 EXPORT_SYMBOL(rtc_mips_set_time);
54
55 int __weak rtc_mips_set_mmss(unsigned long nowtime)
56 {
57         return rtc_mips_set_time(nowtime);
58 }
59
60 int update_persistent_clock(struct timespec now)
61 {
62         return rtc_mips_set_mmss(now.tv_sec);
63 }
64
65 /*
66  * Null high precision timer functions for systems lacking one.
67  */
68 static cycle_t null_hpt_read(void)
69 {
70         return 0;
71 }
72
73 /*
74  * High precision timer functions for a R4k-compatible timer.
75  */
76 static cycle_t c0_hpt_read(void)
77 {
78         return read_c0_count();
79 }
80
81 int (*mips_timer_state)(void);
82
83 int null_perf_irq(void)
84 {
85         return 0;
86 }
87
88 EXPORT_SYMBOL(null_perf_irq);
89
90 int (*perf_irq)(void) = null_perf_irq;
91
92 EXPORT_SYMBOL(perf_irq);
93
94 /*
95  * time_init() - it does the following things.
96  *
97  * 1) plat_time_init() -
98  *      a) (optional) set up RTC routines,
99  *      b) (optional) calibrate and set the mips_hpt_frequency
100  *          (only needed if you intended to use cpu counter as timer interrupt
101  *           source)
102  * 2) calculate a couple of cached variables for later usage
103  */
104
105 unsigned int mips_hpt_frequency;
106
107 static unsigned int __init calibrate_hpt(void)
108 {
109         cycle_t frequency, hpt_start, hpt_end, hpt_count, hz;
110
111         const int loops = HZ / 10;
112         int log_2_loops = 0;
113         int i;
114
115         /*
116          * We want to calibrate for 0.1s, but to avoid a 64-bit
117          * division we round the number of loops up to the nearest
118          * power of 2.
119          */
120         while (loops > 1 << log_2_loops)
121                 log_2_loops++;
122         i = 1 << log_2_loops;
123
124         /*
125          * Wait for a rising edge of the timer interrupt.
126          */
127         while (mips_timer_state());
128         while (!mips_timer_state());
129
130         /*
131          * Now see how many high precision timer ticks happen
132          * during the calculated number of periods between timer
133          * interrupts.
134          */
135         hpt_start = clocksource_mips.read();
136         do {
137                 while (mips_timer_state());
138                 while (!mips_timer_state());
139         } while (--i);
140         hpt_end = clocksource_mips.read();
141
142         hpt_count = (hpt_end - hpt_start) & clocksource_mips.mask;
143         hz = HZ;
144         frequency = hpt_count * hz;
145
146         return frequency >> log_2_loops;
147 }
148
149 struct clocksource clocksource_mips = {
150         .name           = "MIPS",
151         .mask           = CLOCKSOURCE_MASK(32),
152         .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
153 };
154
155 void __init clocksource_set_clock(struct clocksource *cs, unsigned int clock)
156 {
157         u64 temp;
158         u32 shift;
159
160         /* Find a shift value */
161         for (shift = 32; shift > 0; shift--) {
162                 temp = (u64) NSEC_PER_SEC << shift;
163                 do_div(temp, clock);
164                 if ((temp >> 32) == 0)
165                         break;
166         }
167         cs->shift = shift;
168         cs->mult = (u32) temp;
169 }
170
171 void __cpuinit clockevent_set_clock(struct clock_event_device *cd,
172         unsigned int clock)
173 {
174         u64 temp;
175         u32 shift;
176
177         /* Find a shift value */
178         for (shift = 32; shift > 0; shift--) {
179                 temp = (u64) clock << shift;
180                 do_div(temp, NSEC_PER_SEC);
181                 if ((temp >> 32) == 0)
182                         break;
183         }
184         cd->shift = shift;
185         cd->mult = (u32) temp;
186 }
187
188 static void __init init_mips_clocksource(void)
189 {
190         if (!mips_hpt_frequency || clocksource_mips.read == null_hpt_read)
191                 return;
192
193         /* Calclate a somewhat reasonable rating value */
194         clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000;
195
196         clocksource_set_clock(&clocksource_mips, mips_hpt_frequency);
197
198         clocksource_register(&clocksource_mips);
199 }
200
201 void __init __weak plat_time_init(void)
202 {
203 }
204
205 /*
206  * This function exists in order to cause an error due to a duplicate
207  * definition if platform code should have its own implementation.  The hook
208  * to use instead is plat_time_init.  plat_time_init does not receive the
209  * irqaction pointer argument anymore.  This is because any function which
210  * initializes an interrupt timer now takes care of its own request_irq rsp.
211  * setup_irq calls and each clock_event_device should use its own
212  * struct irqrequest.
213  */
214 void __init plat_timer_setup(struct irqaction *irq)
215 {
216         BUG();
217 }
218
219 void __init time_init(void)
220 {
221         plat_time_init();
222
223         /* Choose appropriate high precision timer routines.  */
224         if (!cpu_has_counter && !clocksource_mips.read)
225                 /* No high precision timer -- sorry.  */
226                 clocksource_mips.read = null_hpt_read;
227         else if (!mips_hpt_frequency && !mips_timer_state) {
228                 /* A high precision timer of unknown frequency.  */
229                 if (!clocksource_mips.read)
230                         /* No external high precision timer -- use R4k.  */
231                         clocksource_mips.read = c0_hpt_read;
232         } else {
233                 /* We know counter frequency.  Or we can get it.  */
234                 if (!clocksource_mips.read) {
235                         /* No external high precision timer -- use R4k.  */
236                         clocksource_mips.read = c0_hpt_read;
237                 }
238                 if (!mips_hpt_frequency)
239                         mips_hpt_frequency = calibrate_hpt();
240
241                 /* Report the high precision timer rate for a reference.  */
242                 printk("Using %u.%03u MHz high precision timer.\n",
243                        ((mips_hpt_frequency + 500) / 1000) / 1000,
244                        ((mips_hpt_frequency + 500) / 1000) % 1000);
245         }
246
247         init_mips_clocksource();
248         mips_clockevent_init();
249 }