platsmp.c (c2573077dfacebdf58f69c666e8f15e9528e5a12) | platsmp.c (beddf63fc8e01f06799bd6d7a2dd879885bbc9c6) |
---|---|
1/* linux/arch/arm/mach-exynos4/platsmp.c 2 * 3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. 4 * http://www.samsung.com 5 * 6 * Cloned from linux/arch/arm/mach-vexpress/platsmp.c 7 * 8 * Copyright (C) 2002 ARM Ltd. --- 6 unchanged lines hidden (view full) --- 15 16#include <linux/init.h> 17#include <linux/errno.h> 18#include <linux/delay.h> 19#include <linux/device.h> 20#include <linux/jiffies.h> 21#include <linux/smp.h> 22#include <linux/io.h> | 1/* linux/arch/arm/mach-exynos4/platsmp.c 2 * 3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. 4 * http://www.samsung.com 5 * 6 * Cloned from linux/arch/arm/mach-vexpress/platsmp.c 7 * 8 * Copyright (C) 2002 ARM Ltd. --- 6 unchanged lines hidden (view full) --- 15 16#include <linux/init.h> 17#include <linux/errno.h> 18#include <linux/delay.h> 19#include <linux/device.h> 20#include <linux/jiffies.h> 21#include <linux/smp.h> 22#include <linux/io.h> |
23#include <linux/irqchip/arm-gic.h> |
|
23 24#include <asm/cacheflush.h> 25#include <asm/smp_plat.h> 26#include <asm/smp_scu.h> | 24 25#include <asm/cacheflush.h> 26#include <asm/smp_plat.h> 27#include <asm/smp_scu.h> |
28#include <asm/firmware.h> |
|
27 28#include <mach/hardware.h> 29#include <mach/regs-clock.h> 30#include <mach/regs-pmu.h> 31 32#include <plat/cpu.h> 33 34#include "common.h" --- 35 unchanged lines hidden (view full) --- 70 return (void __iomem *)(S5P_VA_SCU); 71} 72 73static DEFINE_SPINLOCK(boot_lock); 74 75static void __cpuinit exynos_secondary_init(unsigned int cpu) 76{ 77 /* | 29 30#include <mach/hardware.h> 31#include <mach/regs-clock.h> 32#include <mach/regs-pmu.h> 33 34#include <plat/cpu.h> 35 36#include "common.h" --- 35 unchanged lines hidden (view full) --- 72 return (void __iomem *)(S5P_VA_SCU); 73} 74 75static DEFINE_SPINLOCK(boot_lock); 76 77static void __cpuinit exynos_secondary_init(unsigned int cpu) 78{ 79 /* |
80 * if any interrupts are already enabled for the primary 81 * core (e.g. timer irq), then they will not have been enabled 82 * for us: do so 83 */ 84 gic_secondary_init(0); 85 86 /* |
|
78 * let the primary processor know we're out of the 79 * pen, then head off into the C entry point 80 */ 81 write_pen_release(-1); 82 83 /* 84 * Synchronise with the boot thread. 85 */ --- 46 unchanged lines hidden (view full) --- 132 /* 133 * Send the secondary CPU a soft interrupt, thereby causing 134 * the boot monitor to read the system wide flags register, 135 * and branch to the address found there. 136 */ 137 138 timeout = jiffies + (1 * HZ); 139 while (time_before(jiffies, timeout)) { | 87 * let the primary processor know we're out of the 88 * pen, then head off into the C entry point 89 */ 90 write_pen_release(-1); 91 92 /* 93 * Synchronise with the boot thread. 94 */ --- 46 unchanged lines hidden (view full) --- 141 /* 142 * Send the secondary CPU a soft interrupt, thereby causing 143 * the boot monitor to read the system wide flags register, 144 * and branch to the address found there. 145 */ 146 147 timeout = jiffies + (1 * HZ); 148 while (time_before(jiffies, timeout)) { |
149 unsigned long boot_addr; 150 |
|
140 smp_rmb(); 141 | 151 smp_rmb(); 152 |
142 __raw_writel(virt_to_phys(exynos4_secondary_startup), 143 cpu_boot_reg(phys_cpu)); | 153 boot_addr = virt_to_phys(exynos4_secondary_startup); 154 155 /* 156 * Try to set boot address using firmware first 157 * and fall back to boot register if it fails. 158 */ 159 if (call_firmware_op(set_cpu_boot_addr, phys_cpu, boot_addr)) 160 __raw_writel(boot_addr, cpu_boot_reg(phys_cpu)); 161 162 call_firmware_op(cpu_boot, phys_cpu); 163 |
144 arch_send_wakeup_ipi_mask(cpumask_of(cpu)); 145 146 if (pen_release == -1) 147 break; 148 149 udelay(10); 150 } 151 --- 39 unchanged lines hidden (view full) --- 191 if (!(soc_is_exynos5250() || soc_is_exynos5440())) 192 scu_enable(scu_base_addr()); 193 194 /* 195 * Write the address of secondary startup into the 196 * system-wide flags register. The boot monitor waits 197 * until it receives a soft interrupt, and then the 198 * secondary CPU branches to this address. | 164 arch_send_wakeup_ipi_mask(cpumask_of(cpu)); 165 166 if (pen_release == -1) 167 break; 168 169 udelay(10); 170 } 171 --- 39 unchanged lines hidden (view full) --- 211 if (!(soc_is_exynos5250() || soc_is_exynos5440())) 212 scu_enable(scu_base_addr()); 213 214 /* 215 * Write the address of secondary startup into the 216 * system-wide flags register. The boot monitor waits 217 * until it receives a soft interrupt, and then the 218 * secondary CPU branches to this address. |
219 * 220 * Try using firmware operation first and fall back to 221 * boot register if it fails. |
|
199 */ | 222 */ |
200 for (i = 1; i < max_cpus; ++i) 201 __raw_writel(virt_to_phys(exynos4_secondary_startup), 202 cpu_boot_reg(cpu_logical_map(i))); | 223 for (i = 1; i < max_cpus; ++i) { 224 unsigned long phys_cpu; 225 unsigned long boot_addr; 226 227 phys_cpu = cpu_logical_map(i); 228 boot_addr = virt_to_phys(exynos4_secondary_startup); 229 230 if (call_firmware_op(set_cpu_boot_addr, phys_cpu, boot_addr)) 231 __raw_writel(boot_addr, cpu_boot_reg(phys_cpu)); 232 } |
203} 204 205struct smp_operations exynos_smp_ops __initdata = { 206 .smp_init_cpus = exynos_smp_init_cpus, 207 .smp_prepare_cpus = exynos_smp_prepare_cpus, 208 .smp_secondary_init = exynos_secondary_init, 209 .smp_boot_secondary = exynos_boot_secondary, 210#ifdef CONFIG_HOTPLUG_CPU 211 .cpu_die = exynos_cpu_die, 212#endif 213}; | 233} 234 235struct smp_operations exynos_smp_ops __initdata = { 236 .smp_init_cpus = exynos_smp_init_cpus, 237 .smp_prepare_cpus = exynos_smp_prepare_cpus, 238 .smp_secondary_init = exynos_secondary_init, 239 .smp_boot_secondary = exynos_boot_secondary, 240#ifdef CONFIG_HOTPLUG_CPU 241 .cpu_die = exynos_cpu_die, 242#endif 243}; |