]> Pileus Git - ~andy/linux/commitdiff
Merge branch 'gic/cleanup' into next/soc
authorOlof Johansson <olof@lixom.net>
Sun, 28 Apr 2013 22:06:56 +0000 (15:06 -0700)
committerOlof Johansson <olof@lixom.net>
Sun, 28 Apr 2013 22:06:56 +0000 (15:06 -0700)
Merge in the gic cleanup since it has a handful of annoying internal conflicts
with soc development branches. All of them are delete/delete conflicts.

* gic/cleanup:
  irqchip: vic: add include of linux/irq.h
  irqchip: gic: Perform the gic_secondary_init() call via CPU notifier
  irqchip: gic: Call handle_bad_irq() directly
  arm: Move chained_irq_(enter|exit) to a generic file
  arm: Move the set_handle_irq and handle_arch_irq declarations to asm/irq.h

Signed-off-by: Olof Johansson <olof@lixom.net>
Conflicts:
arch/arm/mach-shmobile/smp-emev2.c
arch/arm/mach-shmobile/smp-r8a7779.c
arch/arm/mach-shmobile/smp-sh73a0.c
arch/arm/mach-socfpga/platsmp.c

1  2 
arch/arm/mach-exynos/common.c
arch/arm/mach-shmobile/smp-emev2.c
arch/arm/mach-shmobile/smp-r8a7779.c
arch/arm/mach-shmobile/smp-sh73a0.c
arch/arm/mach-socfpga/platsmp.c
arch/arm/mach-tegra/platsmp.c
drivers/gpio/gpio-tegra.c
drivers/pinctrl/pinctrl-at91.c

index 789d4e66c9506955d145a80555ab7f9182061d90,7bc0f9aa8b331cb8ec072639b5e7ef9d7141b05e..99b7f1cbbb8babf48d09a7b35e43895b3cdac00a
@@@ -26,6 -26,7 +26,7 @@@
  #include <linux/irqchip.h>
  #include <linux/of_address.h>
  #include <linux/irqchip/arm-gic.h>
+ #include <linux/irqchip/chained_irq.h>
  
  #include <asm/proc-fns.h>
  #include <asm/exception.h>
@@@ -463,8 -464,6 +464,8 @@@ void __init exynos4_init_irq(void
         * uses GIC instead of VIC.
         */
        s5p_init_irq(NULL, 0);
 +
 +      gic_arch_extn.irq_set_wake = s3c_irq_wake;
  }
  
  void __init exynos5_init_irq(void)
index 8225c16b371b47fb549b8dd6a9397b5059229b62,384e27dd3601ff19f9d8e4b30db98579f5237333..e38691b4d0ddc0fc2f57856567432d6a8d60d2f3
  #include <linux/spinlock.h>
  #include <linux/io.h>
  #include <linux/delay.h>
- #include <linux/irqchip/arm-gic.h>
  #include <mach/common.h>
  #include <mach/emev2.h>
  #include <asm/smp_plat.h>
  #include <asm/smp_scu.h>
 -#include <asm/cacheflush.h>
  
  #define EMEV2_SCU_BASE 0x1e000000
  
- static void __cpuinit emev2_secondary_init(unsigned int cpu)
 -static DEFINE_SPINLOCK(scu_lock);
 -static void __iomem *scu_base;
 -
 -static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
--{
-       gic_secondary_init(0);
 -      unsigned long tmp;
 -
 -      /* we assume this code is running on a different cpu
 -       * than the one that is changing coherency setting */
 -      spin_lock(&scu_lock);
 -      tmp = readl(scu_base + 8);
 -      tmp &= ~clr;
 -      tmp |= set;
 -      writel(tmp, scu_base + 8);
 -      spin_unlock(&scu_lock);
 -
 -}
 -
 -static unsigned int __init emev2_get_core_count(void)
 -{
 -      if (!scu_base) {
 -              scu_base = ioremap(EMEV2_SCU_BASE, PAGE_SIZE);
 -              emev2_clock_init(); /* need ioremapped SMU */
 -      }
 -
 -      WARN_ON_ONCE(!scu_base);
 -
 -      return scu_base ? scu_get_core_count(scu_base) : 1;
 -}
 -
 -static int emev2_platform_cpu_kill(unsigned int cpu)
 -{
 -      return 0; /* not supported yet */
 -}
 -
 -static int __maybe_unused emev2_cpu_kill(unsigned int cpu)
 -{
 -      int k;
 -
 -      /* this function is running on another CPU than the offline target,
 -       * here we need wait for shutdown code in platform_cpu_die() to
 -       * finish before asking SoC-specific code to power off the CPU core.
 -       */
 -      for (k = 0; k < 1000; k++) {
 -              if (shmobile_cpu_is_dead(cpu))
 -                      return emev2_platform_cpu_kill(cpu);
 -              mdelay(1);
 -      }
 -
 -      return 0;
--}
 -
