11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * linux/arch/arm/mach-footbridge/isa-timer.c 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Copyright (C) 1998 Russell King. 51da177e4SLinus Torvalds * Copyright (C) 1998 Phil Blundell 61da177e4SLinus Torvalds */ 74e8d7637SRussell King #include <linux/clockchips.h> 84e8d7637SRussell King #include <linux/clocksource.h> 9*334955efSRalf Baechle #include <linux/i8253.h> 101da177e4SLinus Torvalds #include <linux/init.h> 111da177e4SLinus Torvalds #include <linux/interrupt.h> 1255e86989SThomas Gleixner #include <linux/irq.h> 13fced80c7SRussell King #include <linux/io.h> 148c414ff3SRussell King #include <linux/spinlock.h> 154e8d7637SRussell King #include <linux/timex.h> 161da177e4SLinus Torvalds 171da177e4SLinus Torvalds #include <asm/irq.h> 181da177e4SLinus Torvalds #include <asm/mach/time.h> 191da177e4SLinus Torvalds 201da177e4SLinus Torvalds #include "common.h" 211da177e4SLinus Torvalds 228c414ff3SRussell King DEFINE_RAW_SPINLOCK(i8253_lock); 234e8d7637SRussell King 244e8d7637SRussell King static void pit_set_mode(enum clock_event_mode mode, 254e8d7637SRussell King struct clock_event_device *evt) 261da177e4SLinus Torvalds { 274e8d7637SRussell King unsigned long flags; 284e8d7637SRussell King 294e8d7637SRussell King raw_local_irq_save(flags); 304e8d7637SRussell King 314e8d7637SRussell King switch (mode) { 324e8d7637SRussell King case CLOCK_EVT_MODE_PERIODIC: 334e8d7637SRussell King outb_p(0x34, PIT_MODE); 344e8d7637SRussell King outb_p(PIT_LATCH & 0xff, PIT_CH0); 354e8d7637SRussell King outb_p(PIT_LATCH >> 8, PIT_CH0); 364e8d7637SRussell King break; 374e8d7637SRussell King 384e8d7637SRussell King case CLOCK_EVT_MODE_SHUTDOWN: 394e8d7637SRussell King case CLOCK_EVT_MODE_UNUSED: 404e8d7637SRussell King outb_p(0x30, PIT_MODE); 414e8d7637SRussell King outb_p(0, PIT_CH0); 424e8d7637SRussell King outb_p(0, PIT_CH0); 434e8d7637SRussell King break; 444e8d7637SRussell King 454e8d7637SRussell King case CLOCK_EVT_MODE_ONESHOT: 464e8d7637SRussell King case CLOCK_EVT_MODE_RESUME: 474e8d7637SRussell King break; 484e8d7637SRussell King } 494e8d7637SRussell King local_irq_restore(flags); 504e8d7637SRussell King } 514e8d7637SRussell King 524e8d7637SRussell King static int pit_set_next_event(unsigned long delta, 534e8d7637SRussell King struct clock_event_device *evt) 544e8d7637SRussell King { 554e8d7637SRussell King return 0; 564e8d7637SRussell King } 574e8d7637SRussell King 584e8d7637SRussell King static struct clock_event_device pit_ce = { 594e8d7637SRussell King .name = "pit", 604e8d7637SRussell King .features = CLOCK_EVT_FEAT_PERIODIC, 614e8d7637SRussell King .set_mode = pit_set_mode, 624e8d7637SRussell King .set_next_event = pit_set_next_event, 634e8d7637SRussell King .shift = 32, 644e8d7637SRussell King }; 654e8d7637SRussell King 664e8d7637SRussell King static irqreturn_t pit_timer_interrupt(int irq, void *dev_id) 674e8d7637SRussell King { 684e8d7637SRussell King struct clock_event_device *ce = dev_id; 694e8d7637SRussell King ce->event_handler(ce); 701da177e4SLinus Torvalds return IRQ_HANDLED; 711da177e4SLinus Torvalds } 721da177e4SLinus Torvalds 734e8d7637SRussell King static struct irqaction pit_timer_irq = { 744e8d7637SRussell King .name = "pit", 754e8d7637SRussell King .handler = pit_timer_interrupt, 76b30fabadSBernhard Walle .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 774e8d7637SRussell King .dev_id = &pit_ce, 781da177e4SLinus Torvalds }; 791da177e4SLinus Torvalds 801da177e4SLinus Torvalds static void __init isa_timer_init(void) 811da177e4SLinus Torvalds { 824e8d7637SRussell King pit_ce.cpumask = cpumask_of(smp_processor_id()); 834e8d7637SRussell King pit_ce.mult = div_sc(PIT_TICK_RATE, NSEC_PER_SEC, pit_ce.shift); 844e8d7637SRussell King pit_ce.max_delta_ns = clockevent_delta2ns(0x7fff, &pit_ce); 854e8d7637SRussell King pit_ce.min_delta_ns = clockevent_delta2ns(0x000f, &pit_ce); 861da177e4SLinus Torvalds 878c414ff3SRussell King clocksource_i8253_init(); 884e8d7637SRussell King 894e8d7637SRussell King setup_irq(pit_ce.irq, &pit_timer_irq); 904e8d7637SRussell King clockevents_register_device(&pit_ce); 911da177e4SLinus Torvalds } 921da177e4SLinus Torvalds 931da177e4SLinus Torvalds struct sys_timer isa_timer = { 941da177e4SLinus Torvalds .init = isa_timer_init, 951da177e4SLinus Torvalds }; 96