All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/2] hwrng: npcm: add NPCM RNG driver support
@ 2019-09-12  9:01 Tomer Maimon
  2019-09-12  9:01 ` [PATCH v3 1/2] dt-binding: hwrng: add NPCM RNG documentation Tomer Maimon
                   ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Tomer Maimon @ 2019-09-12  9:01 UTC (permalink / raw)
  To: mpm, herbert, arnd, gregkh, robh+dt, mark.rutland, avifishman70,
	tali.perry1, venture, yuenn, benjaminfair, sumit.garg,
	jens.wiklander, vkoul, tglx, joel
  Cc: devicetree, linux-kernel, linux-crypto, openbmc, Tomer Maimon

This patch set adds Random Number Generator (RNG) support 
for the Nuvoton NPCM Baseboard Management Controller (BMC).

The RNG driver we use power consumption when the RNG 
is not required.

The NPCM RNG driver tested on NPCM750 evaluation board.

Addressed comments from:.
 - Daniel Thompson: https://lkml.org/lkml/2019/9/10/352
 - Milton Miller II : https://lkml.org/lkml/2019/9/10/847
 - Daniel Thompson: https://lkml.org/lkml/2019/9/10/294

Changes since version 2:
 - Rearrange wait parameter in npcm_rng_read function.
 - Calling pm_runtime_enable function before hwrng_register function 
   called to enable the hwrng before add_early_randomness called.
 - Remove quality dt-binding parameter in the driver and documentation.
 - Disable CONFIG_PM if devm_hwrng_register failed.
 - Remove owner setting in the driver struct.

Changes since version 1:
 - Define timout in real-world units.
 - Using readl_poll_timeout in rng_read function.
 - Honor wait parameter in rng_read function.
 - Using local variable instead of #ifndef.
 - Remove probe print.

Tomer Maimon (2):
  dt-binding: hwrng: add NPCM RNG documentation
  hwrng: npcm: add NPCM RNG driver

 .../bindings/rng/nuvoton,npcm-rng.txt         |  12 ++
 drivers/char/hw_random/Kconfig                |  13 ++
 drivers/char/hw_random/Makefile               |   1 +
 drivers/char/hw_random/npcm-rng.c             | 186 ++++++++++++++++++
 4 files changed, 212 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/rng/nuvoton,npcm-rng.txt
 create mode 100644 drivers/char/hw_random/npcm-rng.c

-- 
2.18.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3 1/2] dt-binding: hwrng: add NPCM RNG documentation
  2019-09-12  9:01 [PATCH v3 0/2] hwrng: npcm: add NPCM RNG driver support Tomer Maimon
@ 2019-09-12  9:01 ` Tomer Maimon
  2019-09-17 19:57     ` Rob Herring
  2019-09-12  9:01 ` [PATCH v3 2/2] hwrng: npcm: add NPCM RNG driver Tomer Maimon
  2019-10-04 15:29 ` [PATCH v3 0/2] hwrng: npcm: add NPCM RNG driver support Herbert Xu
  2 siblings, 1 reply; 12+ messages in thread
From: Tomer Maimon @ 2019-09-12  9:01 UTC (permalink / raw)
  To: mpm, herbert, arnd, gregkh, robh+dt, mark.rutland, avifishman70,
	tali.perry1, venture, yuenn, benjaminfair, sumit.garg,
	jens.wiklander, vkoul, tglx, joel
  Cc: devicetree, linux-kernel, linux-crypto, openbmc, Tomer Maimon

Added device tree binding documentation for Nuvoton BMC
NPCM Random Number Generator (RNG).

Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
---
 .../devicetree/bindings/rng/nuvoton,npcm-rng.txt     | 12 ++++++++++++
 1 file changed, 12 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/rng/nuvoton,npcm-rng.txt

diff --git a/Documentation/devicetree/bindings/rng/nuvoton,npcm-rng.txt b/Documentation/devicetree/bindings/rng/nuvoton,npcm-rng.txt
new file mode 100644
index 000000000000..65c04172fc8c
--- /dev/null
+++ b/Documentation/devicetree/bindings/rng/nuvoton,npcm-rng.txt
@@ -0,0 +1,12 @@
+NPCM SoC Random Number Generator
+
+Required properties:
+- compatible  : "nuvoton,npcm750-rng" for the NPCM7XX BMC.
+- reg         : Specifies physical base address and size of the registers.
+
+Example:
+
+rng: rng@f000b000 {
+	compatible = "nuvoton,npcm750-rng";
+	reg = <0xf000b000 0x8>;
+};
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 2/2] hwrng: npcm: add NPCM RNG driver
  2019-09-12  9:01 [PATCH v3 0/2] hwrng: npcm: add NPCM RNG driver support Tomer Maimon
  2019-09-12  9:01 ` [PATCH v3 1/2] dt-binding: hwrng: add NPCM RNG documentation Tomer Maimon
@ 2019-09-12  9:01 ` Tomer Maimon
  2019-09-12 16:46     ` Vinod Koul
  2019-09-13  9:28   ` Daniel Thompson
  2019-10-04 15:29 ` [PATCH v3 0/2] hwrng: npcm: add NPCM RNG driver support Herbert Xu
  2 siblings, 2 replies; 12+ messages in thread
From: Tomer Maimon @ 2019-09-12  9:01 UTC (permalink / raw)
  To: mpm, herbert, arnd, gregkh, robh+dt, mark.rutland, avifishman70,
	tali.perry1, venture, yuenn, benjaminfair, sumit.garg,
	jens.wiklander, vkoul, tglx, joel
  Cc: devicetree, linux-kernel, linux-crypto, openbmc, Tomer Maimon

Add Nuvoton NPCM BMC Random Number Generator(RNG) driver.

Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
---
 drivers/char/hw_random/Kconfig    |  13 +++
 drivers/char/hw_random/Makefile   |   1 +
 drivers/char/hw_random/npcm-rng.c | 186 ++++++++++++++++++++++++++++++
 3 files changed, 200 insertions(+)
 create mode 100644 drivers/char/hw_random/npcm-rng.c

diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index 59f25286befe..87a1c30e7958 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -440,6 +440,19 @@ config HW_RANDOM_OPTEE
 
 	  If unsure, say Y.
 
+config HW_RANDOM_NPCM
+	tristate "NPCM Random Number Generator support"
+	depends on ARCH_NPCM || COMPILE_TEST
+	default HW_RANDOM
+	help
+ 	  This driver provides support for the Random Number
+	  Generator hardware available in Nuvoton NPCM SoCs.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called npcm-rng.
+
+ 	  If unsure, say Y.
+
 endif # HW_RANDOM
 
 config UML_RANDOM
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index 7c9ef4a7667f..17b6d4e6d591 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -39,3 +39,4 @@ obj-$(CONFIG_HW_RANDOM_MTK)	+= mtk-rng.o
 obj-$(CONFIG_HW_RANDOM_S390) += s390-trng.o
 obj-$(CONFIG_HW_RANDOM_KEYSTONE) += ks-sa-rng.o
 obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o
