1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include <linux/init.h>
19#include <linux/device.h>
20#include <linux/jiffies.h>
21#include <linux/smp.h>
22#include <linux/io.h>
23
24#include <asm/localtimer.h>
25#include <asm/smp_scu.h>
26#include <mach/hardware.h>
27
28
29#define OMAP4_AUXCOREBOOT_REG0 (OMAP44XX_VA_WKUPGEN_BASE + 0x800)
30#define OMAP4_AUXCOREBOOT_REG1 (OMAP44XX_VA_WKUPGEN_BASE + 0x804)
31
32
33static void __iomem *scu_base = OMAP44XX_VA_SCU_BASE;
34
35
36
37
38static inline unsigned int get_core_count(void)
39{
40 if (scu_base)
41 return scu_get_core_count(scu_base);
42 return 1;
43}
44
45static DEFINE_SPINLOCK(boot_lock);
46
47void __cpuinit platform_secondary_init(unsigned int cpu)
48{
49 trace_hardirqs_off();
50
51
52
53
54
55
56
57 gic_cpu_init(0, OMAP2_IO_ADDRESS(OMAP44XX_GIC_CPU_BASE));
58
59
60
61
62 spin_lock(&boot_lock);
63 spin_unlock(&boot_lock);
64}
65
66int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
67{
68 unsigned long timeout;
69
70
71
72
73
74 spin_lock(&boot_lock);
75
76
77
78
79
80
81
82 __raw_writel(cpu, OMAP4_AUXCOREBOOT_REG1);
83 smp_wmb();
84
85 timeout = jiffies + (1 * HZ);
86 while (time_before(jiffies, timeout))
87 ;
88
89
90
91
92
93 spin_unlock(&boot_lock);
94
95 return 0;
96}
97
98static void __init wakeup_secondary(void)
99{
100
101
102
103
104
105
106 __raw_writel(virt_to_phys(omap_secondary_startup), \
107 OMAP4_AUXCOREBOOT_REG0);
108 smp_wmb();
109
110
111
112
113 set_event();
114 mb();
115}
116
117
118
119
120
121void __init smp_init_cpus(void)
122{
123 unsigned int i, ncores = get_core_count();
124
125 for (i = 0; i < ncores; i++)
126 set_cpu_possible(i, true);
127}
128
129void __init smp_prepare_cpus(unsigned int max_cpus)
130{
131 unsigned int ncores = get_core_count();
132 unsigned int cpu = smp_processor_id();
133 int i;
134
135
136 if (ncores == 0) {
137 printk(KERN_ERR
138 "OMAP4: strange core count of 0? Default to 1\n");
139 ncores = 1;
140 }
141
142 if (ncores > NR_CPUS) {
143 printk(KERN_WARNING
144 "OMAP4: no. of cores (%d) greater than configured "
145 "maximum of %d - clipping\n",
146 ncores, NR_CPUS);
147 ncores = NR_CPUS;
148 }
149 smp_store_cpu_info(cpu);
150
151
152
153
154 if (max_cpus > ncores)
155 max_cpus = ncores;
156
157
158
159
160
161 for (i = 0; i < max_cpus; i++)
162 set_cpu_present(i, true);
163
164 if (max_cpus > 1) {
165
166
167
168
169 percpu_timer_setup();
170
171
172
173
174
175 scu_enable(scu_base);
176 wakeup_secondary();
177 }
178}
179