Merge tag 'exynos-cpuidle' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene...
authorOlof Johansson <olof@lixom.net>
Sat, 19 Jul 2014 22:03:08 +0000 (15:03 -0700)
committerOlof Johansson <olof@lixom.net>
Sat, 19 Jul 2014 22:03:08 +0000 (15:03 -0700)
Merge "Samsung exynos cpuidle update for v3.17" from Kukjin Kim:

- add callbacks exynos_suspend() and exynos_powered_up()
  for support cpuidle through mcpm
- skip exynos_cpuidle for exynos5420 because is uses
  cpuidle-big-liggle generic cpuidle driver
- add generic functions to calculate cpu number is used
  for pmu and this is required for exynos5420 multi-cluster
- add of_device_id structure for big.LITTLE cpuidle and
  add "samsung,exynos5420" compatible string for exynos5420

* tag 'exynos-cpuidle' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung:
  ARM: EXYNOS: populate suspend and powered_up callbacks for mcpm
  ARM: EXYNOS: do not allow cpuidle registration for exynos5420
  cpuidle: big.LITTLE: init driver for exynos5420
  cpuidle: big.LITTLE: Add ARCH_EXYNOS entry in config
  ARM: EXYNOS: add generic function to calculate cpu number
  cpuidle: big.LITTLE: add of_device_id structure
  + Linux 3.16-rc5

Signed-off-by: Olof Johansson <olof@lixom.net>
1  2 
arch/arm/configs/multi_v7_defconfig
arch/arm/mach-mvebu/Makefile
arch/arm/mach-mvebu/board-v7.c
arch/arm/mach-mvebu/pmsu.c
arch/arm/mach-sunxi/sunxi.c

@@@ -27,7 -27,7 +27,7 @@@ CONFIG_ARCH_HIGHBANK=
  CONFIG_ARCH_HI3xxx=y
  CONFIG_ARCH_KEYSTONE=y
  CONFIG_ARCH_MXC=y
 -CONFIG_MACH_IMX51_DT=y
 +CONFIG_SOC_IMX51=y
  CONFIG_SOC_IMX53=y
  CONFIG_SOC_IMX6Q=y
  CONFIG_SOC_IMX6SL=y
@@@ -223,12 -223,12 +223,12 @@@ CONFIG_POWER_RESET_GPIO=
  CONFIG_POWER_RESET_SUN6I=y
  CONFIG_SENSORS_LM90=y
  CONFIG_THERMAL=y
- CONFIG_DOVE_THERMAL=y
  CONFIG_ARMADA_THERMAL=y
  CONFIG_WATCHDOG=y
  CONFIG_ORION_WATCHDOG=y
  CONFIG_SUNXI_WATCHDOG=y
  CONFIG_MFD_AS3722=y
+ CONFIG_MFD_BCM590XX=y
  CONFIG_MFD_CROS_EC=y
  CONFIG_MFD_CROS_EC_SPI=y
  CONFIG_MFD_MAX8907=y
@@@ -240,6 -240,7 +240,7 @@@ CONFIG_MFD_TPS65910=
  CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
  CONFIG_REGULATOR_AB8500=y
  CONFIG_REGULATOR_AS3722=y
+ CONFIG_REGULATOR_BCM590XX=y
  CONFIG_REGULATOR_GPIO=y
  CONFIG_REGULATOR_MAX8907=y
  CONFIG_REGULATOR_PALMAS=y
@@@ -7,10 -7,10 +7,10 @@@ CFLAGS_pmsu.o                 := -march=armv7-
  obj-y                          += system-controller.o mvebu-soc-id.o
  
  ifeq ($(CONFIG_MACH_MVEBU_V7),y)
- obj-y                          += cpu-reset.o board-v7.o coherency.o coherency_ll.o pmsu.o
+ obj-y                          += cpu-reset.o board-v7.o coherency.o coherency_ll.o pmsu.o pmsu_ll.o
  obj-$(CONFIG_SMP)              += platsmp.o headsmp.o platsmp-a9.o headsmp-a9.o
 -obj-$(CONFIG_HOTPLUG_CPU)      += hotplug.o
  endif
  
  obj-$(CONFIG_MACH_DOVE)                += dove.o
  obj-$(CONFIG_MACH_KIRKWOOD)    += kirkwood.o kirkwood-pm.o
 +obj-$(CONFIG_MACH_NETXBIG)     += netxbig.o