+obj-$(CONFIG_HW_RANDOM_NPCM) += npcm-rng.o
diff --git a/drivers/char/hw_random/npcm-rng.c b/drivers/char/hw_random/npcm-rng.c
new file mode 100644
index 000000000000..b7c8c7e13a49
--- /dev/null
+++ b/drivers/char/hw_random/npcm-rng.c
@@ -0,0 +1,186 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2019 Nuvoton Technology corporation.
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/init.h>
+#include <linux/random.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/hw_random.h>
+#include <linux/delay.h>
+#include <linux/of_irq.h>
+#include <linux/pm_runtime.h>
+
+#define NPCM_RNGCS_REG		0x00	/* Control and status register */
+#define NPCM_RNGD_REG		0x04	/* Data register */
+#define NPCM_RNGMODE_REG	0x08	/* Mode register */
+
+#define NPCM_RNG_CLK_SET_25MHZ	GENMASK(4, 3) /* 20-25 MHz */
+#define NPCM_RNG_DATA_VALID	BIT(1)
+#define NPCM_RNG_ENABLE		BIT(0)
+#define NPCM_RNG_M1ROSEL	BIT(1)
+
+#define NPCM_RNG_TIMEOUT_USEC	20000
+#define NPCM_RNG_POLL_USEC	1000
+
+#define to_npcm_rng(p)	container_of(p, struct npcm_rng, rng)
+
+struct npcm_rng {
+	void __iomem *base;
+	struct hwrng rng;
+};
+
+static int npcm_rng_init(struct hwrng *rng)
+{
+	struct npcm_rng *priv = to_npcm_rng(rng);
+
+	writel(NPCM_RNG_CLK_SET_25MHZ | NPCM_RNG_ENABLE,
+	       priv->base + NPCM_RNGCS_REG);
+
+	return 0;
+}
+
+static void npcm_rng_cleanup(struct hwrng *rng)
+{
+	struct npcm_rng *priv = to_npcm_rng(rng);
+
+	writel(NPCM_RNG_CLK_SET_25MHZ, priv->base + NPCM_RNGCS_REG);
+}
+
+static int npcm_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
+{
+	struct npcm_rng *priv = to_npcm_rng(rng);
+	int retval = 0;
+	int ready;
+
+	pm_runtime_get_sync((struct device *)priv->rng.priv);
+
+	while (max >= sizeof(u32)) {
+		if (wait) {
+			if (readl_poll_timeout(priv->base + NPCM_RNGCS_REG,
+					       ready,
+					       ready & NPCM_RNG_DATA_VALID,
+					       NPCM_RNG_POLL_USEC,
+					       NPCM_RNG_TIMEOUT_USEC))
+				break;
+		} else {
+			if ((readl(priv->base + NPCM_RNGCS_REG) &
+			    NPCM_RNG_DATA_VALID) == 0)
+				break;
+		}
+
+		*(u32 *)buf = readl(priv->base + NPCM_RNGD_REG);
+		retval += sizeof(u32);
+		buf += sizeof(u32);
+		max -= sizeof(u32);
+	}
+
+	pm_runtime_mark_last_busy((struct device *)priv->rng.priv);
+	pm_runtime_put_sync_autosuspend((struct device *)priv->rng.priv);
+
+	return retval || !wait ? retval : -EIO;
+}
+
+static int npcm_rng_probe(struct platform_device *pdev)
+{
+	struct npcm_rng *priv;
+	struct resource *res;
+	int ret;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	priv->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(priv->base))
+		return PTR_ERR(priv->base);
+
+	dev_set_drvdata(&pdev->dev, priv);
+	pm_runtime_set_autosuspend_delay(&pdev->dev, 100);
+	pm_runtime_use_autosuspend(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+
+#ifndef CONFIG_PM
+	priv->rng.init = npcm_rng_init;
+	priv->rng.cleanup = npcm_rng_cleanup;
+#endif
+	priv->rng.name = pdev->name;
+	priv->rng.read = npcm_rng_read;
+	priv->rng.priv = (unsigned long)&pdev->dev;
+	priv->rng.quality = 1000;
+
+	writel(NPCM_RNG_M1ROSEL, priv->base + NPCM_RNGMODE_REG);
+
+	ret = devm_hwrng_register(&pdev->dev, &priv->rng);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to register rng device: %d\n",
+			ret);
+		pm_runtime_disable(&pdev->dev);
+		pm_runtime_set_suspended(&pdev->dev);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int npcm_rng_remove(struct platform_device *pdev)
+{
+	struct npcm_rng *priv = platform_get_drvdata(pdev);
+
+	devm_hwrng_unregister(&pdev->dev, &priv->rng);
+	pm_runtime_disable(&pdev->dev);
+	pm_runtime_set_suspended(&pdev->dev);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int npcm_rng_runtime_suspend(struct device *dev)
+{
+	struct npcm_rng *priv = dev_get_drvdata(dev);
+
+	npcm_rng_cleanup(&priv->rng);
+
+	return 0;
+}
+
+static int npcm_rng_runtime_resume(struct device *dev)
+{
+	struct npcm_rng *priv = dev_get_drvdata(dev);
+
+	return npcm_rng_init(&priv->rng);
+}
+#endif
+
+static const struct dev_pm_ops npcm_rng_pm_ops = {
+	SET_RUNTIME_PM_OPS(npcm_rng_runtime_suspend,
+			   npcm_rng_runtime_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				pm_runtime_force_resume)
+};
+
+static const struct of_device_id rng_dt_id[] = {
+	{ .compatible = "nuvoton,npcm750-rng",  },
+	{},
+};
+MODULE_DEVICE_TABLE(of, rng_dt_id);
+
+static struct platform_driver npcm_rng_driver = {
+	.driver = {
+		.name		= "npcm-rng",
+		.pm		= &npcm_rng_pm_ops,
+		.of_match_table = of_match_ptr(rng_dt_id),
+	},
+	.probe		= npcm_rng_probe,
+	.remove		= npcm_rng_remove,
+};
+
+module_platform_driver(npcm_rng_driver);
+
+MODULE_DESCRIPTION("Nuvoton NPCM Random Number Generator Driver");
+MODULE_AUTHOR("Tomer Maimon <tomer.maimon@nuvoton.com>");
+MODULE_LICENSE("GPL v2");
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 2/2] hwrng: npcm: add NPCM RNG driver
  2019-09-12  9:01 ` [PATCH v3 2/2] hwrng: npcm: add NPCM RNG driver Tomer Maimon
@ 2019-09-12 16:46     ` Vinod Koul
  2019-09-13  9:28   ` Daniel Thompson
  1 sibling, 0 replies; 12+ messages in thread
From: Vinod Koul @ 2019-09-12 16:46 UTC (permalink / raw)
  To: Tomer Maimon, Herbert Xu
  Cc: mpm, herbert, arnd, gregkh, robh+dt, mark.rutland, avifishman70,
	tali.perry1, venture, yuenn, benjaminfair, sumit.garg,
	jens.wiklander, tglx, joel, devicetree, linux-kernel,
	linux-crypto, openbmc

On 12-09-19, 12:01, Tomer Maimon wrote:
> Add Nuvoton NPCM BMC Random Number Generator(RNG) driver.

Is this a true RNG or a psedo RNG, in case of latter it should be added
in drivers/crypto/. See crypto_register_rng()

> 
> Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
> ---
>  drivers/char/hw_random/Kconfig    |  13 +++
>  drivers/char/hw_random/Makefile   |   1 +
>  drivers/char/hw_random/npcm-rng.c | 186 ++++++++++++++++++++++++++++++
>  3 files changed, 200 insertions(+)
>  create mode 100644 drivers/char/hw_random/npcm-rng.c
> 
> diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
> index 59f25286befe..87a1c30e7958 100644
> --- a/drivers/char/hw_random/Kconfig
> +++ b/drivers/char/hw_random/Kconfig
> @@ -440,6 +440,19 @@ config HW_RANDOM_OPTEE
>  
>  	  If unsure, say Y.
>  
> +config HW_RANDOM_NPCM
> +	tristate "NPCM Random Number Generator support"
> +	depends on ARCH_NPCM || COMPILE_TEST
> +	default HW_RANDOM
> +	help
> + 	  This driver provides support for the Random Number
> +	  Generator hardware available in Nuvoton NPCM SoCs.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called npcm-rng.
> +
> + 	  If unsure, say Y.
> +
>  endif # HW_RANDOM
>  
>  config UML_RANDOM
> diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
> index 7c9ef4a7667f..17b6d4e6d591 100644
> --- a/drivers/char/hw_random/Makefile
> +++ b/drivers/char/hw_random/Makefile
> @@ -39,3 +39,4 @@ obj-$(CONFIG_HW_RANDOM_MTK)	+= mtk-rng.o
>  obj-$(CONFIG_HW_RANDOM_S390) += s390-trng.o
>  obj-$(CONFIG_HW_RANDOM_KEYSTONE) += ks-sa-rng.o
>  obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o
> +obj-$(CONFIG_HW_RANDOM_NPCM) += npcm-rng.o
> diff --git a/drivers/char/hw_random/npcm-rng.c b/drivers/char/hw_random/npcm-rng.c
> new file mode 100644
> index 000000000000..b7c8c7e13a49
> --- /dev/null
> +++ b/drivers/char/hw_random/npcm-rng.c
> @@ -0,0 +1,186 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright (c) 2019 Nuvoton Technology corporation.
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/io.h>
> +#include <linux/iopoll.h>
> +#include <linux/init.h>
> +#include <linux/random.h>
> +#include <linux/err.h>
> +#include <linux/platform_device.h>
> +#include <linux/hw_random.h>
> +#include <linux/delay.h>
> +#include <linux/of_irq.h>
> +#include <linux/pm_runtime.h>
> +
> +#define NPCM_RNGCS_REG		0x00	/* Control and status register */
> +#define NPCM_RNGD_REG		0x04	/* Data register */
> +#define NPCM_RNGMODE_REG	0x08	/* Mode register */
> +
> +#define NPCM_RNG_CLK_SET_25MHZ	GENMASK(4, 3) /* 20-25 MHz */
> +#define NPCM_RNG_DATA_VALID	BIT(1)
> +#define NPCM_RNG_ENABLE		BIT(0)
> +#define NPCM_RNG_M1ROSEL	BIT(1)
> +
> +#define NPCM_RNG_TIMEOUT_USEC	20000
> +#define NPCM_RNG_POLL_USEC	1000
> +
> +#define to_npcm_rng(p)	container_of(p, struct npcm_rng, rng)
> +
> +struct npcm_rng {
> +	void __iomem *base;
> +	struct hwrng rng;
> +};
> +
> +static int npcm_rng_init(struct hwrng *rng)
> +{
> +	struct npcm_rng *priv = to_npcm_rng(rng);
> +
> +	writel(NPCM_RNG_CLK_SET_25MHZ | NPCM_RNG_ENABLE,
> +	       priv->base + NPCM_RNGCS_REG);
> +
> +	return 0;
> +}
> +
> +static void npcm_rng_cleanup(struct hwrng *rng)
> +{
> +	struct npcm_rng *priv = to_npcm_rng(rng);
> +
> +	writel(NPCM_RNG_CLK_SET_25MHZ, priv->base + NPCM_RNGCS_REG);
> +}
> +
> +static int npcm_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
> +{
> +	struct npcm_rng *priv = to_npcm_rng(rng);
> +	int retval = 0;
> +	int ready;
> +
> +	pm_runtime_get_sync((struct device *)priv->rng.priv);
> +
> +	while (max >= sizeof(u32)) {
> +		if (wait) {
> +			if (readl_poll_timeout(priv->base + NPCM_RNGCS_REG,
> +					       ready,
> +					       ready & NPCM_RNG_DATA_VALID,
> +					       NPCM_RNG_POLL_USEC,
> +					       NPCM_RNG_TIMEOUT_USEC))
> +				break;
> +		} else {
> +			if ((readl(priv->base + NPCM_RNGCS_REG) &
> +			    NPCM_RNG_DATA_VALID) == 0)
> +				break;
> +		}
> +
> +		*(u32 *)buf = readl(priv->base + NPCM_RNGD_REG);
> +		retval += sizeof(u32);
> +		buf += sizeof(u32);
> +		max -= sizeof(u32);
> +	}
> +
> +	pm_runtime_mark_last_busy((struct device *)priv->rng.priv);
> +	pm_runtime_put_sync_autosuspend((struct device *)priv->rng.priv);
> +
> +	return retval || !wait ? retval : -EIO;
> +}
> +
> +static int npcm_rng_probe(struct platform_device *pdev)
> +{
> +	struct npcm_rng *priv;
> +	struct resource *res;
> +	int ret;
> +
> +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	priv->base = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(priv->base))
> +		return PTR_ERR(priv->base);
> +
> +	dev_set_drvdata(&pdev->dev, priv);
> +	pm_runtime_set_autosuspend_delay(&pdev->dev, 100);
> +	pm_runtime_use_autosuspend(&pdev->dev);
> +	pm_runtime_enable(&pdev->dev);
> +
> +#ifndef CONFIG_PM
> +	priv->rng.init = npcm_rng_init;
> +	priv->rng.cleanup = npcm_rng_cleanup;
> +#endif
> +	priv->rng.name = pdev->name;
> +	priv->rng.read = npcm_rng_read;
> +	priv->rng.priv = (unsigned long)&pdev->dev;
> +	priv->rng.quality = 1000;
> +
> +	writel(NPCM_RNG_M1ROSEL, priv->base + NPCM_RNGMODE_REG);
> +
> +	ret = devm_hwrng_register(&pdev->dev, &priv->rng);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Failed to register rng device: %d\n",
> +			ret);
> +		pm_runtime_disable(&pdev->dev);
> +		pm_runtime_set_suspended(&pdev->dev);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int npcm_rng_remove(struct platform_device *pdev)
> +{
> +	struct npcm_rng *priv = platform_get_drvdata(pdev);
> +
> +	devm_hwrng_unregister(&pdev->dev, &priv->rng);
> +	pm_runtime_disable(&pdev->dev);
> +	pm_runtime_set_suspended(&pdev->dev);
> +
> +	return 0;
> +}
> +
> +#ifdef CONFIG_PM
> +static int npcm_rng_runtime_suspend(struct device *dev)
> +{
> +	struct npcm_rng *priv = dev_get_drvdata(dev);
> +
> +	npcm_rng_cleanup(&priv->rng);
> +
> +	return 0;
> +}
> +
> +static int npcm_rng_runtime_resume(struct device *dev)
> +{
> +	struct npcm_rng *priv = dev_get_drvdata(dev);
> +
> +	return npcm_rng_init(&priv->rng);
> +}
> +#endif
> +
> +static const struct dev_pm_ops npcm_rng_pm_ops = {
> +	SET_RUNTIME_PM_OPS(npcm_rng_runtime_suspend,
> +			   npcm_rng_runtime_resume, NULL)
> +	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
> +				pm_runtime_force_resume)
> +};
> +
> +static const struct of_device_id rng_dt_id[] = {
> +	{ .compatible = "nuvoton,npcm750-rng",  },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, rng_dt_id);
> +
> +static struct platform_driver npcm_rng_driver = {
> +	.driver = {
> +		.name		= "npcm-rng",
> +		.pm		= &npcm_rng_pm_ops,
> +		.of_match_table = of_match_ptr(rng_dt_id),
> +	},
> +	.probe		= npcm_rng_probe,
> +	.remove		= npcm_rng_remove,
> +};
> +
> +module_platform_driver(npcm_rng_driver);
> +
> +MODULE_DESCRIPTION("Nuvoton NPCM Random Number Generator Driver");
> +MODULE_AUTHOR("Tomer Maimon <tomer.maimon@nuvoton.com>");
> +MODULE_LICENSE("GPL v2");
> -- 
> 2.18.0

-- 
~Vinod

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 2/2] hwrng: npcm: add NPCM RNG driver
@ 2019-09-12 16:46     ` Vinod Koul
  0 siblings, 0 replies; 12+ messages in thread
