Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * RNG driver for Freescale RNGC
0004  *
0005  * Copyright (C) 2008-2012 Freescale Semiconductor, Inc.
0006  * Copyright (C) 2017 Martin Kaiser <martin@kaiser.cx>
0007  */
0008 
0009 #include <linux/module.h>
0010 #include <linux/mod_devicetable.h>
0011 #include <linux/init.h>
0012 #include <linux/kernel.h>
0013 #include <linux/clk.h>
0014 #include <linux/err.h>
0015 #include <linux/platform_device.h>
0016 #include <linux/interrupt.h>
0017 #include <linux/hw_random.h>
0018 #include <linux/completion.h>
0019 #include <linux/io.h>
0020 
0021 #define RNGC_VER_ID         0x0000
0022 #define RNGC_COMMAND            0x0004
0023 #define RNGC_CONTROL            0x0008
0024 #define RNGC_STATUS         0x000C
0025 #define RNGC_ERROR          0x0010
0026 #define RNGC_FIFO           0x0014
0027 
0028 /* the fields in the ver id register */
0029 #define RNGC_TYPE_SHIFT     28
0030 #define RNGC_VER_MAJ_SHIFT      8
0031 
0032 /* the rng_type field */
0033 #define RNGC_TYPE_RNGB          0x1
0034 #define RNGC_TYPE_RNGC          0x2
0035 
0036 
0037 #define RNGC_CMD_CLR_ERR        0x00000020
0038 #define RNGC_CMD_CLR_INT        0x00000010
0039 #define RNGC_CMD_SEED           0x00000002
0040 #define RNGC_CMD_SELF_TEST      0x00000001
0041 
0042 #define RNGC_CTRL_MASK_ERROR        0x00000040
0043 #define RNGC_CTRL_MASK_DONE     0x00000020
0044 #define RNGC_CTRL_AUTO_SEED     0x00000010
0045 
0046 #define RNGC_STATUS_ERROR       0x00010000
0047 #define RNGC_STATUS_FIFO_LEVEL_MASK 0x00000f00
0048 #define RNGC_STATUS_FIFO_LEVEL_SHIFT    8
0049 #define RNGC_STATUS_SEED_DONE       0x00000020
0050 #define RNGC_STATUS_ST_DONE     0x00000010
0051 
0052 #define RNGC_ERROR_STATUS_STAT_ERR  0x00000008
0053 
0054 #define RNGC_TIMEOUT  3000 /* 3 sec */
0055 
0056 
0057 static bool self_test = true;
0058 module_param(self_test, bool, 0);
0059 
0060 struct imx_rngc {
0061     struct device       *dev;
0062     struct clk      *clk;
0063     void __iomem        *base;
0064     struct hwrng        rng;
0065     struct completion   rng_op_done;
0066     /*
0067      * err_reg is written only by the irq handler and read only
0068      * when interrupts are masked, we need no spinlock
0069      */
0070     u32         err_reg;
0071 };
0072 
0073 
0074 static inline void imx_rngc_irq_mask_clear(struct imx_rngc *rngc)
0075 {
0076     u32 ctrl, cmd;
0077 
0078     /* mask interrupts */
0079     ctrl = readl(rngc->base + RNGC_CONTROL);
0080     ctrl |= RNGC_CTRL_MASK_DONE | RNGC_CTRL_MASK_ERROR;
0081     writel(ctrl, rngc->base + RNGC_CONTROL);
0082 
0083     /*
0084      * CLR_INT clears the interrupt only if there's no error
0085      * CLR_ERR clear the interrupt and the error register if there
0086      * is an error
0087      */
0088     cmd = readl(rngc->base + RNGC_COMMAND);
0089     cmd |= RNGC_CMD_CLR_INT | RNGC_CMD_CLR_ERR;
0090     writel(cmd, rngc->base + RNGC_COMMAND);
0091 }
0092 
0093 static inline void imx_rngc_irq_unmask(struct imx_rngc *rngc)
0094 {
0095     u32 ctrl;
0096 
0097     ctrl = readl(rngc->base + RNGC_CONTROL);
0098     ctrl &= ~(RNGC_CTRL_MASK_DONE | RNGC_CTRL_MASK_ERROR);
0099     writel(ctrl, rngc->base + RNGC_CONTROL);
0100 }
0101 
0102 static int imx_rngc_self_test(struct imx_rngc *rngc)
0103 {
0104     u32 cmd;
0105     int ret;
0106 
0107     imx_rngc_irq_unmask(rngc);
0108 
0109     /* run self test */
0110     cmd = readl(rngc->base + RNGC_COMMAND);
0111     writel(cmd | RNGC_CMD_SELF_TEST, rngc->base + RNGC_COMMAND);
0112 
0113     ret = wait_for_completion_timeout(&rngc->rng_op_done, RNGC_TIMEOUT);
0114     imx_rngc_irq_mask_clear(rngc);
0115     if (!ret)
0116         return -ETIMEDOUT;
0117 
0118     return rngc->err_reg ? -EIO : 0;
0119 }
0120 
0121 static int imx_rngc_read(struct hwrng *rng, void *data, size_t max, bool wait)
0122 {
0123     struct imx_rngc *rngc = container_of(rng, struct imx_rngc, rng);
0124     unsigned int status;
0125     unsigned int level;
0126     int retval = 0;
0127 
0128     while (max >= sizeof(u32)) {
0129         status = readl(rngc->base + RNGC_STATUS);
0130 
0131         /* is there some error while reading this random number? */
0132         if (status & RNGC_STATUS_ERROR)
0133             break;
0134 
0135         /* how many random numbers are in FIFO? [0-16] */
0136         level = (status & RNGC_STATUS_FIFO_LEVEL_MASK) >>
0137             RNGC_STATUS_FIFO_LEVEL_SHIFT;
0138 
0139         if (level) {
0140             /* retrieve a random number from FIFO */
0141             *(u32 *)data = readl(rngc->base + RNGC_FIFO);
0142 
0143             retval += sizeof(u32);
0144             data += sizeof(u32);
0145             max -= sizeof(u32);
0146         }
0147     }
0148 
0149     return retval ? retval : -EIO;
0150 }
0151 
0152 static irqreturn_t imx_rngc_irq(int irq, void *priv)
0153 {
0154     struct imx_rngc *rngc = (struct imx_rngc *)priv;
0155     u32 status;
0156 
0157     /*
0158      * clearing the interrupt will also clear the error register
0159      * read error and status before clearing
0160      */
0161     status = readl(rngc->base + RNGC_STATUS);
0162     rngc->err_reg = readl(rngc->base + RNGC_ERROR);
0163 
0164     imx_rngc_irq_mask_clear(rngc);
0165 
0166     if (status & (RNGC_STATUS_SEED_DONE | RNGC_STATUS_ST_DONE))
0167         complete(&rngc->rng_op_done);
0168 
0169     return IRQ_HANDLED;
0170 }
0171 
0172 static int imx_rngc_init(struct hwrng *rng)
0173 {
0174     struct imx_rngc *rngc = container_of(rng, struct imx_rngc, rng);
0175     u32 cmd, ctrl;
0176     int ret;
0177 
0178     /* clear error */
0179     cmd = readl(rngc->base + RNGC_COMMAND);
0180     writel(cmd | RNGC_CMD_CLR_ERR, rngc->base + RNGC_COMMAND);
0181 
0182     imx_rngc_irq_unmask(rngc);
0183 
0184     /* create seed, repeat while there is some statistical error */
0185     do {
0186         /* seed creation */
0187         cmd = readl(rngc->base + RNGC_COMMAND);
0188         writel(cmd | RNGC_CMD_SEED, rngc->base + RNGC_COMMAND);
0189 
0190         ret = wait_for_completion_timeout(&rngc->rng_op_done,
0191                 RNGC_TIMEOUT);
0192 
0193         if (!ret) {
0194             ret = -ETIMEDOUT;
0195             goto err;
0196         }
0197 
0198     } while (rngc->err_reg == RNGC_ERROR_STATUS_STAT_ERR);
0199 
0200     if (rngc->err_reg) {
0201         ret = -EIO;
0202         goto err;
0203     }
0204 
0205     /*
0206      * enable automatic seeding, the rngc creates a new seed automatically
0207      * after serving 2^20 random 160-bit words
0208      */
0209     ctrl = readl(rngc->base + RNGC_CONTROL);
0210     ctrl |= RNGC_CTRL_AUTO_SEED;
0211     writel(ctrl, rngc->base + RNGC_CONTROL);
0212 
0213     /*
0214      * if initialisation was successful, we keep the interrupt
0215      * unmasked until imx_rngc_cleanup is called
0216      * we mask the interrupt ourselves if we return an error
0217      */
0218     return 0;
0219 
0220 err:
0221     imx_rngc_irq_mask_clear(rngc);
0222     return ret;
0223 }
0224 
0225 static void imx_rngc_cleanup(struct hwrng *rng)
0226 {
0227     struct imx_rngc *rngc = container_of(rng, struct imx_rngc, rng);
0228 
0229     imx_rngc_irq_mask_clear(rngc);
0230 }
0231 
0232 static int imx_rngc_probe(struct platform_device *pdev)
0233 {
0234     struct imx_rngc *rngc;
0235     int ret;
0236     int irq;
0237     u32 ver_id;
0238     u8  rng_type;
0239 
0240     rngc = devm_kzalloc(&pdev->dev, sizeof(*rngc), GFP_KERNEL);
0241     if (!rngc)
0242         return -ENOMEM;
0243 
0244     rngc->base = devm_platform_ioremap_resource(pdev, 0);
0245     if (IS_ERR(rngc->base))
0246         return PTR_ERR(rngc->base);
0247 
0248     rngc->clk = devm_clk_get(&pdev->dev, NULL);
0249     if (IS_ERR(rngc->clk)) {
0250         dev_err(&pdev->dev, "Can not get rng_clk\n");
0251         return PTR_ERR(rngc->clk);
0252     }
0253 
0254     irq = platform_get_irq(pdev, 0);
0255     if (irq < 0)
0256         return irq;
0257 
0258     ret = clk_prepare_enable(rngc->clk);
0259     if (ret)
0260         return ret;
0261 
0262     ver_id = readl(rngc->base + RNGC_VER_ID);
0263     rng_type = ver_id >> RNGC_TYPE_SHIFT;
0264     /*
0265      * This driver supports only RNGC and RNGB. (There's a different
0266      * driver for RNGA.)
0267      */
0268     if (rng_type != RNGC_TYPE_RNGC && rng_type != RNGC_TYPE_RNGB) {
0269         ret = -ENODEV;
0270         goto err;
0271     }
0272 
0273     ret = devm_request_irq(&pdev->dev,
0274             irq, imx_rngc_irq, 0, pdev->name, (void *)rngc);
0275     if (ret) {
0276         dev_err(rngc->dev, "Can't get interrupt working.\n");
0277         goto err;
0278     }
0279 
0280     init_completion(&rngc->rng_op_done);
0281 
0282     rngc->rng.name = pdev->name;
0283     rngc->rng.init = imx_rngc_init;
0284     rngc->rng.read = imx_rngc_read;
0285     rngc->rng.cleanup = imx_rngc_cleanup;
0286     rngc->rng.quality = 19;
0287 
0288     rngc->dev = &pdev->dev;
0289     platform_set_drvdata(pdev, rngc);
0290 
0291     imx_rngc_irq_mask_clear(rngc);
0292 
0293     if (self_test) {
0294         ret = imx_rngc_self_test(rngc);
0295         if (ret) {
0296             dev_err(rngc->dev, "self test failed\n");
0297             goto err;
0298         }
0299     }
0300 
0301     ret = hwrng_register(&rngc->rng);
0302     if (ret) {
0303         dev_err(&pdev->dev, "hwrng registration failed\n");
0304         goto err;
0305     }
0306 
0307     dev_info(&pdev->dev,
0308         "Freescale RNG%c registered (HW revision %d.%02d)\n",
0309         rng_type == RNGC_TYPE_RNGB ? 'B' : 'C',
0310         (ver_id >> RNGC_VER_MAJ_SHIFT) & 0xff, ver_id & 0xff);
0311     return 0;
0312 
0313 err:
0314     clk_disable_unprepare(rngc->clk);
0315 
0316     return ret;
0317 }
0318 
0319 static int __exit imx_rngc_remove(struct platform_device *pdev)
0320 {
0321     struct imx_rngc *rngc = platform_get_drvdata(pdev);
0322 
0323     hwrng_unregister(&rngc->rng);
0324 
0325     clk_disable_unprepare(rngc->clk);
0326 
0327     return 0;
0328 }
0329 
0330 static int __maybe_unused imx_rngc_suspend(struct device *dev)
0331 {
0332     struct imx_rngc *rngc = dev_get_drvdata(dev);
0333 
0334     clk_disable_unprepare(rngc->clk);
0335 
0336     return 0;
0337 }
0338 
0339 static int __maybe_unused imx_rngc_resume(struct device *dev)
0340 {
0341     struct imx_rngc *rngc = dev_get_drvdata(dev);
0342 
0343     clk_prepare_enable(rngc->clk);
0344 
0345     return 0;
0346 }
0347 
0348 static SIMPLE_DEV_PM_OPS(imx_rngc_pm_ops, imx_rngc_suspend, imx_rngc_resume);
0349 
0350 static const struct of_device_id imx_rngc_dt_ids[] = {
0351     { .compatible = "fsl,imx25-rngb", .data = NULL, },
0352     { /* sentinel */ }
0353 };
0354 MODULE_DEVICE_TABLE(of, imx_rngc_dt_ids);
0355 
0356 static struct platform_driver imx_rngc_driver = {
0357     .driver = {
0358         .name = "imx_rngc",
0359         .pm = &imx_rngc_pm_ops,
0360         .of_match_table = imx_rngc_dt_ids,
0361     },
0362     .remove = __exit_p(imx_rngc_remove),
0363 };
0364 
0365 module_platform_driver_probe(imx_rngc_driver, imx_rngc_probe);
0366 
0367 MODULE_AUTHOR("Freescale Semiconductor, Inc.");
0368 MODULE_DESCRIPTION("H/W RNGC driver for i.MX");
0369 MODULE_LICENSE("GPL");