Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 48e1fd5a authored by David Daney's avatar David Daney Committed by Ralf Baechle
Browse files

MIPS: Convert DMA to use dma-mapping-common.h



Use asm-generic/dma-mapping-common.h to handle all DMA mapping operations
and establish a default get_dma_ops() that forwards all operations to the
existing code.

Augment dev_archdata to carry a pointer to the struct dma_map_ops, allowing
DMA operations to be overridden on a per device basis.  Currently this is
never filled in, so the default dma_map_ops are used.  A follow-on patch
sets this for Octeon PCI devices.

Also initialize the dma_debug system as it is now used if it is configured.

Includes fixes by Kevin Cernekee <cernekee@gmail.com>.

Signed-off-by: default avatarDavid Daney <ddaney@caviumnetworks.com>
Patchwork: http://patchwork.linux-mips.org/patch/1637/
Patchwork: http://patchwork.linux-mips.org/patch/1678/


Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 43e4f7ae
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -14,6 +14,8 @@ config MIPS
	select HAVE_KRETPROBES
	select HAVE_KRETPROBES
	select RTC_LIB if !MACH_LOONGSON
	select RTC_LIB if !MACH_LOONGSON
	select GENERIC_ATOMIC64 if !64BIT
	select GENERIC_ATOMIC64 if !64BIT
	select HAVE_DMA_ATTRS
	select HAVE_DMA_API_DEBUG


menu "Machine selection"
menu "Machine selection"


+14 −1
Original line number Original line Diff line number Diff line
@@ -3,4 +3,17 @@
 *
 *
 * This file is released under the GPLv2
 * This file is released under the GPLv2
 */
 */
#include <asm-generic/device.h>
#ifndef _ASM_MIPS_DEVICE_H
#define _ASM_MIPS_DEVICE_H

struct dma_map_ops;

struct dev_archdata {
	/* DMA operations on that device */
	struct dma_map_ops *dma_ops;
};

struct pdev_archdata {
};

#endif /* _ASM_MIPS_DEVICE_H*/
+58 −38
Original line number Original line Diff line number Diff line
@@ -5,51 +5,41 @@
#include <asm/cache.h>
#include <asm/cache.h>
#include <asm-generic/dma-coherent.h>
#include <asm-generic/dma-coherent.h>


void *dma_alloc_noncoherent(struct device *dev, size_t size,
#include <dma-coherence.h>
			   dma_addr_t *dma_handle, gfp_t flag);


void dma_free_noncoherent(struct device *dev, size_t size,
extern struct dma_map_ops *mips_dma_map_ops;
			 void *vaddr, dma_addr_t dma_handle);


void *dma_alloc_coherent(struct device *dev, size_t size,
static inline struct dma_map_ops *get_dma_ops(struct device *dev)
			   dma_addr_t *dma_handle, gfp_t flag);
{
	if (dev && dev->archdata.dma_ops)
		return dev->archdata.dma_ops;
	else
		return mips_dma_map_ops;
}


void dma_free_coherent(struct device *dev, size_t size,
static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
			 void *vaddr, dma_addr_t dma_handle);
{
	if (!dev->dma_mask)
		return 0;


extern dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
	return addr + size <= *dev->dma_mask;
	enum dma_data_direction direction);
}
extern void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,

	size_t size, enum dma_data_direction direction);
static inline void dma_mark_clean(void *addr, size_t size) {}
extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,

	enum dma_data_direction direction);
#include <asm-generic/dma-mapping-common.h>
extern dma_addr_t dma_map_page(struct device *dev, struct page *page,
	unsigned long offset, size_t size, enum dma_data_direction direction);


static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
static inline int dma_supported(struct device *dev, u64 mask)
	size_t size, enum dma_data_direction direction)
{
{
	dma_unmap_single(dev, dma_address, size, direction);
	struct dma_map_ops *ops = get_dma_ops(dev);
	return ops->dma_supported(dev, mask);
}
}


extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
static inline int dma_mapping_error(struct device *dev, u64 mask)
	int nhwentries, enum dma_data_direction direction);
{
extern void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
	struct dma_map_ops *ops = get_dma_ops(dev);
	size_t size, enum dma_data_direction direction);
	return ops->mapping_error(dev, mask);
extern void dma_sync_single_for_device(struct device *dev,
}
	dma_addr_t dma_handle, size_t size, enum dma_data_direction direction);
extern 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);
extern 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);
extern void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
	int nelems, enum dma_data_direction direction);
extern void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
	int nelems, enum dma_data_direction direction);
extern int dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
extern int dma_supported(struct device *dev, u64 mask);


static inline int
static inline int
dma_set_mask(struct device *dev, u64 mask)
dma_set_mask(struct device *dev, u64 mask)
@@ -65,4 +55,34 @@ dma_set_mask(struct device *dev, u64 mask)
extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
	       enum dma_data_direction direction);
	       enum dma_data_direction direction);


static inline void *dma_alloc_coherent(struct device *dev, size_t size,
				       dma_addr_t *dma_handle, gfp_t gfp)
{
	void *ret;
	struct dma_map_ops *ops = get_dma_ops(dev);

	ret = ops->alloc_coherent(dev, size, dma_handle, gfp);

	debug_dma_alloc_coherent(dev, size, *dma_handle, ret);

	return ret;
}

static inline void dma_free_coherent(struct device *dev, size_t size,
				     void *vaddr, dma_addr_t dma_handle)
{
	struct dma_map_ops *ops = get_dma_ops(dev);

	ops->free_coherent(dev, size, vaddr, dma_handle);

	debug_dma_free_coherent(dev, size, vaddr, dma_handle);
}


void *dma_alloc_noncoherent(struct device *dev, size_t size,
			   dma_addr_t *dma_handle, gfp_t flag);

void dma_free_noncoherent(struct device *dev, size_t size,
			 void *vaddr, dma_addr_t dma_handle);

#endif /* _ASM_DMA_MAPPING_H */
#endif /* _ASM_DMA_MAPPING_H */
+1 −1
Original line number Original line Diff line number Diff line
@@ -27,7 +27,7 @@ static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
	struct page *page)
	struct page *page)
{
{
	return octeon_map_dma_mem(dev, page_address(page), PAGE_SIZE);
	BUG();
}
}


static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
+2 −1
Original line number Original line Diff line number Diff line
@@ -26,7 +26,8 @@ static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
	return pa;
	return pa;
}
}


static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
	struct page *page)
{
{
	dma_addr_t pa = dev_to_baddr(dev, page_to_phys(page));
	dma_addr_t pa = dev_to_baddr(dev, page_to_phys(page));


Loading