From: Vinod Koul @ 2019-09-12 16:46 UTC (permalink / raw)
  To: Tomer Maimon
  Cc: mpm, herbert, arnd, gregkh, robh+dt, mark.rutland, avifishman70,
	tali.perry1, venture, yuenn, benjaminfair, sumit.garg,
	jens.wiklander, tglx, joel, devicetree, linux-kernel,
	linux-crypto, openbmc

On 12-09-19, 12:01, Tomer Maimon wrote:
> Add Nuvoton NPCM BMC Random Number Generator(RNG) driver.

Is this a true RNG or a psedo RNG, in case of latter it should be added
in drivers/crypto/. See crypto_register_rng()

> 
> Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
> ---
>  drivers/char/hw_random/Kconfig    |  13 +++
>  drivers/char/hw_random/Makefile   |   1 +
>  drivers/char/hw_random/npcm-rng.c | 186 ++++++++++++++++++++++++++++++
>  3 files changed, 200 insertions(+)
>  create mode 100644 drivers/char/hw_random/npcm-rng.c
> 
> diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
> index 59f25286befe..87a1c30e7958 100644
> --- a/drivers/char/hw_random/Kconfig
> +++ b/drivers/char/hw_random/Kconfig
> @@ -440,6 +440,19 @@ config HW_RANDOM_OPTEE
>  
>  	  If unsure, say Y.
>  
> +config HW_RANDOM_NPCM
> +	tristate "NPCM Random Number Generator support"
> +	depends on ARCH_NPCM || COMPILE_TEST
> +	default HW_RANDOM
> +	help
> + 	  This driver provides support for the Random Number
> +	  Generator hardware available in Nuvoton NPCM SoCs.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called npcm-rng.
> +
> + 	  If unsure, say Y.
> +
>  endif # HW_RANDOM
>  
>  config UML_RANDOM
> diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
> index 7c9ef4a7667f..17b6d4e6d591 100644
> --- a/drivers/char/hw_random/Makefile
> +++ b/drivers/char/hw_random/Makefile
> @@ -39,3 +39,4 @@ obj-$(CONFIG_HW_RANDOM_MTK)	+= mtk-rng.o
>  obj-$(CONFIG_HW_RANDOM_S390) += s390-trng.o
>  obj-$(CONFIG_HW_RANDOM_KEYSTONE) += ks-sa-rng.o
>  obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o
> +obj-$(CONFIG_HW_RANDOM_NPCM) += npcm-rng.o
> diff --git a/drivers/char/hw_random/npcm-rng.c b/drivers/char/hw_random/npcm-rng.c
> new file mode 100644
> index 000000000000..b7c8c7e13a49
> --- /dev/null
> +++ b/drivers/char/hw_random/npcm-rng.c
> @@ -0,0 +1,186 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright (c) 2019 Nuvoton Technology corporation.
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/io.h>
> +#include <linux/iopoll.h>
> +#include <linux/init.h>
> +#include <linux/random.h>
> +#include <linux/err.h>
> +#include <linux/platform_device.h>
> +#include <linux/hw_random.h>
> +#include <linux/delay.h>
> +#include <linux/of_irq.h>
> +#include <linux/pm_runtime.h>
> +
> +#define NPCM_RNGCS_REG		0x00	/* Control and status register */
> +#define NPCM_RNGD_REG		0x04	/* Data register */
> +#define NPCM_RNGMODE_REG	0x08	/* Mode register */
> +
> +#define NPCM_RNG_CLK_SET_25MHZ	GENMASK(4, 3) /* 20-25 MHz */
> +#define NPCM_RNG_DATA_VALID	BIT(1)
> +#define NPCM_RNG_ENABLE		BIT(0)
> +#define NPCM_RNG_M1ROSEL	BIT(1)
> +
> +#define NPCM_RNG_TIMEOUT_USEC	20000
> +#define NPCM_RNG_POLL_USEC	1000
> +
> +#define to_npcm_rng(p)	container_of(p, struct npcm_rng, rng)
> +
> +struct npcm_rng {
> +	void __iomem *base;
> +	struct hwrng rng;
> +};
> +
> +static int npcm_rng_init(struct hwrng *rng)
> +{
> +	struct npcm_rng *priv = to_npcm_rng(rng);
> +
> +	writel(NPCM_RNG_CLK_SET_25MHZ | NPCM_RNG_ENABLE,
> +	       priv->base + NPCM_RNGCS_REG);
> +
> +	return 0;
> +}
> +
> +static void npcm_rng_cleanup(struct hwrng *rng)
> +{
> +	struct npcm_rng *priv = to_npcm_rng(rng);
> +
> +	writel(NPCM_RNG_CLK_SET_25MHZ, priv->base + NPCM_RNGCS_REG);
> +}
> +
> +static int npcm_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
> +{
> +	struct npcm_rng *priv = to_npcm_rng(rng);
> +	int retval = 0;
> +	int ready;
> +
> +	pm_runtime_get_sync((struct device *)priv->rng.priv);
> +
> +	while (max >= sizeof(u32)) {
> +		if (wait) {
> +			if (readl_poll_timeout(priv->base + NPCM_RNGCS_REG,
> +					       ready,
> +					       ready & NPCM_RNG_DATA_VALID,
> +					       NPCM_RNG_POLL_USEC,
> +					       NPCM_RNG_TIMEOUT_USEC))
> +				break;
> +		} else {
> +			if ((readl(priv->base + NPCM_RNGCS_REG) &
> +			    NPCM_RNG_DATA_VALID) == 0)
> +				break;
> +		}
> +
> +		*(u32 *)buf = readl(priv->base + NPCM_RNGD_REG);
> +		retval += sizeof(u32);
> +		buf += sizeof(u32);
> +		max -= sizeof(u32);
> +	}
> +
> +	pm_runtime_mark_last_busy((struct device *)priv->rng.priv);
> +	pm_runtime_put_sync_autosuspend((struct device *)priv->rng.priv);
> +
> +	return retval || !wait ? retval : -EIO;
> +}
> +
> +static int npcm_rng_probe(struct platform_device *pdev)
> +{
> +	struct npcm_rng *priv;
> +	struct resource *res;
> +	int ret;
> +
> +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	priv->base = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(priv->base))
> +		return PTR_ERR(priv->base);
> +
> +	dev_set_drvdata(&pdev->dev, priv);
> +	pm_runtime_set_autosuspend_delay(&pdev->dev, 100);
> +	pm_runtime_use_autosuspend(&pdev->dev);
> +	pm_runtime_enable(&pdev->dev);
> +
> +#ifndef CONFIG_PM
> +	priv->rng.init = npcm_rng_init;
> +	priv->rng.cleanup = npcm_rng_cleanup;
> +#endif
> +	priv->rng.name = pdev->name;
> +	priv->rng.read = npcm_rng_read;
> +	priv->rng.priv = (unsigned long)&pdev->dev;
> +	priv->rng.quality = 1000;
> +
> +	writel(NPCM_RNG_M1ROSEL, priv->base + NPCM_RNGMODE_REG);
> +
> +	ret = devm_hwrng_register(&pdev->dev, &priv->rng);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Failed to register rng device: %d\n",
> +			ret);
> +		pm_runtime_disable(&pdev->dev);
> +		pm_runtime_set_suspended(&pdev->dev);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int npcm_rng_remove(struct platform_device *pdev)
> +{
> +	struct npcm_rng *priv = platform_get_drvdata(pdev);
> +
> +	devm_hwrng_unregister(&pdev->dev, &priv->rng);
> +	pm_runtime_disable(&pdev->dev);
> +	pm_runtime_set_suspended(&pdev->dev);
> +
> +	return 0;
> +}
> +
> +#ifdef CONFIG_PM
> +static int npcm_rng_runtime_suspend(struct device *dev)
> +{
> +	struct npcm_rng *priv = dev_get_drvdata(dev);
> +
> +	npcm_rng_cleanup(&priv->rng);
> +
> +	return 0;
> +}
> +
> +static int npcm_rng_runtime_resume(struct device *dev)
> +{
> +	struct npcm_rng *priv = dev_get_drvdata(dev);
> +
> +	return npcm_rng_init(&priv->rng);
> +}
> +#endif
> +
> +static const struct dev_pm_ops npcm_rng_pm_ops = {
> +	SET_RUNTIME_PM_OPS(npcm_rng_runtime_suspend,
> +			   npcm_rng_runtime_resume, NULL)
> +	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
> +				pm_runtime_force_resume)
> +};
> +
> +static const struct of_device_id rng_dt_id[] = {
> +	{ .compatible = "nuvoton,npcm750-rng",  },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, rng_dt_id);
> +
> +static struct platform_driver npcm_rng_driver = {
> +	.driver = {
> +		.name		= "npcm-rng",
> +		.pm		= &npcm_rng_pm_ops,
> +		.of_match_table = of_match_ptr(rng_dt_id),
> +	},
> +	.probe		= npcm_rng_probe,
> +	.remove		= npcm_rng_remove,
> +};
> +
> +module_platform_driver(npcm_rng_driver);
> +
> +MODULE_DESCRIPTION("Nuvoton NPCM Random Number Generator Driver");
> +MODULE_AUTHOR("Tomer Maimon <tomer.maimon@nuvoton.com>");
> +MODULE_LICENSE("GPL v2");
> -- 
> 2.18.0

