aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-09-12 13:30:06 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2017-09-12 13:30:06 -0700
commit52269718dc2cf2585d7a2828f31d46ef46e68000 (patch)
tree9815c6cbaa8c2e3247b6356725c150831dfd4d4e /drivers
parentMerge tag 'uuid-for-4.14' of git://git.infradead.org/users/hch/uuid (diff)
parentdma-coherent: fix dma_declare_coherent_memory() logic error (diff)
downloadlinux-dev-52269718dc2cf2585d7a2828f31d46ef46e68000.tar.xz
linux-dev-52269718dc2cf2585d7a2828f31d46ef46e68000.zip
Merge tag 'dma-mapping-4.14' of git://git.infradead.org/users/hch/dma-mapping
Pull dma-mapping updates from Christoph Hellwig: - removal of the old dma_alloc_noncoherent interface - remove unused flags to dma_declare_coherent_memory - restrict OF DMA configuration to specific physical busses - use the iommu mailing list for dma-mapping questions and patches * tag 'dma-mapping-4.14' of git://git.infradead.org/users/hch/dma-mapping: dma-coherent: fix dma_declare_coherent_memory() logic error ARM: imx: mx31moboard: Remove unused 'dma' variable dma-coherent: remove an unused variable MAINTAINERS: use the iommu list for the dma-mapping subsystem dma-coherent: remove the DMA_MEMORY_MAP and DMA_MEMORY_IO flags dma-coherent: remove the DMA_MEMORY_INCLUDES_CHILDREN flag of: restrict DMA configuration dma-mapping: remove dma_alloc_noncoherent and dma_free_noncoherent i825xx: switch to switch to dma_alloc_attrs au1000_eth: switch to dma_alloc_attrs sgiseeq: switch to dma_alloc_attrs dma-mapping: reduce dma_mapping_error inline bloat
Diffstat (limited to 'drivers')
-rw-r--r--drivers/base/dma-coherent.c85
-rw-r--r--drivers/base/dma-mapping.c7
-rw-r--r--drivers/char/virtio_console.c3
-rw-r--r--drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c5
-rw-r--r--drivers/net/ethernet/amd/au1000_eth.c18
-rw-r--r--drivers/net/ethernet/i825xx/lasi_82596.c6
-rw-r--r--drivers/net/ethernet/i825xx/lib82596.c9
-rw-r--r--drivers/net/ethernet/i825xx/sni_82596.c6
-rw-r--r--drivers/net/ethernet/seeq/sgiseeq.c8
-rw-r--r--drivers/of/device.c48
-rw-r--r--drivers/scsi/NCR_Q720.c3
-rw-r--r--drivers/usb/host/ohci-sm501.c7
-rw-r--r--drivers/usb/host/ohci-tmio.c9
13 files changed, 104 insertions, 110 deletions
diff --git a/drivers/base/dma-coherent.c b/drivers/base/dma-coherent.c
index 1c152aed6b82..a39b2166b145 100644
--- a/drivers/base/dma-coherent.c
+++ b/drivers/base/dma-coherent.c
@@ -37,7 +37,7 @@ static inline dma_addr_t dma_get_device_base(struct device *dev,
return mem->device_base;
}
-static bool dma_init_coherent_memory(
+static int dma_init_coherent_memory(
phys_addr_t phys_addr, dma_addr_t device_addr, size_t size, int flags,
struct dma_coherent_mem **mem)
{
@@ -45,25 +45,28 @@ static bool dma_init_coherent_memory(
void __iomem *mem_base = NULL;
int pages = size >> PAGE_SHIFT;
int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
+ int ret;
- if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0)
- goto out;
- if (!size)
+ if (!size) {
+ ret = -EINVAL;
goto out;
+ }
- if (flags & DMA_MEMORY_MAP)
- mem_base = memremap(phys_addr, size, MEMREMAP_WC);
- else
- mem_base = ioremap(phys_addr, size);
- if (!mem_base)
+ mem_base = memremap(phys_addr, size, MEMREMAP_WC);
+ if (!mem_base) {
+ ret = -EINVAL;
goto out;
-
+ }
dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL);
- if (!dma_mem)
+ if (!dma_mem) {
+ ret = -ENOMEM;
goto out;
+ }
dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
- if (!dma_mem->bitmap)
+ if (!dma_mem->bitmap) {
+ ret = -ENOMEM;
goto out;
+ }
dma_mem->virt_base = mem_base;
dma_mem->device_base = device_addr;
@@ -73,17 +76,13 @@ static bool dma_init_coherent_memory(
spin_lock_init(&dma_mem->spinlock);
*mem = dma_mem;
- return true;
+ return 0;
out:
kfree(dma_mem);
- if (mem_base) {
- if (flags & DMA_MEMORY_MAP)
- memunmap(mem_base);
- else
- iounmap(mem_base);
- }
- return false;
+ if (mem_base)
+ memunmap(mem_base);
+ return ret;
}
static void dma_release_coherent_memory(struct dma_coherent_mem *mem)
@@ -91,10 +90,7 @@ static void dma_release_coherent_memory(struct dma_coherent_mem *mem)
if (!mem)
return;
- if (mem->flags & DMA_MEMORY_MAP)
- memunmap(mem->virt_base);
- else
- iounmap(mem->virt_base);
+ memunmap(mem->virt_base);
kfree(mem->bitmap);
kfree(mem);
}
@@ -109,8 +105,6 @@ static int dma_assign_coherent_memory(struct device *dev,
return -EBUSY;
dev->dma_mem = mem;
- /* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */
-
return 0;
}
@@ -118,16 +112,16 @@ int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr,
dma_addr_t device_addr, size_t size, int flags)
{
struct dma_coherent_mem *mem;
+ int ret;
- if (!dma_init_coherent_memory(phys_addr, device_addr, size, flags,
- &mem))
- return 0;
-
- if (dma_assign_coherent_memory(dev, mem) == 0)
- return flags & DMA_MEMORY_MAP ? DMA_MEMORY_MAP : DMA_MEMORY_IO;
+ ret = dma_init_coherent_memory(phys_addr, device_addr, size, flags, &mem);
+ if (ret)
+ return ret;
- dma_release_coherent_memory(mem);
- return 0;
+ ret = dma_assign_coherent_memory(dev, mem);
+ if (ret)
+ dma_release_coherent_memory(mem);
+ return ret;
}
EXPORT_SYMBOL(dma_declare_coherent_memory);
@@ -171,7 +165,6 @@ static void *__dma_alloc_from_coherent(struct dma_coherent_mem *mem,
int order = get_order(size);
unsigned long flags;
int pageno;
- int dma_memory_map;
void *ret;
spin_lock_irqsave(&mem->spinlock, flags);
@@ -188,15 +181,9 @@ static void *__dma_alloc_from_coherent(struct dma_coherent_mem *mem,
*/
*dma_handle = mem->device_base + (pageno << PAGE_SHIFT);
ret = mem->virt_base + (pageno << PAGE_SHIFT);
- dma_memory_map = (mem->flags & DMA_MEMORY_MAP);
spin_unlock_irqrestore(&mem->spinlock, flags);
- if (dma_memory_map)
- memset(ret, 0, size);
- else
- memset_io(ret, 0, size);
-
+ memset(ret, 0, size);
return ret;
-
err:
spin_unlock_irqrestore(&mem->spinlock, flags);
return NULL;
@@ -359,14 +346,18 @@ static struct reserved_mem *dma_reserved_default_memory __initdata;
static int rmem_dma_device_init(struct reserved_mem *rmem, struct device *dev)
{
struct dma_coherent_mem *mem = rmem->priv;
+ int ret;
- if (!mem &&
- !dma_init_coherent_memory(rmem->base, rmem->base, rmem->size,
- DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE,
- &mem)) {
+ if (!mem)
+ return -ENODEV;
+
+ ret = dma_init_coherent_memory(rmem->base, rmem->base, rmem->size,
+ DMA_MEMORY_EXCLUSIVE, &mem);
+
+ if (ret) {
pr_err("Reserved memory: failed to init DMA memory pool at %pa, size %ld MiB\n",
&rmem->base, (unsigned long)rmem->size / SZ_1M);
- return -ENODEV;
+ return ret;
}
mem->use_dev_dma_pfn_offset = true;
rmem->priv = mem;
diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index b555ff9dd8fc..e584eddef0a7 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -176,13 +176,10 @@ int dmam_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr,
rc = dma_declare_coherent_memory(dev, phys_addr, device_addr, size,
flags);
- if (rc) {
+ if (!rc)
devres_add(dev, res);
- rc = 0;
- } else {
+ else
devres_free(res);
- rc = -ENOMEM;
- }
return rc;
}
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 23f33f95d4a6..d1aed2513bd9 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -451,9 +451,6 @@ static struct port_buffer *alloc_buf(struct virtqueue *vq, size_t buf_size,
* device is created by remoteproc, the DMA memory is
* associated with the grandparent device:
* vdev => rproc => platform-dev.
- * The code here would have been less quirky if
- * DMA_MEMORY_INCLUDES_CHILDREN had been supported
- * in dma-coherent.c
*/
if (!vq->vdev->dev.parent || !vq->vdev->dev.parent->parent)
goto free_buf;
diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
index 96dc01750bc0..36762ec954e7 100644
--- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
+++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
@@ -1708,11 +1708,10 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
err = dma_declare_coherent_memory(&pdev->dev, res->start,
res->start,
resource_size(res),
- DMA_MEMORY_MAP |
DMA_MEMORY_EXCLUSIVE);
- if (!err) {
+ if (err) {
dev_err(&pdev->dev, "Unable to declare CEU memory.\n");
- return -ENXIO;
+ return err;
}
pcdev->video_limit = resource_size(res);
diff --git a/drivers/net/ethernet/amd/au1000_eth.c b/drivers/net/ethernet/amd/au1000_eth.c
index a3c90fe5de00..73ca8879ada7 100644
--- a/drivers/net/ethernet/amd/au1000_eth.c
+++ b/drivers/net/ethernet/amd/au1000_eth.c
@@ -1180,9 +1180,10 @@ static int au1000_probe(struct platform_device *pdev)
/* Allocate the data buffers
* Snooping works fine with eth on all au1xxx
*/
- aup->vaddr = (u32)dma_alloc_noncoherent(NULL, MAX_BUF_SIZE *
- (NUM_TX_BUFFS + NUM_RX_BUFFS),
- &aup->dma_addr, 0);
+ aup->vaddr = (u32)dma_alloc_attrs(NULL, MAX_BUF_SIZE *
+ (NUM_TX_BUFFS + NUM_RX_BUFFS),
+ &aup->dma_addr, 0,
+ DMA_ATTR_NON_CONSISTENT);
if (!aup->vaddr) {
dev_err(&pdev->dev, "failed to allocate data buffers\n");
err = -ENOMEM;
@@ -1361,8 +1362,9 @@ err_remap3:
err_remap2:
iounmap(aup->mac);
err_remap1:
- dma_free_noncoherent(NULL, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS),
- (void *)aup->vaddr, aup->dma_addr);
+ dma_free_attrs(NULL, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS),
+ (void *)aup->vaddr, aup->dma_addr,
+ DMA_ATTR_NON_CONSISTENT);
err_vaddr:
free_netdev(dev);
err_alloc:
@@ -1394,9 +1396,9 @@ static int au1000_remove(struct platform_device *pdev)
if (aup->tx_db_inuse[i])
au1000_ReleaseDB(aup, aup->tx_db_inuse[i]);
- dma_free_noncoherent(NULL, MAX_BUF_SIZE *
- (NUM_TX_BUFFS + NUM_RX_BUFFS),
- (void *)aup->vaddr, aup->dma_addr);
+ dma_free_attrs(NULL, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS),
+ (void *)aup->vaddr, aup->dma_addr,
+ DMA_ATTR_NON_CONSISTENT);
iounmap(aup->macdma);
iounmap(aup->mac);
diff --git a/drivers/net/ethernet/i825xx/lasi_82596.c b/drivers/net/ethernet/i825xx/lasi_82596.c
index aa22e108f09b..b69c622ba8b2 100644
--- a/drivers/net/ethernet/i825xx/lasi_82596.c
+++ b/drivers/net/ethernet/i825xx/lasi_82596.c
@@ -96,8 +96,6 @@
#define OPT_SWAP_PORT 0x0001 /* Need to wordswp on the MPU port */
-#define DMA_ALLOC dma_alloc_noncoherent
-#define DMA_FREE dma_free_noncoherent
#define DMA_WBACK(ndev, addr, len) \
do { dma_cache_sync((ndev)->dev.parent, (void *)addr, len, DMA_TO_DEVICE); } while (0)
@@ -200,8 +198,8 @@ static int __exit lan_remove_chip(struct parisc_device *pdev)
struct i596_private *lp = netdev_priv(dev);
unregister_netdev (dev);
- DMA_FREE(&pdev->dev, sizeof(struct i596_private),
- (void *)lp->dma, lp->dma_addr);
+ dma_free_attrs(&pdev->dev, sizeof(struct i596_private), lp->dma,
+ lp->dma_addr, DMA_ATTR_NON_CONSISTENT);
free_netdev (dev);
return 0;
}
diff --git a/drivers/net/ethernet/i825xx/lib82596.c b/drivers/net/ethernet/i825xx/lib82596.c
index 8449c58f01fd..f00a1dc2128c 100644
--- a/drivers/net/ethernet/i825xx/lib82596.c
+++ b/drivers/net/ethernet/i825xx/lib82596.c
@@ -1063,8 +1063,9 @@ static int i82596_probe(struct net_device *dev)
if (!dev->base_addr || !dev->irq)
return -ENODEV;
- dma = (struct i596_dma *) DMA_ALLOC(dev->dev.parent,
- sizeof(struct i596_dma), &lp->dma_addr, GFP_KERNEL);
+ dma = dma_alloc_attrs(dev->dev.parent, sizeof(struct i596_dma),
+ &lp->dma_addr, GFP_KERNEL,
+ DMA_ATTR_NON_CONSISTENT);
if (!dma) {
printk(KERN_ERR "%s: Couldn't get shared memory\n", __FILE__);
return -ENOMEM;
@@ -1085,8 +1086,8 @@ static int i82596_probe(struct net_device *dev)
i = register_netdev(dev);
if (i) {
- DMA_FREE(dev->dev.parent, sizeof(struct i596_dma),
- (void *)dma, lp->dma_addr);
+ dma_free_attrs(dev->dev.parent, sizeof(struct i596_dma),
+ dma, lp->dma_addr, DMA_ATTR_NON_CONSISTENT);
return i;
}
diff --git a/drivers/net/ethernet/i825xx/sni_82596.c b/drivers/net/ethernet/i825xx/sni_82596.c
index 2af7f77345fb..b2c04a789744 100644
--- a/drivers/net/ethernet/i825xx/sni_82596.c
+++ b/drivers/net/ethernet/i825xx/sni_82596.c
@@ -23,8 +23,6 @@
static const char sni_82596_string[] = "snirm_82596";
-#define DMA_ALLOC dma_alloc_coherent
-#define DMA_FREE dma_free_coherent
#define DMA_WBACK(priv, addr, len) do { } while (0)
#define DMA_INV(priv, addr, len) do { } while (0)
#define DMA_WBACK_INV(priv, addr, len) do { } while (0)
@@ -152,8 +150,8 @@ static int sni_82596_driver_remove(struct platform_device *pdev)
struct i596_private *lp = netdev_priv(dev);
unregister_netdev(dev);
- DMA_FREE(dev->dev.parent, sizeof(struct i596_private),
- lp->dma, lp->dma_addr);
+ dma_free_attrs(dev->dev.parent, sizeof(struct i596_private), lp->dma,
+ lp->dma_addr, DMA_ATTR_NON_CONSISTENT);
iounmap(lp->ca);
iounmap(lp->mpu_port);
free_netdev (dev);
diff --git a/drivers/net/ethernet/seeq/sgiseeq.c b/drivers/net/ethernet/seeq/sgiseeq.c
index 70347720fdf9..573691bc3b71 100644
--- a/drivers/net/ethernet/seeq/sgiseeq.c
+++ b/drivers/net/ethernet/seeq/sgiseeq.c
@@ -737,8 +737,8 @@ static int sgiseeq_probe(struct platform_device *pdev)
sp = netdev_priv(dev);
/* Make private data page aligned */
- sr = dma_alloc_noncoherent(&pdev->dev, sizeof(*sp->srings),
- &sp->srings_dma, GFP_KERNEL);
+ sr = dma_alloc_attrs(&pdev->dev, sizeof(*sp->srings), &sp->srings_dma,
+ GFP_KERNEL, DMA_ATTR_NON_CONSISTENT);
if (!sr) {
printk(KERN_ERR "Sgiseeq: Page alloc failed, aborting.\n");
err = -ENOMEM;
@@ -813,8 +813,8 @@ static int sgiseeq_remove(struct platform_device *pdev)
struct sgiseeq_private *sp = netdev_priv(dev);
unregister_netdev(dev);
- dma_free_noncoherent(&pdev->dev, sizeof(*sp->srings), sp->srings,
- sp->srings_dma);
+ dma_free_attrs(&pdev->dev, sizeof(*sp->srings), sp->srings,
+ sp->srings_dma, DMA_ATTR_NON_CONSISTENT);
free_netdev(dev);
return 0;
diff --git a/drivers/of/device.c b/drivers/of/device.c
index 17b66e9715d2..64b710265d39 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -9,6 +9,9 @@
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
#include <asm/errno.h>
#include "of_private.h"
@@ -84,31 +87,28 @@ int of_device_add(struct platform_device *ofdev)
*/
int of_dma_configure(struct device *dev, struct device_node *np)
{
- u64 dma_addr, paddr, size;
+ u64 dma_addr, paddr, size = 0;
int ret;
bool coherent;
unsigned long offset;
const struct iommu_ops *iommu;
u64 mask;
- /*
- * Set default coherent_dma_mask to 32 bit. Drivers are expected to
- * setup the correct supported mask.
- */
- if (!dev->coherent_dma_mask)
- dev->coherent_dma_mask = DMA_BIT_MASK(32);
-
- /*
- * Set it to coherent_dma_mask by default if the architecture
- * code has not set it.
- */
- if (!dev->dma_mask)
- dev->dma_mask = &dev->coherent_dma_mask;
-
ret = of_dma_get_range(np, &dma_addr, &paddr, &size);
if (ret < 0) {
+ /*
+ * For legacy reasons, we have to assume some devices need
+ * DMA configuration regardless of whether "dma-ranges" is
+ * correctly specified or not.
+ */
+ if (!dev_is_pci(dev) &&
+#ifdef CONFIG_ARM_AMBA
+ dev->bus != &amba_bustype &&
+#endif
+ dev->bus != &platform_bus_type)
+ return ret == -ENODEV ? 0 : ret;
+
dma_addr = offset = 0;
- size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
} else {
offset = PFN_DOWN(paddr - dma_addr);
@@ -129,6 +129,22 @@ int of_dma_configure(struct device *dev, struct device_node *np)
dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);
}
+ /*
+ * Set default coherent_dma_mask to 32 bit. Drivers are expected to
+ * setup the correct supported mask.
+ */
+ if (!dev->coherent_dma_mask)
+ dev->coherent_dma_mask = DMA_BIT_MASK(32);
+ /*
+ * Set it to coherent_dma_mask by default if the architecture
+ * code has not set it.
+ */
+ if (!dev->dma_mask)
+ dev->dma_mask = &dev->coherent_dma_mask;
+
+ if (!size)
+ size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
+
dev->dma_pfn_offset = offset;
/*
diff --git a/drivers/scsi/NCR_Q720.c b/drivers/scsi/NCR_Q720.c
index 05835bf1bf9c..54e7d26908ee 100644
--- a/drivers/scsi/NCR_Q720.c
+++ b/drivers/scsi/NCR_Q720.c
@@ -217,8 +217,7 @@ NCR_Q720_probe(struct device *dev)
}
if (dma_declare_coherent_memory(dev, base_addr, base_addr,
- mem_size, DMA_MEMORY_MAP)
- != DMA_MEMORY_MAP) {
+ mem_size, 0)) {
printk(KERN_ERR "NCR_Q720: DMA declare memory failed\n");
goto out_release_region;
}
diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c
index a8b8d8b8d9f3..d4e0f7cd96fa 100644
--- a/drivers/usb/host/ohci-sm501.c
+++ b/drivers/usb/host/ohci-sm501.c
@@ -123,13 +123,12 @@ static int ohci_hcd_sm501_drv_probe(struct platform_device *pdev)
* regular memory. The HCD_LOCAL_MEM flag does just that.
*/
- if (!dma_declare_coherent_memory(dev, mem->start,
+ retval = dma_declare_coherent_memory(dev, mem->start,
mem->start - mem->parent->start,
resource_size(mem),
- DMA_MEMORY_MAP |
- DMA_MEMORY_EXCLUSIVE)) {
+ DMA_MEMORY_EXCLUSIVE);
+ if (retval) {
dev_err(dev, "cannot declare coherent memory\n");
- retval = -ENXIO;
goto err1;
}
diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c
index cfcfadfc94fc..16d081a093bb 100644
--- a/drivers/usb/host/ohci-tmio.c
+++ b/drivers/usb/host/ohci-tmio.c
@@ -227,13 +227,10 @@ static int ohci_hcd_tmio_drv_probe(struct platform_device *dev)
goto err_ioremap_regs;
}
- if (!dma_declare_coherent_memory(&dev->dev, sram->start,
- sram->start,
- resource_size(sram),
- DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE)) {
- ret = -EBUSY;
+ ret = dma_declare_coherent_memory(&dev->dev, sram->start, sram->start,
+ resource_size(sram), DMA_MEMORY_EXCLUSIVE);
+ if (ret)
goto err_dma_declare;
- }
if (cell->enable) {
ret = cell->enable(dev);