Files
Linux_Drivers/linux_5.10/arch/arm/mach-s3c/pm-s3c2410.c
sam.xiang 5c7dd7acc3 [linux] create linux_5.10.4 from T-head official:
repo: https://github.com/T-head-Semi/linux
	commit: b1313fe517ca3703119dcc99ef3bbf75ab42bcfb

Change-Id: I6cbb35294024ea3a66140e311f4bb705fd7fd626
2023-03-10 20:32:41 +08:00

171 lines
4.0 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// SPDX-License-Identifier: GPL-2.0+
//
// Copyright (c) 2006 Simtec Electronics
// Ben Dooks <ben@simtec.co.uk>
//
// S3C2410 (and compatible) Power Manager (Suspend-To-RAM) support
#include <linux/init.h>
#include <linux/suspend.h>
#include <linux/errno.h>
#include <linux/time.h>
#include <linux/device.h>
#include <linux/syscore_ops.h>
#include <linux/gpio.h>
#include <linux/io.h>
#include <asm/mach-types.h>
#include "regs-gpio.h"
#include "gpio-samsung.h"
#include "gpio-cfg.h"
#include "cpu.h"
#include "pm.h"
#include "h1940.h"
static void s3c2410_pm_prepare(void)
{
/* ensure at least GSTATUS3 has the resume address */
__raw_writel(__pa_symbol(s3c_cpu_resume), S3C2410_GSTATUS3);
S3C_PMDBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3));
S3C_PMDBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4));
if (machine_is_h1940()) {
void *base = phys_to_virt(H1940_SUSPEND_CHECK);
unsigned long ptr;
unsigned long calc = 0;
/* generate check for the bootloader to check on resume */
for (ptr = 0; ptr < 0x40000; ptr += 0x400)
calc += __raw_readl(base+ptr);
__raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
}
/* RX3715 and RX1950 use similar to H1940 code and the
* same offsets for resume and checksum pointers */
if (machine_is_rx3715() || machine_is_rx1950()) {
void *base = phys_to_virt(H1940_SUSPEND_CHECK);
unsigned long ptr;
unsigned long calc = 0;
/* generate check for the bootloader to check on resume */
for (ptr = 0; ptr < 0x40000; ptr += 0x4)
calc += __raw_readl(base+ptr);
__raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
}
if (machine_is_aml_m5900()) {
gpio_request_one(S3C2410_GPF(2), GPIOF_OUT_INIT_HIGH, NULL);
gpio_free(S3C2410_GPF(2));
}
if (machine_is_rx1950()) {
/* According to S3C2442 user's manual, page 7-17,
* when the system is operating in NAND boot mode,
* the hardware pin configuration - EINT[23:21]
* must be set as input for starting up after
* wakeup from sleep mode
*/
s3c_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPIO_INPUT);
s3c_gpio_cfgpin(S3C2410_GPG(14), S3C2410_GPIO_INPUT);
s3c_gpio_cfgpin(S3C2410_GPG(15), S3C2410_GPIO_INPUT);
}
}
static void s3c2410_pm_resume(void)
{
unsigned long tmp;
/* unset the return-from-sleep flag, to ensure reset */
tmp = __raw_readl(S3C2410_GSTATUS2);
tmp &= S3C2410_GSTATUS2_OFFRESET;
__raw_writel(tmp, S3C2410_GSTATUS2);
if (machine_is_aml_m5900()) {
gpio_request_one(S3C2410_GPF(2), GPIOF_OUT_INIT_LOW, NULL);
gpio_free(S3C2410_GPF(2));
}
}
struct syscore_ops s3c2410_pm_syscore_ops = {
.resume = s3c2410_pm_resume,
};
static int s3c2410_pm_add(struct device *dev, struct subsys_interface *sif)
{
pm_cpu_prep = s3c2410_pm_prepare;
pm_cpu_sleep = s3c2410_cpu_suspend;
return 0;
}
#if defined(CONFIG_CPU_S3C2410)
static struct subsys_interface s3c2410_pm_interface = {
.name = "s3c2410_pm",
.subsys = &s3c2410_subsys,
.add_dev = s3c2410_pm_add,
};
/* register ourselves */
static int __init s3c2410_pm_drvinit(void)
{
return subsys_interface_register(&s3c2410_pm_interface);
}
arch_initcall(s3c2410_pm_drvinit);
static struct subsys_interface s3c2410a_pm_interface = {
.name = "s3c2410a_pm",
.subsys = &s3c2410a_subsys,
.add_dev = s3c2410_pm_add,
};
static int __init s3c2410a_pm_drvinit(void)
{
return subsys_interface_register(&s3c2410a_pm_interface);
}
arch_initcall(s3c2410a_pm_drvinit);
#endif
#if defined(CONFIG_CPU_S3C2440)
static struct subsys_interface s3c2440_pm_interface = {
.name = "s3c2440_pm",
.subsys = &s3c2440_subsys,
.add_dev = s3c2410_pm_add,
};
static int __init s3c2440_pm_drvinit(void)
{
return subsys_interface_register(&s3c2440_pm_interface);
}
arch_initcall(s3c2440_pm_drvinit);
#endif
#if defined(CONFIG_CPU_S3C2442)
static struct subsys_interface s3c2442_pm_interface = {
.name = "s3c2442_pm",
.subsys = &s3c2442_subsys,
.add_dev = s3c2410_pm_add,
};
static int __init s3c2442_pm_drvinit(void)
{
return subsys_interface_register(&s3c2442_pm_interface);
}
arch_initcall(s3c2442_pm_drvinit);
#endif