1
0
Fork 0

greybus: firmware: Add firmware management bundle driver

All firmware packages on the Modules or Interfaces are now managed by a
special Firmware Management Protocol. The Interface Manifest shall
at least contain the Firmware Management Bundle and a Firmware
Management Protocol CPort within it.

The bundle may contain additional CPorts based on the extra
functionality required to manage firmware packages.

For example, this is how the Firmware Management Bundle of the Interface
Manifest may look like:

	; Firmware Management Bundle (Bundle 1):
	[bundle-descriptor 1]
	class = 0x16

	; (Mandatory) Firmware Management Protocol on CPort 1
	[cport-descriptor 1]
	bundle = 1
	protocol = 0x18

	; (Optional) Firmware Download Protocol on CPort 2
	[cport-descriptor 2]
	bundle = 1
	protocol = 0x17

	; (Optional) SPI protocol on CPort 3
	[cport-descriptor 3]
	bundle = 1
	protocol = 0x0b

	; (Optional) Component Authentication Protocol (CAP) on CPort 4
	[cport-descriptor 4]
	bundle = 1
	protocol = 0xXX //TBD

This patch adds the basic firmware-management bundle driver, which just
creates a firmware-management connection. Support for individual
protocols will be added separately.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
hifive-unleashed-5.1
Viresh Kumar 2016-04-26 10:20:49 +05:30 committed by Greg Kroah-Hartman
parent 05ab5f0daa
commit 9e04fb7b16
3 changed files with 128 additions and 0 deletions

View File

@ -39,6 +39,7 @@ gb-audio-apbridgea-y := audio_apbridgea.o
gb-audio-manager-y += audio_manager.o
gb-audio-manager-y += audio_manager_module.o
gb-camera-y := camera.o
gb-firmware-y := fw-core.o
obj-m += greybus.o
obj-m += gb-phy.o
@ -60,6 +61,7 @@ endif
obj-m += gb-audio-gb.o
obj-m += gb-audio-apbridgea.o
obj-m += gb-audio-manager.o
obj-m += gb-firmware.o
KERNELVER ?= $(shell uname -r)
KERNELDIR ?= /lib/modules/$(KERNELVER)/build

View File

@ -0,0 +1,123 @@
/*
* Greybus Firmware Core Bundle Driver.
*
* Copyright 2016 Google Inc.
* Copyright 2016 Linaro Ltd.
*
* Released under the GPLv2 only.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/firmware.h>
#include "greybus.h"
struct gb_fw_core {
struct gb_connection *mgmt_connection;
};
static int gb_fw_core_probe(struct gb_bundle *bundle,
const struct greybus_bundle_id *id)
{
struct greybus_descriptor_cport *cport_desc;
struct gb_connection *connection;
struct gb_fw_core *fw_core;
int ret, i;
u16 cport_id;
u8 protocol_id;
fw_core = kzalloc(sizeof(*fw_core), GFP_KERNEL);
if (!fw_core)
return -ENOMEM;
/* Parse CPorts and create connections */
for (i = 0; i < bundle->num_cports; i++) {
cport_desc = &bundle->cport_desc[i];
cport_id = le16_to_cpu(cport_desc->id);
protocol_id = cport_desc->protocol_id;
switch (protocol_id) {
case GREYBUS_PROTOCOL_FW_MANAGEMENT:
/* Disallow multiple Firmware Management CPorts */
if (fw_core->mgmt_connection) {
dev_err(&bundle->dev,
"multiple management CPorts found\n");
ret = -EINVAL;
goto err_destroy_connections;
}
connection = gb_connection_create(bundle, cport_id,
NULL);
if (IS_ERR(connection)) {
ret = PTR_ERR(connection);
dev_err(&bundle->dev,
"failed to create management connection (%d)\n",
ret);
goto err_free_fw_core;
}
fw_core->mgmt_connection = connection;
break;
default:
dev_err(&bundle->dev, "invalid protocol id (0x%02x)\n",
protocol_id);
ret = -EINVAL;
goto err_free_fw_core;
}
}
/* Firmware Management connection is mandatory */
if (!fw_core->mgmt_connection) {
dev_err(&bundle->dev, "missing management connection\n");
ret = -ENODEV;
goto err_free_fw_core;
}
greybus_set_drvdata(bundle, fw_core);
return 0;
err_destroy_connections:
gb_connection_destroy(fw_core->mgmt_connection);
err_free_fw_core:
kfree(fw_core);
return ret;
}
static void gb_fw_core_disconnect(struct gb_bundle *bundle)
{
struct gb_fw_core *fw_core = greybus_get_drvdata(bundle);
gb_connection_destroy(fw_core->mgmt_connection);
kfree(fw_core);
}
static const struct greybus_bundle_id gb_fw_core_id_table[] = {
{ GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_FW_MANAGEMENT) },
{ }
};
static struct greybus_driver gb_fw_core_driver = {
.name = "gb-firmware",
.probe = gb_fw_core_probe,
.disconnect = gb_fw_core_disconnect,
.id_table = gb_fw_core_id_table,
};
static int fw_core_init(void)
{
return greybus_register(&gb_fw_core_driver);
}
module_init(fw_core_init);
static void __exit fw_core_exit(void)
{
greybus_deregister(&gb_fw_core_driver);
}
module_exit(fw_core_exit);
MODULE_ALIAS("greybus:firmware");
MODULE_AUTHOR("Viresh Kumar <viresh.kumar@linaro.org>");
MODULE_DESCRIPTION("Greybus Firmware Bundle Driver");
MODULE_LICENSE("GPL v2");

View File

@ -45,6 +45,8 @@ enum greybus_protocol {
GREYBUS_PROTOCOL_SVC = 0x14,
GREYBUS_PROTOCOL_BOOTROM = 0x15,
GREYBUS_PROTOCOL_CAMERA_DATA = 0x16,
GREYBUS_PROTOCOL_FW_DOWNLOAD = 0x17,
GREYBUS_PROTOCOL_FW_MANAGEMENT = 0x18,
/* ... */
GREYBUS_PROTOCOL_RAW = 0xfe,
GREYBUS_PROTOCOL_VENDOR = 0xff,
@ -73,6 +75,7 @@ enum greybus_class_type {
/* 0x13 is unused */
/* 0x14 is unused */
GREYBUS_CLASS_BOOTROM = 0x15,
GREYBUS_CLASS_FW_MANAGEMENT = 0x16,
/* ... */
GREYBUS_CLASS_RAW = 0xfe,
GREYBUS_CLASS_VENDOR = 0xff,