diff options
Diffstat (limited to 'arch/arm/mach-realview')
-rw-r--r-- | arch/arm/mach-realview/Makefile | 3 | ||||
-rw-r--r-- | arch/arm/mach-realview/core.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-realview/localtimer.c | 39 | ||||
-rw-r--r-- | arch/arm/mach-realview/platsmp.c | 6 |
4 files changed, 54 insertions, 4 deletions
diff --git a/arch/arm/mach-realview/Makefile b/arch/arm/mach-realview/Makefile index 36e76ba937fc..ca1e390c3c28 100644 --- a/arch/arm/mach-realview/Makefile +++ b/arch/arm/mach-realview/Makefile | |||
@@ -4,6 +4,5 @@ | |||
4 | 4 | ||
5 | obj-y := core.o clock.o | 5 | obj-y := core.o clock.o |
6 | obj-$(CONFIG_MACH_REALVIEW_EB) += realview_eb.o | 6 | obj-$(CONFIG_MACH_REALVIEW_EB) += realview_eb.o |
7 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o | 7 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o localtimer.o |
8 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o | 8 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o |
9 | obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o | ||
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index 6c68deed84dc..8cabfec31da2 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c | |||
@@ -596,12 +596,20 @@ static void __init realview_clocksource_init(void) | |||
596 | } | 596 | } |
597 | 597 | ||
598 | /* | 598 | /* |
599 | * Set up timer interrupt, and return the current time in seconds. | 599 | * Set up the clock source and clock events devices |
600 | */ | 600 | */ |
601 | static void __init realview_timer_init(void) | 601 | static void __init realview_timer_init(void) |
602 | { | 602 | { |
603 | u32 val; | 603 | u32 val; |
604 | 604 | ||
605 | #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST | ||
606 | /* | ||
607 | * The dummy clock device has to be registered before the main device | ||
608 | * so that the latter will broadcast the clock events | ||
609 | */ | ||
610 | local_timer_setup(smp_processor_id()); | ||
611 | #endif | ||
612 | |||
605 | /* | 613 | /* |
606 | * set clock frequency: | 614 | * set clock frequency: |
607 | * REALVIEW_REFCLK is 32KHz | 615 | * REALVIEW_REFCLK is 32KHz |
diff --git a/arch/arm/mach-realview/localtimer.c b/arch/arm/mach-realview/localtimer.c index c7bdf04ab094..529eb6979e61 100644 --- a/arch/arm/mach-realview/localtimer.c +++ b/arch/arm/mach-realview/localtimer.c | |||
@@ -14,6 +14,8 @@ | |||
14 | #include <linux/device.h> | 14 | #include <linux/device.h> |
15 | #include <linux/smp.h> | 15 | #include <linux/smp.h> |
16 | #include <linux/jiffies.h> | 16 | #include <linux/jiffies.h> |
17 | #include <linux/percpu.h> | ||
18 | #include <linux/clockchips.h> | ||
17 | 19 | ||
18 | #include <asm/mach/time.h> | 20 | #include <asm/mach/time.h> |
19 | #include <asm/hardware/arm_twd.h> | 21 | #include <asm/hardware/arm_twd.h> |
@@ -25,6 +27,20 @@ | |||
25 | #define TWD_BASE(cpu) (__io_address(REALVIEW_TWD_BASE) + \ | 27 | #define TWD_BASE(cpu) (__io_address(REALVIEW_TWD_BASE) + \ |
26 | ((cpu) * REALVIEW_TWD_SIZE)) | 28 | ((cpu) * REALVIEW_TWD_SIZE)) |
27 | 29 | ||
30 | static DEFINE_PER_CPU(struct clock_event_device, local_clockevent); | ||
31 | |||
32 | /* | ||
33 | * Used on SMP for either the local timer or IPI_TIMER | ||
34 | */ | ||
35 | void local_timer_interrupt(void) | ||
36 | { | ||
37 | struct clock_event_device *clk = &__get_cpu_var(local_clockevent); | ||
38 | |||
39 | clk->event_handler(clk); | ||
40 | } | ||
41 | |||
42 | #ifdef CONFIG_LOCAL_TIMERS | ||
43 | |||
28 | static unsigned long mpcore_timer_rate; | 44 | static unsigned long mpcore_timer_rate; |
29 | 45 | ||
30 | /* | 46 | /* |
@@ -127,3 +143,26 @@ void __cpuexit local_timer_stop(unsigned int cpu) | |||
127 | { | 143 | { |
128 | __raw_writel(0, TWD_BASE(cpu) + TWD_TIMER_CONTROL); | 144 | __raw_writel(0, TWD_BASE(cpu) + TWD_TIMER_CONTROL); |
129 | } | 145 | } |
146 | |||
147 | #else /* CONFIG_LOCAL_TIMERS */ | ||
148 | |||
149 | static void dummy_timer_set_mode(enum clock_event_mode mode, | ||
150 | struct clock_event_device *clk) | ||
151 | { | ||
152 | } | ||
153 | |||
154 | void __cpuinit local_timer_setup(unsigned int cpu) | ||
155 | { | ||
156 | struct clock_event_device *clk = &per_cpu(local_clockevent, cpu); | ||
157 | |||
158 | clk->name = "dummy_timer"; | ||
159 | clk->features = CLOCK_EVT_FEAT_DUMMY; | ||
160 | clk->rating = 200; | ||
161 | clk->set_mode = dummy_timer_set_mode; | ||
162 | clk->broadcast = smp_timer_broadcast; | ||
163 | clk->cpumask = cpumask_of_cpu(cpu); | ||
164 | |||
165 | clockevents_register_device(clk); | ||
166 | } | ||
167 | |||
168 | #endif /* !CONFIG_LOCAL_TIMERS */ | ||
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c index fce3596f9950..bb5eaa48520d 100644 --- a/arch/arm/mach-realview/platsmp.c +++ b/arch/arm/mach-realview/platsmp.c | |||
@@ -187,10 +187,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
187 | if (max_cpus > ncores) | 187 | if (max_cpus > ncores) |
188 | max_cpus = ncores; | 188 | max_cpus = ncores; |
189 | 189 | ||
190 | #ifdef CONFIG_LOCAL_TIMERS | ||
190 | /* | 191 | /* |
191 | * Enable the local timer for primary CPU | 192 | * Enable the local timer for primary CPU. If the device is |
193 | * dummy (!CONFIG_LOCAL_TIMERS), it was already registers in | ||
194 | * realview_timer_init | ||
192 | */ | 195 | */ |
193 | local_timer_setup(cpu); | 196 | local_timer_setup(cpu); |
197 | #endif | ||
194 | 198 | ||
195 | /* | 199 | /* |
196 | * Initialise the present map, which describes the set of CPUs | 200 | * Initialise the present map, which describes the set of CPUs |