virt.c 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * DMA operations that map to virtual addresses without flushing memory.
  4. */
  5. #include <linux/export.h>
  6. #include <linux/mm.h>
  7. #include <linux/dma-map-ops.h>
  8. #include <linux/scatterlist.h>
  9. static void *dma_virt_alloc(struct device *dev, size_t size,
  10. dma_addr_t *dma_handle, gfp_t gfp,
  11. unsigned long attrs)
  12. {
  13. void *ret;
  14. ret = (void *)__get_free_pages(gfp | __GFP_ZERO, get_order(size));
  15. if (ret)
  16. *dma_handle = (uintptr_t)ret;
  17. return ret;
  18. }
  19. static void dma_virt_free(struct device *dev, size_t size,
  20. void *cpu_addr, dma_addr_t dma_addr,
  21. unsigned long attrs)
  22. {
  23. free_pages((unsigned long)cpu_addr, get_order(size));
  24. }
  25. static dma_addr_t dma_virt_map_page(struct device *dev, struct page *page,
  26. unsigned long offset, size_t size,
  27. enum dma_data_direction dir,
  28. unsigned long attrs)
  29. {
  30. return (uintptr_t)(page_address(page) + offset);
  31. }
  32. static int dma_virt_map_sg(struct device *dev, struct scatterlist *sgl,
  33. int nents, enum dma_data_direction dir,
  34. unsigned long attrs)
  35. {
  36. int i;
  37. struct scatterlist *sg;
  38. for_each_sg(sgl, sg, nents, i) {
  39. BUG_ON(!sg_page(sg));
  40. sg_dma_address(sg) = (uintptr_t)sg_virt(sg);
  41. sg_dma_len(sg) = sg->length;
  42. }
  43. return nents;
  44. }
  45. const struct dma_map_ops dma_virt_ops = {
  46. .alloc = dma_virt_alloc,
  47. .free = dma_virt_free,
  48. .map_page = dma_virt_map_page,
  49. .map_sg = dma_virt_map_sg,
  50. .alloc_pages = dma_common_alloc_pages,
  51. .free_pages = dma_common_free_pages,
  52. };
  53. EXPORT_SYMBOL(dma_virt_ops);