scif_map.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*
  2. * Intel MIC Platform Software Stack (MPSS)
  3. *
  4. * Copyright(c) 2014 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. * Intel SCIF driver.
  16. *
  17. */
  18. #ifndef SCIF_MAP_H
  19. #define SCIF_MAP_H
  20. #include "../bus/scif_bus.h"
  21. static __always_inline void *
  22. scif_alloc_coherent(dma_addr_t *dma_handle,
  23. struct scif_dev *scifdev, size_t size,
  24. gfp_t gfp)
  25. {
  26. void *va;
  27. if (scifdev_self(scifdev)) {
  28. va = kmalloc(size, gfp);
  29. if (va)
  30. *dma_handle = virt_to_phys(va);
  31. } else {
  32. va = dma_alloc_coherent(&scifdev->sdev->dev,
  33. size, dma_handle, gfp);
  34. if (va && scifdev_is_p2p(scifdev))
  35. *dma_handle = *dma_handle + scifdev->base_addr;
  36. }
  37. return va;
  38. }
  39. static __always_inline void
  40. scif_free_coherent(void *va, dma_addr_t local,
  41. struct scif_dev *scifdev, size_t size)
  42. {
  43. if (scifdev_self(scifdev)) {
  44. kfree(va);
  45. } else {
  46. if (scifdev_is_p2p(scifdev) && local > scifdev->base_addr)
  47. local = local - scifdev->base_addr;
  48. dma_free_coherent(&scifdev->sdev->dev,
  49. size, va, local);
  50. }
  51. }
  52. static __always_inline int
  53. scif_map_single(dma_addr_t *dma_handle,
  54. void *local, struct scif_dev *scifdev, size_t size)
  55. {
  56. int err = 0;
  57. if (scifdev_self(scifdev)) {
  58. *dma_handle = virt_to_phys((local));
  59. } else {
  60. *dma_handle = dma_map_single(&scifdev->sdev->dev,
  61. local, size, DMA_BIDIRECTIONAL);
  62. if (dma_mapping_error(&scifdev->sdev->dev, *dma_handle))
  63. err = -ENOMEM;
  64. else if (scifdev_is_p2p(scifdev))
  65. *dma_handle = *dma_handle + scifdev->base_addr;
  66. }
  67. if (err)
  68. *dma_handle = 0;
  69. return err;
  70. }
  71. static __always_inline void
  72. scif_unmap_single(dma_addr_t local, struct scif_dev *scifdev,
  73. size_t size)
  74. {
  75. if (!scifdev_self(scifdev)) {
  76. if (scifdev_is_p2p(scifdev))
  77. local = local - scifdev->base_addr;
  78. dma_unmap_single(&scifdev->sdev->dev, local,
  79. size, DMA_BIDIRECTIONAL);
  80. }
  81. }
  82. static __always_inline void *
  83. scif_ioremap(dma_addr_t phys, size_t size, struct scif_dev *scifdev)
  84. {
  85. void *out_virt;
  86. struct scif_hw_dev *sdev = scifdev->sdev;
  87. if (scifdev_self(scifdev))
  88. out_virt = phys_to_virt(phys);
  89. else
  90. out_virt = (void __force *)
  91. sdev->hw_ops->ioremap(sdev, phys, size);
  92. return out_virt;
  93. }
  94. static __always_inline void
  95. scif_iounmap(void *virt, size_t len, struct scif_dev *scifdev)
  96. {
  97. if (!scifdev_self(scifdev)) {
  98. struct scif_hw_dev *sdev = scifdev->sdev;
  99. sdev->hw_ops->iounmap(sdev, (void __force __iomem *)virt);
  100. }
  101. }
  102. static __always_inline int
  103. scif_map_page(dma_addr_t *dma_handle, struct page *page,
  104. struct scif_dev *scifdev)
  105. {
  106. int err = 0;
  107. if (scifdev_self(scifdev)) {
  108. *dma_handle = page_to_phys(page);
  109. } else {
  110. struct scif_hw_dev *sdev = scifdev->sdev;
  111. *dma_handle = dma_map_page(&sdev->dev,
  112. page, 0x0, PAGE_SIZE,
  113. DMA_BIDIRECTIONAL);
  114. if (dma_mapping_error(&sdev->dev, *dma_handle))
  115. err = -ENOMEM;
  116. else if (scifdev_is_p2p(scifdev))
  117. *dma_handle = *dma_handle + scifdev->base_addr;
  118. }
  119. if (err)
  120. *dma_handle = 0;
  121. return err;
  122. }
  123. #endif /* SCIF_MAP_H */