linux/arch/m68k/68000/timers.c
<<
>>
Prefs
   1/***************************************************************************/
   2
   3/*
   4 *  timers.c - Generic hardware timer support.
   5 *
   6 *  Copyright (C) 1993 Hamish Macdonald
   7 *  Copyright (C) 1999 D. Jeff Dionne
   8 *  Copyright (C) 2001 Georges Menie, Ken Desmet
   9 *
  10 * This file is subject to the terms and conditions of the GNU General Public
  11 * License.  See the file COPYING in the main directory of this archive
  12 * for more details.
  13 */
  14
  15/***************************************************************************/
  16
  17#include <linux/types.h>
  18#include <linux/kernel.h>
  19#include <linux/mm.h>
  20#include <linux/interrupt.h>
  21#include <linux/irq.h>
  22#include <linux/clocksource.h>
  23#include <linux/rtc.h>
  24#include <asm/setup.h>
  25#include <asm/machdep.h>
  26#include <asm/MC68VZ328.h>
  27
  28/***************************************************************************/
  29
  30#if defined(CONFIG_DRAGEN2)
  31/* with a 33.16 MHz clock, this will give usec resolution to the time functions */
  32#define CLOCK_SOURCE    TCTL_CLKSOURCE_SYSCLK
  33#define CLOCK_PRE       7
  34#define TICKS_PER_JIFFY 41450
  35
  36#elif defined(CONFIG_XCOPILOT_BUGS)
  37/*
  38 * The only thing I know is that CLK32 is not available on Xcopilot
  39 * I have little idea about what frequency SYSCLK has on Xcopilot.
  40 * The values for prescaler and compare registers were simply
  41 * taken from the original source
  42 */
  43#define CLOCK_SOURCE    TCTL_CLKSOURCE_SYSCLK
  44#define CLOCK_PRE       2
  45#define TICKS_PER_JIFFY 0xd7e4
  46
  47#else
  48/* default to using the 32Khz clock */
  49#define CLOCK_SOURCE    TCTL_CLKSOURCE_32KHZ
  50#define CLOCK_PRE       31
  51#define TICKS_PER_JIFFY 10
  52#endif
  53
  54static u32 m68328_tick_cnt;
  55
  56/***************************************************************************/
  57
  58static irqreturn_t hw_tick(int irq, void *dummy)
  59{
  60        /* Reset Timer1 */
  61        TSTAT &= 0;
  62
  63        m68328_tick_cnt += TICKS_PER_JIFFY;
  64        legacy_timer_tick(1);
  65        return IRQ_HANDLED;
  66}
  67
  68/***************************************************************************/
  69
  70static u64 m68328_read_clk(struct clocksource *cs)
  71{
  72        unsigned long flags;
  73        u32 cycles;
  74
  75        local_irq_save(flags);
  76        cycles = m68328_tick_cnt + TCN;
  77        local_irq_restore(flags);
  78
  79        return cycles;
  80}
  81
  82/***************************************************************************/
  83
  84static struct clocksource m68328_clk = {
  85        .name   = "timer",
  86        .rating = 250,
  87        .read   = m68328_read_clk,
  88        .mask   = CLOCKSOURCE_MASK(32),
  89        .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
  90};
  91
  92/***************************************************************************/
  93
  94void hw_timer_init(void)
  95{
  96        int ret;
  97
  98        /* disable timer 1 */
  99        TCTL = 0;
 100
 101        /* set ISR */
 102        ret = request_irq(TMR_IRQ_NUM, hw_tick, IRQF_TIMER, "timer", NULL);
 103        if (ret) {
 104                pr_err("Failed to request irq %d (timer): %pe\n", TMR_IRQ_NUM,
 105                       ERR_PTR(ret));
 106        }
 107
 108        /* Restart mode, Enable int, Set clock source */
 109        TCTL = TCTL_OM | TCTL_IRQEN | CLOCK_SOURCE;
 110        TPRER = CLOCK_PRE;
 111        TCMP = TICKS_PER_JIFFY;
 112
 113        /* Enable timer 1 */
 114        TCTL |= TCTL_TEN;
 115        clocksource_register_hz(&m68328_clk, TICKS_PER_JIFFY*HZ);
 116}
 117
 118/***************************************************************************/
 119
 120int m68328_hwclk(int set, struct rtc_time *t)
 121{
 122        if (!set) {
 123                long now = RTCTIME;
 124                t->tm_year = 1;
 125                t->tm_mon = 0;
 126                t->tm_mday = 1;
 127                t->tm_hour = (now >> 24) % 24;
 128                t->tm_min = (now >> 16) % 60;
 129                t->tm_sec = now % 60;
 130        }
 131
 132        return 0;
 133}
 134
 135/***************************************************************************/
 136