Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7f3bbb82 authored by Richard Henderson's avatar Richard Henderson Committed by Matt Turner
Browse files

alpha: Primitive support for CPU power down.



Use WTINT to wait for the next interrupt.  Squash the WTINT call
if the PALcode doesn't support it (e.g. MILO).  No attempt is yet
made to skip clock ticks during normal scheduling in order to stay
in power down mode longer.

Signed-off-by: default avatarRichard Henderson <rth@twiddle.net>
parent fddd87d6
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -586,6 +586,30 @@ config NUMA
	  Access).  This option is for configuring high-end multiprocessor
	  server machines.  If in doubt, say N.

config ALPHA_WTINT
	bool "Use WTINT" if ALPHA_SRM || ALPHA_GENERIC
	default y if ALPHA_QEMU
	default n if ALPHA_EV5 || ALPHA_EV56 || (ALPHA_EV4 && !ALPHA_LCA)
	default n if !ALPHA_SRM && !ALPHA_GENERIC
	default y if SMP
	---help---
	  The Wait for Interrupt (WTINT) PALcall attempts to place the CPU
	  to sleep until the next interrupt.  This may reduce the power
	  consumed, and the heat produced by the computer.  However, it has
	  the side effect of making the cycle counter unreliable as a timing
	  device across the sleep.

	  For emulation under QEMU, definitely say Y here, as we have other
	  mechanisms for measuring time than the cycle counter.

	  For EV4 (but not LCA), EV5 and EV56 systems, or for systems running
	  MILO, sleep mode is not supported so you might as well say N here.

	  For SMP systems we cannot use the cycle counter for timing anyway,
	  so you might as well say Y here.

	  If unsure, say N.

config NODES_SHIFT
	int
	default "7"
+1 −0
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ __CALL_PAL_W1(wrmces, unsigned long);
__CALL_PAL_RW2(wrperfmon, unsigned long, unsigned long, unsigned long);
__CALL_PAL_W1(wrusp, unsigned long);
__CALL_PAL_W1(wrvptptr, unsigned long);
__CALL_PAL_RW1(wtint, unsigned long, unsigned long);

/*
 * TB routines..
+1 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@
#define PAL_rdusp	58
#define PAL_whami	60
#define PAL_retsys	61
#define PAL_wtint	62
#define PAL_rti		63


+17 −0
Original line number Diff line number Diff line
@@ -46,6 +46,23 @@
void (*pm_power_off)(void) = machine_power_off;
EXPORT_SYMBOL(pm_power_off);

#ifdef CONFIG_ALPHA_WTINT
/*
 * Sleep the CPU.
 * EV6, LCA45 and QEMU know how to power down, skipping N timer interrupts.
 */
void arch_cpu_idle(void)
{
	wtint(0);
	local_irq_enable();
}

void arch_cpu_idle_dead(void)
{
	wtint(INT_MAX);
}
#endif /* ALPHA_WTINT */

struct halt_info {
	int mode;
	char *restart_cmd;
+15 −0
Original line number Diff line number Diff line
@@ -241,6 +241,21 @@ do_entIF(unsigned long type, struct pt_regs *regs)
			       (const char *)(data[1] | (long)data[2] << 32), 
			       data[0]);
		}
#ifdef CONFIG_ALPHA_WTINT
		if (type == 4) {
			/* If CALL_PAL WTINT is totally unsupported by the
			   PALcode, e.g. MILO, "emulate" it by overwriting
			   the insn.  */
			unsigned int *pinsn
			  = (unsigned int *) regs->pc - 1;
			if (*pinsn == PAL_wtint) {
				*pinsn = 0x47e01400; /* mov 0,$0 */
				imb();
				regs->r0 = 0;
				return;
			}
		}
#endif /* ALPHA_WTINT */
		die_if_kernel((type == 1 ? "Kernel Bug" : "Instruction fault"),
			      regs, type, NULL);
	}