dma-mapping: move the dma_coherent flag to struct device
Various architectures support both coherent and non-coherent dma on a per-device basis. Move the dma_noncoherent flag from the mips archdata field to struct device proper to prepare the infrastructure for reuse on other architectures. Signed-off-by: Christoph Hellwig <hch@lst.de> Acked-by: Paul Burton <paul.burton@mips.com> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Родитель
5748e1b35b
Коммит
f3ecc0ff04
|
@ -1106,6 +1106,7 @@ config ARCH_SUPPORTS_UPROBES
|
|||
bool
|
||||
|
||||
config DMA_MAYBE_COHERENT
|
||||
select ARCH_HAS_DMA_COHERENCE_H
|
||||
select DMA_NONCOHERENT
|
||||
bool
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# MIPS headers
|
||||
generic-(CONFIG_GENERIC_CSUM) += checksum.h
|
||||
generic-y += current.h
|
||||
generic-y += device.h
|
||||
generic-y += dma-contiguous.h
|
||||
generic-y += emergency-restart.h
|
||||
generic-y += export.h
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
/*
|
||||
* Arch specific extensions to struct device
|
||||
*
|
||||
* This file is released under the GPLv2
|
||||
*/
|
||||
#ifndef _ASM_MIPS_DEVICE_H
|
||||
#define _ASM_MIPS_DEVICE_H
|
||||
|
||||
struct dev_archdata {
|
||||
#ifdef CONFIG_DMA_PERDEV_COHERENT
|
||||
/* Non-zero if DMA is coherent with CPU caches */
|
||||
bool dma_coherent;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct pdev_archdata {
|
||||
};
|
||||
|
||||
#endif /* _ASM_MIPS_DEVICE_H*/
|
|
@ -20,6 +20,12 @@ enum coherent_io_user_state {
|
|||
#elif defined(CONFIG_DMA_MAYBE_COHERENT)
|
||||
extern enum coherent_io_user_state coherentio;
|
||||
extern int hw_coherentio;
|
||||
|
||||
static inline bool dev_is_dma_coherent(struct device *dev)
|
||||
{
|
||||
return coherentio == IO_COHERENCE_ENABLED ||
|
||||
(coherentio == IO_COHERENCE_DEFAULT && hw_coherentio);
|
||||
}
|
||||
#else
|
||||
#ifdef CONFIG_DMA_NONCOHERENT
|
||||
#define coherentio IO_COHERENCE_DISABLED
|
||||
|
|
|
@ -25,7 +25,7 @@ static inline void arch_setup_dma_ops(struct device *dev, u64 dma_base,
|
|||
bool coherent)
|
||||
{
|
||||
#ifdef CONFIG_DMA_PERDEV_COHERENT
|
||||
dev->archdata.dma_coherent = coherent;
|
||||
dev->dma_coherent = coherent;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -14,26 +14,6 @@
|
|||
#include <asm/dma-coherence.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#ifdef CONFIG_DMA_PERDEV_COHERENT
|
||||
static inline int dev_is_coherent(struct device *dev)
|
||||
{
|
||||
return dev->archdata.dma_coherent;
|
||||
}
|
||||
#else
|
||||
static inline int dev_is_coherent(struct device *dev)
|
||||
{
|
||||
switch (coherentio) {
|
||||
default:
|
||||
case IO_COHERENCE_DEFAULT:
|
||||
return hw_coherentio;
|
||||
case IO_COHERENCE_ENABLED:
|
||||
return 1;
|
||||
case IO_COHERENCE_DISABLED:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_DMA_PERDEV_COHERENT */
|
||||
|
||||
/*
|
||||
* The affected CPUs below in 'cpu_needs_post_dma_flush()' can speculatively
|
||||
* fill random cachelines with stale data at any time, requiring an extra
|
||||
|
@ -49,7 +29,7 @@ static inline int dev_is_coherent(struct device *dev)
|
|||
*/
|
||||
static inline bool cpu_needs_post_dma_flush(struct device *dev)
|
||||
{
|
||||
if (dev_is_coherent(dev))
|
||||
if (dev_is_dma_coherent(dev))
|
||||
return false;
|
||||
|
||||
switch (boot_cpu_type()) {
|
||||
|
@ -76,7 +56,7 @@ void *arch_dma_alloc(struct device *dev, size_t size,
|
|||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
if (!dev_is_coherent(dev) && !(attrs & DMA_ATTR_NON_CONSISTENT)) {
|
||||
if (!dev_is_dma_coherent(dev) && !(attrs & DMA_ATTR_NON_CONSISTENT)) {
|
||||
dma_cache_wback_inv((unsigned long) ret, size);
|
||||
ret = (void *)UNCAC_ADDR(ret);
|
||||
}
|
||||
|
@ -87,7 +67,7 @@ void *arch_dma_alloc(struct device *dev, size_t size,
|
|||
void arch_dma_free(struct device *dev, size_t size, void *cpu_addr,
|
||||
dma_addr_t dma_addr, unsigned long attrs)
|
||||
{
|
||||
if (!(attrs & DMA_ATTR_NON_CONSISTENT) && !dev_is_coherent(dev))
|
||||
if (!(attrs & DMA_ATTR_NON_CONSISTENT) && !dev_is_dma_coherent(dev))
|
||||
cpu_addr = (void *)CAC_ADDR((unsigned long)cpu_addr);
|
||||
dma_direct_free(dev, size, cpu_addr, dma_addr, attrs);
|
||||
}
|
||||
|
@ -103,7 +83,7 @@ int arch_dma_mmap(struct device *dev, struct vm_area_struct *vma,
|
|||
unsigned long pfn;
|
||||
int ret = -ENXIO;
|
||||
|
||||
if (!dev_is_coherent(dev))
|
||||
if (!dev_is_dma_coherent(dev))
|
||||
addr = CAC_ADDR(addr);
|
||||
|
||||
pfn = page_to_pfn(virt_to_page((void *)addr));
|
||||
|
@ -187,7 +167,7 @@ static inline void dma_sync_phys(phys_addr_t paddr, size_t size,
|
|||
void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr,
|
||||
size_t size, enum dma_data_direction dir)
|
||||
{
|
||||
if (!dev_is_coherent(dev))
|
||||
if (!dev_is_dma_coherent(dev))
|
||||
dma_sync_phys(paddr, size, dir);
|
||||
}
|
||||
|
||||
|
@ -203,6 +183,6 @@ void arch_dma_cache_sync(struct device *dev, void *vaddr, size_t size,
|
|||
{
|
||||
BUG_ON(direction == DMA_NONE);
|
||||
|
||||
if (!dev_is_coherent(dev))
|
||||
if (!dev_is_dma_coherent(dev))
|
||||
dma_sync_virt(vaddr, size, direction);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -4,6 +4,22 @@
|
|||
|
||||
#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,
|
||||
|
|
|
@ -13,6 +13,9 @@ config NEED_DMA_MAP_STATE
|
|||
config ARCH_DMA_ADDR_T_64BIT
|
||||
def_bool 64BIT || PHYS_ADDR_T_64BIT
|
||||
|
||||
config ARCH_HAS_DMA_COHERENCE_H
|
||||
bool
|
||||
|
||||
config HAVE_GENERIC_DMA_COHERENT
|
||||
bool
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче