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

greybus: firmware: Rename to bootrom protocol

Align with Greybus specifications and rename Firmware Protocol driver as
Bootrom Protocol driver.
Signed-off-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@google.com>
parent 0c35631b
......@@ -9,7 +9,7 @@ greybus-y := core.o \
control.o \
svc.o \
svc_watchdog.o \
firmware.o \
bootrom.o \
operation.o \
legacy.o
......
/*
* FIRMWARE Greybus driver.
* BOOTROM Greybus driver.
*
* Copyright 2015 Google Inc.
* Copyright 2015 Linaro Ltd.
* Copyright 2016 Google Inc.
* Copyright 2016 Linaro Ltd.
*
* Released under the GPLv2 only.
*/
#include <linux/firmware.h>
#include "firmware.h"
#include "bootrom.h"
#include "greybus.h"
struct gb_firmware {
struct gb_bootrom {
struct gb_connection *connection;
const struct firmware *fw;
u8 protocol_major;
u8 protocol_minor;
};
static void free_firmware(struct gb_firmware *firmware)
static void free_firmware(struct gb_bootrom *bootrom)
{
release_firmware(firmware->fw);
firmware->fw = NULL;
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 firmware protocol) for es2 chip only, when VID/PID
* 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 firmware_es2_fixup_vid_pid(struct gb_firmware *firmware)
static void bootrom_es2_fixup_vid_pid(struct gb_bootrom *bootrom)
{
struct gb_firmware_get_vid_pid_response response;
struct gb_connection *connection = firmware->connection;
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_FIRMWARE_TYPE_GET_VID_PID,
ret = gb_operation_sync(connection, GB_BOOTROM_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);
"Bootrom get vid/pid operation failed (%d)\n", ret);
return;
}
......@@ -64,21 +64,21 @@ static void firmware_es2_fixup_vid_pid(struct gb_firmware *firmware)
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, "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_firmware *firmware, u8 stage)
static int download_firmware(struct gb_bootrom *bootrom, u8 stage)
{
struct gb_connection *connection = firmware->connection;
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 (firmware->fw)
free_firmware(firmware);
if (bootrom->fw)
free_firmware(bootrom);
/*
* Create firmware name
......@@ -97,7 +97,7 @@ static int download_firmware(struct gb_firmware *firmware, u8 stage)
dev_info(&connection->bundle->dev, "Firmware file '%s' requested\n",
firmware_name);
rc = request_firmware(&firmware->fw, firmware_name,
rc = request_firmware(&bootrom->fw, firmware_name,
&connection->bundle->dev);
if (rc)
dev_err(&connection->bundle->dev,
......@@ -106,11 +106,11 @@ static int download_firmware(struct gb_firmware *firmware, u8 stage)
return rc;
}
static int gb_firmware_size_request(struct gb_operation *op)
static int gb_bootrom_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 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;
......@@ -121,7 +121,7 @@ static int gb_firmware_size_request(struct gb_operation *op)
return -EINVAL;
}
ret = download_firmware(firmware, size_request->stage);
ret = download_firmware(bootrom, size_request->stage);
if (ret) {
dev_err(dev, "%s: failed to download firmware (%d)\n", __func__,
ret);
......@@ -131,24 +131,24 @@ static int gb_firmware_size_request(struct gb_operation *op)
if (!gb_operation_response_alloc(op, sizeof(*size_response),
GFP_KERNEL)) {
dev_err(dev, "%s: error allocating response\n", __func__);
free_firmware(firmware);
free_firmware(bootrom);
return -ENOMEM;
}
size_response = op->response->payload;
size_response->size = cpu_to_le32(firmware->fw->size);
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_firmware_get_firmware(struct gb_operation *op)
static int gb_bootrom_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 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;
......@@ -189,10 +189,10 @@ static int gb_firmware_get_firmware(struct gb_operation *op)
return 0;
}
static int gb_firmware_ready_to_boot(struct gb_operation *op)
static int gb_bootrom_ready_to_boot(struct gb_operation *op)
{
struct gb_connection *connection = op->connection;
struct gb_firmware_ready_to_boot_request *rtb_request;
struct gb_bootrom_ready_to_boot_request *rtb_request;
struct device *dev = &connection->bundle->dev;
u8 status;
......@@ -207,7 +207,7 @@ static int gb_firmware_ready_to_boot(struct gb_operation *op)
status = rtb_request->status;
/* Return error if the blob was invalid */
if (status == GB_FIRMWARE_BOOT_STATUS_INVALID)
if (status == GB_BOOTROM_BOOT_STATUS_INVALID)
return -EINVAL;
/*
......@@ -218,17 +218,17 @@ static int gb_firmware_ready_to_boot(struct gb_operation *op)
return 0;
}
static int gb_firmware_request_handler(struct gb_operation *op)
static int gb_bootrom_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);
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);
......@@ -236,18 +236,18 @@ static int gb_firmware_request_handler(struct gb_operation *op)
}
}
static int gb_firmware_get_version(struct gb_firmware *firmware)
static int gb_bootrom_get_version(struct gb_bootrom *bootrom)
{
struct gb_bundle *bundle = firmware->connection->bundle;
struct gb_firmware_version_request request;
struct gb_firmware_version_response response;
struct gb_bundle *bundle = bootrom->connection->bundle;
struct gb_bootrom_version_request request;
struct gb_bootrom_version_response response;
int ret;
request.major = GB_FIRMWARE_VERSION_MAJOR;
request.minor = GB_FIRMWARE_VERSION_MINOR;
request.major = GB_BOOTROM_VERSION_MAJOR;
request.minor = GB_BOOTROM_VERSION_MINOR;
ret = gb_operation_sync(firmware->connection,
GB_FIRMWARE_TYPE_VERSION,
ret = gb_operation_sync(bootrom->connection,
GB_BOOTROM_TYPE_VERSION,
&request, sizeof(request), &response,
sizeof(response));
if (ret) {
......@@ -264,8 +264,8 @@ static int gb_firmware_get_version(struct gb_firmware *firmware)
return -ENOTSUPP;
}
firmware->protocol_major = response.major;
firmware->protocol_minor = response.minor;
bootrom->protocol_major = response.major;
bootrom->protocol_minor = response.minor;
dev_dbg(&bundle->dev, "%s - %u.%u\n", __func__, response.major,
response.minor);
......@@ -273,55 +273,55 @@ static int gb_firmware_get_version(struct gb_firmware *firmware)
return 0;
}
static int gb_firmware_probe(struct gb_bundle *bundle,
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_firmware *firmware;
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_FIRMWARE)
if (cport_desc->protocol_id != GREYBUS_PROTOCOL_BOOTROM)
return -ENODEV;
firmware = kzalloc(sizeof(*firmware), GFP_KERNEL);
if (!firmware)
bootrom = kzalloc(sizeof(*bootrom), GFP_KERNEL);
if (!bootrom)
return -ENOMEM;
connection = gb_connection_create(bundle,
le16_to_cpu(cport_desc->id),
gb_firmware_request_handler);
gb_bootrom_request_handler);
if (IS_ERR(connection)) {
ret = PTR_ERR(connection);
goto err_free_firmware;
goto err_free_bootrom;
}
gb_connection_set_data(connection, firmware);
gb_connection_set_data(connection, bootrom);
firmware->connection = connection;
bootrom->connection = connection;
greybus_set_drvdata(bundle, firmware);
greybus_set_drvdata(bundle, bootrom);
ret = gb_connection_enable_tx(connection);
if (ret)
goto err_connection_destroy;
ret = gb_firmware_get_version(firmware);
ret = gb_bootrom_get_version(bootrom);
if (ret)
goto err_connection_disable;
firmware_es2_fixup_vid_pid(firmware);
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_FIRMWARE_TYPE_AP_READY, NULL, 0,
ret = gb_operation_sync(connection, GB_BOOTROM_TYPE_AP_READY, NULL, 0,
NULL, 0);
if (ret) {
dev_err(&connection->bundle->dev,
......@@ -337,46 +337,46 @@ static int gb_firmware_probe(struct gb_bundle *bundle,
gb_connection_disable(connection);
err_connection_destroy:
gb_connection_destroy(connection);
err_free_firmware:
kfree(firmware);
err_free_bootrom:
kfree(bootrom);
return ret;
}
static void gb_firmware_disconnect(struct gb_bundle *bundle)
static void gb_bootrom_disconnect(struct gb_bundle *bundle)
{
struct gb_firmware *firmware = greybus_get_drvdata(bundle);
struct gb_bootrom *bootrom = greybus_get_drvdata(bundle);
dev_dbg(&bundle->dev, "%s\n", __func__);
gb_connection_disable(firmware->connection);
gb_connection_disable(bootrom->connection);
/* Release firmware */
if (firmware->fw)
free_firmware(firmware);
if (bootrom->fw)
free_firmware(bootrom);
gb_connection_destroy(firmware->connection);
kfree(firmware);
gb_connection_destroy(bootrom->connection);
kfree(bootrom);
}
static const struct greybus_bundle_id gb_firmware_id_table[] = {
{ GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_FIRMWARE) },
static const struct greybus_bundle_id gb_bootrom_id_table[] = {
{ GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_BOOTROM) },
{ }
};
static struct greybus_driver gb_firmware_driver = {
.name = "firmware",
.probe = gb_firmware_probe,
.disconnect = gb_firmware_disconnect,
.id_table = gb_firmware_id_table,
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_firmware_init(void)
int gb_bootrom_init(void)
{
return greybus_register(&gb_firmware_driver);
return greybus_register(&gb_bootrom_driver);
}
void gb_firmware_exit(void)
void gb_bootrom_exit(void)
{
greybus_deregister(&gb_firmware_driver);
greybus_deregister(&gb_bootrom_driver);
}
/*
* 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 */
......@@ -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);
......
/*
* 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 */
......@@ -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,
......
......@@ -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;
......
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