From 5a53e02eaf223c42c6ca8d9664c1191ea7c2b106 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Sun, 3 Apr 2016 12:18:35 +0530 Subject: greybus: firmware: Rename to bootrom protocol Align with Greybus specifications and rename Firmware Protocol driver as Bootrom Protocol driver. Signed-off-by: Viresh Kumar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/Makefile | 2 +- drivers/staging/greybus/bootrom.c | 382 ++++++++++++++++++++++++++++ drivers/staging/greybus/bootrom.h | 16 ++ drivers/staging/greybus/core.c | 14 +- drivers/staging/greybus/firmware.c | 382 ---------------------------- drivers/staging/greybus/firmware.h | 16 -- drivers/staging/greybus/greybus_manifest.h | 4 +- drivers/staging/greybus/greybus_protocols.h | 80 +++--- 8 files changed, 448 insertions(+), 448 deletions(-) create mode 100644 drivers/staging/greybus/bootrom.c create mode 100644 drivers/staging/greybus/bootrom.h delete mode 100644 drivers/staging/greybus/firmware.c delete mode 100644 drivers/staging/greybus/firmware.h (limited to 'drivers/staging/greybus') diff --git a/drivers/staging/greybus/Makefile b/drivers/staging/greybus/Makefile index ec92891a5773..65259ea9d111 100644 --- a/drivers/staging/greybus/Makefile +++ b/drivers/staging/greybus/Makefile @@ -9,7 +9,7 @@ greybus-y := core.o \ control.o \ svc.o \ svc_watchdog.o \ - firmware.o \ + bootrom.o \ operation.o \ legacy.o diff --git a/drivers/staging/greybus/bootrom.c b/drivers/staging/greybus/bootrom.c new file mode 100644 index 000000000000..3cbe9feff53d --- /dev/null +++ b/drivers/staging/greybus/bootrom.c @@ -0,0 +1,382 @@ +/* + * BOOTROM Greybus driver. + * + * Copyright 2016 Google Inc. + * Copyright 2016 Linaro Ltd. + * + * Released under the GPLv2 only. + */ + +#include + +#include "bootrom.h" +#include "greybus.h" + + +struct gb_bootrom { + struct gb_connection *connection; + const struct firmware *fw; + u8 protocol_major; + u8 protocol_minor; +}; + +static void free_firmware(struct gb_bootrom *bootrom) +{ + release_firmware(bootrom->fw); + bootrom->fw = NULL; +} + +/* + * The es2 chip doesn't have VID/PID programmed into the hardware and we need to + * hack that up to distinguish different modules and their firmware blobs. + * + * This fetches VID/PID (over bootrom protocol) for es2 chip only, when VID/PID + * already sent during hotplug are 0. + * + * Otherwise, we keep intf->vendor_id/product_id same as what's passed + * during hotplug. + */ +static void bootrom_es2_fixup_vid_pid(struct gb_bootrom *bootrom) +{ + struct gb_bootrom_get_vid_pid_response response; + struct gb_connection *connection = bootrom->connection; + struct gb_interface *intf = connection->bundle->intf; + int ret; + + if (!(intf->quirks & GB_INTERFACE_QUIRK_NO_ARA_IDS)) + return; + + ret = gb_operation_sync(connection, GB_BOOTROM_TYPE_GET_VID_PID, + NULL, 0, &response, sizeof(response)); + if (ret) { + dev_err(&connection->bundle->dev, + "Bootrom get vid/pid operation failed (%d)\n", ret); + return; + } + + /* + * 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, "Bootrom got vid (0x%x)/pid (0x%x)\n", + intf->vendor_id, intf->product_id); +} + +/* This returns path of the firmware blob on the disk */ +static int download_firmware(struct gb_bootrom *bootrom, u8 stage) +{ + struct gb_connection *connection = bootrom->connection; + struct gb_interface *intf = connection->bundle->intf; + char firmware_name[48]; + int rc; + + /* Already have a firmware, free it */ + if (bootrom->fw) + free_firmware(bootrom); + + /* + * Create firmware name + * + * XXX Name it properly.. + */ + snprintf(firmware_name, sizeof(firmware_name), + "ara_%08x_%08x_%08x_%08x_%02x.tftf", + intf->ddbl1_manufacturer_id, intf->ddbl1_product_id, + intf->vendor_id, intf->product_id, stage); + + // FIXME: + // Turn to dev_dbg later after everyone has valid bootloaders with good + // ids, but leave this as dev_info for now to make it easier to track + // down "empty" vid/pid modules. + dev_info(&connection->bundle->dev, "Firmware file '%s' requested\n", + firmware_name); + + rc = request_firmware(&bootrom->fw, firmware_name, + &connection->bundle->dev); + if (rc) + dev_err(&connection->bundle->dev, + "Firware request for %s has failed : %d", + firmware_name, rc); + return rc; +} + +static int gb_bootrom_firmware_size_request(struct gb_operation *op) +{ + struct gb_bootrom *bootrom = gb_connection_get_data(op->connection); + struct gb_bootrom_firmware_size_request *size_request = op->request->payload; + struct gb_bootrom_firmware_size_response *size_response; + struct device *dev = &op->connection->bundle->dev; + int ret; + + if (op->request->payload_size != sizeof(*size_request)) { + dev_err(dev, "%s: illegal size of firmware size request (%zu != %zu)\n", + __func__, op->request->payload_size, + sizeof(*size_request)); + return -EINVAL; + } + + ret = download_firmware(bootrom, size_request->stage); + if (ret) { + dev_err(dev, "%s: failed to download firmware (%d)\n", __func__, + ret); + return ret; + } + + if (!gb_operation_response_alloc(op, sizeof(*size_response), + GFP_KERNEL)) { + dev_err(dev, "%s: error allocating response\n", __func__); + free_firmware(bootrom); + return -ENOMEM; + } + + size_response = op->response->payload; + size_response->size = cpu_to_le32(bootrom->fw->size); + + dev_dbg(dev, "%s: firmware size %d bytes\n", __func__, size_response->size); + + return 0; +} + +static int gb_bootrom_get_firmware(struct gb_operation *op) +{ + struct gb_bootrom *bootrom = gb_connection_get_data(op->connection); + const struct firmware *fw = bootrom->fw; + struct gb_bootrom_get_firmware_request *firmware_request; + struct gb_bootrom_get_firmware_response *firmware_response; + struct device *dev = &op->connection->bundle->dev; + unsigned int offset, size; + + if (op->request->payload_size != sizeof(*firmware_request)) { + dev_err(dev, "%s: Illegal size of get firmware request (%zu %zu)\n", + __func__, op->request->payload_size, + sizeof(*firmware_request)); + return -EINVAL; + } + + if (!fw) { + dev_err(dev, "%s: firmware not available\n", __func__); + return -EINVAL; + } + + firmware_request = op->request->payload; + offset = le32_to_cpu(firmware_request->offset); + size = le32_to_cpu(firmware_request->size); + + if (offset >= fw->size || size > fw->size - offset) { + dev_warn(dev, "bad firmware request (offs = %u, size = %u)\n", + offset, size); + return -EINVAL; + } + + if (!gb_operation_response_alloc(op, sizeof(*firmware_response) + size, + GFP_KERNEL)) { + dev_err(dev, "%s: error allocating response\n", __func__); + return -ENOMEM; + } + + firmware_response = op->response->payload; + memcpy(firmware_response->data, fw->data + offset, size); + + dev_dbg(dev, "responding with firmware (offs = %u, size = %u)\n", offset, + size); + + return 0; +} + +static int gb_bootrom_ready_to_boot(struct gb_operation *op) +{ + struct gb_connection *connection = op->connection; + struct gb_bootrom_ready_to_boot_request *rtb_request; + struct device *dev = &connection->bundle->dev; + u8 status; + + if (op->request->payload_size != sizeof(*rtb_request)) { + dev_err(dev, "%s: Illegal size of ready to boot request (%zu %zu)\n", + __func__, op->request->payload_size, + sizeof(*rtb_request)); + return -EINVAL; + } + + rtb_request = op->request->payload; + status = rtb_request->status; + + /* Return error if the blob was invalid */ + if (status == GB_BOOTROM_BOOT_STATUS_INVALID) + return -EINVAL; + + /* + * XXX Should we return error for insecure firmware? + */ + dev_dbg(dev, "ready to boot: 0x%x, 0\n", status); + + return 0; +} + +static int gb_bootrom_request_handler(struct gb_operation *op) +{ + u8 type = op->type; + + switch (type) { + case GB_BOOTROM_TYPE_FIRMWARE_SIZE: + return gb_bootrom_firmware_size_request(op); + case GB_BOOTROM_TYPE_GET_FIRMWARE: + return gb_bootrom_get_firmware(op); + case GB_BOOTROM_TYPE_READY_TO_BOOT: + return gb_bootrom_ready_to_boot(op); + default: + dev_err(&op->connection->bundle->dev, + "unsupported request: %u\n", type); + return -EINVAL; + } +} + +static int gb_bootrom_get_version(struct gb_bootrom *bootrom) +{ + struct gb_bundle *bundle = bootrom->connection->bundle; + struct gb_bootrom_version_request request; + struct gb_bootrom_version_response response; + int ret; + + request.major = GB_BOOTROM_VERSION_MAJOR; + request.minor = GB_BOOTROM_VERSION_MINOR; + + ret = gb_operation_sync(bootrom->connection, + GB_BOOTROM_TYPE_VERSION, + &request, sizeof(request), &response, + sizeof(response)); + if (ret) { + dev_err(&bundle->dev, + "failed to get protocol version: %d\n", + ret); + return ret; + } + + if (response.major > request.major) { + dev_err(&bundle->dev, + "unsupported major protocol version (%u > %u)\n", + response.major, request.major); + return -ENOTSUPP; + } + + bootrom->protocol_major = response.major; + bootrom->protocol_minor = response.minor; + + dev_dbg(&bundle->dev, "%s - %u.%u\n", __func__, response.major, + response.minor); + + return 0; +} + +static int gb_bootrom_probe(struct gb_bundle *bundle, + const struct greybus_bundle_id *id) +{ + struct greybus_descriptor_cport *cport_desc; + struct gb_connection *connection; + struct gb_bootrom *bootrom; + int ret; + + if (bundle->num_cports != 1) + return -ENODEV; + + cport_desc = &bundle->cport_desc[0]; + if (cport_desc->protocol_id != GREYBUS_PROTOCOL_BOOTROM) + return -ENODEV; + + bootrom = kzalloc(sizeof(*bootrom), GFP_KERNEL); + if (!bootrom) + return -ENOMEM; + + connection = gb_connection_create(bundle, + le16_to_cpu(cport_desc->id), + gb_bootrom_request_handler); + if (IS_ERR(connection)) { + ret = PTR_ERR(connection); + goto err_free_bootrom; + } + + gb_connection_set_data(connection, bootrom); + + bootrom->connection = connection; + + greybus_set_drvdata(bundle, bootrom); + + ret = gb_connection_enable_tx(connection); + if (ret) + goto err_connection_destroy; + + ret = gb_bootrom_get_version(bootrom); + if (ret) + goto err_connection_disable; + + bootrom_es2_fixup_vid_pid(bootrom); + + ret = gb_connection_enable(connection); + if (ret) + goto err_connection_disable; + + /* Tell bootrom we're ready. */ + ret = gb_operation_sync(connection, GB_BOOTROM_TYPE_AP_READY, NULL, 0, + NULL, 0); + if (ret) { + dev_err(&connection->bundle->dev, + "failed to send AP READY: %d\n", ret); + goto err_connection_disable; + } + + dev_dbg(&bundle->dev, "AP_READY sent\n"); + + return 0; + +err_connection_disable: + gb_connection_disable(connection); +err_connection_destroy: + gb_connection_destroy(connection); +err_free_bootrom: + kfree(bootrom); + + return ret; +} + +static void gb_bootrom_disconnect(struct gb_bundle *bundle) +{ + struct gb_bootrom *bootrom = greybus_get_drvdata(bundle); + + dev_dbg(&bundle->dev, "%s\n", __func__); + + gb_connection_disable(bootrom->connection); + + /* Release firmware */ + if (bootrom->fw) + free_firmware(bootrom); + + gb_connection_destroy(bootrom->connection); + kfree(bootrom); +} + +static const struct greybus_bundle_id gb_bootrom_id_table[] = { + { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_BOOTROM) }, + { } +}; + +static struct greybus_driver gb_bootrom_driver = { + .name = "bootrom", + .probe = gb_bootrom_probe, + .disconnect = gb_bootrom_disconnect, + .id_table = gb_bootrom_id_table, +}; + +int gb_bootrom_init(void) +{ + return greybus_register(&gb_bootrom_driver); +} + +void gb_bootrom_exit(void) +{ + greybus_deregister(&gb_bootrom_driver); +} diff --git a/drivers/staging/greybus/bootrom.h b/drivers/staging/greybus/bootrom.h new file mode 100644 index 000000000000..fd2d1938ef21 --- /dev/null +++ b/drivers/staging/greybus/bootrom.h @@ -0,0 +1,16 @@ +/* + * Greybus bootrom code + * + * Copyright 2016 Google Inc. + * Copyright 2016 Linaro Ltd. + * + * Released under the GPLv2 only. + */ + +#ifndef __BOOTROM_H +#define __BOOTROM_H + +int gb_bootrom_init(void); +void gb_bootrom_exit(void); + +#endif /* __BOOTROM_H */ diff --git a/drivers/staging/greybus/core.c b/drivers/staging/greybus/core.c index ca7469ee8994..d8680667ca32 100644 --- a/drivers/staging/greybus/core.c +++ b/drivers/staging/greybus/core.c @@ -10,7 +10,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #define CREATE_TRACE_POINTS -#include "firmware.h" +#include "bootrom.h" #include "greybus.h" #include "greybus_trace.h" #include "legacy.h" @@ -243,10 +243,10 @@ static int __init gb_init(void) goto error_operation; } - retval = gb_firmware_init(); + retval = gb_bootrom_init(); if (retval) { - pr_err("gb_firmware_init failed\n"); - goto error_firmware; + pr_err("gb_bootrom_init failed\n"); + goto error_bootrom; } retval = gb_legacy_init(); @@ -258,8 +258,8 @@ static int __init gb_init(void) return 0; /* Success */ error_legacy: - gb_firmware_exit(); -error_firmware: + gb_bootrom_exit(); +error_bootrom: gb_operation_exit(); error_operation: gb_hd_exit(); @@ -275,7 +275,7 @@ module_init(gb_init); static void __exit gb_exit(void) { gb_legacy_exit(); - gb_firmware_exit(); + gb_bootrom_exit(); gb_operation_exit(); gb_hd_exit(); bus_unregister(&greybus_bus_type); diff --git a/drivers/staging/greybus/firmware.c b/drivers/staging/greybus/firmware.c deleted file mode 100644 index b1e373c16440..000000000000 --- a/drivers/staging/greybus/firmware.c +++ /dev/null @@ -1,382 +0,0 @@ -/* - * FIRMWARE Greybus driver. - * - * Copyright 2015 Google Inc. - * Copyright 2015 Linaro Ltd. - * - * Released under the GPLv2 only. - */ - -#include - -#include "firmware.h" -#include "greybus.h" - - -struct gb_firmware { - struct gb_connection *connection; - const struct firmware *fw; - u8 protocol_major; - u8 protocol_minor; -}; - -static void free_firmware(struct gb_firmware *firmware) -{ - release_firmware(firmware->fw); - firmware->fw = NULL; -} - -/* - * The es2 chip doesn't have VID/PID programmed into the hardware and we need to - * hack that up to distinguish different modules and their firmware blobs. - * - * This fetches VID/PID (over firmware protocol) for es2 chip only, when VID/PID - * already sent during hotplug are 0. - * - * Otherwise, we keep intf->vendor_id/product_id same as what's passed - * during hotplug. - */ -static void firmware_es2_fixup_vid_pid(struct gb_firmware *firmware) -{ - struct gb_firmware_get_vid_pid_response response; - struct gb_connection *connection = firmware->connection; - struct gb_interface *intf = connection->bundle->intf; - int ret; - - if (!(intf->quirks & GB_INTERFACE_QUIRK_NO_ARA_IDS)) - return; - - ret = gb_operation_sync(connection, GB_FIRMWARE_TYPE_GET_VID_PID, - NULL, 0, &response, sizeof(response)); - if (ret) { - dev_err(&connection->bundle->dev, - "Firmware get vid/pid operation failed (%d)\n", ret); - return; - } - - /* - * 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", - intf->vendor_id, intf->product_id); -} - -/* This returns path of the firmware blob on the disk */ -static int download_firmware(struct gb_firmware *firmware, u8 stage) -{ - struct gb_connection *connection = firmware->connection; - struct gb_interface *intf = connection->bundle->intf; - char firmware_name[48]; - int rc; - - /* Already have a firmware, free it */ - if (firmware->fw) - free_firmware(firmware); - - /* - * Create firmware name - * - * XXX Name it properly.. - */ - snprintf(firmware_name, sizeof(firmware_name), - "ara_%08x_%08x_%08x_%08x_%02x.tftf", - intf->ddbl1_manufacturer_id, intf->ddbl1_product_id, - intf->vendor_id, intf->product_id, stage); - - // FIXME: - // Turn to dev_dbg later after everyone has valid bootloaders with good - // ids, but leave this as dev_info for now to make it easier to track - // down "empty" vid/pid modules. - dev_info(&connection->bundle->dev, "Firmware file '%s' requested\n", - firmware_name); - - rc = request_firmware(&firmware->fw, firmware_name, - &connection->bundle->dev); - if (rc) - dev_err(&connection->bundle->dev, - "Firware request for %s has failed : %d", - firmware_name, rc); - return rc; -} - -static int gb_firmware_size_request(struct gb_operation *op) -{ - struct gb_firmware *firmware = gb_connection_get_data(op->connection); - struct gb_firmware_size_request *size_request = op->request->payload; - struct gb_firmware_size_response *size_response; - struct device *dev = &op->connection->bundle->dev; - int ret; - - if (op->request->payload_size != sizeof(*size_request)) { - dev_err(dev, "%s: illegal size of firmware size request (%zu != %zu)\n", - __func__, op->request->payload_size, - sizeof(*size_request)); - return -EINVAL; - } - - ret = download_firmware(firmware, size_request->stage); - if (ret) { - dev_err(dev, "%s: failed to download firmware (%d)\n", __func__, - ret); - return ret; - } - - if (!gb_operation_response_alloc(op, sizeof(*size_response), - GFP_KERNEL)) { - dev_err(dev, "%s: error allocating response\n", __func__); - free_firmware(firmware); - return -ENOMEM; - } - - size_response = op->response->payload; - size_response->size = cpu_to_le32(firmware->fw->size); - - dev_dbg(dev, "%s: firmware size %d bytes\n", __func__, size_response->size); - - return 0; -} - -static int gb_firmware_get_firmware(struct gb_operation *op) -{ - struct gb_firmware *firmware = gb_connection_get_data(op->connection); - const struct firmware *fw = firmware->fw; - struct gb_firmware_get_firmware_request *firmware_request; - struct gb_firmware_get_firmware_response *firmware_response; - struct device *dev = &op->connection->bundle->dev; - unsigned int offset, size; - - if (op->request->payload_size != sizeof(*firmware_request)) { - dev_err(dev, "%s: Illegal size of get firmware request (%zu %zu)\n", - __func__, op->request->payload_size, - sizeof(*firmware_request)); - return -EINVAL; - } - - if (!fw) { - dev_err(dev, "%s: firmware not available\n", __func__); - return -EINVAL; - } - - firmware_request = op->request->payload; - offset = le32_to_cpu(firmware_request->offset); - size = le32_to_cpu(firmware_request->size); - - if (offset >= fw->size || size > fw->size - offset) { - dev_warn(dev, "bad firmware request (offs = %u, size = %u)\n", - offset, size); - return -EINVAL; - } - - if (!gb_operation_response_alloc(op, sizeof(*firmware_response) + size, - GFP_KERNEL)) { - dev_err(dev, "%s: error allocating response\n", __func__); - return -ENOMEM; - } - - firmware_response = op->response->payload; - memcpy(firmware_response->data, fw->data + offset, size); - - dev_dbg(dev, "responding with firmware (offs = %u, size = %u)\n", offset, - size); - - return 0; -} - -static int gb_firmware_ready_to_boot(struct gb_operation *op) -{ - struct gb_connection *connection = op->connection; - struct gb_firmware_ready_to_boot_request *rtb_request; - struct device *dev = &connection->bundle->dev; - u8 status; - - if (op->request->payload_size != sizeof(*rtb_request)) { - dev_err(dev, "%s: Illegal size of ready to boot request (%zu %zu)\n", - __func__, op->request->payload_size, - sizeof(*rtb_request)); - return -EINVAL; - } - - rtb_request = op->request->payload; - status = rtb_request->status; - - /* Return error if the blob was invalid */ - if (status == GB_FIRMWARE_BOOT_STATUS_INVALID) - return -EINVAL; - - /* - * XXX Should we return error for insecure firmware? - */ - dev_dbg(dev, "ready to boot: 0x%x, 0\n", status); - - return 0; -} - -static int gb_firmware_request_handler(struct gb_operation *op) -{ - u8 type = op->type; - - switch (type) { - case GB_FIRMWARE_TYPE_FIRMWARE_SIZE: - return gb_firmware_size_request(op); - case GB_FIRMWARE_TYPE_GET_FIRMWARE: - return gb_firmware_get_firmware(op); - case GB_FIRMWARE_TYPE_READY_TO_BOOT: - return gb_firmware_ready_to_boot(op); - default: - dev_err(&op->connection->bundle->dev, - "unsupported request: %u\n", type); - return -EINVAL; - } -} - -static int gb_firmware_get_version(struct gb_firmware *firmware) -{ - struct gb_bundle *bundle = firmware->connection->bundle; - struct gb_firmware_version_request request; - struct gb_firmware_version_response response; - int ret; - - request.major = GB_FIRMWARE_VERSION_MAJOR; - request.minor = GB_FIRMWARE_VERSION_MINOR; - - ret = gb_operation_sync(firmware->connection, - GB_FIRMWARE_TYPE_VERSION, - &request, sizeof(request), &response, - sizeof(response)); - if (ret) { - dev_err(&bundle->dev, - "failed to get protocol version: %d\n", - ret); - return ret; - } - - if (response.major > request.major) { - dev_err(&bundle->dev, - "unsupported major protocol version (%u > %u)\n", - response.major, request.major); - return -ENOTSUPP; - } - - firmware->protocol_major = response.major; - firmware->protocol_minor = response.minor; - - dev_dbg(&bundle->dev, "%s - %u.%u\n", __func__, response.major, - response.minor); - - return 0; -} - -static int gb_firmware_probe(struct gb_bundle *bundle, - const struct greybus_bundle_id *id) -{ - struct greybus_descriptor_cport *cport_desc; - struct gb_connection *connection; - struct gb_firmware *firmware; - int ret; - - if (bundle->num_cports != 1) - return -ENODEV; - - cport_desc = &bundle->cport_desc[0]; - if (cport_desc->protocol_id != GREYBUS_PROTOCOL_FIRMWARE) - return -ENODEV; - - firmware = kzalloc(sizeof(*firmware), GFP_KERNEL); - if (!firmware) - return -ENOMEM; - - connection = gb_connection_create(bundle, - le16_to_cpu(cport_desc->id), - gb_firmware_request_handler); - if (IS_ERR(connection)) { - ret = PTR_ERR(connection); - goto err_free_firmware; - } - - gb_connection_set_data(connection, firmware); - - firmware->connection = connection; - - greybus_set_drvdata(bundle, firmware); - - ret = gb_connection_enable_tx(connection); - if (ret) - goto err_connection_destroy; - - ret = gb_firmware_get_version(firmware); - if (ret) - goto err_connection_disable; - - firmware_es2_fixup_vid_pid(firmware); - - ret = gb_connection_enable(connection); - if (ret) - goto err_connection_disable; - - /* Tell bootrom we're ready. */ - ret = gb_operation_sync(connection, GB_FIRMWARE_TYPE_AP_READY, NULL, 0, - NULL, 0); - if (ret) { - dev_err(&connection->bundle->dev, - "failed to send AP READY: %d\n", ret); - goto err_connection_disable; - } - - dev_dbg(&bundle->dev, "AP_READY sent\n"); - - return 0; - -err_connection_disable: - gb_connection_disable(connection); -err_connection_destroy: - gb_connection_destroy(connection); -err_free_firmware: - kfree(firmware); - - return ret; -} - -static void gb_firmware_disconnect(struct gb_bundle *bundle) -{ - struct gb_firmware *firmware = greybus_get_drvdata(bundle); - - dev_dbg(&bundle->dev, "%s\n", __func__); - - gb_connection_disable(firmware->connection); - - /* Release firmware */ - if (firmware->fw) - free_firmware(firmware); - - gb_connection_destroy(firmware->connection); - kfree(firmware); -} - -static const struct greybus_bundle_id gb_firmware_id_table[] = { - { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_FIRMWARE) }, - { } -}; - -static struct greybus_driver gb_firmware_driver = { - .name = "firmware", - .probe = gb_firmware_probe, - .disconnect = gb_firmware_disconnect, - .id_table = gb_firmware_id_table, -}; - -int gb_firmware_init(void) -{ - return greybus_register(&gb_firmware_driver); -} - -void gb_firmware_exit(void) -{ - greybus_deregister(&gb_firmware_driver); -} diff --git a/drivers/staging/greybus/firmware.h b/drivers/staging/greybus/firmware.h deleted file mode 100644 index f25744c1648e..000000000000 --- a/drivers/staging/greybus/firmware.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Greybus firmware code - * - * Copyright 2015 Google Inc. - * Copyright 2015 Linaro Ltd. - * - * Released under the GPLv2 only. - */ - -#ifndef __FIRMWARE_H -#define __FIRMWARE_H - -int gb_firmware_init(void); -void gb_firmware_exit(void); - -#endif /* __FIRMWARE_H */ diff --git a/drivers/staging/greybus/greybus_manifest.h b/drivers/staging/greybus/greybus_manifest.h index 12b6e74ee345..460fced979a4 100644 --- a/drivers/staging/greybus/greybus_manifest.h +++ b/drivers/staging/greybus/greybus_manifest.h @@ -43,7 +43,7 @@ enum greybus_protocol { GREYBUS_PROTOCOL_AUDIO_MGMT = 0x12, GREYBUS_PROTOCOL_AUDIO_DATA = 0x13, GREYBUS_PROTOCOL_SVC = 0x14, - GREYBUS_PROTOCOL_FIRMWARE = 0x15, + GREYBUS_PROTOCOL_BOOTROM = 0x15, GREYBUS_PROTOCOL_CAMERA_DATA = 0x16, /* ... */ GREYBUS_PROTOCOL_RAW = 0xfe, @@ -72,7 +72,7 @@ enum greybus_class_type { GREYBUS_CLASS_AUDIO = 0x12, /* 0x13 is unused */ /* 0x14 is unused */ - GREYBUS_CLASS_FIRMWARE = 0x15, + GREYBUS_CLASS_BOOTROM = 0x15, /* ... */ GREYBUS_CLASS_RAW = 0xfe, GREYBUS_CLASS_VENDOR = 0xff, diff --git a/drivers/staging/greybus/greybus_protocols.h b/drivers/staging/greybus/greybus_protocols.h index 06888e029473..959ff1b7d8ce 100644 --- a/drivers/staging/greybus/greybus_protocols.h +++ b/drivers/staging/greybus/greybus_protocols.h @@ -212,70 +212,70 @@ struct gb_control_timesync_authoritative_request { #define GB_APB_REQUEST_CPORT_FEAT_EN 0x0b #define GB_APB_REQUEST_CPORT_FEAT_DIS 0x0c -/* Firmware Protocol */ - -/* Version of the Greybus firmware protocol we support */ -#define GB_FIRMWARE_VERSION_MAJOR 0x00 -#define GB_FIRMWARE_VERSION_MINOR 0x01 - -/* Greybus firmware request types */ -#define GB_FIRMWARE_TYPE_VERSION 0x01 -#define GB_FIRMWARE_TYPE_FIRMWARE_SIZE 0x02 -#define GB_FIRMWARE_TYPE_GET_FIRMWARE 0x03 -#define GB_FIRMWARE_TYPE_READY_TO_BOOT 0x04 -#define GB_FIRMWARE_TYPE_AP_READY 0x05 /* Request with no-payload */ -#define GB_FIRMWARE_TYPE_GET_VID_PID 0x06 /* Request with no-payload */ - -/* Greybus firmware boot stages */ -#define GB_FIRMWARE_BOOT_STAGE_ONE 0x01 /* Reserved for the boot ROM */ -#define GB_FIRMWARE_BOOT_STAGE_TWO 0x02 /* Firmware package to be loaded by the boot ROM */ -#define GB_FIRMWARE_BOOT_STAGE_THREE 0x03 /* Module personality package loaded by Stage 2 firmware */ - -/* Greybus firmware ready to boot status */ -#define GB_FIRMWARE_BOOT_STATUS_INVALID 0x00 /* Firmware blob could not be validated */ -#define GB_FIRMWARE_BOOT_STATUS_INSECURE 0x01 /* Firmware blob is valid but insecure */ -#define GB_FIRMWARE_BOOT_STATUS_SECURE 0x02 /* Firmware blob is valid and secure */ - -/* Max firmware data fetch size in bytes */ -#define GB_FIRMWARE_FETCH_MAX 2000 - -struct gb_firmware_version_request { +/* Bootrom Protocol */ + +/* Version of the Greybus bootrom protocol we support */ +#define GB_BOOTROM_VERSION_MAJOR 0x00 +#define GB_BOOTROM_VERSION_MINOR 0x01 + +/* Greybus bootrom request types */ +#define GB_BOOTROM_TYPE_VERSION 0x01 +#define GB_BOOTROM_TYPE_FIRMWARE_SIZE 0x02 +#define GB_BOOTROM_TYPE_GET_FIRMWARE 0x03 +#define GB_BOOTROM_TYPE_READY_TO_BOOT 0x04 +#define GB_BOOTROM_TYPE_AP_READY 0x05 /* Request with no-payload */ +#define GB_BOOTROM_TYPE_GET_VID_PID 0x06 /* Request with no-payload */ + +/* Greybus bootrom boot stages */ +#define GB_BOOTROM_BOOT_STAGE_ONE 0x01 /* Reserved for the boot ROM */ +#define GB_BOOTROM_BOOT_STAGE_TWO 0x02 /* Bootrom package to be loaded by the boot ROM */ +#define GB_BOOTROM_BOOT_STAGE_THREE 0x03 /* Module personality package loaded by Stage 2 firmware */ + +/* Greybus bootrom ready to boot status */ +#define GB_BOOTROM_BOOT_STATUS_INVALID 0x00 /* Firmware blob could not be validated */ +#define GB_BOOTROM_BOOT_STATUS_INSECURE 0x01 /* Firmware blob is valid but insecure */ +#define GB_BOOTROM_BOOT_STATUS_SECURE 0x02 /* Firmware blob is valid and secure */ + +/* Max bootrom data fetch size in bytes */ +#define GB_BOOTROM_FETCH_MAX 2000 + +struct gb_bootrom_version_request { __u8 major; __u8 minor; } __packed; -struct gb_firmware_version_response { +struct gb_bootrom_version_response { __u8 major; __u8 minor; } __packed; -/* Firmware protocol firmware size request/response */ -struct gb_firmware_size_request { +/* Bootrom protocol firmware size request/response */ +struct gb_bootrom_firmware_size_request { __u8 stage; } __packed; -struct gb_firmware_size_response { +struct gb_bootrom_firmware_size_response { __le32 size; } __packed; -/* Firmware protocol get firmware request/response */ -struct gb_firmware_get_firmware_request { +/* Bootrom protocol get firmware request/response */ +struct gb_bootrom_get_firmware_request { __le32 offset; __le32 size; } __packed; -struct gb_firmware_get_firmware_response { +struct gb_bootrom_get_firmware_response { __u8 data[0]; } __packed; -/* Firmware protocol Ready to boot request */ -struct gb_firmware_ready_to_boot_request { +/* Bootrom protocol Ready to boot request */ +struct gb_bootrom_ready_to_boot_request { __u8 status; } __packed; -/* Firmware protocol Ready to boot response has no payload */ +/* Bootrom protocol Ready to boot response has no payload */ -/* Firmware protocol get VID/PID request has no payload */ -struct gb_firmware_get_vid_pid_response { +/* Bootrom protocol get VID/PID request has no payload */ +struct gb_bootrom_get_vid_pid_response { __le32 vendor_id; __le32 product_id; } __packed; -- cgit v1.2.3