Kernel watchdog timeout

Implement kernel watchdog that detects when firmware becomes
unresponsive.

Change-Id: I5c5b58a56a2ce629e1fd7cabae83b61823239ea6
diff --git a/kernel/ethosu_device.c b/kernel/ethosu_device.c
index dfdaa58..f440331 100644
--- a/kernel/ethosu_device.c
+++ b/kernel/ethosu_device.c
@@ -252,6 +252,18 @@
 	return ret;
 }
 
+static void ethosu_watchdog_callback(struct ethosu_watchdog *wdog)
+{
+	struct ethosu_device *edev =
+		container_of(wdog, struct ethosu_device, watchdog);
+
+	mutex_lock(&edev->mutex);
+
+	dev_warn(edev->dev, "Device watchdog timeout");
+
+	mutex_unlock(&edev->mutex);
+}
+
 static int ethosu_open(struct inode *inode,
 		       struct file *file)
 {
@@ -442,11 +454,16 @@
 
 	dma_set_mask_and_coherent(edev->dev, DMA_BIT_MASK(DMA_ADDR_BITS));
 
-	ret = ethosu_mailbox_init(&edev->mailbox, dev, in_queue, out_queue,
-				  ethosu_mbox_rx, edev);
+	ret = ethosu_watchdog_init(&edev->watchdog, dev,
+				   ethosu_watchdog_callback);
 	if (ret)
 		goto release_reserved_mem;
 
+	ret = ethosu_mailbox_init(&edev->mailbox, dev, in_queue, out_queue,
+				  ethosu_mbox_rx, edev, &edev->watchdog);
+	if (ret)
+		goto deinit_watchdog;
+
 	cdev_init(&edev->cdev, &fops);
 	edev->cdev.owner = THIS_MODULE;
 
@@ -476,6 +493,9 @@
 deinit_mailbox:
 	ethosu_mailbox_deinit(&edev->mailbox);
 
+deinit_watchdog:
+	ethosu_watchdog_deinit(&edev->watchdog);
+
 release_reserved_mem:
 	of_reserved_mem_device_release(edev->dev);
 
@@ -485,6 +505,7 @@
 void ethosu_dev_deinit(struct ethosu_device *edev)
 {
 	ethosu_mailbox_deinit(&edev->mailbox);
+	ethosu_watchdog_deinit(&edev->watchdog);
 	device_destroy(edev->class, edev->cdev.dev);
 	cdev_del(&edev->cdev);
 	of_reserved_mem_device_release(edev->dev);