at v2.6.21 229 lines 5.4 kB view raw
1/* 2 * Copyright (C) 2004-2006 Atmel Corporation 3 * 4 * Based on MIPS implementation arch/mips/kernel/time.c 5 * Copyright 2001 MontaVista Software Inc. 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 */ 11 12#include <linux/clk.h> 13#include <linux/clocksource.h> 14#include <linux/time.h> 15#include <linux/module.h> 16#include <linux/interrupt.h> 17#include <linux/irq.h> 18#include <linux/kernel_stat.h> 19#include <linux/errno.h> 20#include <linux/init.h> 21#include <linux/profile.h> 22#include <linux/sysdev.h> 23 24#include <asm/div64.h> 25#include <asm/sysreg.h> 26#include <asm/io.h> 27#include <asm/sections.h> 28 29static cycle_t read_cycle_count(void) 30{ 31 return (cycle_t)sysreg_read(COUNT); 32} 33 34static struct clocksource clocksource_avr32 = { 35 .name = "avr32", 36 .rating = 350, 37 .read = read_cycle_count, 38 .mask = CLOCKSOURCE_MASK(32), 39 .shift = 16, 40 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 41}; 42 43/* 44 * By default we provide the null RTC ops 45 */ 46static unsigned long null_rtc_get_time(void) 47{ 48 return mktime(2004, 1, 1, 0, 0, 0); 49} 50 51static int null_rtc_set_time(unsigned long sec) 52{ 53 return 0; 54} 55 56static unsigned long (*rtc_get_time)(void) = null_rtc_get_time; 57static int (*rtc_set_time)(unsigned long) = null_rtc_set_time; 58 59/* how many counter cycles in a jiffy? */ 60static unsigned long cycles_per_jiffy; 61 62/* cycle counter value at the previous timer interrupt */ 63static unsigned int timerhi, timerlo; 64 65/* the count value for the next timer interrupt */ 66static unsigned int expirelo; 67 68static void avr32_timer_ack(void) 69{ 70 unsigned int count; 71 72 /* Ack this timer interrupt and set the next one */ 73 expirelo += cycles_per_jiffy; 74 if (expirelo == 0) { 75 printk(KERN_DEBUG "expirelo == 0\n"); 76 sysreg_write(COMPARE, expirelo + 1); 77 } else { 78 sysreg_write(COMPARE, expirelo); 79 } 80 81 /* Check to see if we have missed any timer interrupts */ 82 count = sysreg_read(COUNT); 83 if ((count - expirelo) < 0x7fffffff) { 84 expirelo = count + cycles_per_jiffy; 85 sysreg_write(COMPARE, expirelo); 86 } 87} 88 89static unsigned int avr32_hpt_read(void) 90{ 91 return sysreg_read(COUNT); 92} 93 94/* 95 * Taken from MIPS c0_hpt_timer_init(). 96 * 97 * Why is it so complicated, and what is "count"? My assumption is 98 * that `count' specifies the "reference cycle", i.e. the cycle since 99 * reset that should mean "zero". The reason COUNT is written twice is 100 * probably to make sure we don't get any timer interrupts while we 101 * are messing with the counter. 102 */ 103static void avr32_hpt_init(unsigned int count) 104{ 105 count = sysreg_read(COUNT) - count; 106 expirelo = (count / cycles_per_jiffy + 1) * cycles_per_jiffy; 107 sysreg_write(COUNT, expirelo - cycles_per_jiffy); 108 sysreg_write(COMPARE, expirelo); 109 sysreg_write(COUNT, count); 110} 111 112/* 113 * local_timer_interrupt() does profiling and process accounting on a 114 * per-CPU basis. 115 * 116 * In UP mode, it is invoked from the (global) timer_interrupt. 117 */ 118static void local_timer_interrupt(int irq, void *dev_id) 119{ 120 if (current->pid) 121 profile_tick(CPU_PROFILING); 122 update_process_times(user_mode(get_irq_regs())); 123} 124 125static irqreturn_t 126timer_interrupt(int irq, void *dev_id) 127{ 128 unsigned int count; 129 130 /* ack timer interrupt and try to set next interrupt */ 131 count = avr32_hpt_read(); 132 avr32_timer_ack(); 133 134 /* Update timerhi/timerlo for intra-jiffy calibration */ 135 timerhi += count < timerlo; /* Wrap around */ 136 timerlo = count; 137 138 /* 139 * Call the generic timer interrupt handler 140 */ 141 write_seqlock(&xtime_lock); 142 do_timer(1); 143 write_sequnlock(&xtime_lock); 144 145 /* 146 * In UP mode, we call local_timer_interrupt() to do profiling 147 * and process accounting. 148 * 149 * SMP is not supported yet. 150 */ 151 local_timer_interrupt(irq, dev_id); 152 153 return IRQ_HANDLED; 154} 155 156static struct irqaction timer_irqaction = { 157 .handler = timer_interrupt, 158 .flags = IRQF_DISABLED, 159 .name = "timer", 160}; 161 162void __init time_init(void) 163{ 164 unsigned long mult, shift, count_hz; 165 int ret; 166 167 xtime.tv_sec = rtc_get_time(); 168 xtime.tv_nsec = 0; 169 170 set_normalized_timespec(&wall_to_monotonic, 171 -xtime.tv_sec, -xtime.tv_nsec); 172 173 printk("Before time_init: count=%08lx, compare=%08lx\n", 174 (unsigned long)sysreg_read(COUNT), 175 (unsigned long)sysreg_read(COMPARE)); 176 177 count_hz = clk_get_rate(boot_cpu_data.clk); 178 shift = clocksource_avr32.shift; 179 mult = clocksource_hz2mult(count_hz, shift); 180 clocksource_avr32.mult = mult; 181 182 printk("Cycle counter: mult=%lu, shift=%lu\n", mult, shift); 183 184 { 185 u64 tmp; 186 187 tmp = TICK_NSEC; 188 tmp <<= shift; 189 tmp += mult / 2; 190 do_div(tmp, mult); 191 192 cycles_per_jiffy = tmp; 193 } 194 195 /* This sets up the high precision timer for the first interrupt. */ 196 avr32_hpt_init(avr32_hpt_read()); 197 198 printk("After time_init: count=%08lx, compare=%08lx\n", 199 (unsigned long)sysreg_read(COUNT), 200 (unsigned long)sysreg_read(COMPARE)); 201 202 ret = clocksource_register(&clocksource_avr32); 203 if (ret) 204 printk(KERN_ERR 205 "timer: could not register clocksource: %d\n", ret); 206 207 ret = setup_irq(0, &timer_irqaction); 208 if (ret) 209 printk("timer: could not request IRQ 0: %d\n", ret); 210} 211 212static struct sysdev_class timer_class = { 213 set_kset_name("timer"), 214}; 215 216static struct sys_device timer_device = { 217 .id = 0, 218 .cls = &timer_class, 219}; 220 221static int __init init_timer_sysfs(void) 222{ 223 int err = sysdev_class_register(&timer_class); 224 if (!err) 225 err = sysdev_register(&timer_device); 226 return err; 227} 228 229device_initcall(init_timer_sysfs);