hwrng: npcm - Add NPCM8XX support
authorTomer Maimon <tmaimon77@gmail.com>
Thu, 29 Sep 2022 13:31:11 +0000 (16:31 +0300)
committerHerbert Xu <herbert@gondor.apana.org.au>
Fri, 21 Oct 2022 11:15:35 +0000 (19:15 +0800)
Adding RNG NPCM8XX support to NPCM RNG driver.
RNG NPCM8XX uses a different clock prescaler.

As part of adding NPCM8XX support:
- Add NPCM8XX specific compatible string.
- Add data to handle architecture specific clock prescaler.

Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/char/hw_random/npcm-rng.c

index 1ec5f267a6566d10ec536cecd367e671ae5a78c0..5bf7f370f9859655881fec9c092c59ae709ccc45 100644 (file)
 #include <linux/delay.h>
 #include <linux/of_irq.h>
 #include <linux/pm_runtime.h>
+#include <linux/of_device.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_62_5MHZ       BIT(2) /* 60-80 MHz */
 #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)
 struct npcm_rng {
        void __iomem *base;
        struct hwrng rng;
+       u32 clkp;
 };
 
 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);
+       writel(priv->clkp | NPCM_RNG_ENABLE, priv->base + NPCM_RNGCS_REG);
 
        return 0;
 }
@@ -47,7 +49,7 @@ 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);
+       writel(priv->clkp, priv->base + NPCM_RNGCS_REG);
 }
 
 static int npcm_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
@@ -110,6 +112,7 @@ static int npcm_rng_probe(struct platform_device *pdev)
        priv->rng.read = npcm_rng_read;
        priv->rng.priv = (unsigned long)&pdev->dev;
        priv->rng.quality = 1000;
+       priv->clkp = (u32)(uintptr_t)of_device_get_match_data(&pdev->dev);
 
        writel(NPCM_RNG_M1ROSEL, priv->base + NPCM_RNGMODE_REG);
 
@@ -162,7 +165,10 @@ static const struct dev_pm_ops npcm_rng_pm_ops = {
 };
 
 static const struct of_device_id rng_dt_id[] __maybe_unused = {
-       { .compatible = "nuvoton,npcm750-rng",  },
+       { .compatible = "nuvoton,npcm750-rng",
+               .data = (void *)NPCM_RNG_CLK_SET_25MHZ },
+       { .compatible = "nuvoton,npcm845-rng",
+               .data = (void *)NPCM_RNG_CLK_SET_62_5MHZ },
        {},
 };
 MODULE_DEVICE_TABLE(of, rng_dt_id);