@@@ -23,6 -23,7 +23,7 @@@
  #include <linux/mbus.h>
  #include <linux/signal.h>
  #include <linux/slab.h>
+ #include <linux/irqchip.h>
  #include <asm/hardware/cache-l2x0.h>
  #include <asm/mach/arch.h>
  #include <asm/mach/map.h>
@@@ -71,17 -72,23 +72,23 @@@ static int armada_375_external_abort_wa
        return 1;
  }
  
- static void __init mvebu_timer_and_clk_init(void)
+ static void __init mvebu_init_irq(void)
  {
-       of_clk_init(NULL);
-       clocksource_of_init();
+       irqchip_init();
        mvebu_scu_enable();
        coherency_init();
        BUG_ON(mvebu_mbus_dt_init(coherency_available()));
+ }
+ static void __init external_abort_quirk(void)
+ {
+       u32 dev, rev;
  
-       if (of_machine_is_compatible("marvell,armada375"))
-               hook_fault_code(16 + 6, armada_375_external_abort_wa, SIGBUS, 0,
-                               "imprecise external abort");
+       if (mvebu_get_soc_id(&dev, &rev) == 0 && rev > ARMADA_375_Z1_REV)
+               return;
+       hook_fault_code(16 + 6, armada_375_external_abort_wa, SIGBUS, 0,
+                       "imprecise external abort");
  }
  
  static void __init i2c_quirk(void)
