Merge tag 'dma-mapping-4.20' of git://git.infradead.org/users/hch/dma-mapping
Pull dma mapping updates from Christoph Hellwig: "First batch of dma-mapping changes for 4.20. There will be a second PR as some big changes were only applied just before the end of the merge window, and I want to give them a few more days in linux-next. Summary: - mostly more consolidation of the direct mapping code, including converting over hexagon, and merging the coherent and non-coherent code into a single dma_map_ops instance (me) - cleanups for the dma_configure/dma_unconfigure callchains (me) - better handling of dma_masks in odd setups (me, Alexander Duyck) - better debugging of passing vmalloc address to the DMA API (Stephen Boyd) - CMA command line parsing fix (He Zhe)" * tag 'dma-mapping-4.20' of git://git.infradead.org/users/hch/dma-mapping: (27 commits) dma-direct: respect DMA_ATTR_NO_WARN dma-mapping: translate __GFP_NOFAIL to DMA_ATTR_NO_WARN dma-direct: document the zone selection logic dma-debug: Check for drivers mapping invalid addresses in dma_map_single() dma-direct: fix return value of dma_direct_supported dma-mapping: move dma_default_get_required_mask under ifdef dma-direct: always allow dma mask <= physiscal memory size dma-direct: implement complete bus_dma_mask handling dma-direct: refine dma_direct_alloc zone selection dma-direct: add an explicit dma_direct_get_required_mask dma-mapping: make the get_required_mask method available unconditionally unicore32: remove swiotlb support Revert "dma-mapping: clear dev->dma_ops in arch_teardown_dma_ops" dma-mapping: support non-coherent devices in dma_common_get_sgtable dma-mapping: consolidate the dma mmap implementations dma-mapping: merge direct and noncoherent ops dma-mapping: move the dma_coherent flag to struct device MIPS: don't select DMA_MAYBE_COHERENT from DMA_PERDEV_COHERENT dma-mapping: add the missing ARCH_HAS_SYNC_DMA_FOR_CPU_ALL declaration dma-mapping: fix panic caused by passing empty cma command line argument ...
This commit is contained in:
@@ -831,8 +831,6 @@ static inline int acpi_dma_configure(struct device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void acpi_dma_deconfigure(struct device *dev) { }
|
||||
|
||||
#define ACPI_PTR(_ptr) (NULL)
|
||||
|
||||
static inline void acpi_device_set_enumerated(struct acpi_device *adev)
|
||||
|
@@ -927,6 +927,8 @@ struct dev_links_info {
|
||||
* @offline: Set after successful invocation of bus type's .offline().
|
||||
* @of_node_reused: Set if the device-tree node is shared with an ancestor
|
||||
* device.
|
||||
* @dma_coherent: this particular device is dma coherent, even if the
|
||||
* architecture supports non-coherent devices.
|
||||
*
|
||||
* At the lowest level, every device in a Linux system is represented by an
|
||||
* instance of struct device. The device structure contains the information
|
||||
@@ -1016,6 +1018,11 @@ struct device {
|
||||
bool offline_disabled:1;
|
||||
bool offline:1;
|
||||
bool of_node_reused:1;
|
||||
#if defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE) || \
|
||||
defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU) || \
|
||||
defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL)
|
||||
bool dma_coherent:1;
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline struct device *kobj_to_dev(struct kobject *kobj)
|
||||
|
@@ -32,6 +32,9 @@ extern void dma_debug_add_bus(struct bus_type *bus);
|
||||
|
||||
extern int dma_debug_resize_entries(u32 num_entries);
|
||||
|
||||
extern void debug_dma_map_single(struct device *dev, const void *addr,
|
||||
unsigned long len);
|
||||
|
||||
extern void debug_dma_map_page(struct device *dev, struct page *page,
|
||||
size_t offset, size_t size,
|
||||
int direction, dma_addr_t dma_addr,
|
||||
@@ -103,6 +106,11 @@ static inline int dma_debug_resize_entries(u32 num_entries)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void debug_dma_map_single(struct device *dev, const void *addr,
|
||||
unsigned long len)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void debug_dma_map_page(struct device *dev, struct page *page,
|
||||
size_t offset, size_t size,
|
||||
int direction, dma_addr_t dma_addr,
|
||||
|
@@ -27,7 +27,8 @@ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
|
||||
if (!dev->dma_mask)
|
||||
return false;
|
||||
|
||||
return addr + size - 1 <= *dev->dma_mask;
|
||||
return addr + size - 1 <=
|
||||
min_not_zero(*dev->dma_mask, dev->bus_dma_mask);
|
||||
}
|
||||
#endif /* !CONFIG_ARCH_HAS_PHYS_TO_DMA */
|
||||
|
||||
@@ -55,10 +56,15 @@ static inline void dma_mark_clean(void *addr, size_t size)
|
||||
}
|
||||
#endif /* CONFIG_ARCH_HAS_DMA_MARK_CLEAN */
|
||||
|
||||
u64 dma_direct_get_required_mask(struct device *dev);
|
||||
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);
|
||||
void *dma_direct_alloc_pages(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs);
|
||||
void dma_direct_free_pages(struct device *dev, size_t size, void *cpu_addr,
|
||||
dma_addr_t dma_addr, unsigned long attrs);
|
||||
dma_addr_t dma_direct_map_page(struct device *dev, struct page *page,
|
||||
unsigned long offset, size_t size, enum dma_data_direction dir,
|
||||
unsigned long attrs);
|
||||
|
@@ -130,13 +130,10 @@ struct dma_map_ops {
|
||||
enum dma_data_direction direction);
|
||||
int (*mapping_error)(struct device *dev, dma_addr_t dma_addr);
|
||||
int (*dma_supported)(struct device *dev, u64 mask);
|
||||
#ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK
|
||||
u64 (*get_required_mask)(struct device *dev);
|
||||
#endif
|
||||
};
|
||||
|
||||
extern const struct dma_map_ops dma_direct_ops;
|
||||
extern const struct dma_map_ops dma_noncoherent_ops;
|
||||
extern const struct dma_map_ops dma_virt_ops;
|
||||
|
||||
#define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
|
||||
@@ -232,6 +229,7 @@ static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
|
||||
dma_addr_t addr;
|
||||
|
||||
BUG_ON(!valid_dma_direction(dir));
|
||||
debug_dma_map_single(dev, ptr, size);
|
||||
addr = ops->map_page(dev, virt_to_page(ptr),
|
||||
offset_in_page(ptr), size,
|
||||
dir, attrs);
|
||||
@@ -445,7 +443,8 @@ dma_cache_sync(struct device *dev, void *vaddr, size_t size,
|
||||
}
|
||||
|
||||
extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
|
||||
void *cpu_addr, dma_addr_t dma_addr, size_t size);
|
||||
void *cpu_addr, dma_addr_t dma_addr, size_t size,
|
||||
unsigned long attrs);
|
||||
|
||||
void *dma_common_contiguous_remap(struct page *page, size_t size,
|
||||
unsigned long vm_flags,
|
||||
@@ -477,14 +476,14 @@ dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, void *cpu_addr,
|
||||
BUG_ON(!ops);
|
||||
if (ops->mmap)
|
||||
return ops->mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
|
||||
return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size);
|
||||
return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
|
||||
}
|
||||
|
||||
#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, 0)
|
||||
|
||||
int
|
||||
dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
|
||||
void *cpu_addr, dma_addr_t dma_addr, size_t size);
|
||||
dma_common_get_sgtable(struct device *dev, struct sg_table *sgt, void *cpu_addr,
|
||||
dma_addr_t dma_addr, size_t size, unsigned long attrs);
|
||||
|
||||
static inline int
|
||||
dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
|
||||
@@ -496,7 +495,8 @@ dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
|
||||
if (ops->get_sgtable)
|
||||
return ops->get_sgtable(dev, sgt, cpu_addr, dma_addr, size,
|
||||
attrs);
|
||||
return dma_common_get_sgtable(dev, sgt, cpu_addr, dma_addr, size);
|
||||
return dma_common_get_sgtable(dev, sgt, cpu_addr, dma_addr, size,
|
||||
attrs);
|
||||
}
|
||||
|
||||
#define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, 0)
|
||||
@@ -558,9 +558,11 @@ static inline void dma_free_attrs(struct device *dev, size_t size,
|
||||
}
|
||||
|
||||
static inline void *dma_alloc_coherent(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_handle, gfp_t flag)
|
||||
dma_addr_t *dma_handle, gfp_t gfp)
|
||||
{
|
||||
return dma_alloc_attrs(dev, size, dma_handle, flag, 0);
|
||||
|
||||
return dma_alloc_attrs(dev, size, dma_handle, gfp,
|
||||
(gfp & __GFP_NOWARN) ? DMA_ATTR_NO_WARN : 0);
|
||||
}
|
||||
|
||||
static inline void dma_free_coherent(struct device *dev, size_t size,
|
||||
@@ -753,18 +755,6 @@ dma_mark_declared_memory_occupied(struct device *dev,
|
||||
}
|
||||
#endif /* CONFIG_HAVE_GENERIC_DMA_COHERENT */
|
||||
|
||||
#ifdef CONFIG_HAS_DMA
|
||||
int dma_configure(struct device *dev);
|
||||
void dma_deconfigure(struct device *dev);
|
||||
#else
|
||||
static inline int dma_configure(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void dma_deconfigure(struct device *dev) {}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Managed DMA API
|
||||
*/
|
||||
@@ -806,8 +796,12 @@ static inline void dmam_release_declared_memory(struct device *dev)
|
||||
static inline void *dma_alloc_wc(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_addr, gfp_t gfp)
|
||||
{
|
||||
return dma_alloc_attrs(dev, size, dma_addr, gfp,
|
||||
DMA_ATTR_WRITE_COMBINE);
|
||||
unsigned long attrs = DMA_ATTR_NO_WARN;
|
||||
|
||||
if (gfp & __GFP_NOWARN)
|
||||
attrs |= DMA_ATTR_NO_WARN;
|
||||
|
||||
return dma_alloc_attrs(dev, size, dma_addr, gfp, attrs);
|
||||
}
|
||||
#ifndef dma_alloc_writecombine
|
||||
#define dma_alloc_writecombine dma_alloc_wc
|
||||
|
@@ -4,18 +4,35 @@
|
||||
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
#ifdef CONFIG_ARCH_HAS_DMA_COHERENCE_H
|
||||
#include <asm/dma-coherence.h>
|
||||
#elif defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE) || \
|
||||
defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU) || \
|
||||
defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL)
|
||||
static inline bool dev_is_dma_coherent(struct device *dev)
|
||||
{
|
||||
return dev->dma_coherent;
|
||||
}
|
||||
#else
|
||||
static inline bool dev_is_dma_coherent(struct device *dev)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif /* CONFIG_ARCH_HAS_DMA_COHERENCE_H */
|
||||
|
||||
void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
|
||||
gfp_t gfp, unsigned long attrs);
|
||||
void arch_dma_free(struct device *dev, size_t size, void *cpu_addr,
|
||||
dma_addr_t dma_addr, unsigned long attrs);
|
||||
long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr,
|
||||
dma_addr_t dma_addr);
|
||||
|
||||
#ifdef CONFIG_DMA_NONCOHERENT_MMAP
|
||||
int arch_dma_mmap(struct device *dev, struct vm_area_struct *vma,
|
||||
void *cpu_addr, dma_addr_t dma_addr, size_t size,
|
||||
#ifdef CONFIG_ARCH_HAS_DMA_MMAP_PGPROT
|
||||
pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
|
||||
unsigned long attrs);
|
||||
#else
|
||||
#define arch_dma_mmap NULL
|
||||
#endif /* CONFIG_DMA_NONCOHERENT_MMAP */
|
||||
# define arch_dma_mmap_pgprot(dev, prot, attrs) pgprot_noncached(prot)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DMA_NONCOHERENT_CACHE_SYNC
|
||||
void arch_dma_cache_sync(struct device *dev, void *vaddr, size_t size,
|
||||
|
@@ -58,7 +58,6 @@ static inline struct device_node *of_cpu_device_node_get(int cpu)
|
||||
int of_dma_configure(struct device *dev,
|
||||
struct device_node *np,
|
||||
bool force_dma);
|
||||
void of_dma_deconfigure(struct device *dev);
|
||||
#else /* CONFIG_OF */
|
||||
|
||||
static inline int of_driver_match_device(struct device *dev,
|
||||
@@ -113,8 +112,6 @@ static inline int of_dma_configure(struct device *dev,
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void of_dma_deconfigure(struct device *dev)
|
||||
{}
|
||||
#endif /* CONFIG_OF */
|
||||
|
||||
#endif /* _LINUX_OF_DEVICE_H */
|
||||
|
Reference in New Issue
Block a user