Commit f3e6c097 authored by Viresh Kumar's avatar Viresh Kumar Committed by Greg Kroah-Hartman

greybus: svc: Expose and retain VID/PID received from bootrom for ES2

ES2 chips doesn't have efuses for storing module's vendor_id and
product_id and so we have hacked bootrom earlier using firmware
protocol, so that VID/PID can be received for fetching firmware
packages.

Another requirement is to expose them to sysfs, so that modules can be
identified properly.

That can be easily solved by updating interface's VID/PID, when fetched
using firmware protocol and later reusing them while the module switches
its identity from bootrom to firmware.

Do that only if the module is ES2 and the VID/PID sent during hotplug
are both 0.
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 fd7c28eb
...@@ -14,8 +14,6 @@ ...@@ -14,8 +14,6 @@
struct gb_firmware { struct gb_firmware {
struct gb_connection *connection; struct gb_connection *connection;
const struct firmware *fw; const struct firmware *fw;
u32 vendor_id;
u32 product_id;
}; };
static void free_firmware(struct gb_firmware *firmware) static void free_firmware(struct gb_firmware *firmware)
...@@ -31,7 +29,7 @@ static void free_firmware(struct gb_firmware *firmware) ...@@ -31,7 +29,7 @@ static void free_firmware(struct gb_firmware *firmware)
* This fetches VID/PID (over firmware protocol) for es2 chip only, when VID/PID * This fetches VID/PID (over firmware protocol) for es2 chip only, when VID/PID
* already sent during hotplug are 0. * already sent during hotplug are 0.
* *
* Otherwise, we keep firmware->vendor_id/product_id same as what's passed * Otherwise, we keep intf->vendor_id/product_id same as what's passed
* during hotplug. * during hotplug.
*/ */
static void firmware_es2_fixup_vid_pid(struct gb_firmware *firmware) static void firmware_es2_fixup_vid_pid(struct gb_firmware *firmware)
...@@ -59,11 +57,18 @@ static void firmware_es2_fixup_vid_pid(struct gb_firmware *firmware) ...@@ -59,11 +57,18 @@ static void firmware_es2_fixup_vid_pid(struct gb_firmware *firmware)
return; return;
} }
firmware->vendor_id = le32_to_cpu(response.vendor_id); /*
firmware->product_id = le32_to_cpu(response.product_id); * NOTE: This is hacked, so that the same values of VID/PID can be used
* by next firmware level as well. The uevent for bootrom will still
* have VID/PID as 0, though after this point the sysfs files will start
* showing the updated values. But yeah, that's a bit racy as the same
* sysfs files would be showing 0 before this point.
*/
intf->vendor_id = le32_to_cpu(response.vendor_id);
intf->product_id = le32_to_cpu(response.product_id);
dev_dbg(&connection->bundle->dev, "Firmware got vid (0x%x)/pid (0x%x)\n", dev_dbg(&connection->bundle->dev, "Firmware got vid (0x%x)/pid (0x%x)\n",
firmware->vendor_id, firmware->product_id); intf->vendor_id, intf->product_id);
} }
/* This returns path of the firmware blob on the disk */ /* This returns path of the firmware blob on the disk */
...@@ -86,7 +91,7 @@ static int download_firmware(struct gb_firmware *firmware, u8 stage) ...@@ -86,7 +91,7 @@ static int download_firmware(struct gb_firmware *firmware, u8 stage)
snprintf(firmware_name, sizeof(firmware_name), snprintf(firmware_name, sizeof(firmware_name),
"ara_%08x_%08x_%08x_%08x_%02x.tftf", "ara_%08x_%08x_%08x_%08x_%02x.tftf",
intf->ddbl1_manufacturer_id, intf->ddbl1_product_id, intf->ddbl1_manufacturer_id, intf->ddbl1_product_id,
firmware->vendor_id, firmware->product_id, stage); intf->vendor_id, intf->product_id, stage);
// FIXME: // FIXME:
// Turn to dev_dbg later after everyone has valid bootloaders with good // Turn to dev_dbg later after everyone has valid bootloaders with good
...@@ -246,9 +251,6 @@ static int gb_firmware_connection_init(struct gb_connection *connection) ...@@ -246,9 +251,6 @@ static int gb_firmware_connection_init(struct gb_connection *connection)
firmware->connection = connection; firmware->connection = connection;
connection->private = firmware; connection->private = firmware;
firmware->vendor_id = connection->intf->vendor_id;
firmware->product_id = connection->intf->product_id;
firmware_es2_fixup_vid_pid(firmware); firmware_es2_fixup_vid_pid(firmware);
/* Tell bootrom we're ready. */ /* Tell bootrom we're ready. */
......
...@@ -464,6 +464,8 @@ static void gb_svc_process_intf_hotplug(struct gb_operation *operation) ...@@ -464,6 +464,8 @@ static void gb_svc_process_intf_hotplug(struct gb_operation *operation)
struct gb_host_device *hd = connection->hd; struct gb_host_device *hd = connection->hd;
struct gb_interface *intf; struct gb_interface *intf;
u8 intf_id, device_id; u8 intf_id, device_id;
u32 vendor_id = 0;
u32 product_id = 0;
int ret; int ret;
/* The request message size has already been verified. */ /* The request message size has already been verified. */
...@@ -474,6 +476,14 @@ static void gb_svc_process_intf_hotplug(struct gb_operation *operation) ...@@ -474,6 +476,14 @@ static void gb_svc_process_intf_hotplug(struct gb_operation *operation)
intf = gb_interface_find(hd, intf_id); intf = gb_interface_find(hd, intf_id);
if (intf) { if (intf) {
/*
* For ES2, we need to maintain the same vendor/product ids we
* got from bootrom, otherwise userspace can't distinguish
* between modules.
*/
vendor_id = intf->vendor_id;
product_id = intf->product_id;
/* /*
* We have received a hotplug request for an interface that * We have received a hotplug request for an interface that
* already exists. * already exists.
...@@ -506,6 +516,20 @@ static void gb_svc_process_intf_hotplug(struct gb_operation *operation) ...@@ -506,6 +516,20 @@ static void gb_svc_process_intf_hotplug(struct gb_operation *operation)
intf->product_id = le32_to_cpu(request->data.ara_prod_id); intf->product_id = le32_to_cpu(request->data.ara_prod_id);
intf->serial_number = le64_to_cpu(request->data.serial_number); intf->serial_number = le64_to_cpu(request->data.serial_number);
/*
* Use VID/PID specified at hotplug if:
* - Bridge ASIC chip isn't ES2
* - Received non-zero Vendor/Product ids
*
* Otherwise, use the ids we received from bootrom.
*/
if (intf->ddbl1_manufacturer_id == ES2_DDBL1_MFR_ID &&
intf->ddbl1_product_id == ES2_DDBL1_PROD_ID &&
intf->vendor_id == 0 && intf->product_id == 0) {
intf->vendor_id = vendor_id;
intf->product_id = product_id;
}
ret = gb_svc_read_and_clear_module_boot_status(intf); ret = gb_svc_read_and_clear_module_boot_status(intf);
if (ret) { if (ret) {
dev_err(&svc->dev, "failed to clear boot status of interface %u: %d\n", dev_err(&svc->dev, "failed to clear boot status of interface %u: %d\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment