mxc-rnga.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. /*
  2. * RNG driver for Freescale RNGA
  3. *
  4. * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
  5. * Author: Alan Carvalho de Assis <acassis@gmail.com>
  6. */
  7. /*
  8. * The code contained herein is licensed under the GNU General Public
  9. * License. You may obtain a copy of the GNU General Public License
  10. * Version 2 or later at the following locations:
  11. *
  12. * http://www.opensource.org/licenses/gpl-license.html
  13. * http://www.gnu.org/copyleft/gpl.html
  14. *
  15. * This driver is based on other RNG drivers.
  16. */
  17. #include <linux/module.h>
  18. #include <linux/init.h>
  19. #include <linux/kernel.h>
  20. #include <linux/clk.h>
  21. #include <linux/err.h>
  22. #include <linux/ioport.h>
  23. #include <linux/platform_device.h>
  24. #include <linux/hw_random.h>
  25. #include <linux/delay.h>
  26. #include <linux/io.h>
  27. /* RNGA Registers */
  28. #define RNGA_CONTROL 0x00
  29. #define RNGA_STATUS 0x04
  30. #define RNGA_ENTROPY 0x08
  31. #define RNGA_OUTPUT_FIFO 0x0c
  32. #define RNGA_MODE 0x10
  33. #define RNGA_VERIFICATION_CONTROL 0x14
  34. #define RNGA_OSC_CONTROL_COUNTER 0x18
  35. #define RNGA_OSC1_COUNTER 0x1c
  36. #define RNGA_OSC2_COUNTER 0x20
  37. #define RNGA_OSC_COUNTER_STATUS 0x24
  38. /* RNGA Registers Range */
  39. #define RNG_ADDR_RANGE 0x28
  40. /* RNGA Control Register */
  41. #define RNGA_CONTROL_SLEEP 0x00000010
  42. #define RNGA_CONTROL_CLEAR_INT 0x00000008
  43. #define RNGA_CONTROL_MASK_INTS 0x00000004
  44. #define RNGA_CONTROL_HIGH_ASSURANCE 0x00000002
  45. #define RNGA_CONTROL_GO 0x00000001
  46. #define RNGA_STATUS_LEVEL_MASK 0x0000ff00
  47. /* RNGA Status Register */
  48. #define RNGA_STATUS_OSC_DEAD 0x80000000
  49. #define RNGA_STATUS_SLEEP 0x00000010
  50. #define RNGA_STATUS_ERROR_INT 0x00000008
  51. #define RNGA_STATUS_FIFO_UNDERFLOW 0x00000004
  52. #define RNGA_STATUS_LAST_READ_STATUS 0x00000002
  53. #define RNGA_STATUS_SECURITY_VIOLATION 0x00000001
  54. static struct platform_device *rng_dev;
  55. static int mxc_rnga_data_present(struct hwrng *rng, int wait)
  56. {
  57. void __iomem *rng_base = (void __iomem *)rng->priv;
  58. int i;
  59. for (i = 0; i < 20; i++) {
  60. /* how many random numbers are in FIFO? [0-16] */
  61. int level = (__raw_readl(rng_base + RNGA_STATUS) &
  62. RNGA_STATUS_LEVEL_MASK) >> 8;
  63. if (level || !wait)
  64. return !!level;
  65. udelay(10);
  66. }
  67. return 0;
  68. }
  69. static int mxc_rnga_data_read(struct hwrng *rng, u32 * data)
  70. {
  71. int err;
  72. u32 ctrl;
  73. void __iomem *rng_base = (void __iomem *)rng->priv;
  74. /* retrieve a random number from FIFO */
  75. *data = __raw_readl(rng_base + RNGA_OUTPUT_FIFO);
  76. /* some error while reading this random number? */
  77. err = __raw_readl(rng_base + RNGA_STATUS) & RNGA_STATUS_ERROR_INT;
  78. /* if error: clear error interrupt, but doesn't return random number */
  79. if (err) {
  80. dev_dbg(&rng_dev->dev, "Error while reading random number!\n");
  81. ctrl = __raw_readl(rng_base + RNGA_CONTROL);
  82. __raw_writel(ctrl | RNGA_CONTROL_CLEAR_INT,
  83. rng_base + RNGA_CONTROL);
  84. return 0;
  85. } else
  86. return 4;
  87. }
  88. static int mxc_rnga_init(struct hwrng *rng)
  89. {
  90. u32 ctrl, osc;
  91. void __iomem *rng_base = (void __iomem *)rng->priv;
  92. /* wake up */
  93. ctrl = __raw_readl(rng_base + RNGA_CONTROL);
  94. __raw_writel(ctrl & ~RNGA_CONTROL_SLEEP, rng_base + RNGA_CONTROL);
  95. /* verify if oscillator is working */
  96. osc = __raw_readl(rng_base + RNGA_STATUS);
  97. if (osc & RNGA_STATUS_OSC_DEAD) {
  98. dev_err(&rng_dev->dev, "RNGA Oscillator is dead!\n");
  99. return -ENODEV;
  100. }
  101. /* go running */
  102. ctrl = __raw_readl(rng_base + RNGA_CONTROL);
  103. __raw_writel(ctrl | RNGA_CONTROL_GO, rng_base + RNGA_CONTROL);
  104. return 0;
  105. }
  106. static void mxc_rnga_cleanup(struct hwrng *rng)
  107. {
  108. u32 ctrl;
  109. void __iomem *rng_base = (void __iomem *)rng->priv;
  110. ctrl = __raw_readl(rng_base + RNGA_CONTROL);
  111. /* stop rnga */
  112. __raw_writel(ctrl & ~RNGA_CONTROL_GO, rng_base + RNGA_CONTROL);
  113. }
  114. static struct hwrng mxc_rnga = {
  115. .name = "mxc-rnga",
  116. .init = mxc_rnga_init,
  117. .cleanup = mxc_rnga_cleanup,
  118. .data_present = mxc_rnga_data_present,
  119. .data_read = mxc_rnga_data_read
  120. };
  121. static int __init mxc_rnga_probe(struct platform_device *pdev)
  122. {
  123. int err = -ENODEV;
  124. struct clk *clk;
  125. struct resource *res, *mem;
  126. void __iomem *rng_base = NULL;
  127. if (rng_dev)
  128. return -EBUSY;
  129. clk = clk_get(&pdev->dev, "rng");
  130. if (IS_ERR(clk)) {
  131. dev_err(&pdev->dev, "Could not get rng_clk!\n");
  132. err = PTR_ERR(clk);
  133. goto out;
  134. }
  135. clk_enable(clk);
  136. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  137. if (!res) {
  138. err = -ENOENT;
  139. goto err_region;
  140. }
  141. mem = request_mem_region(res->start, resource_size(res), pdev->name);
  142. if (mem == NULL) {
  143. err = -EBUSY;
  144. goto err_region;
  145. }
  146. rng_base = ioremap(res->start, resource_size(res));
  147. if (!rng_base) {
  148. err = -ENOMEM;
  149. goto err_ioremap;
  150. }
  151. mxc_rnga.priv = (unsigned long)rng_base;
  152. err = hwrng_register(&mxc_rnga);
  153. if (err) {
  154. dev_err(&pdev->dev, "MXC RNGA registering failed (%d)\n", err);
  155. goto err_register;
  156. }
  157. rng_dev = pdev;
  158. dev_info(&pdev->dev, "MXC RNGA Registered.\n");
  159. return 0;
  160. err_register:
  161. iounmap(rng_base);
  162. rng_base = NULL;
  163. err_ioremap:
  164. release_mem_region(res->start, resource_size(res));
  165. err_region:
  166. clk_disable(clk);
  167. clk_put(clk);
  168. out:
  169. return err;
  170. }
  171. static int __exit mxc_rnga_remove(struct platform_device *pdev)
  172. {
  173. struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  174. void __iomem *rng_base = (void __iomem *)mxc_rnga.priv;
  175. struct clk *clk = clk_get(&pdev->dev, "rng");
  176. hwrng_unregister(&mxc_rnga);
  177. iounmap(rng_base);
  178. release_mem_region(res->start, resource_size(res));
  179. clk_disable(clk);
  180. clk_put(clk);
  181. return 0;
  182. }
  183. static struct platform_driver mxc_rnga_driver = {
  184. .driver = {
  185. .name = "mxc_rnga",
  186. .owner = THIS_MODULE,
  187. },
  188. .remove = __exit_p(mxc_rnga_remove),
  189. };
  190. static int __init mod_init(void)
  191. {
  192. return platform_driver_probe(&mxc_rnga_driver, mxc_rnga_probe);
  193. }
  194. static void __exit mod_exit(void)
  195. {
  196. platform_driver_unregister(&mxc_rnga_driver);
  197. }
  198. module_init(mod_init);
  199. module_exit(mod_exit);
  200. MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  201. MODULE_DESCRIPTION("H/W RNGA driver for i.MX");
  202. MODULE_LICENSE("GPL");