2 * Copyright (C) 2011 Texas Instruments Incorporated
3 * Author: Mark Salter <msalter@redhat.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 #include <linux/module.h>
10 #include <linux/dma-mapping.h>
12 #include <linux/mm_types.h>
13 #include <linux/scatterlist.h>
15 #include <asm/cacheflush.h>
17 static void c6x_dma_sync(dma_addr_t handle
, size_t size
,
18 enum dma_data_direction dir
)
20 unsigned long paddr
= handle
;
22 BUG_ON(!valid_dma_direction(dir
));
26 L2_cache_block_invalidate(paddr
, paddr
+ size
);
29 L2_cache_block_writeback(paddr
, paddr
+ size
);
31 case DMA_BIDIRECTIONAL
:
32 L2_cache_block_writeback_invalidate(paddr
, paddr
+ size
);
39 dma_addr_t
dma_map_single(struct device
*dev
, void *ptr
, size_t size
,
40 enum dma_data_direction dir
)
42 dma_addr_t addr
= virt_to_phys(ptr
);
44 c6x_dma_sync(addr
, size
, dir
);
46 debug_dma_map_page(dev
, virt_to_page(ptr
),
47 (unsigned long)ptr
& ~PAGE_MASK
, size
,
51 EXPORT_SYMBOL(dma_map_single
);
54 void dma_unmap_single(struct device
*dev
, dma_addr_t handle
,
55 size_t size
, enum dma_data_direction dir
)
57 c6x_dma_sync(handle
, size
, dir
);
59 debug_dma_unmap_page(dev
, handle
, size
, dir
, true);
61 EXPORT_SYMBOL(dma_unmap_single
);
64 int dma_map_sg(struct device
*dev
, struct scatterlist
*sglist
,
65 int nents
, enum dma_data_direction dir
)
67 struct scatterlist
*sg
;
70 for_each_sg(sglist
, sg
, nents
, i
)
71 sg
->dma_address
= dma_map_single(dev
, sg_virt(sg
), sg
->length
,
74 debug_dma_map_sg(dev
, sglist
, nents
, nents
, dir
);
78 EXPORT_SYMBOL(dma_map_sg
);
81 void dma_unmap_sg(struct device
*dev
, struct scatterlist
*sglist
,
82 int nents
, enum dma_data_direction dir
)
84 struct scatterlist
*sg
;
87 for_each_sg(sglist
, sg
, nents
, i
)
88 dma_unmap_single(dev
, sg_dma_address(sg
), sg
->length
, dir
);
90 debug_dma_unmap_sg(dev
, sglist
, nents
, dir
);
92 EXPORT_SYMBOL(dma_unmap_sg
);
94 void dma_sync_single_for_cpu(struct device
*dev
, dma_addr_t handle
,
95 size_t size
, enum dma_data_direction dir
)
97 c6x_dma_sync(handle
, size
, dir
);
99 debug_dma_sync_single_for_cpu(dev
, handle
, size
, dir
);
101 EXPORT_SYMBOL(dma_sync_single_for_cpu
);
104 void dma_sync_single_for_device(struct device
*dev
, dma_addr_t handle
,
105 size_t size
, enum dma_data_direction dir
)
107 c6x_dma_sync(handle
, size
, dir
);
109 debug_dma_sync_single_for_device(dev
, handle
, size
, dir
);
111 EXPORT_SYMBOL(dma_sync_single_for_device
);
114 void dma_sync_sg_for_cpu(struct device
*dev
, struct scatterlist
*sglist
,
115 int nents
, enum dma_data_direction dir
)
117 struct scatterlist
*sg
;
120 for_each_sg(sglist
, sg
, nents
, i
)
121 dma_sync_single_for_cpu(dev
, sg_dma_address(sg
),
124 debug_dma_sync_sg_for_cpu(dev
, sglist
, nents
, dir
);
126 EXPORT_SYMBOL(dma_sync_sg_for_cpu
);
129 void dma_sync_sg_for_device(struct device
*dev
, struct scatterlist
*sglist
,
130 int nents
, enum dma_data_direction dir
)
132 struct scatterlist
*sg
;
135 for_each_sg(sglist
, sg
, nents
, i
)
136 dma_sync_single_for_device(dev
, sg_dma_address(sg
),
139 debug_dma_sync_sg_for_device(dev
, sglist
, nents
, dir
);
141 EXPORT_SYMBOL(dma_sync_sg_for_device
);
144 /* Number of entries preallocated for DMA-API debugging */
145 #define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
147 static int __init
dma_init(void)
149 dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES
);
153 fs_initcall(dma_init
);