1/* 2 * arch/ubicom32/kernel/timer_broadcast.c 3 * Implements a dummy clock event for each cpu. 4 * 5 * Copyright (C) 2008 Paul Mundt 6 * (C) Copyright 2009, Ubicom, Inc. 7 * 8 * This file is part of the Ubicom32 Linux Kernel Port. 9 * 10 * The Ubicom32 Linux Kernel Port is free software: you can redistribute 11 * it and/or modify it under the terms of the GNU General Public License 12 * as published by the Free Software Foundation, either version 2 of the 13 * License, or (at your option) any later version. 14 * 15 * The Ubicom32 Linux Kernel Port is distributed in the hope that it 16 * will be useful, but WITHOUT ANY WARRANTY; without even the implied 17 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 18 * the GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with the Ubicom32 Linux Kernel Port. If not, 22 * see <http://www.gnu.org/licenses/>. 23 * 24 * Ubicom32 implementation derived from (with many thanks): 25 * arch/m68knommu 26 * arch/blackfin 27 * arch/parisc 28 * arch/arm 29 * arch/sh 30 */ 31#include <linux/init.h> 32#include <linux/kernel.h> 33#include <linux/delay.h> 34#include <linux/device.h> 35#include <linux/smp.h> 36#include <linux/jiffies.h> 37#include <linux/percpu.h> 38#include <linux/clockchips.h> 39#include <linux/irq.h> 40 41static DEFINE_PER_CPU(struct clock_event_device, local_clockevent); 42 43/* 44 * The broadcast trick only works when the timer will be used in a periodic mode. 45 * If the user has configured either NO_HZ or HIGH_RES_TIMERS they must have 46 * a per cpu timer. 47 */ 48#if defined(CONFIG_NO_HZ) || defined(CONFIG_HIGH_RES_TIMERS) 49#error "Tickless and High Resolution Timers require per-CPU local timers: CONFIG_LOCAL_TIMERS" 50#endif 51 52/* 53 * local_timer_interrupt() 54 * Used on SMP for local timer interrupt sent via an IPI. 55 */ 56void local_timer_interrupt(void) 57{ 58 struct clock_event_device *dev = &__get_cpu_var(local_clockevent); 59 60 dev->event_handler(dev); 61} 62 63/* 64 * dummy_timer_set_next_event() 65 * Cause the timer to go off "cycles" from now. 66 */ 67static int dummy_timer_set_next_event(unsigned long cycles, struct clock_event_device *dev) 68{ 69 return 0; 70} 71 72/* 73 * dummy_timer_set_mode() 74 * Do Nothing. 75 */ 76static void dummy_timer_set_mode(enum clock_event_mode mode, 77 struct clock_event_device *clk) 78{ 79} 80 81/* 82 * local_timer_setup() 83 * Adds a clock event for the specified cpu. 84 */ 85int __cpuinit local_timer_setup(unsigned int cpu) 86{ 87 struct clock_event_device *dev = &per_cpu(local_clockevent, cpu); 88 89 dev->name = "timer-dummy"; 90 dev->features = CLOCK_EVT_FEAT_DUMMY; 91 dev->rating = 200; 92 dev->mult = 1; 93 dev->set_mode = dummy_timer_set_mode; 94 dev->set_next_event = dummy_timer_set_next_event; 95 dev->broadcast = smp_timer_broadcast; 96 dev->cpumask = cpumask_of_cpu(cpu); 97 dev->irq = -1; 98 printk(KERN_NOTICE "timer[%d]: %s - created\n", dev->irq, dev->name); 99 100 clockevents_register_device(dev); 101 return 0; 102} 103