summaryrefslogtreecommitdiff
path: root/drivers/acpi/device_pm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/device_pm.c')
-rw-r--r--drivers/acpi/device_pm.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index 995019063f6..8be4b29e38a 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -665,3 +665,59 @@ void acpi_dev_pm_detach(struct device *dev, bool power_off)
}
}
EXPORT_SYMBOL_GPL(acpi_dev_pm_detach);
+
+/**
+ * acpi_dev_pm_add_dependent - Add physical device depending for PM.
+ * @handle: Handle of ACPI device node.
+ * @depdev: Device depending on that node for PM.
+ */
+void acpi_dev_pm_add_dependent(acpi_handle handle, struct device *depdev)
+{
+ struct acpi_device_physical_node *dep;
+ struct acpi_device *adev;
+
+ if (!depdev || acpi_bus_get_device(handle, &adev))
+ return;
+
+ mutex_lock(&adev->physical_node_lock);
+
+ list_for_each_entry(dep, &adev->power_dependent, node)
+ if (dep->dev == depdev)
+ goto out;
+
+ dep = kzalloc(sizeof(*dep), GFP_KERNEL);
+ if (dep) {
+ dep->dev = depdev;
+ list_add_tail(&dep->node, &adev->power_dependent);
+ }
+
+ out:
+ mutex_unlock(&adev->physical_node_lock);
+}
+EXPORT_SYMBOL_GPL(acpi_dev_pm_add_dependent);
+
+/**
+ * acpi_dev_pm_remove_dependent - Remove physical device depending for PM.
+ * @handle: Handle of ACPI device node.
+ * @depdev: Device depending on that node for PM.
+ */
+void acpi_dev_pm_remove_dependent(acpi_handle handle, struct device *depdev)
+{
+ struct acpi_device_physical_node *dep;
+ struct acpi_device *adev;
+
+ if (!depdev || acpi_bus_get_device(handle, &adev))
+ return;
+
+ mutex_lock(&adev->physical_node_lock);
+
+ list_for_each_entry(dep, &adev->power_dependent, node)
+ if (dep->dev == depdev) {
+ list_del(&dep->node);
+ kfree(dep);
+ break;
+ }
+
+ mutex_unlock(&adev->physical_node_lock);
+}
+EXPORT_SYMBOL_GPL(acpi_dev_pm_remove_dependent);