diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-03-31 13:53:43 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-03-31 13:53:43 +0200 |
commit | 7bee946358c3cb957d4aa648fc5ab3cad0b232d0 (patch) | |
tree | 693061ebde2abc35ecc846e5084630d7225aaaff /arch/powerpc/kernel/rtas.c | |
parent | d820ac4c2fa881079e6b689d2098adce337558ae (diff) | |
parent | 15f7176eb1cccec0a332541285ee752b935c1c85 (diff) |
Merge branch 'linus' into locking-for-linus
Conflicts:
lib/Kconfig.debug
Diffstat (limited to 'arch/powerpc/kernel/rtas.c')
-rw-r--r-- | arch/powerpc/kernel/rtas.c | 10 |
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; |