Lines Matching +full:wide +full:- +full:range

1 // SPDX-License-Identifier: GPL-2.0-only
3 * drivers/char/hw_random/timeriomem-rng.c
7 * Derived from drivers/char/hw_random/omap-rng.c
12 * This driver is useful for platforms that have an IO range that provides
31 #include <linux/timeriomem-rng.h>
50 int period_us = ktime_to_us(priv->period); in timeriomem_rng_read()
58 if (!wait && !priv->present) in timeriomem_rng_read()
61 wait_for_completion(&priv->completion); in timeriomem_rng_read()
67 * a wide range of values (1us to 1s have been observed), allow in timeriomem_rng_read()
74 *(u32 *)data = readl(priv->io_base); in timeriomem_rng_read()
77 max -= sizeof(u32); in timeriomem_rng_read()
84 priv->present = 0; in timeriomem_rng_read()
85 reinit_completion(&priv->completion); in timeriomem_rng_read()
86 hrtimer_forward_now(&priv->timer, priv->period); in timeriomem_rng_read()
87 hrtimer_restart(&priv->timer); in timeriomem_rng_read()
97 priv->present = 1; in timeriomem_rng_trigger()
98 complete(&priv->completion); in timeriomem_rng_trigger()
105 struct timeriomem_rng_data *pdata = pdev->dev.platform_data; in timeriomem_rng_probe()
111 if (!pdev->dev.of_node && !pdata) { in timeriomem_rng_probe()
112 dev_err(&pdev->dev, "timeriomem_rng_data is missing\n"); in timeriomem_rng_probe()
113 return -EINVAL; in timeriomem_rng_probe()
118 return -ENXIO; in timeriomem_rng_probe()
120 if (res->start % 4 != 0 || resource_size(res) < 4) { in timeriomem_rng_probe()
121 dev_err(&pdev->dev, in timeriomem_rng_probe()
122 "address must be at least four bytes wide and 32-bit aligned\n"); in timeriomem_rng_probe()
123 return -EINVAL; in timeriomem_rng_probe()
127 priv = devm_kzalloc(&pdev->dev, in timeriomem_rng_probe()
130 return -ENOMEM; in timeriomem_rng_probe()
134 if (pdev->dev.of_node) { in timeriomem_rng_probe()
137 if (!of_property_read_u32(pdev->dev.of_node, in timeriomem_rng_probe()
141 dev_err(&pdev->dev, "missing period\n"); in timeriomem_rng_probe()
142 return -EINVAL; in timeriomem_rng_probe()
145 if (!of_property_read_u32(pdev->dev.of_node, in timeriomem_rng_probe()
147 priv->rng_ops.quality = i; in timeriomem_rng_probe()
149 priv->rng_ops.quality = 0; in timeriomem_rng_probe()
151 period = pdata->period; in timeriomem_rng_probe()
152 priv->rng_ops.quality = pdata->quality; in timeriomem_rng_probe()
155 priv->period = ns_to_ktime(period * NSEC_PER_USEC); in timeriomem_rng_probe()
156 init_completion(&priv->completion); in timeriomem_rng_probe()
157 hrtimer_init(&priv->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); in timeriomem_rng_probe()
158 priv->timer.function = timeriomem_rng_trigger; in timeriomem_rng_probe()
160 priv->rng_ops.name = dev_name(&pdev->dev); in timeriomem_rng_probe()
161 priv->rng_ops.read = timeriomem_rng_read; in timeriomem_rng_probe()
163 priv->io_base = devm_ioremap_resource(&pdev->dev, res); in timeriomem_rng_probe()
164 if (IS_ERR(priv->io_base)) { in timeriomem_rng_probe()
165 return PTR_ERR(priv->io_base); in timeriomem_rng_probe()
169 priv->present = 1; in timeriomem_rng_probe()
170 complete(&priv->completion); in timeriomem_rng_probe()
172 err = devm_hwrng_register(&pdev->dev, &priv->rng_ops); in timeriomem_rng_probe()
174 dev_err(&pdev->dev, "problem registering\n"); in timeriomem_rng_probe()
178 dev_info(&pdev->dev, "32bits from 0x%p @ %dus\n", in timeriomem_rng_probe()
179 priv->io_base, period); in timeriomem_rng_probe()
188 hrtimer_cancel(&priv->timer); in timeriomem_rng_remove()