summaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorJohan Hovold <johan@hovoldconsulting.com>2016-01-19 12:51:21 +0100
committerGreg Kroah-Hartman <gregkh@google.com>2016-01-19 12:17:13 -0800
commitb807aa7aa51129b1754e7d17f6a2e30e3c6f7a4b (patch)
tree7cef4e9e6ff0e64a5a9f223396eb272064e82d52 /drivers/staging
parent96a9b9b0eb2c5b9626bdad02c057fb22f133fc86 (diff)
downloadop-kernel-dev-b807aa7aa51129b1754e7d17f6a2e30e3c6f7a4b.zip
op-kernel-dev-b807aa7aa51129b1754e7d17f6a2e30e3c6f7a4b.tar.gz
greybus: control: add bundle-version operation
Add bundle-version operation to fetch the version of the bundle class. Retrieve the bundle version of all bundles when initialising the interface in case the control-protocol version is greater than 0.1. Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Johan Hovold <johan@hovoldconsulting.com> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/greybus/bundle.h4
-rw-r--r--drivers/staging/greybus/control.c51
-rw-r--r--drivers/staging/greybus/control.h3
-rw-r--r--drivers/staging/greybus/greybus_protocols.h10
-rw-r--r--drivers/staging/greybus/interface.c4
5 files changed, 72 insertions, 0 deletions
diff --git a/drivers/staging/greybus/bundle.h b/drivers/staging/greybus/bundle.h
index 682ec32..837682d 100644
--- a/drivers/staging/greybus/bundle.h
+++ b/drivers/staging/greybus/bundle.h
@@ -16,8 +16,12 @@
struct gb_bundle {
struct device dev;
struct gb_interface *intf;
+
u8 id;
u8 class;
+ u8 class_major;
+ u8 class_minor;
+
struct list_head connections;
u8 *state;
diff --git a/drivers/staging/greybus/control.c b/drivers/staging/greybus/control.c
index 3077940..0e50fd4 100644
--- a/drivers/staging/greybus/control.c
+++ b/drivers/staging/greybus/control.c
@@ -54,6 +54,54 @@ int gb_control_get_version(struct gb_control *control)
return 0;
}
+static int gb_control_get_bundle_version(struct gb_control *control,
+ struct gb_bundle *bundle)
+{
+ struct gb_interface *intf = control->connection->intf;
+ struct gb_control_bundle_version_request request;
+ struct gb_control_bundle_version_response response;
+ int ret;
+
+ request.bundle_id = bundle->id;
+
+ ret = gb_operation_sync(control->connection,
+ GB_CONTROL_TYPE_BUNDLE_VERSION,
+ &request, sizeof(request),
+ &response, sizeof(response));
+ if (ret) {
+ dev_err(&intf->dev,
+ "failed to get bundle %u class version: %d\n",
+ bundle->id, ret);
+ return ret;
+ }
+
+ bundle->class_major = response.major;
+ bundle->class_minor = response.minor;
+
+ dev_dbg(&intf->dev, "%s - %u: %u.%u\n", __func__, bundle->id,
+ response.major, response.minor);
+
+ return 0;
+}
+
+int gb_control_get_bundle_versions(struct gb_control *control)
+{
+ struct gb_interface *intf = control->connection->intf;
+ struct gb_bundle *bundle;
+ int ret;
+
+ if (!control->has_bundle_version)
+ return 0;
+
+ list_for_each_entry(bundle, &intf->bundles, links) {
+ ret = gb_control_get_bundle_version(control, bundle);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
/* Get Manifest's size from the interface */
int gb_control_get_manifest_size_operation(struct gb_interface *intf)
{
@@ -170,6 +218,9 @@ int gb_control_enable(struct gb_control *control)
if (ret)
goto err_disable_connection;
+ if (control->protocol_major > 0 || control->protocol_minor > 1)
+ control->has_bundle_version = true;
+
return 0;
err_disable_connection:
diff --git a/drivers/staging/greybus/control.h b/drivers/staging/greybus/control.h
index dd0a2d7..d31e7c6 100644
--- a/drivers/staging/greybus/control.h
+++ b/drivers/staging/greybus/control.h
@@ -15,6 +15,8 @@ struct gb_control {
u8 protocol_major;
u8 protocol_minor;
+
+ bool has_bundle_version;
};
struct gb_control *gb_control_create(struct gb_interface *intf);
@@ -22,6 +24,7 @@ int gb_control_enable(struct gb_control *control);
void gb_control_disable(struct gb_control *control);
void gb_control_destroy(struct gb_control *control);
+int gb_control_get_bundle_versions(struct gb_control *control);
int gb_control_connected_operation(struct gb_control *control, u16 cport_id);
int gb_control_disconnected_operation(struct gb_control *control, u16 cport_id);
int gb_control_get_manifest_size_operation(struct gb_interface *intf);
diff --git a/drivers/staging/greybus/greybus_protocols.h b/drivers/staging/greybus/greybus_protocols.h
index abbb214..84fb6ab 100644
--- a/drivers/staging/greybus/greybus_protocols.h
+++ b/drivers/staging/greybus/greybus_protocols.h
@@ -123,6 +123,7 @@ struct gb_protocol_version_response {
#define GB_CONTROL_TYPE_CONNECTED 0x05
#define GB_CONTROL_TYPE_DISCONNECTED 0x06
#define GB_CONTROL_TYPE_INTERFACE_VERSION 0x0a
+#define GB_CONTROL_TYPE_BUNDLE_VERSION 0x0b
struct gb_control_version_request {
__u8 major;
@@ -134,6 +135,15 @@ struct gb_control_version_response {
__u8 minor;
} __packed;
+struct gb_control_bundle_version_request {
+ __u8 bundle_id;
+} __packed;
+
+struct gb_control_bundle_version_response {
+ __u8 major;
+ __u8 minor;
+} __packed;
+
/* Control protocol manifest get size request has no payload*/
struct gb_control_get_manifest_size_response {
__le16 size;
diff --git a/drivers/staging/greybus/interface.c b/drivers/staging/greybus/interface.c
index c345350..9c05d81 100644
--- a/drivers/staging/greybus/interface.c
+++ b/drivers/staging/greybus/interface.c
@@ -228,6 +228,10 @@ int gb_interface_init(struct gb_interface *intf, u8 device_id)
if (ret)
goto free_manifest;
+ ret = gb_control_get_bundle_versions(intf->control);
+ if (ret)
+ goto free_manifest;
+
/* Register the interface and its bundles. */
ret = device_add(&intf->dev);
if (ret) {
OpenPOWER on IntegriCloud