summaryrefslogtreecommitdiff
path: root/drivers/staging/greybus/fw-core.c
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@linaro.org>2016-05-14 23:42:21 +0530
committerGreg Kroah-Hartman <gregkh@google.com>2016-05-15 00:23:52 +0200
commit013e665372733fafd08599f0fc58ff5f450e4694 (patch)
treed1e508dfce009d495d3a083e3b73f75d56f12ae0 /drivers/staging/greybus/fw-core.c
parent8502eb3b7870c6a0c53f39caaf5b4c01a22f2a25 (diff)
greybus: fw-management: Add firmware-management protocol driver
This patch adds Firmware Management Protocol support to firmware core, which allows the AP to manage firmware on an Interface. Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Reviewed-by: Jun Li <li_jun@projectara.com> Tested-by: Karthik Ravi Shankar <karthikrs@google.com> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Diffstat (limited to 'drivers/staging/greybus/fw-core.c')
-rw-r--r--drivers/staging/greybus/fw-core.c42
1 files changed, 38 insertions, 4 deletions
diff --git a/drivers/staging/greybus/fw-core.c b/drivers/staging/greybus/fw-core.c
index a6865276855a..0a456c547c52 100644
--- a/drivers/staging/greybus/fw-core.c
+++ b/drivers/staging/greybus/fw-core.c
@@ -17,6 +17,13 @@ struct gb_fw_core {
struct gb_connection *mgmt_connection;
};
+struct gb_connection *to_fw_mgmt_connection(struct device *dev)
+{
+ struct gb_fw_core *fw_core = dev_get_drvdata(dev);
+
+ return fw_core->mgmt_connection;
+}
+
static int gb_fw_core_probe(struct gb_bundle *bundle,
const struct greybus_bundle_id *id)
{
@@ -48,7 +55,7 @@ static int gb_fw_core_probe(struct gb_bundle *bundle,
}
connection = gb_connection_create(bundle, cport_id,
- NULL);
+ gb_fw_mgmt_request_handler);
if (IS_ERR(connection)) {
ret = PTR_ERR(connection);
dev_err(&bundle->dev,
@@ -102,13 +109,23 @@ static int gb_fw_core_probe(struct gb_bundle *bundle,
fw_core->download_connection = NULL;
}
+ ret = gb_fw_mgmt_connection_init(fw_core->mgmt_connection);
+ if (ret) {
+ /* We may still be able to work with the Interface */
+ dev_err(&bundle->dev, "failed to initialize firmware management connection, disable it (%d)\n",
+ ret);
+ goto err_exit_connections;
+ }
+
greybus_set_drvdata(bundle, fw_core);
return 0;
+err_exit_connections:
+ gb_fw_download_connection_exit(fw_core->download_connection);
err_destroy_connections:
- gb_connection_destroy(fw_core->download_connection);
gb_connection_destroy(fw_core->mgmt_connection);
+ gb_connection_destroy(fw_core->download_connection);
err_free_fw_core:
kfree(fw_core);
@@ -119,9 +136,11 @@ static void gb_fw_core_disconnect(struct gb_bundle *bundle)
{
struct gb_fw_core *fw_core = greybus_get_drvdata(bundle);
+ gb_fw_mgmt_connection_exit(fw_core->mgmt_connection);
gb_fw_download_connection_exit(fw_core->download_connection);
- gb_connection_destroy(fw_core->download_connection);
+
gb_connection_destroy(fw_core->mgmt_connection);
+ gb_connection_destroy(fw_core->download_connection);
kfree(fw_core);
}
@@ -140,13 +159,28 @@ static struct greybus_driver gb_fw_core_driver = {
static int fw_core_init(void)
{
- return greybus_register(&gb_fw_core_driver);
+ int ret;
+
+ ret = fw_mgmt_init();
+ if (ret) {
+ pr_err("Failed to initialize fw-mgmt core (%d)\n", ret);
+ return ret;
+ }
+
+ ret = greybus_register(&gb_fw_core_driver);
+ if (ret) {
+ fw_mgmt_exit();
+ return ret;
+ }
+
+ return 0;
}
module_init(fw_core_init);
static void __exit fw_core_exit(void)
{
greybus_deregister(&gb_fw_core_driver);
+ fw_mgmt_exit();
}
module_exit(fw_core_exit);