162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci//
362306a36Sopenharmony_ci// Copyright (c) 2011 Wolfson Microelectronics, plc
462306a36Sopenharmony_ci// Copyright (c) 2011 Samsung Electronics Co., Ltd.
562306a36Sopenharmony_ci//		http://www.samsung.com
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include <linux/kernel.h>
862306a36Sopenharmony_ci#include <linux/init.h>
962306a36Sopenharmony_ci#include <linux/cpuidle.h>
1062306a36Sopenharmony_ci#include <linux/io.h>
1162306a36Sopenharmony_ci#include <linux/export.h>
1262306a36Sopenharmony_ci#include <linux/time.h>
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include <asm/cpuidle.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#include "cpu.h"
1762306a36Sopenharmony_ci#include "map.h"
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#include "regs-sys-s3c64xx.h"
2062306a36Sopenharmony_ci#include "regs-syscon-power-s3c64xx.h"
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_cistatic __cpuidle int s3c64xx_enter_idle(struct cpuidle_device *dev,
2362306a36Sopenharmony_ci					struct cpuidle_driver *drv, int index)
2462306a36Sopenharmony_ci{
2562306a36Sopenharmony_ci	unsigned long tmp;
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci	/* Setup PWRCFG to enter idle mode */
2862306a36Sopenharmony_ci	tmp = __raw_readl(S3C64XX_PWR_CFG);
2962306a36Sopenharmony_ci	tmp &= ~S3C64XX_PWRCFG_CFG_WFI_MASK;
3062306a36Sopenharmony_ci	tmp |= S3C64XX_PWRCFG_CFG_WFI_IDLE;
3162306a36Sopenharmony_ci	__raw_writel(tmp, S3C64XX_PWR_CFG);
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci	cpu_do_idle();
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci	return index;
3662306a36Sopenharmony_ci}
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_cistatic struct cpuidle_driver s3c64xx_cpuidle_driver = {
3962306a36Sopenharmony_ci	.name	= "s3c64xx_cpuidle",
4062306a36Sopenharmony_ci	.owner  = THIS_MODULE,
4162306a36Sopenharmony_ci	.states = {
4262306a36Sopenharmony_ci		{
4362306a36Sopenharmony_ci			.enter            = s3c64xx_enter_idle,
4462306a36Sopenharmony_ci			.exit_latency     = 1,
4562306a36Sopenharmony_ci			.target_residency = 1,
4662306a36Sopenharmony_ci			.name             = "IDLE",
4762306a36Sopenharmony_ci			.desc             = "System active, ARM gated",
4862306a36Sopenharmony_ci		},
4962306a36Sopenharmony_ci	},
5062306a36Sopenharmony_ci	.state_count = 1,
5162306a36Sopenharmony_ci};
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_cistatic int __init s3c64xx_init_cpuidle(void)
5462306a36Sopenharmony_ci{
5562306a36Sopenharmony_ci	if (soc_is_s3c64xx())
5662306a36Sopenharmony_ci		return cpuidle_register(&s3c64xx_cpuidle_driver, NULL);
5762306a36Sopenharmony_ci	return 0;
5862306a36Sopenharmony_ci}
5962306a36Sopenharmony_cidevice_initcall(s3c64xx_init_cpuidle);
60