ccp-platform.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. /*
  2. * AMD Cryptographic Coprocessor (CCP) driver
  3. *
  4. * Copyright (C) 2014 Advanced Micro Devices, Inc.
  5. *
  6. * Author: Tom Lendacky <thomas.lendacky@amd.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License version 2 as
  10. * published by the Free Software Foundation.
  11. */
  12. #include <linux/module.h>
  13. #include <linux/kernel.h>
  14. #include <linux/device.h>
  15. #include <linux/platform_device.h>
  16. #include <linux/ioport.h>
  17. #include <linux/dma-mapping.h>
  18. #include <linux/kthread.h>
  19. #include <linux/sched.h>
  20. #include <linux/interrupt.h>
  21. #include <linux/spinlock.h>
  22. #include <linux/delay.h>
  23. #include <linux/ccp.h>
  24. #include <linux/of.h>
  25. #include <linux/of_address.h>
  26. #include <linux/acpi.h>
  27. #include "ccp-dev.h"
  28. struct ccp_platform {
  29. int use_acpi;
  30. int coherent;
  31. };
  32. static int ccp_get_irq(struct ccp_device *ccp)
  33. {
  34. struct device *dev = ccp->dev;
  35. struct platform_device *pdev = container_of(dev,
  36. struct platform_device, dev);
  37. int ret;
  38. ret = platform_get_irq(pdev, 0);
  39. if (ret < 0)
  40. return ret;
  41. ccp->irq = ret;
  42. ret = request_irq(ccp->irq, ccp_irq_handler, 0, "ccp", dev);
  43. if (ret) {
  44. dev_notice(dev, "unable to allocate IRQ (%d)\n", ret);
  45. return ret;
  46. }
  47. return 0;
  48. }
  49. static int ccp_get_irqs(struct ccp_device *ccp)
  50. {
  51. struct device *dev = ccp->dev;
  52. int ret;
  53. ret = ccp_get_irq(ccp);
  54. if (!ret)
  55. return 0;
  56. /* Couldn't get an interrupt */
  57. dev_notice(dev, "could not enable interrupts (%d)\n", ret);
  58. return ret;
  59. }
  60. static void ccp_free_irqs(struct ccp_device *ccp)
  61. {
  62. struct device *dev = ccp->dev;
  63. free_irq(ccp->irq, dev);
  64. }
  65. static struct resource *ccp_find_mmio_area(struct ccp_device *ccp)
  66. {
  67. struct device *dev = ccp->dev;
  68. struct platform_device *pdev = container_of(dev,
  69. struct platform_device, dev);
  70. struct resource *ior;
  71. ior = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  72. if (ior && (resource_size(ior) >= 0x800))
  73. return ior;
  74. return NULL;
  75. }
  76. static int ccp_platform_probe(struct platform_device *pdev)
  77. {
  78. struct ccp_device *ccp;
  79. struct ccp_platform *ccp_platform;
  80. struct device *dev = &pdev->dev;
  81. struct acpi_device *adev = ACPI_COMPANION(dev);
  82. struct resource *ior;
  83. int ret;
  84. ret = -ENOMEM;
  85. ccp = ccp_alloc_struct(dev);
  86. if (!ccp)
  87. goto e_err;
  88. ccp_platform = devm_kzalloc(dev, sizeof(*ccp_platform), GFP_KERNEL);
  89. if (!ccp_platform)
  90. goto e_err;
  91. ccp->dev_specific = ccp_platform;
  92. ccp->get_irq = ccp_get_irqs;
  93. ccp->free_irq = ccp_free_irqs;
  94. ccp_platform->use_acpi = (!adev || acpi_disabled) ? 0 : 1;
  95. ior = ccp_find_mmio_area(ccp);
  96. ccp->io_map = devm_ioremap_resource(dev, ior);
  97. if (IS_ERR(ccp->io_map)) {
  98. ret = PTR_ERR(ccp->io_map);
  99. goto e_err;
  100. }
  101. ccp->io_regs = ccp->io_map;
  102. ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48));
  103. if (ret) {
  104. dev_err(dev, "dma_set_mask_and_coherent failed (%d)\n", ret);
  105. goto e_err;
  106. }
  107. ccp_platform->coherent = device_dma_is_coherent(ccp->dev);
  108. if (ccp_platform->coherent)
  109. ccp->axcache = CACHE_WB_NO_ALLOC;
  110. else
  111. ccp->axcache = CACHE_NONE;
  112. dev_set_drvdata(dev, ccp);
  113. ret = ccp_init(ccp);
  114. if (ret)
  115. goto e_err;
  116. dev_notice(dev, "enabled\n");
  117. return 0;
  118. e_err:
  119. dev_notice(dev, "initialization failed\n");
  120. return ret;
  121. }
  122. static int ccp_platform_remove(struct platform_device *pdev)
  123. {
  124. struct device *dev = &pdev->dev;
  125. struct ccp_device *ccp = dev_get_drvdata(dev);
  126. ccp_destroy(ccp);
  127. dev_notice(dev, "disabled\n");
  128. return 0;
  129. }
  130. #ifdef CONFIG_PM
  131. static int ccp_platform_suspend(struct platform_device *pdev,
  132. pm_message_t state)
  133. {
  134. struct device *dev = &pdev->dev;
  135. struct ccp_device *ccp = dev_get_drvdata(dev);
  136. unsigned long flags;
  137. unsigned int i;
  138. spin_lock_irqsave(&ccp->cmd_lock, flags);
  139. ccp->suspending = 1;
  140. /* Wake all the queue kthreads to prepare for suspend */
  141. for (i = 0; i < ccp->cmd_q_count; i++)
  142. wake_up_process(ccp->cmd_q[i].kthread);
  143. spin_unlock_irqrestore(&ccp->cmd_lock, flags);
  144. /* Wait for all queue kthreads to say they're done */
  145. while (!ccp_queues_suspended(ccp))
  146. wait_event_interruptible(ccp->suspend_queue,
  147. ccp_queues_suspended(ccp));
  148. return 0;
  149. }
  150. static int ccp_platform_resume(struct platform_device *pdev)
  151. {
  152. struct device *dev = &pdev->dev;
  153. struct ccp_device *ccp = dev_get_drvdata(dev);
  154. unsigned long flags;
  155. unsigned int i;
  156. spin_lock_irqsave(&ccp->cmd_lock, flags);
  157. ccp->suspending = 0;
  158. /* Wake up all the kthreads */
  159. for (i = 0; i < ccp->cmd_q_count; i++) {
  160. ccp->cmd_q[i].suspended = 0;
  161. wake_up_process(ccp->cmd_q[i].kthread);
  162. }
  163. spin_unlock_irqrestore(&ccp->cmd_lock, flags);
  164. return 0;
  165. }
  166. #endif
  167. #ifdef CONFIG_ACPI
  168. static const struct acpi_device_id ccp_acpi_match[] = {
  169. { "AMDI0C00", 0 },
  170. { },
  171. };
  172. MODULE_DEVICE_TABLE(acpi, ccp_acpi_match);
  173. #endif
  174. #ifdef CONFIG_OF
  175. static const struct of_device_id ccp_of_match[] = {
  176. { .compatible = "amd,ccp-seattle-v1a" },
  177. { },
  178. };
  179. MODULE_DEVICE_TABLE(of, ccp_of_match);
  180. #endif
  181. static struct platform_driver ccp_platform_driver = {
  182. .driver = {
  183. .name = "AMD Cryptographic Coprocessor",
  184. #ifdef CONFIG_ACPI
  185. .acpi_match_table = ccp_acpi_match,
  186. #endif
  187. #ifdef CONFIG_OF
  188. .of_match_table = ccp_of_match,
  189. #endif
  190. },
  191. .probe = ccp_platform_probe,
  192. .remove = ccp_platform_remove,
  193. #ifdef CONFIG_PM
  194. .suspend = ccp_platform_suspend,
  195. .resume = ccp_platform_resume,
  196. #endif
  197. };
  198. int ccp_platform_init(void)
  199. {
  200. return platform_driver_register(&ccp_platform_driver);
  201. }
  202. void ccp_platform_exit(void)
  203. {
  204. platform_driver_unregister(&ccp_platform_driver);
  205. }