summaryrefslogtreecommitdiff
path: root/drivers/thunderbolt/domain.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/thunderbolt/domain.c')
-rw-r--r--drivers/thunderbolt/domain.c42
1 files changed, 41 insertions, 1 deletions
diff --git a/drivers/thunderbolt/domain.c b/drivers/thunderbolt/domain.c
index e377128663e9..092381e2accf 100644
--- a/drivers/thunderbolt/domain.c
+++ b/drivers/thunderbolt/domain.c
@@ -12,6 +12,7 @@
#include <linux/device.h>
#include <linux/idr.h>
#include <linux/module.h>
+#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <linux/random.h>
#include <crypto/hash.h>
@@ -132,6 +133,8 @@ static ssize_t boot_acl_show(struct device *dev, struct device_attribute *attr,
if (!uuids)
return -ENOMEM;
+ pm_runtime_get_sync(&tb->dev);
+
if (mutex_lock_interruptible(&tb->lock)) {
ret = -ERESTARTSYS;
goto out;
@@ -153,7 +156,10 @@ static ssize_t boot_acl_show(struct device *dev, struct device_attribute *attr,
}
out:
+ pm_runtime_mark_last_busy(&tb->dev);
+ pm_runtime_put_autosuspend(&tb->dev);
kfree(uuids);
+
return ret;
}
@@ -208,9 +214,11 @@ static ssize_t boot_acl_store(struct device *dev, struct device_attribute *attr,
goto err_free_acl;
}
+ pm_runtime_get_sync(&tb->dev);
+
if (mutex_lock_interruptible(&tb->lock)) {
ret = -ERESTARTSYS;
- goto err_free_acl;
+ goto err_rpm_put;
}
ret = tb->cm_ops->set_boot_acl(tb, acl, tb->nboot_acl);
if (!ret) {
@@ -219,6 +227,9 @@ static ssize_t boot_acl_store(struct device *dev, struct device_attribute *attr,
}
mutex_unlock(&tb->lock);
+err_rpm_put:
+ pm_runtime_mark_last_busy(&tb->dev);
+ pm_runtime_put_autosuspend(&tb->dev);
err_free_acl:
kfree(acl);
err_free_str:
@@ -430,6 +441,13 @@ int tb_domain_add(struct tb *tb)
/* This starts event processing */
mutex_unlock(&tb->lock);
+ pm_runtime_no_callbacks(&tb->dev);
+ pm_runtime_set_active(&tb->dev);
+ pm_runtime_enable(&tb->dev);
+ pm_runtime_set_autosuspend_delay(&tb->dev, TB_AUTOSUSPEND_DELAY);
+ pm_runtime_mark_last_busy(&tb->dev);
+ pm_runtime_use_autosuspend(&tb->dev);
+
return 0;
err_domain_del:
@@ -518,6 +536,28 @@ void tb_domain_complete(struct tb *tb)
tb->cm_ops->complete(tb);
}
+int tb_domain_runtime_suspend(struct tb *tb)
+{
+ if (tb->cm_ops->runtime_suspend) {
+ int ret = tb->cm_ops->runtime_suspend(tb);
+ if (ret)
+ return ret;
+ }
+ tb_ctl_stop(tb->ctl);
+ return 0;
+}
+
+int tb_domain_runtime_resume(struct tb *tb)
+{
+ tb_ctl_start(tb->ctl);
+ if (tb->cm_ops->runtime_resume) {
+ int ret = tb->cm_ops->runtime_resume(tb);
+ if (ret)
+ return ret;
+ }
+ return 0;
+}
+
/**
* tb_domain_approve_switch() - Approve switch
* @tb: Domain the switch belongs to