-- 
~Vinod

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 2/2] hwrng: npcm: add NPCM RNG driver
  2019-09-12  9:01 ` [PATCH v3 2/2] hwrng: npcm: add NPCM RNG driver Tomer Maimon
  2019-09-12 16:46     ` Vinod Koul
@ 2019-09-13  9:28   ` Daniel Thompson
  1 sibling, 0 replies; 12+ messages in thread
From: Daniel Thompson @ 2019-09-13  9:28 UTC (permalink / raw)
  To: Tomer Maimon
  Cc: mpm, herbert, arnd, gregkh, robh+dt, mark.rutland, avifishman70,
	tali.perry1, venture, yuenn, benjaminfair, sumit.garg,
	jens.wiklander, vkoul, tglx, joel, devicetree, linux-kernel,
	linux-crypto, openbmc

On Thu, Sep 12, 2019 at 12:01:49PM +0300, Tomer Maimon wrote:
> Add Nuvoton NPCM BMC Random Number Generator(RNG) driver.
> 
> Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>

Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org>

Note, you are welcome to preseve this if you have to respin and
change directory based on Vinod's feedback...


> ---
>  drivers/char/hw_random/Kconfig    |  13 +++
>  drivers/char/hw_random/Makefile   |   1 +
>  drivers/char/hw_random/npcm-rng.c | 186 ++++++++++++++++++++++++++++++
>  3 files changed, 200 insertions(+)
>  create mode 100644 drivers/char/hw_random/npcm-rng.c
> 
> diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
> index 59f25286befe..87a1c30e7958 100644
> --- a/drivers/char/hw_random/Kconfig
> +++ b/drivers/char/hw_random/Kconfig
> @@ -440,6 +440,19 @@ config HW_RANDOM_OPTEE
>  
>  	  If unsure, say Y.
>  
> +config HW_RANDOM_NPCM
> +	tristate "NPCM Random Number Generator support"
> +	depends on ARCH_NPCM || COMPILE_TEST
> +	default HW_RANDOM
> +	help
> + 	  This driver provides support for the Random Number
> +	  Generator hardware available in Nuvoton NPCM SoCs.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called npcm-rng.
> +
> + 	  If unsure, say Y.
> +
>  endif # HW_RANDOM
>  
>  config UML_RANDOM
> diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
> index 7c9ef4a7667f..17b6d4e6d591 100644
> --- a/drivers/char/hw_random/Makefile
> +++ b/drivers/char/hw_random/Makefile
> @@ -39,3 +39,4 @@ obj-$(CONFIG_HW_RANDOM_MTK)	+= mtk-rng.o
>  obj-$(CONFIG_HW_RANDOM_S390) += s390-trng.o
>  obj-$(CONFIG_HW_RANDOM_KEYSTONE) += ks-sa-rng.o
>  obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o
> +obj-$(CONFIG_HW_RANDOM_NPCM) += npcm-rng.o
> diff --git a/drivers/char/hw_random/npcm-rng.c b/drivers/char/hw_random/npcm-rng.c
> new file mode 100644
> index 000000000000..b7c8c7e13a49
> --- /dev/null
> +++ b/drivers/char/hw_random/npcm-rng.c
> @@ -0,0 +1,186 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright (c) 2019 Nuvoton Technology corporation.
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/io.h>
> +#include <linux/iopoll.h>
> +#include <linux/init.h>
> +#include <linux/random.h>
> +#include <linux/err.h>
> +#include <linux/platform_device.h>
> +#include <linux/hw_random.h>
> +#include <linux/delay.h>
> +#include <linux/of_irq.h>
> +#include <linux/pm_runtime.h>
> +
> +#define NPCM_RNGCS_REG		0x00	/* Control and status register */
> +#define NPCM_RNGD_REG		0x04	/* Data register */
> +#define NPCM_RNGMODE_REG	0x08	/* Mode register */
> +
> +#define NPCM_RNG_CLK_SET_25MHZ	GENMASK(4, 3) /* 20-25 MHz */
> +#define NPCM_RNG_DATA_VALID	BIT(1)
> +#define NPCM_RNG_ENABLE		BIT(0)
> +#define NPCM_RNG_M1ROSEL	BIT(1)
> +
> +#define NPCM_RNG_TIMEOUT_USEC	20000
> +#define NPCM_RNG_POLL_USEC	1000
> +
> +#define to_npcm_rng(p)	container_of(p, struct npcm_rng, rng)
> +
> +struct npcm_rng {
> +	void __iomem *base;
> +	struct hwrng rng;
> +};
> +
> +static int npcm_rng_init(struct hwrng *rng)
> +{
> +	struct npcm_rng *priv = to_npcm_rng(rng);
> +
> +	writel(NPCM_RNG_CLK_SET_25MHZ | NPCM_RNG_ENABLE,
> +	       priv->base + NPCM_RNGCS_REG);
> +
> +	return 0;
> +}
> +
> +static void npcm_rng_cleanup(struct hwrng *rng)
> +{
> +	struct npcm_rng *priv = to_npcm_rng(rng);
> +
> +	writel(NPCM_RNG_CLK_SET_25MHZ, priv->base + NPCM_RNGCS_REG);
> +}
> +
> +static int npcm_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
> +{
> +	struct npcm_rng *priv = to_npcm_rng(rng);
> +	int retval = 0;
> +	int ready;
> +
> +	pm_runtime_get_sync((struct device *)priv->rng.priv);
> +
> +	while (max >= sizeof(u32)) {
> +		if (wait) {
> +			if (readl_poll_timeout(priv->base + NPCM_RNGCS_REG,
> +					       ready,
> +					       ready & NPCM_RNG_DATA_VALID,
> +					       NPCM_RNG_POLL_USEC,
> +					       NPCM_RNG_TIMEOUT_USEC))
> +				break;
> +		} else {
> +			if ((readl(priv->base + NPCM_RNGCS_REG) &
> +			    NPCM_RNG_DATA_VALID) == 0)
> +				break;
> +		}
> +
> +		*(u32 *)buf = readl(priv->base + NPCM_RNGD_REG);
> +		retval += sizeof(u32);
> +		buf += sizeof(u32);
> +		max -= sizeof(u32);
> +	}
> +
> +	pm_runtime_mark_last_busy((struct device *)priv->rng.priv);
> +	pm_runtime_put_sync_autosuspend((struct device *)priv->rng.priv);
> +
> +	return retval || !wait ? retval : -EIO;
> +}
> +
> +static int npcm_rng_probe(struct platform_device *pdev)
> +{
> +	struct npcm_rng *priv;
> +	struct resource *res;
> +	int ret;
> +
> +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	priv->base = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(priv->base))
> +		return PTR_ERR(priv->base);
> +
> +	dev_set_drvdata(&pdev->dev, priv);
> +	pm_runtime_set_autosuspend_delay(&pdev->dev, 100);
> +	pm_runtime_use_autosuspend(&pdev->dev);
> +	pm_runtime_enable(&pdev->dev);
> +
> +#ifndef CONFIG_PM
> +	priv->rng.init = npcm_rng_init;
> +	priv->rng.cleanup = npcm_rng_cleanup;
> +#endif
> +	priv->rng.name = pdev->name;
> +	priv->rng.read = npcm_rng_read;
> +	priv->rng.priv = (unsigned long)&pdev->dev;
> +	priv->rng.quality = 1000;
> +
> +	writel(NPCM_RNG_M1ROSEL, priv->base + NPCM_RNGMODE_REG);
> +
> +	ret = devm_hwrng_register(&pdev->dev, &priv->rng);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Failed to register rng device: %d\n",
> +			ret);
> +		pm_runtime_disable(&pdev->dev);
> +		pm_runtime_set_suspended(&pdev->dev);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int npcm_rng_remove(struct platform_device *pdev)
> +{
> +	struct npcm_rng *priv = platform_get_drvdata(pdev);
> +
> +	devm_hwrng_unregister(&pdev->dev, &priv->rng);
> +	pm_runtime_disable(&pdev->dev);
> +	pm_runtime_set_suspended(&pdev->dev);
> +
> +	return 0;
> +}
> +
> +#ifdef CONFIG_PM
> +static int npcm_rng_runtime_suspend(struct device *dev)
> +{
> +	struct npcm_rng *priv = dev_get_drvdata(dev);
> +
> +	npcm_rng_cleanup(&priv->rng);
> +
> +	return 0;
> +}
> +
> +static int npcm_rng_runtime_resume(struct device *dev)
> +{
> +	struct npcm_rng *priv = dev_get_drvdata(dev);
> +
> +	return npcm_rng_init(&priv->rng);
> +}
> +#endif
> +
> +static const struct dev_pm_ops npcm_rng_pm_ops = {
> +	SET_RUNTIME_PM_OPS(npcm_rng_runtime_suspend,
> +			   npcm_rng_runtime_resume, NULL)
> +	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
> +				pm_runtime_force_resume)
> +};
> +
> +static const struct of_device_id rng_dt_id[] = {
> +	{ .compatible = "nuvoton,npcm750-rng",  },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, rng_dt_id);
> +
> +static struct platform_driver npcm_rng_driver = {
> +	.driver = {
> +		.name		= "npcm-rng",
> +		.pm		= &npcm_rng_pm_ops,
> +		.of_match_table = of_match_ptr(rng_dt_id),
> +	},
> +	.probe		= npcm_rng_probe,
> +	.remove		= npcm_rng_remove,
> +};
> +
> +module_platform_driver(npcm_rng_driver);
> +
> +MODULE_DESCRIPTION("Nuvoton NPCM Random Number Generator Driver");
> +MODULE_AUTHOR("Tomer Maimon <tomer.maimon@nuvoton.com>");
> +MODULE_LICENSE("GPL v2");
> -- 
> 2.18.0
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 2/2] hwrng: npcm: add NPCM RNG driver
  2019-09-12 16:46     ` Vinod Koul