--
  static int __cpuinit emev2_boot_secondary(unsigned int cpu, struct task_struct *idle)
  {
 -      cpu = cpu_logical_map(cpu);
 -
 -      /* enable cache coherency */
 -      modify_scu_cpu_psr(0, 3 << (cpu * 8));
 -
 -      /* Tell ROM loader about our vector (in headsmp.S) */
 -      emev2_set_boot_vector(__pa(shmobile_secondary_vector));
 -
 -      arch_send_wakeup_ipi_mask(cpumask_of(cpu));
 +      arch_send_wakeup_ipi_mask(cpumask_of(cpu_logical_map(cpu)));
        return 0;
  }
  
  static void __init emev2_smp_prepare_cpus(unsigned int max_cpus)
  {
 -      int cpu = cpu_logical_map(0);
 +      scu_enable(shmobile_scu_base);
  
 -      scu_enable(scu_base);
 +      /* Tell ROM loader about our vector (in headsmp-scu.S) */
 +      emev2_set_boot_vector(__pa(shmobile_secondary_vector_scu));
  
 -      /* enable cache coherency on CPU0 */
 -      modify_scu_cpu_psr(0, 3 << (cpu * 8));
 +      /* enable cache coherency on booting CPU */
 +      scu_power_mode(shmobile_scu_base, SCU_PM_NORMAL);
  }
  
  static void __init emev2_smp_init_cpus(void)
  {
 -      unsigned int ncores = emev2_get_core_count();
 +      unsigned int ncores;
 +
 +      /* setup EMEV2 specific SCU base */
 +      shmobile_scu_base = ioremap(EMEV2_SCU_BASE, PAGE_SIZE);
 +      emev2_clock_init(); /* need ioremapped SMU */
 +
 +      ncores = shmobile_scu_base ? scu_get_core_count(shmobile_scu_base) : 1;
  
        shmobile_smp_init_cpus(ncores);
  }
  struct smp_operations emev2_smp_ops __initdata = {
        .smp_init_cpus          = emev2_smp_init_cpus,
        .smp_prepare_cpus       = emev2_smp_prepare_cpus,
-       .smp_secondary_init     = emev2_secondary_init,
        .smp_boot_secondary     = emev2_boot_secondary,
 -#ifdef CONFIG_HOTPLUG_CPU
 -      .cpu_kill               = emev2_cpu_kill,
 -      .cpu_die                = shmobile_cpu_die,
 -      .cpu_disable            = shmobile_cpu_disable,
 -#endif
  };
index ea4535a5c4e23e8014dc84207bb2d6c043c5d73a,994906560edd6f4fcf27f436592c7e18f094bedd..a853bf182ed5ef2d4f21f11718f7983ba90f932f
  #include <linux/spinlock.h>
  #include <linux/io.h>
  #include <linux/delay.h>
