[][openwrt][mt7988][tops][Fix L2TP/IPSec deadlock and check if TOPS HW exists]

[Description]
Fix HW issue between tunnel offload engine and crypto offload engine.

Check if TOPS HW exists before bring-up.

Sync from internal dev repo.
Commit-Id <5951d48c0b4fd965d66afddcb322f5244614076f>

[Release-log]
N/A

Change-Id: I132d67e23117f7bd14def1f8d42173eb0b7211f7
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/8023635
diff --git a/package-21.02/kernel/tops/src/init.c b/package-21.02/kernel/tops/src/init.c
index 05a7fe4..62c7806 100644
--- a/package-21.02/kernel/tops/src/init.c
+++ b/package-21.02/kernel/tops/src/init.c
@@ -5,11 +5,13 @@
  * Author: Ren-Ting Wang <ren-ting.wang@mediatek.com>
  */
 
-#include <linux/of.h>
-#include <linux/err.h>
+#include <linux/debugfs.h>
 #include <linux/device.h>
+#include <linux/err.h>
+#include <linux/io.h>
 #include <linux/module.h>
-#include <linux/debugfs.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 
@@ -29,6 +31,8 @@
 #include "tunnel.h"
 #include "wdt.h"
 
+#define EFUSE_TOPS_POWER_OFF		(0xD08)
+
 struct device *tops_dev;
 struct dentry *tops_debugfs_root;
 
@@ -200,8 +204,52 @@
 	},
 };
 
+static int __init mtk_tops_hw_disabled(void)
+{
+	struct platform_device *efuse_pdev;
+	struct device_node *efuse_node;
+	struct resource res;
+	void __iomem *efuse_base;
+	int ret = 0;
+
+	efuse_node = of_find_compatible_node(NULL, NULL, "mediatek,efuse");
+	if (!efuse_node)
+		return -ENODEV;
+
+	efuse_pdev = of_find_device_by_node(efuse_node);
+	if (!efuse_pdev) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	if (of_address_to_resource(efuse_node, 0, &res)) {
+		ret = -ENXIO;
+		goto out;
+	}
+
+	/* since we are not probed yet, we cannot use devm_* API */
+	efuse_base = ioremap(res.start, resource_size(&res));
+	if (!efuse_base) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	if (readl(efuse_base + EFUSE_TOPS_POWER_OFF))
+		ret = -ENODEV;
+
+	iounmap(efuse_base);
+
+out:
+	of_node_put(efuse_node);
+
+	return ret;
+}
+
 static int __init mtk_tops_init(void)
 {
+	if (mtk_tops_hw_disabled())
+		return -ENODEV;
+
 	tops_debugfs_root = debugfs_create_dir("tops", NULL);
 	if (IS_ERR(tops_debugfs_root)) {
 		TOPS_ERR("create tops debugfs root directory failed\n");