isa-timer.c 2.0 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6
/*
 *  linux/arch/arm/mach-footbridge/isa-timer.c
 *
 *  Copyright (C) 1998 Russell King.
 *  Copyright (C) 1998 Phil Blundell
 */
7 8
#include <linux/clockchips.h>
#include <linux/clocksource.h>
9
#include <linux/i8253.h>
L
Linus Torvalds 已提交
10 11
#include <linux/init.h>
#include <linux/interrupt.h>
12
#include <linux/irq.h>
13
#include <linux/io.h>
14
#include <linux/spinlock.h>
15
#include <linux/timex.h>
L
Linus Torvalds 已提交
16 17 18 19 20 21

#include <asm/irq.h>
#include <asm/mach/time.h>

#include "common.h"

22
DEFINE_RAW_SPINLOCK(i8253_lock);
L
Linus Torvalds 已提交
23

24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
static void pit_set_mode(enum clock_event_mode mode,
	struct clock_event_device *evt)
{
	unsigned long flags;

	raw_local_irq_save(flags);

	switch (mode) {
	case CLOCK_EVT_MODE_PERIODIC:
		outb_p(0x34, PIT_MODE);
		outb_p(PIT_LATCH & 0xff, PIT_CH0);
		outb_p(PIT_LATCH >> 8, PIT_CH0);
		break;

	case CLOCK_EVT_MODE_SHUTDOWN:
	case CLOCK_EVT_MODE_UNUSED:
		outb_p(0x30, PIT_MODE);
		outb_p(0, PIT_CH0);
		outb_p(0, PIT_CH0);
		break;

	case CLOCK_EVT_MODE_ONESHOT:
	case CLOCK_EVT_MODE_RESUME:
		break;
	}
	local_irq_restore(flags);
}
L
Linus Torvalds 已提交
51

52 53 54 55
static int pit_set_next_event(unsigned long delta,
	struct clock_event_device *evt)
{
	return 0;
L
Linus Torvalds 已提交
56 57
}

58 59 60 61 62 63 64 65 66
static struct clock_event_device pit_ce = {
	.name		= "pit",
	.features	= CLOCK_EVT_FEAT_PERIODIC,
	.set_mode	= pit_set_mode,
	.set_next_event	= pit_set_next_event,
	.shift		= 32,
};

static irqreturn_t pit_timer_interrupt(int irq, void *dev_id)
L
Linus Torvalds 已提交
67
{
68 69
	struct clock_event_device *ce = dev_id;
	ce->event_handler(ce);
L
Linus Torvalds 已提交
70 71 72
	return IRQ_HANDLED;
}

73 74 75
static struct irqaction pit_timer_irq = {
	.name		= "pit",
	.handler	= pit_timer_interrupt,
B
Bernhard Walle 已提交
76
	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
77
	.dev_id		= &pit_ce,
L
Linus Torvalds 已提交
78 79 80 81
};

static void __init isa_timer_init(void)
{
82 83 84 85 86
	pit_ce.cpumask = cpumask_of(smp_processor_id());
	pit_ce.mult = div_sc(PIT_TICK_RATE, NSEC_PER_SEC, pit_ce.shift);
	pit_ce.max_delta_ns = clockevent_delta2ns(0x7fff, &pit_ce);
	pit_ce.min_delta_ns = clockevent_delta2ns(0x000f, &pit_ce);

87
	clocksource_i8253_init();
L
Linus Torvalds 已提交
88

89 90
	setup_irq(pit_ce.irq, &pit_timer_irq);
	clockevents_register_device(&pit_ce);
L
Linus Torvalds 已提交
91 92 93 94 95
}

struct sys_timer isa_timer = {
	.init		= isa_timer_init,
};