- #include <linux/irqchip/arm-gic.h>
  #include <mach/common.h>
  #include <mach/r8a7779.h>
 +#include <asm/cacheflush.h>
  #include <asm/smp_plat.h>
  #include <asm/smp_scu.h>
  #include <asm/smp_twd.h>
  
  #define AVECR IOMEM(0xfe700040)
 +#define R8A7779_SCU_BASE 0xf0000000
  
  static struct r8a7779_pm_ch r8a7779_ch_cpu1 = {
        .chan_offs = 0x40, /* PWRSR0 .. PWRER0 */
@@@ -58,14 -55,44 +57,14 @@@ static struct r8a7779_pm_ch *r8a7779_ch
        [3] = &r8a7779_ch_cpu3,
  };
  
 -static void __iomem *scu_base_addr(void)
 -{
 -      return (void __iomem *)0xf0000000;
 -}
 -
 -static DEFINE_SPINLOCK(scu_lock);
 -static unsigned long tmp;
 -
  #ifdef CONFIG_HAVE_ARM_TWD
 -static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29);
 -
 +static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, R8A7779_SCU_BASE + 0x600, 29);
  void __init r8a7779_register_twd(void)
  {
        twd_local_timer_register(&twd_local_timer);
  }
  #endif
  
 -static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
 -{
 -      void __iomem *scu_base = scu_base_addr();
 -
 -      spin_lock(&scu_lock);
 -      tmp = __raw_readl(scu_base + 8);
 -      tmp &= ~clr;
 -      tmp |= set;
 -      spin_unlock(&scu_lock);
 -
 -      /* disable cache coherency after releasing the lock */
 -      __raw_writel(tmp, scu_base + 8);
 -}
 -
 -static unsigned int __init r8a7779_get_core_count(void)
 -{
 -      void __iomem *scu_base = scu_base_addr();
 -
 -      return scu_get_core_count(scu_base);
 -}
 -
  static int r8a7779_platform_cpu_kill(unsigned int cpu)
  {
        struct r8a7779_pm_ch *ch = NULL;
  
        cpu = cpu_logical_map(cpu);
  
 -      /* disable cache coherency */
 -      modify_scu_cpu_psr(3 << (cpu * 8), 0);
 -
        if (cpu < ARRAY_SIZE(r8a7779_ch_cpu))
                ch = r8a7779_ch_cpu[cpu];
  
        return ret ? ret : 1;
  }
  
- static void __cpuinit r8a7779_secondary_init(unsigned int cpu)
 -static int __maybe_unused r8a7779_cpu_kill(unsigned int cpu)
--{
-       gic_secondary_init(0);
 -      int k;
 -
 -      /* this function is running on another CPU than the offline target,
 -       * here we need wait for shutdown code in platform_cpu_die() to
 -       * finish before asking SoC-specific code to power off the CPU core.
 -       */
 -      for (k = 0; k < 1000; k++) {
 -              if (shmobile_cpu_is_dead(cpu))
 -                      return r8a7779_platform_cpu_kill(cpu);
 -
 -              mdelay(1);
 -      }
 -
 -      return 0;
--}
 -
