Merge tag 'selinux-pr-20201214' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / drivers / acpi / device_pm.c
index 94d91c6..3586434 100644 (file)
@@ -749,7 +749,7 @@ static void acpi_pm_notify_work_func(struct acpi_device_wakeup_context *context)
 static DEFINE_MUTEX(acpi_wakeup_lock);
 
 static int __acpi_device_wakeup_enable(struct acpi_device *adev,
-                                      u32 target_state, int max_count)
+                                      u32 target_state)
 {
        struct acpi_device_wakeup *wakeup = &adev->wakeup;
        acpi_status status;
@@ -757,15 +757,26 @@ static int __acpi_device_wakeup_enable(struct acpi_device *adev,
 
        mutex_lock(&acpi_wakeup_lock);
 
-       if (wakeup->enable_count >= max_count)
-               goto out;
-
+       /*
+        * If the device wakeup power is already enabled, disable it and enable
+        * it again in case it depends on the configuration of subordinate
+        * devices and the conditions have changed since it was enabled last
+        * time.
+        */
        if (wakeup->enable_count > 0)
-               goto inc;
+               acpi_disable_wakeup_device_power(adev);
 
        error = acpi_enable_wakeup_device_power(adev, target_state);
-       if (error)
+       if (error) {
+               if (wakeup->enable_count > 0) {
+                       acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number);
+                       wakeup->enable_count = 0;
+               }
                goto out;
+       }
+
+       if (wakeup->enable_count > 0)
+               goto inc;
 
        status = acpi_enable_gpe(wakeup->gpe_device, wakeup->gpe_number);
        if (ACPI_FAILURE(status)) {
@@ -778,7 +789,10 @@ static int __acpi_device_wakeup_enable(struct acpi_device *adev,
                          (unsigned int)wakeup->gpe_number);
 
 inc:
-       wakeup->enable_count++;
+       if (wakeup->enable_count < INT_MAX)
+               wakeup->enable_count++;
+       else
+               acpi_handle_info(adev->handle, "Wakeup enable count out of bounds!\n");
 
 out:
        mutex_unlock(&acpi_wakeup_lock);
@@ -799,7 +813,7 @@ out:
  */
 static int acpi_device_wakeup_enable(struct acpi_device *adev, u32 target_state)
 {
-       return __acpi_device_wakeup_enable(adev, target_state, 1);
+       return __acpi_device_wakeup_enable(adev, target_state);
 }
 
 /**
@@ -829,8 +843,12 @@ out:
        mutex_unlock(&acpi_wakeup_lock);
 }
 
-static int __acpi_pm_set_device_wakeup(struct device *dev, bool enable,
-                                      int max_count)
+/**
+ * acpi_pm_set_device_wakeup - Enable/disable remote wakeup for given device.
+ * @dev: Device to enable/disable to generate wakeup events.
+ * @enable: Whether to enable or disable the wakeup functionality.
+ */
+int acpi_pm_set_device_wakeup(struct device *dev, bool enable)
 {
        struct acpi_device *adev;
        int error;
@@ -850,36 +868,14 @@ static int __acpi_pm_set_device_wakeup(struct device *dev, bool enable,
                return 0;
        }
 
-       error = __acpi_device_wakeup_enable(adev, acpi_target_system_state(),
-                                           max_count);
+       error = __acpi_device_wakeup_enable(adev, acpi_target_system_state());
        if (!error)
                dev_dbg(dev, "Wakeup enabled by ACPI\n");
 
        return error;
 }
-
-/**
- * acpi_pm_set_device_wakeup - Enable/disable remote wakeup for given device.
- * @dev: Device to enable/disable to generate wakeup events.
- * @enable: Whether to enable or disable the wakeup functionality.
- */
-int acpi_pm_set_device_wakeup(struct device *dev, bool enable)
-{
-       return __acpi_pm_set_device_wakeup(dev, enable, 1);
-}
 EXPORT_SYMBOL_GPL(acpi_pm_set_device_wakeup);
 
-/**
- * acpi_pm_set_bridge_wakeup - Enable/disable remote wakeup for given bridge.
- * @dev: Bridge device to enable/disable to generate wakeup events.
- * @enable: Whether to enable or disable the wakeup functionality.
- */
-int acpi_pm_set_bridge_wakeup(struct device *dev, bool enable)
-{
-       return __acpi_pm_set_device_wakeup(dev, enable, INT_MAX);
-}
-EXPORT_SYMBOL_GPL(acpi_pm_set_bridge_wakeup);
-
 /**
  * acpi_dev_pm_low_power - Put ACPI device into a low-power state.
  * @dev: Device to put into a low-power state.