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