Lines Matching full:rng

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:
21 #include <crypto/internal/rng.h>
66 struct exynos_rng_dev *rng; member
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()
97 static int exynos_rng_set_seed(struct exynos_rng_dev *rng, in exynos_rng_set_seed() argument
117 exynos_rng_writel(rng, val, EXYNOS_RNG_SEED(seed_reg)); in exynos_rng_set_seed()
120 val = exynos_rng_readl(rng, EXYNOS_RNG_STATUS); in exynos_rng_set_seed()
122 dev_warn(rng->dev, "Seed setting not finished\n"); 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()
140 static int exynos_rng_get_random(struct exynos_rng_dev *rng, in exynos_rng_get_random() argument
146 if (rng->type == EXYNOS_PRNG_EXYNOS4) { in exynos_rng_get_random()
147 exynos_rng_writel(rng, EXYNOS_RNG_CONTROL_START, in exynos_rng_get_random()
149 } else if (rng->type == EXYNOS_PRNG_EXYNOS5) { in exynos_rng_get_random()
150 exynos_rng_writel(rng, EXYNOS_RNG_GEN_PRNG, in exynos_rng_get_random()
154 while (!(exynos_rng_readl(rng, in exynos_rng_get_random()
162 exynos_rng_writel(rng, EXYNOS_RNG_STATUS_RNG_DONE, 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()
172 static void exynos_rng_reseed(struct exynos_rng_dev *rng) in exynos_rng_reseed() argument
174 unsigned long next_seeding = rng->last_seeding + \ in exynos_rng_reseed()
181 rng->bytes_seeding < EXYNOS_RNG_RESEED_BYTES) in exynos_rng_reseed()
184 if (exynos_rng_get_random(rng, seed, sizeof(seed), &read)) in exynos_rng_reseed()
187 exynos_rng_set_seed(rng, seed, read); 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() local
203 ret = clk_prepare_enable(rng->clk); in exynos_rng_generate()
207 mutex_lock(&rng->lock); in exynos_rng_generate()
209 ret = exynos_rng_get_random(rng, dst, dlen, &read); in exynos_rng_generate()
216 exynos_rng_reseed(rng); 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() local
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()
270 struct exynos_rng_dev *rng; in exynos_rng_probe() local
276 rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL); in exynos_rng_probe()
277 if (!rng) in exynos_rng_probe()
280 rng->type = (enum exynos_prng_type)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()
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()
295 platform_set_drvdata(pdev, rng); in exynos_rng_probe()
297 exynos_rng_dev = rng; in exynos_rng_probe()
302 "Couldn't register rng crypto alg: %d\n", ret); in exynos_rng_probe()
320 struct exynos_rng_dev *rng = dev_get_drvdata(dev); in exynos_rng_suspend() local
324 if (!rng->last_seeding) in exynos_rng_suspend()
327 rng->seed_save_len = 0; in exynos_rng_suspend()
328 ret = clk_prepare_enable(rng->clk); in exynos_rng_suspend()
332 mutex_lock(&rng->lock); in exynos_rng_suspend()
335 exynos_rng_get_random(rng, rng->seed_save, sizeof(rng->seed_save), in exynos_rng_suspend()
336 &(rng->seed_save_len)); in exynos_rng_suspend()
338 mutex_unlock(&rng->lock); in exynos_rng_suspend()
340 dev_dbg(rng->dev, "Stored %u bytes for seeding on system resume\n", in exynos_rng_suspend()
341 rng->seed_save_len); in exynos_rng_suspend()
343 clk_disable_unprepare(rng->clk); in exynos_rng_suspend()
350 struct exynos_rng_dev *rng = dev_get_drvdata(dev); in exynos_rng_resume() local
354 if (!rng->last_seeding) in exynos_rng_resume()
357 ret = clk_prepare_enable(rng->clk); in exynos_rng_resume()
361 mutex_lock(&rng->lock); in exynos_rng_resume()
363 ret = exynos_rng_set_seed(rng, rng->seed_save, rng->seed_save_len); in exynos_rng_resume()
365 mutex_unlock(&rng->lock); in exynos_rng_resume()
367 clk_disable_unprepare(rng->clk); in exynos_rng_resume()
377 .compatible = "samsung,exynos4-rng",
389 .name = "exynos-rng",