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 | |
parent | 776165481d8ed956ccb92465f97ba727eed53e4c (diff) |
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')
-rw-r--r-- | drivers/staging/greybus/control.c | 65 | ||||
-rw-r--r-- | drivers/staging/greybus/control.h | 3 | ||||
-rw-r--r-- | drivers/staging/greybus/greybus_protocols.h | 21 |
3 files changed, 88 insertions, 1 deletions
diff --git a/drivers/staging/greybus/control.c b/drivers/staging/greybus/control.c index 88e5718965d6..a95c776f17a1 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) { diff --git a/drivers/staging/greybus/control.h b/drivers/staging/greybus/control.h index b1e5af25352a..c7f34635ea92 100644 --- a/drivers/staging/greybus/control.h +++ b/drivers/staging/greybus/control.h @@ -52,5 +52,6 @@ int gb_control_timesync_get_last_event(struct gb_control *control, u64 *frame_time); int gb_control_timesync_authoritative(struct gb_control *control, u64 *frame_time); - +int gb_control_bundle_suspend(struct gb_control *control, u8 bundle_id); +int gb_control_bundle_resume(struct gb_control *control, u8 bundle_id); #endif /* __CONTROL_H */ diff --git a/drivers/staging/greybus/greybus_protocols.h b/drivers/staging/greybus/greybus_protocols.h index 0043b912f720..3b6fd0268529 100644 --- a/drivers/staging/greybus/greybus_protocols.h +++ b/drivers/staging/greybus/greybus_protocols.h @@ -126,6 +126,8 @@ struct gb_protocol_version_response { #define GB_CONTROL_TYPE_DISCONNECTING 0x0c #define GB_CONTROL_TYPE_TIMESYNC_GET_LAST_EVENT 0x0d #define GB_CONTROL_TYPE_MODE_SWITCH 0x0e +#define GB_CONTROL_TYPE_BUNDLE_SUSPEND 0x0f +#define GB_CONTROL_TYPE_BUNDLE_RESUME 0x10 struct gb_control_version_request { __u8 major; @@ -191,6 +193,25 @@ struct gb_control_timesync_get_last_event_response { __le64 frame_time; } __packed; +/* + * All Bundle power management operations use the same request and response + * layout and status codes. + */ + +#define GB_CONTROL_BUNDLE_PM_OK 0x00 +#define GB_CONTROL_BUNDLE_PM_INVAL 0x01 +#define GB_CONTROL_BUNDLE_PM_BUSY 0x02 +#define GB_CONTROL_BUNDLE_PM_FAIL 0x03 +#define GB_CONTROL_BUNDLE_PM_NA 0x04 + +struct gb_control_bundle_pm_request { + __u8 bundle_id; +} __packed; + +struct gb_control_bundle_pm_response { + __u8 status; +} __packed; + /* APBridge protocol */ /* request APB1 log */ |