diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-05-08 14:03:03 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-05-14 05:29:48 -0400 |
commit | 798778b8653f64b7b2162ac70eca10367cff6ce8 (patch) | |
tree | cc1739a919b413592d8d6f5cc0cdd5fcf75ce6e6 /arch/mips | |
parent | 82491451dd25a3abe8496ddbd04ddb3f77d285c2 (diff) |
clocksource: convert mips to generic i8253 clocksource
Convert MIPS i8253 clocksource code to use generic i8253 clocksource.
Acked-by: John Stultz <john.stultz@linaro.org>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/Kconfig | 1 | ||||
-rw-r--r-- | arch/mips/include/asm/i8253.h | 5 | ||||
-rw-r--r-- | arch/mips/kernel/i8253.c | 78 |
3 files changed, 7 insertions, 77 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 8e256cc5dcd9..f7f6419e4c84 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -2339,6 +2339,7 @@ config MMU | |||
2339 | 2339 | ||
2340 | config I8253 | 2340 | config I8253 |
2341 | bool | 2341 | bool |
2342 | select CLKSRC_I8253 | ||
2342 | select MIPS_EXTERNAL_TIMER | 2343 | select MIPS_EXTERNAL_TIMER |
2343 | 2344 | ||
2344 | config ZONE_DMA32 | 2345 | config ZONE_DMA32 |
diff --git a/arch/mips/include/asm/i8253.h b/arch/mips/include/asm/i8253.h index 48bb82372994..9ad011366f73 100644 --- a/arch/mips/include/asm/i8253.h +++ b/arch/mips/include/asm/i8253.h | |||
@@ -12,8 +12,13 @@ | |||
12 | #define PIT_CH0 0x40 | 12 | #define PIT_CH0 0x40 |
13 | #define PIT_CH2 0x42 | 13 | #define PIT_CH2 0x42 |
14 | 14 | ||
15 | #define PIT_LATCH LATCH | ||
16 | |||
15 | extern raw_spinlock_t i8253_lock; | 17 | extern raw_spinlock_t i8253_lock; |
16 | 18 | ||
17 | extern void setup_pit_timer(void); | 19 | extern void setup_pit_timer(void); |
18 | 20 | ||
21 | #define inb_pit inb_p | ||
22 | #define outb_pit outb_p | ||
23 | |||
19 | #endif /* __ASM_I8253_H */ | 24 | #endif /* __ASM_I8253_H */ |
diff --git a/arch/mips/kernel/i8253.c b/arch/mips/kernel/i8253.c index 2392a7a296d4..391221b6a6aa 100644 --- a/arch/mips/kernel/i8253.c +++ b/arch/mips/kernel/i8253.c | |||
@@ -125,87 +125,11 @@ void __init setup_pit_timer(void) | |||
125 | setup_irq(0, &irq0); | 125 | setup_irq(0, &irq0); |
126 | } | 126 | } |
127 | 127 | ||
128 | /* | ||
129 | * Since the PIT overflows every tick, its not very useful | ||
130 | * to just read by itself. So use jiffies to emulate a free | ||
131 | * running counter: | ||
132 | */ | ||
133 | static cycle_t pit_read(struct clocksource *cs) | ||
134 | { | ||
135 | unsigned long flags; | ||
136 | int count; | ||
137 | u32 jifs; | ||
138 | static int old_count; | ||
139 | static u32 old_jifs; | ||
140 | |||
141 | raw_spin_lock_irqsave(&i8253_lock, flags); | ||
142 | /* | ||
143 | * Although our caller may have the read side of xtime_lock, | ||
144 | * this is now a seqlock, and we are cheating in this routine | ||
145 | * by having side effects on state that we cannot undo if | ||
146 | * there is a collision on the seqlock and our caller has to | ||
147 | * retry. (Namely, old_jifs and old_count.) So we must treat | ||
148 | * jiffies as volatile despite the lock. We read jiffies | ||
149 | * before latching the timer count to guarantee that although | ||
150 | * the jiffies value might be older than the count (that is, | ||
151 | * the counter may underflow between the last point where | ||
152 | * jiffies was incremented and the point where we latch the | ||
153 | * count), it cannot be newer. | ||
154 | */ | ||
155 | jifs = jiffies; | ||
156 | outb_p(0x00, PIT_MODE); /* latch the count ASAP */ | ||
157 | count = inb_p(PIT_CH0); /* read the latched count */ | ||
158 | count |= inb_p(PIT_CH0) << 8; | ||
159 | |||
160 | /* VIA686a test code... reset the latch if count > max + 1 */ | ||
161 | if (count > LATCH) { | ||
162 | outb_p(0x34, PIT_MODE); | ||
163 | outb_p(LATCH & 0xff, PIT_CH0); | ||
164 | outb(LATCH >> 8, PIT_CH0); | ||
165 | count = LATCH - 1; | ||
166 | } | ||
167 | |||
168 | /* | ||
169 | * It's possible for count to appear to go the wrong way for a | ||
170 | * couple of reasons: | ||
171 | * | ||
172 | * 1. The timer counter underflows, but we haven't handled the | ||
173 | * resulting interrupt and incremented jiffies yet. | ||
174 | * 2. Hardware problem with the timer, not giving us continuous time, | ||
175 | * the counter does small "jumps" upwards on some Pentium systems, | ||
176 | * (see c't 95/10 page 335 for Neptun bug.) | ||
177 | * | ||
178 | * Previous attempts to handle these cases intelligently were | ||
179 | * buggy, so we just do the simple thing now. | ||
180 | */ | ||
181 | if (count > old_count && jifs == old_jifs) { | ||
182 | count = old_count; | ||
183 | } | ||
184 | old_count = count; | ||
185 | old_jifs = jifs; | ||
186 | |||
187 | raw_spin_unlock_irqrestore(&i8253_lock, flags); | ||
188 | |||
189 | count = (LATCH - 1) - count; | ||
190 | |||
191 | return (cycle_t)(jifs * LATCH) + count; | ||
192 | } | ||
193 | |||
194 | static struct clocksource clocksource_pit = { | ||
195 | .name = "pit", | ||
196 | .rating = 110, | ||
197 | .read = pit_read, | ||
198 | .mask = CLOCKSOURCE_MASK(32), | ||
199 | .mult = 0, | ||
200 | .shift = 20, | ||
201 | }; | ||
202 | |||
203 | static int __init init_pit_clocksource(void) | 128 | static int __init init_pit_clocksource(void) |
204 | { | 129 | { |
205 | if (num_possible_cpus() > 1) /* PIT does not scale! */ | 130 | if (num_possible_cpus() > 1) /* PIT does not scale! */ |
206 | return 0; | 131 | return 0; |
207 | 132 | ||
208 | clocksource_pit.mult = clocksource_hz2mult(CLOCK_TICK_RATE, 20); | 133 | return clocksource_i8253_init(); |
209 | return clocksource_register(&clocksource_pit); | ||
210 | } | 134 | } |
211 | arch_initcall(init_pit_clocksource); | 135 | arch_initcall(init_pit_clocksource); |