diff options
Diffstat (limited to 'drivers/acpi/processor_idle.c')
-rw-r--r-- | drivers/acpi/processor_idle.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index f3decb30223f..47a8caa89dbe 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -224,6 +224,7 @@ static void lapic_timer_state_broadcast(struct acpi_processor *pr, | |||
224 | /* | 224 | /* |
225 | * Suspend / resume control | 225 | * Suspend / resume control |
226 | */ | 226 | */ |
227 | static int acpi_idle_suspend; | ||
227 | static u32 saved_bm_rld; | 228 | static u32 saved_bm_rld; |
228 | 229 | ||
229 | static void acpi_idle_bm_rld_save(void) | 230 | static void acpi_idle_bm_rld_save(void) |
@@ -242,13 +243,21 @@ static void acpi_idle_bm_rld_restore(void) | |||
242 | 243 | ||
243 | int acpi_processor_suspend(struct acpi_device * device, pm_message_t state) | 244 | int acpi_processor_suspend(struct acpi_device * device, pm_message_t state) |
244 | { | 245 | { |
246 | if (acpi_idle_suspend == 1) | ||
247 | return 0; | ||
248 | |||
245 | acpi_idle_bm_rld_save(); | 249 | acpi_idle_bm_rld_save(); |
250 | acpi_idle_suspend = 1; | ||
246 | return 0; | 251 | return 0; |
247 | } | 252 | } |
248 | 253 | ||
249 | int acpi_processor_resume(struct acpi_device * device) | 254 | int acpi_processor_resume(struct acpi_device * device) |
250 | { | 255 | { |
256 | if (acpi_idle_suspend == 0) | ||
257 | return 0; | ||
258 | |||
251 | acpi_idle_bm_rld_restore(); | 259 | acpi_idle_bm_rld_restore(); |
260 | acpi_idle_suspend = 0; | ||
252 | return 0; | 261 | return 0; |
253 | } | 262 | } |
254 | 263 | ||
@@ -754,6 +763,12 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, | |||
754 | 763 | ||
755 | local_irq_disable(); | 764 | local_irq_disable(); |
756 | 765 | ||
766 | if (acpi_idle_suspend) { | ||
767 | local_irq_enable(); | ||
768 | cpu_relax(); | ||
769 | return -EBUSY; | ||
770 | } | ||
771 | |||
757 | lapic_timer_state_broadcast(pr, cx, 1); | 772 | lapic_timer_state_broadcast(pr, cx, 1); |
758 | kt1 = ktime_get_real(); | 773 | kt1 = ktime_get_real(); |
759 | acpi_idle_do_entry(cx); | 774 | acpi_idle_do_entry(cx); |
@@ -823,6 +838,12 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
823 | 838 | ||
824 | local_irq_disable(); | 839 | local_irq_disable(); |
825 | 840 | ||
841 | if (acpi_idle_suspend) { | ||
842 | local_irq_enable(); | ||
843 | cpu_relax(); | ||
844 | return -EBUSY; | ||
845 | } | ||
846 | |||
826 | if (cx->entry_method != ACPI_CSTATE_FFH) { | 847 | if (cx->entry_method != ACPI_CSTATE_FFH) { |
827 | current_thread_info()->status &= ~TS_POLLING; | 848 | current_thread_info()->status &= ~TS_POLLING; |
828 | /* | 849 | /* |
@@ -907,14 +928,21 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
907 | drv, drv->safe_state_index); | 928 | drv, drv->safe_state_index); |
908 | } else { | 929 | } else { |
909 | local_irq_disable(); | 930 | local_irq_disable(); |
910 | acpi_safe_halt(); | 931 | if (!acpi_idle_suspend) |
932 | acpi_safe_halt(); | ||
911 | local_irq_enable(); | 933 | local_irq_enable(); |
912 | return -EINVAL; | 934 | return -EBUSY; |
913 | } | 935 | } |
914 | } | 936 | } |
915 | 937 | ||
916 | local_irq_disable(); | 938 | local_irq_disable(); |
917 | 939 | ||
940 | if (acpi_idle_suspend) { | ||
941 | local_irq_enable(); | ||
942 | cpu_relax(); | ||
943 | return -EBUSY; | ||
944 | } | ||
945 | |||
918 | if (cx->entry_method != ACPI_CSTATE_FFH) { | 946 | if (cx->entry_method != ACPI_CSTATE_FFH) { |
919 | current_thread_info()->status &= ~TS_POLLING; | 947 | current_thread_info()->status &= ~TS_POLLING; |
920 | /* | 948 | /* |