dma-mapping: add a new dma_alloc_pages API
This API is the equivalent of alloc_pages, except that the returned memory is guaranteed to be DMA addressable by the passed in device. The implementation will also be used to provide a more sensible replacement for DMA_ATTR_NON_CONSISTENT flag. Additionally dma_alloc_noncoherent is switched over to use dma_alloc_pages as its backend. Signed-off-by: Christoph Hellwig <hch@lst.de> Acked-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de> (MIPS part)
This commit is contained in:
parent
5a84292271
commit
efa70f2fdc
23 changed files with 206 additions and 37 deletions
|
|
@ -115,6 +115,11 @@ void *dma_direct_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
|
|||
gfp_t gfp, unsigned long attrs);
|
||||
void dma_direct_free(struct device *dev, size_t size, void *cpu_addr,
|
||||
dma_addr_t dma_addr, unsigned long attrs);
|
||||
struct page *dma_direct_alloc_pages(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_handle, enum dma_data_direction dir, gfp_t gfp);
|
||||
void dma_direct_free_pages(struct device *dev, size_t size,
|
||||
struct page *page, dma_addr_t dma_addr,
|
||||
enum dma_data_direction dir);
|
||||
int dma_direct_get_sgtable(struct device *dev, struct sg_table *sgt,
|
||||
void *cpu_addr, dma_addr_t dma_addr, size_t size,
|
||||
unsigned long attrs);
|
||||
|
|
|
|||
|
|
@ -27,11 +27,6 @@
|
|||
* buffered to improve performance.
|
||||
*/
|
||||
#define DMA_ATTR_WRITE_COMBINE (1UL << 2)
|
||||
/*
|
||||
* DMA_ATTR_NON_CONSISTENT: Lets the platform to choose to return either
|
||||
* consistent or non-consistent memory as it sees fit.
|
||||
*/
|
||||
#define DMA_ATTR_NON_CONSISTENT (1UL << 3)
|
||||
/*
|
||||
* DMA_ATTR_NO_KERNEL_MAPPING: Lets the platform to avoid creating a kernel
|
||||
* virtual mapping for the allocated buffer.
|
||||
|
|
@ -74,6 +69,11 @@ struct dma_map_ops {
|
|||
void (*free)(struct device *dev, size_t size,
|
||||
void *vaddr, dma_addr_t dma_handle,
|
||||
unsigned long attrs);
|
||||
struct page *(*alloc_pages)(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_handle, enum dma_data_direction dir,
|
||||
gfp_t gfp);
|
||||
void (*free_pages)(struct device *dev, size_t size, struct page *vaddr,
|
||||
dma_addr_t dma_handle, enum dma_data_direction dir);
|
||||
int (*mmap)(struct device *, struct vm_area_struct *,
|
||||
void *, dma_addr_t, size_t,
|
||||
unsigned long attrs);
|
||||
|
|
@ -376,17 +376,14 @@ static inline unsigned long dma_get_merge_boundary(struct device *dev)
|
|||
}
|
||||
#endif /* CONFIG_HAS_DMA */
|
||||
|
||||
static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_handle, enum dma_data_direction dir, gfp_t gfp)
|
||||
{
|
||||
return dma_alloc_attrs(dev, size, dma_handle, gfp,
|
||||
DMA_ATTR_NON_CONSISTENT);
|
||||
}
|
||||
static inline void dma_free_noncoherent(struct device *dev, size_t size,
|
||||
void *vaddr, dma_addr_t dma_handle, enum dma_data_direction dir)
|
||||
{
|
||||
dma_free_attrs(dev, size, vaddr, dma_handle, DMA_ATTR_NON_CONSISTENT);
|
||||
}
|
||||
struct page *dma_alloc_pages(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_handle, enum dma_data_direction dir, gfp_t gfp);
|
||||
void dma_free_pages(struct device *dev, size_t size, struct page *page,
|
||||
dma_addr_t dma_handle, enum dma_data_direction dir);
|
||||
void *dma_alloc_noncoherent(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_handle, enum dma_data_direction dir, gfp_t gfp);
|
||||
void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
|
||||
dma_addr_t dma_handle, enum dma_data_direction dir);
|
||||
|
||||
static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
|
||||
size_t size, enum dma_data_direction dir, unsigned long attrs)
|
||||
|
|
@ -512,7 +509,10 @@ static inline void dma_sync_sgtable_for_device(struct device *dev,
|
|||
extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
|
||||
void *cpu_addr, dma_addr_t dma_addr, size_t size,
|
||||
unsigned long attrs);
|
||||
|
||||
struct page *dma_common_alloc_pages(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_handle, enum dma_data_direction dir, gfp_t gfp);
|
||||
void dma_common_free_pages(struct device *dev, size_t size, struct page *vaddr,
|
||||
dma_addr_t dma_handle, enum dma_data_direction dir);
|
||||
struct page **dma_common_find_pages(void *cpu_addr);
|
||||
void *dma_common_contiguous_remap(struct page *page, size_t size,
|
||||
pgprot_t prot, const void *caller);
|
||||
|
|
|
|||
|
|
@ -31,9 +31,6 @@ static __always_inline bool dma_alloc_need_uncached(struct device *dev,
|
|||
return false;
|
||||
if (attrs & DMA_ATTR_NO_KERNEL_MAPPING)
|
||||
return false;
|
||||
if (IS_ENABLED(CONFIG_DMA_NONCOHERENT_CACHE_SYNC) &&
|
||||
(attrs & DMA_ATTR_NON_CONSISTENT))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue