cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cpuidle.c (2318B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * arch/sh/kernel/cpu/shmobile/cpuidle.c
      4 *
      5 * Cpuidle support code for SuperH Mobile
      6 *
      7 *  Copyright (C) 2009 Magnus Damm
      8 */
      9#include <linux/init.h>
     10#include <linux/kernel.h>
     11#include <linux/io.h>
     12#include <linux/suspend.h>
     13#include <linux/cpuidle.h>
     14#include <linux/export.h>
     15#include <asm/suspend.h>
     16#include <linux/uaccess.h>
     17
     18static unsigned long cpuidle_mode[] = {
     19	SUSP_SH_SLEEP, /* regular sleep mode */
     20	SUSP_SH_SLEEP | SUSP_SH_SF, /* sleep mode + self refresh */
     21	SUSP_SH_STANDBY | SUSP_SH_SF, /* software standby mode + self refresh */
     22};
     23
     24static int cpuidle_sleep_enter(struct cpuidle_device *dev,
     25				struct cpuidle_driver *drv,
     26				int index)
     27{
     28	unsigned long allowed_mode = SUSP_SH_SLEEP;
     29	int requested_state = index;
     30	int allowed_state;
     31	int k;
     32
     33	/* convert allowed mode to allowed state */
     34	for (k = ARRAY_SIZE(cpuidle_mode) - 1; k > 0; k--)
     35		if (cpuidle_mode[k] == allowed_mode)
     36			break;
     37
     38	allowed_state = k;
     39
     40	/* take the following into account for sleep mode selection:
     41	 * - allowed_state: best mode allowed by hardware (clock deps)
     42	 * - requested_state: best mode allowed by software (latencies)
     43	 */
     44	k = min_t(int, allowed_state, requested_state);
     45
     46	sh_mobile_call_standby(cpuidle_mode[k]);
     47
     48	return k;
     49}
     50
     51static struct cpuidle_driver cpuidle_driver = {
     52	.name   = "sh_idle",
     53	.owner  = THIS_MODULE,
     54	.states = {
     55		{
     56			.exit_latency = 1,
     57			.target_residency = 1 * 2,
     58			.power_usage = 3,
     59			.enter = cpuidle_sleep_enter,
     60			.name = "C1",
     61			.desc = "SuperH Sleep Mode",
     62		},
     63		{
     64			.exit_latency = 100,
     65			.target_residency = 1 * 2,
     66			.power_usage = 1,
     67			.enter = cpuidle_sleep_enter,
     68			.name = "C2",
     69			.desc = "SuperH Sleep Mode [SF]",
     70			.flags = CPUIDLE_FLAG_UNUSABLE,
     71		},
     72		{
     73			.exit_latency = 2300,
     74			.target_residency = 1 * 2,
     75			.power_usage = 1,
     76			.enter = cpuidle_sleep_enter,
     77			.name = "C3",
     78			.desc = "SuperH Mobile Standby Mode [SF]",
     79			.flags = CPUIDLE_FLAG_UNUSABLE,
     80		},
     81	},
     82	.safe_state_index = 0,
     83	.state_count = 3,
     84};
     85
     86int __init sh_mobile_setup_cpuidle(void)
     87{
     88	if (sh_mobile_sleep_supported & SUSP_SH_SF)
     89		cpuidle_driver.states[1].flags = CPUIDLE_FLAG_NONE;
     90
     91	if (sh_mobile_sleep_supported & SUSP_SH_STANDBY)
     92		cpuidle_driver.states[2].flags = CPUIDLE_FLAG_NONE;
     93
     94	return cpuidle_register(&cpuidle_driver, NULL);
     95}