From fcdba3c33a4dfdc3dc3f2cce46aaf0d6fc1df6c1 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Wed, 5 Feb 2020 15:00:02 +0100 Subject: hwrng: imx-rngc - improve dependencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The imx-rngc driver binds to devices that are compatible to "fsl,imx25-rngb". Grepping through the device tree sources suggests this only exists on i.MX25. So restrict dependencies to configs that have this SoC enabled, but allow compile testing. For the latter additional dependencies for clk and readl/writel are necessary. Signed-off-by: Uwe Kleine-König Signed-off-by: Herbert Xu --- drivers/char/hw_random/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/char') diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index 914e293ba62b..ddbfa190caf4 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig @@ -244,7 +244,8 @@ config HW_RANDOM_MXC_RNGA config HW_RANDOM_IMX_RNGC tristate "Freescale i.MX RNGC Random Number Generator" - depends on ARCH_MXC + depends on HAS_IOMEM && HAVE_CLK + depends on SOC_IMX25 || COMPILE_TEST default HW_RANDOM ---help--- This driver provides kernel-side support for the Random Number -- cgit v1.2.3 From ba02b35239f7ea08ee9959689a66fee8782c1c8c Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sat, 22 Feb 2020 12:38:55 +1100 Subject: hwrng: omap3-rom - Include linux/io.h for virt_to_phys This patch adds linux/io.h to the header list to ensure that we get virt_to_phys on all architectures. Signed-off-by: Herbert Xu --- drivers/char/hw_random/omap3-rom-rng.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/char') diff --git a/drivers/char/hw_random/omap3-rom-rng.c b/drivers/char/hw_random/omap3-rom-rng.c index e08a8887e718..a431c5cbe2be 100644 --- a/drivers/char/hw_random/omap3-rom-rng.c +++ b/drivers/char/hw_random/omap3-rom-rng.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3 From ace74b627c88ea96d4fe5811a5128475aa6a49a6 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 4 Mar 2020 22:21:48 -0800 Subject: hwrng: ks-sa - move TI Keystone driver into the config menu structure Move the TI Keystone hardware random number generator into the same menu as all of the other hardware random number generators. This makes the driver config be listed in the correct place in the kconfig tools. Fixes: eb428ee0e3ca ("hwrng: ks-sa - add hw_random driver") Signed-off-by: Randy Dunlap Cc: Vitaly Andrianov Cc: Tero Kristo Cc: Murali Karicheri Cc: Herbert Xu Cc: Matt Mackall Cc: linux-crypto@vger.kernel.org Signed-off-by: Herbert Xu --- drivers/char/hw_random/Kconfig | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index ddbfa190caf4..9bc46da8d77a 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig @@ -467,6 +467,13 @@ config HW_RANDOM_NPCM If unsure, say Y. +config HW_RANDOM_KEYSTONE + depends on ARCH_KEYSTONE || COMPILE_TEST + default HW_RANDOM + tristate "TI Keystone NETCP SA Hardware random number generator" + help + This option enables Keystone's hardware random generator. + endif # HW_RANDOM config UML_RANDOM @@ -483,10 +490,3 @@ config UML_RANDOM (check your distro, or download from http://sourceforge.net/projects/gkernel/). rngd periodically reads /dev/hwrng and injects the entropy into /dev/random. - -config HW_RANDOM_KEYSTONE - depends on ARCH_KEYSTONE || COMPILE_TEST - default HW_RANDOM - tristate "TI Keystone NETCP SA Hardware random number generator" - help - This option enables Keystone's hardware random generator. -- cgit v1.2.3 From 47a1f8e8b3637ff5f7806587883d7d94068d9ee8 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Thu, 5 Mar 2020 21:58:20 +0100 Subject: hwrng: imx-rngc - fix an error path Make sure that the rngc interrupt is masked if the rngc self test fails. Self test failure means that probe fails as well. Interrupts should be masked in this case, regardless of the error. Cc: stable@vger.kernel.org Fixes: 1d5449445bd0 ("hwrng: mx-rngc - add a driver for Freescale RNGC") Reviewed-by: PrasannaKumar Muralidharan Signed-off-by: Martin Kaiser Signed-off-by: Herbert Xu --- drivers/char/hw_random/imx-rngc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/char') diff --git a/drivers/char/hw_random/imx-rngc.c b/drivers/char/hw_random/imx-rngc.c index 30cf00f8e9a0..0576801944fd 100644 --- a/drivers/char/hw_random/imx-rngc.c +++ b/drivers/char/hw_random/imx-rngc.c @@ -105,8 +105,10 @@ static int imx_rngc_self_test(struct imx_rngc *rngc) return -ETIMEDOUT; } - if (rngc->err_reg != 0) + if (rngc->err_reg != 0) { + imx_rngc_irq_mask_clear(rngc); return -EIO; + } return 0; } -- cgit v1.2.3 From 3acd9ea9331cd56f9769d16211c865d4638fd12d Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Thu, 5 Mar 2020 21:58:21 +0100 Subject: hwrng: imx-rngc - use automatic seeding The rngc requires a new seed for its prng after generating 2^20 160-bit words of random data. At the moment, we seed the prng only once during initalisation. Set the rngc to auto seed mode so that it kicks off the internal reseeding operation when a new seed is required. Keep the manual calculation of the initial seed when the device is probed and switch to automatic seeding afterwards. Reviewed-by: PrasannaKumar Muralidharan Signed-off-by: Martin Kaiser Signed-off-by: Herbert Xu --- drivers/char/hw_random/imx-rngc.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/hw_random/imx-rngc.c b/drivers/char/hw_random/imx-rngc.c index 0576801944fd..903894518c8d 100644 --- a/drivers/char/hw_random/imx-rngc.c +++ b/drivers/char/hw_random/imx-rngc.c @@ -31,6 +31,7 @@ #define RNGC_CTRL_MASK_ERROR 0x00000040 #define RNGC_CTRL_MASK_DONE 0x00000020 +#define RNGC_CTRL_AUTO_SEED 0x00000010 #define RNGC_STATUS_ERROR 0x00010000 #define RNGC_STATUS_FIFO_LEVEL_MASK 0x00000f00 @@ -167,7 +168,7 @@ static irqreturn_t imx_rngc_irq(int irq, void *priv) static int imx_rngc_init(struct hwrng *rng) { struct imx_rngc *rngc = container_of(rng, struct imx_rngc, rng); - u32 cmd; + u32 cmd, ctrl; int ret; /* clear error */ @@ -192,7 +193,18 @@ static int imx_rngc_init(struct hwrng *rng) } while (rngc->err_reg == RNGC_ERROR_STATUS_STAT_ERR); - return rngc->err_reg ? -EIO : 0; + if (rngc->err_reg) + return -EIO; + + /* + * enable automatic seeding, the rngc creates a new seed automatically + * after serving 2^20 random 160-bit words + */ + ctrl = readl(rngc->base + RNGC_CONTROL); + ctrl |= RNGC_CTRL_AUTO_SEED; + writel(ctrl, rngc->base + RNGC_CONTROL); + + return 0; } static int imx_rngc_probe(struct platform_device *pdev) -- cgit v1.2.3 From f7d79450d192d194a88c37b55c048d3840a5d74b Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Thu, 5 Mar 2020 21:58:22 +0100 Subject: hwrng: imx-rngc - (trivial) simplify error prints Remove the device name, it is added by the dev_...() routines. Drop the error code as well. It will be shown by the driver core when the probe operation failed. Reviewed-by: PrasannaKumar Muralidharan Signed-off-by: Martin Kaiser Signed-off-by: Herbert Xu --- drivers/char/hw_random/imx-rngc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/hw_random/imx-rngc.c b/drivers/char/hw_random/imx-rngc.c index 903894518c8d..92e93abcc9cc 100644 --- a/drivers/char/hw_random/imx-rngc.c +++ b/drivers/char/hw_random/imx-rngc.c @@ -258,14 +258,14 @@ static int imx_rngc_probe(struct platform_device *pdev) if (self_test) { ret = imx_rngc_self_test(rngc); if (ret) { - dev_err(rngc->dev, "FSL RNGC self test failed.\n"); + dev_err(rngc->dev, "self test failed\n"); goto err; } } ret = hwrng_register(&rngc->rng); if (ret) { - dev_err(&pdev->dev, "FSL RNGC registering failed (%d)\n", ret); + dev_err(&pdev->dev, "hwrng registration failed\n"); goto err; } -- cgit v1.2.3 From b9957fc944586da3d4a175c811afec563636c713 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Thu, 5 Mar 2020 21:58:23 +0100 Subject: hwrng: imx-rngc - check the rng type Read the rng type and hardware revision during probe. Fail the probe operation if the type is not one of rngc or rngb. (There's also an rnga type, which needs a different driver.) Display the type and revision in a debug print if probe was successful. Reviewed-by: PrasannaKumar Muralidharan Signed-off-by: Martin Kaiser Signed-off-by: Herbert Xu --- drivers/char/hw_random/imx-rngc.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'drivers/char') diff --git a/drivers/char/hw_random/imx-rngc.c b/drivers/char/hw_random/imx-rngc.c index 92e93abcc9cc..50a8923d829a 100644 --- a/drivers/char/hw_random/imx-rngc.c +++ b/drivers/char/hw_random/imx-rngc.c @@ -18,12 +18,22 @@ #include #include +#define RNGC_VER_ID 0x0000 #define RNGC_COMMAND 0x0004 #define RNGC_CONTROL 0x0008 #define RNGC_STATUS 0x000C #define RNGC_ERROR 0x0010 #define RNGC_FIFO 0x0014 +/* the fields in the ver id register */ +#define RNGC_TYPE_SHIFT 28 +#define RNGC_VER_MAJ_SHIFT 8 + +/* the rng_type field */ +#define RNGC_TYPE_RNGB 0x1 +#define RNGC_TYPE_RNGC 0x2 + + #define RNGC_CMD_CLR_ERR 0x00000020 #define RNGC_CMD_CLR_INT 0x00000010 #define RNGC_CMD_SEED 0x00000002 @@ -212,6 +222,8 @@ static int imx_rngc_probe(struct platform_device *pdev) struct imx_rngc *rngc; int ret; int irq; + u32 ver_id; + u8 rng_type; rngc = devm_kzalloc(&pdev->dev, sizeof(*rngc), GFP_KERNEL); if (!rngc) @@ -237,6 +249,17 @@ static int imx_rngc_probe(struct platform_device *pdev) if (ret) return ret; + ver_id = readl(rngc->base + RNGC_VER_ID); + rng_type = ver_id >> RNGC_TYPE_SHIFT; + /* + * This driver supports only RNGC and RNGB. (There's a different + * driver for RNGA.) + */ + if (rng_type != RNGC_TYPE_RNGC && rng_type != RNGC_TYPE_RNGB) { + ret = -ENODEV; + goto err; + } + ret = devm_request_irq(&pdev->dev, irq, imx_rngc_irq, 0, pdev->name, (void *)rngc); if (ret) { @@ -269,7 +292,10 @@ static int imx_rngc_probe(struct platform_device *pdev) goto err; } - dev_info(&pdev->dev, "Freescale RNGC registered.\n"); + dev_info(&pdev->dev, + "Freescale RNG%c registered (HW revision %d.%02d)\n", + rng_type == RNGC_TYPE_RNGB ? 'B' : 'C', + (ver_id >> RNGC_VER_MAJ_SHIFT) & 0xff, ver_id & 0xff); return 0; err: -- cgit v1.2.3 From f086fd1e43443dd3c3fd26d3d1a59e52fc4bf29b Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Thu, 5 Mar 2020 21:58:24 +0100 Subject: hwrng: imx-rngc - simplify interrupt mask/unmask Use a simpler approach for masking / unmasking the rngc interrupt: The interrupt is unmasked while self-test is running and when the rngc driver is used by the hwrng core. Mask the interrupt again when self test is finished, regardless of self test success or failure. Unmask the interrupt in the init function. Add a cleanup function where the rngc interrupt is masked again. Signed-off-by: Martin Kaiser Signed-off-by: Herbert Xu --- drivers/char/hw_random/imx-rngc.c | 43 +++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 15 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/hw_random/imx-rngc.c b/drivers/char/hw_random/imx-rngc.c index 50a8923d829a..9c47e431ce90 100644 --- a/drivers/char/hw_random/imx-rngc.c +++ b/drivers/char/hw_random/imx-rngc.c @@ -111,17 +111,11 @@ static int imx_rngc_self_test(struct imx_rngc *rngc) writel(cmd | RNGC_CMD_SELF_TEST, rngc->base + RNGC_COMMAND); ret = wait_for_completion_timeout(&rngc->rng_op_done, RNGC_TIMEOUT); - if (!ret) { - imx_rngc_irq_mask_clear(rngc); + imx_rngc_irq_mask_clear(rngc); + if (!ret) return -ETIMEDOUT; - } - - if (rngc->err_reg != 0) { - imx_rngc_irq_mask_clear(rngc); - return -EIO; - } - return 0; + return rngc->err_reg ? -EIO : 0; } static int imx_rngc_read(struct hwrng *rng, void *data, size_t max, bool wait) @@ -185,10 +179,10 @@ static int imx_rngc_init(struct hwrng *rng) cmd = readl(rngc->base + RNGC_COMMAND); writel(cmd | RNGC_CMD_CLR_ERR, rngc->base + RNGC_COMMAND); + imx_rngc_irq_unmask(rngc); + /* create seed, repeat while there is some statistical error */ do { - imx_rngc_irq_unmask(rngc); - /* seed creation */ cmd = readl(rngc->base + RNGC_COMMAND); writel(cmd | RNGC_CMD_SEED, rngc->base + RNGC_COMMAND); @@ -197,14 +191,16 @@ static int imx_rngc_init(struct hwrng *rng) RNGC_TIMEOUT); if (!ret) { - imx_rngc_irq_mask_clear(rngc); - return -ETIMEDOUT; + ret = -ETIMEDOUT; + goto err; } } while (rngc->err_reg == RNGC_ERROR_STATUS_STAT_ERR); - if (rngc->err_reg) - return -EIO; + if (rngc->err_reg) { + ret = -EIO; + goto err; + } /* * enable automatic seeding, the rngc creates a new seed automatically @@ -214,7 +210,23 @@ static int imx_rngc_init(struct hwrng *rng) ctrl |= RNGC_CTRL_AUTO_SEED; writel(ctrl, rngc->base + RNGC_CONTROL); + /* + * if initialisation was successful, we keep the interrupt + * unmasked until imx_rngc_cleanup is called + * we mask the interrupt ourselves if we return an error + */ return 0; + +err: + imx_rngc_irq_mask_clear(rngc); + return ret; +} + +static void imx_rngc_cleanup(struct hwrng *rng) +{ + struct imx_rngc *rngc = container_of(rng, struct imx_rngc, rng); + + imx_rngc_irq_mask_clear(rngc); } static int imx_rngc_probe(struct platform_device *pdev) @@ -272,6 +284,7 @@ static int imx_rngc_probe(struct platform_device *pdev) rngc->rng.name = pdev->name; rngc->rng.init = imx_rngc_init; rngc->rng.read = imx_rngc_read; + rngc->rng.cleanup = imx_rngc_cleanup; rngc->dev = &pdev->dev; platform_set_drvdata(pdev, rngc); -- cgit v1.2.3