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 | /* |
