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,  /*   * Suspend / resume control   */ +static int acpi_idle_suspend;  static u32 saved_bm_rld;  static void acpi_idle_bm_rld_save(void) @@ -242,13 +243,21 @@ static void acpi_idle_bm_rld_restore(void)  int acpi_processor_suspend(struct acpi_device * device, pm_message_t state)  { +	if (acpi_idle_suspend == 1) +		return 0; +  	acpi_idle_bm_rld_save(); +	acpi_idle_suspend = 1;  	return 0;  }  int acpi_processor_resume(struct acpi_device * device)  { +	if (acpi_idle_suspend == 0) +		return 0; +  	acpi_idle_bm_rld_restore(); +	acpi_idle_suspend = 0;  	return 0;  } @@ -754,6 +763,12 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,  	local_irq_disable(); +	if (acpi_idle_suspend) { +		local_irq_enable(); +		cpu_relax(); +		return -EBUSY; +	} +  	lapic_timer_state_broadcast(pr, cx, 1);  	kt1 = ktime_get_real();  	acpi_idle_do_entry(cx); @@ -823,6 +838,12 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,  	local_irq_disable(); +	if (acpi_idle_suspend) { +		local_irq_enable(); +		cpu_relax(); +		return -EBUSY; +	} +  	if (cx->entry_method != ACPI_CSTATE_FFH) {  		current_thread_info()->status &= ~TS_POLLING;  		/* @@ -907,14 +928,21 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,  						drv, drv->safe_state_index);  		} else {  			local_irq_disable(); -			acpi_safe_halt(); +			if (!acpi_idle_suspend) +				acpi_safe_halt();  			local_irq_enable(); -			return -EINVAL; +			return -EBUSY;  		}  	}  	local_irq_disable(); +	if (acpi_idle_suspend) { +		local_irq_enable(); +		cpu_relax(); +		return -EBUSY; +	} +  	if (cx->entry_method != ACPI_CSTATE_FFH) {  		current_thread_info()->status &= ~TS_POLLING;  		/* | 
