mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-27 06:34:11 +08:00
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>
This commit is contained in:
parent
05ab5f0daa
commit
9e04fb7b16
@ -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
|
||||
|
123
drivers/staging/greybus/fw-core.c
Normal file
123
drivers/staging/greybus/fw-core.c
Normal 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");
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user