aboutsummaryrefslogtreecommitdiff
path: root/kernel/ethosu_mailbox.c
diff options
context:
space:
mode:
authorKristofer Jonsson <kristofer.jonsson@arm.com>2022-03-17 17:15:52 +0100
committerKristofer Jonsson <kristofer.jonsson@arm.com>2022-04-04 15:34:47 +0200
commit442fefb74a28307cfcd009723504ea5ac1353430 (patch)
treee22c128b2888de206d84c48f19e4d268f782d10e /kernel/ethosu_mailbox.c
parentf5b98c965c51def4f63d7fb198f70180e195b2e8 (diff)
downloadethos-u-linux-driver-stack-442fefb74a28307cfcd009723504ea5ac1353430.tar.gz
Reset firmware
Reset the firmware if it becomes unresponsive. Use ping to send keep alive requests. Only monitor ping and inference request messages. The other messages pass no resources to the firmware and can be cancelled without resetting the firmware. Change-Id: Ifbcc370f02d79a64f25598f11376a1dc84a7a066
Diffstat (limited to 'kernel/ethosu_mailbox.c')
-rw-r--r--kernel/ethosu_mailbox.c96
1 files changed, 89 insertions, 7 deletions
diff --git a/kernel/ethosu_mailbox.c b/kernel/ethosu_mailbox.c
index 7753baa..7355361 100644
--- a/kernel/ethosu_mailbox.c
+++ b/kernel/ethosu_mailbox.c
@@ -23,16 +23,29 @@
****************************************************************************/
#include "ethosu_mailbox.h"
-#include "ethosu_watchdog.h"
#include "ethosu_buffer.h"
#include "ethosu_core_interface.h"
#include "ethosu_device.h"
+#include "ethosu_watchdog.h"
+#include <linux/jiffies.h>
#include <linux/resource.h>
#include <linux/uio.h>
/****************************************************************************
+ * Includes
+ ****************************************************************************/
+
+#ifndef fallthrough
+#if __has_attribute(__fallthrough__)
+#define fallthrough __attribute__((__fallthrough__))
+#else
+#define fallthrough do {} while (0) /* fallthrough */
+#endif
+#endif
+
+/****************************************************************************
* Functions
****************************************************************************/
@@ -41,10 +54,9 @@ static void ethosu_wd_inc(struct ethosu_mailbox *mbox,
{
switch (type) {
case ETHOSU_CORE_MSG_PING:
+ mbox->ping_count++;
+ fallthrough;
case ETHOSU_CORE_MSG_INFERENCE_REQ:
- case ETHOSU_CORE_MSG_VERSION_REQ:
- case ETHOSU_CORE_MSG_CAPABILITIES_REQ:
- case ETHOSU_CORE_MSG_NETWORK_INFO_REQ:
ethosu_watchdog_inc(mbox->wdog);
break;
default:
@@ -57,10 +69,9 @@ static void ethosu_wd_dec(struct ethosu_mailbox *mbox,
{
switch (type) {
case ETHOSU_CORE_MSG_PONG:
+ mbox->ping_count--;
+ fallthrough;
case ETHOSU_CORE_MSG_INFERENCE_RSP:
- case ETHOSU_CORE_MSG_VERSION_RSP:
- case ETHOSU_CORE_MSG_CAPABILITIES_RSP:
- case ETHOSU_CORE_MSG_NETWORK_INFO_RSP:
ethosu_watchdog_dec(mbox->wdog);
break;
default:
@@ -190,6 +201,36 @@ void ethosu_mailbox_reset(struct ethosu_mailbox *mbox)
mbox->out_queue->header.read = mbox->out_queue->header.write;
}
+void ethosu_mailbox_wait_prepare(struct ethosu_mailbox *mbox)
+{
+ mbox->in_queue->header.size = 0;
+ mbox->in_queue->header.read = 0xffffff;
+ mbox->in_queue->header.write = 0xffffff;
+}
+
+int ethosu_mailbox_wait_firmware(struct ethosu_mailbox *mbox)
+{
+ const unsigned long timeout = 1000;
+ const unsigned long end = jiffies + msecs_to_jiffies(timeout);
+ volatile struct ethosu_core_queue_header *hdr =
+ &mbox->in_queue->header;
+ int ret = -ETIMEDOUT;
+
+ /* Spin wait on mailbox initialization */
+ while ((end - jiffies) < timeout)
+ if (hdr->size != 0 &&
+ hdr->read != 0xffffff &&
+ hdr->write != 0xffffff) {
+ ret = 0;
+ break;
+ }
+
+ dev_info(mbox->dev, "mbox: Wait. ret=%d, size=%u, read=%u, write=%u",
+ ret, hdr->size, hdr->read, hdr->write);
+
+ return ret;
+}
+
int ethosu_mailbox_read(struct ethosu_mailbox *mbox,
struct ethosu_core_msg *header,
void *data,
@@ -241,6 +282,45 @@ int ethosu_mailbox_read(struct ethosu_mailbox *mbox,
return 0;
}
+int ethosu_mailbox_find(struct ethosu_mailbox *mbox,
+ struct ethosu_mailbox_msg *msg)
+{
+ struct ethosu_mailbox_msg *cur;
+
+ list_for_each_entry(cur, &mbox->pending_list, list) {
+ if (cur == msg)
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+void ethosu_mailbox_fail(struct ethosu_mailbox *mbox)
+{
+ struct ethosu_mailbox_msg *cur, *cur_tmp;
+
+ list_for_each_entry_safe(cur, cur_tmp, &mbox->pending_list, list) {
+ cur->fail(cur);
+ }
+}
+
+int ethosu_mailbox_resend(struct ethosu_mailbox *mbox)
+{
+ struct ethosu_mailbox_msg *cur, *cur_tmp;
+ int ret;
+
+ list_for_each_entry_safe(cur, cur_tmp, &mbox->pending_list, list) {
+ ret = cur->resend(cur);
+ if (ret) {
+ cur->fail(cur);
+
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
int ethosu_mailbox_ping(struct ethosu_mailbox *mbox)
{
return ethosu_queue_write_msg(mbox, ETHOSU_CORE_MSG_PING, NULL, 0);
@@ -380,6 +460,8 @@ int ethosu_mailbox_init(struct ethosu_mailbox *mbox,
mbox->callback = callback;
mbox->user_arg = user_arg;
mbox->wdog = wdog;
+ mbox->ping_count = 0;
+ INIT_LIST_HEAD(&mbox->pending_list);
mbox->client.dev = dev;
mbox->client.rx_callback = ethosu_mailbox_rx_callback;