@@@ -118,16 -125,8 +125,16 @@@ static void __init thermal_quirk(void
  {
        struct device_node *np;
        u32 dev, rev;
 +      int res;
  
 -      if (mvebu_get_soc_id(&dev, &rev) == 0 && rev > ARMADA_375_Z1_REV)
 +      /*
 +       * The early SoC Z1 revision needs a quirk to be applied in order
 +       * for the thermal controller to work properly. This quirk breaks
 +       * the thermal support if applied on a SoC that doesn't need it,
 +       * so we enforce the SoC revision to be known.
 +       */
 +      res = mvebu_get_soc_id(&dev, &rev);
 +      if (res < 0 || (res == 0 && rev > ARMADA_375_Z1_REV))
                return;
  
        for_each_compatible_node(np, NULL, "marvell,armada375-thermal") {
  
                /*
                 * The thermal controller needs some quirk too, so let's change
 -               * the compatible string to reflect this.
 +               * the compatible string to reflect this and allow the driver
 +               * the take the necessary action.
                 */
                prop = kzalloc(sizeof(*prop), GFP_KERNEL);
                prop->name = kstrdup("compatible", GFP_KERNEL);
@@@ -178,8 -176,10 +185,10 @@@ static void __init mvebu_dt_init(void
  {
        if (of_machine_is_compatible("plathome,openblocks-ax3-4"))
                i2c_quirk();
-       if (of_machine_is_compatible("marvell,a375-db"))
+       if (of_machine_is_compatible("marvell,a375-db")) {
+               external_abort_quirk();
                thermal_quirk();
+       }
  
        of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
  }
@@@ -194,7 -194,7 +203,7 @@@ DT_MACHINE_START(ARMADA_370_XP_DT, "Mar
        .l2c_aux_mask   = ~0,
        .smp            = smp_ops(armada_xp_smp_ops),
        .init_machine   = mvebu_dt_init,
-       .init_time      = mvebu_timer_and_clk_init,
+       .init_irq       = mvebu_init_irq,
        .restart        = mvebu_restart,
        .dt_compat      = armada_370_xp_dt_compat,
  MACHINE_END
@@@ -207,7 -207,7 +216,7 @@@ static const char * const armada_375_dt
  DT_MACHINE_START(ARMADA_375_DT, "Marvell Armada 375 (Device Tree)")
        .l2c_aux_val    = 0,
        .l2c_aux_mask   = ~0,
-       .init_time      = mvebu_timer_and_clk_init,
+       .init_irq       = mvebu_init_irq,
        .init_machine   = mvebu_dt_init,
        .restart        = mvebu_restart,
        .dt_compat      = armada_375_dt_compat,
@@@ -222,7 -222,7 +231,7 @@@ static const char * const armada_38x_dt
  DT_MACHINE_START(ARMADA_38X_DT, "Marvell Armada 380/385 (Device Tree)")
        .l2c_aux_val    = 0,
        .l2c_aux_mask   = ~0,
-       .init_time      = mvebu_timer_and_clk_init,
+       .init_irq       = mvebu_init_irq,
        .restart        = mvebu_restart,
        .dt_compat      = armada_38x_dt_compat,
  MACHINE_END
@@@ -66,6 -66,8 +66,8 @@@ static void __iomem *pmsu_mp_base
  extern void ll_disable_coherency(void);
  extern void ll_enable_coherency(void);
  
+ extern void armada_370_xp_cpu_resume(void);
  static struct platform_device armada_xp_cpuidle_device = {
        .name = "cpuidle-armada-370-xp",
  };
@@@ -140,21 -142,14 +142,14 @@@ static void armada_370_xp_pmsu_enable_l
        writel(reg, pmsu_mp_base + L2C_NFABRIC_PM_CTL);
  }
  
- static void armada_370_xp_cpu_resume(void)
- {
-       asm volatile("bl    ll_add_cpu_to_smp_group\n\t"
-                    "bl    ll_enable_coherency\n\t"
-                    "b     cpu_resume\n\t");
- }
  /* No locking is needed because we only access per-CPU registers */
 -void armada_370_xp_pmsu_idle_prepare(bool deepidle)
 +int armada_370_xp_pmsu_idle_enter(unsigned long deepidle)
  {
        unsigned int hw_cpu = cpu_logical_map(smp_processor_id());
        u32 reg;
  
        if (pmsu_mp_base == NULL)
 -              return;
 +              return -EINVAL;
  
        /*
         * Adjust the PMSU configuration to wait for WFI signal, enable
        reg = readl(pmsu_mp_base + PMSU_CPU_POWER_DOWN_CONTROL(hw_cpu));
        reg |= PMSU_CPU_POWER_DOWN_DIS_SNP_Q_SKIP;
        writel(reg, pmsu_mp_base + PMSU_CPU_POWER_DOWN_CONTROL(hw_cpu));
 -}
 -
 -static noinline int do_armada_370_xp_cpu_suspend(unsigned long deepidle)
 -{
 -      armada_370_xp_pmsu_idle_prepare(deepidle);
  
        v7_exit_coherency_flush(all);
  
  
  static int armada_370_xp_cpu_suspend(unsigned long deepidle)
  {
 -      return cpu_suspend(deepidle, do_armada_370_xp_cpu_suspend);
 +      return cpu_suspend(deepidle, armada_370_xp_pmsu_idle_enter);
  }
  
  /* No locking is needed because we only access per-CPU registers */
 -static noinline void armada_370_xp_pmsu_idle_restore(void)
 +void armada_370_xp_pmsu_idle_exit(void)
  {
        unsigned int hw_cpu = cpu_logical_map(smp_processor_id());
        u32 reg;
@@@ -248,7 -248,7 +243,7 @@@ static int armada_370_xp_cpu_pm_notify(
                unsigned int hw_cpu = cpu_logical_map(smp_processor_id());
                mvebu_pmsu_set_cpu_boot_addr(hw_cpu, armada_370_xp_cpu_resume);
        } else if (action == CPU_PM_EXIT) {
 -              armada_370_xp_pmsu_idle_restore();
 +              armada_370_xp_pmsu_idle_exit();
        }
  
        return NOTIFY_OK;
@@@ -258,7 -258,7 +253,7 @@@ static struct notifier_block armada_370
        .notifier_call = armada_370_xp_cpu_pm_notify,
  };
  
 -int __init armada_370_xp_cpu_pm_init(void)
 +static int __init armada_370_xp_cpu_pm_init(void)
  {
        struct device_node *np;
  
  
  #include <linux/clk-provider.h>
  #include <linux/clocksource.h>
+ #include <linux/delay.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/of_address.h>
+ #include <linux/of_irq.h>
+ #include <linux/of_platform.h>
+ #include <linux/io.h>
+ #include <linux/reboot.h>
  
  #include <asm/mach/arch.h>
+ #include <asm/mach/map.h>
+ #include <asm/system_misc.h>
+ #define SUN4I_WATCHDOG_CTRL_REG               0x00
+ #define SUN4I_WATCHDOG_CTRL_RESTART           BIT(0)
+ #define SUN4I_WATCHDOG_MODE_REG               0x04
+ #define SUN4I_WATCHDOG_MODE_ENABLE            BIT(0)
+ #define SUN4I_WATCHDOG_MODE_RESET_ENABLE      BIT(1)
+ #define SUN6I_WATCHDOG1_IRQ_REG               0x00
+ #define SUN6I_WATCHDOG1_CTRL_REG      0x10
+ #define SUN6I_WATCHDOG1_CTRL_RESTART          BIT(0)
+ #define SUN6I_WATCHDOG1_CONFIG_REG    0x14
+ #define SUN6I_WATCHDOG1_CONFIG_RESTART                BIT(0)
+ #define SUN6I_WATCHDOG1_CONFIG_IRQ            BIT(1)
+ #define SUN6I_WATCHDOG1_MODE_REG      0x18
+ #define SUN6I_WATCHDOG1_MODE_ENABLE           BIT(0)
+ static void __iomem *wdt_base;
+ static void sun4i_restart(enum reboot_mode mode, const char *cmd)
+ {
+       if (!wdt_base)
+               return;
+       /* Enable timer and set reset bit in the watchdog */
+       writel(SUN4I_WATCHDOG_MODE_ENABLE | SUN4I_WATCHDOG_MODE_RESET_ENABLE,
+              wdt_base + SUN4I_WATCHDOG_MODE_REG);
+       /*
+        * Restart the watchdog. The default (and lowest) interval
+        * value for the watchdog is 0.5s.
+        */
+       writel(SUN4I_WATCHDOG_CTRL_RESTART, wdt_base + SUN4I_WATCHDOG_CTRL_REG);
+       while (1) {
+               mdelay(5);
+               writel(SUN4I_WATCHDOG_MODE_ENABLE | SUN4I_WATCHDOG_MODE_RESET_ENABLE,
+                      wdt_base + SUN4I_WATCHDOG_MODE_REG);
+       }
+ }
+ static struct of_device_id sunxi_restart_ids[] = {
+       { .compatible = "allwinner,sun4i-a10-wdt" },
+       { /*sentinel*/ }
+ };
+ static void sunxi_setup_restart(void)
+ {
+       struct device_node *np;
+       np = of_find_matching_node(NULL, sunxi_restart_ids);
+       if (WARN(!np, "unable to setup watchdog restart"))
+               return;
+       wdt_base = of_iomap(np, 0);
+       WARN(!wdt_base, "failed to map watchdog base address");
+ }
+ static void __init sunxi_dt_init(void)
+ {
+       sunxi_setup_restart();
+       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+ }
  
  static const char * const sunxi_board_dt_compat[] = {
        "allwinner,sun4i-a10",
@@@ -23,7 -96,9 +96,9 @@@
  };
  
  DT_MACHINE_START(SUNXI_DT, "Allwinner A1X (Device Tree)")
+       .init_machine   = sunxi_dt_init,
        .dt_compat      = sunxi_board_dt_compat,
+       .restart        = sun4i_restart,
  MACHINE_END
  
  static const char * const sun6i_board_dt_compat[] = {
@@@ -51,14 -126,7 +126,16 @@@ static const char * const sun7i_board_d
  };
  
  DT_MACHINE_START(SUN7I_DT, "Allwinner sun7i (A20) Family")
+       .init_machine   = sunxi_dt_init,
        .dt_compat      = sun7i_board_dt_compat,
+       .restart        = sun4i_restart,
  MACHINE_END
 +
 +static const char * const sun8i_board_dt_compat[] = {
 +      "allwinner,sun8i-a23",
 +      NULL,
 +};
 +
 +DT_MACHINE_START(SUN8I_DT, "Allwinner sun8i (A23) Family")
 +      .dt_compat      = sun8i_board_dt_compat,
 +MACHINE_END