aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2008-08-06 05:37:07 -0400
committerPaul Mundt <lethal@linux-sh.org>2008-09-07 21:35:03 -0400
commit8c24594deab89a484879bee270e948f0a556ed75 (patch)
tree2b0c95a4d53614e1118ea20aa7e705d983ddb23f /arch/sh
parent6f52707e6882eb3bc6920c3f59beb05d23d68354 (diff)
sh: generic clockevent broadcast support.
This hooks up GENERIC_CLOCKEVENTS_BROADCAST and a dummy local timer, which we call in to from the timer IPI when no other local timer is provided. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh')
-rw-r--r--arch/sh/Kconfig4
-rw-r--r--arch/sh/include/asm/smp.h3
-rw-r--r--arch/sh/kernel/smp.c7
-rw-r--r--arch/sh/kernel/time_32.c9
-rw-r--r--arch/sh/kernel/timers/Makefile1
-rw-r--r--arch/sh/kernel/timers/timer-broadcast.c57
6 files changed, 77 insertions, 4 deletions
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 5131d50f851..399664c1f38 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -66,6 +66,9 @@ config GENERIC_TIME
66config GENERIC_CLOCKEVENTS 66config GENERIC_CLOCKEVENTS
67 def_bool n 67 def_bool n
68 68
69config GENERIC_CLOCKEVENTS_BROADCAST
70 bool
71
69config GENERIC_LOCKBREAK 72config GENERIC_LOCKBREAK
70 def_bool y 73 def_bool y
71 depends on SMP && PREEMPT 74 depends on SMP && PREEMPT
@@ -323,6 +326,7 @@ config CPU_SUBTYPE_SHX3
323 select ARCH_SPARSEMEM_ENABLE 326 select ARCH_SPARSEMEM_ENABLE
324 select SYS_SUPPORTS_NUMA 327 select SYS_SUPPORTS_NUMA
325 select SYS_SUPPORTS_SMP 328 select SYS_SUPPORTS_SMP
329 select GENERIC_CLOCKEVENTS_BROADCAST
326 330
327# SH4AL-DSP Processor Support 331# SH4AL-DSP Processor Support
328 332
diff --git a/arch/sh/include/asm/smp.h b/arch/sh/include/asm/smp.h
index 9d22cda67c2..85b660c17eb 100644
--- a/arch/sh/include/asm/smp.h
+++ b/arch/sh/include/asm/smp.h
@@ -33,6 +33,9 @@ enum {
33void smp_message_recv(unsigned int msg); 33void smp_message_recv(unsigned int msg);
34void smp_timer_broadcast(cpumask_t mask); 34void smp_timer_broadcast(cpumask_t mask);
35 35
36void local_timer_interrupt(void);
37void local_timer_setup(unsigned int cpu);
38
36void plat_smp_setup(void); 39void plat_smp_setup(void);
37void plat_prepare_cpus(unsigned int max_cpus); 40void plat_prepare_cpus(unsigned int max_cpus);
38int plat_smp_processor_id(void); 41int plat_smp_processor_id(void);
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
index 9cb3734dbd4..c55d314166c 100644
--- a/arch/sh/kernel/smp.c
+++ b/arch/sh/kernel/smp.c
@@ -84,9 +84,12 @@ asmlinkage void __cpuinit start_secondary(void)
84 84
85 local_irq_enable(); 85 local_irq_enable();
86 86
87 cpu = smp_processor_id();
88
89 /* Enable local timers */
90 local_timer_setup(cpu);
87 calibrate_delay(); 91 calibrate_delay();
88 92
89 cpu = smp_processor_id();
90 smp_store_cpu_info(cpu); 93 smp_store_cpu_info(cpu);
91 94
92 cpu_set(cpu, cpu_online_map); 95 cpu_set(cpu, cpu_online_map);
@@ -195,7 +198,7 @@ void smp_timer_broadcast(cpumask_t mask)
195static void ipi_timer(void) 198static void ipi_timer(void)
196{ 199{
197 irq_enter(); 200 irq_enter();
198 /* XXX ... */ 201 local_timer_interrupt();
199 irq_exit(); 202 irq_exit();
200} 203}
201 204
diff --git a/arch/sh/kernel/time_32.c b/arch/sh/kernel/time_32.c
index 0758b5ee818..decee0a453a 100644
--- a/arch/sh/kernel/time_32.c
+++ b/arch/sh/kernel/time_32.c
@@ -1,9 +1,9 @@
1/* 1/*
2 * arch/sh/kernel/time.c 2 * arch/sh/kernel/time_32.c
3 * 3 *
4 * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka 4 * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka
5 * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> 5 * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
6 * Copyright (C) 2002 - 2007 Paul Mundt 6 * Copyright (C) 2002 - 2008 Paul Mundt
7 * Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org> 7 * Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org>
8 * 8 *
9 * Some code taken from i386 version. 9 * Some code taken from i386 version.
@@ -16,6 +16,7 @@
16#include <linux/timex.h> 16#include <linux/timex.h>
17#include <linux/sched.h> 17#include <linux/sched.h>
18#include <linux/clockchips.h> 18#include <linux/clockchips.h>
19#include <linux/smp.h>
19#include <asm/clock.h> 20#include <asm/clock.h>
20#include <asm/rtc.h> 21#include <asm/rtc.h>
21#include <asm/timer.h> 22#include <asm/timer.h>
@@ -260,6 +261,10 @@ void __init time_init(void)
260 sys_timer = get_sys_timer(); 261 sys_timer = get_sys_timer();
261 printk(KERN_INFO "Using %s for system timer\n", sys_timer->name); 262 printk(KERN_INFO "Using %s for system timer\n", sys_timer->name);
262 263
264#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
265 local_timer_setup(smp_processor_id());
266#endif
267
263 if (sys_timer->ops->read) 268 if (sys_timer->ops->read)
264 clocksource_sh.read = sys_timer->ops->read; 269 clocksource_sh.read = sys_timer->ops->read;
265 270
diff --git a/arch/sh/kernel/timers/Makefile b/arch/sh/kernel/timers/Makefile
index bcf244ff6a1..0b7f8577193 100644
--- a/arch/sh/kernel/timers/Makefile
+++ b/arch/sh/kernel/timers/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_SH_TMU) += timer-tmu.o
8obj-$(CONFIG_SH_MTU2) += timer-mtu2.o 8obj-$(CONFIG_SH_MTU2) += timer-mtu2.o
9obj-$(CONFIG_SH_CMT) += timer-cmt.o 9obj-$(CONFIG_SH_CMT) += timer-cmt.o
10 10
11obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += timer-broadcast.o
diff --git a/arch/sh/kernel/timers/timer-broadcast.c b/arch/sh/kernel/timers/timer-broadcast.c
new file mode 100644
index 00000000000..c2317635230
--- /dev/null
+++ b/arch/sh/kernel/timers/timer-broadcast.c
@@ -0,0 +1,57 @@
1/*
2 * Dummy local timer
3 *
4 * Copyright (C) 2008 Paul Mundt
5 *
6 * cloned from:
7 *
8 * linux/arch/arm/mach-realview/localtimer.c
9 *
10 * Copyright (C) 2002 ARM Ltd.
11 * All Rights Reserved
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 */
17#include <linux/init.h>
18#include <linux/kernel.h>
19#include <linux/delay.h>
20#include <linux/device.h>
21#include <linux/smp.h>
22#include <linux/jiffies.h>
23#include <linux/percpu.h>
24#include <linux/clockchips.h>
25#include <linux/irq.h>
26
27static DEFINE_PER_CPU(struct clock_event_device, local_clockevent);
28
29/*
30 * Used on SMP for either the local timer or SMP_MSG_TIMER
31 */
32void local_timer_interrupt(void)
33{
34 struct clock_event_device *clk = &__get_cpu_var(local_clockevent);
35
36 clk->event_handler(clk);
37}
38
39static void dummy_timer_set_mode(enum clock_event_mode mode,
40 struct clock_event_device *clk)
41{
42}
43
44void __cpuinit local_timer_setup(unsigned int cpu)
45{
46 struct clock_event_device *clk = &per_cpu(local_clockevent, cpu);
47
48 clk->name = "dummy_timer";
49 clk->features = CLOCK_EVT_FEAT_DUMMY;
50 clk->rating = 200;
51 clk->mult = 1;
52 clk->set_mode = dummy_timer_set_mode;
53 clk->broadcast = smp_timer_broadcast;
54 clk->cpumask = cpumask_of_cpu(cpu);
55
56 clockevents_register_device(clk);
57}