diff options
author | David Lin <dtwlin@google.com> | 2016-07-07 22:07:00 -0500 |
---|---|---|
committer | Alex Elder <elder@linaro.org> | 2016-07-08 14:56:28 -0500 |
commit | 2c8e8841e3b8cea90cc9b7172eebfdf90b06038a (patch) | |
tree | 72cafea7ab5b272759f9d505b89994deadbb1839 /drivers/staging/greybus/control.c | |
parent | 776165481d8ed956ccb92465f97ba727eed53e4c (diff) | |
download | op-kernel-dev-2c8e8841e3b8cea90cc9b7172eebfdf90b06038a.zip op-kernel-dev-2c8e8841e3b8cea90cc9b7172eebfdf90b06038a.tar.gz |
greybus: control: add bundle suspend and resume preparations
Add the AP implementation for the Greybus Control Bundle Suspend
Operation. This Operation is used to request a Bundle to enter the
BUNDLE_SUSPENDED state, all Connections associated with this Bundle must
be closed before issuing this operation.
Add the AP implementation for the Greybus Control Bundle Resume
Operation. This operation request a specific Bundle to transition from
the BUNDLE_SUSPENDED state to the BUNDLE_ACTIVE state.
Signed-off-by: David Lin <dtwlin@google.com>
Reviewed-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Alex Elder <elder@linaro.org>
Diffstat (limited to 'drivers/staging/greybus/control.c')
-rw-r--r-- | drivers/staging/greybus/control.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/drivers/staging/greybus/control.c b/drivers/staging/greybus/control.c index 88e5718..a95c776 100644 --- a/drivers/staging/greybus/control.c +++ b/drivers/staging/greybus/control.c @@ -233,6 +233,71 @@ int gb_control_timesync_authoritative(struct gb_control *control, NULL, 0); } +static int gb_control_bundle_pm_status_map(u8 status) +{ + switch (status) { + case GB_CONTROL_BUNDLE_PM_INVAL: + return -EINVAL; + case GB_CONTROL_BUNDLE_PM_BUSY: + return -EBUSY; + case GB_CONTROL_BUNDLE_PM_NA: + return -ENOMSG; + case GB_CONTROL_BUNDLE_PM_FAIL: + default: + return -EREMOTEIO; + } +} + +int gb_control_bundle_suspend(struct gb_control *control, u8 bundle_id) +{ + struct gb_control_bundle_pm_request request; + struct gb_control_bundle_pm_response response; + int ret; + + request.bundle_id = bundle_id; + ret = gb_operation_sync(control->connection, + GB_CONTROL_TYPE_BUNDLE_SUSPEND, &request, + sizeof(request), &response, sizeof(response)); + if (ret) { + dev_err(&control->dev, + "failed to send bundle suspend: %d\n", ret); + return ret; + } + + if (response.status != GB_CONTROL_BUNDLE_PM_OK) { + dev_err(&control->dev, + "bundle error while suspending: %d\n", response.status); + return gb_control_bundle_pm_status_map(response.status); + } + + return 0; +} + +int gb_control_bundle_resume(struct gb_control *control, u8 bundle_id) +{ + struct gb_control_bundle_pm_request request; + struct gb_control_bundle_pm_response response; + int ret; + + request.bundle_id = bundle_id; + ret = gb_operation_sync(control->connection, + GB_CONTROL_TYPE_BUNDLE_RESUME, &request, + sizeof(request), &response, sizeof(response)); + if (ret) { + dev_err(&control->dev, + "failed to send bundle resume: %d\n", ret); + return ret; + } + + if (response.status != GB_CONTROL_BUNDLE_PM_OK) { + dev_err(&control->dev, + "bundle error while resuming: %d\n", response.status); + return gb_control_bundle_pm_status_map(response.status); + } + + return 0; +} + static ssize_t vendor_string_show(struct device *dev, struct device_attribute *attr, char *buf) { |