11c51ed4fSMagnus Damm /* 21c51ed4fSMagnus Damm * SMP support for R-Mobile / SH-Mobile 31c51ed4fSMagnus Damm * 41c51ed4fSMagnus Damm * Copyright (C) 2010 Magnus Damm 51c51ed4fSMagnus Damm * 61c51ed4fSMagnus Damm * Based on vexpress, Copyright (C) 2002 ARM Ltd, All Rights Reserved 71c51ed4fSMagnus Damm * 81c51ed4fSMagnus Damm * This program is free software; you can redistribute it and/or modify 91c51ed4fSMagnus Damm * it under the terms of the GNU General Public License version 2 as 101c51ed4fSMagnus Damm * published by the Free Software Foundation. 111c51ed4fSMagnus Damm */ 121c51ed4fSMagnus Damm #include <linux/init.h> 131c51ed4fSMagnus Damm #include <linux/errno.h> 141c51ed4fSMagnus Damm #include <linux/delay.h> 151c51ed4fSMagnus Damm #include <linux/device.h> 161c51ed4fSMagnus Damm #include <linux/smp.h> 171c51ed4fSMagnus Damm #include <linux/io.h> 181c51ed4fSMagnus Damm #include <asm/localtimer.h> 191c51ed4fSMagnus Damm 201c51ed4fSMagnus Damm static unsigned int __init shmobile_smp_get_core_count(void) 211c51ed4fSMagnus Damm { 221c51ed4fSMagnus Damm return 1; 231c51ed4fSMagnus Damm } 241c51ed4fSMagnus Damm 251c51ed4fSMagnus Damm static void __init shmobile_smp_prepare_cpus(void) 261c51ed4fSMagnus Damm { 271c51ed4fSMagnus Damm /* do nothing for now */ 281c51ed4fSMagnus Damm } 291c51ed4fSMagnus Damm 301c51ed4fSMagnus Damm 311c51ed4fSMagnus Damm void __cpuinit platform_secondary_init(unsigned int cpu) 321c51ed4fSMagnus Damm { 331c51ed4fSMagnus Damm trace_hardirqs_off(); 341c51ed4fSMagnus Damm } 351c51ed4fSMagnus Damm 361c51ed4fSMagnus Damm int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) 371c51ed4fSMagnus Damm { 381c51ed4fSMagnus Damm return -ENOSYS; 391c51ed4fSMagnus Damm } 401c51ed4fSMagnus Damm 411c51ed4fSMagnus Damm void __init smp_init_cpus(void) 421c51ed4fSMagnus Damm { 431c51ed4fSMagnus Damm unsigned int ncores = shmobile_smp_get_core_count(); 441c51ed4fSMagnus Damm unsigned int i; 451c51ed4fSMagnus Damm 461c51ed4fSMagnus Damm for (i = 0; i < ncores; i++) 471c51ed4fSMagnus Damm set_cpu_possible(i, true); 481c51ed4fSMagnus Damm } 491c51ed4fSMagnus Damm 501c51ed4fSMagnus Damm void __init smp_prepare_cpus(unsigned int max_cpus) 511c51ed4fSMagnus Damm { 521c51ed4fSMagnus Damm unsigned int ncores = shmobile_smp_get_core_count(); 531c51ed4fSMagnus Damm unsigned int cpu = smp_processor_id(); 541c51ed4fSMagnus Damm int i; 551c51ed4fSMagnus Damm 561c51ed4fSMagnus Damm smp_store_cpu_info(cpu); 571c51ed4fSMagnus Damm 581c51ed4fSMagnus Damm if (max_cpus > ncores) 591c51ed4fSMagnus Damm max_cpus = ncores; 601c51ed4fSMagnus Damm 611c51ed4fSMagnus Damm for (i = 0; i < max_cpus; i++) 621c51ed4fSMagnus Damm set_cpu_present(i, true); 631c51ed4fSMagnus Damm 641c51ed4fSMagnus Damm if (max_cpus > 1) { 651c51ed4fSMagnus Damm shmobile_smp_prepare_cpus(); 661c51ed4fSMagnus Damm 671c51ed4fSMagnus Damm /* 681c51ed4fSMagnus Damm * Enable the local timer or broadcast device for the 691c51ed4fSMagnus Damm * boot CPU, but only if we have more than one CPU. 701c51ed4fSMagnus Damm */ 711c51ed4fSMagnus Damm percpu_timer_setup(); 721c51ed4fSMagnus Damm } 731c51ed4fSMagnus Damm } 74