--
  static int __cpuinit r8a7779_boot_secondary(unsigned int cpu, struct task_struct *idle)
  {
        struct r8a7779_pm_ch *ch = NULL;
  
        cpu = cpu_logical_map(cpu);
  
 -      /* enable cache coherency */
 -      modify_scu_cpu_psr(0, 3 << (cpu * 8));
 -
        if (cpu < ARRAY_SIZE(r8a7779_ch_cpu))
                ch = r8a7779_ch_cpu[cpu];
  
  
  static void __init r8a7779_smp_prepare_cpus(unsigned int max_cpus)
  {
 -      int cpu = cpu_logical_map(0);
 +      scu_enable(shmobile_scu_base);
  
 -      scu_enable(scu_base_addr());
 +      /* Map the reset vector (in headsmp-scu.S) */
 +      __raw_writel(__pa(shmobile_secondary_vector_scu), AVECR);
  
 -      /* Map the reset vector (in headsmp.S) */
 -      __raw_writel(__pa(shmobile_secondary_vector), AVECR);
 -
 -      /* enable cache coherency on CPU0 */
 -      modify_scu_cpu_psr(0, 3 << (cpu * 8));
 +      /* enable cache coherency on booting CPU */
 +      scu_power_mode(shmobile_scu_base, SCU_PM_NORMAL);
  
        r8a7779_pm_init();
  
  
  static void __init r8a7779_smp_init_cpus(void)
  {
 -      unsigned int ncores = r8a7779_get_core_count();
 +      /* setup r8a7779 specific SCU base */
 +      shmobile_scu_base = IOMEM(R8A7779_SCU_BASE);
 +
 +      shmobile_smp_init_cpus(scu_get_core_count(shmobile_scu_base));
 +}
  
 -      shmobile_smp_init_cpus(ncores);
 +#ifdef CONFIG_HOTPLUG_CPU
 +static int r8a7779_scu_psr_core_disabled(int cpu)
 +{
 +      unsigned long mask = 3 << (cpu * 8);
 +
 +      if ((__raw_readl(shmobile_scu_base + 8) & mask) == mask)
 +              return 1;
 +
 +      return 0;
 +}
 +
 +static int r8a7779_cpu_kill(unsigned int cpu)
 +{
 +      int k;
 +
 +      /* this function is running on another CPU than the offline target,
 +       * here we need wait for shutdown code in platform_cpu_die() to
 +       * finish before asking SoC-specific code to power off the CPU core.
 +       */
 +      for (k = 0; k < 1000; k++) {
 +              if (r8a7779_scu_psr_core_disabled(cpu))
 +                      return r8a7779_platform_cpu_kill(cpu);
 +
 +              mdelay(1);
 +      }
 +
 +      return 0;
 +}
 +
 +static void r8a7779_cpu_die(unsigned int cpu)
 +{
 +      dsb();
 +      flush_cache_all();
 +
 +      /* disable cache coherency */
 +      scu_power_mode(shmobile_scu_base, SCU_PM_POWEROFF);
 +
 +      /* Endless loop until power off from r8a7779_cpu_kill() */
 +      while (1)
 +              cpu_do_idle();
 +}
 +
 +static int r8a7779_cpu_disable(unsigned int cpu)
 +{
 +      /* only CPU1->3 have power domains, do not allow hotplug of CPU0 */
 +      return cpu == 0 ? -EPERM : 0;
  }
 +#endif /* CONFIG_HOTPLUG_CPU */
  
  struct smp_operations r8a7779_smp_ops  __initdata = {
        .smp_init_cpus          = r8a7779_smp_init_cpus,
        .smp_prepare_cpus       = r8a7779_smp_prepare_cpus,
-       .smp_secondary_init     = r8a7779_secondary_init,
        .smp_boot_secondary     = r8a7779_boot_secondary,
  #ifdef CONFIG_HOTPLUG_CPU
        .cpu_kill               = r8a7779_cpu_kill,
 -      .cpu_die                = shmobile_cpu_die,
 -      .cpu_disable            = shmobile_cpu_disable,
 +      .cpu_die                = r8a7779_cpu_die,
 +      .cpu_disable            = r8a7779_cpu_disable,
  #endif
  };
index 5ae502b16437c53dec44317f63c8f53e14edf273,d0f9aca22477f7c52c24364be91ca098608ed363..bf79626ee5a487624c567d5ec0c88f199f400aaa
@@@ -23,7 -23,6 +23,6 @@@
  #include <linux/spinlock.h>
  #include <linux/io.h>
  #include <linux/delay.h>
- #include <linux/irqchip/arm-gic.h>
  #include <mach/common.h>
  #include <asm/cacheflush.h>
  #include <asm/smp_plat.h>
  
  #define PSTR_SHUTDOWN_MODE    3
  
 -static void __iomem *scu_base_addr(void)
 -{
 -      return (void __iomem *)0xf0000000;
 -}
 +#define SH73A0_SCU_BASE 0xf0000000
  
  #ifdef CONFIG_HAVE_ARM_TWD
 -static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29);
 +static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, SH73A0_SCU_BASE + 0x600, 29);
  void __init sh73a0_register_twd(void)
  {
        twd_local_timer_register(&twd_local_timer);
  }
  #endif
  
- static void __cpuinit sh73a0_secondary_init(unsigned int cpu)
 -static unsigned int __init sh73a0_get_core_count(void)
--{
-       gic_secondary_init(0);
 -      void __iomem *scu_base = scu_base_addr();
 -
 -      return scu_get_core_count(scu_base);
--}
--
  static int __cpuinit sh73a0_boot_secondary(unsigned int cpu, struct task_struct *idle)
  {
        cpu = cpu_logical_map(cpu);
  
  static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus)
  {
 -      scu_enable(scu_base_addr());
 +      scu_enable(shmobile_scu_base);
  
 -      /* Map the reset vector (in headsmp-sh73a0.S) */
 +      /* Map the reset vector (in headsmp-scu.S) */
        __raw_writel(0, APARMBAREA);      /* 4k */
 -      __raw_writel(__pa(sh73a0_secondary_vector), SBAR);
 +      __raw_writel(__pa(shmobile_secondary_vector_scu), SBAR);
  
        /* enable cache coherency on booting CPU */
 -      scu_power_mode(scu_base_addr(), SCU_PM_NORMAL);
 +      scu_power_mode(shmobile_scu_base, SCU_PM_NORMAL);
  }
  
  static void __init sh73a0_smp_init_cpus(void)
  {
 -      unsigned int ncores = sh73a0_get_core_count();
 +      /* setup sh73a0 specific SCU base */
 +      shmobile_scu_base = IOMEM(SH73A0_SCU_BASE);
  
 -      shmobile_smp_init_cpus(ncores);
 +      shmobile_smp_init_cpus(scu_get_core_count(shmobile_scu_base));
  }
  
  #ifdef CONFIG_HOTPLUG_CPU
