diff options
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r-- | arch/arm/mach-omap2/dpll3xxx.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap2/include/mach/entry-macro.S | 93 | ||||
-rw-r--r-- | arch/arm/mach-omap2/include/mach/omap4-common.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap-hotplug.c | 14 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap-smp.c | 68 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap4-common.c | 11 | ||||
-rw-r--r-- | arch/arm/mach-omap2/timer-gp.c | 5 |
7 files changed, 57 insertions, 137 deletions
diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c index ed8d330522f1..ebb888f59365 100644 --- a/arch/arm/mach-omap2/dpll3xxx.c +++ b/arch/arm/mach-omap2/dpll3xxx.c | |||
@@ -26,10 +26,10 @@ | |||
26 | #include <linux/clk.h> | 26 | #include <linux/clk.h> |
27 | #include <linux/io.h> | 27 | #include <linux/io.h> |
28 | #include <linux/bitops.h> | 28 | #include <linux/bitops.h> |
29 | #include <linux/clkdev.h> | ||
29 | 30 | ||
30 | #include <plat/cpu.h> | 31 | #include <plat/cpu.h> |
31 | #include <plat/clock.h> | 32 | #include <plat/clock.h> |
32 | #include <asm/clkdev.h> | ||
33 | 33 | ||
34 | #include "clock.h" | 34 | #include "clock.h" |
35 | #include "prm.h" | 35 | #include "prm.h" |
diff --git a/arch/arm/mach-omap2/include/mach/entry-macro.S b/arch/arm/mach-omap2/include/mach/entry-macro.S index 06e64e1fc28a..d54c4f89a8bd 100644 --- a/arch/arm/mach-omap2/include/mach/entry-macro.S +++ b/arch/arm/mach-omap2/include/mach/entry-macro.S | |||
@@ -105,6 +105,35 @@ omap_irq_base: .word 0 | |||
105 | 9999: | 105 | 9999: |
106 | .endm | 106 | .endm |
107 | 107 | ||
108 | #ifdef CONFIG_SMP | ||
109 | /* We assume that irqstat (the raw value of the IRQ acknowledge | ||
110 | * register) is preserved from the macro above. | ||
111 | * If there is an IPI, we immediately signal end of interrupt | ||
112 | * on the controller, since this requires the original irqstat | ||
113 | * value which we won't easily be able to recreate later. | ||
114 | */ | ||
115 | |||
116 | .macro test_for_ipi, irqnr, irqstat, base, tmp | ||
117 | bic \irqnr, \irqstat, #0x1c00 | ||
118 | cmp \irqnr, #16 | ||
119 | it cc | ||
120 | strcc \irqstat, [\base, #GIC_CPU_EOI] | ||
121 | it cs | ||
122 | cmpcs \irqnr, \irqnr | ||
123 | .endm | ||
124 | |||
125 | /* As above, this assumes that irqstat and base are preserved */ | ||
126 | |||
127 | .macro test_for_ltirq, irqnr, irqstat, base, tmp | ||
128 | bic \irqnr, \irqstat, #0x1c00 | ||
129 | mov \tmp, #0 | ||
130 | cmp \irqnr, #29 | ||
131 | itt eq | ||
132 | moveq \tmp, #1 | ||
133 | streq \irqstat, [\base, #GIC_CPU_EOI] | ||
134 | cmp \tmp, #0 | ||
135 | .endm | ||
136 | #endif /* CONFIG_SMP */ | ||
108 | 137 | ||
109 | #else /* MULTI_OMAP2 */ | 138 | #else /* MULTI_OMAP2 */ |
110 | 139 | ||
@@ -141,74 +170,16 @@ omap_irq_base: .word 0 | |||
141 | 170 | ||
142 | 171 | ||
143 | #ifdef CONFIG_ARCH_OMAP4 | 172 | #ifdef CONFIG_ARCH_OMAP4 |
173 | #define HAVE_GET_IRQNR_PREAMBLE | ||
174 | #include <asm/hardware/entry-macro-gic.S> | ||
144 | 175 | ||
145 | .macro get_irqnr_preamble, base, tmp | 176 | .macro get_irqnr_preamble, base, tmp |
146 | ldr \base, =OMAP4_IRQ_BASE | 177 | ldr \base, =OMAP4_IRQ_BASE |
147 | .endm | 178 | .endm |
148 | 179 | ||
149 | /* | ||
150 | * The interrupt numbering scheme is defined in the | ||
151 | * interrupt controller spec. To wit: | ||
152 | * | ||
153 | * Interrupts 0-15 are IPI | ||
154 | * 16-28 are reserved | ||
155 | * 29-31 are local. We allow 30 to be used for the watchdog. | ||
156 | * 32-1020 are global | ||
157 | * 1021-1022 are reserved | ||
158 | * 1023 is "spurious" (no interrupt) | ||
159 | * | ||
160 | * For now, we ignore all local interrupts so only return an | ||
161 | * interrupt if it's between 30 and 1020. The test_for_ipi | ||
162 | * routine below will pick up on IPIs. | ||
163 | * A simple read from the controller will tell us the number | ||
164 | * of the highest priority enabled interrupt. | ||
165 | * We then just need to check whether it is in the | ||
166 | * valid range for an IRQ (30-1020 inclusive). | ||
167 | */ | ||
168 | .macro get_irqnr_and_base, irqnr, irqstat, base, tmp | ||
169 | ldr \irqstat, [\base, #GIC_CPU_INTACK] | ||
170 | |||
171 | ldr \tmp, =1021 | ||
172 | |||
173 | bic \irqnr, \irqstat, #0x1c00 | ||
174 | |||
175 | cmp \irqnr, #29 | ||
176 | cmpcc \irqnr, \irqnr | ||
177 | cmpne \irqnr, \tmp | ||
178 | cmpcs \irqnr, \irqnr | ||
179 | .endm | ||
180 | #endif | 180 | #endif |
181 | #endif /* MULTI_OMAP2 */ | ||
182 | |||
183 | #ifdef CONFIG_SMP | ||
184 | /* We assume that irqstat (the raw value of the IRQ acknowledge | ||
185 | * register) is preserved from the macro above. | ||
186 | * If there is an IPI, we immediately signal end of interrupt | ||
187 | * on the controller, since this requires the original irqstat | ||
188 | * value which we won't easily be able to recreate later. | ||
189 | */ | ||
190 | 181 | ||
191 | .macro test_for_ipi, irqnr, irqstat, base, tmp | 182 | #endif /* MULTI_OMAP2 */ |
192 | bic \irqnr, \irqstat, #0x1c00 | ||
193 | cmp \irqnr, #16 | ||
194 | it cc | ||
195 | strcc \irqstat, [\base, #GIC_CPU_EOI] | ||
196 | it cs | ||
197 | cmpcs \irqnr, \irqnr | ||
198 | .endm | ||
199 | |||
200 | /* As above, this assumes that irqstat and base are preserved */ | ||
201 | |||
202 | .macro test_for_ltirq, irqnr, irqstat, base, tmp | ||
203 | bic \irqnr, \irqstat, #0x1c00 | ||
204 | mov \tmp, #0 | ||
205 | cmp \irqnr, #29 | ||
206 | itt eq | ||
207 | moveq \tmp, #1 | ||
208 | streq \irqstat, [\base, #GIC_CPU_EOI] | ||
209 | cmp \tmp, #0 | ||
210 | .endm | ||
211 | #endif /* CONFIG_SMP */ | ||
212 | 183 | ||
213 | .macro irq_prio_table | 184 | .macro irq_prio_table |
214 | .endm | 185 | .endm |
diff --git a/arch/arm/mach-omap2/include/mach/omap4-common.h b/arch/arm/mach-omap2/include/mach/omap4-common.h index 2744dfee1ff4..5b0270b28934 100644 --- a/arch/arm/mach-omap2/include/mach/omap4-common.h +++ b/arch/arm/mach-omap2/include/mach/omap4-common.h | |||
@@ -24,7 +24,6 @@ | |||
24 | extern void __iomem *l2cache_base; | 24 | extern void __iomem *l2cache_base; |
25 | #endif | 25 | #endif |
26 | 26 | ||
27 | extern void __iomem *gic_cpu_base_addr; | ||
28 | extern void __iomem *gic_dist_base_addr; | 27 | extern void __iomem *gic_dist_base_addr; |
29 | 28 | ||
30 | extern void __init gic_init_irq(void); | 29 | extern void __init gic_init_irq(void); |
diff --git a/arch/arm/mach-omap2/omap-hotplug.c b/arch/arm/mach-omap2/omap-hotplug.c index 6cee456ca542..4976b9393e49 100644 --- a/arch/arm/mach-omap2/omap-hotplug.c +++ b/arch/arm/mach-omap2/omap-hotplug.c | |||
@@ -17,16 +17,13 @@ | |||
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | #include <linux/errno.h> | 18 | #include <linux/errno.h> |
19 | #include <linux/smp.h> | 19 | #include <linux/smp.h> |
20 | #include <linux/completion.h> | ||
21 | 20 | ||
22 | #include <asm/cacheflush.h> | 21 | #include <asm/cacheflush.h> |
23 | #include <mach/omap4-common.h> | 22 | #include <mach/omap4-common.h> |
24 | 23 | ||
25 | static DECLARE_COMPLETION(cpu_killed); | ||
26 | |||
27 | int platform_cpu_kill(unsigned int cpu) | 24 | int platform_cpu_kill(unsigned int cpu) |
28 | { | 25 | { |
29 | return wait_for_completion_timeout(&cpu_killed, 5000); | 26 | return 1; |
30 | } | 27 | } |
31 | 28 | ||
32 | /* | 29 | /* |
@@ -35,15 +32,6 @@ int platform_cpu_kill(unsigned int cpu) | |||
35 | */ | 32 | */ |
36 | void platform_cpu_die(unsigned int cpu) | 33 | void platform_cpu_die(unsigned int cpu) |
37 | { | 34 | { |
38 | unsigned int this_cpu = hard_smp_processor_id(); | ||
39 | |||
40 | if (cpu != this_cpu) { | ||
41 | pr_crit("platform_cpu_die running on %u, should be %u\n", | ||
42 | this_cpu, cpu); | ||
43 | BUG(); | ||
44 | } | ||
45 | pr_notice("CPU%u: shutdown\n", cpu); | ||
46 | complete(&cpu_killed); | ||
47 | flush_cache_all(); | 35 | flush_cache_all(); |
48 | dsb(); | 36 | dsb(); |
49 | 37 | ||
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index 9e9f70e18e3c..b66cfe8bc464 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
22 | 22 | ||
23 | #include <asm/cacheflush.h> | 23 | #include <asm/cacheflush.h> |
24 | #include <asm/localtimer.h> | ||
25 | #include <asm/smp_scu.h> | 24 | #include <asm/smp_scu.h> |
26 | #include <mach/hardware.h> | 25 | #include <mach/hardware.h> |
27 | #include <mach/omap4-common.h> | 26 | #include <mach/omap4-common.h> |
@@ -29,28 +28,16 @@ | |||
29 | /* SCU base address */ | 28 | /* SCU base address */ |
30 | static void __iomem *scu_base; | 29 | static void __iomem *scu_base; |
31 | 30 | ||
32 | /* | ||
33 | * Use SCU config register to count number of cores | ||
34 | */ | ||
35 | static inline unsigned int get_core_count(void) | ||
36 | { | ||
37 | if (scu_base) | ||
38 | return scu_get_core_count(scu_base); | ||
39 | return 1; | ||
40 | } | ||
41 | |||
42 | static DEFINE_SPINLOCK(boot_lock); | 31 | static DEFINE_SPINLOCK(boot_lock); |
43 | 32 | ||
44 | void __cpuinit platform_secondary_init(unsigned int cpu) | 33 | void __cpuinit platform_secondary_init(unsigned int cpu) |
45 | { | 34 | { |
46 | trace_hardirqs_off(); | ||
47 | |||
48 | /* | 35 | /* |
49 | * If any interrupts are already enabled for the primary | 36 | * If any interrupts are already enabled for the primary |
50 | * core (e.g. timer irq), then they will not have been enabled | 37 | * core (e.g. timer irq), then they will not have been enabled |
51 | * for us: do so | 38 | * for us: do so |
52 | */ | 39 | */ |
53 | gic_cpu_init(0, gic_cpu_base_addr); | 40 | gic_secondary_init(0); |
54 | 41 | ||
55 | /* | 42 | /* |
56 | * Synchronise with the boot thread. | 43 | * Synchronise with the boot thread. |
@@ -76,7 +63,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) | |||
76 | omap_modify_auxcoreboot0(0x200, 0xfffffdff); | 63 | omap_modify_auxcoreboot0(0x200, 0xfffffdff); |
77 | flush_cache_all(); | 64 | flush_cache_all(); |
78 | smp_wmb(); | 65 | smp_wmb(); |
79 | smp_cross_call(cpumask_of(cpu)); | 66 | smp_cross_call(cpumask_of(cpu), 1); |
80 | 67 | ||
81 | /* | 68 | /* |
82 | * Now the secondary core is starting up let it run its | 69 | * Now the secondary core is starting up let it run its |
@@ -118,25 +105,9 @@ void __init smp_init_cpus(void) | |||
118 | scu_base = ioremap(OMAP44XX_SCU_BASE, SZ_256); | 105 | scu_base = ioremap(OMAP44XX_SCU_BASE, SZ_256); |
119 | BUG_ON(!scu_base); | 106 | BUG_ON(!scu_base); |
120 | 107 | ||
121 | ncores = get_core_count(); | 108 | ncores = scu_get_core_count(scu_base); |
122 | |||
123 | for (i = 0; i < ncores; i++) | ||
124 | set_cpu_possible(i, true); | ||
125 | } | ||
126 | |||
127 | void __init smp_prepare_cpus(unsigned int max_cpus) | ||
128 | { | ||
129 | unsigned int ncores = get_core_count(); | ||
130 | unsigned int cpu = smp_processor_id(); | ||
131 | int i; | ||
132 | 109 | ||
133 | /* sanity check */ | 110 | /* sanity check */ |
134 | if (ncores == 0) { | ||
135 | printk(KERN_ERR | ||
136 | "OMAP4: strange core count of 0? Default to 1\n"); | ||
137 | ncores = 1; | ||
138 | } | ||
139 | |||
140 | if (ncores > NR_CPUS) { | 111 | if (ncores > NR_CPUS) { |
141 | printk(KERN_WARNING | 112 | printk(KERN_WARNING |
142 | "OMAP4: no. of cores (%d) greater than configured " | 113 | "OMAP4: no. of cores (%d) greater than configured " |
@@ -144,13 +115,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
144 | ncores, NR_CPUS); | 115 | ncores, NR_CPUS); |
145 | ncores = NR_CPUS; | 116 | ncores = NR_CPUS; |
146 | } | 117 | } |
147 | smp_store_cpu_info(cpu); | ||
148 | 118 | ||
149 | /* | 119 | for (i = 0; i < ncores; i++) |
150 | * are we trying to boot more cores than exist? | 120 | set_cpu_possible(i, true); |
151 | */ | 121 | } |
152 | if (max_cpus > ncores) | 122 | |
153 | max_cpus = ncores; | 123 | void __init platform_smp_prepare_cpus(unsigned int max_cpus) |
124 | { | ||
125 | int i; | ||
154 | 126 | ||
155 | /* | 127 | /* |
156 | * Initialise the present map, which describes the set of CPUs | 128 | * Initialise the present map, which describes the set of CPUs |
@@ -159,18 +131,10 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
159 | for (i = 0; i < max_cpus; i++) | 131 | for (i = 0; i < max_cpus; i++) |
160 | set_cpu_present(i, true); | 132 | set_cpu_present(i, true); |
161 | 133 | ||
162 | if (max_cpus > 1) { | 134 | /* |
163 | /* | 135 | * Initialise the SCU and wake up the secondary core using |
164 | * Enable the local timer or broadcast device for the | 136 | * wakeup_secondary(). |
165 | * boot CPU, but only if we have more than one CPU. | 137 | */ |
166 | */ | 138 | scu_enable(scu_base); |
167 | percpu_timer_setup(); | 139 | wakeup_secondary(); |
168 | |||
169 | /* | ||
170 | * Initialise the SCU and wake up the secondary core using | ||
171 | * wakeup_secondary(). | ||
172 | */ | ||
173 | scu_enable(scu_base); | ||
174 | wakeup_secondary(); | ||
175 | } | ||
176 | } | 140 | } |
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c index 2f895553e6a8..666e852988d5 100644 --- a/arch/arm/mach-omap2/omap4-common.c +++ b/arch/arm/mach-omap2/omap4-common.c | |||
@@ -26,21 +26,22 @@ | |||
26 | void __iomem *l2cache_base; | 26 | void __iomem *l2cache_base; |
27 | #endif | 27 | #endif |
28 | 28 | ||
29 | void __iomem *gic_cpu_base_addr; | ||
30 | void __iomem *gic_dist_base_addr; | 29 | void __iomem *gic_dist_base_addr; |
31 | 30 | ||
32 | 31 | ||
33 | void __init gic_init_irq(void) | 32 | void __init gic_init_irq(void) |
34 | { | 33 | { |
34 | void __iomem *gic_cpu_base; | ||
35 | |||
35 | /* Static mapping, never released */ | 36 | /* Static mapping, never released */ |
36 | gic_dist_base_addr = ioremap(OMAP44XX_GIC_DIST_BASE, SZ_4K); | 37 | gic_dist_base_addr = ioremap(OMAP44XX_GIC_DIST_BASE, SZ_4K); |
37 | BUG_ON(!gic_dist_base_addr); | 38 | BUG_ON(!gic_dist_base_addr); |
38 | gic_dist_init(0, gic_dist_base_addr, 29); | ||
39 | 39 | ||
40 | /* Static mapping, never released */ | 40 | /* Static mapping, never released */ |
41 | gic_cpu_base_addr = ioremap(OMAP44XX_GIC_CPU_BASE, SZ_512); | 41 | gic_cpu_base = ioremap(OMAP44XX_GIC_CPU_BASE, SZ_512); |
42 | BUG_ON(!gic_cpu_base_addr); | 42 | BUG_ON(!gic_cpu_base); |
43 | gic_cpu_init(0, gic_cpu_base_addr); | 43 | |
44 | gic_init(0, 29, gic_dist_base_addr, gic_cpu_base); | ||
44 | } | 45 | } |
45 | 46 | ||
46 | #ifdef CONFIG_CACHE_L2X0 | 47 | #ifdef CONFIG_CACHE_L2X0 |
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c index e13c29eecf2b..a7816dbdc6b1 100644 --- a/arch/arm/mach-omap2/timer-gp.c +++ b/arch/arm/mach-omap2/timer-gp.c | |||
@@ -195,7 +195,6 @@ static struct clocksource clocksource_gpt = { | |||
195 | .rating = 300, | 195 | .rating = 300, |
196 | .read = clocksource_read_cycles, | 196 | .read = clocksource_read_cycles, |
197 | .mask = CLOCKSOURCE_MASK(32), | 197 | .mask = CLOCKSOURCE_MASK(32), |
198 | .shift = 24, | ||
199 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 198 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
200 | }; | 199 | }; |
201 | 200 | ||
@@ -220,9 +219,7 @@ static void __init omap2_gp_clocksource_init(void) | |||
220 | 219 | ||
221 | omap_dm_timer_set_load_start(gpt, 1, 0); | 220 | omap_dm_timer_set_load_start(gpt, 1, 0); |
222 | 221 | ||
223 | clocksource_gpt.mult = | 222 | if (clocksource_register_hz(&clocksource_gpt, tick_rate)) |
224 | clocksource_khz2mult(tick_rate/1000, clocksource_gpt.shift); | ||
225 | if (clocksource_register(&clocksource_gpt)) | ||
226 | printk(err2, clocksource_gpt.name); | 223 | printk(err2, clocksource_gpt.name); |
227 | } | 224 | } |
228 | #endif | 225 | #endif |