Lines Matching +full:resume +full:- +full:offset
1 // SPDX-License-Identifier: GPL-2.0
3 * exynos-rng.c - Random Number Generator driver for the Exynos
7 * Loosely based on old driver from drivers/char/hw_random/exynos-rng.c:
51 * Driver re-seeds itself with generated random numbers to hinder
54 * Time for next re-seed in ms.
76 /* Generated numbers stored for seeding during resume */
87 static u32 exynos_rng_readl(struct exynos_rng_dev *rng, u32 offset) in exynos_rng_readl() argument
89 return readl_relaxed(rng->mem + offset); in exynos_rng_readl()
92 static void exynos_rng_writel(struct exynos_rng_dev *rng, u32 val, u32 offset) in exynos_rng_writel() argument
94 writel_relaxed(val, rng->mem + offset); in exynos_rng_writel()
107 return -EINVAL; in exynos_rng_set_seed()
122 dev_warn(rng->dev, "Seed setting not finished\n"); in exynos_rng_set_seed()
123 return -EIO; in exynos_rng_set_seed()
126 rng->last_seeding = jiffies; in exynos_rng_set_seed()
127 rng->bytes_seeding = 0; in exynos_rng_set_seed()
138 * On error: return -ERRNO.
146 if (rng->type == EXYNOS_PRNG_EXYNOS4) { in exynos_rng_get_random()
149 } else if (rng->type == EXYNOS_PRNG_EXYNOS5) { in exynos_rng_get_random()
155 EXYNOS_RNG_STATUS) & EXYNOS_RNG_STATUS_RNG_DONE) && --retry) in exynos_rng_get_random()
159 return -ETIMEDOUT; in exynos_rng_get_random()
165 memcpy_fromio(dst, rng->mem + EXYNOS_RNG_OUT_BASE, *read); in exynos_rng_get_random()
166 rng->bytes_seeding += *read; in exynos_rng_get_random()
171 /* Re-seed itself from time to time */
174 unsigned long next_seeding = rng->last_seeding + \ in exynos_rng_reseed()
181 rng->bytes_seeding < EXYNOS_RNG_RESEED_BYTES) in exynos_rng_reseed()
190 mutex_unlock(&rng->lock); in exynos_rng_reseed()
191 mutex_lock(&rng->lock); in exynos_rng_reseed()
199 struct exynos_rng_dev *rng = ctx->rng; in exynos_rng_generate()
203 ret = clk_prepare_enable(rng->clk); in exynos_rng_generate()
207 mutex_lock(&rng->lock); in exynos_rng_generate()
213 dlen -= read; in exynos_rng_generate()
218 mutex_unlock(&rng->lock); in exynos_rng_generate()
220 clk_disable_unprepare(rng->clk); in exynos_rng_generate()
229 struct exynos_rng_dev *rng = ctx->rng; in exynos_rng_seed()
232 ret = clk_prepare_enable(rng->clk); in exynos_rng_seed()
236 mutex_lock(&rng->lock); in exynos_rng_seed()
237 ret = exynos_rng_set_seed(ctx->rng, seed, slen); in exynos_rng_seed()
238 mutex_unlock(&rng->lock); in exynos_rng_seed()
240 clk_disable_unprepare(rng->clk); in exynos_rng_seed()
249 ctx->rng = exynos_rng_dev; in exynos_rng_kcapi_init()
274 return -EEXIST; in exynos_rng_probe()
276 rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL); in exynos_rng_probe()
278 return -ENOMEM; in exynos_rng_probe()
280 rng->type = (uintptr_t)of_device_get_match_data(&pdev->dev); in exynos_rng_probe()
282 mutex_init(&rng->lock); in exynos_rng_probe()
284 rng->dev = &pdev->dev; in exynos_rng_probe()
285 rng->clk = devm_clk_get(&pdev->dev, "secss"); in exynos_rng_probe()
286 if (IS_ERR(rng->clk)) { in exynos_rng_probe()
287 dev_err(&pdev->dev, "Couldn't get clock.\n"); in exynos_rng_probe()
288 return PTR_ERR(rng->clk); in exynos_rng_probe()
291 rng->mem = devm_platform_ioremap_resource(pdev, 0); in exynos_rng_probe()
292 if (IS_ERR(rng->mem)) in exynos_rng_probe()
293 return PTR_ERR(rng->mem); in exynos_rng_probe()
301 dev_err(&pdev->dev, in exynos_rng_probe()
321 /* If we were never seeded then after resume it will be the same */ in exynos_rng_suspend()
322 if (!rng->last_seeding) in exynos_rng_suspend()
325 rng->seed_save_len = 0; in exynos_rng_suspend()
326 ret = clk_prepare_enable(rng->clk); in exynos_rng_suspend()
330 mutex_lock(&rng->lock); in exynos_rng_suspend()
332 /* Get new random numbers and store them for seeding on resume. */ in exynos_rng_suspend()
333 exynos_rng_get_random(rng, rng->seed_save, sizeof(rng->seed_save), in exynos_rng_suspend()
334 &(rng->seed_save_len)); in exynos_rng_suspend()
336 mutex_unlock(&rng->lock); in exynos_rng_suspend()
338 dev_dbg(rng->dev, "Stored %u bytes for seeding on system resume\n", in exynos_rng_suspend()
339 rng->seed_save_len); in exynos_rng_suspend()
341 clk_disable_unprepare(rng->clk); in exynos_rng_suspend()
352 if (!rng->last_seeding) in exynos_rng_resume()
355 ret = clk_prepare_enable(rng->clk); in exynos_rng_resume()
359 mutex_lock(&rng->lock); in exynos_rng_resume()
361 ret = exynos_rng_set_seed(rng, rng->seed_save, rng->seed_save_len); in exynos_rng_resume()
363 mutex_unlock(&rng->lock); in exynos_rng_resume()
365 clk_disable_unprepare(rng->clk); in exynos_rng_resume()
375 .compatible = "samsung,exynos4-rng",
378 .compatible = "samsung,exynos5250-prng",
387 .name = "exynos-rng",