@@@ -119,26 -122,20 +113,25 @@@ static void sh73a0_cpu_die(unsigned in
        flush_cache_all();
  
        /* Set power off mode. This takes the CPU out of the MP cluster */
 -      scu_power_mode(scu_base_addr(), SCU_PM_POWEROFF);
 +      scu_power_mode(shmobile_scu_base, SCU_PM_POWEROFF);
  
        /* Enter shutdown mode */
        cpu_do_idle();
  }
 +
 +static int sh73a0_cpu_disable(unsigned int cpu)
 +{
 +      return 0; /* CPU0 and CPU1 supported */
 +}
  #endif /* CONFIG_HOTPLUG_CPU */
  
  struct smp_operations sh73a0_smp_ops __initdata = {
        .smp_init_cpus          = sh73a0_smp_init_cpus,
        .smp_prepare_cpus       = sh73a0_smp_prepare_cpus,
-       .smp_secondary_init     = sh73a0_secondary_init,
        .smp_boot_secondary     = sh73a0_boot_secondary,
  #ifdef CONFIG_HOTPLUG_CPU
        .cpu_kill               = sh73a0_cpu_kill,
        .cpu_die                = sh73a0_cpu_die,
 -      .cpu_disable            = shmobile_cpu_disable_any,
 +      .cpu_disable            = sh73a0_cpu_disable,
  #endif
  };
index b907fb986d9e937428e6a688ca8a08a5a9492d2e,ca14d1d5ac7f9f1d05d540bfbe5ca0781c5f47f5..b51ce8c7929dcf16991d2f3e45914c7ede976b92
@@@ -22,7 -22,6 +22,6 @@@
  #include <linux/io.h>
  #include <linux/of.h>
  #include <linux/of_address.h>
- #include <linux/irqchip/arm-gic.h>
  
  #include <asm/cacheflush.h>
  #include <asm/smp_scu.h>
  
  #include "core.h"
  
- static void __cpuinit socfpga_secondary_init(unsigned int cpu)
- {
-       /*
-        * if any interrupts are already enabled for the primary
-        * core (e.g. timer irq), then they will not have been enabled
-        * for us: do so
-        */
-       gic_secondary_init(0);
- }
 -extern void __iomem *sys_manager_base_addr;
 -extern void __iomem *rst_manager_base_addr;
--
  static int __cpuinit socfpga_boot_secondary(unsigned int cpu, struct task_struct *idle)
  {
        int trampoline_size = &secondary_trampoline_end - &secondary_trampoline;
@@@ -106,7 -98,6 +95,6 @@@ static void socfpga_cpu_die(unsigned in
  struct smp_operations socfpga_smp_ops __initdata = {
        .smp_init_cpus          = socfpga_smp_init_cpus,
        .smp_prepare_cpus       = socfpga_smp_prepare_cpus,
-       .smp_secondary_init     = socfpga_secondary_init,
        .smp_boot_secondary     = socfpga_boot_secondary,
  #ifdef CONFIG_HOTPLUG_CPU
        .cpu_die                = socfpga_cpu_die,
index 516aab28fe34217a8f99576df6b89b99a82f39f9,9348d3c496a98fd0e81f3f940cce8cbcf96b7d75..0c4963bd4b443c329af0cfffc0a57a7bb0773113
@@@ -18,7 -18,6 +18,6 @@@
  #include <linux/jiffies.h>
  #include <linux/smp.h>
  #include <linux/io.h>
- #include <linux/irqchip/arm-gic.h>
  #include <linux/clk/tegra.h>
  
  #include <asm/cacheflush.h>
  #include <asm/smp_scu.h>
  #include <asm/smp_plat.h>
  
 -#include <mach/powergate.h>
 -
  #include "fuse.h"
  #include "flowctrl.h"
  #include "reset.h"
 +#include "pmc.h"
  
  #include "common.h"
  #include "iomap.h"
  
 -extern void tegra_secondary_startup(void);
 -
  static cpumask_t tegra_cpu_init_mask;
  
 -#define EVP_CPU_RESET_VECTOR \
 -      (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100)
 -
  static void __cpuinit tegra_secondary_init(unsigned int cpu)
  {
-       /*
-        * if any interrupts are already enabled for the primary
-        * core (e.g. timer irq), then they will not have been enabled
-        * for us: do so
-        */
-       gic_secondary_init(0);
        cpumask_set_cpu(cpu, &tegra_cpu_init_mask);
  }
  
 -static int tegra20_power_up_cpu(unsigned int cpu)
 +
 +static int tegra20_boot_secondary(unsigned int cpu, struct task_struct *idle)
  {
 -      /* Enable the CPU clock. */
 -      tegra_enable_cpu_clock(cpu);
 +      cpu = cpu_logical_map(cpu);
 +
 +      /*
 +       * Force the CPU into reset. The CPU must remain in reset when
 +       * the flow controller state is cleared (which will cause the
 +       * flow controller to stop driving reset if the CPU has been
 +       * power-gated via the flow controller). This will have no
 +       * effect on first boot of the CPU since it should already be
 +       * in reset.
 +       */
 +      tegra_put_cpu_in_reset(cpu);
  
 -      /* Clear flow controller CSR. */
 -      flowctrl_write_cpu_csr(cpu, 0);
 +      /*
 +       * Unhalt the CPU. If the flow controller was used to
 +       * power-gate the CPU this will cause the flow controller to
 +       * stop driving reset. The CPU will remain in reset because the
 +       * clock and reset block is now driving reset.
 +       */
 +      flowctrl_write_cpu_halt(cpu, 0);
  
 +      tegra_enable_cpu_clock(cpu);
 +      flowctrl_write_cpu_csr(cpu, 0); /* Clear flow controller CSR. */
 +      tegra_cpu_out_of_reset(cpu);
        return 0;
  }
  
 -static int tegra30_power_up_cpu(unsigned int cpu)
 +static int tegra30_boot_secondary(unsigned int cpu, struct task_struct *idle)
  {
 -      int ret, pwrgateid;
 +      int ret;
        unsigned long timeout;
  
 -      pwrgateid = tegra_cpu_powergate_id(cpu);
 -      if (pwrgateid < 0)
 -              return pwrgateid;
 +      cpu = cpu_logical_map(cpu);
 +      tegra_put_cpu_in_reset(cpu);
 +      flowctrl_write_cpu_halt(cpu, 0);
  
        /*
         * The power up sequence of cold boot CPU and warm boot CPU
         * the IO clamps.
         * For cold boot CPU, do not wait. After the cold boot CPU be
         * booted, it will run to tegra_secondary_init() and set
 -       * tegra_cpu_init_mask which influences what tegra30_power_up_cpu()
 +       * tegra_cpu_init_mask which influences what tegra30_boot_secondary()
         * next time around.
         */
        if (cpumask_test_cpu(cpu, &tegra_cpu_init_mask)) {
                timeout = jiffies + msecs_to_jiffies(50);
                do {
 -                      if (!tegra_powergate_is_powered(pwrgateid))
 +                      if (tegra_pmc_cpu_is_powered(cpu))
                                goto remove_clamps;
                        udelay(10);
                } while (time_before(jiffies, timeout));
         * be un-gated by un-toggling the power gate register
         * manually.
         */
 -      if (!tegra_powergate_is_powered(pwrgateid)) {
 -              ret = tegra_powergate_power_on(pwrgateid);
 +      if (!tegra_pmc_cpu_is_powered(cpu)) {
 +              ret = tegra_pmc_cpu_power_on(cpu);
                if (ret)
                        return ret;
  
                /* Wait for the power to come up. */
                timeout = jiffies + msecs_to_jiffies(100);
 -              while (tegra_powergate_is_powered(pwrgateid)) {
 +              while (tegra_pmc_cpu_is_powered(cpu)) {
                        if (time_after(jiffies, timeout))
                                return -ETIMEDOUT;
                        udelay(10);
@@@ -135,34 -115,57 +127,34 @@@ remove_clamps
        udelay(10);
  
        /* Remove I/O clamps. */
 -      ret = tegra_powergate_remove_clamping(pwrgateid);
 -      udelay(10);
 +      ret = tegra_pmc_cpu_remove_clamping(cpu);
 +      if (ret)
 +              return ret;
  
 -      /* Clear flow controller CSR. */
 -      flowctrl_write_cpu_csr(cpu, 0);
 +      udelay(10);
  
 +      flowctrl_write_cpu_csr(cpu, 0); /* Clear flow controller CSR. */
 +      tegra_cpu_out_of_reset(cpu);
        return 0;
  }
  
 -static int __cpuinit tegra_boot_secondary(unsigned int cpu, struct task_struct *idle)
 +static int tegra114_boot_secondary(unsigned int cpu, struct task_struct *idle)
  {
 -      int status;
 -
        cpu = cpu_logical_map(cpu);
 +      return tegra_pmc_cpu_power_on(cpu);
 +}
  
 -      /*
 -       * Force the CPU into reset. The CPU must remain in reset when the
 -       * flow controller state is cleared (which will cause the flow
 -       * controller to stop driving reset if the CPU has been power-gated
 -       * via the flow controller). This will have no effect on first boot
 -       * of the CPU since it should already be in reset.
 -       */
 -      tegra_put_cpu_in_reset(cpu);
 -
 -      /*
 -       * Unhalt the CPU. If the flow controller was used to power-gate the
 -       * CPU this will cause the flow controller to stop driving reset.
 -       * The CPU will remain in reset because the clock and reset block
 -       * is now driving reset.
 -       */
 -      flowctrl_write_cpu_halt(cpu, 0);
 -
 -      switch (tegra_chip_id) {
 -      case TEGRA20:
 -              status = tegra20_power_up_cpu(cpu);
 -              break;
 -      case TEGRA30:
 -              status = tegra30_power_up_cpu(cpu);
 -              break;
 -      default:
 -              status = -EINVAL;
 -              break;
 -      }
 -
 -      if (status)
 -              goto done;
 -
 -      /* Take the CPU out of reset. */
 -      tegra_cpu_out_of_reset(cpu);
 -done:
 -      return status;
 +static int __cpuinit tegra_boot_secondary(unsigned int cpu,
 +                                        struct task_struct *idle)
 +{
 +      if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id == TEGRA20)
 +              return tegra20_boot_secondary(cpu, idle);
 +      if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30)
 +              return tegra30_boot_secondary(cpu, idle);
 +      if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_chip_id == TEGRA114)
 +              return tegra114_boot_secondary(cpu, idle);
 +
 +      return -EINVAL;
  }
  
  static void __init tegra_smp_prepare_cpus(unsigned int max_cpus)
index e3956359202c23080e5f751bf5484ba9792a3eb0,8e21555488883d34fbc4f086baf72ec93b9bbc4f..dde0656ea951257bef7503b3d3b066de0a7b9c19
  #include <linux/platform_device.h>
  #include <linux/module.h>
  #include <linux/irqdomain.h>
+ #include <linux/irqchip/chained_irq.h>
  #include <linux/pinctrl/consumer.h>
  #include <linux/pm.h>
  
- #include <asm/mach/irq.h>
  #define GPIO_BANK(x)          ((x) >> 5)
  #define GPIO_PORT(x)          (((x) >> 3) & 0x3)
  #define GPIO_BIT(x)           ((x) & 0x7)
@@@ -72,7 -71,6 +71,7 @@@ struct tegra_gpio_bank 
        u32 oe[4];
        u32 int_enb[4];
        u32 int_lvl[4];
 +      u32 wake_enb[4];
  #endif
  };
  
@@@ -334,31 -332,15 +333,31 @@@ static int tegra_gpio_suspend(struct de
                        bank->oe[p] = tegra_gpio_readl(GPIO_OE(gpio));
                        bank->int_enb[p] = tegra_gpio_readl(GPIO_INT_ENB(gpio));
                        bank->int_lvl[p] = tegra_gpio_readl(GPIO_INT_LVL(gpio));
 +
 +                      /* Enable gpio irq for wake up source */
 +                      tegra_gpio_writel(bank->wake_enb[p],
 +                                        GPIO_INT_ENB(gpio));
                }
        }
        local_irq_restore(flags);
        return 0;
  }
  
 -static int tegra_gpio_wake_enable(struct irq_data *d, unsigned int enable)
 +static int tegra_gpio_irq_set_wake(struct irq_data *d, unsigned int enable)
  {
        struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d);
 +      int gpio = d->hwirq;
 +      u32 port, bit, mask;
 +
 +      port = GPIO_PORT(gpio);
 +      bit = GPIO_BIT(gpio);
 +      mask = BIT(bit);
 +
 +      if (enable)
 +              bank->wake_enb[port] |= mask;
 +      else
 +              bank->wake_enb[port] &= ~mask;
 +
        return irq_set_irq_wake(bank->irq, enable);
  }
  #endif
@@@ -370,7 -352,7 +369,7 @@@ static struct irq_chip tegra_gpio_irq_c
        .irq_unmask     = tegra_gpio_irq_unmask,
        .irq_set_type   = tegra_gpio_irq_set_type,
  #ifdef CONFIG_PM_SLEEP
 -      .irq_set_wake   = tegra_gpio_wake_enable,
 +      .irq_set_wake   = tegra_gpio_irq_set_wake,
  #endif
  };
  
