summaryrefslogtreecommitdiff
path: root/arch/powerpc/kernel/rtas.c
diff options
context:
space:
mode:
authorFelix Blyakher <felixb@sgi.com>2009-03-30 22:08:33 -0500
committerFelix Blyakher <felixb@sgi.com>2009-03-30 22:08:33 -0500
commit930861c4e6f13ce2e7d06cd1ef11441a065517d9 (patch)
treedf6ff01f89768ff8d6fe6a64491be30e6e56c3e0 /arch/powerpc/kernel/rtas.c
parent8b112171734c791afaf43ccc8c6ec492e7006e44 (diff)
parent15f7176eb1cccec0a332541285ee752b935c1c85 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'arch/powerpc/kernel/rtas.c')
-rw-r--r--arch/powerpc/kernel/rtas.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index fdfe14c4bdef..ee4c7609b649 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -46,6 +46,7 @@ EXPORT_SYMBOL(rtas);
struct rtas_suspend_me_data {
atomic_t working; /* number of cpus accessing this struct */
+ atomic_t done;
int token; /* ibm,suspend-me */
int error;
struct completion *complete; /* wait on this until working == 0 */
@@ -689,7 +690,7 @@ static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE;
#ifdef CONFIG_PPC_PSERIES
static void rtas_percpu_suspend_me(void *info)
{
- long rc;
+ long rc = H_SUCCESS;
unsigned long msr_save;
int cpu;
struct rtas_suspend_me_data *data =
@@ -701,7 +702,8 @@ static void rtas_percpu_suspend_me(void *info)
msr_save = mfmsr();
mtmsr(msr_save & ~(MSR_EE));
- rc = plpar_hcall_norets(H_JOIN);
+ while (rc == H_SUCCESS && !atomic_read(&data->done))
+ rc = plpar_hcall_norets(H_JOIN);
mtmsr(msr_save);
@@ -724,6 +726,9 @@ static void rtas_percpu_suspend_me(void *info)
smp_processor_id(), rc);
data->error = rc;
}
+
+ atomic_set(&data->done, 1);
+
/* This cpu did the suspend or got an error; in either case,
* we need to prod all other other cpus out of join state.
* Extra prods are harmless.
@@ -766,6 +771,7 @@ static int rtas_ibm_suspend_me(struct rtas_args *args)
}
atomic_set(&data.working, 0);
+ atomic_set(&data.done, 0);
data.token = rtas_token("ibm,suspend-me");
data.error = 0;
data.complete = &done;