diff options
author | Arnd Bergmann <arnd@arndb.de> | 2012-05-14 09:59:18 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2012-05-14 11:35:50 -0400 |
commit | 090a80cba39f2763a488b6f7c65e38922d5aa17a (patch) | |
tree | ba3797eeca74c42be95bc592ed2db1be99e329d2 /arch/arm/mach-spear13xx/platsmp.c | |
parent | 36be50515fe2aef61533b516fa2576a2c7fe7664 (diff) | |
parent | eb3f995d7e73fd78b8fcdc55cfbf01a74a09a6e8 (diff) |
Merge branch 'spear/13xx' into next/soc2
* spear/13xx:
pinctrl: SPEAr1310: Fix pin numbers for clcd_high_res
SPEAr: Update MAINTAINERS and Documentation
SPEAr13xx: Add defconfig
SPEAr13xx: Add compilation support
SPEAr13xx: Add dts and dtsi files
pinctrl: Add SPEAr13xx pinctrl drivers
pinctrl: SPEAr: Create macro for declaring GPIO PINS
SPEAr13xx: Add common clock framework support
SPEAr13xx: Add source files
SPEAr13xx: Add header files
Depends on clock, pinctrl and dt branches to go first.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/arm/mach-spear13xx/platsmp.c')
-rw-r--r-- | arch/arm/mach-spear13xx/platsmp.c | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/arch/arm/mach-spear13xx/platsmp.c b/arch/arm/mach-spear13xx/platsmp.c new file mode 100644 index 000000000000..f5d07f2663d7 --- /dev/null +++ b/arch/arm/mach-spear13xx/platsmp.c | |||
@@ -0,0 +1,127 @@ | |||
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/hardware/gic.h> | ||
20 | #include <asm/smp_scu.h> | ||
21 | #include <mach/spear.h> | ||
22 | |||
23 | /* | ||
24 | * control for which core is the next to come out of the secondary | ||
25 | * boot "holding pen" | ||
26 | */ | ||
27 | volatile int __cpuinitdata pen_release = -1; | ||
28 | static DEFINE_SPINLOCK(boot_lock); | ||
29 | |||
30 | static void __iomem *scu_base = IOMEM(VA_SCU_BASE); | ||
31 | extern void spear13xx_secondary_startup(void); | ||
32 | |||
33 | void __cpuinit platform_secondary_init(unsigned int cpu) | ||
34 | { | ||
35 | /* | ||
36 | * if any interrupts are already enabled for the primary | ||
37 | * core (e.g. timer irq), then they will not have been enabled | ||
38 | * for us: do so | ||
39 | */ | ||
40 | gic_secondary_init(0); | ||
41 | |||
42 | /* | ||
43 | * let the primary processor know we're out of the | ||
44 | * pen, then head off into the C entry point | ||
45 | */ | ||
46 | pen_release = -1; | ||
47 | smp_wmb(); | ||
48 | |||
49 | /* | ||
50 | * Synchronise with the boot thread. | ||
51 | */ | ||
52 | spin_lock(&boot_lock); | ||
53 | spin_unlock(&boot_lock); | ||
54 | } | ||
55 | |||
56 | int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) | ||
57 | { | ||
58 | unsigned long timeout; | ||
59 | |||
60 | /* | ||
61 | * set synchronisation state between this boot processor | ||
62 | * and the secondary one | ||
63 | */ | ||
64 | spin_lock(&boot_lock); | ||
65 | |||
66 | /* | ||
67 | * The secondary processor is waiting to be released from | ||
68 | * the holding pen - release it, then wait for it to flag | ||
69 | * that it has been released by resetting pen_release. | ||
70 | * | ||
71 | * Note that "pen_release" is the hardware CPU ID, whereas | ||
72 | * "cpu" is Linux's internal ID. | ||
73 | */ | ||
74 | pen_release = cpu; | ||
75 | flush_cache_all(); | ||
76 | outer_flush_all(); | ||
77 | |||
78 | timeout = jiffies + (1 * HZ); | ||
79 | while (time_before(jiffies, timeout)) { | ||
80 | smp_rmb(); | ||
81 | if (pen_release == -1) | ||
82 | break; | ||
83 | |||
84 | udelay(10); | ||
85 | } | ||
86 | |||
87 | /* | ||
88 | * now the secondary core is starting up let it run its | ||
89 | * calibrations, then wait for it to finish | ||
90 | */ | ||
91 | spin_unlock(&boot_lock); | ||
92 | |||
93 | return pen_release != -1 ? -ENOSYS : 0; | ||
94 | } | ||
95 | |||
96 | /* | ||
97 | * Initialise the CPU possible map early - this describes the CPUs | ||
98 | * which may be present or become present in the system. | ||
99 | */ | ||
100 | void __init smp_init_cpus(void) | ||
101 | { | ||
102 | unsigned int i, ncores = scu_get_core_count(scu_base); | ||
103 | |||
104 | if (ncores > nr_cpu_ids) { | ||
105 | pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", | ||
106 | ncores, nr_cpu_ids); | ||
107 | ncores = nr_cpu_ids; | ||
108 | } | ||
109 | |||
110 | for (i = 0; i < ncores; i++) | ||
111 | set_cpu_possible(i, true); | ||
112 | |||
113 | set_smp_cross_call(gic_raise_softirq); | ||
114 | } | ||
115 | |||
116 | void __init platform_smp_prepare_cpus(unsigned int max_cpus) | ||
117 | { | ||
118 | |||
119 | scu_enable(scu_base); | ||
120 | |||
121 | /* | ||
122 | * Write the address of secondary startup into the system-wide location | ||
123 | * (presently it is in SRAM). The BootMonitor waits until it receives a | ||
124 | * soft interrupt, and then the secondary CPU branches to this address. | ||
125 | */ | ||
126 | __raw_writel(virt_to_phys(spear13xx_secondary_startup), SYS_LOCATION); | ||
127 | } | ||