Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <haslam_axel@projectara.com>
Signed-off-by: David Lin <dtwlin@google.com>
Reviewed-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Alex Elder <elder@linaro.org>

authored by

Axel Haslam and committed by
Alex Elder
993dc992 22b87087

+25 -5
+25 -5
drivers/staging/greybus/gpio.c
··· 66 66 static int gb_gpio_activate_operation(struct gb_gpio_controller *ggc, u8 which) 67 67 { 68 68 struct gb_gpio_activate_request request; 69 + struct gbphy_device *gbphy_dev = ggc->gbphy_dev; 69 70 int ret; 71 + 72 + ret = gbphy_runtime_get_sync(gbphy_dev); 73 + if (ret) 74 + return ret; 70 75 71 76 request.which = which; 72 77 ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_ACTIVATE, 73 78 &request, sizeof(request), NULL, 0); 74 - if (!ret) 75 - ggc->lines[which].active = true; 76 - return ret; 79 + if (ret) { 80 + gbphy_runtime_put_autosuspend(gbphy_dev); 81 + return ret; 82 + } 83 + 84 + ggc->lines[which].active = true; 85 + 86 + return 0; 77 87 } 78 88 79 89 static void gb_gpio_deactivate_operation(struct gb_gpio_controller *ggc, 80 90 u8 which) 81 91 { 82 - struct device *dev = &ggc->gbphy_dev->dev; 92 + struct gbphy_device *gbphy_dev = ggc->gbphy_dev; 93 + struct device *dev = &gbphy_dev->dev; 83 94 struct gb_gpio_deactivate_request request; 84 95 int ret; 85 96 ··· 99 88 &request, sizeof(request), NULL, 0); 100 89 if (ret) { 101 90 dev_err(dev, "failed to deactivate gpio %u\n", which); 102 - return; 91 + goto out_pm_put; 103 92 } 104 93 105 94 ggc->lines[which].active = false; 95 + 96 + out_pm_put: 97 + gbphy_runtime_put_autosuspend(gbphy_dev); 106 98 } 107 99 108 100 static int gb_gpio_get_direction_operation(struct gb_gpio_controller *ggc, ··· 723 709 goto exit_gpiochip_remove; 724 710 } 725 711 712 + gbphy_runtime_put_autosuspend(gbphy_dev); 726 713 return 0; 727 714 728 715 exit_gpiochip_remove: ··· 743 728 { 744 729 struct gb_gpio_controller *ggc = gb_gbphy_get_data(gbphy_dev); 745 730 struct gb_connection *connection = ggc->connection; 731 + int ret; 732 + 733 + ret = gbphy_runtime_get_sync(gbphy_dev); 734 + if (ret) 735 + gbphy_runtime_get_noresume(gbphy_dev); 746 736 747 737 gb_connection_disable_rx(connection); 748 738 gb_gpio_irqchip_remove(ggc);