From: Olof Johansson Date: Sat, 22 Sep 2012 07:06:21 +0000 (-0700) Subject: Merge branch 'multiplatform/smp_ops' into next/multiplatform X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=25468fe89f88c4ceeef94526e94ae0db176f6999;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git Merge branch 'multiplatform/smp_ops' into next/multiplatform * multiplatform/smp_ops: ARM: consolidate pen_release instead of having per platform definitions ARM: smp: Make SMP operations mandatory ARM: SoC: convert spear13xx to SMP operations ARM: SoC: convert imx6q to SMP operations ARM: SoC: convert highbank to SMP operations ARM: SoC: convert shmobile SMP to SMP operations ARM: SoC: convert ux500 to SMP operations ARM: SoC: convert MSM to SMP operations ARM: SoC: convert Exynos4 to SMP operations ARM: SoC: convert Tegra to SMP operations ARM: SoC: convert OMAP4 to SMP operations ARM: SoC: convert VExpress/RealView to SMP operations ARM: SoC: add per-platform SMP operations Conflicts due to file moves or removals in: arch/arm/mach-msm/board-msm8960.c arch/arm/mach-msm/board-msm8x60.c arch/arm/mach-tegra/board-harmony.c arch/arm/mach-tegra/board-trimslice.c Conflicts due to board file cleanup: arch/arm/mach-tegra/board-paz00.c Conflicts due to cpu hotplug addition: arch/arm/mach-tegra/hotplug.c Signed-off-by: Olof Johansson --- 25468fe89f88c4ceeef94526e94ae0db176f6999 diff --cc arch/arm/mach-highbank/core.h index 8b9fb1a46a91,598ee7882b03..286ec82a4f63 --- a/arch/arm/mach-highbank/core.h +++ b/arch/arm/mach-highbank/core.h @@@ -8,10 -8,7 +8,13 @@@ extern void highbank_lluart_map_io(void static inline void highbank_lluart_map_io(void) {} #endif +#ifdef CONFIG_PM_SLEEP +extern void highbank_pm_init(void); +#else +static inline void highbank_pm_init(void) {} +#endif + extern void highbank_smc1(int fn, int arg); + extern void highbank_cpu_die(unsigned int cpu); + + extern struct smp_operations highbank_smp_ops; diff --cc arch/arm/mach-msm/board-dt-8660.c index f77f57f39104,000000000000..e5643f629dcd mode 100644,000000..100644 --- a/arch/arm/mach-msm/board-dt-8660.c +++ b/arch/arm/mach-msm/board-dt-8660.c @@@ -1,63 -1,0 +1,65 @@@ +/* Copyright (c) 2010-2012, The Linux Foundation. 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 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include + +#include +#include + +#include +#include "common.h" ++#include "core.h" + +static const struct of_device_id msm_dt_gic_match[] __initconst = { + { .compatible = "qcom,msm-8660-qgic", .data = gic_of_init }, + {} +}; + +static void __init msm8x60_init_irq(void) +{ + of_irq_init(msm_dt_gic_match); +} + +static void __init msm8x60_init_late(void) +{ + smd_debugfs_init(); +} + +static struct of_dev_auxdata msm_auxdata_lookup[] __initdata = { + {} +}; + +static void __init msm8x60_dt_init(void) +{ + of_platform_populate(NULL, of_default_bus_match_table, + msm_auxdata_lookup, NULL); +} + +static const char *msm8x60_fluid_match[] __initdata = { + "qcom,msm8660-fluid", + "qcom,msm8660-surf", + NULL +}; + +DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)") ++ .smp = smp_ops(msm_smp_ops), + .map_io = msm_map_msm8x60_io, + .init_irq = msm8x60_init_irq, + .handle_irq = gic_handle_irq, + .init_machine = msm8x60_dt_init, + .init_late = msm8x60_init_late, + .timer = &msm_dt_timer, + .dt_compat = msm8x60_fluid_match, +MACHINE_END diff --cc arch/arm/mach-msm/board-dt-8960.c index 8df99b8f3c92,000000000000..139d61bbc8e7 mode 100644,000000..100644 --- a/arch/arm/mach-msm/board-dt-8960.c +++ b/arch/arm/mach-msm/board-dt-8960.c @@@ -1,49 -1,0 +1,51 @@@ +/* Copyright (c) 2012, The Linux Foundation. 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 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include + +#include +#include + +#include "common.h" ++#include "core.h" + +static const struct of_device_id msm_dt_gic_match[] __initconst = { + { .compatible = "qcom,msm-qgic2", .data = gic_of_init }, + { } +}; + +static void __init msm_dt_init_irq(void) +{ + of_irq_init(msm_dt_gic_match); +} + +static void __init msm_dt_init(void) +{ + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); +} + +static const char * const msm8960_dt_match[] __initconst = { + "qcom,msm8960-cdp", + NULL +}; + +DT_MACHINE_START(MSM8960_DT, "Qualcomm MSM (Flattened Device Tree)") ++ .smp = smp_ops(msm_smp_ops), + .map_io = msm_map_msm8960_io, + .init_irq = msm_dt_init_irq, + .timer = &msm_dt_timer, + .init_machine = msm_dt_init, + .dt_compat = msm8960_dt_match, + .handle_irq = gic_handle_irq, +MACHINE_END diff --cc arch/arm/mach-msm/platsmp.c index 2d791e6b4ad1,57af32ef75ed..637021c0d8af --- a/arch/arm/mach-msm/platsmp.c +++ b/arch/arm/mach-msm/platsmp.c @@@ -22,18 -22,19 +22,14 @@@ #include #include -#include - #include "scm-boot.h" + #include "core.h" #define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0 #define SCSS_CPU1CORE_RESET 0xD80 #define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64 -/* Mask for edge trigger PPIs except AVS_SVICINT and AVS_SVICINTSWDONE */ -#define GIC_PPI_EDGE_MASK 0xFFFFD7FF - extern void msm_secondary_startup(void); - /* - * control for which core is the next to come out of the secondary - * boot "holding pen". - */ - volatile int pen_release = -1; static DEFINE_SPINLOCK(boot_lock); @@@ -43,8 -44,11 +39,8 @@@ static inline int get_core_count(void return ((read_cpuid_id() >> 4) & 3) + 1; } - void __cpuinit platform_secondary_init(unsigned int cpu) + static void __cpuinit msm_secondary_init(unsigned int cpu) { - /* Configure edge-triggered PPIs */ - writel(GIC_PPI_EDGE_MASK, MSM_QGIC_DIST_BASE + GIC_DIST_CONFIG + 4); - /* * if any interrupts are already enabled for the primary * core (e.g. timer irq), then they will not have been enabled diff --cc arch/arm/mach-tegra/board-dt-tegra20.c index 5957ffbd4af6,a30537c8003d..5d8c8fb060b0 --- a/arch/arm/mach-tegra/board-dt-tegra20.c +++ b/arch/arm/mach-tegra/board-dt-tegra20.c @@@ -42,8 -42,10 +42,9 @@@ #include #include "board.h" -#include "board-harmony.h" #include "clock.h" #include "devices.h" + #include "common.h" struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = { OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC1_BASE, "sdhci-tegra.0", NULL), diff --cc arch/arm/mach-tegra/common.h index 000000000000,301b35e2f890..02f71b4f1e51 mode 000000,100644..100644 --- a/arch/arm/mach-tegra/common.h +++ b/arch/arm/mach-tegra/common.h @@@ -1,0 -1,3 +1,4 @@@ + extern struct smp_operations tegra_smp_ops; + + extern void tegra_cpu_die(unsigned int cpu); ++extern int tegra_cpu_disable(unsigned int cpu); diff --cc arch/arm/mach-tegra/hotplug.c index d02a35476135,2440705438f4..dca5141a2c31 --- a/arch/arm/mach-tegra/hotplug.c +++ b/arch/arm/mach-tegra/hotplug.c @@@ -12,62 -12,102 +12,57 @@@ #include #include -#include +#include -static inline void cpu_enter_lowpower(void) -{ - unsigned int v; - - flush_cache_all(); - asm volatile( - " mcr p15, 0, %1, c7, c5, 0\n" - " mcr p15, 0, %1, c7, c10, 4\n" - /* - * Turn off coherency - */ - " mrc p15, 0, %0, c1, c0, 1\n" - " bic %0, %0, #0x20\n" - " mcr p15, 0, %0, c1, c0, 1\n" - " mrc p15, 0, %0, c1, c0, 0\n" - " bic %0, %0, %2\n" - " mcr p15, 0, %0, c1, c0, 0\n" - : "=&r" (v) - : "r" (0), "Ir" (CR_C) - : "cc"); -} +#include "sleep.h" +#include "tegra_cpu_car.h" -static inline void cpu_leave_lowpower(void) -{ - unsigned int v; - - asm volatile( - "mrc p15, 0, %0, c1, c0, 0\n" - " orr %0, %0, %1\n" - " mcr p15, 0, %0, c1, c0, 0\n" - " mrc p15, 0, %0, c1, c0, 1\n" - " orr %0, %0, #0x20\n" - " mcr p15, 0, %0, c1, c0, 1\n" - : "=&r" (v) - : "Ir" (CR_C) - : "cc"); -} - -static inline void platform_do_lowpower(unsigned int cpu, int *spurious) -{ - /* - * there is no power-control hardware on this platform, so all - * we can do is put the core into WFI; this is safe as the calling - * code will have already disabled interrupts - */ - for (;;) { - /* - * here's the WFI - */ - asm(".word 0xe320f003\n" - : - : - : "memory", "cc"); - - /*if (pen_release == cpu) {*/ - /* - * OK, proper wakeup, we're done - */ - break; - /*}*/ - - /* - * Getting here, means that we have come out of WFI without - * having been woken up - this shouldn't happen - * - * Just note it happening - when we're woken, we can report - * its occurrence. - */ - (*spurious)++; - } -} +static void (*tegra_hotplug_shutdown)(void); - int platform_cpu_kill(unsigned int cpu) - { - return 1; - } - /* * platform-specific code to shutdown a CPU * * Called with IRQs disabled */ - void platform_cpu_die(unsigned int cpu) + void __ref tegra_cpu_die(unsigned int cpu) { - int spurious = 0; + cpu = cpu_logical_map(cpu); - /* - * we're ready for shutdown now, so do it - */ - cpu_enter_lowpower(); - platform_do_lowpower(cpu, &spurious); + /* Flush the L1 data cache. */ + flush_cache_all(); + + /* Shut down the current CPU. */ + tegra_hotplug_shutdown(); + + /* Clock gate the CPU */ + tegra_wait_cpu_in_reset(cpu); + tegra_disable_cpu_clock(cpu); + + /* Should never return here. */ + BUG(); +} - int platform_cpu_disable(unsigned int cpu) ++int tegra_cpu_disable(unsigned int cpu) +{ /* - * bring this CPU back into the world of cache - * coherency, and then restore interrupts + * we don't allow CPU 0 to be shutdown (it is still too special + * e.g. clock tick interrupts) */ - cpu_leave_lowpower(); + return cpu == 0 ? -EPERM : 0; +} - if (spurious) - pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious); +#ifdef CONFIG_ARCH_TEGRA_2x_SOC +extern void tegra20_hotplug_shutdown(void); +void __init tegra20_hotplug_init(void) +{ + tegra_hotplug_shutdown = tegra20_hotplug_shutdown; +} +#endif + +#ifdef CONFIG_ARCH_TEGRA_3x_SOC +extern void tegra30_hotplug_shutdown(void); +void __init tegra30_hotplug_init(void) +{ + tegra_hotplug_shutdown = tegra30_hotplug_shutdown; } +#endif diff --cc arch/arm/mach-tegra/platsmp.c index 96ed1718eef0,24bfb6534c21..81cb26591acf --- a/arch/arm/mach-tegra/platsmp.c +++ b/arch/arm/mach-tegra/platsmp.c @@@ -31,16 -31,28 +31,18 @@@ #include "fuse.h" #include "flowctrl.h" #include "reset.h" +#include "tegra_cpu_car.h" + #include "common.h" + extern void tegra_secondary_startup(void); static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE); #define EVP_CPU_RESET_VECTOR \ (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100) -#define CLK_RST_CONTROLLER_CLK_CPU_CMPLX \ - (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x4c) -#define CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET \ - (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x340) -#define CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR \ - (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x344) -#define CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR \ - (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x34c) - -#define CPU_CLOCK(cpu) (0x1<<(8+cpu)) -#define CPU_RESET(cpu) (0x1111ul<<(cpu)) - void __cpuinit platform_secondary_init(unsigned int cpu) + static void __cpuinit tegra_secondary_init(unsigned int cpu) { /* * if any interrupts are already enabled for the primary @@@ -167,3 -188,13 +169,14 @@@ static void __init tegra_smp_prepare_cp tegra_cpu_reset_handler_init(); scu_enable(scu_base); } + + struct smp_operations tegra_smp_ops __initdata = { + .smp_init_cpus = tegra_smp_init_cpus, + .smp_prepare_cpus = tegra_smp_prepare_cpus, + .smp_secondary_init = tegra_secondary_init, + .smp_boot_secondary = tegra_boot_secondary, + #ifdef CONFIG_HOTPLUG_CPU + .cpu_die = tegra_cpu_die, ++ .cpu_disable = tegra_cpu_disable, + #endif + };