Commit d39bf704 authored by Viresh Kumar's avatar Viresh Kumar Committed by Greg Kroah-Hartman
Browse files

greybus: interface: Fetch and expose version of interface's firmware



The version of the currently running firmware on the module is useful
for userspace as it can be used to find if an update is available or
not. This patch fetches interface's version with a new control operation
and exposes the same in userspace.

Signed-off-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: default avatarJohan Hovold <johan@hovoldconsulting.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@google.com>
parent 57c6bcc6
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -73,6 +73,14 @@ Contact: Greg Kroah-Hartman <greg@kroah.com>
Description:
		Vendor ID string of a Greybus interface block.

What:		/sys/bus/greybus/device/N-I/version
Date:		October 2015
KernelVersion:	4.XX
Contact:	Greg Kroah-Hartman <greg@kroah.com>
Description:
		Interface version represented as <16 bit major number>.<16 bit
		minor number>.

What:		/sys/bus/greybus/device/N-I.B
Date:		October 2015
KernelVersion:	4.XX
+29 −0
Original line number Diff line number Diff line
@@ -59,6 +59,35 @@ int gb_control_disconnected_operation(struct gb_control *control, u16 cport_id)
				 sizeof(request), NULL, 0);
}

int gb_control_get_interface_version_operation(struct gb_interface *intf)
{
	struct gb_control_interface_version_response response;
	struct gb_connection *connection = intf->control->connection;
	int ret;

	/* The ES3 bootrom fails to boot if this request it sent to it */
	if (intf->boot_over_unipro)
		return 0;

	ret = gb_operation_sync(connection, GB_CONTROL_TYPE_INTERFACE_VERSION,
				NULL, 0, &response, sizeof(response));
	if (ret) {
		dev_err(&connection->intf->dev,
			"failed to get interface version: %d\n", ret);
		/*
		 * FIXME: Return success until the time we bump version of
		 * control protocol. The interface-version is already set to
		 * 0.0, so no need to update that.
		 */
		return 0;
	}

	intf->version_major = le16_to_cpu(response.major);
	intf->version_minor = le16_to_cpu(response.minor);

	return 0;
}

struct gb_control *gb_control_create(struct gb_interface *intf)
{
	struct gb_control *control;
+1 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ int gb_control_disconnected_operation(struct gb_control *control, u16 cport_id);
int gb_control_get_manifest_size_operation(struct gb_interface *intf);
int gb_control_get_manifest_operation(struct gb_interface *intf, void *manifest,
				      size_t size);
int gb_control_get_interface_version_operation(struct gb_interface *intf);

int gb_control_protocol_init(void);
void gb_control_protocol_exit(void);
+7 −0
Original line number Diff line number Diff line
@@ -125,6 +125,7 @@ struct gb_protocol_version_response {
#define GB_CONTROL_TYPE_GET_MANIFEST		0x04
#define GB_CONTROL_TYPE_CONNECTED		0x05
#define GB_CONTROL_TYPE_DISCONNECTED		0x06
#define GB_CONTROL_TYPE_INTERFACE_VERSION	0x0a

/* Control protocol manifest get size request has no payload*/
struct gb_control_get_manifest_size_response {
@@ -146,6 +147,12 @@ struct gb_control_disconnected_request {
} __packed;
/* Control protocol [dis]connected response has no payload */

/* Control protocol interface version request has no payload */
struct gb_control_interface_version_response {
	__le16			major;
	__le16			minor;
} __packed;


/* Firmware Protocol */

+15 −0
Original line number Diff line number Diff line
@@ -29,6 +29,16 @@ gb_interface_attr(vendor_string, "%s");
gb_interface_attr(product_string, "%s");
gb_interface_attr(serial_number, "0x%016llx");

static ssize_t version_show(struct device *dev, struct device_attribute *attr,
			    char *buf)
{
	struct gb_interface *intf = to_gb_interface(dev);

	return scnprintf(buf, PAGE_SIZE, "%u.%u\n", intf->version_major,
			 intf->version_minor);
}
static DEVICE_ATTR_RO(version);

static struct attribute *interface_attrs[] = {
	&dev_attr_ddbl1_manufacturer_id.attr,
	&dev_attr_ddbl1_product_id.attr,
@@ -38,6 +48,7 @@ static struct attribute *interface_attrs[] = {
	&dev_attr_vendor_string.attr,
	&dev_attr_product_string.attr,
	&dev_attr_serial_number.attr,
	&dev_attr_version.attr,
	NULL,
};
ATTRIBUTE_GROUPS(interface);
@@ -214,6 +225,10 @@ int gb_interface_init(struct gb_interface *intf, u8 device_id)
		goto free_manifest;
	}

	ret = gb_control_get_interface_version_operation(intf);
	if (ret)
		goto free_manifest;

	/* Register the interface and its bundles. */
	ret = device_add(&intf->dev);
	if (ret) {
Loading