diff options
| -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); |
