1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (c) 2015, Daniel Thompson 4 */ 5 6 #include <linux/clk.h> 7 #include <linux/delay.h> 8 #include <linux/hw_random.h> 9 #include <linux/io.h> 10 #include <linux/iopoll.h> 11 #include <linux/kernel.h> 12 #include <linux/module.h> 13 #include <linux/of_address.h> 14 #include <linux/of_platform.h> 15 #include <linux/pm_runtime.h> 16 #include <linux/reset.h> 17 #include <linux/slab.h> 18 19 #define RNG_CR 0x00 20 #define RNG_CR_RNGEN BIT(2) 21 #define RNG_CR_CED BIT(5) 22 23 #define RNG_SR 0x04 24 #define RNG_SR_SEIS BIT(6) 25 #define RNG_SR_CEIS BIT(5) 26 #define RNG_SR_DRDY BIT(0) 27 28 #define RNG_DR 0x08 29 30 struct stm32_rng_private { 31 struct hwrng rng; 32 void __iomem *base; 33 struct clk *clk; 34 struct reset_control *rst; 35 bool ced; 36 }; 37 38 static int stm32_rng_read(struct hwrng *rng, void *data, size_t max, bool wait) 39 { 40 struct stm32_rng_private *priv = 41 container_of(rng, struct stm32_rng_private, rng); 42 u32 sr; 43 int retval = 0; 44 45 pm_runtime_get_sync((struct device *) priv->rng.priv); 46 47 while (max >= sizeof(u32)) { 48 sr = readl_relaxed(priv->base + RNG_SR); 49 /* Manage timeout which is based on timer and take */ 50 /* care of initial delay time when enabling rng */ 51 if (!sr && wait) { 52 int err; 53 54 err = readl_relaxed_poll_timeout_atomic(priv->base 55 + RNG_SR, 56 sr, sr, 57 10, 50000); 58 if (err) 59 dev_err((struct device *)priv->rng.priv, 60 "%s: timeout %x!\n", __func__, sr); 61 } 62 63 /* If error detected or data not ready... */ 64 if (sr != RNG_SR_DRDY) { 65 if (WARN_ONCE(sr & (RNG_SR_SEIS | RNG_SR_CEIS), 66 "bad RNG status - %x\n", sr)) 67 writel_relaxed(0, priv->base + RNG_SR); 68 break; 69 } 70 71 *(u32 *)data = readl_relaxed(priv->base + RNG_DR); 72 73 retval += sizeof(u32); 74 data += sizeof(u32); 75 max -= sizeof(u32); 76 } 77 78 pm_runtime_mark_last_busy((struct device *) priv->rng.priv); 79 pm_runtime_put_sync_autosuspend((struct device *) priv->rng.priv); 80 81 return retval || !wait ? retval : -EIO; 82 } 83 84 static int stm32_rng_init(struct hwrng *rng) 85 { 86 struct stm32_rng_private *priv = 87 container_of(rng, struct stm32_rng_private, rng); 88 int err; 89 90 err = clk_prepare_enable(priv->clk); 91 if (err) 92 return err; 93 94 if (priv->ced) 95 writel_relaxed(RNG_CR_RNGEN, priv->base + RNG_CR); 96 else 97 writel_relaxed(RNG_CR_RNGEN | RNG_CR_CED, 98 priv->base + RNG_CR); 99 100 /* clear error indicators */ 101 writel_relaxed(0, priv->base + RNG_SR); 102 103 return 0; 104 } 105 106 static void stm32_rng_cleanup(struct hwrng *rng) 107 { 108 struct stm32_rng_private *priv = 109 container_of(rng, struct stm32_rng_private, rng); 110 111 writel_relaxed(0, priv->base + RNG_CR); 112 clk_disable_unprepare(priv->clk); 113 } 114 115 static int stm32_rng_probe(struct platform_device *ofdev) 116 { 117 struct device *dev = &ofdev->dev; 118 struct device_node *np = ofdev->dev.of_node; 119 struct stm32_rng_private *priv; 120 struct resource res; 121 int err; 122 123 priv = devm_kzalloc(dev, sizeof(struct stm32_rng_private), GFP_KERNEL); 124 if (!priv) 125 return -ENOMEM; 126 127 err = of_address_to_resource(np, 0, &res); 128 if (err) 129 return err; 130 131 priv->base = devm_ioremap_resource(dev, &res); 132 if (IS_ERR(priv->base)) 133 return PTR_ERR(priv->base); 134 135 priv->clk = devm_clk_get(&ofdev->dev, NULL); 136 if (IS_ERR(priv->clk)) 137 return PTR_ERR(priv->clk); 138 139 priv->rst = devm_reset_control_get(&ofdev->dev, NULL); 140 if (!IS_ERR(priv->rst)) { 141 reset_control_assert(priv->rst); 142 udelay(2); 143 reset_control_deassert(priv->rst); 144 } 145 146 priv->ced = of_property_read_bool(np, "clock-error-detect"); 147 148 dev_set_drvdata(dev, priv); 149 150 priv->rng.name = dev_driver_string(dev); 151 #ifndef CONFIG_PM 152 priv->rng.init = stm32_rng_init; 153 priv->rng.cleanup = stm32_rng_cleanup; 154 #endif 155 priv->rng.read = stm32_rng_read; 156 priv->rng.priv = (unsigned long) dev; 157 priv->rng.quality = 900; 158 159 pm_runtime_set_autosuspend_delay(dev, 100); 160 pm_runtime_use_autosuspend(dev); 161 pm_runtime_enable(dev); 162 163 return devm_hwrng_register(dev, &priv->rng); 164 } 165 166 static int stm32_rng_remove(struct platform_device *ofdev) 167 { 168 pm_runtime_disable(&ofdev->dev); 169 170 return 0; 171 } 172 173 #ifdef CONFIG_PM 174 static int stm32_rng_runtime_suspend(struct device *dev) 175 { 176 struct stm32_rng_private *priv = dev_get_drvdata(dev); 177 178 stm32_rng_cleanup(&priv->rng); 179 180 return 0; 181 } 182 183 static int stm32_rng_runtime_resume(struct device *dev) 184 { 185 struct stm32_rng_private *priv = dev_get_drvdata(dev); 186 187 return stm32_rng_init(&priv->rng); 188 } 189 #endif 190 191 static const struct dev_pm_ops stm32_rng_pm_ops = { 192 SET_RUNTIME_PM_OPS(stm32_rng_runtime_suspend, 193 stm32_rng_runtime_resume, NULL) 194 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 195 pm_runtime_force_resume) 196 }; 197 198 199 static const struct of_device_id stm32_rng_match[] = { 200 { 201 .compatible = "st,stm32-rng", 202 }, 203 {}, 204 }; 205 MODULE_DEVICE_TABLE(of, stm32_rng_match); 206 207 static struct platform_driver stm32_rng_driver = { 208 .driver = { 209 .name = "stm32-rng", 210 .pm = &stm32_rng_pm_ops, 211 .of_match_table = stm32_rng_match, 212 }, 213 .probe = stm32_rng_probe, 214 .remove = stm32_rng_remove, 215 }; 216 217 module_platform_driver(stm32_rng_driver); 218 219 MODULE_LICENSE("GPL"); 220 MODULE_AUTHOR("Daniel Thompson <daniel.thompson@linaro.org>"); 221 MODULE_DESCRIPTION("STMicroelectronics STM32 RNG device driver"); 222