aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/rtas.c
diff options
context:
space:
mode:
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);
46 46
47struct rtas_suspend_me_data { 47struct rtas_suspend_me_data {
48 atomic_t working; /* number of cpus accessing this struct */ 48 atomic_t working; /* number of cpus accessing this struct */
49 atomic_t done;
49 int token; /* ibm,suspend-me */ 50 int token; /* ibm,suspend-me */
50 int error; 51 int error;
51 struct completion *complete; /* wait on this until working == 0 */ 52 struct completion *complete; /* wait on this until working == 0 */
@@ -689,7 +690,7 @@ static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE;
689#ifdef CONFIG_PPC_PSERIES 690#ifdef CONFIG_PPC_PSERIES
690static void rtas_percpu_suspend_me(void *info) 691static void rtas_percpu_suspend_me(void *info)
691{ 692{
692 long rc; 693 long rc = H_SUCCESS;
693 unsigned long msr_save; 694 unsigned long msr_save;
694 int cpu; 695 int cpu;
695 struct rtas_suspend_me_data *data = 696 struct rtas_suspend_me_data *data =
@@ -701,7 +702,8 @@ static void rtas_percpu_suspend_me(void *info)
701 msr_save = mfmsr(); 702 msr_save = mfmsr();
702 mtmsr(msr_save & ~(MSR_EE)); 703 mtmsr(msr_save & ~(MSR_EE));
703 704
704 rc = plpar_hcall_norets(H_JOIN); 705 while (rc == H_SUCCESS && !atomic_read(&data->done))
706 rc = plpar_hcall_norets(H_JOIN);
705 707
706 mtmsr(msr_save); 708 mtmsr(msr_save);
707 709
@@ -724,6 +726,9 @@ static void rtas_percpu_suspend_me(void *info)
724 smp_processor_id(), rc); 726 smp_processor_id(), rc);
725 data->error = rc; 727 data->error = rc;
726 } 728 }
729
730 atomic_set(&data->done, 1);
731
727 /* This cpu did the suspend or got an error; in either case, 732 /* This cpu did the suspend or got an error; in either case,
728 * we need to prod all other other cpus out of join state. 733 * we need to prod all other other cpus out of join state.
729 * Extra prods are harmless. 734 * Extra prods are harmless.
@@ -766,6 +771,7 @@ static int rtas_ibm_suspend_me(struct rtas_args *args)
766 } 771 }
767 772
768 atomic_set(&data.working, 0); 773 atomic_set(&data.working, 0);
774 atomic_set(&data.done, 0);
769 data.token = rtas_token("ibm,suspend-me"); 775 data.token = rtas_token("ibm,suspend-me");
770 data.error = 0; 776 data.error = 0;
771 data.complete = &done; 777 data.complete = &done;