dma-noop.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * lib/dma-noop.c
  4. *
  5. * DMA operations that map to physical addresses without flushing memory.
  6. */
  7. #include <linux/export.h>
  8. #include <linux/mm.h>
  9. #include <linux/dma-mapping.h>
  10. #include <linux/scatterlist.h>
  11. #include <linux/pfn.h>
  12. static void *dma_noop_alloc(struct device *dev, size_t size,
  13. dma_addr_t *dma_handle, gfp_t gfp,
  14. unsigned long attrs)
  15. {
  16. void *ret;
  17. ret = (void *)__get_free_pages(gfp, get_order(size));
  18. if (ret)
  19. *dma_handle = virt_to_phys(ret) - PFN_PHYS(dev->dma_pfn_offset);
  20. return ret;
  21. }
  22. static void dma_noop_free(struct device *dev, size_t size,
  23. void *cpu_addr, dma_addr_t dma_addr,
  24. unsigned long attrs)
  25. {
  26. free_pages((unsigned long)cpu_addr, get_order(size));
  27. }
  28. static dma_addr_t dma_noop_map_page(struct device *dev, struct page *page,
  29. unsigned long offset, size_t size,
  30. enum dma_data_direction dir,
  31. unsigned long attrs)
  32. {
  33. return page_to_phys(page) + offset - PFN_PHYS(dev->dma_pfn_offset);
  34. }
  35. static int dma_noop_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
  36. enum dma_data_direction dir,
  37. unsigned long attrs)
  38. {
  39. int i;
  40. struct scatterlist *sg;
  41. for_each_sg(sgl, sg, nents, i) {
  42. dma_addr_t offset = PFN_PHYS(dev->dma_pfn_offset);
  43. void *va;
  44. BUG_ON(!sg_page(sg));
  45. va = sg_virt(sg);
  46. sg_dma_address(sg) = (dma_addr_t)virt_to_phys(va) - offset;
  47. sg_dma_len(sg) = sg->length;
  48. }
  49. return nents;
  50. }
  51. const struct dma_map_ops dma_noop_ops = {
  52. .alloc = dma_noop_alloc,
  53. .free = dma_noop_free,
  54. .map_page = dma_noop_map_page,
  55. .map_sg = dma_noop_map_sg,
  56. };
  57. EXPORT_SYMBOL(dma_noop_ops);