1
0
Fork 0

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: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
hifive-unleashed-5.1
Viresh Kumar 2015-12-28 11:59:01 +05:30 committed by Greg Kroah-Hartman
parent 57c6bcc635
commit d39bf704ac
6 changed files with 63 additions and 0 deletions

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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 */

View File

@ -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) {

View File

@ -32,6 +32,9 @@ struct gb_interface {
u32 product_id;
u64 serial_number;
u16 version_major;
u16 version_minor;
struct gb_host_device *hd;
/* The interface needs to boot over unipro */