diff options
Diffstat (limited to 'drivers/thunderbolt/domain.c')
-rw-r--r-- | drivers/thunderbolt/domain.c | 55 |
1 files changed, 41 insertions, 14 deletions
diff --git a/drivers/thunderbolt/domain.c b/drivers/thunderbolt/domain.c index a923ebdeb73c..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: @@ -509,26 +527,35 @@ int tb_domain_resume_noirq(struct tb *tb) int tb_domain_suspend(struct tb *tb) { - int ret; + return tb->cm_ops->suspend ? tb->cm_ops->suspend(tb) : 0; +} - mutex_lock(&tb->lock); - if (tb->cm_ops->suspend) { - ret = tb->cm_ops->suspend(tb); - if (ret) { - mutex_unlock(&tb->lock); +void tb_domain_complete(struct tb *tb) +{ + if (tb->cm_ops->complete) + 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; - } } - mutex_unlock(&tb->lock); + tb_ctl_stop(tb->ctl); return 0; } -void tb_domain_complete(struct tb *tb) +int tb_domain_runtime_resume(struct tb *tb) { - mutex_lock(&tb->lock); - if (tb->cm_ops->complete) - tb->cm_ops->complete(tb); - mutex_unlock(&tb->lock); + 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; } /** |