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

idle.c (2695B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Idle daemon for PowerPC.  Idle daemon will handle any action
      4 * that needs to be taken when the system becomes idle.
      5 *
      6 * Originally written by Cort Dougan (cort@cs.nmt.edu).
      7 * Subsequent 32-bit hacking by Tom Rini, Armin Kuster,
      8 * Paul Mackerras and others.
      9 *
     10 * iSeries supported added by Mike Corrigan <mikejc@us.ibm.com>
     11 *
     12 * Additional shared processor, SMT, and firmware support
     13 *    Copyright (c) 2003 Dave Engebretsen <engebret@us.ibm.com>
     14 *
     15 * 32-bit and 64-bit versions merged by Paul Mackerras <paulus@samba.org>
     16 */
     17
     18#include <linux/sched.h>
     19#include <linux/kernel.h>
     20#include <linux/smp.h>
     21#include <linux/cpu.h>
     22#include <linux/sysctl.h>
     23#include <linux/tick.h>
     24
     25#include <asm/processor.h>
     26#include <asm/cputable.h>
     27#include <asm/time.h>
     28#include <asm/machdep.h>
     29#include <asm/runlatch.h>
     30#include <asm/smp.h>
     31
     32
     33unsigned long cpuidle_disable = IDLE_NO_OVERRIDE;
     34EXPORT_SYMBOL(cpuidle_disable);
     35
     36static int __init powersave_off(char *arg)
     37{
     38	ppc_md.power_save = NULL;
     39	cpuidle_disable = IDLE_POWERSAVE_OFF;
     40	return 1;
     41}
     42__setup("powersave=off", powersave_off);
     43
     44void arch_cpu_idle(void)
     45{
     46	ppc64_runlatch_off();
     47
     48	if (ppc_md.power_save) {
     49		ppc_md.power_save();
     50		/*
     51		 * Some power_save functions return with
     52		 * interrupts enabled, some don't.
     53		 */
     54		if (irqs_disabled())
     55			raw_local_irq_enable();
     56	} else {
     57		raw_local_irq_enable();
     58		/*
     59		 * Go into low thread priority and possibly
     60		 * low power mode.
     61		 */
     62		HMT_low();
     63		HMT_very_low();
     64	}
     65
     66	HMT_medium();
     67	ppc64_runlatch_on();
     68}
     69
     70int powersave_nap;
     71
     72#ifdef CONFIG_PPC_970_NAP
     73void power4_idle(void)
     74{
     75	if (!cpu_has_feature(CPU_FTR_CAN_NAP))
     76		return;
     77
     78	if (!powersave_nap)
     79		return;
     80
     81	if (!prep_irq_for_idle())
     82		return;
     83
     84	if (cpu_has_feature(CPU_FTR_ALTIVEC))
     85		asm volatile(PPC_DSSALL " ; sync" ::: "memory");
     86
     87	power4_idle_nap();
     88
     89	/*
     90	 * power4_idle_nap returns with interrupts enabled (soft and hard).
     91	 * to our caller with interrupts enabled (soft and hard). Our caller
     92	 * can cope with either interrupts disabled or enabled upon return.
     93	 */
     94}
     95#endif
     96
     97#ifdef CONFIG_SYSCTL
     98/*
     99 * Register the sysctl to set/clear powersave_nap.
    100 */
    101static struct ctl_table powersave_nap_ctl_table[] = {
    102	{
    103		.procname	= "powersave-nap",
    104		.data		= &powersave_nap,
    105		.maxlen		= sizeof(int),
    106		.mode		= 0644,
    107		.proc_handler	= proc_dointvec,
    108	},
    109	{}
    110};
    111static struct ctl_table powersave_nap_sysctl_root[] = {
    112	{
    113		.procname	= "kernel",
    114		.mode		= 0555,
    115		.child		= powersave_nap_ctl_table,
    116	},
    117	{}
    118};
    119
    120static int __init
    121register_powersave_nap_sysctl(void)
    122{
    123	register_sysctl_table(powersave_nap_sysctl_root);
    124
    125	return 0;
    126}
    127__initcall(register_powersave_nap_sysctl);
    128#endif