Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mips: Use common i8253 clockevent

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/20110609130622.133068765@linutronix.de

+3 -95
+1
arch/mips/Kconfig
··· 2391 2391 config I8253 2392 2392 bool 2393 2393 select CLKSRC_I8253 2394 + select CLKEVT_I8253 2394 2395 select MIPS_EXTERNAL_TIMER 2395 2396 2396 2397 config ZONE_DMA32
+2 -95
arch/mips/kernel/i8253.c
··· 4 4 */ 5 5 #include <linux/clockchips.h> 6 6 #include <linux/i8253.h> 7 - #include <linux/init.h> 8 - #include <linux/interrupt.h> 9 - #include <linux/jiffies.h> 10 7 #include <linux/module.h> 11 8 #include <linux/smp.h> 12 - #include <linux/spinlock.h> 13 9 #include <linux/irq.h> 14 10 15 - #include <asm/delay.h> 16 - #include <asm/io.h> 17 11 #include <asm/time.h> 18 - 19 - /* 20 - * Initialize the PIT timer. 21 - * 22 - * This is also called after resume to bring the PIT into operation again. 23 - */ 24 - static void init_pit_timer(enum clock_event_mode mode, 25 - struct clock_event_device *evt) 26 - { 27 - raw_spin_lock(&i8253_lock); 28 - 29 - switch(mode) { 30 - case CLOCK_EVT_MODE_PERIODIC: 31 - /* binary, mode 2, LSB/MSB, ch 0 */ 32 - outb_p(0x34, PIT_MODE); 33 - outb_p(LATCH & 0xff , PIT_CH0); /* LSB */ 34 - outb(LATCH >> 8 , PIT_CH0); /* MSB */ 35 - break; 36 - 37 - case CLOCK_EVT_MODE_SHUTDOWN: 38 - case CLOCK_EVT_MODE_UNUSED: 39 - if (evt->mode == CLOCK_EVT_MODE_PERIODIC || 40 - evt->mode == CLOCK_EVT_MODE_ONESHOT) { 41 - outb_p(0x30, PIT_MODE); 42 - outb_p(0, PIT_CH0); 43 - outb_p(0, PIT_CH0); 44 - } 45 - break; 46 - 47 - case CLOCK_EVT_MODE_ONESHOT: 48 - /* One shot setup */ 49 - outb_p(0x38, PIT_MODE); 50 - break; 51 - 52 - case CLOCK_EVT_MODE_RESUME: 53 - /* Nothing to do here */ 54 - break; 55 - } 56 - raw_spin_unlock(&i8253_lock); 57 - } 58 - 59 - /* 60 - * Program the next event in oneshot mode 61 - * 62 - * Delta is given in PIT ticks 63 - */ 64 - static int pit_next_event(unsigned long delta, struct clock_event_device *evt) 65 - { 66 - raw_spin_lock(&i8253_lock); 67 - outb_p(delta & 0xff , PIT_CH0); /* LSB */ 68 - outb(delta >> 8 , PIT_CH0); /* MSB */ 69 - raw_spin_unlock(&i8253_lock); 70 - 71 - return 0; 72 - } 73 - 74 - /* 75 - * On UP the PIT can serve all of the possible timer functions. On SMP systems 76 - * it can be solely used for the global tick. 77 - * 78 - * The profiling and update capabilites are switched off once the local apic is 79 - * registered. This mechanism replaces the previous #ifdef LOCAL_APIC - 80 - * !using_apic_timer decisions in do_timer_interrupt_hook() 81 - */ 82 - static struct clock_event_device pit_clockevent = { 83 - .name = "pit", 84 - .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 85 - .set_mode = init_pit_timer, 86 - .set_next_event = pit_next_event, 87 - .irq = 0, 88 - }; 89 12 90 13 static irqreturn_t timer_interrupt(int irq, void *dev_id) 91 14 { 92 - pit_clockevent.event_handler(&pit_clockevent); 15 + i8253_clockevent.event_handler(&pit_clockevent); 93 16 94 17 return IRQ_HANDLED; 95 18 } ··· 23 100 .name = "timer" 24 101 }; 25 102 26 - /* 27 - * Initialize the conversion factor and the min/max deltas of the clock event 28 - * structure and register the clock event source with the framework. 29 - */ 30 103 void __init setup_pit_timer(void) 31 104 { 32 - struct clock_event_device *cd = &pit_clockevent; 33 - unsigned int cpu = smp_processor_id(); 34 - 35 - /* 36 - * Start pit with the boot cpu mask and make it global after the 37 - * IO_APIC has been initialized. 38 - */ 39 - cd->cpumask = cpumask_of(cpu); 40 - clockevent_set_clock(cd, CLOCK_TICK_RATE); 41 - cd->max_delta_ns = clockevent_delta2ns(0x7FFF, cd); 42 - cd->min_delta_ns = clockevent_delta2ns(0xF, cd); 43 - clockevents_register_device(cd); 44 - 105 + clockevent_i8253_init(true); 45 106 setup_irq(0, &irq0); 46 107 } 47 108