[3/5] hw_random: ixp4xx: Turn into a module

Message ID 20210511132928.814697-3-linus.walleij@linaro.org
State Accepted
Commit 854a004305c202d85e2536459187bc7ab5edef31
Headers show
Series
  • [1/5] hw_random: ixp4xx: enable compile-testing
Related show

Commit Message

Linus Walleij May 11, 2021, 1:29 p.m.
Instead of just initializing always, which will invariably
create problems on multiplatform builds, turn this driver into
a module and pass a resource with the memory location.
The device only exist on the IXP46x so we only register
the device for the IXP46x SoC.

Cc: Deepak Saxena <dsaxena@plexity.net>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

---
The idea is to apply this through the ARM SoC tree along
with other IXP4xx refactorings.
Please tell me if you prefer another solution.
---
 arch/arm/mach-ixp4xx/common.c       | 24 ++++++++++++++++++-
 drivers/char/hw_random/ixp4xx-rng.c | 37 +++++++++++++----------------
 2 files changed, 40 insertions(+), 21 deletions(-)

-- 
2.30.2

Comments

Herbert Xu May 21, 2021, 7:10 a.m. | #1
On Tue, May 11, 2021 at 03:29:26PM +0200, Linus Walleij wrote:
> Instead of just initializing always, which will invariably

> create problems on multiplatform builds, turn this driver into

> a module and pass a resource with the memory location.

> The device only exist on the IXP46x so we only register

> the device for the IXP46x SoC.

> 

> Cc: Deepak Saxena <dsaxena@plexity.net>

> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

> ---

> The idea is to apply this through the ARM SoC tree along

> with other IXP4xx refactorings.

> Please tell me if you prefer another solution.

> ---

>  arch/arm/mach-ixp4xx/common.c       | 24 ++++++++++++++++++-

>  drivers/char/hw_random/ixp4xx-rng.c | 37 +++++++++++++----------------

>  2 files changed, 40 insertions(+), 21 deletions(-)


Acked-by: Herbert Xu <herbert@gondor.apana.org.au>

-- 
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

Patch

diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index f86c1bf34eea..a10aa14d09b1 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -237,6 +237,27 @@  static struct resource ixp46x_i2c_resources[] = {
 	}
 };
 
+/* A single 32-bit register on IXP46x */
+#define IXP4XX_HWRANDOM_BASE_PHYS	0x70002100
+
+static struct resource ixp46x_hwrandom_resource[] = {
+	{
+		.start = IXP4XX_HWRANDOM_BASE_PHYS,
+		.end = IXP4XX_HWRANDOM_BASE_PHYS + 0x3,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device ixp46x_hwrandom_device = {
+	.name           = "ixp4xx-hwrandom",
+	.id             = -1,
+	.dev = {
+		.coherent_dma_mask      = DMA_BIT_MASK(32),
+	},
+	.resource = ixp46x_hwrandom_resource,
+	.num_resources  = ARRAY_SIZE(ixp46x_hwrandom_resource),
+};
+
 /*
  * I2C controller. The IXP46x uses the same block as the IOP3xx, so
  * we just use the same device name.
@@ -249,7 +270,8 @@  static struct platform_device ixp46x_i2c_controller = {
 };
 
 static struct platform_device *ixp46x_devices[] __initdata = {
-	&ixp46x_i2c_controller
+	&ixp46x_hwrandom_device,
+	&ixp46x_i2c_controller,
 };
 
 unsigned long ixp4xx_exp_bus_size;
diff --git a/drivers/char/hw_random/ixp4xx-rng.c b/drivers/char/hw_random/ixp4xx-rng.c
index defd8176cb68..8b59aeefd4a4 100644
--- a/drivers/char/hw_random/ixp4xx-rng.c
+++ b/drivers/char/hw_random/ixp4xx-rng.c
@@ -15,6 +15,7 @@ 
 #include <linux/types.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/platform_device.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
 #include <linux/hw_random.h>
@@ -36,35 +37,31 @@  static struct hwrng ixp4xx_rng_ops = {
 	.data_read	= ixp4xx_rng_data_read,
 };
 
-static int __init ixp4xx_rng_init(void)
+static int ixp4xx_rng_probe(struct platform_device *pdev)
 {
 	void __iomem * rng_base;
-	int err;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
 
 	if (!cpu_is_ixp46x()) /* includes IXP455 */
 		return -ENOSYS;
 
-	rng_base = ioremap(0x70002100, 4);
-	if (!rng_base)
-		return -ENOMEM;
-	ixp4xx_rng_ops.priv = (unsigned long)rng_base;
-	err = hwrng_register(&ixp4xx_rng_ops);
-	if (err)
-		iounmap(rng_base);
-
-	return err;
-}
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	rng_base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(rng_base))
+		return PTR_ERR(rng_base);
 
-static void __exit ixp4xx_rng_exit(void)
-{
-	void __iomem * rng_base = (void __iomem *)ixp4xx_rng_ops.priv;
-
-	hwrng_unregister(&ixp4xx_rng_ops);
-	iounmap(rng_base);
+	ixp4xx_rng_ops.priv = (unsigned long)rng_base;
+	return devm_hwrng_register(dev, &ixp4xx_rng_ops);
 }
 
-module_init(ixp4xx_rng_init);
-module_exit(ixp4xx_rng_exit);
+static struct platform_driver ixp4xx_rng_driver = {
+	.driver = {
+		.name = "ixp4xx-hwrandom",
+	},
+	.probe = ixp4xx_rng_probe,
+};
+module_platform_driver(ixp4xx_rng_driver);
 
 MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>");
 MODULE_DESCRIPTION("H/W Pseudo-Random Number Generator (RNG) driver for IXP45x/46x");