1 | // SPDX-License-Identifier: GPL-2.0 |
---|---|
2 | /* |
3 | * sl3516-ce-rng.c - hardware cryptographic offloader for SL3516 SoC. |
4 | * |
5 | * Copyright (C) 2021 Corentin Labbe <clabbe@baylibre.com> |
6 | * |
7 | * This file handle the RNG found in the SL3516 crypto engine |
8 | */ |
9 | #include "sl3516-ce.h" |
10 | #include <linux/pm_runtime.h> |
11 | #include <linux/hw_random.h> |
12 | |
13 | static int sl3516_ce_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait) |
14 | { |
15 | struct sl3516_ce_dev *ce; |
16 | u32 *data = buf; |
17 | size_t read = 0; |
18 | int err; |
19 | |
20 | ce = container_of(rng, struct sl3516_ce_dev, trng); |
21 | |
22 | #ifdef CONFIG_CRYPTO_DEV_SL3516_DEBUG |
23 | ce->hwrng_stat_req++; |
24 | ce->hwrng_stat_bytes += max; |
25 | #endif |
26 | |
27 | err = pm_runtime_get_sync(dev: ce->dev); |
28 | if (err < 0) { |
29 | pm_runtime_put_noidle(dev: ce->dev); |
30 | return err; |
31 | } |
32 | |
33 | while (read < max) { |
34 | *data = readl(addr: ce->base + IPSEC_RAND_NUM_REG); |
35 | data++; |
36 | read += 4; |
37 | } |
38 | |
39 | pm_runtime_put(dev: ce->dev); |
40 | |
41 | return read; |
42 | } |
43 | |
44 | int sl3516_ce_rng_register(struct sl3516_ce_dev *ce) |
45 | { |
46 | int ret; |
47 | |
48 | ce->trng.name = "SL3516 Crypto Engine RNG"; |
49 | ce->trng.read = sl3516_ce_rng_read; |
50 | ce->trng.quality = 700; |
51 | |
52 | ret = hwrng_register(rng: &ce->trng); |
53 | if (ret) |
54 | dev_err(ce->dev, "Fail to register the RNG\n"); |
55 | return ret; |
56 | } |
57 | |
58 | void sl3516_ce_rng_unregister(struct sl3516_ce_dev *ce) |
59 | { |
60 | hwrng_unregister(rng: &ce->trng); |
61 | } |
62 |