Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d710aa31 authored by Tomasz Figa's avatar Tomasz Figa Committed by Kukjin Kim
Browse files

ARM: EXYNOS: Stop using legacy Samsung PM code



Since Exynos SoCs does not follow most of the semantics of older SoCs
when configuring the system to enter sleep, there is no reason to rely
on the legacy Samsung PM core anymore.

This patch adds local Exynos suspend ops and removes all the code left
unnecessary. As a side effect, suspend support on Exynos becomes
multiplatform-friendly.

Signed-off-by: default avatarTomasz Figa <t.figa@samsung.com>
Acked-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: default avatarKukjin Kim <kgene.kim@samsung.com>
parent 559ba237
Loading
Loading
Loading
Loading
+0 −8
Original line number Diff line number Diff line
@@ -49,8 +49,6 @@ config CPU_EXYNOS4210
	select ARCH_HAS_BANDGAP
	select ARM_CPU_SUSPEND if PM_SLEEP
	select PINCTRL_EXYNOS
	select S5P_PM if PM_SLEEP
	select S5P_SLEEP if PM_SLEEP
	select SAMSUNG_DMADEV
	help
	  Enable EXYNOS4210 CPU support
@@ -61,8 +59,6 @@ config SOC_EXYNOS4212
	depends on ARCH_EXYNOS4
	select ARCH_HAS_BANDGAP
	select PINCTRL_EXYNOS
	select S5P_PM if PM_SLEEP
	select S5P_SLEEP if PM_SLEEP
	select SAMSUNG_DMADEV
	help
	  Enable EXYNOS4212 SoC support
@@ -84,8 +80,6 @@ config SOC_EXYNOS5250
	select ARCH_HAS_BANDGAP
	select PINCTRL_EXYNOS
	select PM_GENERIC_DOMAINS if PM_RUNTIME
	select S5P_PM if PM_SLEEP
	select S5P_SLEEP if PM_SLEEP
	select S5P_DEV_MFC
	select SAMSUNG_DMADEV
	help
@@ -96,8 +90,6 @@ config SOC_EXYNOS5420
	default y
	depends on ARCH_EXYNOS5
	select PM_GENERIC_DOMAINS if PM_RUNTIME
	select S5P_PM if PM_SLEEP
	select S5P_SLEEP if PM_SLEEP
	help
	  Enable EXYNOS5420 SoC support

+1 −1
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@ obj- :=

obj-$(CONFIG_ARCH_EXYNOS)	+= common.o

obj-$(CONFIG_S5P_PM)		+= pm.o
obj-$(CONFIG_PM_SLEEP)		+= pm.o sleep.o
obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o
obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o

+8 −0
Original line number Diff line number Diff line
@@ -27,12 +27,20 @@ void exynos_init_late(void);

void exynos_firmware_init(void);

#ifdef CONFIG_PINCTRL_EXYNOS
extern u32 exynos_get_eint_wake_mask(void);
#else
static inline u32 exynos_get_eint_wake_mask(void) { return 0xffffffff; }
#endif

#ifdef CONFIG_PM_SLEEP
extern void __init exynos_pm_init(void);
#else
static inline void exynos_pm_init(void) {}
#endif

extern void exynos_cpu_resume(void);

extern struct smp_operations exynos_smp_ops;

extern void exynos_cpu_die(unsigned int cpu);
+0 −75
Original line number Diff line number Diff line
/* linux/arch/arm/mach-exynos4/include/mach/pm-core.h
 *
 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
 *		http://www.samsung.com
 *
 * Based on arch/arm/mach-s3c2410/include/mach/pm-core.h,
 * Copyright 2008 Simtec Electronics
 *      Ben Dooks <ben@simtec.co.uk>
 *      http://armlinux.simtec.co.uk/
 *
 * EXYNOS4210 - PM core support for arch/arm/plat-s5p/pm.c
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
*/

#ifndef __ASM_ARCH_PM_CORE_H
#define __ASM_ARCH_PM_CORE_H __FILE__

#include <linux/of.h>
#include <mach/map.h>

#define S5P_EINT_WAKEUP_MASK			(S5P_VA_PMU + 0x0604)
#define S5P_WAKEUP_MASK				(S5P_VA_PMU + 0x0608)

#ifdef CONFIG_PINCTRL_EXYNOS
extern u32 exynos_get_eint_wake_mask(void);
#else
static inline u32 exynos_get_eint_wake_mask(void) { return 0xffffffff; }
#endif

static inline void s3c_pm_debug_init_uart(void)
{
	/* nothing here yet */
}

static inline void s3c_pm_arch_prepare_irqs(void)
{
	__raw_writel(exynos_get_eint_wake_mask(), S5P_EINT_WAKEUP_MASK);
	__raw_writel(s3c_irqwake_intmask & ~(1 << 31), S5P_WAKEUP_MASK);
}

