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 (1935B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (C) 2006-2007 PA Semi, Inc
      4 *
      5 * Maintained by: Olof Johansson <olof@lixom.net>
      6 */
      7
      8#undef DEBUG
      9
     10#include <linux/kernel.h>
     11#include <linux/string.h>
     12#include <linux/irq.h>
     13
     14#include <asm/machdep.h>
     15#include <asm/reg.h>
     16#include <asm/smp.h>
     17
     18#include "pasemi.h"
     19
     20struct sleep_mode {
     21	char *name;
     22	void (*entry)(void);
     23};
     24
     25static struct sleep_mode modes[] = {
     26	{ .name = "spin", .entry = &idle_spin },
     27	{ .name = "doze", .entry = &idle_doze },
     28};
     29
     30static int current_mode = 0;
     31
     32static int pasemi_system_reset_exception(struct pt_regs *regs)
     33{
     34	/* If we were woken up from power savings, we need to return
     35	 * to the calling function, since nip is not saved across
     36	 * all modes.
     37	 */
     38
     39	if (regs->msr & SRR1_WAKEMASK)
     40		regs_set_return_ip(regs, regs->link);
     41
     42	switch (regs->msr & SRR1_WAKEMASK) {
     43	case SRR1_WAKEDEC:
     44		set_dec(1);
     45		break;
     46	case SRR1_WAKEEE:
     47		/*
     48		 * Handle these when interrupts get re-enabled and we take
     49		 * them as regular exceptions. We are in an NMI context
     50		 * and can't handle these here.
     51		 */
     52		break;
     53	default:
     54		/* do system reset */
     55		return 0;
     56	}
     57
     58	/* Set higher astate since we come out of power savings at 0 */
     59	restore_astate(hard_smp_processor_id());
     60
     61	/* everything handled */
     62	regs_set_recoverable(regs);
     63	return 1;
     64}
     65
     66static int __init pasemi_idle_init(void)
     67{
     68#ifndef CONFIG_PPC_PASEMI_CPUFREQ
     69	pr_warn("No cpufreq driver, powersavings modes disabled\n");
     70	current_mode = 0;
     71#endif
     72
     73	ppc_md.system_reset_exception = pasemi_system_reset_exception;
     74	ppc_md.power_save = modes[current_mode].entry;
     75	pr_info("Using PA6T idle loop (%s)\n", modes[current_mode].name);
     76
     77	return 0;
     78}
     79machine_late_initcall(pasemi, pasemi_idle_init);
     80
     81static int __init idle_param(char *p)
     82{
     83	int i;
     84	for (i = 0; i < ARRAY_SIZE(modes); i++) {
     85		if (!strcmp(modes[i].name, p)) {
     86			current_mode = i;
     87			break;
     88		}
     89	}
     90	return 0;
     91}
     92
     93early_param("idle", idle_param);