diff options
-rw-r--r-- | drivers/acpi/device_pm.c | 69 | ||||
-rw-r--r-- | include/linux/acpi.h | 2 |
2 files changed, 34 insertions, 37 deletions
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index eec5ed5be949..bea6896be122 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c | |||
@@ -1041,6 +1041,40 @@ static struct dev_pm_domain acpi_general_pm_domain = { | |||
1041 | }; | 1041 | }; |
1042 | 1042 | ||
1043 | /** | 1043 | /** |
1044 | * acpi_dev_pm_detach - Remove ACPI power management from the device. | ||
1045 | * @dev: Device to take care of. | ||
1046 | * @power_off: Whether or not to try to remove power from the device. | ||
1047 | * | ||
1048 | * Remove the device from the general ACPI PM domain and remove its wakeup | ||
1049 | * notifier. If @power_off is set, additionally remove power from the device if | ||
1050 | * possible. | ||
1051 | * | ||
1052 | * Callers must ensure proper synchronization of this function with power | ||
1053 | * management callbacks. | ||
1054 | */ | ||
1055 | static void acpi_dev_pm_detach(struct device *dev, bool power_off) | ||
1056 | { | ||
1057 | struct acpi_device *adev = ACPI_COMPANION(dev); | ||
1058 | |||
1059 | if (adev && dev->pm_domain == &acpi_general_pm_domain) { | ||
1060 | dev->pm_domain = NULL; | ||
1061 | acpi_remove_pm_notifier(adev); | ||
1062 | if (power_off) { | ||
1063 | /* | ||
1064 | * If the device's PM QoS resume latency limit or flags | ||
1065 | * have been exposed to user space, they have to be | ||
1066 | * hidden at this point, so that they don't affect the | ||
1067 | * choice of the low-power state to put the device into. | ||
1068 | */ | ||
1069 | dev_pm_qos_hide_latency_limit(dev); | ||
1070 | dev_pm_qos_hide_flags(dev); | ||
1071 | acpi_device_wakeup(adev, ACPI_STATE_S0, false); | ||
1072 | acpi_dev_pm_low_power(dev, adev, ACPI_STATE_S0); | ||
1073 | } | ||
1074 | } | ||
1075 | } | ||
1076 | |||
1077 | /** | ||
1044 | * acpi_dev_pm_attach - Prepare device for ACPI power management. | 1078 | * acpi_dev_pm_attach - Prepare device for ACPI power management. |
1045 | * @dev: Device to prepare. | 1079 | * @dev: Device to prepare. |
1046 | * @power_on: Whether or not to power on the device. | 1080 | * @power_on: Whether or not to power on the device. |
@@ -1077,39 +1111,4 @@ int acpi_dev_pm_attach(struct device *dev, bool power_on) | |||
1077 | return 0; | 1111 | return 0; |
1078 | } | 1112 | } |
1079 | EXPORT_SYMBOL_GPL(acpi_dev_pm_attach); | 1113 | EXPORT_SYMBOL_GPL(acpi_dev_pm_attach); |
1080 | |||
1081 | /** | ||
1082 | * acpi_dev_pm_detach - Remove ACPI power management from the device. | ||
1083 | * @dev: Device to take care of. | ||
1084 | * @power_off: Whether or not to try to remove power from the device. | ||
1085 | * | ||
1086 | * Remove the device from the general ACPI PM domain and remove its wakeup | ||
1087 | * notifier. If @power_off is set, additionally remove power from the device if | ||
1088 | * possible. | ||
1089 | * | ||
1090 | * Callers must ensure proper synchronization of this function with power | ||
1091 | * management callbacks. | ||
1092 | */ | ||
1093 | void acpi_dev_pm_detach(struct device *dev, bool power_off) | ||
1094 | { | ||
1095 | struct acpi_device *adev = ACPI_COMPANION(dev); | ||
1096 | |||
1097 | if (adev && dev->pm_domain == &acpi_general_pm_domain) { | ||
1098 | dev->pm_domain = NULL; | ||
1099 | acpi_remove_pm_notifier(adev); | ||
1100 | if (power_off) { | ||
1101 | /* | ||
1102 | * If the device's PM QoS resume latency limit or flags | ||
1103 | * have been exposed to user space, they have to be | ||
1104 | * hidden at this point, so that they don't affect the | ||
1105 | * choice of the low-power state to put the device into. | ||
1106 | */ | ||
1107 | dev_pm_qos_hide_latency_limit(dev); | ||
1108 | dev_pm_qos_hide_flags(dev); | ||
1109 | acpi_device_wakeup(adev, ACPI_STATE_S0, false); | ||
1110 | acpi_dev_pm_low_power(dev, adev, ACPI_STATE_S0); | ||
1111 | } | ||
1112 | } | ||
1113 | } | ||
1114 | EXPORT_SYMBOL_GPL(acpi_dev_pm_detach); | ||
1115 | #endif /* CONFIG_PM */ | 1114 | #endif /* CONFIG_PM */ |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 807cbc46d73e..b7926bb9b444 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -587,7 +587,6 @@ static inline int acpi_subsys_freeze(struct device *dev) { return 0; } | |||
587 | #if defined(CONFIG_ACPI) && defined(CONFIG_PM) | 587 | #if defined(CONFIG_ACPI) && defined(CONFIG_PM) |
588 | struct acpi_device *acpi_dev_pm_get_node(struct device *dev); | 588 | struct acpi_device *acpi_dev_pm_get_node(struct device *dev); |
589 | int acpi_dev_pm_attach(struct device *dev, bool power_on); | 589 | int acpi_dev_pm_attach(struct device *dev, bool power_on); |
590 | void acpi_dev_pm_detach(struct device *dev, bool power_off); | ||
591 | #else | 590 | #else |
592 | static inline struct acpi_device *acpi_dev_pm_get_node(struct device *dev) | 591 | static inline struct acpi_device *acpi_dev_pm_get_node(struct device *dev) |
593 | { | 592 | { |
@@ -597,7 +596,6 @@ static inline int acpi_dev_pm_attach(struct device *dev, bool power_on) | |||
597 | { | 596 | { |
598 | return -ENODEV; | 597 | return -ENODEV; |
599 | } | 598 | } |
600 | static inline void acpi_dev_pm_detach(struct device *dev, bool power_off) {} | ||
601 | #endif | 599 | #endif |
602 | 600 | ||
603 | #ifdef CONFIG_ACPI | 601 | #ifdef CONFIG_ACPI |