Merge branch 'multiplatform/smp_ops' into next/multiplatform
Olof Johansson [Sat, 22 Sep 2012 07:06:21 +0000 (00:06 -0700)]
* 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 <olof@lixom.net>

27 files changed:
1  2 
arch/arm/mach-highbank/core.h
arch/arm/mach-highbank/highbank.c
arch/arm/mach-imx/mach-imx6q.c
arch/arm/mach-msm/board-dt-8660.c
arch/arm/mach-msm/board-dt-8960.c
arch/arm/mach-msm/platsmp.c
arch/arm/mach-omap2/board-4430sdp.c
arch/arm/mach-omap2/board-generic.c
arch/arm/mach-omap2/board-omap4panda.c
arch/arm/mach-omap2/common.h
arch/arm/mach-omap2/omap-hotplug.c
arch/arm/mach-omap2/omap-smp.c
arch/arm/mach-realview/realview_pb11mp.c
arch/arm/mach-realview/realview_pbx.c
arch/arm/mach-shmobile/board-ag5evm.c
arch/arm/mach-shmobile/board-kzm9g.c
arch/arm/mach-shmobile/board-marzen.c
arch/arm/mach-shmobile/setup-emev2.c
arch/arm/mach-tegra/board-dt-tegra20.c
arch/arm/mach-tegra/common.c
arch/arm/mach-tegra/common.h
arch/arm/mach-tegra/hotplug.c
arch/arm/mach-tegra/platsmp.c
arch/arm/mach-ux500/board-mop500.c
arch/arm/mach-ux500/platsmp.c
arch/arm/mach-vexpress/v2m.c
arch/arm/plat-mxc/include/mach/common.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;
Simple merge
Simple merge
index f77f57f,0000000..e5643f6
mode 100644,000000..100644
--- /dev/null
@@@ -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 <linux/init.h>
 +#include <linux/of.h>
 +#include <linux/of_irq.h>
 +#include <linux/of_platform.h>
 +
 +#include <asm/mach/arch.h>
 +#include <asm/hardware/gic.h>
 +
 +#include <mach/board.h>
 +#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
index 8df99b8,0000000..139d61b
mode 100644,000000..100644
--- /dev/null
@@@ -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 <linux/init.h>
 +#include <linux/of_irq.h>
 +#include <linux/of_platform.h>
 +
 +#include <asm/hardware/gic.h>
 +#include <asm/mach/arch.h>
 +
 +#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
  #include <asm/mach-types.h>
  #include <asm/smp_plat.h>
  
 -#include <mach/msm_iomap.h>
 -
  #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
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
  #include <mach/irqs.h>
  
  #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),
Simple merge
index 0000000,301b35e..02f71b4
mode 000000,100644..100644
--- /dev/null
@@@ -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);
  #include <linux/smp.h>
  
  #include <asm/cacheflush.h>
 -#include <asm/cp15.h>
 +#include <asm/smp_plat.h>
  
 -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
  #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
+ };
Simple merge
Simple merge
Simple merge