@ 2019-09-15  6:26       ` Tomer Maimon
  -1 siblings, 0 replies; 12+ messages in thread
From: Tomer Maimon @ 2019-09-15  6:26 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Herbert Xu, mpm, Arnd Bergmann, Greg KH, Rob Herring,
	Mark Rutland, Avi Fishman, Tali Perry, Patrick Venture,
	Nancy Yuen, Benjamin Fair, sumit.garg, jens.wiklander,
	Thomas Gleixner, Joel Stanley, devicetree,
	Linux Kernel Mailing List, linux-crypto, OpenBMC Maillist

[-- Attachment #1: Type: text/plain, Size: 8552 bytes --]

Hi Vinod,

Thanks for your notification.

NPCM Hardware RNG is true RNG.

Tomer

On Thu, 12 Sep 2019 at 19:47, Vinod Koul <vkoul@kernel.org> wrote:

> On 12-09-19, 12:01, Tomer Maimon wrote:
> > Add Nuvoton NPCM BMC Random Number Generator(RNG) driver.
>
> Is this a true RNG or a psedo RNG, in case of latter it should be added
> in drivers/crypto/. See crypto_register_rng()
>
> >
> > Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
> > ---
> >  drivers/char/hw_random/Kconfig    |  13 +++
> >  drivers/char/hw_random/Makefile   |   1 +
> >  drivers/char/hw_random/npcm-rng.c | 186 ++++++++++++++++++++++++++++++
> >  3 files changed, 200 insertions(+)
> >  create mode 100644 drivers/char/hw_random/npcm-rng.c
> >
> > diff --git a/drivers/char/hw_random/Kconfig
> b/drivers/char/hw_random/Kconfig
> > index 59f25286befe..87a1c30e7958 100644
> > --- a/drivers/char/hw_random/Kconfig
> > +++ b/drivers/char/hw_random/Kconfig
> > @@ -440,6 +440,19 @@ config HW_RANDOM_OPTEE
> >
> >         If unsure, say Y.
> >
> > +config HW_RANDOM_NPCM
> > +     tristate "NPCM Random Number Generator support"
> > +     depends on ARCH_NPCM || COMPILE_TEST
> > +     default HW_RANDOM
> > +     help
> > +       This driver provides support for the Random Number
> > +       Generator hardware available in Nuvoton NPCM SoCs.
> > +
> > +       To compile this driver as a module, choose M here: the
> > +       module will be called npcm-rng.
> > +
> > +       If unsure, say Y.
> > +
> >  endif # HW_RANDOM
> >
> >  config UML_RANDOM
> > diff --git a/drivers/char/hw_random/Makefile
> b/drivers/char/hw_random/Makefile
> > index 7c9ef4a7667f..17b6d4e6d591 100644
> > --- a/drivers/char/hw_random/Makefile
> > +++ b/drivers/char/hw_random/Makefile
> > @@ -39,3 +39,4 @@ obj-$(CONFIG_HW_RANDOM_MTK) += mtk-rng.o
> >  obj-$(CONFIG_HW_RANDOM_S390) += s390-trng.o
> >  obj-$(CONFIG_HW_RANDOM_KEYSTONE) += ks-sa-rng.o
> >  obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o
> > +obj-$(CONFIG_HW_RANDOM_NPCM) += npcm-rng.o
> > diff --git a/drivers/char/hw_random/npcm-rng.c
> b/drivers/char/hw_random/npcm-rng.c
> > new file mode 100644
> > index 000000000000..b7c8c7e13a49
> > --- /dev/null
> > +++ b/drivers/char/hw_random/npcm-rng.c
> > @@ -0,0 +1,186 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +// Copyright (c) 2019 Nuvoton Technology corporation.
> > +
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/io.h>
> > +#include <linux/iopoll.h>
> > +#include <linux/init.h>
> > +#include <linux/random.h>
> > +#include <linux/err.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/hw_random.h>
> > +#include <linux/delay.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/pm_runtime.h>
> > +
> > +#define NPCM_RNGCS_REG               0x00    /* Control and status
> register */
> > +#define NPCM_RNGD_REG                0x04    /* Data register */
> > +#define NPCM_RNGMODE_REG     0x08    /* Mode register */
> > +
> > +#define NPCM_RNG_CLK_SET_25MHZ       GENMASK(4, 3) /* 20-25 MHz */
> > +#define NPCM_RNG_DATA_VALID  BIT(1)
> > +#define NPCM_RNG_ENABLE              BIT(0)
> > +#define NPCM_RNG_M1ROSEL     BIT(1)
> > +
> > +#define NPCM_RNG_TIMEOUT_USEC        20000
> > +#define NPCM_RNG_POLL_USEC   1000
> > +
> > +#define to_npcm_rng(p)       container_of(p, struct npcm_rng, rng)
> > +
> > +struct npcm_rng {
> > +     void __iomem *base;
> > +     struct hwrng rng;
> > +};
> > +
> > +static int npcm_rng_init(struct hwrng *rng)
> > +{
> > +     struct npcm_rng *priv = to_npcm_rng(rng);
> > +
> > +     writel(NPCM_RNG_CLK_SET_25MHZ | NPCM_RNG_ENABLE,
> > +            priv->base + NPCM_RNGCS_REG);
> > +
> > +     return 0;
> > +}
> > +
> > +static void npcm_rng_cleanup(struct hwrng *rng)
> > +{
> > +     struct npcm_rng *priv = to_npcm_rng(rng);
> > +
> > +     writel(NPCM_RNG_CLK_SET_25MHZ, priv->base + NPCM_RNGCS_REG);
> > +}
> > +
> > +static int npcm_rng_read(struct hwrng *rng, void *buf, size_t max, bool
> wait)
> > +{
> > +     struct npcm_rng *priv = to_npcm_rng(rng);
> > +     int retval = 0;
> > +     int ready;
> > +
> > +     pm_runtime_get_sync((struct device *)priv->rng.priv);
> > +
> > +     while (max >= sizeof(u32)) {
> > +             if (wait) {
> > +                     if (readl_poll_timeout(priv->base + NPCM_RNGCS_REG,
> > +                                            ready,
> > +                                            ready & NPCM_RNG_DATA_VALID,
> > +                                            NPCM_RNG_POLL_USEC,
> > +                                            NPCM_RNG_TIMEOUT_USEC))
> > +                             break;
> > +             } else {
> > +                     if ((readl(priv->base + NPCM_RNGCS_REG) &
> > +                         NPCM_RNG_DATA_VALID) == 0)
> > +                             break;
> > +             }
> > +
> > +             *(u32 *)buf = readl(priv->base + NPCM_RNGD_REG);
> > +             retval += sizeof(u32);
> > +             buf += sizeof(u32);
> > +             max -= sizeof(u32);
> > +     }
> > +
> > +     pm_runtime_mark_last_busy((struct device *)priv->rng.priv);
> > +     pm_runtime_put_sync_autosuspend((struct device *)priv->rng.priv);
> > +
> > +     return retval || !wait ? retval : -EIO;
> > +}
> > +
> > +static int npcm_rng_probe(struct platform_device *pdev)
> > +{
> > +     struct npcm_rng *priv;
> > +     struct resource *res;
> > +     int ret;
> > +
> > +     priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> > +     if (!priv)
> > +             return -ENOMEM;
> > +
> > +     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +     priv->base = devm_ioremap_resource(&pdev->dev, res);
> > +     if (IS_ERR(priv->base))
> > +             return PTR_ERR(priv->base);
> > +
> > +     dev_set_drvdata(&pdev->dev, priv);
> > +     pm_runtime_set_autosuspend_delay(&pdev->dev, 100);
> > +     pm_runtime_use_autosuspend(&pdev->dev);
> > +     pm_runtime_enable(&pdev->dev);
> > +
> > +#ifndef CONFIG_PM
> > +     priv->rng.init = npcm_rng_init;
> > +     priv->rng.cleanup = npcm_rng_cleanup;
> > +#endif
> > +     priv->rng.name = pdev->name;
> > +     priv->rng.read = npcm_rng_read;
> > +     priv->rng.priv = (unsigned long)&pdev->dev;
> > +     priv->rng.quality = 1000;
> > +
> > +     writel(NPCM_RNG_M1ROSEL, priv->base + NPCM_RNGMODE_REG);
> > +
> > +     ret = devm_hwrng_register(&pdev->dev, &priv->rng);
> > +     if (ret) {
> > +             dev_err(&pdev->dev, "Failed to register rng device: %d\n",
> > +                     ret);
> > +             pm_runtime_disable(&pdev->dev);
> > +             pm_runtime_set_suspended(&pdev->dev);
> > +             return ret;
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static int npcm_rng_remove(struct platform_device *pdev)
> > +{
> > +     struct npcm_rng *priv = platform_get_drvdata(pdev);
> > +
> > +     devm_hwrng_unregister(&pdev->dev, &priv->rng);
> > +     pm_runtime_disable(&pdev->dev);
> > +     pm_runtime_set_suspended(&pdev->dev);
> > +
> > +     return 0;
> > +}
> > +
> > +#ifdef CONFIG_PM
> > +static int npcm_rng_runtime_suspend(struct device *dev)
> > +{
> > +     struct npcm_rng *priv = dev_get_drvdata(dev);
> > +
> > +     npcm_rng_cleanup(&priv->rng);
> > +
> > +     return 0;
> > +}
> > +
> > +static int npcm_rng_runtime_resume(struct device *dev)
> > +{
> > +     struct npcm_rng *priv = dev_get_drvdata(dev);
> > +
> > +     return npcm_rng_init(&priv->rng);
> > +}
> > +#endif
> > +
> > +static const struct dev_pm_ops npcm_rng_pm_ops = {
> > +     SET_RUNTIME_PM_OPS(npcm_rng_runtime_suspend,
> > +                        npcm_rng_runtime_resume, NULL)
> > +     SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
> > +                             pm_runtime_force_resume)
> > +};
> > +
> > +static const struct of_device_id rng_dt_id[] = {
> > +     { .compatible = "nuvoton,npcm750-rng",  },
> > +     {},
> > +};
> > +MODULE_DEVICE_TABLE(of, rng_dt_id);
> > +
> > +static struct platform_driver npcm_rng_driver = {
> > +     .driver = {
> > +             .name           = "npcm-rng",
> > +             .pm             = &npcm_rng_pm_ops,
> > +             .of_match_table = of_match_ptr(rng_dt_id),
> > +     },
> > +     .probe          = npcm_rng_probe,
> > +     .remove         = npcm_rng_remove,
> > +};
> > +
> > +module_platform_driver(npcm_rng_driver);
> > +
> > +MODULE_DESCRIPTION("Nuvoton NPCM Random Number Generator Driver");
> > +MODULE_AUTHOR("Tomer Maimon <tomer.maimon@nuvoton.com>");
> > +MODULE_LICENSE("GPL v2");
> > --
> > 2.18.0
>
> --
> ~Vinod
>

[-- Attachment #2: Type: text/html, Size: 11492 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 2/2] hwrng: npcm: add NPCM RNG driver
@ 2019-09-15  6:26       ` Tomer Maimon
  0 siblings, 0 replies; 12+ messages in thread
