]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
greybus: svc: add power mode call for link hibernation
authorDavid Lin <dtwlin@google.com>
Fri, 8 Jul 2016 03:07:00 +0000 (22:07 -0500)
committerAlex Elder <elder@linaro.org>
Fri, 8 Jul 2016 19:56:28 +0000 (14:56 -0500)
Due to when using set_power_mode to hibernate a link, it won't trigger a
POWERMODEIND event, hence the hard-coded GB_SVC_SETPWRM_PWR_OK would be
returned and it should also be considered as successful result code for
link hibernation. Therefore, adding this set_power_mode_hibernate
function to separate the two calls in order to check with the correct
result code.

Testing Done:
 - Suspend an Interface and observe no set power mode error.

Signed-off-by: David Lin <dtwlin@google.com>
Reviewed-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Alex Elder <elder@linaro.org>
drivers/staging/greybus/svc.c
drivers/staging/greybus/svc.h

index a46d7fb0139bf60fb74fd05b58418acc11e0c6f0..14bada965dddca4c7378961f8f29ec4da4c48d5a 100644 (file)
@@ -687,6 +687,41 @@ int gb_svc_intf_set_power_mode(struct gb_svc *svc, u8 intf_id, u8 hs_series,
 }
 EXPORT_SYMBOL_GPL(gb_svc_intf_set_power_mode);
 
+int gb_svc_intf_set_power_mode_hibernate(struct gb_svc *svc, u8 intf_id)
+{
+       struct gb_svc_intf_set_pwrm_request request;
+       struct gb_svc_intf_set_pwrm_response response;
+       int ret;
+       u16 result_code;
+
+       memset(&request, 0, sizeof(request));
+
+       request.intf_id = intf_id;
+       request.hs_series = GB_SVC_UNIPRO_HS_SERIES_A;
+       request.tx_mode = GB_SVC_UNIPRO_HIBERNATE_MODE;
+       request.rx_mode = GB_SVC_UNIPRO_HIBERNATE_MODE;
+
+       ret = gb_operation_sync(svc->connection, GB_SVC_TYPE_INTF_SET_PWRM,
+                               &request, sizeof(request),
+                               &response, sizeof(response));
+       if (ret < 0) {
+               dev_err(&svc->dev,
+                       "failed to send set power mode operation to interface %u: %d\n",
+                       intf_id, ret);
+               return ret;
+       }
+
+       result_code = response.result_code;
+       if (result_code != GB_SVC_SETPWRM_PWR_OK) {
+               dev_err(&svc->dev,
+                       "failed to hibernate the link for interface %u: %u\n",
+                       intf_id, result_code);
+               return -EIO;
+       }
+
+       return 0;
+}
+
 int gb_svc_ping(struct gb_svc *svc)
 {
        return gb_operation_sync_timeout(svc->connection, GB_SVC_TYPE_PING,
index 750eaff7d0cdb42f7615f84e9ecd40e17aebd60f..4ab066b90a5b1aad37c9841ef750604d5094a6de 100644 (file)
@@ -84,6 +84,7 @@ int gb_svc_intf_set_power_mode(struct gb_svc *svc, u8 intf_id, u8 hs_series,
                               u8 flags, u32 quirks,
                               struct gb_svc_l2_timer_cfg *local,
                               struct gb_svc_l2_timer_cfg *remote);
+int gb_svc_intf_set_power_mode_hibernate(struct gb_svc *svc, u8 intf_id);
 int gb_svc_ping(struct gb_svc *svc);
 int gb_svc_watchdog_create(struct gb_svc *svc);
 void gb_svc_watchdog_destroy(struct gb_svc *svc);