aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-spear/platsmp.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-02 12:38:16 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-02 12:38:16 -0400
commit99c6bcf46d2233d33e441834e958ed0bc22b190a (patch)
tree25abf5e856bc0f08d75e623715eb5acc4d4de2b2 /arch/arm/mach-spear/platsmp.c
parent97b1007a2924aaa9126398623f6755a8c3c6a616 (diff)
parent2fdfe1c26fb9f24cfdf124384abb35396ca2cd3f (diff)
Merge tag 'multiplatform-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC multiplatform updates from Olof Johansson: "More multiplatform enablement for ARM platforms. The ones converted in this branch are: - bcm2835 - cns3xxx - sirf - nomadik - msx - spear - tegra - ux500 We're getting close to having most of them converted! One of the larger platforms remaining is Samsung Exynos, and there are a bunch of supporting patches in this merge window for it. There was a patch in this branch to a early version of multiplatform conversion, but it ended up being reverted due to need of more bake time. The revert commit is part of the branch since it would have required rebasing multiple dependent branches and they were stable by then" * tag 'multiplatform-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (70 commits) mmc: sdhci-s3c: Fix operation on non-single image Samsung platforms clocksource: nomadik-mtu: fix up clocksource/timer Revert "ARM: exynos: enable multiplatform support" ARM: SPEAr13xx: Fix typo "ARCH_HAVE_CPUFREQ" ARM: exynos: enable multiplatform support rtc: s3c: make header file local mtd: onenand/samsung: make regs-onenand.h file local thermal/exynos: remove unnecessary header inclusions mmc: sdhci-s3c: remove platform dependencies ARM: samsung: move mfc device definition to s5p-dev-mfc.c ARM: exynos: move debug-macro.S to include/debug/ ARM: exynos: prepare for sparse IRQ ARM: exynos: introduce EXYNOS_ATAGS symbol ARM: tegra: build assembly files with -march=armv7-a ARM: Push selects for TWD/SCU into machine entries ARM: ux500: build hotplug.o for ARMv7-a ARM: ux500: move to multiplatform ARM: ux500: make remaining headers local ARM: ux500: make irqs.h local to platform ARM: ux500: get rid of <mach/[hardware|db8500-regs].h> ...
Diffstat (limited to 'arch/arm/mach-spear/platsmp.c')
-rw-r--r--arch/arm/mach-spear/platsmp.c122
1 files changed, 122 insertions, 0 deletions
diff --git a/arch/arm/mach-spear/platsmp.c b/arch/arm/mach-spear/platsmp.c
new file mode 100644
index 000000000000..9c4c722c954e
--- /dev/null
+++ b/arch/arm/mach-spear/platsmp.c
@@ -0,0 +1,122 @@
1/*
2 * arch/arm/mach-spear13xx/platsmp.c
3 *
4 * based upon linux/arch/arm/mach-realview/platsmp.c
5 *
6 * Copyright (C) 2012 ST Microelectronics Ltd.
7 * Shiraz Hashim <shiraz.hashim@st.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/delay.h>
15#include <linux/jiffies.h>
16#include <linux/io.h>
17#include <linux/smp.h>
18#include <asm/cacheflush.h>
19#include <asm/smp_scu.h>
20#include <mach/spear.h>
21#include "generic.h"
22
23static DEFINE_SPINLOCK(boot_lock);
24
25static void __iomem *scu_base = IOMEM(VA_SCU_BASE);
26
27static void __cpuinit spear13xx_secondary_init(unsigned int cpu)
28{
29 /*
30 * let the primary processor know we're out of the
31 * pen, then head off into the C entry point
32 */
33 pen_release = -1;
34 smp_wmb();
35
36 /*
37 * Synchronise with the boot thread.
38 */
39 spin_lock(&boot_lock);
40 spin_unlock(&boot_lock);
41}
42
43static int __cpuinit spear13xx_boot_secondary(unsigned int cpu, struct task_struct *idle)
44{
45 unsigned long timeout;
46
47 /*
48 * set synchronisation state between this boot processor
49 * and the secondary one
50 */
51 spin_lock(&boot_lock);
52
53 /*
54 * The secondary processor is waiting to be released from
55 * the holding pen - release it, then wait for it to flag
56 * that it has been released by resetting pen_release.
57 *
58 * Note that "pen_release" is the hardware CPU ID, whereas
59 * "cpu" is Linux's internal ID.
60 */
61 pen_release = cpu;
62 flush_cache_all();
63 outer_flush_all();
64
65 timeout = jiffies + (1 * HZ);
66 while (time_before(jiffies, timeout)) {
67 smp_rmb();
68 if (pen_release == -1)
69 break;
70
71 udelay(10);
72 }
73
74 /*
75 * now the secondary core is starting up let it run its
76 * calibrations, then wait for it to finish
77 */
78 spin_unlock(&boot_lock);
79
80 return pen_release != -1 ? -ENOSYS : 0;
81}
82
83/*
84 * Initialise the CPU possible map early - this describes the CPUs
85 * which may be present or become present in the system.
86 */
87static void __init spear13xx_smp_init_cpus(void)
88{
89 unsigned int i, ncores = scu_get_core_count(scu_base);
90
91 if (ncores > nr_cpu_ids) {
92 pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
93 ncores, nr_cpu_ids);
94 ncores = nr_cpu_ids;
95 }
96
97 for (i = 0; i < ncores; i++)
98 set_cpu_possible(i, true);
99}
100
101static void __init spear13xx_smp_prepare_cpus(unsigned int max_cpus)
102{
103
104 scu_enable(scu_base);
105
106 /*
107 * Write the address of secondary startup into the system-wide location
108 * (presently it is in SRAM). The BootMonitor waits until it receives a
109 * soft interrupt, and then the secondary CPU branches to this address.
110 */
111 __raw_writel(virt_to_phys(spear13xx_secondary_startup), SYS_LOCATION);
112}
113
114struct smp_operations spear13xx_smp_ops __initdata = {
115 .smp_init_cpus = spear13xx_smp_init_cpus,
116 .smp_prepare_cpus = spear13xx_smp_prepare_cpus,
117 .smp_secondary_init = spear13xx_secondary_init,
118 .smp_boot_secondary = spear13xx_boot_secondary,
119#ifdef CONFIG_HOTPLUG_CPU
120 .cpu_die = spear13xx_cpu_die,
121#endif
122};