xref: /linux/drivers/char/hw_random/stm32-rng.c (revision 8a922b7728a93d837954315c98b84f6b78de0c4f)
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