diff options
author | Dave C Boutcher <boutcher@cs.umn.edu> | 2006-06-12 20:49:20 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-06-15 05:31:27 -0400 |
commit | 368a6ba5d188552aea2a668301a259164c9f355e (patch) | |
tree | d22916e2870618b2b4ff26588df8f66a5928ac64 | |
parent | 0e4aa9c2009187fff1c999fe0aaa134c1a84f48a (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.c | 22 | ||||
-rw-r--r-- | include/asm-powerpc/hvcall.h | 10 | ||||
-rw-r--r-- | include/asm-powerpc/rtas.h | 1 |
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: | |||
593 | static int rtas_ibm_suspend_me(struct rtas_args *args) | 593 | static 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 |