aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAxel Haslam <[email protected]>2016-07-14 15:13:00 -0500
committerAlex Elder <[email protected]>2016-07-14 16:53:55 -0500
commit993dc992f2e415adf9ddc69476ebaefda6af1043 (patch)
treeaee7fd565e27e2e3e1c9a7f9917781aa11f2a08f
parent22b8708725c20ce57d79e51a7e98628b382420a4 (diff)
greybus: gpio: Add runtime_pm suppourt
Add runtime pm support for the gpio driver. Since there is no remote wakeup support, the module will not suspend as long as a gpio is requested. Maybe an optimization could be made, to allow suspend if all the requested gpios are in output mode, since the bridge should maintain the state of the gpio during suspend. Testing Done: using the test board, let the gpbrige enter standby and request a gpio. Signed-off-by: Axel Haslam <[email protected]> Signed-off-by: David Lin <[email protected]> Reviewed-by: Johan Hovold <[email protected]> Signed-off-by: Alex Elder <[email protected]>
-rw-r--r--drivers/staging/greybus/gpio.c30
1 files changed, 25 insertions, 5 deletions
diff --git a/drivers/staging/greybus/gpio.c b/drivers/staging/greybus/gpio.c
index deae2658c7a8..8fa9998b4c3d 100644
--- a/drivers/staging/greybus/gpio.c
+++ b/drivers/staging/greybus/gpio.c
@@ -66,20 +66,31 @@ static int gb_gpio_line_count_operation(struct gb_gpio_controller *ggc)
static int gb_gpio_activate_operation(struct gb_gpio_controller *ggc, u8 which)
{
struct gb_gpio_activate_request request;
+ struct gbphy_device *gbphy_dev = ggc->gbphy_dev;
int ret;
+ ret = gbphy_runtime_get_sync(gbphy_dev);
+ if (ret)
+ return ret;
+
request.which = which;
ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_ACTIVATE,
&request, sizeof(request), NULL, 0);
- if (!ret)
- ggc->lines[which].active = true;
- return ret;
+ if (ret) {
+ gbphy_runtime_put_autosuspend(gbphy_dev);
+ return ret;
+ }
+
+ ggc->lines[which].active = true;
+
+ return 0;
}
static void gb_gpio_deactivate_operation(struct gb_gpio_controller *ggc,
u8 which)
{
- struct device *dev = &ggc->gbphy_dev->dev;
+ struct gbphy_device *gbphy_dev = ggc->gbphy_dev;
+ struct device *dev = &gbphy_dev->dev;
struct gb_gpio_deactivate_request request;
int ret;
@@ -88,10 +99,13 @@ static void gb_gpio_deactivate_operation(struct gb_gpio_controller *ggc,
&request, sizeof(request), NULL, 0);
if (ret) {
dev_err(dev, "failed to deactivate gpio %u\n", which);
- return;
+ goto out_pm_put;
}
ggc->lines[which].active = false;
+
+out_pm_put:
+ gbphy_runtime_put_autosuspend(gbphy_dev);
}
static int gb_gpio_get_direction_operation(struct gb_gpio_controller *ggc,
@@ -709,6 +723,7 @@ static int gb_gpio_probe(struct gbphy_device *gbphy_dev,
goto exit_gpiochip_remove;
}
+ gbphy_runtime_put_autosuspend(gbphy_dev);
return 0;
exit_gpiochip_remove:
@@ -728,6 +743,11 @@ static void gb_gpio_remove(struct gbphy_device *gbphy_dev)
{
struct gb_gpio_controller *ggc = gb_gbphy_get_data(gbphy_dev);
struct gb_connection *connection = ggc->connection;
+ int ret;
+
+ ret = gbphy_runtime_get_sync(gbphy_dev);
+ if (ret)
+ gbphy_runtime_get_noresume(gbphy_dev);
gb_connection_disable_rx(connection);
gb_gpio_irqchip_remove(ggc);