1/*
2 *  This file contains the power_save function for 970-family CPUs.
3 *
4 *  This program is free software; you can redistribute it and/or
5 *  modify it under the terms of the GNU General Public License
6 *  as published by the Free Software Foundation; either version
7 *  2 of the License, or (at your option) any later version.
8 */
9
10#include <linux/threads.h>
11#include <asm/processor.h>
12#include <asm/page.h>
13#include <asm/cputable.h>
14#include <asm/thread_info.h>
15#include <asm/ppc_asm.h>
16#include <asm/asm-offsets.h>
17#include <asm/irqflags.h>
18
19#undef DEBUG
20
21	.text
22
23_GLOBAL(power4_idle)
24BEGIN_FTR_SECTION
25	blr
26END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP)
27	/* Now check if user or arch enabled NAP mode */
28	LOAD_REG_ADDRBASE(r3,powersave_nap)
29	lwz	r4,ADDROFF(powersave_nap)(r3)
30	cmpwi	0,r4,0
31	beqlr
32
33	/* Hard disable interrupts */
34	mfmsr	r7
35	rldicl	r0,r7,48,1
36	rotldi	r0,r0,16
37	mtmsrd	r0,1
38
39	/* Check if something happened while soft-disabled */
40	lbz	r0,PACAIRQHAPPENED(r13)
41	cmpwi	cr0,r0,0
42	bnelr
43
44	/* Soft-enable interrupts */
45#ifdef CONFIG_TRACE_IRQFLAGS
46	mflr	r0
47	std	r0,16(r1)
48	stdu    r1,-128(r1)
49	bl	trace_hardirqs_on
50	addi    r1,r1,128
51	ld	r0,16(r1)
52	mtlr	r0
53	mfmsr	r7
54#endif /* CONFIG_TRACE_IRQFLAGS */
55
56	li	r0,1
57	stb	r0,PACASOFTIRQEN(r13)	/* we'll hard-enable shortly */
58BEGIN_FTR_SECTION
59	DSSALL
60	sync
61END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
62	CURRENT_THREAD_INFO(r9, r1)
63	ld	r8,TI_LOCAL_FLAGS(r9)	/* set napping bit */
64	ori	r8,r8,_TLF_NAPPING	/* so when we take an exception */
65	std	r8,TI_LOCAL_FLAGS(r9)	/* it will return to our caller */
66	ori	r7,r7,MSR_EE
67	oris	r7,r7,MSR_POW@h
681:	sync
69	isync
70	mtmsrd	r7
71	isync
72	b	1b
73
74