aboutsummaryrefslogtreecommitdiff
path: root/kernel/ethosu_network_info.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/ethosu_network_info.c')
-rw-r--r--kernel/ethosu_network_info.c125
1 files changed, 48 insertions, 77 deletions
diff --git a/kernel/ethosu_network_info.c b/kernel/ethosu_network_info.c
index ebb059c..da95309 100644
--- a/kernel/ethosu_network_info.c
+++ b/kernel/ethosu_network_info.c
@@ -29,37 +29,15 @@
#include "ethosu_mailbox.h"
#include "uapi/ethosu.h"
-/****************************************************************************
- * Functions
- ****************************************************************************/
+#define NETWORK_INFO_RESP_TIMEOUT_MS 3000
-static void ethosu_network_info_destroy(struct kref *kref)
+static inline int ethosu_network_info_send(struct ethosu_network_info *info)
{
- struct ethosu_network_info *info =
- container_of(kref, struct ethosu_network_info, kref);
-
- dev_info(info->edev->dev, "Network info destroy. handle=0x%pK\n", info);
-
- list_del(&info->msg.list);
-
- ethosu_network_put(info->net);
-
- devm_kfree(info->edev->dev, info);
-}
-
-static int ethosu_network_info_send(struct ethosu_network_info *info)
-{
- int ret;
-
/* Send network info request to firmware */
- ret = ethosu_mailbox_network_info_request(&info->edev->mailbox,
- info,
- info->net->buf,
- info->net->index);
- if (ret)
- return ret;
-
- return 0;
+ return ethosu_mailbox_network_info_request(&info->edev->mailbox,
+ &info->msg,
+ info->net->buf,
+ info->net->index);
}
static void ethosu_network_info_fail(struct ethosu_mailbox_msg *msg)
@@ -92,91 +70,84 @@ static int ethosu_network_info_resend(struct ethosu_mailbox_msg *msg)
return 0;
}
-struct ethosu_network_info *ethosu_network_info_create(
- struct ethosu_device *edev,
- struct ethosu_network *net,
- struct ethosu_uapi_network_info *uapi)
+int ethosu_network_info_request(struct ethosu_network *net,
+ struct ethosu_uapi_network_info *uapi)
{
struct ethosu_network_info *info;
int ret;
+ int timeout;
- info = devm_kzalloc(edev->dev, sizeof(*info), GFP_KERNEL);
+ info = devm_kzalloc(net->edev->dev, sizeof(*info), GFP_KERNEL);
if (!info)
- return ERR_PTR(-ENOMEM);
+ return -ENOMEM;
- info->edev = edev;
+ info->edev = net->edev;
info->net = net;
info->uapi = uapi;
- kref_init(&info->kref);
init_completion(&info->done);
info->msg.fail = ethosu_network_info_fail;
info->msg.resend = ethosu_network_info_resend;
- /* Insert network info to network info list */
- list_add(&info->msg.list, &edev->mailbox.pending_list);
+ ret = ethosu_mailbox_register(&info->edev->mailbox, &info->msg);
+ if (ret < 0)
+ goto kfree;
/* Get reference to network */
- ethosu_network_get(net);
+ ethosu_network_get(info->net);
ret = ethosu_network_info_send(info);
if (ret)
- goto put_info;
-
- dev_info(edev->dev, "Network info create. handle=%p\n", info);
-
- return info;
+ goto deregister;
-put_info:
- ethosu_network_info_put(info);
-
- return ERR_PTR(ret);
-}
-
-void ethosu_network_info_get(struct ethosu_network_info *info)
-{
- kref_get(&info->kref);
-}
-
-int ethosu_network_info_put(struct ethosu_network_info *info)
-{
- return kref_put(&info->kref, ethosu_network_info_destroy);
-}
-
-int ethosu_network_info_wait(struct ethosu_network_info *info,
- int timeout_ms)
-{
- int timeout;
+ dev_info(info->edev->dev, "Network info create. Id=%d, handle=0x%p\n\n",
+ info->msg.id, info);
+ /* Unlock the device mutex and wait for completion */
+ mutex_unlock(&info->edev->mutex);
timeout = wait_for_completion_timeout(&info->done,
- msecs_to_jiffies(timeout_ms));
+ msecs_to_jiffies(
+ NETWORK_INFO_RESP_TIMEOUT_MS));
+ mutex_lock(&info->edev->mutex);
- if (!timeout) {
- dev_warn(info->edev->dev,
- "Network info timed out.");
+ if (0 == timeout) {
+ dev_warn(info->edev->dev, "Network info timed out.");
- return -ETIME;
+ ret = -ETIME;
+ goto deregister;
}
- return info->errno;
+deregister:
+ ethosu_mailbox_deregister(&info->edev->mailbox, &info->msg);
+ ethosu_network_put(info->net);
+
+kfree:
+ dev_info(info->edev->dev, "Network info destroy. Id=%d, handle=0x%p\n",
+ info->msg.id, info);
+ devm_kfree(info->edev->dev, info);
+
+ return ret;
}
void ethosu_network_info_rsp(struct ethosu_device *edev,
struct ethosu_core_network_info_rsp *rsp)
{
- struct ethosu_network_info *info =
- (struct ethosu_network_info *)rsp->user_arg;
- uint32_t i;
int ret;
+ int id = (int)rsp->user_arg;
+ struct ethosu_mailbox_msg *msg;
+ struct ethosu_network_info *info;
+ uint32_t i;
- ret = ethosu_mailbox_find(&edev->mailbox, &info->msg);
- if (0 != ret) {
+ msg = ethosu_mailbox_find(&edev->mailbox, id);
+ if (IS_ERR(msg)) {
dev_warn(edev->dev,
- "Handle not found in network info list. handle=0x%p\n",
- info);
+ "Id for network info msg not found. Id=%d\n",
+ id);
return;
}
+ info = container_of(msg, typeof(*info), msg);
+
if (completion_done(&info->done))
return;