dma-coherent.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /*
  2. * Copyright (C) 2004 - 2007 Paul Mundt
  3. *
  4. * This file is subject to the terms and conditions of the GNU General Public
  5. * License. See the file "COPYING" in the main directory of this archive
  6. * for more details.
  7. */
  8. #include <linux/mm.h>
  9. #include <linux/init.h>
  10. #include <linux/dma-noncoherent.h>
  11. #include <linux/module.h>
  12. #include <asm/cacheflush.h>
  13. #include <asm/addrspace.h>
  14. void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
  15. gfp_t gfp, unsigned long attrs)
  16. {
  17. void *ret, *ret_nocache;
  18. int order = get_order(size);
  19. gfp |= __GFP_ZERO;
  20. ret = (void *)__get_free_pages(gfp, order);
  21. if (!ret)
  22. return NULL;
  23. /*
  24. * Pages from the page allocator may have data present in
  25. * cache. So flush the cache before using uncached memory.
  26. */
  27. arch_sync_dma_for_device(dev, virt_to_phys(ret), size,
  28. DMA_BIDIRECTIONAL);
  29. ret_nocache = (void __force *)ioremap_nocache(virt_to_phys(ret), size);
  30. if (!ret_nocache) {
  31. free_pages((unsigned long)ret, order);
  32. return NULL;
  33. }
  34. split_page(pfn_to_page(virt_to_phys(ret) >> PAGE_SHIFT), order);
  35. *dma_handle = virt_to_phys(ret);
  36. if (!WARN_ON(!dev))
  37. *dma_handle -= PFN_PHYS(dev->dma_pfn_offset);
  38. return ret_nocache;
  39. }
  40. void arch_dma_free(struct device *dev, size_t size, void *vaddr,
  41. dma_addr_t dma_handle, unsigned long attrs)
  42. {
  43. int order = get_order(size);
  44. unsigned long pfn = (dma_handle >> PAGE_SHIFT);
  45. int k;
  46. if (!WARN_ON(!dev))
  47. pfn += dev->dma_pfn_offset;
  48. for (k = 0; k < (1 << order); k++)
  49. __free_pages(pfn_to_page(pfn + k), 0);
  50. iounmap(vaddr);
  51. }
  52. void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr,
  53. size_t size, enum dma_data_direction dir)
  54. {
  55. void *addr = sh_cacheop_vaddr(phys_to_virt(paddr));
  56. switch (dir) {
  57. case DMA_FROM_DEVICE: /* invalidate only */
  58. __flush_invalidate_region(addr, size);
  59. break;
  60. case DMA_TO_DEVICE: /* writeback only */
  61. __flush_wback_region(addr, size);
  62. break;
  63. case DMA_BIDIRECTIONAL: /* writeback and invalidate */
  64. __flush_purge_region(addr, size);
  65. break;
  66. default:
  67. BUG();
  68. }
  69. }