Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@ greybus-y := core.o \
		control.o	\
		svc.o		\
		svc_watchdog.o	\
		firmware.o	\
		bootrom.o	\
		operation.o	\
		legacy.o

+85 −85
Original line number Diff line number Diff line
/*
 * 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);
}
+16 −0
Original line number Diff line number Diff line
/*
 * 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 */
+7 −7
Original line number Diff line number Diff line
@@ -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);
+0 −16
Original line number Diff line number Diff line
/*
 * 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 */
Loading