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

Commit 738ef42e authored by Becky Bruce's avatar Becky Bruce Committed by Benjamin Herrenschmidt
Browse files

powerpc: Change archdata dma_data to a union



Sometimes this is used to hold a simple offset, and sometimes
it is used to hold a pointer.  This patch changes it to a union containing
void * and dma_addr_t.  get/set accessors are also provided, because it was
getting a bit ugly to get to the actual data.

Signed-off-by: default avatarBecky Bruce <beckyb@kernel.crashing.org>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 1cebd7a0
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -15,7 +15,16 @@ struct dev_archdata {

	/* DMA operations on that device */
	struct dma_map_ops	*dma_ops;
	void			*dma_data;

	/*
	 * When an iommu is in use, dma_data is used as a ptr to the base of the
	 * iommu_table.  Otherwise, it is a simple numerical offset.
	 */
	union {
		dma_addr_t	dma_offset;
		void		*iommu_table_base;
	} dma_data;

#ifdef CONFIG_SWIOTLB
	dma_addr_t		max_direct_dma_addr;
#endif
+8 −2
Original line number Diff line number Diff line
@@ -97,14 +97,20 @@ static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
 * swiotlb use this function, but it is typically not used by implementations
 * with an iommu.
 */
static inline unsigned long get_dma_offset(struct device *dev)
static inline dma_addr_t get_dma_offset(struct device *dev)
{
	if (dev)
		return (unsigned long)dev->archdata.dma_data;
		return dev->archdata.dma_data.dma_offset;

	return PCI_DRAM_OFFSET;
}

static inline void set_dma_offset(struct device *dev, dma_addr_t off)
{
	if (dev)
		dev->archdata.dma_data.dma_offset = off;
}

/* this will be removed soon */
#define flush_write_buffers()

+10 −0
Original line number Diff line number Diff line
@@ -70,6 +70,16 @@ struct iommu_table {

struct scatterlist;

static inline void set_iommu_table_base(struct device *dev, void *base)
{
	dev->archdata.dma_data.iommu_table_base = base;
}

static inline void *get_iommu_table_base(struct device *dev)
{
	return dev->archdata.dma_data.iommu_table_base;
}

/* Frees table for an individual device node */
extern void iommu_free_table(struct iommu_table *tbl, const char *node_name);

+8 −8
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@
static void *dma_iommu_alloc_coherent(struct device *dev, size_t size,
				      dma_addr_t *dma_handle, gfp_t flag)
{
	return iommu_alloc_coherent(dev, dev->archdata.dma_data, size,
	return iommu_alloc_coherent(dev, get_iommu_table_base(dev), size,
				    dma_handle, device_to_mask(dev), flag,
				    dev_to_node(dev));
}
@@ -26,7 +26,7 @@ static void *dma_iommu_alloc_coherent(struct device *dev, size_t size,
static void dma_iommu_free_coherent(struct device *dev, size_t size,
				    void *vaddr, dma_addr_t dma_handle)
{
	iommu_free_coherent(dev->archdata.dma_data, size, vaddr, dma_handle);
	iommu_free_coherent(get_iommu_table_base(dev), size, vaddr, dma_handle);
}

/* Creates TCEs for a user provided buffer.  The user buffer must be
@@ -39,8 +39,8 @@ static dma_addr_t dma_iommu_map_page(struct device *dev, struct page *page,
				     enum dma_data_direction direction,
				     struct dma_attrs *attrs)
{
	return iommu_map_page(dev, dev->archdata.dma_data, page, offset, size,
			      device_to_mask(dev), direction, attrs);
	return iommu_map_page(dev, get_iommu_table_base(dev), page, offset,
			      size, device_to_mask(dev), direction, attrs);
}


@@ -48,7 +48,7 @@ static void dma_iommu_unmap_page(struct device *dev, dma_addr_t dma_handle,
				 size_t size, enum dma_data_direction direction,
				 struct dma_attrs *attrs)
{
	iommu_unmap_page(dev->archdata.dma_data, dma_handle, size, direction,
	iommu_unmap_page(get_iommu_table_base(dev), dma_handle, size, direction,
			 attrs);
}

@@ -57,7 +57,7 @@ static int dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist,
			    int nelems, enum dma_data_direction direction,
			    struct dma_attrs *attrs)
{
	return iommu_map_sg(dev, dev->archdata.dma_data, sglist, nelems,
	return iommu_map_sg(dev, get_iommu_table_base(dev), sglist, nelems,
			    device_to_mask(dev), direction, attrs);
}

@@ -65,14 +65,14 @@ static void dma_iommu_unmap_sg(struct device *dev, struct scatterlist *sglist,
		int nelems, enum dma_data_direction direction,
		struct dma_attrs *attrs)
{
	iommu_unmap_sg(dev->archdata.dma_data, sglist, nelems, direction,
	iommu_unmap_sg(get_iommu_table_base(dev), sglist, nelems, direction,
		       attrs);
}

/* We support DMA to/from any memory page via the iommu */
static int dma_iommu_dma_supported(struct device *dev, u64 mask)
{
	struct iommu_table *tbl = dev->archdata.dma_data;
	struct iommu_table *tbl = get_iommu_table_base(dev);

	if (!tbl || tbl->it_offset > mask) {
		printk(KERN_INFO
+1 −1
Original line number Diff line number Diff line
@@ -1117,7 +1117,7 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)

		/* Hook up default DMA ops */
		sd->dma_ops = pci_dma_ops;
		sd->dma_data = (void *)PCI_DRAM_OFFSET;
		set_dma_offset(&dev->dev, PCI_DRAM_OFFSET);

		/* Additional platform DMA/iommu setup */
		if (ppc_md.pci_dma_dev_setup)
Loading