greybus: vibrator: integrate runtime pm
authorAnn Chen <chen_ann@projectara.com>
Fri, 22 Jul 2016 07:33:55 +0000 (15:33 +0800)
committerGreg Kroah-Hartman <gregkh@google.com>
Fri, 22 Jul 2016 21:06:39 +0000 (14:06 -0700)
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>
drivers/staging/greybus/vibrator.c

index 33b2bf9..db55839 100644 (file)
@@ -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]);