PageRenderTime 30ms CodeModel.GetById 35ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/misc/mic/card/mic_device.c

https://gitlab.com/openbar/rpi-linux
C | 356 lines | 238 code | 39 blank | 79 comment | 17 complexity | cfcf4a4273143996231ab0183cf41598 MD5 | raw file
  1. /*
  2. * Intel MIC Platform Software Stack (MPSS)
  3. *
  4. * Copyright(c) 2013 Intel Corporation.
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License, version 2, as
  8. * published by the Free Software Foundation.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * General Public License for more details.
  14. *
  15. * The full GNU General Public License is included in this distribution in
  16. * the file called "COPYING".
  17. *
  18. * Disclaimer: The codes contained in these modules may be specific to
  19. * the Intel Software Development Platform codenamed: Knights Ferry, and
  20. * the Intel product codenamed: Knights Corner, and are not backward
  21. * compatible with other Intel products. Additionally, Intel will NOT
  22. * support the codes or instruction set in future products.
  23. *
  24. * Intel MIC Card driver.
  25. *
  26. */
  27. #include <linux/module.h>
  28. #include <linux/pci.h>
  29. #include <linux/interrupt.h>
  30. #include <linux/reboot.h>
  31. #include <linux/dmaengine.h>
  32. #include <linux/kmod.h>
  33. #include <linux/mic_common.h>
  34. #include "../common/mic_dev.h"
  35. #include "mic_device.h"
  36. #include "mic_virtio.h"
  37. static struct mic_driver *g_drv;
  38. static int __init mic_dp_init(void)
  39. {
  40. struct mic_driver *mdrv = g_drv;
  41. struct mic_device *mdev = &mdrv->mdev;
  42. struct mic_bootparam __iomem *bootparam;
  43. u64 lo, hi, dp_dma_addr;
  44. u32 magic;
  45. lo = mic_read_spad(&mdrv->mdev, MIC_DPLO_SPAD);
  46. hi = mic_read_spad(&mdrv->mdev, MIC_DPHI_SPAD);
  47. dp_dma_addr = lo | (hi << 32);
  48. mdrv->dp = mic_card_map(mdev, dp_dma_addr, MIC_DP_SIZE);
  49. if (!mdrv->dp) {
  50. dev_err(mdrv->dev, "Cannot remap Aperture BAR\n");
  51. return -ENOMEM;
  52. }
  53. bootparam = mdrv->dp;
  54. magic = ioread32(&bootparam->magic);
  55. if (MIC_MAGIC != magic) {
  56. dev_err(mdrv->dev, "bootparam magic mismatch 0x%x\n", magic);
  57. return -EIO;
  58. }
  59. return 0;
  60. }
  61. /* Uninitialize the device page */
  62. static void mic_dp_uninit(void)
  63. {
  64. mic_card_unmap(&g_drv->mdev, g_drv->dp);
  65. }
  66. /**
  67. * mic_request_card_irq - request an irq.
  68. *
  69. * @handler: interrupt handler passed to request_threaded_irq.
  70. * @thread_fn: thread fn. passed to request_threaded_irq.
  71. * @name: The ASCII name of the callee requesting the irq.
  72. * @data: private data that is returned back when calling the
  73. * function handler.
  74. * @index: The doorbell index of the requester.
  75. *
  76. * returns: The cookie that is transparent to the caller. Passed
  77. * back when calling mic_free_irq. An appropriate error code
  78. * is returned on failure. Caller needs to use IS_ERR(return_val)
  79. * to check for failure and PTR_ERR(return_val) to obtained the
  80. * error code.
  81. *
  82. */
  83. struct mic_irq *
  84. mic_request_card_irq(irq_handler_t handler,
  85. irq_handler_t thread_fn, const char *name,
  86. void *data, int index)
  87. {
  88. int rc = 0;
  89. unsigned long cookie;
  90. struct mic_driver *mdrv = g_drv;
  91. rc = request_threaded_irq(mic_db_to_irq(mdrv, index), handler,
  92. thread_fn, 0, name, data);
  93. if (rc) {
  94. dev_err(mdrv->dev, "request_threaded_irq failed rc = %d\n", rc);
  95. goto err;
  96. }
  97. mdrv->irq_info.irq_usage_count[index]++;
  98. cookie = index;
  99. return (struct mic_irq *)cookie;
  100. err:
  101. return ERR_PTR(rc);
  102. }
  103. /**
  104. * mic_free_card_irq - free irq.
  105. *
  106. * @cookie: cookie obtained during a successful call to mic_request_threaded_irq
  107. * @data: private data specified by the calling function during the
  108. * mic_request_threaded_irq
  109. *
  110. * returns: none.
  111. */
  112. void mic_free_card_irq(struct mic_irq *cookie, void *data)
  113. {
  114. int index;
  115. struct mic_driver *mdrv = g_drv;
  116. index = (unsigned long)cookie & 0xFFFFU;
  117. free_irq(mic_db_to_irq(mdrv, index), data);
  118. mdrv->irq_info.irq_usage_count[index]--;
  119. }
  120. /**
  121. * mic_next_card_db - Get the doorbell with minimum usage count.
  122. *
  123. * Returns the irq index.
  124. */
  125. int mic_next_card_db(void)
  126. {
  127. int i;
  128. int index = 0;
  129. struct mic_driver *mdrv = g_drv;
  130. for (i = 0; i < mdrv->intr_info.num_intr; i++) {
  131. if (mdrv->irq_info.irq_usage_count[i] <
  132. mdrv->irq_info.irq_usage_count[index])
  133. index = i;
  134. }
  135. return index;
  136. }
  137. /**
  138. * mic_init_irq - Initialize irq information.
  139. *
  140. * Returns 0 in success. Appropriate error code on failure.
  141. */
  142. static int mic_init_irq(void)
  143. {
  144. struct mic_driver *mdrv = g_drv;
  145. mdrv->irq_info.irq_usage_count = kzalloc((sizeof(u32) *
  146. mdrv->intr_info.num_intr),
  147. GFP_KERNEL);
  148. if (!mdrv->irq_info.irq_usage_count)
  149. return -ENOMEM;
  150. return 0;
  151. }
  152. /**
  153. * mic_uninit_irq - Uninitialize irq information.
  154. *
  155. * None.
  156. */
  157. static void mic_uninit_irq(void)
  158. {
  159. struct mic_driver *mdrv = g_drv;
  160. kfree(mdrv->irq_info.irq_usage_count);
  161. }
  162. static inline struct mic_driver *scdev_to_mdrv(struct scif_hw_dev *scdev)
  163. {
  164. return dev_get_drvdata(scdev->dev.parent);
  165. }
  166. static struct mic_irq *
  167. ___mic_request_irq(struct scif_hw_dev *scdev,
  168. irqreturn_t (*func)(int irq, void *data),
  169. const char *name, void *data,
  170. int db)
  171. {
  172. return mic_request_card_irq(func, NULL, name, data, db);
  173. }
  174. static void
  175. ___mic_free_irq(struct scif_hw_dev *scdev,
  176. struct mic_irq *cookie, void *data)
  177. {
  178. return mic_free_card_irq(cookie, data);
  179. }
  180. static void ___mic_ack_interrupt(struct scif_hw_dev *scdev, int num)
  181. {
  182. struct mic_driver *mdrv = scdev_to_mdrv(scdev);
  183. mic_ack_interrupt(&mdrv->mdev);
  184. }
  185. static int ___mic_next_db(struct scif_hw_dev *scdev)
  186. {
  187. return mic_next_card_db();
  188. }
  189. static void ___mic_send_intr(struct scif_hw_dev *scdev, int db)
  190. {
  191. struct mic_driver *mdrv = scdev_to_mdrv(scdev);
  192. mic_send_intr(&mdrv->mdev, db);
  193. }
  194. static void ___mic_send_p2p_intr(struct scif_hw_dev *scdev, int db,
  195. struct mic_mw *mw)
  196. {
  197. mic_send_p2p_intr(db, mw);
  198. }
  199. static void __iomem *
  200. ___mic_ioremap(struct scif_hw_dev *scdev,
  201. phys_addr_t pa, size_t len)
  202. {
  203. struct mic_driver *mdrv = scdev_to_mdrv(scdev);
  204. return mic_card_map(&mdrv->mdev, pa, len);
  205. }
  206. static void ___mic_iounmap(struct scif_hw_dev *scdev, void __iomem *va)
  207. {
  208. struct mic_driver *mdrv = scdev_to_mdrv(scdev);
  209. mic_card_unmap(&mdrv->mdev, va);
  210. }
  211. static struct scif_hw_ops scif_hw_ops = {
  212. .request_irq = ___mic_request_irq,
  213. .free_irq = ___mic_free_irq,
  214. .ack_interrupt = ___mic_ack_interrupt,
  215. .next_db = ___mic_next_db,
  216. .send_intr = ___mic_send_intr,
  217. .send_p2p_intr = ___mic_send_p2p_intr,
  218. .ioremap = ___mic_ioremap,
  219. .iounmap = ___mic_iounmap,
  220. };
  221. static int mic_request_dma_chans(struct mic_driver *mdrv)
  222. {
  223. dma_cap_mask_t mask;
  224. struct dma_chan *chan;
  225. request_module("mic_x100_dma");
  226. dma_cap_zero(mask);
  227. dma_cap_set(DMA_MEMCPY, mask);
  228. do {
  229. chan = dma_request_channel(mask, NULL, NULL);
  230. if (chan) {
  231. mdrv->dma_ch[mdrv->num_dma_ch++] = chan;
  232. if (mdrv->num_dma_ch >= MIC_MAX_DMA_CHAN)
  233. break;
  234. }
  235. } while (chan);
  236. dev_info(mdrv->dev, "DMA channels # %d\n", mdrv->num_dma_ch);
  237. return mdrv->num_dma_ch;
  238. }
  239. static void mic_free_dma_chans(struct mic_driver *mdrv)
  240. {
  241. int i = 0;
  242. for (i = 0; i < mdrv->num_dma_ch; i++) {
  243. dma_release_channel(mdrv->dma_ch[i]);
  244. mdrv->dma_ch[i] = NULL;
  245. }
  246. mdrv->num_dma_ch = 0;
  247. }
  248. /*
  249. * mic_driver_init - MIC driver initialization tasks.
  250. *
  251. * Returns 0 in success. Appropriate error code on failure.
  252. */
  253. int __init mic_driver_init(struct mic_driver *mdrv)
  254. {
  255. int rc;
  256. struct mic_bootparam __iomem *bootparam;
  257. u8 node_id;
  258. g_drv = mdrv;
  259. /* Unloading the card module is not supported. */
  260. if (!try_module_get(mdrv->dev->driver->owner)) {
  261. rc = -ENODEV;
  262. goto done;
  263. }
  264. rc = mic_dp_init();
  265. if (rc)
  266. goto put;
  267. rc = mic_init_irq();
  268. if (rc)
  269. goto dp_uninit;
  270. if (!mic_request_dma_chans(mdrv)) {
  271. rc = -ENODEV;
  272. goto irq_uninit;
  273. }
  274. rc = mic_devices_init(mdrv);
  275. if (rc)
  276. goto dma_free;
  277. bootparam = mdrv->dp;
  278. node_id = ioread8(&bootparam->node_id);
  279. mdrv->scdev = scif_register_device(mdrv->dev, MIC_SCIF_DEV,
  280. NULL, &scif_hw_ops,
  281. 0, node_id, &mdrv->mdev.mmio, NULL,
  282. NULL, mdrv->dp, mdrv->dma_ch,
  283. mdrv->num_dma_ch, true);
  284. if (IS_ERR(mdrv->scdev)) {
  285. rc = PTR_ERR(mdrv->scdev);
  286. goto device_uninit;
  287. }
  288. mic_create_card_debug_dir(mdrv);
  289. done:
  290. return rc;
  291. device_uninit:
  292. mic_devices_uninit(mdrv);
  293. dma_free:
  294. mic_free_dma_chans(mdrv);
  295. irq_uninit:
  296. mic_uninit_irq();
  297. dp_uninit:
  298. mic_dp_uninit();
  299. put:
  300. module_put(mdrv->dev->driver->owner);
  301. return rc;
  302. }
  303. /*
  304. * mic_driver_uninit - MIC driver uninitialization tasks.
  305. *
  306. * Returns None
  307. */
  308. void mic_driver_uninit(struct mic_driver *mdrv)
  309. {
  310. mic_delete_card_debug_dir(mdrv);
  311. scif_unregister_device(mdrv->scdev);
  312. mic_devices_uninit(mdrv);
  313. mic_free_dma_chans(mdrv);
  314. mic_uninit_irq();
  315. mic_dp_uninit();
  316. module_put(mdrv->dev->driver->owner);
  317. }