summaryrefslogtreecommitdiff
path: root/drivers/staging/greybus/core.c
diff options
context:
space:
mode:
authorDavid Lin <dtwlin@google.com>2016-07-14 15:13:00 -0500
committerAlex Elder <elder@linaro.org>2016-07-14 16:53:55 -0500
commit61e13db9cc8945d53f72d4021594ee3be214e667 (patch)
tree29dd0a9dcfedf78e99de80833d65870eab32cae0 /drivers/staging/greybus/core.c
parent30a3bf7b30d86b94ad4fbdcf9cdce1dcf5037c58 (diff)
greybus: bundle: add runtime pm support
This patch adds runtime pm support for the bundle core. Unbound bundle devices are always deactivated. During probe, Runtime PM status is set to enabled and active and the usage count is incremented. If the driver supports runtime PM, it should call pm_runtime_put() in its probe routine and pm_runtime_get_sync() in remove routine as bundle needs to be resume before it can be deactivated. Testing Done: - Check runtime_status of the bundle driver when bundle goes to suspend Signed-off-by: David Lin <dtwlin@google.com> Signed-off-by: Axel Haslam <ahaslam@baylibre.com> Reviewed-by: Johan Hovold <johan@hovoldconsulting.com> Signed-off-by: Alex Elder <elder@linaro.org>
Diffstat (limited to 'drivers/staging/greybus/core.c')
-rw-r--r--drivers/staging/greybus/core.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/drivers/staging/greybus/core.c b/drivers/staging/greybus/core.c
index ca3bad910aae..53d9ba151aeb 100644
--- a/drivers/staging/greybus/core.c
+++ b/drivers/staging/greybus/core.c
@@ -13,6 +13,8 @@
#include "greybus.h"
#include "greybus_trace.h"
+#define GB_BUNDLE_AUTOSUSPEND_MS 3000
+
/* Allow greybus to be disabled at boot if needed */
static bool nogreybus;
#ifdef MODULE
@@ -162,6 +164,12 @@ static int greybus_probe(struct device *dev)
if (!id)
return -ENODEV;
+ retval = pm_runtime_get_sync(&bundle->intf->dev);
+ if (retval < 0) {
+ pm_runtime_put_noidle(&bundle->intf->dev);
+ return retval;
+ }
+
/*
* FIXME: We need to perform error handling on bundle activate call
* below when firmware is ready. We just allow the activate operation to
@@ -169,6 +177,19 @@ static int greybus_probe(struct device *dev)
*/
gb_control_bundle_activate(bundle->intf->control, bundle->id);
+ /*
+ * Unbound bundle devices are always deactivated. During probe, the
+ * Runtime PM is set to enabled and active and the usage count is
+ * incremented. If the driver supports runtime PM, it should call
+ * pm_runtime_put() in its probe routine and pm_runtime_get_sync()
+ * in remove routine.
+ */
+ pm_runtime_set_autosuspend_delay(dev, GB_BUNDLE_AUTOSUSPEND_MS);
+ pm_runtime_use_autosuspend(dev);
+ pm_runtime_get_noresume(dev);
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+
retval = driver->probe(bundle, id);
if (retval) {
/*
@@ -178,11 +199,19 @@ static int greybus_probe(struct device *dev)
gb_control_bundle_deactivate(bundle->intf->control, bundle->id);
+ pm_runtime_disable(dev);
+ pm_runtime_set_suspended(dev);
+ pm_runtime_put_noidle(dev);
+ pm_runtime_dont_use_autosuspend(dev);
+ pm_runtime_put(&bundle->intf->dev);
+
return retval;
}
gb_timesync_schedule_asynchronous(bundle->intf);
+ pm_runtime_put(&bundle->intf->dev);
+
return 0;
}
@@ -191,6 +220,11 @@ static int greybus_remove(struct device *dev)
struct greybus_driver *driver = to_greybus_driver(dev->driver);
struct gb_bundle *bundle = to_gb_bundle(dev);
struct gb_connection *connection;
+ int retval;
+
+ retval = pm_runtime_get_sync(dev);
+ if (retval < 0)
+ dev_err(dev, "failed to resume bundle: %d\n", retval);
/*
* Disable (non-offloaded) connections early in case the interface is
@@ -215,6 +249,12 @@ static int greybus_remove(struct device *dev)
if (!bundle->intf->disconnected)
gb_control_bundle_deactivate(bundle->intf->control, bundle->id);
+ pm_runtime_put_noidle(dev);
+ pm_runtime_disable(dev);
+ pm_runtime_set_suspended(dev);
+ pm_runtime_dont_use_autosuspend(dev);
+ pm_runtime_put_noidle(dev);
+
return 0;
}