aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave C Boutcher <boutcher@cs.umn.edu>2006-06-12 20:49:20 -0400
committerPaul Mackerras <paulus@samba.org>2006-06-15 05:31:27 -0400
commit368a6ba5d188552aea2a668301a259164c9f355e (patch)
treed22916e2870618b2b4ff26588df8f66a5928ac64
parent0e4aa9c2009187fff1c999fe0aaa134c1a84f48a (diff)
[POWERPC] check firmware state before suspending
Currently the kernel blindly halts all the processors and calls the ibm,suspend-me rtas call. If the firmware is not in the correct state, we then re-start all the processors and return. It is much smarter to first check the firmware state, and only if it is waiting, call the ibm,suspend-me call. Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--arch/powerpc/kernel/rtas.c22
-rw-r--r--include/asm-powerpc/hvcall.h10
-rw-r--r--include/asm-powerpc/rtas.h1
3 files changed, 33 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 13496f319855..fd15e3e3bb33 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -593,9 +593,31 @@ out:
593static int rtas_ibm_suspend_me(struct rtas_args *args) 593static int rtas_ibm_suspend_me(struct rtas_args *args)
594{ 594{
595 int i; 595 int i;
596 long state;
597 long rc;
598 unsigned long dummy;
596 599
597 struct rtas_suspend_me_data data; 600 struct rtas_suspend_me_data data;
598 601
602 /* Make sure the state is valid */
603 rc = plpar_hcall(H_VASI_STATE,
604 ((u64)args->args[0] << 32) | args->args[1],
605 0, 0, 0,
606 &state, &dummy, &dummy);
607
608 if (rc) {
609 printk(KERN_ERR "rtas_ibm_suspend_me: vasi_state returned %ld\n",rc);
610 return rc;
611 } else if (state == H_VASI_ENABLED) {
612 args->args[args->nargs] = RTAS_NOT_SUSPENDABLE;
613 return 0;
614 } else if (state != H_VASI_SUSPENDING) {
615 printk(KERN_ERR "rtas_ibm_suspend_me: vasi_state returned state %ld\n",
616 state);
617 args->args[args->nargs] = -1;
618 return 0;
619 }
620
599 data.waiting = 1; 621 data.waiting = 1;
600 data.args = args; 622 data.args = args;
601 623
diff --git a/include/asm-powerpc/hvcall.h b/include/asm-powerpc/hvcall.h
index 6cc7e1fb7bfd..0d3c4e85711a 100644
--- a/include/asm-powerpc/hvcall.h
+++ b/include/asm-powerpc/hvcall.h
@@ -102,6 +102,15 @@
102#define H_PP1 (1UL<<(63-62)) 102#define H_PP1 (1UL<<(63-62))
103#define H_PP2 (1UL<<(63-63)) 103#define H_PP2 (1UL<<(63-63))
104 104
105/* VASI States */
106#define H_VASI_INVALID 0
107#define H_VASI_ENABLED 1
108#define H_VASI_ABORTED 2
109#define H_VASI_SUSPENDING 3
110#define H_VASI_SUSPENDED 4
111#define H_VASI_RESUMED 5
112#define H_VASI_COMPLETED 6
113
105/* DABRX flags */ 114/* DABRX flags */
106#define H_DABRX_HYPERVISOR (1UL<<(63-61)) 115#define H_DABRX_HYPERVISOR (1UL<<(63-61))
107#define H_DABRX_KERNEL (1UL<<(63-62)) 116#define H_DABRX_KERNEL (1UL<<(63-62))
@@ -190,6 +199,7 @@
190#define H_QUERY_INT_STATE 0x1E4 199#define H_QUERY_INT_STATE 0x1E4
191#define H_POLL_PENDING 0x1D8 200#define H_POLL_PENDING 0x1D8
192#define H_JOIN 0x298 201#define H_JOIN 0x298
202#define H_VASI_STATE 0x2A4
193#define H_ENABLE_CRQ 0x2B0 203#define H_ENABLE_CRQ 0x2B0
194 204
195#ifndef __ASSEMBLY__ 205#ifndef __ASSEMBLY__
diff --git a/include/asm-powerpc/rtas.h b/include/asm-powerpc/rtas.h
index a3b4e55569c7..02e213e3d69f 100644
--- a/include/asm-powerpc/rtas.h
+++ b/include/asm-powerpc/rtas.h
@@ -24,6 +24,7 @@
24#define RTAS_RMOBUF_MAX (64 * 1024) 24#define RTAS_RMOBUF_MAX (64 * 1024)
25 25
26/* RTAS return status codes */ 26/* RTAS return status codes */
27#define RTAS_NOT_SUSPENDABLE -9004
27#define RTAS_BUSY -2 /* RTAS Busy */ 28#define RTAS_BUSY -2 /* RTAS Busy */
28#define RTAS_EXTENDED_DELAY_MIN 9900 29#define RTAS_EXTENDED_DELAY_MIN 9900
29#define RTAS_EXTENDED_DELAY_MAX 9905 30#define RTAS_EXTENDED_DELAY_MAX 9905