linux/arch/arm/mach-footbridge/dc21285-timer.c
<<
>>
Prefs
   1/*
   2 *  linux/arch/arm/mach-footbridge/dc21285-timer.c
   3 *
   4 *  Copyright (C) 1998 Russell King.
   5 *  Copyright (C) 1998 Phil Blundell
   6 */
   7#include <linux/clockchips.h>
   8#include <linux/clocksource.h>
   9#include <linux/init.h>
  10#include <linux/interrupt.h>
  11#include <linux/irq.h>
  12
  13#include <asm/irq.h>
  14
  15#include <asm/hardware/dec21285.h>
  16#include <asm/mach/time.h>
  17#include <asm/system_info.h>
  18
  19#include "common.h"
  20
  21static cycle_t cksrc_dc21285_read(struct clocksource *cs)
  22{
  23        return cs->mask - *CSR_TIMER2_VALUE;
  24}
  25
  26static int cksrc_dc21285_enable(struct clocksource *cs)
  27{
  28        *CSR_TIMER2_LOAD = cs->mask;
  29        *CSR_TIMER2_CLR = 0;
  30        *CSR_TIMER2_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_DIV16;
  31        return 0;
  32}
  33
  34static void cksrc_dc21285_disable(struct clocksource *cs)
  35{
  36        *CSR_TIMER2_CNTL = 0;
  37}
  38
  39static struct clocksource cksrc_dc21285 = {
  40        .name           = "dc21285_timer2",
  41        .rating         = 200,
  42        .read           = cksrc_dc21285_read,
  43        .enable         = cksrc_dc21285_enable,
  44        .disable        = cksrc_dc21285_disable,
  45        .mask           = CLOCKSOURCE_MASK(24),
  46        .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
  47};
  48
  49static void ckevt_dc21285_set_mode(enum clock_event_mode mode,
  50        struct clock_event_device *c)
  51{
  52        switch (mode) {
  53        case CLOCK_EVT_MODE_RESUME:
  54        case CLOCK_EVT_MODE_PERIODIC:
  55                *CSR_TIMER1_CLR = 0;
  56                *CSR_TIMER1_LOAD = (mem_fclk_21285 + 8 * HZ) / (16 * HZ);
  57                *CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD |
  58                                   TIMER_CNTL_DIV16;
  59                break;
  60
  61        default:
  62                *CSR_TIMER1_CNTL = 0;
  63                break;
  64        }
  65}
  66
  67static struct clock_event_device ckevt_dc21285 = {
  68        .name           = "dc21285_timer1",
  69        .features       = CLOCK_EVT_FEAT_PERIODIC,
  70        .rating         = 200,
  71        .irq            = IRQ_TIMER1,
  72        .set_mode       = ckevt_dc21285_set_mode,
  73};
  74
  75static irqreturn_t timer1_interrupt(int irq, void *dev_id)
  76{
  77        struct clock_event_device *ce = dev_id;
  78
  79        *CSR_TIMER1_CLR = 0;
  80
  81        ce->event_handler(ce);
  82
  83        return IRQ_HANDLED;
  84}
  85
  86static struct irqaction footbridge_timer_irq = {
  87        .name           = "dc21285_timer1",
  88        .handler        = timer1_interrupt,
  89        .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
  90        .dev_id         = &ckevt_dc21285,
  91};
  92
  93/*
  94 * Set up timer interrupt.
  95 */
  96void __init footbridge_timer_init(void)
  97{
  98        struct clock_event_device *ce = &ckevt_dc21285;
  99
 100        clocksource_register_hz(&cksrc_dc21285, (mem_fclk_21285 + 8) / 16);
 101
 102        setup_irq(ce->irq, &footbridge_timer_irq);
 103
 104        ce->cpumask = cpumask_of(smp_processor_id());
 105        clockevents_config_and_register(ce, mem_fclk_21285, 0x4, 0xffffff);
 106}
 107