From: Tomer Maimon @ 2019-09-15  6:26 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Herbert Xu, mpm, Arnd Bergmann, Greg KH, Rob Herring,
	Mark Rutland, Avi Fishman, Tali Perry, Patrick Venture,
	Nancy Yuen, Benjamin Fair, sumit.garg, jens.wiklander,
	Thomas Gleixner, Joel Stanley, devicetree,
	Linux Kernel Mailing List, linux-crypto, OpenBMC Maillist

[-- Attachment #1: Type: text/plain, Size: 8552 bytes --]

Hi Vinod,

Thanks for your notification.

NPCM Hardware RNG is true RNG.

Tomer

On Thu, 12 Sep 2019 at 19:47, Vinod Koul <vkoul@kernel.org> wrote:

> On 12-09-19, 12:01, Tomer Maimon wrote:
> > Add Nuvoton NPCM BMC Random Number Generator(RNG) driver.
>
> Is this a true RNG or a psedo RNG, in case of latter it should be added
> in drivers/crypto/. See crypto_register_rng()
>
> >
> > Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
> > ---
> >  drivers/char/hw_random/Kconfig    |  13 +++
> >  drivers/char/hw_random/Makefile   |   1 +
> >  drivers/char/hw_random/npcm-rng.c | 186 ++++++++++++++++++++++++++++++
> >  3 files changed, 200 insertions(+)
> >  create mode 100644 drivers/char/hw_random/npcm-rng.c
> >
> > diff --git a/drivers/char/hw_random/Kconfig
> b/drivers/char/hw_random/Kconfig
> > index 59f25286befe..87a1c30e7958 100644
> > --- a/drivers/char/hw_random/Kconfig
> > +++ b/drivers/char/hw_random/Kconfig
> > @@ -440,6 +440,19 @@ config HW_RANDOM_OPTEE
> >
> >         If unsure, say Y.
> >
> > +config HW_RANDOM_NPCM
> > +     tristate "NPCM Random Number Generator support"
> > +     depends on ARCH_NPCM || COMPILE_TEST
> > +     default HW_RANDOM
> > +     help
> > +       This driver provides support for the Random Number
> > +       Generator hardware available in Nuvoton NPCM SoCs.
> > +
> > +       To compile this driver as a module, choose M here: the
> > +       module will be called npcm-rng.
> > +
> > +       If unsure, say Y.
> > +
> >  endif # HW_RANDOM
> >
> >  config UML_RANDOM
> > diff --git a/drivers/char/hw_random/Makefile
> b/drivers/char/hw_random/Makefile
> > index 7c9ef4a7667f..17b6d4e6d591 100644
> > --- a/drivers/char/hw_random/Makefile
> > +++ b/drivers/char/hw_random/Makefile
> > @@ -39,3 +39,4 @@ obj-$(CONFIG_HW_RANDOM_MTK) += mtk-rng.o
> >  obj-$(CONFIG_HW_RANDOM_S390) += s390-trng.o
> >  obj-$(CONFIG_HW_RANDOM_KEYSTONE) += ks-sa-rng.o
> >  obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o
> > +obj-$(CONFIG_HW_RANDOM_NPCM) += npcm-rng.o
> > diff --git a/drivers/char/hw_random/npcm-rng.c
> b/drivers/char/hw_random/npcm-rng.c
> > new file mode 100644
> > index 000000000000..b7c8c7e13a49
> > --- /dev/null
> > +++ b/drivers/char/hw_random/npcm-rng.c
> > @@ -0,0 +1,186 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +// Copyright (c) 2019 Nuvoton Technology corporation.
> > +
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/io.h>
> > +#include <linux/iopoll.h>
> > +#include <linux/init.h>
> > +#include <linux/random.h>
> > +#include <linux/err.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/hw_random.h>
> > +#include <linux/delay.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/pm_runtime.h>
> > +
> > +#define NPCM_RNGCS_REG               0x00    /* Control and status
> register */
> > +#define NPCM_RNGD_REG                0x04    /* Data register */
> > +#define NPCM_RNGMODE_REG     0x08    /* Mode register */
> > +
> > +#define NPCM_RNG_CLK_SET_25MHZ       GENMASK(4, 3) /* 20-25 MHz */
> > +#define NPCM_RNG_DATA_VALID  BIT(1)
> > +#define NPCM_RNG_ENABLE              BIT(0)
> > +#define NPCM_RNG_M1ROSEL     BIT(1)
> > +
> > +#define NPCM_RNG_TIMEOUT_USEC        20000
> > +#define NPCM_RNG_POLL_USEC   1000
> > +
> > +#define to_npcm_rng(p)       container_of(p, struct npcm_rng, rng)
> > +
> > +struct npcm_rng {
> > +     void __iomem *base;
> > +     struct hwrng rng;
> > +};
> > +
> > +static int npcm_rng_init(struct hwrng *rng)
> > +{
> > +     struct npcm_rng *priv = to_npcm_rng(rng);
> > +
> > +     writel(NPCM_RNG_CLK_SET_25MHZ | NPCM_RNG_ENABLE,
> > +            priv->base + NPCM_RNGCS_REG);
> > +
> > +     return 0;
> > +}
> > +
> > +static void npcm_rng_cleanup(struct hwrng *rng)
> > +{
> > +     struct npcm_rng *priv = to_npcm_rng(rng);
> > +
> > +     writel(NPCM_RNG_CLK_SET_25MHZ, priv->base + NPCM_RNGCS_REG);
> > +}
> > +
> > +static int npcm_rng_read(struct hwrng *rng, void *buf, size_t max, bool
> wait)
> > +{
> > +     struct npcm_rng *priv = to_npcm_rng(rng);
> > +     int retval = 0;
> > +     int ready;
> > +
> > +     pm_runtime_get_sync((struct device *)priv->rng.priv);
> > +
> > +     while (max >= sizeof(u32)) {
> > +             if (wait) {
> > +                     if (readl_poll_timeout(priv->base + NPCM_RNGCS_REG,
> > +                                            ready,
> > +                                            ready & NPCM_RNG_DATA_VALID,
> > +                                            NPCM_RNG_POLL_USEC,
> > +                                            NPCM_RNG_TIMEOUT_USEC))
> > +                             break;
> > +             } else {
> > +                     if ((readl(priv->base + NPCM_RNGCS_REG) &
> > +                         NPCM_RNG_DATA_VALID) == 0)
> > +                             break;
> > +             }
> > +
> > +             *(u32 *)buf = readl(priv->base + NPCM_RNGD_REG);
> > +             retval += sizeof(u32);
> > +             buf += sizeof(u32);
> > +             max -= sizeof(u32);
> > +     }
> > +
> > +     pm_runtime_mark_last_busy((struct device *)priv->rng.priv);
> > +     pm_runtime_put_sync_autosuspend((struct device *)priv->rng.priv);
> > +
> > +     return retval || !wait ? retval : -EIO;
> > +}
> > +
> > +static int npcm_rng_probe(struct platform_device *pdev)
> > +{
> > +     struct npcm_rng *priv;
> > +     struct resource *res;
> > +     int ret;
> > +
> > +     priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> > +     if (!priv)
> > +             return -ENOMEM;
> > +
> > +     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +     priv->base = devm_ioremap_resource(&pdev->dev, res);
> > +     if (IS_ERR(priv->base))
> > +             return PTR_ERR(priv->base);
> > +
> > +     dev_set_drvdata(&pdev->dev, priv);
> > +     pm_runtime_set_autosuspend_delay(&pdev->dev, 100);
> > +     pm_runtime_use_autosuspend(&pdev->dev);
> > +     pm_runtime_enable(&pdev->dev);
> > +
> > +#ifndef CONFIG_PM
> > +     priv->rng.init = npcm_rng_init;
> > +     priv->rng.cleanup = npcm_rng_cleanup;
> > +#endif
> > +     priv->rng.name = pdev->name;
> > +     priv->rng.read = npcm_rng_read;
> > +     priv->rng.priv = (unsigned long)&pdev->dev;
> > +     priv->rng.quality = 1000;
> > +
> > +     writel(NPCM_RNG_M1ROSEL, priv->base + NPCM_RNGMODE_REG);
> > +
> > +     ret = devm_hwrng_register(&pdev->dev, &priv->rng);
> > +     if (ret) {
> > +             dev_err(&pdev->dev, "Failed to register rng device: %d\n",
> > +                     ret);
> > +             pm_runtime_disable(&pdev->dev);
> > +             pm_runtime_set_suspended(&pdev->dev);
> > +             return ret;
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static int npcm_rng_remove(struct platform_device *pdev)
> > +{
> > +     struct npcm_rng *priv = platform_get_drvdata(pdev);
> > +
> > +     devm_hwrng_unregister(&pdev->dev, &priv->rng);
> > +     pm_runtime_disable(&pdev->dev);
> > +     pm_runtime_set_suspended(&pdev->dev);
> > +
> > +     return 0;
> > +}
> > +
> > +#ifdef CONFIG_PM
> > +static int npcm_rng_runtime_suspend(struct device *dev)
> > +{
> > +     struct npcm_rng *priv = dev_get_drvdata(dev);
> > +
> > +     npcm_rng_cleanup(&priv->rng);
> > +
> > +     return 0;
> > +}
> > +
> > +static int npcm_rng_runtime_resume(struct device *dev)
> > +{
> > +     struct npcm_rng *priv = dev_get_drvdata(dev);
> > +
> > +     return npcm_rng_init(&priv->rng);
> > +}
> > +#endif
> > +
> > +static const struct dev_pm_ops npcm_rng_pm_ops = {
> > +     SET_RUNTIME_PM_OPS(npcm_rng_runtime_suspend,
> > +                        npcm_rng_runtime_resume, NULL)
> > +     SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
> > +                             pm_runtime_force_resume)
> > +};
> > +
> > +static const struct of_device_id rng_dt_id[] = {
> > +     { .compatible = "nuvoton,npcm750-rng",  },
> > +     {},
> > +};
> > +MODULE_DEVICE_TABLE(of, rng_dt_id);
> > +
> > +static struct platform_driver npcm_rng_driver = {
> > +     .driver = {
> > +             .name           = "npcm-rng",
> > +             .pm             = &npcm_rng_pm_ops,
> > +             .of_match_table = of_match_ptr(rng_dt_id),
> > +     },
> > +     .probe          = npcm_rng_probe,
> > +     .remove         = npcm_rng_remove,
> > +};
> > +
> > +module_platform_driver(npcm_rng_driver);
> > +
> > +MODULE_DESCRIPTION("Nuvoton NPCM Random Number Generator Driver");
> > +MODULE_AUTHOR("Tomer Maimon <tomer.maimon@nuvoton.com>");
> > +MODULE_LICENSE("GPL v2");
> > --
> > 2.18.0
>
> --
> ~Vinod
>

[-- Attachment #2: Type: text/html, Size: 11492 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 1/2] dt-binding: hwrng: add NPCM RNG documentation
  2019-09-12  9:01 ` [PATCH v3 1/2] dt-binding: hwrng: add NPCM RNG documentation Tomer Maimon
@ 2019-09-17 19:57     ` Rob Herring
  0 siblings, 0 replies; 12+ messages in thread
From: Rob Herring @ 2019-09-17 19:57 UTC (permalink / raw)
  To: Tomer Maimon
  Cc: mpm, herbert, arnd, gregkh, robh+dt, mark.rutland, avifishman70,
	tali.perry1, venture, yuenn, benjaminfair, sumit.garg,
	jens.wiklander, vkoul, tglx, joel, devicetree, linux-kernel,
	linux-crypto, openbmc, Tomer Maimon

On Thu, 12 Sep 2019 12:01:48 +0300, Tomer Maimon wrote:
> Added device tree binding documentation for Nuvoton BMC
> NPCM Random Number Generator (RNG).
> 
> Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
> ---
>  .../devicetree/bindings/rng/nuvoton,npcm-rng.txt     | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/rng/nuvoton,npcm-rng.txt
> 

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 1/2] dt-binding: hwrng: add NPCM RNG documentation
@ 2019-09-17 19:57     ` Rob Herring
  0 siblings, 0 replies; 12+ messages in thread
From: Rob Herring @ 2019-09-17 19:57 UTC (permalink / raw)
  Cc: mpm, herbert, arnd, gregkh, robh+dt, mark.rutland, avifishman70,
	tali.perry1, venture, yuenn, benjaminfair, sumit.garg,
	jens.wiklander, vkoul, tglx, joel, devicetree, linux-kernel,
	linux-crypto, openbmc, Tomer Maimon

On Thu, 12 Sep 2019 12:01:48 +0300, Tomer Maimon wrote:
> Added device tree binding documentation for Nuvoton BMC
> NPCM Random Number Generator (RNG).
> 
> Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
> ---
>  .../devicetree/bindings/rng/nuvoton,npcm-rng.txt     | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/rng/nuvoton,npcm-rng.txt
> 

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 2/2] hwrng: npcm: add NPCM RNG driver
  2019-09-15  6:26       ` Tomer Maimon
  (?)
@ 2019-10-02 12:41       ` Tomer Maimon
  -1 siblings, 0 replies; 12+ messages in thread
From: Tomer Maimon @ 2019-10-02 12:41 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Herbert Xu, mpm, Arnd Bergmann, Greg KH, Rob Herring,
	Mark Rutland, Avi Fishman, Tali Perry, Patrick Venture,
	Nancy Yuen, Benjamin Fair, sumit.garg, Jens Wiklander,
	Thomas Gleixner, Joel Stanley, devicetree,
	Linux Kernel Mailing List, linux-crypto, OpenBMC Maillist

[-- Attachment #1: Type: text/plain, Size: 9013 bytes --]

HI all,

Appreciate a lot if one of the maintainers can take a look on HWRNG-NPCM
driver.

Thanks a lot!

Tomer


On Sun, 15 Sep 2019 at 09:26, Tomer Maimon <tmaimon77@gmail.com> wrote:

> Hi Vinod,
>
> Thanks for your notification.
>
> NPCM Hardware RNG is true RNG.
>
> Tomer
>
> On Thu, 12 Sep 2019 at 19:47, Vinod Koul <vkoul@kernel.org> wrote:
>
>> On 12-09-19, 12:01, Tomer Maimon wrote:
>> > Add Nuvoton NPCM BMC Random Number Generator(RNG) driver.
>>
>> Is this a true RNG or a psedo RNG, in case of latter it should be added
>> in drivers/crypto/. See crypto_register_rng()
>>
>> >
>> > Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
>> > ---
>> >  drivers/char/hw_random/Kconfig    |  13 +++
>> >  drivers/char/hw_random/Makefile   |   1 +
>> >  drivers/char/hw_random/npcm-rng.c | 186 ++++++++++++++++++++++++++++++
>> >  3 files changed, 200 insertions(+)
>> >  create mode 100644 drivers/char/hw_random/npcm-rng.c
>> >
>> > diff --git a/drivers/char/hw_random/Kconfig
>> b/drivers/char/hw_random/Kconfig
>> > index 59f25286befe..87a1c30e7958 100644
>> > --- a/drivers/char/hw_random/Kconfig
>> > +++ b/drivers/char/hw_random/Kconfig
>> > @@ -440,6 +440,19 @@ config HW_RANDOM_OPTEE
>> >
>> >         If unsure, say Y.
>> >
>> > +config HW_RANDOM_NPCM
>> > +     tristate "NPCM Random Number Generator support"
>> > +     depends on ARCH_NPCM || COMPILE_TEST
>> > +     default HW_RANDOM
>> > +     help
>> > +       This driver provides support for the Random Number
>> > +       Generator hardware available in Nuvoton NPCM SoCs.
>> > +
>> > +       To compile this driver as a module, choose M here: the
>> > +       module will be called npcm-rng.
>> > +
>> > +       If unsure, say Y.
>> > +
>> >  endif # HW_RANDOM
>> >
>> >  config UML_RANDOM
>> > diff --git a/drivers/char/hw_random/Makefile
>> b/drivers/char/hw_random/Makefile
>> > index 7c9ef4a7667f..17b6d4e6d591 100644
>> > --- a/drivers/char/hw_random/Makefile
>> > +++ b/drivers/char/hw_random/Makefile
>> > @@ -39,3 +39,4 @@ obj-$(CONFIG_HW_RANDOM_MTK) += mtk-rng.o
>> >  obj-$(CONFIG_HW_RANDOM_S390) += s390-trng.o
>> >  obj-$(CONFIG_HW_RANDOM_KEYSTONE) += ks-sa-rng.o
>> >  obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o
>> > +obj-$(CONFIG_HW_RANDOM_NPCM) += npcm-rng.o
>> > diff --git a/drivers/char/hw_random/npcm-rng.c
>> b/drivers/char/hw_random/npcm-rng.c
>> > new file mode 100644
>> > index 000000000000..b7c8c7e13a49
>> > --- /dev/null
>> > +++ b/drivers/char/hw_random/npcm-rng.c
>> > @@ -0,0 +1,186 @@
>> > +// SPDX-License-Identifier: GPL-2.0
>> > +// Copyright (c) 2019 Nuvoton Technology corporation.
>> > +
>> > +#include <linux/kernel.h>
>> > +#include <linux/module.h>
>> > +#include <linux/io.h>
>> > +#include <linux/iopoll.h>
>> > +#include <linux/init.h>
>> > +#include <linux/random.h>
>> > +#include <linux/err.h>
>> > +#include <linux/platform_device.h>
>> > +#include <linux/hw_random.h>
>> > +#include <linux/delay.h>
>> > +#include <linux/of_irq.h>
>> > +#include <linux/pm_runtime.h>
>> > +
>> > +#define NPCM_RNGCS_REG               0x00    /* Control and status
>> register */
>> > +#define NPCM_RNGD_REG                0x04    /* Data register */
>> > +#define NPCM_RNGMODE_REG     0x08    /* Mode register */
>> > +
>> > +#define NPCM_RNG_CLK_SET_25MHZ       GENMASK(4, 3) /* 20-25 MHz */
>> > +#define NPCM_RNG_DATA_VALID  BIT(1)
>> > +#define NPCM_RNG_ENABLE              BIT(0)
>> > +#define NPCM_RNG_M1ROSEL     BIT(1)
>> > +
>> > +#define NPCM_RNG_TIMEOUT_USEC        20000
>> > +#define NPCM_RNG_POLL_USEC   1000
>> > +
>> > +#define to_npcm_rng(p)       container_of(p, struct npcm_rng, rng)
>> > +
>> > +struct npcm_rng {
>> > +     void __iomem *base;
>> > +     struct hwrng rng;
>> > +};
>> > +
>> > +static int npcm_rng_init(struct hwrng *rng)
>> > +{
>> > +     struct npcm_rng *priv = to_npcm_rng(rng);
>> > +
>> > +     writel(NPCM_RNG_CLK_SET_25MHZ | NPCM_RNG_ENABLE,
>> > +            priv->base + NPCM_RNGCS_REG);
>> > +
>> > +     return 0;
>> > +}
>> > +
>> > +static void npcm_rng_cleanup(struct hwrng *rng)
>> > +{
>> > +     struct npcm_rng *priv = to_npcm_rng(rng);
>> > +
>> > +     writel(NPCM_RNG_CLK_SET_25MHZ, priv->base + NPCM_RNGCS_REG);
>> > +}
>> > +
>> > +static int npcm_rng_read(struct hwrng *rng, void *buf, size_t max,
>> bool wait)
>> > +{
>> > +     struct npcm_rng *priv = to_npcm_rng(rng);
>> > +     int retval = 0;
>> > +     int ready;
>> > +
>> > +     pm_runtime_get_sync((struct device *)priv->rng.priv);
>> > +
>> > +     while (max >= sizeof(u32)) {
>> > +             if (wait) {
>> > +                     if (readl_poll_timeout(priv->base +
>> NPCM_RNGCS_REG,
>> > +                                            ready,
>> > +                                            ready &
>> NPCM_RNG_DATA_VALID,
>> > +                                            NPCM_RNG_POLL_USEC,
>> > +                                            NPCM_RNG_TIMEOUT_USEC))
>> > +                             break;
>> > +             } else {
>> > +                     if ((readl(priv->base + NPCM_RNGCS_REG) &
>> > +                         NPCM_RNG_DATA_VALID) == 0)
>> > +                             break;
>> > +             }
>> > +
>> > +             *(u32 *)buf = readl(priv->base + NPCM_RNGD_REG);
>> > +             retval += sizeof(u32);
>> > +             buf += sizeof(u32);
>> > +             max -= sizeof(u32);
>> > +     }
>> > +
>> > +     pm_runtime_mark_last_busy((struct device *)priv->rng.priv);
>> > +     pm_runtime_put_sync_autosuspend((struct device *)priv->rng.priv);
>> > +
>> > +     return retval || !wait ? retval : -EIO;
>> > +}
>> > +
>> > +static int npcm_rng_probe(struct platform_device *pdev)
>> > +{
>> > +     struct npcm_rng *priv;
>> > +     struct resource *res;
>> > +     int ret;
>> > +
>> > +     priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
>> > +     if (!priv)
>> > +             return -ENOMEM;
>> > +
>> > +     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> > +     priv->base = devm_ioremap_resource(&pdev->dev, res);
>> > +     if (IS_ERR(priv->base))
>> > +             return PTR_ERR(priv->base);
>> > +
>> > +     dev_set_drvdata(&pdev->dev, priv);
>> > +     pm_runtime_set_autosuspend_delay(&pdev->dev, 100);
>> > +     pm_runtime_use_autosuspend(&pdev->dev);
>> > +     pm_runtime_enable(&pdev->dev);
>> > +
>> > +#ifndef CONFIG_PM
>> > +     priv->rng.init = npcm_rng_init;
>> > +     priv->rng.cleanup = npcm_rng_cleanup;
>> > +#endif
>> > +     priv->rng.name = pdev->name;
>> > +     priv->rng.read = npcm_rng_read;
>> > +     priv->rng.priv = (unsigned long)&pdev->dev;
>> > +     priv->rng.quality = 1000;
>> > +
>> > +     writel(NPCM_RNG_M1ROSEL, priv->base + NPCM_RNGMODE_REG);
>> > +
>> > +     ret = devm_hwrng_register(&pdev->dev, &priv->rng);
>> > +     if (ret) {
>> > +             dev_err(&pdev->dev, "Failed to register rng device: %d\n",
>> > +                     ret);
>> > +             pm_runtime_disable(&pdev->dev);
>> > +             pm_runtime_set_suspended(&pdev->dev);
>> > +             return ret;
>> > +     }
>> > +
>> > +     return 0;
>> > +}
>> > +
>> > +static int npcm_rng_remove(struct platform_device *pdev)
>> > +{
>> > +     struct npcm_rng *priv = platform_get_drvdata(pdev);
>> > +
>> > +     devm_hwrng_unregister(&pdev->dev, &priv->rng);
>> > +     pm_runtime_disable(&pdev->dev);
>> > +     pm_runtime_set_suspended(&pdev->dev);
>> > +
>> > +     return 0;
>> > +}
>> > +
>> > +#ifdef CONFIG_PM
>> > +static int npcm_rng_runtime_suspend(struct device *dev)
>> > +{
>> > +     struct npcm_rng *priv = dev_get_drvdata(dev);
>> > +
>> > +     npcm_rng_cleanup(&priv->rng);
>> > +
>> > +     return 0;
>> > +}
>> > +
>> > +static int npcm_rng_runtime_resume(struct device *dev)
>> > +{
>> > +     struct npcm_rng *priv = dev_get_drvdata(dev);
>> > +
>> > +     return npcm_rng_init(&priv->rng);
>> > +}
>> > +#endif
>> > +
>> > +static const struct dev_pm_ops npcm_rng_pm_ops = {
>> > +     SET_RUNTIME_PM_OPS(npcm_rng_runtime_suspend,
>> > +                        npcm_rng_runtime_resume, NULL)
>> > +     SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
>> > +                             pm_runtime_force_resume)
>> > +};
>> > +
>> > +static const struct of_device_id rng_dt_id[] = {
>> > +     { .compatible = "nuvoton,npcm750-rng",  },
>> > +     {},
>> > +};
>> > +MODULE_DEVICE_TABLE(of, rng_dt_id);
>> > +
>> > +static struct platform_driver npcm_rng_driver = {
>> > +     .driver = {
>> > +             .name           = "npcm-rng",
>> > +             .pm             = &npcm_rng_pm_ops,
>> > +             .of_match_table = of_match_ptr(rng_dt_id),
>> > +     },
>> > +     .probe          = npcm_rng_probe,
>> > +     .remove         = npcm_rng_remove,
>> > +};
>> > +
>> > +module_platform_driver(npcm_rng_driver);
>> > +
>> > +MODULE_DESCRIPTION("Nuvoton NPCM Random Number Generator Driver");
>> > +MODULE_AUTHOR("Tomer Maimon <tomer.maimon@nuvoton.com>");
>> > +MODULE_LICENSE("GPL v2");
>> > --
>> > 2.18.0
>>
>> --
>> ~Vinod
>>
>

[-- Attachment #2: Type: text/html, Size: 12060 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 0/2] hwrng: npcm: add NPCM RNG driver support
  2019-09-12  9:01 [PATCH v3 0/2] hwrng: npcm: add NPCM RNG driver support Tomer Maimon
  2019-09-12  9:01 ` [PATCH v3 1/2] dt-binding: hwrng: add NPCM RNG documentation Tomer Maimon
  2019-09-12  9:01 ` [PATCH v3 2/2] hwrng: npcm: add NPCM RNG driver Tomer Maimon
@ 2019-10-04 15:29 ` Herbert Xu
  2 siblings, 0 replies; 12+ messages in thread
From: Herbert Xu @ 2019-10-04 15:29 UTC (permalink / raw)
  To: Tomer Maimon
  Cc: mpm, arnd, gregkh, robh+dt, mark.rutland, avifishman70,
	tali.perry1, venture, yuenn, benjaminfair, sumit.garg,
	jens.wiklander, vkoul, tglx, joel, devicetree, linux-kernel,
	linux-crypto, openbmc

On Thu, Sep 12, 2019 at 12:01:47PM +0300, Tomer Maimon wrote:
> This patch set adds Random Number Generator (RNG) support 
> for the Nuvoton NPCM Baseboard Management Controller (BMC).
> 
> The RNG driver we use power consumption when the RNG 
> is not required.
> 
> The NPCM RNG driver tested on NPCM750 evaluation board.
> 
> Addressed comments from:.
>  - Daniel Thompson: https://lkml.org/lkml/2019/9/10/352
>  - Milton Miller II : https://lkml.org/lkml/2019/9/10/847
>  - Daniel Thompson: https://lkml.org/lkml/2019/9/10/294
> 
> Changes since version 2:
>  - Rearrange wait parameter in npcm_rng_read function.
>  - Calling pm_runtime_enable function before hwrng_register function 
>    called to enable the hwrng before add_early_randomness called.
>  - Remove quality dt-binding parameter in the driver and documentation.
>  - Disable CONFIG_PM if devm_hwrng_register failed.
>  - Remove owner setting in the driver struct.
> 
> Changes since version 1:
>  - Define timout in real-world units.
>  - Using readl_poll_timeout in rng_read function.
>  - Honor wait parameter in rng_read function.
>  - Using local variable instead of #ifndef.
>  - Remove probe print.
> 
> Tomer Maimon (2):
>   dt-binding: hwrng: add NPCM RNG documentation
>   hwrng: npcm: add NPCM RNG driver
> 
>  .../bindings/rng/nuvoton,npcm-rng.txt         |  12 ++
>  drivers/char/hw_random/Kconfig                |  13 ++
>  drivers/char/hw_random/Makefile               |   1 +
>  drivers/char/hw_random/npcm-rng.c             | 186 ++++++++++++++++++
>  4 files changed, 212 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/rng/nuvoton,npcm-rng.txt
>  create mode 100644 drivers/char/hw_random/npcm-rng.c

All applied.  Thanks.
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2019-10-04 15:30 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-12  9:01 [PATCH v3 0/2] hwrng: npcm: add NPCM RNG driver support Tomer Maimon
2019-09-12  9:01 ` [PATCH v3 1/2] dt-binding: hwrng: add NPCM RNG documentation Tomer Maimon
2019-09-17 19:57   ` Rob Herring
2019-09-17 19:57     ` Rob Herring
2019-09-12  9:01 ` [PATCH v3 2/2] hwrng: npcm: add NPCM RNG driver Tomer Maimon
2019-09-12 16:46   ` Vinod Koul
2019-09-12 16:46     ` Vinod Koul
2019-09-15  6:26     ` Tomer Maimon
2019-09-15  6:26       ` Tomer Maimon
2019-10-02 12:41       ` Tomer Maimon
2019-09-13  9:28   ` Daniel Thompson
2019-10-04 15:29 ` [PATCH v3 0/2] hwrng: npcm: add NPCM RNG driver support Herbert Xu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.