airoha: an7581: replace TRNG patch with upstream version
authorChristian Marangi <ansuelsmth@gmail.com>
Mon, 28 Oct 2024 13:01:52 +0000 (14:01 +0100)
committerChristian Marangi <ansuelsmth@gmail.com>
Mon, 28 Oct 2024 13:01:52 +0000 (14:01 +0100)
Replace TRNG patch with upstream version.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
target/linux/airoha/patches-6.6/030-v6.13-hwrng-airoha-add-support-for-Airoha-EN7581-TRNG.patch [new file with mode: 0644]
target/linux/airoha/patches-6.6/102-hwrng-add-support-for-Airoha-EN7581-TRNG.patch [deleted file]

diff --git a/target/linux/airoha/patches-6.6/030-v6.13-hwrng-airoha-add-support-for-Airoha-EN7581-TRNG.patch b/target/linux/airoha/patches-6.6/030-v6.13-hwrng-airoha-add-support-for-Airoha-EN7581-TRNG.patch
new file mode 100644 (file)
index 0000000..e21fb56
--- /dev/null
@@ -0,0 +1,306 @@
+From 5c5db81bff81a0fcd9ad998543d4241cbfe4742f Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Thu, 17 Oct 2024 14:44:38 +0200
+Subject: [PATCH 2/2] hwrng: airoha - add support for Airoha EN7581 TRNG
+
+Add support for Airoha TRNG. The Airoha SoC provide a True RNG module
+that can output 4 bytes of raw data at times.
+
+The module makes use of various noise source to provide True Random
+Number Generation.
+
+On probe the module is reset to operate Health Test and verify correct
+execution of it.
+
+The module can also provide DRBG function but the execution mode is
+mutually exclusive, running as TRNG doesn't permit to also run it as
+DRBG.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+Reviewed-by: Martin Kaiser <martin@kaiser.cx>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+---
+ drivers/char/hw_random/Kconfig       |  13 ++
+ drivers/char/hw_random/Makefile      |   1 +
+ drivers/char/hw_random/airoha-trng.c | 243 +++++++++++++++++++++++++++
+ 3 files changed, 257 insertions(+)
+ create mode 100644 drivers/char/hw_random/airoha-trng.c
+
+--- a/drivers/char/hw_random/Kconfig
++++ b/drivers/char/hw_random/Kconfig
+@@ -62,6 +62,19 @@ config HW_RANDOM_AMD
+         If unsure, say Y.
++config HW_RANDOM_AIROHA
++      tristate "Airoha True HW Random Number Generator support"
++      depends on ARCH_AIROHA || COMPILE_TEST
++      default HW_RANDOM
++      help
++        This driver provides kernel-side support for the True Random Number
++        Generator hardware found on Airoha SoC.
++
++        To compile this driver as a module, choose M here: the
++        module will be called airoha-rng.
++
++        If unsure, say Y.
++
+ config HW_RANDOM_ATMEL
+       tristate "Atmel Random Number Generator support"
+       depends on (ARCH_AT91 || COMPILE_TEST)
+--- a/drivers/char/hw_random/Makefile
++++ b/drivers/char/hw_random/Makefile
+@@ -8,6 +8,7 @@ rng-core-y := core.o
+ obj-$(CONFIG_HW_RANDOM_TIMERIOMEM) += timeriomem-rng.o
+ obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o
+ obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o
++obj-$(CONFIG_HW_RANDOM_AIROHA) += airoha-trng.o
+ obj-$(CONFIG_HW_RANDOM_ATMEL) += atmel-rng.o
+ obj-$(CONFIG_HW_RANDOM_BA431) += ba431-rng.o
+ obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o
+--- /dev/null
++++ b/drivers/char/hw_random/airoha-trng.c
+@@ -0,0 +1,243 @@
++// SPDX-License-Identifier: GPL-2.0
++/* Copyright (C) 2024 Christian Marangi */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/mod_devicetable.h>
++#include <linux/bitfield.h>
++#include <linux/delay.h>
++#include <linux/hw_random.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/iopoll.h>
++#include <linux/platform_device.h>
++
++#define TRNG_IP_RDY                   0x800
++#define   CNT_TRANS                   GENMASK(15, 8)
++#define   SAMPLE_RDY                  BIT(0)
++#define TRNG_NS_SEK_AND_DAT_EN                0x804
++#define         RNG_EN                        BIT(31) /* referenced as ring_en */
++#define         RAW_DATA_EN                   BIT(16)
++#define TRNG_HEALTH_TEST_SW_RST               0x808
++#define   SW_RST                      BIT(0) /* Active High */
++#define TRNG_INTR_EN                  0x818
++#define   INTR_MASK                   BIT(16)
++#define   CONTINUOUS_HEALTH_INITR_EN  BIT(2)
++#define   SW_STARTUP_INITR_EN         BIT(1)
++#define   RST_STARTUP_INITR_EN                BIT(0)
++/* Notice that Health Test are done only out of Reset and with RNG_EN */
++#define TRNG_HEALTH_TEST_STATUS               0x824
++#define   CONTINUOUS_HEALTH_AP_TEST_FAIL BIT(23)
++#define   CONTINUOUS_HEALTH_RC_TEST_FAIL BIT(22)
++#define   SW_STARTUP_TEST_DONE                BIT(21)
++#define   SW_STARTUP_AP_TEST_FAIL     BIT(20)
++#define   SW_STARTUP_RC_TEST_FAIL     BIT(19)
++#define   RST_STARTUP_TEST_DONE               BIT(18)
++#define   RST_STARTUP_AP_TEST_FAIL    BIT(17)
++#define   RST_STARTUP_RC_TEST_FAIL    BIT(16)
++#define   RAW_DATA_VALID              BIT(7)
++
++#define TRNG_RAW_DATA_OUT             0x828
++
++#define TRNG_CNT_TRANS_VALID          0x80
++#define BUSY_LOOP_SLEEP                       10
++#define BUSY_LOOP_TIMEOUT             (BUSY_LOOP_SLEEP * 10000)
++
++struct airoha_trng {
++      void __iomem *base;
++      struct hwrng rng;
++      struct device *dev;
++
++      struct completion rng_op_done;
++};
++
++static int airoha_trng_irq_mask(struct airoha_trng *trng)
++{
++      u32 val;
++
++      val = readl(trng->base + TRNG_INTR_EN);
++      val |= INTR_MASK;
++      writel(val, trng->base + TRNG_INTR_EN);
++
++      return 0;
++}
++
++static int airoha_trng_irq_unmask(struct airoha_trng *trng)
++{
++      u32 val;
++
++      val = readl(trng->base + TRNG_INTR_EN);
++      val &= ~INTR_MASK;
++      writel(val, trng->base + TRNG_INTR_EN);
++
++      return 0;
++}
++
++static int airoha_trng_init(struct hwrng *rng)
++{
++      struct airoha_trng *trng = container_of(rng, struct airoha_trng, rng);
++      int ret;
++      u32 val;
++
++      val = readl(trng->base + TRNG_NS_SEK_AND_DAT_EN);
++      val |= RNG_EN;
++      writel(val, trng->base + TRNG_NS_SEK_AND_DAT_EN);
++
++      /* Set out of SW Reset */
++      airoha_trng_irq_unmask(trng);
++      writel(0, trng->base + TRNG_HEALTH_TEST_SW_RST);
++
++      ret = wait_for_completion_timeout(&trng->rng_op_done, BUSY_LOOP_TIMEOUT);
++      if (ret <= 0) {
++              dev_err(trng->dev, "Timeout waiting for Health Check\n");
++              airoha_trng_irq_mask(trng);
++              return -ENODEV;
++      }
++
++      /* Check if Health Test Failed */
++      val = readl(trng->base + TRNG_HEALTH_TEST_STATUS);
++      if (val & (RST_STARTUP_AP_TEST_FAIL | RST_STARTUP_RC_TEST_FAIL)) {
++              dev_err(trng->dev, "Health Check fail: %s test fail\n",
++                      val & RST_STARTUP_AP_TEST_FAIL ? "AP" : "RC");
++              return -ENODEV;
++      }
++
++      /* Check if IP is ready */
++      ret = readl_poll_timeout(trng->base + TRNG_IP_RDY, val,
++                               val & SAMPLE_RDY, 10, 1000);
++      if (ret < 0) {
++              dev_err(trng->dev, "Timeout waiting for IP ready");
++              return -ENODEV;
++      }
++
++      /* CNT_TRANS must be 0x80 for IP to be considered ready */
++      ret = readl_poll_timeout(trng->base + TRNG_IP_RDY, val,
++                               FIELD_GET(CNT_TRANS, val) == TRNG_CNT_TRANS_VALID,
++                               10, 1000);
++      if (ret < 0) {
++              dev_err(trng->dev, "Timeout waiting for IP ready");
++              return -ENODEV;
++      }
++
++      return 0;
++}
++
++static void airoha_trng_cleanup(struct hwrng *rng)
++{
++      struct airoha_trng *trng = container_of(rng, struct airoha_trng, rng);
++      u32 val;
++
++      val = readl(trng->base + TRNG_NS_SEK_AND_DAT_EN);
++      val &= ~RNG_EN;
++      writel(val, trng->base + TRNG_NS_SEK_AND_DAT_EN);
++
++      /* Put it in SW Reset */
++      writel(SW_RST, trng->base + TRNG_HEALTH_TEST_SW_RST);
++}
++
++static int airoha_trng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
++{
++      struct airoha_trng *trng = container_of(rng, struct airoha_trng, rng);
++      u32 *data = buf;
++      u32 status;
++      int ret;
++
++      ret = readl_poll_timeout(trng->base + TRNG_HEALTH_TEST_STATUS, status,
++                               status & RAW_DATA_VALID, 10, 1000);
++      if (ret < 0) {
++              dev_err(trng->dev, "Timeout waiting for TRNG RAW Data valid\n");
++              return ret;
++      }
++
++      *data = readl(trng->base + TRNG_RAW_DATA_OUT);
++
++      return 4;
++}
++
++static irqreturn_t airoha_trng_irq(int irq, void *priv)
++{
++      struct airoha_trng *trng = (struct airoha_trng *)priv;
++
++      airoha_trng_irq_mask(trng);
++      /* Just complete the task, we will read the value later */
++      complete(&trng->rng_op_done);
++
++      return IRQ_HANDLED;
++}
++
++static int airoha_trng_probe(struct platform_device *pdev)
++{
++      struct device *dev = &pdev->dev;
++      struct airoha_trng *trng;
++      int irq, ret;
++      u32 val;
++
++      trng = devm_kzalloc(dev, sizeof(*trng), GFP_KERNEL);
++      if (!trng)
++              return -ENOMEM;
++
++      trng->base = devm_platform_ioremap_resource(pdev, 0);
++      if (IS_ERR(trng->base))
++              return PTR_ERR(trng->base);
++
++      irq = platform_get_irq(pdev, 0);
++      if (irq < 0)
++              return irq;
++
++      airoha_trng_irq_mask(trng);
++      ret = devm_request_irq(&pdev->dev, irq, airoha_trng_irq, 0,
++                             pdev->name, (void *)trng);
++      if (ret) {
++              dev_err(dev, "Can't get interrupt working.\n");
++              return ret;
++      }
++
++      init_completion(&trng->rng_op_done);
++
++      /* Enable interrupt for SW reset Health Check */
++      val = readl(trng->base + TRNG_INTR_EN);
++      val |= RST_STARTUP_INITR_EN;
++      writel(val, trng->base + TRNG_INTR_EN);
++
++      /* Set output to raw data */
++      val = readl(trng->base + TRNG_NS_SEK_AND_DAT_EN);
++      val |= RAW_DATA_EN;
++      writel(val, trng->base + TRNG_NS_SEK_AND_DAT_EN);
++
++      /* Put it in SW Reset */
++      writel(SW_RST, trng->base + TRNG_HEALTH_TEST_SW_RST);
++
++      trng->dev = dev;
++      trng->rng.name = pdev->name;
++      trng->rng.init = airoha_trng_init;
++      trng->rng.cleanup = airoha_trng_cleanup;
++      trng->rng.read = airoha_trng_read;
++
++      ret = devm_hwrng_register(dev, &trng->rng);
++      if (ret) {
++              dev_err(dev, "failed to register rng device: %d\n", ret);
++              return ret;
++      }
++
++      return 0;
++}
++
++static const struct of_device_id airoha_trng_of_match[] = {
++      { .compatible = "airoha,en7581-trng", },
++      {},
++};
++MODULE_DEVICE_TABLE(of, airoha_trng_of_match);
++
++static struct platform_driver airoha_trng_driver = {
++      .driver = {
++              .name = "airoha-trng",
++              .of_match_table = airoha_trng_of_match,
++      },
++      .probe = airoha_trng_probe,
++};
++
++module_platform_driver(airoha_trng_driver);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>");
++MODULE_DESCRIPTION("Airoha True Random Number Generator driver");
diff --git a/target/linux/airoha/patches-6.6/102-hwrng-add-support-for-Airoha-EN7581-TRNG.patch b/target/linux/airoha/patches-6.6/102-hwrng-add-support-for-Airoha-EN7581-TRNG.patch
deleted file mode 100644 (file)
index 1c99369..0000000
+++ /dev/null
@@ -1,304 +0,0 @@
-From 9dbd16ac89e00bd8640ecac3971b0943410b5cec Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Sat, 6 Jul 2024 01:15:24 +0200
-Subject: [PATCH 2/2] hwrng: add support for Airoha EN7581 TRNG
-
-Add support for Airoha TRNG. The Airoha SoC provide a True RNG module
-that can output 4 bytes of raw data at times.
-
-The module makes use of various noise source to provide True Random
-Number Generation.
-
-On probe the module is reset to operate Health Test and verify correct
-execution of it.
-
-The module can also provide DRBG function but the execution mode is
-mutually exclusive, running as TRNG doesn't permit to also run it as
-DRBG.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- drivers/char/hw_random/Kconfig       |  13 ++
- drivers/char/hw_random/Makefile      |   1 +
- drivers/char/hw_random/airoha-trng.c | 243 +++++++++++++++++++++++++++
- 3 files changed, 257 insertions(+)
- create mode 100644 drivers/char/hw_random/airoha-trng.c
-
---- a/drivers/char/hw_random/Kconfig
-+++ b/drivers/char/hw_random/Kconfig
-@@ -62,6 +62,19 @@ config HW_RANDOM_AMD
-         If unsure, say Y.
-+config HW_RANDOM_AIROHA
-+      tristate "Airoha True HW Random Number Generator support"
-+      depends on ARCH_AIROHA || COMPILE_TEST
-+      default HW_RANDOM
-+      help
-+        This driver provides kernel-side support for the True Random Number
-+        Generator hardware found on Airoha SoC.
-+
-+        To compile this driver as a module, choose M here: the
-+        module will be called airoha-rng.
-+
-+        If unsure, say Y.
-+
- config HW_RANDOM_ATMEL
-       tristate "Atmel Random Number Generator support"
-       depends on (ARCH_AT91 || COMPILE_TEST)
---- a/drivers/char/hw_random/Makefile
-+++ b/drivers/char/hw_random/Makefile
-@@ -8,6 +8,7 @@ rng-core-y := core.o
- obj-$(CONFIG_HW_RANDOM_TIMERIOMEM) += timeriomem-rng.o
- obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o
- obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o
-+obj-$(CONFIG_HW_RANDOM_AIROHA) += airoha-trng.o
- obj-$(CONFIG_HW_RANDOM_ATMEL) += atmel-rng.o
- obj-$(CONFIG_HW_RANDOM_BA431) += ba431-rng.o
- obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o
---- /dev/null
-+++ b/drivers/char/hw_random/airoha-trng.c
-@@ -0,0 +1,243 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/* Copyright (C) 2024 Christian Marangi */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/mod_devicetable.h>
-+#include <linux/err.h>
-+#include <linux/io.h>
-+#include <linux/iopoll.h>
-+#include <linux/interrupt.h>
-+#include <linux/hw_random.h>
-+#include <linux/platform_device.h>
-+#include <linux/delay.h>
-+
-+#define TRNG_IP_RDY                   0x800
-+#define   CNT_TRANS                   GENMASK(15, 8)
-+#define   SAMPLE_RDY                  BIT(0)
-+#define TRNG_NS_SEK_AND_DAT_EN                0x804
-+#define         RNG_EN                        BIT(31) /* referenced as ring_en */
-+#define         RAW_DATA_EN                   BIT(16)
-+#define TRNG_HEALTH_TEST_SW_RST               0x808
-+#define   SW_RST                      BIT(0) /* Active High */
-+#define TRNG_INTR_EN                  0x818
-+#define   INTR_MASK                   BIT(16)
-+#define   CONTINUOUS_HEALTH_INITR_EN  BIT(2)
-+#define   SW_STARTUP_INITR_EN         BIT(1)
-+#define   RST_STARTUP_INITR_EN                BIT(0)
-+/* Notice that Health Test are done only out of Reset and with RNG_EN */
-+#define TRNG_HEALTH_TEST_STATUS               0x824
-+#define   CONTINUOUS_HEALTH_AP_TEST_FAIL BIT(23)
-+#define   CONTINUOUS_HEALTH_RC_TEST_FAIL BIT(22)
-+#define   SW_STARTUP_TEST_DONE                BIT(21)
-+#define   SW_STARTUP_AP_TEST_FAIL     BIT(20)
-+#define   SW_STARTUP_RC_TEST_FAIL     BIT(19)
-+#define   RST_STARTUP_TEST_DONE               BIT(18)
-+#define   RST_STARTUP_AP_TEST_FAIL    BIT(17)
-+#define   RST_STARTUP_RC_TEST_FAIL    BIT(16)
-+#define   RAW_DATA_VALID              BIT(7)
-+
-+#define TRNG_RAW_DATA_OUT             0x828
-+
-+#define TRNG_CNT_TRANS_VALID          0x80
-+#define BUSY_LOOP_SLEEP                       10
-+#define BUSY_LOOP_TIMEOUT             (BUSY_LOOP_SLEEP * 10000)
-+
-+struct airoha_trng {
-+      void __iomem *base;
-+      struct hwrng rng;
-+      struct device *dev;
-+
-+      struct completion rng_op_done;
-+};
-+
-+static int airoha_trng_irq_mask(struct airoha_trng *trng)
-+{
-+      u32 val;
-+
-+      val = readl(trng->base + TRNG_INTR_EN);
-+      val |= INTR_MASK;
-+      writel(val, trng->base + TRNG_INTR_EN);
-+
-+      return 0;
-+}
-+
-+static int airoha_trng_irq_unmask(struct airoha_trng *trng)
-+{
-+      u32 val;
-+
-+      val = readl(trng->base + TRNG_INTR_EN);
-+      val &= ~INTR_MASK;
-+      writel(val, trng->base + TRNG_INTR_EN);
-+
-+      return 0;
-+}
-+
-+static int airoha_trng_init(struct hwrng *rng)
-+{
-+      struct airoha_trng *trng = container_of(rng, struct airoha_trng, rng);
-+      int ret;
-+      u32 val;
-+
-+      val = readl(trng->base + TRNG_NS_SEK_AND_DAT_EN);
-+      val |= RNG_EN;
-+      writel(val, trng->base + TRNG_NS_SEK_AND_DAT_EN);
-+
-+      /* Set out of SW Reset */
-+      airoha_trng_irq_unmask(trng);
-+      writel(0, trng->base + TRNG_HEALTH_TEST_SW_RST);
-+
-+      ret = wait_for_completion_timeout(&trng->rng_op_done, BUSY_LOOP_TIMEOUT);
-+      if (ret <= 0) {
-+              dev_err(trng->dev, "Timeout waiting for Health Check\n");
-+              airoha_trng_irq_mask(trng);
-+              return -ENODEV;
-+      }
-+
-+      /* Check if Health Test Failed */
-+      val = readl(trng->base + TRNG_HEALTH_TEST_STATUS);
-+      if (val & (RST_STARTUP_AP_TEST_FAIL | RST_STARTUP_RC_TEST_FAIL)) {
-+              dev_err(trng->dev, "Health Check fail: %s test fail\n",
-+                      val & RST_STARTUP_AP_TEST_FAIL ? "AP" : "RC");
-+              return -ENODEV;
-+      }
-+
-+      /* Check if IP is ready */
-+      ret = readl_poll_timeout(trng->base + TRNG_IP_RDY, val,
-+                               val & SAMPLE_RDY, 10, 1000);
-+      if (ret < 0) {
-+              dev_err(trng->dev, "Timeout waiting for IP ready");
-+              return -ENODEV;
-+      }
-+
-+      /* CNT_TRANS must be 0x80 for IP to be considered ready */
-+      ret = readl_poll_timeout(trng->base + TRNG_IP_RDY, val,
-+                               FIELD_GET(CNT_TRANS, val) == TRNG_CNT_TRANS_VALID,
-+                               10, 1000);
-+      if (ret < 0) {
-+              dev_err(trng->dev, "Timeout waiting for IP ready");
-+              return -ENODEV;
-+      }
-+
-+      return 0;
-+}
-+
-+static void airoha_trng_cleanup(struct hwrng *rng)
-+{
-+      struct airoha_trng *trng = container_of(rng, struct airoha_trng, rng);
-+      u32 val;
-+
-+      val = readl(trng->base + TRNG_NS_SEK_AND_DAT_EN);
-+      val &= ~RNG_EN;
-+      writel(val, trng->base + TRNG_NS_SEK_AND_DAT_EN);
-+
-+      /* Put it in SW Reset */
-+      writel(SW_RST, trng->base + TRNG_HEALTH_TEST_SW_RST);
-+}
-+
-+static int airoha_trng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
-+{
-+      struct airoha_trng *trng = container_of(rng, struct airoha_trng, rng);
-+      u32 *data = buf;
-+      u32 status;
-+      int ret;
-+
-+      ret = readl_poll_timeout(trng->base + TRNG_HEALTH_TEST_STATUS, status,
-+                               status & RAW_DATA_VALID, 10, 1000);
-+      if (ret < 0) {
-+              dev_err(trng->dev, "Timeout waiting for TRNG RAW Data valid\n");
-+              return ret;
-+      }
-+
-+      *data = readl(trng->base + TRNG_RAW_DATA_OUT);
-+
-+      return 4;
-+}
-+
-+static irqreturn_t airoha_trng_irq(int irq, void *priv)
-+{
-+      struct airoha_trng *trng = (struct airoha_trng *)priv;
-+
-+      airoha_trng_irq_mask(trng);
-+      /* Just complete the task, we will read the value later */
-+      complete(&trng->rng_op_done);
-+
-+      return IRQ_HANDLED;
-+}
-+
-+static int airoha_trng_probe(struct platform_device *pdev)
-+{
-+      struct device *dev = &pdev->dev;
-+      struct airoha_trng *trng;
-+      int irq, ret;
-+      u32 val;
-+
-+      trng = devm_kzalloc(dev, sizeof(*trng), GFP_KERNEL);
-+      if (!trng)
-+              return -ENOMEM;
-+
-+      trng->base = devm_platform_ioremap_resource(pdev, 0);
-+      if (IS_ERR(trng->base))
-+              return PTR_ERR(trng->base);
-+
-+      irq = platform_get_irq(pdev, 0);
-+      if (irq < 0)
-+              return irq;
-+
-+      airoha_trng_irq_mask(trng);
-+      ret = devm_request_irq(&pdev->dev, irq, airoha_trng_irq, 0,
-+                             pdev->name, (void *)trng);
-+      if (ret) {
-+              dev_err(dev, "Can't get interrupt working.\n");
-+              return ret;
-+      }
-+
-+      init_completion(&trng->rng_op_done);
-+
-+      /* Enable interrupt for SW reset Health Check */
-+      val = readl(trng->base + TRNG_INTR_EN);
-+      val |= RST_STARTUP_INITR_EN;
-+      writel(val, trng->base + TRNG_INTR_EN);
-+
-+      /* Set output to raw data */
-+      val = readl(trng->base + TRNG_NS_SEK_AND_DAT_EN);
-+      val |= RAW_DATA_EN;
-+      writel(val, trng->base + TRNG_NS_SEK_AND_DAT_EN);
-+
-+      /* Put it in SW Reset */
-+      writel(SW_RST, trng->base + TRNG_HEALTH_TEST_SW_RST);
-+
-+      trng->dev = dev;
-+      trng->rng.name = pdev->name;
-+      trng->rng.init = airoha_trng_init;
-+      trng->rng.cleanup = airoha_trng_cleanup;
-+      trng->rng.read = airoha_trng_read;
-+
-+      ret = devm_hwrng_register(dev, &trng->rng);
-+      if (ret) {
-+              dev_err(dev, "failed to register rng device: %d\n", ret);
-+              return ret;
-+      }
-+
-+      return 0;
-+}
-+
-+static const struct of_device_id airoha_trng_of_match[] = {
-+      { .compatible = "airoha,en7581-trng", },
-+      {},
-+};
-+MODULE_DEVICE_TABLE(of, airoha_trng_of_match);
-+
-+static struct platform_driver airoha_trng_driver = {
-+      .driver = {
-+              .name = "airoha-trng",
-+              .of_match_table = airoha_trng_of_match,
-+      },
-+      .probe = airoha_trng_probe,
-+};
-+
-+module_platform_driver(airoha_trng_driver);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>");
-+MODULE_DESCRIPTION("Airoha True Random Number Generator driver");