diff options
author | Peter De Schrijver <pdeschrijver@nvidia.com> | 2012-07-19 15:44:05 +0300 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2013-09-14 12:14:51 -0700 |
commit | e780103d0ad125d6c0a3c8534bbea4adf8179a57 (patch) | |
tree | 9a31c5594af13b6bf07d38e7b1b285f9caf097f3 /arch/arm/mach-tegra/platsmp.c | |
parent | aa2bacbad3de9e668e16e38172c7606c077a6572 (diff) |
ARM: tegra: fix section mismatch for get_core_count
get_core_count calls scu_get_core_count which is part of the __init section.
Hence we can only call this from another function inside this section.
Refactor the code to initialize number_of_cores at boottime in an __init
function.
Change-Id: I200a6ea297a8abe1a3b3fbdd050de5917875d7bc
Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com>
Reviewed-on: http://git-master/r/117053
Reviewed-by: Simone Willett <swillett@nvidia.com>
Tested-by: Simone Willett <swillett@nvidia.com>
Rebase-Id: Ra89316289b1c471916dcbc9e3b260894b2f34265
Diffstat (limited to 'arch/arm/mach-tegra/platsmp.c')
-rw-r--r-- | arch/arm/mach-tegra/platsmp.c | 40 |
1 files changed, 23 insertions, 17 deletions
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c index ffc1d2006b56..92527d0c2481 100644 --- a/arch/arm/mach-tegra/platsmp.c +++ b/arch/arm/mach-tegra/platsmp.c @@ -58,7 +58,9 @@ const struct cpumask *const tegra_cpu_init_mask = to_cpumask(tegra_cpu_init_bits static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE); #endif -static noinline unsigned int get_core_count(void) +static unsigned int number_of_cores; + +static void __init setup_core_count(void) { #ifndef CONFIG_ARCH_TEGRA_2x_SOC u32 l2ctlr; @@ -68,31 +70,31 @@ static noinline unsigned int get_core_count(void) /* Cortex-A15? */ if (cpuid == 0xC0F) { __asm__("mrc p15, 1, %0, c9, c0, 2\n" : "=r" (l2ctlr)); - return ((l2ctlr >> 24) & 3) + 1; + number_of_cores = ((l2ctlr >> 24) & 3) + 1; } + else { #endif #ifdef CONFIG_HAVE_ARM_SCU - return scu_get_core_count(scu_base); + number_of_cores = scu_get_core_count(scu_base); #else - return 1; + number_of_cores = 1; +#endif +#ifndef CONFIG_ARCH_TEGRA_2x_SOC + } + if (number_of_cores > 1) { + u32 fuse_sku = readl(FUSE_SKU_DIRECT_CONFIG); + number_of_cores -= FUSE_SKU_NUM_DISABLED_CPUS(fuse_sku); + BUG_ON((int)number_of_cores <= 0); + } #endif } static unsigned int available_cpus(void) { - static unsigned int ncores; - if (ncores == 0) { - ncores = get_core_count(); -#ifndef CONFIG_ARCH_TEGRA_2x_SOC - if (ncores > 1) { - u32 fuse_sku = readl(FUSE_SKU_DIRECT_CONFIG); - ncores -= FUSE_SKU_NUM_DISABLED_CPUS(fuse_sku); - BUG_ON((int)ncores <= 0); - } -#endif - } - return ncores; + BUG_ON((int)number_of_cores <= 0); + + return number_of_cores; } static int is_g_cluster_available(unsigned int cpu) @@ -301,9 +303,13 @@ done: */ static void __init tegra_smp_init_cpus(void) { - unsigned int ncores = available_cpus(); + unsigned int ncores; unsigned int i; + setup_core_count(); + + ncores = available_cpus(); + if (ncores > nr_cpu_ids) { pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", ncores, nr_cpu_ids); |