--- a/arch/arm/mach-cns3xxx/platsmp.c +++ b/arch/arm/mach-cns3xxx/platsmp.c @@ -1,18 +1,17 @@ -/* linux/arch/arm/mach-cns3xxx/platsmp.c +/* + * linux/arch/arm/mach-cns3xxx/platsmp.c * - * Copyright 2011 Gateworks Corporation + * Copyright (C) 2002 ARM Ltd. + * Copyright 2012 Gateworks Corporation * Chris Lang + * Tim Harvey * - * Cloned from linux/arch/arm/mach-vexpress/platsmp.c - * - * Copyright (C) 2002 ARM Ltd. * All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. -*/ - + */ #include #include #include @@ -30,11 +29,13 @@ extern void cns3xxx_secondary_startup(void); +#define SCU_CPU_STATUS 0x08 +static void __iomem *scu_base; + /* * control for which core is the next to come out of the secondary * boot "holding pen" */ - volatile int __cpuinitdata pen_release = -1; /* @@ -50,11 +51,6 @@ static void write_pen_release(int val) outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1)); } -static void __iomem *scu_base_addr(void) -{ - return (void __iomem *)(CNS3XXX_TC11MP_SCU_BASE_VIRT); -} - static DEFINE_SPINLOCK(boot_lock); void __cpuinit platform_secondary_init(unsigned int cpu) @@ -128,25 +124,24 @@ int __cpuinit boot_secondary(unsigned in * Initialise the CPU possible map early - this describes the CPUs * which may be present or become present in the system. */ - void __init smp_init_cpus(void) { - void __iomem *scu_base = scu_base_addr(); unsigned int i, ncores; + unsigned int status; - ncores = scu_base ? scu_get_core_count(scu_base) : 1; + scu_base = (void __iomem *) CNS3XXX_TC11MP_SCU_BASE_VIRT; - /* sanity check */ - if (ncores > NR_CPUS) { - printk(KERN_WARNING - "cns3xxx: no. of cores (%d) greater than configured " - "maximum of %d - clipping\n", - ncores, NR_CPUS); - ncores = NR_CPUS; + /* for CNS3xxx SCU_CPU_STATUS must be examined instead of SCU_CONFIGURATION + * used in scu_get_core_count + */ + status = __raw_readl(scu_base + SCU_CPU_STATUS); + for (i = 0; i < NR_CPUS+1; i++) { + if (((status >> (i*2)) & 0x3) == 0) + set_cpu_possible(i, true); + else + break; } - - for (i = 0; i < ncores; i++) - set_cpu_possible(i, true); + ncores = i; set_smp_cross_call(gic_raise_softirq); } @@ -159,10 +154,14 @@ void __init platform_smp_prepare_cpus(un * Initialise the present map, which describes the set of CPUs * actually populated at the present time. */ - for (i = 0; i < max_cpus; i++) + for (i = 0; i < max_cpus; i++) { set_cpu_present(i, true); + } - scu_enable(scu_base_addr()); + /* + * enable SCU + */ + scu_enable(scu_base); /* * Write the address of secondary startup into the