Modified: trunk/arch/blackfin/include/asm/dma-mapping.h (7860 => 7861)
--- trunk/arch/blackfin/include/asm/dma-mapping.h 2009-11-24 06:11:14 UTC (rev 7860)
+++ trunk/arch/blackfin/include/asm/dma-mapping.h 2009-11-24 10:20:41 UTC (rev 7861)
@@ -20,7 +20,21 @@
*/
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+#define dma_supported(d, m) (1)
+#define dma_get_cache_alignment() (32)
+#define dma_is_consistent(d, h) (1)
+static inline int
+dma_set_mask(struct device *dev, u64 dma_mask)
+{
+ if (!dev->dma_mask || !dma_supported(dev, dma_mask))
+ return -EIO;
+
+ *dev->dma_mask = dma_mask;
+
+ return 0;
+}
+
static inline
int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
{
@@ -90,28 +104,38 @@
extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
int nhwentries, enum dma_data_direction direction);
-static inline void dma_sync_single_for_cpu(struct device *dev,
+extern void dma_sync_single_range_for_cpu(struct device *dev,
+ dma_addr_t handle, unsigned long offset, size_t size,
+ enum dma_data_direction dir);
+
+extern void dma_sync_single_range_for_device(struct device *dev,
+ dma_addr_t handle, unsigned long offset, size_t size,
+ enum dma_data_direction dir);
+
+static inline void
+dma_sync_single_for_cpu(struct device *dev,
dma_addr_t handle, size_t size,
enum dma_data_direction dir)
{
+ dma_sync_single_range_for_cpu(dev, handle, 0, size, dir);
}
-static inline void dma_sync_single_for_device(struct device *dev,
+static inline void
+dma_sync_single_for_device(struct device *dev,
dma_addr_t handle, size_t size,
enum dma_data_direction dir)
{
+ dma_sync_single_range_for_device(dev, handle, 0, size, dir);
}
-static inline void dma_sync_sg_for_cpu(struct device *dev,
+extern void dma_sync_sg_for_cpu(struct device *dev,
struct scatterlist *sg,
- int nents, enum dma_data_direction dir)
-{
-}
+ int nents, enum dma_data_direction dir);
-static inline void dma_sync_sg_for_device(struct device *dev,
+extern void dma_sync_sg_for_device(struct device *dev,
struct scatterlist *sg,
- int nents, enum dma_data_direction dir)
-{
-}
+ int nents, enum dma_data_direction dir);
+extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
+ enum dma_data_direction direction);
#endif /* _BLACKFIN_DMA_MAPPING_H */
Modified: trunk/arch/blackfin/kernel/dma-mapping.c (7860 => 7861)
--- trunk/arch/blackfin/kernel/dma-mapping.c 2009-11-24 06:11:14 UTC (rev 7860)
+++ trunk/arch/blackfin/kernel/dma-mapping.c 2009-11-24 10:20:41 UTC (rev 7861)
@@ -119,59 +119,44 @@
/*
* Streaming DMA mappings
*/
-
-dma_addr_t
-dma_map_single(struct device *dev, void *ptr, size_t size,
+static inline void __dma_sync(dma_addr_t addr, size_t size,
enum dma_data_direction direction)
{
switch (direction) {
case DMA_NONE:
BUG();
case DMA_TO_DEVICE: /* writeback only */
- flush_dcache_range((dma_addr_t)ptr,
- (dma_addr_t)ptr + size);
+ flush_dcache_range(addr, addr + size);
break;
case DMA_FROM_DEVICE: /* invalidate only */
case DMA_BIDIRECTIONAL: /* flush and invalidate */
/*
* for blackfin, invalidating cache will flush cache too
*/
- invalidate_dcache_range((dma_addr_t)ptr,
- (dma_addr_t)ptr + size);
+ invalidate_dcache_range(addr, addr + size);
break;
}
+}
+dma_addr_t
+dma_map_single(struct device *dev, void *ptr, size_t size,
+ enum dma_data_direction direction)
+{
+ __dma_sync((dma_addr_t)ptr, size, direction);
+
return (dma_addr_t) ptr;
}
EXPORT_SYMBOL(dma_map_single);
int
dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
- enum dma_data_direction direction)
+ enum dma_data_direction direction)
{
int i;
- switch (direction) {
- case DMA_NONE:
- BUG();
- case DMA_TO_DEVICE: /* writeback only */
- for (i = 0; i < nents; i++, sg++) {
- sg->dma_address = (dma_addr_t) sg_virt(sg);
- flush_dcache_range(sg->dma_address,
- sg->dma_address + sg_dma_len(sg));
- }
- break;
- case DMA_FROM_DEVICE: /* invalidate only */
- case DMA_BIDIRECTIONAL: /* writeback and invalidate */
- /*
- * for blackfin, invalidating cache will flush cache too
- */
- for (i = 0; i < nents; i++, sg++) {
- sg->dma_address = (dma_addr_t) sg_virt(sg);
- invalidate_dcache_range(sg->dma_address,
- sg->dma_address + sg_dma_len(sg));
- }
- break;
+ for (i = 0; i < nents; i++, sg++) {
+ sg->dma_address = (dma_addr_t) sg_virt(sg);
+ __dma_sync(sg_dma_address(sg), sg_dma_len(sg), direction);
}
return nents;
@@ -191,3 +176,49 @@
BUG_ON(!valid_dma_direction(direction));
}
EXPORT_SYMBOL(dma_unmap_sg);
+
+/*
+ * transfer ownership of the mapped streaming DMA buffer to the CPU
+ */
+void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
+ unsigned long offset, size_t size, enum dma_data_direction direction)
+{
+ BUG_ON(!valid_dma_direction(direction));
+}
+EXPORT_SYMBOL(dma_sync_single_range_for_cpu);
+
+void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
+ enum dma_data_direction direction)
+{
+ BUG_ON(!valid_dma_direction(direction));
+}
+EXPORT_SYMBOL(dma_sync_sg_for_cpu);
+
+/*
+ * allow the device to access the mapped streaming DMA buffer again
+ */
+void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
+ unsigned long offset, size_t size, enum dma_data_direction direction)
+{
+ __dma_sync(dma_handle + offset, size, direction);
+}
+EXPORT_SYMBOL(dma_sync_single_range_for_device);
+
+void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
+ enum dma_data_direction direction)
+{
+ int i;
+
+ for (i = 0; i < nelems; i++, sg++) {
+ sg->dma_address = (dma_addr_t) sg_virt(sg);
+ __dma_sync(sg_dma_address(sg), sg_dma_len(sg), direction);
+ }
+}
+EXPORT_SYMBOL(dma_sync_sg_for_device);
+
+void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
+ enum dma_data_direction direction)
+{
+ __dma_sync((dma_addr_t)vaddr, size, direction);
+}
+EXPORT_SYMBOL(dma_cache_sync);