index efb7f10e902a0e1aa9701ed5506a23d204b1a9df,5cbadc9ad2e84ab26a5de4078cbb6c64cfcdddb9..b141a28473b5c6c9ab0fefb4a6d807865a7e05b6
@@@ -18,6 -18,7 +18,7 @@@
  #include <linux/interrupt.h>
  #include <linux/irq.h>
  #include <linux/irqdomain.h>
+ #include <linux/irqchip/chained_irq.h>
  #include <linux/io.h>
  #include <linux/gpio.h>
  #include <linux/pinctrl/machine.h>
@@@ -27,8 -28,6 +28,6 @@@
  /* Since we request GPIOs from ourself */
  #include <linux/pinctrl/consumer.h>
  
- #include <asm/mach/irq.h>
  #include <mach/hardware.h>
  #include <mach/at91_pio.h>
  
@@@ -1277,80 -1276,21 +1276,80 @@@ static int alt_gpio_irq_type(struct irq
  }
  
  #ifdef CONFIG_PM
 +
 +static u32 wakeups[MAX_GPIO_BANKS];
 +static u32 backups[MAX_GPIO_BANKS];
 +
  static int gpio_irq_set_wake(struct irq_data *d, unsigned state)
  {
        struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d);
        unsigned        bank = at91_gpio->pioc_idx;
 +      unsigned mask = 1 << d->hwirq;
  
        if (unlikely(bank >= MAX_GPIO_BANKS))
                return -EINVAL;
  
 +      if (state)
 +              wakeups[bank] |= mask;
 +      else
 +              wakeups[bank] &= ~mask;
 +
        irq_set_irq_wake(at91_gpio->pioc_virq, state);
  
        return 0;
  }
 +
 +void at91_pinctrl_gpio_suspend(void)
 +{
 +      int i;
 +
 +      for (i = 0; i < gpio_banks; i++) {
 +              void __iomem  *pio;
 +
 +              if (!gpio_chips[i])
 +                      continue;
 +
 +              pio = gpio_chips[i]->regbase;
 +
 +              backups[i] = __raw_readl(pio + PIO_IMR);
 +              __raw_writel(backups[i], pio + PIO_IDR);
 +              __raw_writel(wakeups[i], pio + PIO_IER);
 +
 +              if (!wakeups[i]) {
 +                      clk_unprepare(gpio_chips[i]->clock);
 +                      clk_disable(gpio_chips[i]->clock);
 +              } else {
 +                      printk(KERN_DEBUG "GPIO-%c may wake for %08x\n",
 +                             'A'+i, wakeups[i]);
 +              }
 +      }
 +}
 +
 +void at91_pinctrl_gpio_resume(void)
 +{
 +      int i;
 +
 +      for (i = 0; i < gpio_banks; i++) {
 +              void __iomem  *pio;
 +
 +              if (!gpio_chips[i])
 +                      continue;
 +
 +              pio = gpio_chips[i]->regbase;
 +
 +              if (!wakeups[i]) {
 +                      if (clk_prepare(gpio_chips[i]->clock) == 0)
 +                              clk_enable(gpio_chips[i]->clock);
 +              }
 +
 +              __raw_writel(wakeups[i], pio + PIO_IDR);
 +              __raw_writel(backups[i], pio + PIO_IER);
 +      }
 +}
 +
  #else
  #define gpio_irq_set_wake     NULL
 -#endif
 +#endif /* CONFIG_PM */
  
  static struct irq_chip gpio_irqchip = {
        .name           = "GPIO",