diff options
Diffstat (limited to 'drivers/acpi/device_pm.c')
| -rw-r--r-- | drivers/acpi/device_pm.c | 136 | 
1 files changed, 70 insertions, 66 deletions
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 96de787e6104..318fa32a141e 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -37,68 +37,6 @@  #define _COMPONENT	ACPI_POWER_COMPONENT  ACPI_MODULE_NAME("device_pm"); -static DEFINE_MUTEX(acpi_pm_notifier_lock); - -/** - * acpi_add_pm_notifier - Register PM notifier for given ACPI device. - * @adev: ACPI device to add the notifier for. - * @context: Context information to pass to the notifier routine. - * - * NOTE: @adev need not be a run-wake or wakeup device to be a valid source of - * PM wakeup events.  For example, wakeup events may be generated for bridges - * if one of the devices below the bridge is signaling wakeup, even if the - * bridge itself doesn't have a wakeup GPE associated with it. - */ -acpi_status acpi_add_pm_notifier(struct acpi_device *adev, -				 acpi_notify_handler handler, void *context) -{ -	acpi_status status = AE_ALREADY_EXISTS; - -	mutex_lock(&acpi_pm_notifier_lock); - -	if (adev->wakeup.flags.notifier_present) -		goto out; - -	status = acpi_install_notify_handler(adev->handle, -					     ACPI_SYSTEM_NOTIFY, -					     handler, context); -	if (ACPI_FAILURE(status)) -		goto out; - -	adev->wakeup.flags.notifier_present = true; - - out: -	mutex_unlock(&acpi_pm_notifier_lock); -	return status; -} - -/** - * acpi_remove_pm_notifier - Unregister PM notifier from given ACPI device. - * @adev: ACPI device to remove the notifier from. - */ -acpi_status acpi_remove_pm_notifier(struct acpi_device *adev, -				    acpi_notify_handler handler) -{ -	acpi_status status = AE_BAD_PARAMETER; - -	mutex_lock(&acpi_pm_notifier_lock); - -	if (!adev->wakeup.flags.notifier_present) -		goto out; - -	status = acpi_remove_notify_handler(adev->handle, -					    ACPI_SYSTEM_NOTIFY, -					    handler); -	if (ACPI_FAILURE(status)) -		goto out; - -	adev->wakeup.flags.notifier_present = false; - - out: -	mutex_unlock(&acpi_pm_notifier_lock); -	return status; -} -  /**   * acpi_power_state_string - String representation of ACPI device power state.   * @state: ACPI device power state to return the string representation of. @@ -340,11 +278,13 @@ int acpi_bus_init_power(struct acpi_device *device)  		if (result)  			return result;  	} else if (state == ACPI_STATE_UNKNOWN) { -		/* No power resources and missing _PSC? Try to force D0. */ +		/* +		 * No power resources and missing _PSC?  Cross fingers and make +		 * it D0 in hope that this is what the BIOS put the device into. +		 * [We tried to force D0 here by executing _PS0, but that broke +		 * Toshiba P870-303 in a nasty way.] +		 */  		state = ACPI_STATE_D0; -		result = acpi_dev_pm_explicit_set(device, state); -		if (result) -			return result;  	}  	device->power.state = state;  	return 0; @@ -385,6 +325,69 @@ bool acpi_bus_power_manageable(acpi_handle handle)  }  EXPORT_SYMBOL(acpi_bus_power_manageable); +#ifdef CONFIG_PM +static DEFINE_MUTEX(acpi_pm_notifier_lock); + +/** + * acpi_add_pm_notifier - Register PM notifier for given ACPI device. + * @adev: ACPI device to add the notifier for. + * @context: Context information to pass to the notifier routine. + * + * NOTE: @adev need not be a run-wake or wakeup device to be a valid source of + * PM wakeup events.  For example, wakeup events may be generated for bridges + * if one of the devices below the bridge is signaling wakeup, even if the + * bridge itself doesn't have a wakeup GPE associated with it. + */ +acpi_status acpi_add_pm_notifier(struct acpi_device *adev, +				 acpi_notify_handler handler, void *context) +{ +	acpi_status status = AE_ALREADY_EXISTS; + +	mutex_lock(&acpi_pm_notifier_lock); + +	if (adev->wakeup.flags.notifier_present) +		goto out; + +	status = acpi_install_notify_handler(adev->handle, +					     ACPI_SYSTEM_NOTIFY, +					     handler, context); +	if (ACPI_FAILURE(status)) +		goto out; + +	adev->wakeup.flags.notifier_present = true; + + out: +	mutex_unlock(&acpi_pm_notifier_lock); +	return status; +} + +/** + * acpi_remove_pm_notifier - Unregister PM notifier from given ACPI device. + * @adev: ACPI device to remove the notifier from. + */ +acpi_status acpi_remove_pm_notifier(struct acpi_device *adev, +				    acpi_notify_handler handler) +{ +	acpi_status status = AE_BAD_PARAMETER; + +	mutex_lock(&acpi_pm_notifier_lock); + +	if (!adev->wakeup.flags.notifier_present) +		goto out; + +	status = acpi_remove_notify_handler(adev->handle, +					    ACPI_SYSTEM_NOTIFY, +					    handler); +	if (ACPI_FAILURE(status)) +		goto out; + +	adev->wakeup.flags.notifier_present = false; + + out: +	mutex_unlock(&acpi_pm_notifier_lock); +	return status; +} +  bool acpi_bus_can_wakeup(acpi_handle handle)  {  	struct acpi_device *device; @@ -1023,3 +1026,4 @@ void acpi_dev_pm_remove_dependent(acpi_handle handle, struct device *depdev)  	mutex_unlock(&adev->physical_node_lock);  }  EXPORT_SYMBOL_GPL(acpi_dev_pm_remove_dependent); +#endif /* CONFIG_PM */  |