greybus: interface: Receive serial-number on hotplug event

Two exactly same modules can be uniquely identified using module's
serial-number. This patch updates the interface hotplug event to also
receive the serial-number of the module.

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>
diff --git a/drivers/staging/greybus/Documentation/sysfs-bus-greybus b/drivers/staging/greybus/Documentation/sysfs-bus-greybus
index 2cd17c7..0d16d76 100644
--- a/drivers/staging/greybus/Documentation/sysfs-bus-greybus
+++ b/drivers/staging/greybus/Documentation/sysfs-bus-greybus
@@ -37,6 +37,14 @@
 Description:
 		The ID of a Greybus interface.
 
+What:		/sys/bus/greybus/device/N-I/serial_number
+Date:		October 2015
+KernelVersion:	4.XX
+Contact:	Greg Kroah-Hartman <greg@kroah.com>
+Description:
+		Serial Number of the Greybus interface, represented by a 64 bit
+		hexadecimal number.
+
 What:		/sys/bus/greybus/device/N-I/product_id
 Date:		October 2015
 KernelVersion:	4.XX
diff --git a/drivers/staging/greybus/Documentation/sysfs/greybus1/1-2/serial_number b/drivers/staging/greybus/Documentation/sysfs/greybus1/1-2/serial_number
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/drivers/staging/greybus/Documentation/sysfs/greybus1/1-2/serial_number
diff --git a/drivers/staging/greybus/Documentation/sysfs/greybus1/1-4/serial_number b/drivers/staging/greybus/Documentation/sysfs/greybus1/1-4/serial_number
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/drivers/staging/greybus/Documentation/sysfs/greybus1/1-4/serial_number
diff --git a/drivers/staging/greybus/Documentation/sysfs/greybus2/2-3/serial_number b/drivers/staging/greybus/Documentation/sysfs/greybus2/2-3/serial_number
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/drivers/staging/greybus/Documentation/sysfs/greybus2/2-3/serial_number
diff --git a/drivers/staging/greybus/greybus_protocols.h b/drivers/staging/greybus/greybus_protocols.h
index 773e1ab..f66f4d7 100644
--- a/drivers/staging/greybus/greybus_protocols.h
+++ b/drivers/staging/greybus/greybus_protocols.h
@@ -757,6 +757,7 @@
 		__le32	ddbl1_prod_id;
 		__le32	ara_vend_id;
 		__le32	ara_prod_id;
+		__le64	serial_number;
 	} data;
 } __packed;
 /* hotplug response has no payload */
diff --git a/drivers/staging/greybus/interface.c b/drivers/staging/greybus/interface.c
index c4b9e14..69eb788 100644
--- a/drivers/staging/greybus/interface.c
+++ b/drivers/staging/greybus/interface.c
@@ -27,6 +27,7 @@
 gb_interface_attr(product_id, "0x%08x");
 gb_interface_attr(vendor_string, "%s");
 gb_interface_attr(product_string, "%s");
+gb_interface_attr(serial_number, "0x%016llx");
 
 static struct attribute *interface_attrs[] = {
 	&dev_attr_ddbl1_manufacturer_id.attr,
@@ -36,6 +37,7 @@
 	&dev_attr_product_id.attr,
 	&dev_attr_vendor_string.attr,
 	&dev_attr_product_string.attr,
+	&dev_attr_serial_number.attr,
 	NULL,
 };
 ATTRIBUTE_GROUPS(interface);
diff --git a/drivers/staging/greybus/interface.h b/drivers/staging/greybus/interface.h
index d192b74..a1a1f9f 100644
--- a/drivers/staging/greybus/interface.h
+++ b/drivers/staging/greybus/interface.h
@@ -30,6 +30,7 @@
 	u32 ddbl1_product_id;
 	u32 vendor_id;
 	u32 product_id;
+	u64 serial_number;
 
 	struct gb_host_device *hd;
 
diff --git a/drivers/staging/greybus/svc.c b/drivers/staging/greybus/svc.c
index 4178699..fe7bd28 100644
--- a/drivers/staging/greybus/svc.c
+++ b/drivers/staging/greybus/svc.c
@@ -429,6 +429,7 @@
 	intf->ddbl1_product_id = le32_to_cpu(request->data.ddbl1_prod_id);
 	intf->vendor_id = le32_to_cpu(request->data.ara_vend_id);
 	intf->product_id = le32_to_cpu(request->data.ara_prod_id);
+	intf->serial_number = le64_to_cpu(request->data.serial_number);
 
 	ret = gb_svc_read_and_clear_module_boot_status(intf);
 	if (ret) {