diff options
-rw-r--r-- | arch/arm/mach-exynos/common.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-exynos/cpuidle.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-exynos/hotplug.c | 45 | ||||
-rw-r--r-- | arch/arm/mach-exynos/pm.c | 7 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap_phy_internal.c | 32 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm44xx.c | 7 | ||||
-rw-r--r-- | arch/arm/mach-omap2/vc.c | 2 | ||||
-rw-r--r-- | arch/arm/plat-samsung/include/plat/pm.h | 2 |
11 files changed, 93 insertions, 12 deletions
diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c index 4e1dd8d1eda8..454bc6ed9a8d 100644 --- a/arch/arm/mach-exynos/common.c +++ b/arch/arm/mach-exynos/common.c @@ -615,6 +615,8 @@ void __init exynos5_init_irq(void) * uses GIC instead of VIC. */ s5p_init_irq(NULL, 0); + + gic_arch_extn.irq_set_wake = s3c_irq_wake; } struct bus_type exynos_subsys = { diff --git a/arch/arm/mach-exynos/cpuidle.c b/arch/arm/mach-exynos/cpuidle.c index cff0595d0d35..8e4ec21ef2cf 100644 --- a/arch/arm/mach-exynos/cpuidle.c +++ b/arch/arm/mach-exynos/cpuidle.c @@ -116,7 +116,8 @@ static int exynos4_enter_core0_aftr(struct cpuidle_device *dev, cpu_suspend(0, idle_finisher); #ifdef CONFIG_SMP - scu_enable(S5P_VA_SCU); + if (!soc_is_exynos5250()) + scu_enable(S5P_VA_SCU); #endif cpu_pm_exit(); diff --git a/arch/arm/mach-exynos/hotplug.c b/arch/arm/mach-exynos/hotplug.c index f4d7dd20cdac..c3f825b27947 100644 --- a/arch/arm/mach-exynos/hotplug.c +++ b/arch/arm/mach-exynos/hotplug.c @@ -20,10 +20,11 @@ #include <asm/smp_plat.h> #include <mach/regs-pmu.h> +#include <plat/cpu.h> #include "common.h" -static inline void cpu_enter_lowpower(void) +static inline void cpu_enter_lowpower_a9(void) { unsigned int v; @@ -45,6 +46,35 @@ static inline void cpu_enter_lowpower(void) : "cc"); } +static inline void cpu_enter_lowpower_a15(void) +{ + unsigned int v; + + asm volatile( + " mrc p15, 0, %0, c1, c0, 0\n" + " bic %0, %0, %1\n" + " mcr p15, 0, %0, c1, c0, 0\n" + : "=&r" (v) + : "Ir" (CR_C) + : "cc"); + + flush_cache_louis(); + + asm volatile( + /* + * Turn off coherency + */ + " mrc p15, 0, %0, c1, c0, 1\n" + " bic %0, %0, %1\n" + " mcr p15, 0, %0, c1, c0, 1\n" + : "=&r" (v) + : "Ir" (0x40) + : "cc"); + + isb(); + dsb(); +} + static inline void cpu_leave_lowpower(void) { unsigned int v; @@ -103,11 +133,20 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious) void __ref exynos_cpu_die(unsigned int cpu) { int spurious = 0; + int primary_part = 0; /* - * we're ready for shutdown now, so do it + * we're ready for shutdown now, so do it. + * Exynos4 is A9 based while Exynos5 is A15; check the CPU part + * number by reading the Main ID register and then perform the + * appropriate sequence for entering low power. */ - cpu_enter_lowpower(); + asm("mrc p15, 0, %0, c0, c0, 0" : "=r"(primary_part) : : "cc"); + if ((primary_part & 0xfff0) == 0xc0f0) + cpu_enter_lowpower_a15(); + else + cpu_enter_lowpower_a9(); + platform_do_lowpower(cpu, &spurious); /* diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c index c06c992943a1..8df6ec547f78 100644 --- a/arch/arm/mach-exynos/pm.c +++ b/arch/arm/mach-exynos/pm.c @@ -81,6 +81,9 @@ static int exynos_cpu_suspend(unsigned long arg) outer_flush_all(); #endif + if (soc_is_exynos5250()) + flush_cache_all(); + /* issue the standby signal into the pm unit. */ cpu_do_idle(); @@ -312,6 +315,10 @@ static void exynos_pm_resume(void) } early_wakeup: + + /* Clear SLEEP mode set in INFORM1 */ + __raw_writel(0x0, S5P_INFORM1); + return; } diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 219fb075741b..ce1661d18e56 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -21,6 +21,7 @@ #include <linux/io.h> #include <linux/platform_data/gpio-omap.h> #include <linux/power/smartreflex.h> +#include <linux/platform_data/omap_ocp2scp.h> #include <linux/i2c-omap.h> #include <linux/omap-dma.h> diff --git a/arch/arm/mach-omap2/omap_phy_internal.c b/arch/arm/mach-omap2/omap_phy_internal.c index 4d76a3ca5bf3..e237602e10ea 100644 --- a/arch/arm/mach-omap2/omap_phy_internal.c +++ b/arch/arm/mach-omap2/omap_phy_internal.c @@ -33,6 +33,38 @@ #include "control.h" #include "usb.h" +#define CONTROL_DEV_CONF 0x300 +#define PHY_PD 0x1 + +/** + * omap4430_phy_power_down: disable MUSB PHY during early init + * + * OMAP4 MUSB PHY module is enabled by default on reset, but this will + * prevent core retention if not disabled by SW. USB driver will + * later on enable this, once and if the driver needs it. + */ +static int __init omap4430_phy_power_down(void) +{ + void __iomem *ctrl_base; + + if (!cpu_is_omap44xx()) + return 0; + + ctrl_base = ioremap(OMAP443X_SCM_BASE, SZ_1K); + if (!ctrl_base) { + pr_err("control module ioremap failed\n"); + return -ENOMEM; + } + + /* Power down the phy */ + __raw_writel(PHY_PD, ctrl_base + CONTROL_DEV_CONF); + + iounmap(ctrl_base); + + return 0; +} +early_initcall(omap4430_phy_power_down); + void am35x_musb_reset(void) { u32 regval; diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index e5a4c3a0accd..f4b3143a8b1d 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -40,6 +40,7 @@ static struct omap_device_pm_latency *pm_lats; */ int (*omap_pm_suspend)(void); +#ifdef CONFIG_PM /** * struct omap2_oscillator - Describe the board main oscillator latencies * @startup_time: oscillator startup latency @@ -69,6 +70,7 @@ void omap_pm_get_oscillator(u32 *tstart, u32 *tshut) *tstart = oscillator.startup_time; *tshut = oscillator.shutdown_time; } +#endif static int __init _init_omap_device(char *name) { diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index 4db7b238a0d5..02c291c8e470 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -135,7 +135,7 @@ extern void omap_pm_get_oscillator(u32 *tstart, u32 *tshut); extern void omap_pm_setup_sr_i2c_pcb_length(u32 mm); #else static inline void omap_pm_setup_oscillator(u32 tstart, u32 tshut) { } -static inline void omap_pm_get_oscillator(u32 *tstart, u32 *tshut) { } +static inline void omap_pm_get_oscillator(u32 *tstart, u32 *tshut) { *tstart = *tshut = 0; } static inline void omap_pm_setup_sr_i2c_pcb_length(u32 mm) { } #endif diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index 7da75aed1514..aa6fd98f606e 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -101,13 +101,6 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) if (!strncmp(pwrdm->name, "cpu", 3)) return 0; - /* - * FIXME: Remove this check when core retention is supported - * Only MPUSS power domain is added in the list. - */ - if (strcmp(pwrdm->name, "mpu_pwrdm")) - return 0; - pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC); if (!pwrst) return -ENOMEM; diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c index 71396c3aa35f..49ac7977e03e 100644 --- a/arch/arm/mach-omap2/vc.c +++ b/arch/arm/mach-omap2/vc.c @@ -666,6 +666,7 @@ static u8 omap_vc_calc_vsel(struct voltagedomain *voltdm, u32 uvolt) return voltdm->pmic->uv_to_vsel(uvolt); } +#ifdef CONFIG_PM /** * omap_pm_setup_sr_i2c_pcb_length - set length of SR I2C traces on PCB * @mm: length of the PCB trace in millimetres @@ -678,6 +679,7 @@ void __init omap_pm_setup_sr_i2c_pcb_length(u32 mm) { sr_i2c_pcb_length = mm; } +#endif void __init omap_vc_init_channel(struct voltagedomain *voltdm) { diff --git a/arch/arm/plat-samsung/include/plat/pm.h b/arch/arm/plat-samsung/include/plat/pm.h index 61fc53740fbd..887a0c954379 100644 --- a/arch/arm/plat-samsung/include/plat/pm.h +++ b/arch/arm/plat-samsung/include/plat/pm.h @@ -107,10 +107,12 @@ extern void s3c_pm_do_restore(struct sleep_save *ptr, int count); extern void s3c_pm_do_restore_core(struct sleep_save *ptr, int count); #ifdef CONFIG_PM +extern int s3c_irq_wake(struct irq_data *data, unsigned int state); extern int s3c_irqext_wake(struct irq_data *data, unsigned int state); extern int s3c24xx_irq_suspend(void); extern void s3c24xx_irq_resume(void); #else +#define s3c_irq_wake NULL #define s3c_irqext_wake NULL #define s3c24xx_irq_suspend NULL #define s3c24xx_irq_resume NULL |