2 * arch/ubicom32/kernel/timer_device.c
3 * Implements a Ubicom32 clock device and event devices.
5 * (C) Copyright 2009, Ubicom, Inc.
7 * This file is part of the Ubicom32 Linux Kernel Port.
9 * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10 * it and/or modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation, either version 2 of the
12 * License, or (at your option) any later version.
14 * The Ubicom32 Linux Kernel Port is distributed in the hope that it
15 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
16 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
17 * the GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with the Ubicom32 Linux Kernel Port. If not,
21 * see <http://www.gnu.org/licenses/>.
23 * Ubicom32 implementation derived from (with many thanks):
28 #include <linux/types.h>
29 #include <linux/clockchips.h>
30 #include <linux/clocksource.h>
31 #include <linux/spinlock.h>
32 #include <asm/ip5000.h>
33 #include <asm/machdep.h>
35 #if defined(CONFIG_SMP)
39 #if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
40 #define MAX_TIMERS (2 + CONFIG_TIMER_EXTRA_ALLOC)
42 #define MAX_TIMERS (NR_CPUS + CONFIG_TIMER_EXTRA_ALLOC)
46 #error "Ubicom32 only has 10 timers"
49 static unsigned int frequency;
50 static struct clock_event_device timer_device_devs[MAX_TIMERS];
51 static struct irqaction timer_device_irqs[MAX_TIMERS];
52 static int timer_device_next_timer = 0;
54 DEFINE_SPINLOCK(timer_device_lock);
57 * timer_device_set_next_event()
58 * Cause the timer to go off "cycles" from now.
60 static int timer_device_set_next_event(unsigned long cycles, struct clock_event_device *dev)
62 timer_set(dev->irq, cycles);
67 * timer_device_set_mode()
68 * Handle the mode switch for a clock event device.
70 static void timer_device_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
73 case CLOCK_EVT_MODE_SHUTDOWN:
75 * Make sure the vector is disabled
76 * until the next event is set.
78 printk(KERN_NOTICE "timer[%d]: shutdown\n", dev->irq);
79 ldsr_disable_vector(dev->irq);
82 case CLOCK_EVT_MODE_ONESHOT:
84 * Make sure the vector is disabled
85 * until the next event is set.
87 printk(KERN_NOTICE "timer[%d]: oneshot\n", dev->irq);
88 ldsr_disable_vector(dev->irq);
91 case CLOCK_EVT_MODE_PERIODIC:
93 * The periodic request is 1 per jiffies
95 printk(KERN_NOTICE "timer[%d]: periodic: %d cycles\n",
96 dev->irq, frequency / CONFIG_HZ);
97 timer_set(dev->irq, frequency / CONFIG_HZ);
100 case CLOCK_EVT_MODE_UNUSED:
101 case CLOCK_EVT_MODE_RESUME:
102 printk(KERN_WARNING "timer[%d]: unimplemented mode: %d\n",
109 * timer_device_event()
110 * Call the device's event handler.
112 * The pointer is initialized by the generic Linux code
113 * to the function to be called.
115 static irqreturn_t timer_device_event(int irq, void *dev_id)
117 struct clock_event_device *dev = (struct clock_event_device *)dev_id;
119 if (dev->mode == CLOCK_EVT_MODE_PERIODIC) {
121 * The periodic request is 1 per jiffies
123 timer_reset(dev->irq, frequency / CONFIG_HZ);
126 * The timer will go off again at the rollover
127 * point. We must disable the IRQ to prevent
128 * getting a spurious interrupt.
130 ldsr_disable_vector(dev->irq);
133 if (!dev->event_handler) {
134 printk(KERN_CRIT "no registered event handler\n");
138 dev->event_handler(dev);
143 * timer_device_clockbase_read()
144 * Provide a primary clocksource around the sysval timer.
146 static cycle_t timer_device_clockbase_read(void)
148 return (cycle_t)UBICOM32_IO_TIMER->sysval;
152 * Primary Clock Source Description
154 * We use 24 for the shift factor because we want
155 * to ensure there are less than 2^24 clocks
156 * in a jiffie of 10 ms.
158 static struct clocksource timer_device_clockbase = {
161 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
162 .mask = CLOCKSOURCE_MASK(32),
165 .read = timer_device_clockbase_read,
169 * timer_device_alloc_event()
170 * Allocate a timer device event.
172 static int timer_device_alloc_event(const char *name, int cpuid, const struct cpumask *cpumask)
174 struct clock_event_device *dev;
175 struct irqaction *action;
178 * Are we out of configured timers?
180 spin_lock(&timer_device_lock);
181 if (timer_device_next_timer >= MAX_TIMERS) {
182 spin_unlock(&timer_device_lock);
183 printk(KERN_WARNING "out of timer event entries\n");
186 dev = &timer_device_devs[timer_device_next_timer];
187 action = &timer_device_irqs[timer_device_next_timer];
188 timer_device_next_timer++;
189 spin_unlock(&timer_device_lock);
192 * Now allocate a timer to ourselves.
194 dev->irq = timer_alloc();
195 if (dev->irq == -1) {
196 spin_lock(&timer_device_lock);
197 timer_device_next_timer--;
198 spin_unlock(&timer_device_lock);
199 printk(KERN_WARNING "out of hardware timers\n");
204 * Init the IRQ action structure. Make sure
205 * this in place before you register the clock
209 action->flags = IRQF_DISABLED | IRQF_TIMER;
210 action->handler = timer_device_event;
211 //cpumask_copy(&action->mask, mask);
212 action->dev_id = dev;
213 setup_irq(dev->irq, action);
214 irq_set_affinity(dev->irq, cpumask);
215 ldsr_disable_vector(dev->irq);
218 * init clock dev structure.
220 * The min_delta_ns is chosen to ensure that setting next
221 * event will never be requested with too small of value.
224 dev->rating = timer_device_clockbase.rating;
225 dev->shift = timer_device_clockbase.shift;
226 dev->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
227 dev->set_mode = timer_device_set_mode;
228 dev->set_next_event = timer_device_set_next_event;
229 dev->mult = div_sc(frequency, NSEC_PER_SEC, dev->shift);
230 dev->max_delta_ns = clockevent_delta2ns(0xffffffff, dev);
231 dev->min_delta_ns = clockevent_delta2ns(100, dev);
232 //dev->cpumask = mask;
233 printk(KERN_NOTICE "timer[%d]: %s - created\n", dev->irq, dev->name);
236 * Now register the device.
238 clockevents_register_device(dev);
242 #if defined(CONFIG_LOCAL_TIMERS)
244 * local_timer_setup()
245 * Allocation function for creating a per cpu local timer.
247 int __cpuinit local_timer_setup(unsigned int cpu)
249 return timer_device_alloc_event("timer-cpu", cpu);
254 * timer_device_init()
255 * Create and init a generic clock driver for Ubicom32.
257 void timer_device_init(void)
262 * Get the frequency from the processor device tree node or use
263 * the default if not available. We will store this as the frequency
264 * of the timer to avoid future calculations.
266 frequency = processor_frequency();
267 if (frequency == 0) {
268 frequency = CLOCK_TICK_RATE;
272 * Setup the primary clock source around sysval. Linux does not
273 * supply a Mhz multiplier so convert down to khz.
275 timer_device_clockbase.mult =
276 clocksource_khz2mult(frequency / 1000,
277 timer_device_clockbase.shift);
278 if (clocksource_register(&timer_device_clockbase)) {
279 printk(KERN_ERR "timer: clocksource failed to register\n");
284 * Always allocate a primary timer.
286 timer_device_alloc_event("timer-primary", -1, cpu_all_mask);
288 #if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
290 * If BROADCAST is selected we need to add a broadcast timer.
292 timer_device_alloc_event("timer-broadcast", -1, cpu_all_mask);
296 * Allocate extra timers that are requested.
298 for (i = 0; i < CONFIG_TIMER_EXTRA_ALLOC; i++) {
299 timer_device_alloc_event("timer-extra", -1, cpu_all_mask);