sl3516-ce-rng.c 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  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 <[email protected]>
  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. static int sl3516_ce_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
  13. {
  14. struct sl3516_ce_dev *ce;
  15. u32 *data = buf;
  16. size_t read = 0;
  17. int err;
  18. ce = container_of(rng, struct sl3516_ce_dev, trng);
  19. #ifdef CONFIG_CRYPTO_DEV_SL3516_DEBUG
  20. ce->hwrng_stat_req++;
  21. ce->hwrng_stat_bytes += max;
  22. #endif
  23. err = pm_runtime_get_sync(ce->dev);
  24. if (err < 0) {
  25. pm_runtime_put_noidle(ce->dev);
  26. return err;
  27. }
  28. while (read < max) {
  29. *data = readl(ce->base + IPSEC_RAND_NUM_REG);
  30. data++;
  31. read += 4;
  32. }
  33. pm_runtime_put(ce->dev);
  34. return read;
  35. }
  36. int sl3516_ce_rng_register(struct sl3516_ce_dev *ce)
  37. {
  38. int ret;
  39. ce->trng.name = "SL3516 Crypto Engine RNG";
  40. ce->trng.read = sl3516_ce_rng_read;
  41. ce->trng.quality = 700;
  42. ret = hwrng_register(&ce->trng);
  43. if (ret)
  44. dev_err(ce->dev, "Fail to register the RNG\n");
  45. return ret;
  46. }
  47. void sl3516_ce_rng_unregister(struct sl3516_ce_dev *ce)
  48. {
  49. hwrng_unregister(&ce->trng);
  50. }