diff options
author | Ann Chen <chen_ann@projectara.com> | 2016-07-22 10:33:55 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@google.com> | 2016-07-23 00:06:39 +0300 |
commit | 633e45eaac40406739baae960d2c8abac40dbb83 (patch) | |
tree | db8e976a00d585562bcf41673734f7cd49a5f8c3 | |
parent | 553cba82b1ada07c8d29405c4900a66891c06052 (diff) | |
download | linux-633e45eaac40406739baae960d2c8abac40dbb83.tar.xz |
greybus: vibrator: integrate runtime pm
Integrate greybus drivers with the Linux Kernel RuntimePM framework
for vibrator driver.
Testing Done: AP side (kernel) can control the vibrator driver with
suspend and resume.
Signed-off-by: Ann Chen <chen_ann@projectara.com>
Reviewed-by: David Lin <dtwlin@google.com>
Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
-rw-r--r-- | drivers/staging/greybus/vibrator.c | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/drivers/staging/greybus/vibrator.c b/drivers/staging/greybus/vibrator.c index 33b2bf9c16c8..db5583962101 100644 --- a/drivers/staging/greybus/vibrator.c +++ b/drivers/staging/greybus/vibrator.c @@ -13,6 +13,8 @@ #include <linux/device.h> #include <linux/kdev_t.h> #include <linux/idr.h> +#include <linux/pm_runtime.h> + #include "greybus.h" struct gb_vibrator_device { @@ -32,16 +34,37 @@ struct gb_vibrator_on_request { static int turn_on(struct gb_vibrator_device *vib, u16 timeout_ms) { struct gb_vibrator_on_request request; + struct gb_bundle *bundle = vib->connection->bundle; + int ret; + + ret = gb_pm_runtime_get_sync(bundle); + if (ret) + return ret; request.timeout_ms = cpu_to_le16(timeout_ms); - return gb_operation_sync(vib->connection, GB_VIBRATOR_TYPE_ON, - &request, sizeof(request), NULL, 0); + ret = gb_operation_sync(vib->connection, GB_VIBRATOR_TYPE_ON, + &request, sizeof(request), NULL, 0); + + gb_pm_runtime_put_autosuspend(bundle); + + return ret; } static int turn_off(struct gb_vibrator_device *vib) { - return gb_operation_sync(vib->connection, GB_VIBRATOR_TYPE_OFF, - NULL, 0, NULL, 0); + struct gb_bundle *bundle = vib->connection->bundle; + int ret; + + ret = gb_pm_runtime_get_sync(bundle); + if (ret) + return ret; + + ret = gb_operation_sync(vib->connection, GB_VIBRATOR_TYPE_OFF, + NULL, 0, NULL, 0); + + gb_pm_runtime_put_autosuspend(bundle); + + return ret; } static ssize_t timeout_store(struct device *dev, struct device_attribute *attr, @@ -151,6 +174,8 @@ static int gb_vibrator_probe(struct gb_bundle *bundle, } #endif + gb_pm_runtime_put_autosuspend(bundle); + return 0; err_ida_remove: @@ -168,6 +193,11 @@ err_free_vib: static void gb_vibrator_disconnect(struct gb_bundle *bundle) { struct gb_vibrator_device *vib = greybus_get_drvdata(bundle); + int ret; + + ret = gb_pm_runtime_get_sync(bundle); + if (ret) + gb_pm_runtime_get_noresume(bundle); #if LINUX_VERSION_CODE <= KERNEL_VERSION(3,11,0) sysfs_remove_group(&vib->dev->kobj, vibrator_groups[0]); |