static inline void s3c_pm_arch_stop_clocks(void)
{
	/* nothing here yet */
}

static inline void s3c_pm_arch_show_resume_irqs(void)
{
	/* nothing here yet */
}

static inline void s3c_pm_arch_update_uart(void __iomem *regs,
					   struct pm_uart_save *save)
{
	/* nothing here yet */
}

static inline void s3c_pm_restored_gpios(void)
{
	/* nothing here yet */
}

static inline void samsung_pm_saved_gpios(void)
{
	/* nothing here yet */
}

/* Compatibility definitions to make plat-samsung/pm.c compile */
#define IRQ_EINT_BIT(x)		1
#define s3c_irqwake_intallow	0
#define s3c_irqwake_eintallow	0

#endif /* __ASM_ARCH_PM_CORE_H */
+71 −8
Original line number Diff line number Diff line
@@ -23,14 +23,14 @@
#include <asm/cacheflush.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/smp_scu.h>
#include <asm/suspend.h>

#include <plat/cpu.h>
#include <plat/pm.h>
#include <plat/pm-common.h>
#include <plat/pll.h>
#include <plat/regs-srom.h>

#include <mach/map.h>
#include <mach/pm-core.h>

#include "common.h"
#include "regs-pmu.h"
@@ -48,6 +48,7 @@ static struct sleep_save exynos_core_save[] = {
	SAVE_ITEM(S5P_SROM_BC3),
};

static u32 exynos_irqwake_intmask = 0xffffffff;

/* For Cortex-A9 Diagnostic and Power control register */
static unsigned int save_arm_register[2];
@@ -72,6 +73,10 @@ static void exynos_pm_prepare(void)
{
	unsigned int tmp;

	/* Set wake-up mask registers */
	__raw_writel(exynos_get_eint_wake_mask(), S5P_EINT_WAKEUP_MASK);
	__raw_writel(exynos_irqwake_intmask & ~(1 << 31), S5P_WAKEUP_MASK);

	s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save));

	if (soc_is_exynos5250()) {
@@ -89,7 +94,7 @@ static void exynos_pm_prepare(void)

	/* ensure at least INFORM0 has the resume address */

	__raw_writel(virt_to_phys(s3c_cpu_resume), S5P_INFORM0);
	__raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0);
}

static int exynos_pm_suspend(void)
@@ -187,14 +192,71 @@ static struct syscore_ops exynos_pm_syscore_ops = {
	.resume		= exynos_pm_resume,
};

void __init exynos_pm_init(void)
/*
 * Suspend Ops
 */

static int exynos_suspend_enter(suspend_state_t state)
{
	u32 tmp;
	int ret;

	s3c_pm_debug_init();

	S3C_PMDBG("%s: suspending the system...\n", __func__);

	S3C_PMDBG("%s: wakeup masks: %08x,%08x\n", __func__,
			exynos_irqwake_intmask, exynos_get_eint_wake_mask());

	if (exynos_irqwake_intmask == -1U
	    && exynos_get_eint_wake_mask() == -1U) {
		pr_err("%s: No wake-up sources!\n", __func__);
		pr_err("%s: Aborting sleep\n", __func__);
		return -EINVAL;
	}

	s3c_pm_save_uarts();
	exynos_pm_prepare();
	flush_cache_all();
	s3c_pm_check_store();

	ret = cpu_suspend(0, exynos_cpu_suspend);
	if (ret)
		return ret;

	s3c_pm_restore_uarts();

	S3C_PMDBG("%s: wakeup stat: %08x\n", __func__,
			__raw_readl(S5P_WAKEUP_STAT));

	s3c_pm_check_restore();

	pm_cpu_prep = exynos_pm_prepare;
	pm_cpu_sleep = exynos_cpu_suspend;
	S3C_PMDBG("%s: resuming the system...\n", __func__);

	s3c_pm_init();
	return 0;
}

static int exynos_suspend_prepare(void)
{
	s3c_pm_check_prepare();

	return 0;
}

static void exynos_suspend_finish(void)
{
	s3c_pm_check_cleanup();
}

static const struct platform_suspend_ops exynos_suspend_ops = {
	.enter		= exynos_suspend_enter,
	.prepare	= exynos_suspend_prepare,
	.finish		= exynos_suspend_finish,
	.valid		= suspend_valid_only_mem,
};

void __init exynos_pm_init(void)
{
	u32 tmp;

	/* All wakeup disable */
	tmp = __raw_readl(S5P_WAKEUP_MASK);
@@ -202,4 +264,5 @@ void __init exynos_pm_init(void)
	__raw_writel(tmp, S5P_WAKEUP_MASK);

	register_syscore_ops(&exynos_pm_syscore_ops);
	suspend_set_ops(&exynos_suspend_ops);
}
Loading