Merge tag 'v4.2-rc1' into patchwork
[linux-2.6-block.git] / arch / microblaze / include / asm / dma-mapping.h
CommitLineData
ccfe27d7
MS
1/*
2 * Implements the generic device dma API for microblaze and the pci
3 *
4 * Copyright (C) 2009-2010 Michal Simek <monstr@monstr.eu>
5 * Copyright (C) 2009-2010 PetaLogix
6 *
7 * This file is subject to the terms and conditions of the GNU General
8 * Public License. See the file COPYING in the main directory of this
9 * archive for more details.
10 *
11 * This file is base on powerpc and x86 dma-mapping.h versions
12 * Copyright (C) 2004 IBM
13 */
14
15#ifndef _ASM_MICROBLAZE_DMA_MAPPING_H
16#define _ASM_MICROBLAZE_DMA_MAPPING_H
17
18/*
395cf969 19 * See Documentation/DMA-API-HOWTO.txt and
ccfe27d7
MS
20 * Documentation/DMA-API.txt for documentation.
21 */
22
23#include <linux/types.h>
24#include <linux/cache.h>
25#include <linux/mm.h>
26#include <linux/scatterlist.h>
27#include <linux/dma-debug.h>
28#include <linux/dma-attrs.h>
29#include <asm/io.h>
30#include <asm-generic/dma-coherent.h>
cf560c18 31#include <asm/cacheflush.h>
ccfe27d7
MS
32
33#define DMA_ERROR_CODE (~(dma_addr_t)0x0)
34
35#define __dma_alloc_coherent(dev, gfp, size, handle) NULL
36#define __dma_free_coherent(size, addr) ((void)0)
ccfe27d7 37
ccfe27d7
MS
38/*
39 * Available generic sets of operations
40 */
41extern struct dma_map_ops dma_direct_ops;
42
43static inline struct dma_map_ops *get_dma_ops(struct device *dev)
44{
3b3b6853 45 return &dma_direct_ops;
ccfe27d7
MS
46}
47
ccfe27d7
MS
48static inline int dma_supported(struct device *dev, u64 mask)
49{
50 struct dma_map_ops *ops = get_dma_ops(dev);
51
52 if (unlikely(!ops))
53 return 0;
54 if (!ops->dma_supported)
55 return 1;
56 return ops->dma_supported(dev, mask);
57}
58
ccfe27d7
MS
59static inline int dma_set_mask(struct device *dev, u64 dma_mask)
60{
61 struct dma_map_ops *ops = get_dma_ops(dev);
62
63 if (unlikely(ops == NULL))
64 return -EIO;
65 if (ops->set_dma_mask)
66 return ops->set_dma_mask(dev, dma_mask);
67 if (!dev->dma_mask || !dma_supported(dev, dma_mask))
68 return -EIO;
69 *dev->dma_mask = dma_mask;
70 return 0;
71}
72
73#include <asm-generic/dma-mapping-common.h>
74
cf560c18
EB
75static inline void __dma_sync(unsigned long paddr,
76 size_t size, enum dma_data_direction direction)
77{
78 switch (direction) {
79 case DMA_TO_DEVICE:
80 case DMA_BIDIRECTIONAL:
81 flush_dcache_range(paddr, paddr + size);
82 break;
83 case DMA_FROM_DEVICE:
84 invalidate_dcache_range(paddr, paddr + size);
85 break;
86 default:
87 BUG();
88 }
89}
90
ccfe27d7
MS
91static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
92{
93 struct dma_map_ops *ops = get_dma_ops(dev);
e728fa18
SK
94
95 debug_dma_mapping_error(dev, dma_addr);
ccfe27d7
MS
96 if (ops->mapping_error)
97 return ops->mapping_error(dev, dma_addr);
98
99 return (dma_addr == DMA_ERROR_CODE);
100}
101
102#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
103#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
ccfe27d7 104
988624ec
AP
105#define dma_alloc_coherent(d, s, h, f) dma_alloc_attrs(d, s, h, f, NULL)
106
107static inline void *dma_alloc_attrs(struct device *dev, size_t size,
108 dma_addr_t *dma_handle, gfp_t flag,
109 struct dma_attrs *attrs)
ccfe27d7
MS
110{
111 struct dma_map_ops *ops = get_dma_ops(dev);
112 void *memory;
113
114 BUG_ON(!ops);
115
988624ec 116 memory = ops->alloc(dev, size, dma_handle, flag, attrs);
ccfe27d7
MS
117
118 debug_dma_alloc_coherent(dev, size, *dma_handle, memory);
119 return memory;
120}
121
988624ec
AP
122#define dma_free_coherent(d,s,c,h) dma_free_attrs(d, s, c, h, NULL)
123
124static inline void dma_free_attrs(struct device *dev, size_t size,
125 void *cpu_addr, dma_addr_t dma_handle,
126 struct dma_attrs *attrs)
ccfe27d7
MS
127{
128 struct dma_map_ops *ops = get_dma_ops(dev);
129
130 BUG_ON(!ops);
131 debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
988624ec 132 ops->free(dev, size, cpu_addr, dma_handle, attrs);
ccfe27d7
MS
133}
134
ccfe27d7
MS
135static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
136 enum dma_data_direction direction)
137{
138 BUG_ON(direction == DMA_NONE);
cf560c18 139 __dma_sync(virt_to_phys(vaddr), size, (int)direction);
ccfe27d7
MS
140}
141
142#endif /* _ASM_MICROBLAZE_DMA_MAPPING_H */