summaryrefslogtreecommitdiffstats
path: root/drivers/staging/greybus/vibrator.c
diff options
context:
space:
mode:
authorAnn Chen <chen_ann@projectara.com>2016-07-22 15:33:55 +0800
committerGreg Kroah-Hartman <gregkh@google.com>2016-07-22 14:06:39 -0700
commit633e45eaac40406739baae960d2c8abac40dbb83 (patch)
treedb8e976a00d585562bcf41673734f7cd49a5f8c3 /drivers/staging/greybus/vibrator.c
parent553cba82b1ada07c8d29405c4900a66891c06052 (diff)
downloadlinux-633e45eaac40406739baae960d2c8abac40dbb83.tar.bz2
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>
Diffstat (limited to 'drivers/staging/greybus/vibrator.c')
-rw-r--r--drivers/staging/greybus/vibrator.c38
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]);