GNU Linux-libre 4.14.259-gnu1
[releases.git] / drivers / char / hw_random / timeriomem-rng.c
1 /*
2  * drivers/char/hw_random/timeriomem-rng.c
3  *
4  * Copyright (C) 2009 Alexander Clouter <alex@digriz.org.uk>
5  *
6  * Derived from drivers/char/hw_random/omap-rng.c
7  *   Copyright 2005 (c) MontaVista Software, Inc.
8  *   Author: Deepak Saxena <dsaxena@plexity.net>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  *
14  * Overview:
15  *   This driver is useful for platforms that have an IO range that provides
16  *   periodic random data from a single IO memory address.  All the platform
17  *   has to do is provide the address and 'wait time' that new data becomes
18  *   available.
19  *
20  * TODO: add support for reading sizes other than 32bits and masking
21  */
22
23 #include <linux/completion.h>
24 #include <linux/delay.h>
25 #include <linux/hrtimer.h>
26 #include <linux/hw_random.h>
27 #include <linux/io.h>
28 #include <linux/ktime.h>
29 #include <linux/module.h>
30 #include <linux/of.h>
31 #include <linux/platform_device.h>
32 #include <linux/slab.h>
33 #include <linux/time.h>
34 #include <linux/timeriomem-rng.h>
35
36 struct timeriomem_rng_private {
37         void __iomem            *io_base;
38         ktime_t                 period;
39         unsigned int            present:1;
40
41         struct hrtimer          timer;
42         struct completion       completion;
43
44         struct hwrng            rng_ops;
45 };
46
47 static int timeriomem_rng_read(struct hwrng *hwrng, void *data,
48                                 size_t max, bool wait)
49 {
50         struct timeriomem_rng_private *priv =
51                 container_of(hwrng, struct timeriomem_rng_private, rng_ops);
52         int retval = 0;
53         int period_us = ktime_to_us(priv->period);
54
55         /*
56          * The RNG provides 32-bits per read.  Ensure there is enough space for
57          * at minimum one read.
58          */
59         if (max < sizeof(u32))
60                 return 0;
61
62         /*
63          * There may not have been enough time for new data to be generated
64          * since the last request.  If the caller doesn't want to wait, let them
65          * bail out.  Otherwise, wait for the completion.  If the new data has
66          * already been generated, the completion should already be available.
67          */
68         if (!wait && !priv->present)
69                 return 0;
70
71         wait_for_completion(&priv->completion);
72
73         do {
74                 /*
75                  * After the first read, all additional reads will need to wait
76                  * for the RNG to generate new data.  Since the period can have
77                  * a wide range of values (1us to 1s have been observed), allow
78                  * for 1% tolerance in the sleep time rather than a fixed value.
79                  */
80                 if (retval > 0)
81                         usleep_range(period_us,
82                                         period_us + max(1, period_us / 100));
83
84                 *(u32 *)data = readl(priv->io_base);
85                 retval += sizeof(u32);
86                 data += sizeof(u32);
87                 max -= sizeof(u32);
88         } while (wait && max > sizeof(u32));
89
90         /*
91          * Block any new callers until the RNG has had time to generate new
92          * data.
93          */
94         priv->present = 0;
95         reinit_completion(&priv->completion);
96         hrtimer_forward_now(&priv->timer, priv->period);
97         hrtimer_restart(&priv->timer);
98
99         return retval;
100 }
101
102 static enum hrtimer_restart timeriomem_rng_trigger(struct hrtimer *timer)
103 {
104         struct timeriomem_rng_private *priv
105                 = container_of(timer, struct timeriomem_rng_private, timer);
106
107         priv->present = 1;
108         complete(&priv->completion);
109
110         return HRTIMER_NORESTART;
111 }
112
113 static int timeriomem_rng_probe(struct platform_device *pdev)
114 {
115         struct timeriomem_rng_data *pdata = pdev->dev.platform_data;
116         struct timeriomem_rng_private *priv;
117         struct resource *res;
118         int err = 0;
119         int period;
120
121         if (!pdev->dev.of_node && !pdata) {
122                 dev_err(&pdev->dev, "timeriomem_rng_data is missing\n");
123                 return -EINVAL;
124         }
125
126         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
127         if (!res)
128                 return -ENXIO;
129
130         if (res->start % 4 != 0 || resource_size(res) != 4) {
131                 dev_err(&pdev->dev,
132                         "address must be four bytes wide and aligned\n");
133                 return -EINVAL;
134         }
135
136         /* Allocate memory for the device structure (and zero it) */
137         priv = devm_kzalloc(&pdev->dev,
138                         sizeof(struct timeriomem_rng_private), GFP_KERNEL);
139         if (!priv)
140                 return -ENOMEM;
141
142         platform_set_drvdata(pdev, priv);
143
144         if (pdev->dev.of_node) {
145                 int i;
146
147                 if (!of_property_read_u32(pdev->dev.of_node,
148                                                 "period", &i))
149                         period = i;
150                 else {
151                         dev_err(&pdev->dev, "missing period\n");
152                         return -EINVAL;
153                 }
154
155                 if (!of_property_read_u32(pdev->dev.of_node,
156                                                 "quality", &i))
157                         priv->rng_ops.quality = i;
158                 else
159                         priv->rng_ops.quality = 0;
160         } else {
161                 period = pdata->period;
162                 priv->rng_ops.quality = pdata->quality;
163         }
164
165         priv->period = ns_to_ktime(period * NSEC_PER_USEC);
166         init_completion(&priv->completion);
167         hrtimer_init(&priv->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
168         priv->timer.function = timeriomem_rng_trigger;
169
170         priv->rng_ops.name = dev_name(&pdev->dev);
171         priv->rng_ops.read = timeriomem_rng_read;
172
173         priv->io_base = devm_ioremap_resource(&pdev->dev, res);
174         if (IS_ERR(priv->io_base)) {
175                 return PTR_ERR(priv->io_base);
176         }
177
178         /* Assume random data is already available. */
179         priv->present = 1;
180         complete(&priv->completion);
181
182         err = hwrng_register(&priv->rng_ops);
183         if (err) {
184                 dev_err(&pdev->dev, "problem registering\n");
185                 return err;
186         }
187
188         dev_info(&pdev->dev, "32bits from 0x%p @ %dus\n",
189                         priv->io_base, period);
190
191         return 0;
192 }
193
194 static int timeriomem_rng_remove(struct platform_device *pdev)
195 {
196         struct timeriomem_rng_private *priv = platform_get_drvdata(pdev);
197
198         hwrng_unregister(&priv->rng_ops);
199         hrtimer_cancel(&priv->timer);
200
201         return 0;
202 }
203
204 static const struct of_device_id timeriomem_rng_match[] = {
205         { .compatible = "timeriomem_rng" },
206         {},
207 };
208 MODULE_DEVICE_TABLE(of, timeriomem_rng_match);
209
210 static struct platform_driver timeriomem_rng_driver = {
211         .driver = {
212                 .name           = "timeriomem_rng",
213                 .of_match_table = timeriomem_rng_match,
214         },
215         .probe          = timeriomem_rng_probe,
216         .remove         = timeriomem_rng_remove,
217 };
218
219 module_platform_driver(timeriomem_rng_driver);
220
221 MODULE_LICENSE("GPL");
222 MODULE_AUTHOR("Alexander Clouter <alex@digriz.org.uk>");
223 MODULE_DESCRIPTION("Timer IOMEM H/W RNG driver");