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()
117 priv = devm_kzalloc(&pdev->dev, in timeriomem_rng_probe()
120 return -ENOMEM; in timeriomem_rng_probe()
124 priv->io_base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); in timeriomem_rng_probe()
125 if (IS_ERR(priv->io_base)) in timeriomem_rng_probe()
126 return PTR_ERR(priv->io_base); in timeriomem_rng_probe()
128 if (res->start % 4 != 0 || resource_size(res) < 4) { in timeriomem_rng_probe()
129 dev_err(&pdev->dev, in timeriomem_rng_probe()
130 "address must be at least four bytes wide and 32-bit aligned\n"); in timeriomem_rng_probe()
131 return -EINVAL; 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 period = pdata->period; in timeriomem_rng_probe()
150 priv->rng_ops.quality = pdata->quality; in timeriomem_rng_probe()
153 priv->period = ns_to_ktime(period * NSEC_PER_USEC); in timeriomem_rng_probe()
154 init_completion(&priv->completion); in timeriomem_rng_probe()
155 hrtimer_init(&priv->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); in timeriomem_rng_probe()
156 priv->timer.function = timeriomem_rng_trigger; in timeriomem_rng_probe()
158 priv->rng_ops.name = dev_name(&pdev->dev); in timeriomem_rng_probe()
159 priv->rng_ops.read = timeriomem_rng_read; in timeriomem_rng_probe()
162 priv->present = 1; in timeriomem_rng_probe()
163 complete(&priv->completion); in timeriomem_rng_probe()
165 err = devm_hwrng_register(&pdev->dev, &priv->rng_ops); in timeriomem_rng_probe()
167 dev_err(&pdev->dev, "problem registering\n"); in timeriomem_rng_probe()
171 dev_info(&pdev->dev, "32bits from 0x%p @ %dus\n", in timeriomem_rng_probe()
172 priv->io_base, period); in timeriomem_rng_probe()
181 hrtimer_cancel(&priv->timer); in timeriomem_rng_remove()