Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright (c) 2015, Daniel Thompson
0004  */
0005 
0006 #include <linux/clk.h>
0007 #include <linux/delay.h>
0008 #include <linux/hw_random.h>
0009 #include <linux/io.h>
0010 #include <linux/iopoll.h>
0011 #include <linux/kernel.h>
0012 #include <linux/module.h>
0013 #include <linux/of_address.h>
0014 #include <linux/of_platform.h>
0015 #include <linux/pm_runtime.h>
0016 #include <linux/reset.h>
0017 #include <linux/slab.h>
0018 
0019 #define RNG_CR 0x00
0020 #define RNG_CR_RNGEN BIT(2)
0021 #define RNG_CR_CED BIT(5)
0022 
0023 #define RNG_SR 0x04
0024 #define RNG_SR_SEIS BIT(6)
0025 #define RNG_SR_CEIS BIT(5)
0026 #define RNG_SR_DRDY BIT(0)
0027 
0028 #define RNG_DR 0x08
0029 
0030 struct stm32_rng_private {
0031     struct hwrng rng;
0032     void __iomem *base;
0033     struct clk *clk;
0034     struct reset_control *rst;
0035     bool ced;
0036 };
0037 
0038 static int stm32_rng_read(struct hwrng *rng, void *data, size_t max, bool wait)
0039 {
0040     struct stm32_rng_private *priv =
0041         container_of(rng, struct stm32_rng_private, rng);
0042     u32 sr;
0043     int retval = 0;
0044 
0045     pm_runtime_get_sync((struct device *) priv->rng.priv);
0046 
0047     while (max > sizeof(u32)) {
0048         sr = readl_relaxed(priv->base + RNG_SR);
0049         /* Manage timeout which is based on timer and take */
0050         /* care of initial delay time when enabling rng */
0051         if (!sr && wait) {
0052             retval = readl_relaxed_poll_timeout_atomic(priv->base
0053                                    + RNG_SR,
0054                                    sr, sr,
0055                                    10, 50000);
0056             if (retval)
0057                 dev_err((struct device *)priv->rng.priv,
0058                     "%s: timeout %x!\n", __func__, sr);
0059         }
0060 
0061         /* If error detected or data not ready... */
0062         if (sr != RNG_SR_DRDY) {
0063             if (WARN_ONCE(sr & (RNG_SR_SEIS | RNG_SR_CEIS),
0064                     "bad RNG status - %x\n", sr))
0065                 writel_relaxed(0, priv->base + RNG_SR);
0066             break;
0067         }
0068 
0069         *(u32 *)data = readl_relaxed(priv->base + RNG_DR);
0070 
0071         retval += sizeof(u32);
0072         data += sizeof(u32);
0073         max -= sizeof(u32);
0074     }
0075 
0076     pm_runtime_mark_last_busy((struct device *) priv->rng.priv);
0077     pm_runtime_put_sync_autosuspend((struct device *) priv->rng.priv);
0078 
0079     return retval || !wait ? retval : -EIO;
0080 }
0081 
0082 static int stm32_rng_init(struct hwrng *rng)
0083 {
0084     struct stm32_rng_private *priv =
0085         container_of(rng, struct stm32_rng_private, rng);
0086     int err;
0087 
0088     err = clk_prepare_enable(priv->clk);
0089     if (err)
0090         return err;
0091 
0092     if (priv->ced)
0093         writel_relaxed(RNG_CR_RNGEN, priv->base + RNG_CR);
0094     else
0095         writel_relaxed(RNG_CR_RNGEN | RNG_CR_CED,
0096                    priv->base + RNG_CR);
0097 
0098     /* clear error indicators */
0099     writel_relaxed(0, priv->base + RNG_SR);
0100 
0101     return 0;
0102 }
0103 
0104 static void stm32_rng_cleanup(struct hwrng *rng)
0105 {
0106     struct stm32_rng_private *priv =
0107         container_of(rng, struct stm32_rng_private, rng);
0108 
0109     writel_relaxed(0, priv->base + RNG_CR);
0110     clk_disable_unprepare(priv->clk);
0111 }
0112 
0113 static int stm32_rng_probe(struct platform_device *ofdev)
0114 {
0115     struct device *dev = &ofdev->dev;
0116     struct device_node *np = ofdev->dev.of_node;
0117     struct stm32_rng_private *priv;
0118     struct resource res;
0119     int err;
0120 
0121     priv = devm_kzalloc(dev, sizeof(struct stm32_rng_private), GFP_KERNEL);
0122     if (!priv)
0123         return -ENOMEM;
0124 
0125     err = of_address_to_resource(np, 0, &res);
0126     if (err)
0127         return err;
0128 
0129     priv->base = devm_ioremap_resource(dev, &res);
0130     if (IS_ERR(priv->base))
0131         return PTR_ERR(priv->base);
0132 
0133     priv->clk = devm_clk_get(&ofdev->dev, NULL);
0134     if (IS_ERR(priv->clk))
0135         return PTR_ERR(priv->clk);
0136 
0137     priv->rst = devm_reset_control_get(&ofdev->dev, NULL);
0138     if (!IS_ERR(priv->rst)) {
0139         reset_control_assert(priv->rst);
0140         udelay(2);
0141         reset_control_deassert(priv->rst);
0142     }
0143 
0144     priv->ced = of_property_read_bool(np, "clock-error-detect");
0145 
0146     dev_set_drvdata(dev, priv);
0147 
0148     priv->rng.name = dev_driver_string(dev);
0149 #ifndef CONFIG_PM
0150     priv->rng.init = stm32_rng_init;
0151     priv->rng.cleanup = stm32_rng_cleanup;
0152 #endif
0153     priv->rng.read = stm32_rng_read;
0154     priv->rng.priv = (unsigned long) dev;
0155     priv->rng.quality = 900;
0156 
0157     pm_runtime_set_autosuspend_delay(dev, 100);
0158     pm_runtime_use_autosuspend(dev);
0159     pm_runtime_enable(dev);
0160 
0161     return devm_hwrng_register(dev, &priv->rng);
0162 }
0163 
0164 static int stm32_rng_remove(struct platform_device *ofdev)
0165 {
0166     pm_runtime_disable(&ofdev->dev);
0167 
0168     return 0;
0169 }
0170 
0171 #ifdef CONFIG_PM
0172 static int stm32_rng_runtime_suspend(struct device *dev)
0173 {
0174     struct stm32_rng_private *priv = dev_get_drvdata(dev);
0175 
0176     stm32_rng_cleanup(&priv->rng);
0177 
0178     return 0;
0179 }
0180 
0181 static int stm32_rng_runtime_resume(struct device *dev)
0182 {
0183     struct stm32_rng_private *priv = dev_get_drvdata(dev);
0184 
0185     return stm32_rng_init(&priv->rng);
0186 }
0187 #endif
0188 
0189 static const struct dev_pm_ops stm32_rng_pm_ops = {
0190     SET_RUNTIME_PM_OPS(stm32_rng_runtime_suspend,
0191                stm32_rng_runtime_resume, NULL)
0192     SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
0193                 pm_runtime_force_resume)
0194 };
0195 
0196 
0197 static const struct of_device_id stm32_rng_match[] = {
0198     {
0199         .compatible = "st,stm32-rng",
0200     },
0201     {},
0202 };
0203 MODULE_DEVICE_TABLE(of, stm32_rng_match);
0204 
0205 static struct platform_driver stm32_rng_driver = {
0206     .driver = {
0207         .name = "stm32-rng",
0208         .pm = &stm32_rng_pm_ops,
0209         .of_match_table = stm32_rng_match,
0210     },
0211     .probe = stm32_rng_probe,
0212     .remove = stm32_rng_remove,
0213 };
0214 
0215 module_platform_driver(stm32_rng_driver);
0216 
0217 MODULE_LICENSE("GPL");
0218 MODULE_AUTHOR("Daniel Thompson <daniel.thompson@linaro.org>");
0219 MODULE_DESCRIPTION("STMicroelectronics STM32 RNG device driver");