11c51ed4fSMagnus Damm /* 21c51ed4fSMagnus Damm * SMP support for R-Mobile / SH-Mobile 31c51ed4fSMagnus Damm * 41c51ed4fSMagnus Damm * Copyright (C) 2010 Magnus Damm 5c413521eSPaul Mundt * Copyright (C) 2011 Paul Mundt 61c51ed4fSMagnus Damm * 71c51ed4fSMagnus Damm * Based on vexpress, Copyright (C) 2002 ARM Ltd, All Rights Reserved 81c51ed4fSMagnus Damm * 91c51ed4fSMagnus Damm * This program is free software; you can redistribute it and/or modify 101c51ed4fSMagnus Damm * it under the terms of the GNU General Public License version 2 as 111c51ed4fSMagnus Damm * published by the Free Software Foundation. 121c51ed4fSMagnus Damm */ 131c51ed4fSMagnus Damm #include <linux/init.h> 141c51ed4fSMagnus Damm #include <linux/errno.h> 151c51ed4fSMagnus Damm #include <linux/delay.h> 161c51ed4fSMagnus Damm #include <linux/device.h> 171c51ed4fSMagnus Damm #include <linux/smp.h> 181c51ed4fSMagnus Damm #include <linux/io.h> 190f7b332fSRussell King #include <asm/hardware/gic.h> 201c51ed4fSMagnus Damm #include <asm/localtimer.h> 2172f4d579SMagnus Damm #include <asm/mach-types.h> 2272f4d579SMagnus Damm #include <mach/common.h> 231c51ed4fSMagnus Damm 241c51ed4fSMagnus Damm static unsigned int __init shmobile_smp_get_core_count(void) 251c51ed4fSMagnus Damm { 2672f4d579SMagnus Damm if (machine_is_ag5evm()) 2772f4d579SMagnus Damm return sh73a0_get_core_count(); 2872f4d579SMagnus Damm 291c51ed4fSMagnus Damm return 1; 301c51ed4fSMagnus Damm } 311c51ed4fSMagnus Damm 321c51ed4fSMagnus Damm static void __init shmobile_smp_prepare_cpus(void) 331c51ed4fSMagnus Damm { 3472f4d579SMagnus Damm if (machine_is_ag5evm()) 3572f4d579SMagnus Damm sh73a0_smp_prepare_cpus(); 361c51ed4fSMagnus Damm } 371c51ed4fSMagnus Damm 381c51ed4fSMagnus Damm void __cpuinit platform_secondary_init(unsigned int cpu) 391c51ed4fSMagnus Damm { 401c51ed4fSMagnus Damm trace_hardirqs_off(); 4172f4d579SMagnus Damm 4272f4d579SMagnus Damm if (machine_is_ag5evm()) 4372f4d579SMagnus Damm sh73a0_secondary_init(cpu); 441c51ed4fSMagnus Damm } 451c51ed4fSMagnus Damm 461c51ed4fSMagnus Damm int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) 471c51ed4fSMagnus Damm { 4872f4d579SMagnus Damm if (machine_is_ag5evm()) 4972f4d579SMagnus Damm return sh73a0_boot_secondary(cpu); 5072f4d579SMagnus Damm 511c51ed4fSMagnus Damm return -ENOSYS; 521c51ed4fSMagnus Damm } 531c51ed4fSMagnus Damm 541c51ed4fSMagnus Damm void __init smp_init_cpus(void) 551c51ed4fSMagnus Damm { 561c51ed4fSMagnus Damm unsigned int ncores = shmobile_smp_get_core_count(); 571c51ed4fSMagnus Damm unsigned int i; 581c51ed4fSMagnus Damm 591c51ed4fSMagnus Damm for (i = 0; i < ncores; i++) 601c51ed4fSMagnus Damm set_cpu_possible(i, true); 610f7b332fSRussell King 620f7b332fSRussell King set_smp_cross_call(gic_raise_softirq); 631c51ed4fSMagnus Damm } 641c51ed4fSMagnus Damm 65c413521eSPaul Mundt void __init platform_smp_prepare_cpus(unsigned int max_cpus) 661c51ed4fSMagnus Damm { 671c51ed4fSMagnus Damm int i; 681c51ed4fSMagnus Damm 691c51ed4fSMagnus Damm for (i = 0; i < max_cpus; i++) 701c51ed4fSMagnus Damm set_cpu_present(i, true); 711c51ed4fSMagnus Damm 721c51ed4fSMagnus Damm shmobile_smp_prepare_cpus(); 731c51ed4fSMagnus Damm } 74