* [PATCH 01/10] ARM: dmabounce: fix map_single() error return value
2011-07-04 8:47 [PATCH 00/10] dmabounce cleanups Russell King - ARM Linux
@ 2011-07-04 8:47 ` Russell King - ARM Linux
2011-07-04 8:48 ` [PATCH 02/10] ARM: dma-mapping: define dma_(un)?map_single in terms of dma_(un)?map_page Russell King - ARM Linux
` (8 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Russell King - ARM Linux @ 2011-07-04 8:47 UTC (permalink / raw)
To: linux-arm-kernel
When map_single() is unable to obtain a safe buffer, we must return
the dma_addr_t error value, which is ~0 rather than 0.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/common/dmabounce.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index e568163..841df7d 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -255,7 +255,7 @@ static inline dma_addr_t map_single(struct device *dev, void *ptr, size_t size,
if (buf == 0) {
dev_err(dev, "%s: unable to map unsafe buffer %p!\n",
__func__, ptr);
- return 0;
+ return ~0;
}
dev_dbg(dev,
--
1.7.4.4
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 02/10] ARM: dma-mapping: define dma_(un)?map_single in terms of dma_(un)?map_page
2011-07-04 8:47 [PATCH 00/10] dmabounce cleanups Russell King - ARM Linux
2011-07-04 8:47 ` [PATCH 01/10] ARM: dmabounce: fix map_single() error return value Russell King - ARM Linux
@ 2011-07-04 8:48 ` Russell King - ARM Linux
2011-07-04 8:48 ` [PATCH 03/10] ARM: dmabounce: avoid needless valid_dma_direction() check Russell King - ARM Linux
` (7 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Russell King - ARM Linux @ 2011-07-04 8:48 UTC (permalink / raw)
To: linux-arm-kernel
Use dma_map_page()/dma_unmap_page() internals to handle dma_map_single()
and dma_unmap_single().
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/common/dmabounce.c | 28 ----------------------------
arch/arm/include/asm/dma-mapping.h | 31 +++++++++----------------------
2 files changed, 9 insertions(+), 50 deletions(-)
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index 841df7d..8a0588b 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -328,34 +328,6 @@ static inline void unmap_single(struct device *dev, dma_addr_t dma_addr,
* substitute the safe buffer for the unsafe one.
* (basically move the buffer from an unsafe area to a safe one)
*/
-dma_addr_t __dma_map_single(struct device *dev, void *ptr, size_t size,
- enum dma_data_direction dir)
-{
- dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
- __func__, ptr, size, dir);
-
- BUG_ON(!valid_dma_direction(dir));
-
- return map_single(dev, ptr, size, dir);
-}
-EXPORT_SYMBOL(__dma_map_single);
-
-/*
- * see if a mapped address was really a "safe" buffer and if so, copy
- * the data from the safe buffer back to the unsafe buffer and free up
- * the safe buffer. (basically return things back to the way they
- * should be)
- */
-void __dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
- enum dma_data_direction dir)
-{
- dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
- __func__, (void *) dma_addr, size, dir);
-
- unmap_single(dev, dma_addr, size, dir);
-}
-EXPORT_SYMBOL(__dma_unmap_single);
-
dma_addr_t __dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size, enum dma_data_direction dir)
{
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index 4fff837..d2903d0 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -298,10 +298,6 @@ extern int dma_needs_bounce(struct device*, dma_addr_t, size_t);
/*
* The DMA API, implemented by dmabounce.c. See below for descriptions.
*/
-extern dma_addr_t __dma_map_single(struct device *, void *, size_t,
- enum dma_data_direction);
-extern void __dma_unmap_single(struct device *, dma_addr_t, size_t,
- enum dma_data_direction);
extern dma_addr_t __dma_map_page(struct device *, struct page *,
unsigned long, size_t, enum dma_data_direction);
extern void __dma_unmap_page(struct device *, dma_addr_t, size_t,
@@ -328,13 +324,6 @@ static inline int dmabounce_sync_for_device(struct device *d, dma_addr_t addr,
}
-static inline dma_addr_t __dma_map_single(struct device *dev, void *cpu_addr,
- size_t size, enum dma_data_direction dir)
-{
- __dma_single_cpu_to_dev(cpu_addr, size, dir);
- return virt_to_dma(dev, cpu_addr);
-}
-
static inline dma_addr_t __dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size, enum dma_data_direction dir)
{
@@ -342,12 +331,6 @@ static inline dma_addr_t __dma_map_page(struct device *dev, struct page *page,
return pfn_to_dma(dev, page_to_pfn(page)) + offset;
}
-static inline void __dma_unmap_single(struct device *dev, dma_addr_t handle,
- size_t size, enum dma_data_direction dir)
-{
- __dma_single_dev_to_cpu(dma_to_virt(dev, handle), size, dir);
-}
-
static inline void __dma_unmap_page(struct device *dev, dma_addr_t handle,
size_t size, enum dma_data_direction dir)
{
@@ -373,14 +356,18 @@ static inline void __dma_unmap_page(struct device *dev, dma_addr_t handle,
static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
size_t size, enum dma_data_direction dir)
{
+ unsigned long offset;
+ struct page *page;
dma_addr_t addr;
+ BUG_ON(!virt_addr_valid(cpu_addr));
+ BUG_ON(!virt_addr_valid(cpu_addr + size - 1));
BUG_ON(!valid_dma_direction(dir));
- addr = __dma_map_single(dev, cpu_addr, size, dir);
- debug_dma_map_page(dev, virt_to_page(cpu_addr),
- (unsigned long)cpu_addr & ~PAGE_MASK, size,
- dir, addr, true);
+ page = virt_to_page(cpu_addr);
+ offset = (unsigned long)cpu_addr & ~PAGE_MASK;
+ addr = __dma_map_page(dev, page, offset, size, dir);
+ debug_dma_map_page(dev, page, offset, size, dir, addr, true);
return addr;
}
@@ -430,7 +417,7 @@ static inline void dma_unmap_single(struct device *dev, dma_addr_t handle,
size_t size, enum dma_data_direction dir)
{
debug_dma_unmap_page(dev, handle, size, dir, true);
- __dma_unmap_single(dev, handle, size, dir);
+ __dma_unmap_page(dev, handle, size, dir);
}
/**
--
1.7.4.4
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 03/10] ARM: dmabounce: avoid needless valid_dma_direction() check
2011-07-04 8:47 [PATCH 00/10] dmabounce cleanups Russell King - ARM Linux
2011-07-04 8:47 ` [PATCH 01/10] ARM: dmabounce: fix map_single() error return value Russell King - ARM Linux
2011-07-04 8:48 ` [PATCH 02/10] ARM: dma-mapping: define dma_(un)?map_single in terms of dma_(un)?map_page Russell King - ARM Linux
@ 2011-07-04 8:48 ` Russell King - ARM Linux
2011-07-04 8:48 ` [PATCH 04/10] ARM: dmabounce: separate out decision to bounce Russell King - ARM Linux
` (6 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Russell King - ARM Linux @ 2011-07-04 8:48 UTC (permalink / raw)
To: linux-arm-kernel
This check is done at the DMA API level, so there's no point repeating
it here.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/common/dmabounce.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index 8a0588b..3e0fa15 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -334,8 +334,6 @@ dma_addr_t __dma_map_page(struct device *dev, struct page *page,
dev_dbg(dev, "%s(page=%p,off=%#lx,size=%zx,dir=%x)\n",
__func__, page, offset, size, dir);
- BUG_ON(!valid_dma_direction(dir));
-
if (PageHighMem(page)) {
dev_err(dev, "DMA buffer bouncing of HIGHMEM pages "
"is not supported\n");
--
1.7.4.4
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 04/10] ARM: dmabounce: separate out decision to bounce
2011-07-04 8:47 [PATCH 00/10] dmabounce cleanups Russell King - ARM Linux
` (2 preceding siblings ...)
2011-07-04 8:48 ` [PATCH 03/10] ARM: dmabounce: avoid needless valid_dma_direction() check Russell King - ARM Linux
@ 2011-07-04 8:48 ` Russell King - ARM Linux
2011-07-04 8:49 ` [PATCH 05/10] ARM: dmabounce: move decision for bouncing into __dma_map_page() Russell King - ARM Linux
` (5 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Russell King - ARM Linux @ 2011-07-04 8:48 UTC (permalink / raw)
To: linux-arm-kernel
Move the decision to perform DMA bouncing out of map_single() into its
own stand-alone function.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/common/dmabounce.c | 46 ++++++++++++++++++++++++++----------------
1 files changed, 28 insertions(+), 18 deletions(-)
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index 3e0fa15..643e1d6 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -219,36 +219,46 @@ static struct safe_buffer *find_safe_buffer_dev(struct device *dev,
return find_safe_buffer(dev->archdata.dmabounce, dma_addr);
}
-static inline dma_addr_t map_single(struct device *dev, void *ptr, size_t size,
- enum dma_data_direction dir)
+static int needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size)
{
- struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
- dma_addr_t dma_addr;
- int needs_bounce = 0;
-
- if (device_info)
- DO_STATS ( device_info->map_op_count++ );
-
- dma_addr = virt_to_dma(dev, ptr);
+ if (!dev || !dev->archdata.dmabounce)
+ return 0;
if (dev->dma_mask) {
- unsigned long mask = *dev->dma_mask;
- unsigned long limit;
+ unsigned long limit, mask = *dev->dma_mask;
limit = (mask + 1) & ~mask;
if (limit && size > limit) {
dev_err(dev, "DMA mapping too big (requested %#x "
"mask %#Lx)\n", size, *dev->dma_mask);
- return ~0;
+ return -E2BIG;
}
- /*
- * Figure out if we need to bounce from the DMA mask.
- */
- needs_bounce = (dma_addr | (dma_addr + size - 1)) & ~mask;
+ /* Figure out if we need to bounce from the DMA mask. */
+ if ((dma_addr | (dma_addr + size - 1)) & ~mask)
+ return 1;
}
- if (device_info && (needs_bounce || dma_needs_bounce(dev, dma_addr, size))) {
+ return dma_needs_bounce(dev, dma_addr, size) ? 1 : 0;
+}
+
+static inline dma_addr_t map_single(struct device *dev, void *ptr, size_t size,
+ enum dma_data_direction dir)
+{
+ struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
+ dma_addr_t dma_addr;
+ int ret;
+
+ if (device_info)
+ DO_STATS ( device_info->map_op_count++ );
+
+ dma_addr = virt_to_dma(dev, ptr);
+
+ ret = needs_bounce(dev, dma_addr, size);
+ if (ret < 0)
+ return ~0;
+
+ if (ret > 0) {
struct safe_buffer *buf;
buf = alloc_safe_buffer(device_info, ptr, size, dir);
--
1.7.4.4
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 05/10] ARM: dmabounce: move decision for bouncing into __dma_map_page()
2011-07-04 8:47 [PATCH 00/10] dmabounce cleanups Russell King - ARM Linux
` (3 preceding siblings ...)
2011-07-04 8:48 ` [PATCH 04/10] ARM: dmabounce: separate out decision to bounce Russell King - ARM Linux
@ 2011-07-04 8:49 ` Russell King - ARM Linux
2011-07-04 8:49 ` [PATCH 06/10] ARM: dmabounce: remove useless pr_err Russell King - ARM Linux
` (4 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Russell King - ARM Linux @ 2011-07-04 8:49 UTC (permalink / raw)
To: linux-arm-kernel
Move the decision whether to bounce into __dma_map_page(), before
the check for high pages. This avoids triggering the high page
check for devices which aren't using dmabounce. Fix the unmap path
to cope too.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/common/dmabounce.c | 124 ++++++++++++++++++++-----------------------
1 files changed, 58 insertions(+), 66 deletions(-)
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index 643e1d6..6ae292c 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -246,88 +246,58 @@ static inline dma_addr_t map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction dir)
{
struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
- dma_addr_t dma_addr;
- int ret;
+ struct safe_buffer *buf;
if (device_info)
DO_STATS ( device_info->map_op_count++ );
- dma_addr = virt_to_dma(dev, ptr);
-
- ret = needs_bounce(dev, dma_addr, size);
- if (ret < 0)
+ buf = alloc_safe_buffer(device_info, ptr, size, dir);
+ if (buf == 0) {
+ dev_err(dev, "%s: unable to map unsafe buffer %p!\n",
+ __func__, ptr);
return ~0;
+ }
- if (ret > 0) {
- struct safe_buffer *buf;
-
- buf = alloc_safe_buffer(device_info, ptr, size, dir);
- if (buf == 0) {
- dev_err(dev, "%s: unable to map unsafe buffer %p!\n",
- __func__, ptr);
- return ~0;
- }
-
- dev_dbg(dev,
- "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n",
- __func__, buf->ptr, virt_to_dma(dev, buf->ptr),
- buf->safe, buf->safe_dma_addr);
-
- if ((dir == DMA_TO_DEVICE) ||
- (dir == DMA_BIDIRECTIONAL)) {
- dev_dbg(dev, "%s: copy unsafe %p to safe %p, size %d\n",
- __func__, ptr, buf->safe, size);
- memcpy(buf->safe, ptr, size);
- }
- ptr = buf->safe;
+ dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n",
+ __func__, buf->ptr, virt_to_dma(dev, buf->ptr),
+ buf->safe, buf->safe_dma_addr);
- dma_addr = buf->safe_dma_addr;
- } else {
- /*
- * We don't need to sync the DMA buffer since
- * it was allocated via the coherent allocators.
- */
- __dma_single_cpu_to_dev(ptr, size, dir);
+ if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) {
+ dev_dbg(dev, "%s: copy unsafe %p to safe %p, size %d\n",
+ __func__, ptr, buf->safe, size);
+ memcpy(buf->safe, ptr, size);
}
- return dma_addr;
+ return buf->safe_dma_addr;
}
-static inline void unmap_single(struct device *dev, dma_addr_t dma_addr,
+static inline void unmap_single(struct device *dev, struct safe_buffer *buf,
size_t size, enum dma_data_direction dir)
{
- struct safe_buffer *buf = find_safe_buffer_dev(dev, dma_addr, "unmap");
-
- if (buf) {
- BUG_ON(buf->size != size);
- BUG_ON(buf->direction != dir);
+ BUG_ON(buf->size != size);
+ BUG_ON(buf->direction != dir);
- dev_dbg(dev,
- "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n",
- __func__, buf->ptr, virt_to_dma(dev, buf->ptr),
- buf->safe, buf->safe_dma_addr);
+ dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n",
+ __func__, buf->ptr, virt_to_dma(dev, buf->ptr),
+ buf->safe, buf->safe_dma_addr);
- DO_STATS(dev->archdata.dmabounce->bounce_count++);
+ DO_STATS(dev->archdata.dmabounce->bounce_count++);
- if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) {
- void *ptr = buf->ptr;
+ if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) {
+ void *ptr = buf->ptr;
- dev_dbg(dev,
- "%s: copy back safe %p to unsafe %p size %d\n",
- __func__, buf->safe, ptr, size);
- memcpy(ptr, buf->safe, size);
+ dev_dbg(dev, "%s: copy back safe %p to unsafe %p size %d\n",
+ __func__, buf->safe, ptr, size);
+ memcpy(ptr, buf->safe, size);
- /*
- * Since we may have written to a page cache page,
- * we need to ensure that the data will be coherent
- * with user mappings.
- */
- __cpuc_flush_dcache_area(ptr, size);
- }
- free_safe_buffer(dev->archdata.dmabounce, buf);
- } else {
- __dma_single_dev_to_cpu(dma_to_virt(dev, dma_addr), size, dir);
+ /*
+ * Since we may have written to a page cache page,
+ * we need to ensure that the data will be coherent
+ * with user mappings.
+ */
+ __cpuc_flush_dcache_area(ptr, size);
}
+ free_safe_buffer(dev->archdata.dmabounce, buf);
}
/* ************************************************** */
@@ -341,12 +311,25 @@ static inline void unmap_single(struct device *dev, dma_addr_t dma_addr,
dma_addr_t __dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size, enum dma_data_direction dir)
{
+ dma_addr_t dma_addr;
+ int ret;
+
dev_dbg(dev, "%s(page=%p,off=%#lx,size=%zx,dir=%x)\n",
__func__, page, offset, size, dir);
+ dma_addr = pfn_to_dma(dev, page_to_pfn(page)) + offset;
+
+ ret = needs_bounce(dev, dma_addr, size);
+ if (ret < 0)
+ return ~0;
+
+ if (ret == 0) {
+ __dma_page_cpu_to_dev(page, offset, size, dir);
+ return dma_addr;
+ }
+
if (PageHighMem(page)) {
- dev_err(dev, "DMA buffer bouncing of HIGHMEM pages "
- "is not supported\n");
+ dev_err(dev, "DMA buffer bouncing of HIGHMEM pages is not supported\n");
return ~0;
}
@@ -363,10 +346,19 @@ EXPORT_SYMBOL(__dma_map_page);
void __dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
enum dma_data_direction dir)
{
+ struct safe_buffer *buf;
+
dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
__func__, (void *) dma_addr, size, dir);
- unmap_single(dev, dma_addr, size, dir);
+ buf = find_safe_buffer_dev(dev, dma_addr, __func__);
+ if (!buf) {
+ __dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, dma_addr)),
+ dma_addr & ~PAGE_MASK, size, dir);
+ return;
+ }
+
+ unmap_single(dev, buf, size, dir);
}
EXPORT_SYMBOL(__dma_unmap_page);
--
1.7.4.4
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 06/10] ARM: dmabounce: remove useless pr_err
2011-07-04 8:47 [PATCH 00/10] dmabounce cleanups Russell King - ARM Linux
` (4 preceding siblings ...)
2011-07-04 8:49 ` [PATCH 05/10] ARM: dmabounce: move decision for bouncing into __dma_map_page() Russell King - ARM Linux
@ 2011-07-04 8:49 ` Russell King - ARM Linux
2011-07-04 8:49 ` [PATCH 07/10] ARM: dmabounce: check pointer against NULL not 0 Russell King - ARM Linux
` (3 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Russell King - ARM Linux @ 2011-07-04 8:49 UTC (permalink / raw)
To: linux-arm-kernel
We already check that dev != NULL, so this won't be reached.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/common/dmabounce.c | 5 +----
1 files changed, 1 insertions(+), 4 deletions(-)
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index 6ae292c..0077c1b 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -210,10 +210,7 @@ static struct safe_buffer *find_safe_buffer_dev(struct device *dev,
if (!dev || !dev->archdata.dmabounce)
return NULL;
if (dma_mapping_error(dev, dma_addr)) {
- if (dev)
- dev_err(dev, "Trying to %s invalid mapping\n", where);
- else
- pr_err("unknown device: Trying to %s invalid mapping\n", where);
+ dev_err(dev, "Trying to %s invalid mapping\n", where);
return NULL;
}
return find_safe_buffer(dev->archdata.dmabounce, dma_addr);
--
1.7.4.4
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 07/10] ARM: dmabounce: check pointer against NULL not 0
2011-07-04 8:47 [PATCH 00/10] dmabounce cleanups Russell King - ARM Linux
` (5 preceding siblings ...)
2011-07-04 8:49 ` [PATCH 06/10] ARM: dmabounce: remove useless pr_err Russell King - ARM Linux
@ 2011-07-04 8:49 ` Russell King - ARM Linux
2011-07-04 8:50 ` [PATCH 08/10] ARM: dmabounce: correct unmap_single dev_dbg Russell King - ARM Linux
` (2 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Russell King - ARM Linux @ 2011-07-04 8:49 UTC (permalink / raw)
To: linux-arm-kernel
Pointers should be checked against NULL rather than 0, otherwise we
get sparse warnings.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/common/dmabounce.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index 0077c1b..b4a8759 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -249,7 +249,7 @@ static inline dma_addr_t map_single(struct device *dev, void *ptr, size_t size,
DO_STATS ( device_info->map_op_count++ );
buf = alloc_safe_buffer(device_info, ptr, size, dir);
- if (buf == 0) {
+ if (buf == NULL) {
dev_err(dev, "%s: unable to map unsafe buffer %p!\n",
__func__, ptr);
return ~0;
--
1.7.4.4
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 08/10] ARM: dmabounce: correct unmap_single dev_dbg
2011-07-04 8:47 [PATCH 00/10] dmabounce cleanups Russell King - ARM Linux
` (6 preceding siblings ...)
2011-07-04 8:49 ` [PATCH 07/10] ARM: dmabounce: check pointer against NULL not 0 Russell King - ARM Linux
@ 2011-07-04 8:50 ` Russell King - ARM Linux
2011-07-04 8:50 ` [PATCH 09/10] ARM: dmabounce: get rid of dma_needs_bounce global function Russell King - ARM Linux
2011-07-04 8:50 ` [PATCH 10/10] ARM: dmabounce: no need to check dev->bus type in needs_bounce function Russell King - ARM Linux
9 siblings, 0 replies; 11+ messages in thread
From: Russell King - ARM Linux @ 2011-07-04 8:50 UTC (permalink / raw)
To: linux-arm-kernel
DMA addresses should not be casted to void * for printing. Fix
that to be consistent with the rest of the file.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/common/dmabounce.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index b4a8759..4f13505 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -345,8 +345,8 @@ void __dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
{
struct safe_buffer *buf;
- dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
- __func__, (void *) dma_addr, size, dir);
+ dev_dbg(dev, "%s(dma=%#x,size=%d,dir=%x)\n",
+ __func__, dma_addr, size, dir);
buf = find_safe_buffer_dev(dev, dma_addr, __func__);
if (!buf) {
--
1.7.4.4
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 09/10] ARM: dmabounce: get rid of dma_needs_bounce global function
2011-07-04 8:47 [PATCH 00/10] dmabounce cleanups Russell King - ARM Linux
` (7 preceding siblings ...)
2011-07-04 8:50 ` [PATCH 08/10] ARM: dmabounce: correct unmap_single dev_dbg Russell King - ARM Linux
@ 2011-07-04 8:50 ` Russell King - ARM Linux
2011-07-04 8:50 ` [PATCH 10/10] ARM: dmabounce: no need to check dev->bus type in needs_bounce function Russell King - ARM Linux
9 siblings, 0 replies; 11+ messages in thread
From: Russell King - ARM Linux @ 2011-07-04 8:50 UTC (permalink / raw)
To: linux-arm-kernel
Pass the device type specific needs_bounce function in at dmabounce
register time, avoiding the need for a platform specific global
function to do this.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/common/dmabounce.c | 8 +++-
arch/arm/common/it8152.c | 17 +++++-----
arch/arm/common/sa1111.c | 60 ++++++++++++++++++-----------------
arch/arm/include/asm/dma-mapping.h | 22 +------------
arch/arm/mach-ixp4xx/common-pci.c | 12 +++---
5 files changed, 53 insertions(+), 66 deletions(-)
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index 4f13505..595ecd2 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -79,6 +79,8 @@ struct dmabounce_device_info {
struct dmabounce_pool large;
rwlock_t lock;
+
+ int (*needs_bounce)(struct device *, dma_addr_t, size_t);
};
#ifdef STATS
@@ -236,7 +238,7 @@ static int needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size)
return 1;
}
- return dma_needs_bounce(dev, dma_addr, size) ? 1 : 0;
+ return !!dev->archdata.dmabounce->needs_bounce(dev, dma_addr, size);
}
static inline dma_addr_t map_single(struct device *dev, void *ptr, size_t size,
@@ -430,7 +432,8 @@ static int dmabounce_init_pool(struct dmabounce_pool *pool, struct device *dev,
}
int dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
- unsigned long large_buffer_size)
+ unsigned long large_buffer_size,
+ int (*needs_bounce_fn)(struct device *, dma_addr_t, size_t))
{
struct dmabounce_device_info *device_info;
int ret;
@@ -466,6 +469,7 @@ int dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
device_info->dev = dev;
INIT_LIST_HEAD(&device_info->safe_buffers);
rwlock_init(&device_info->lock);
+ device_info->needs_bounce = needs_bounce_fn;
#ifdef STATS
device_info->total_allocs = 0;
diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c
index 7a21927..80b49e1 100644
--- a/arch/arm/common/it8152.c
+++ b/arch/arm/common/it8152.c
@@ -243,6 +243,13 @@ static struct resource it8152_mem = {
* ITE8152 chip can address up to 64MByte, so all the devices
* connected to ITE8152 (PCI and USB) should have limited DMA window
*/
+static int it8152_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size)
+{
+ dev_dbg(dev, "%s: dma_addr %08x, size %08x\n",
+ __func__, dma_addr, size);
+ return dev->bus == &pci_bus_type &&
+ (dma_addr + size - PHYS_OFFSET) >= SZ_64M;
+}
/*
* Setup DMA mask to 64MB on devices connected to ITE8152. Ignore all
@@ -254,7 +261,7 @@ static int it8152_pci_platform_notify(struct device *dev)
if (dev->dma_mask)
*dev->dma_mask = (SZ_64M - 1) | PHYS_OFFSET;
dev->coherent_dma_mask = (SZ_64M - 1) | PHYS_OFFSET;
- dmabounce_register_dev(dev, 2048, 4096);
+ dmabounce_register_dev(dev, 2048, 4096, it8152_needs_bounce);
}
return 0;
}
@@ -267,14 +274,6 @@ static int it8152_pci_platform_notify_remove(struct device *dev)
return 0;
}
-int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size)
-{
- dev_dbg(dev, "%s: dma_addr %08x, size %08x\n",
- __func__, dma_addr, size);
- return (dev->bus == &pci_bus_type) &&
- ((dma_addr + size - PHYS_OFFSET) >= SZ_64M);
-}
-
int dma_set_coherent_mask(struct device *dev, u64 mask)
{
if (mask >= PHYS_OFFSET + SZ_64M - 1)
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index 9c49a46..0569de6 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -579,7 +579,36 @@ sa1111_configure_smc(struct sa1111 *sachip, int sdram, unsigned int drac,
sachip->dev->coherent_dma_mask &= sa1111_dma_mask[drac >> 2];
}
+#endif
+#ifdef CONFIG_DMABOUNCE
+/*
+ * According to the "Intel StrongARM SA-1111 Microprocessor Companion
+ * Chip Specification Update" (June 2000), erratum #7, there is a
+ * significant bug in the SA1111 SDRAM shared memory controller. If
+ * an access to a region of memory above 1MB relative to the bank base,
+ * it is important that address bit 10 _NOT_ be asserted. Depending
+ * on the configuration of the RAM, bit 10 may correspond to one
+ * of several different (processor-relative) address bits.
+ *
+ * This routine only identifies whether or not a given DMA address
+ * is susceptible to the bug.
+ *
+ * This should only get called for sa1111_device types due to the
+ * way we configure our device dma_masks.
+ */
+static int sa1111_needs_bounce(struct device *dev, dma_addr_t addr, size_t size)
+{
+ /*
+ * Section 4.6 of the "Intel StrongARM SA-1111 Development Module
+ * User's Guide" mentions that jumpers R51 and R52 control the
+ * target of SA-1111 DMA (either SDRAM bank 0 on Assabet, or
+ * SDRAM bank 1 on Neponset). The default configuration selects
+ * Assabet, so any address in bank 1 is necessarily invalid.
+ */
+ return (machine_is_assabet() || machine_is_pfs168()) &&
+ (addr >= 0xc8000000 || (addr + size) >= 0xc8000000);
+}
#endif
static void sa1111_dev_release(struct device *_dev)
@@ -644,7 +673,8 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent,
dev->dev.dma_mask = &dev->dma_mask;
if (dev->dma_mask != 0xffffffffUL) {
- ret = dmabounce_register_dev(&dev->dev, 1024, 4096);
+ ret = dmabounce_register_dev(&dev->dev, 1024, 4096,
+ sa1111_needs_bounce);
if (ret) {
dev_err(&dev->dev, "SA1111: Failed to register"
" with dmabounce\n");
@@ -818,34 +848,6 @@ static void __sa1111_remove(struct sa1111 *sachip)
kfree(sachip);
}
-/*
- * According to the "Intel StrongARM SA-1111 Microprocessor Companion
- * Chip Specification Update" (June 2000), erratum #7, there is a
- * significant bug in the SA1111 SDRAM shared memory controller. If
- * an access to a region of memory above 1MB relative to the bank base,
- * it is important that address bit 10 _NOT_ be asserted. Depending
- * on the configuration of the RAM, bit 10 may correspond to one
- * of several different (processor-relative) address bits.
- *
- * This routine only identifies whether or not a given DMA address
- * is susceptible to the bug.
- *
- * This should only get called for sa1111_device types due to the
- * way we configure our device dma_masks.
- */
-int dma_needs_bounce(struct device *dev, dma_addr_t addr, size_t size)
-{
- /*
- * Section 4.6 of the "Intel StrongARM SA-1111 Development Module
- * User's Guide" mentions that jumpers R51 and R52 control the
- * target of SA-1111 DMA (either SDRAM bank 0 on Assabet, or
- * SDRAM bank 1 on Neponset). The default configuration selects
- * Assabet, so any address in bank 1 is necessarily invalid.
- */
- return ((machine_is_assabet() || machine_is_pfs168()) &&
- (addr >= 0xc8000000 || (addr + size) >= 0xc8000000));
-}
-
struct sa1111_save_data {
unsigned int skcr;
unsigned int skpcr;
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index d2903d0..4ad2533 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -256,14 +256,14 @@ int dma_mmap_writecombine(struct device *, struct vm_area_struct *,
* @dev: valid struct device pointer
* @small_buf_size: size of buffers to use with small buffer pool
* @large_buf_size: size of buffers to use with large buffer pool (can be 0)
+ * @needs_bounce_fn: called to determine whether buffer needs bouncing
*
* This function should be called by low-level platform code to register
* a device as requireing DMA buffer bouncing. The function will allocate
* appropriate DMA pools for the device.
- *
*/
extern int dmabounce_register_dev(struct device *, unsigned long,
- unsigned long);
+ unsigned long, int (*)(struct device *, dma_addr_t, size_t));
/**
* dmabounce_unregister_dev
@@ -277,24 +277,6 @@ extern int dmabounce_register_dev(struct device *, unsigned long,
*/
extern void dmabounce_unregister_dev(struct device *);
-/**
- * dma_needs_bounce
- *
- * @dev: valid struct device pointer
- * @dma_handle: dma_handle of unbounced buffer
- * @size: size of region being mapped
- *
- * Platforms that utilize the dmabounce mechanism must implement
- * this function.
- *
- * The dmabounce routines call this function whenever a dma-mapping
- * is requested to determine whether a given buffer needs to be bounced
- * or not. The function must return 0 if the buffer is OK for
- * DMA access and 1 if the buffer needs to be bounced.
- *
- */
-extern int dma_needs_bounce(struct device*, dma_addr_t, size_t);
-
/*
* The DMA API, implemented by dmabounce.c. See below for descriptions.
*/
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c
index e9a5893..d7db10c 100644
--- a/arch/arm/mach-ixp4xx/common-pci.c
+++ b/arch/arm/mach-ixp4xx/common-pci.c
@@ -316,6 +316,11 @@ static int abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *r
}
+static int ixp4xx_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size)
+{
+ return dev->bus == &pci_bus_type && (dma_addr + size) >= SZ_64M;
+}
+
/*
* Setup DMA mask to 64MB on PCI devices. Ignore all other devices.
*/
@@ -324,7 +329,7 @@ static int ixp4xx_pci_platform_notify(struct device *dev)
if(dev->bus == &pci_bus_type) {
*dev->dma_mask = SZ_64M - 1;
dev->coherent_dma_mask = SZ_64M - 1;
- dmabounce_register_dev(dev, 2048, 4096);
+ dmabounce_register_dev(dev, 2048, 4096, ixp4xx_needs_bounce);
}
return 0;
}
@@ -337,11 +342,6 @@ static int ixp4xx_pci_platform_notify_remove(struct device *dev)
return 0;
}
-int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size)
-{
- return (dev->bus == &pci_bus_type ) && ((dma_addr + size) >= SZ_64M);
-}
-
void __init ixp4xx_pci_preinit(void)
{
unsigned long cpuid = read_cpuid_id();
--
1.7.4.4
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 10/10] ARM: dmabounce: no need to check dev->bus type in needs_bounce function
2011-07-04 8:47 [PATCH 00/10] dmabounce cleanups Russell King - ARM Linux
` (8 preceding siblings ...)
2011-07-04 8:50 ` [PATCH 09/10] ARM: dmabounce: get rid of dma_needs_bounce global function Russell King - ARM Linux
@ 2011-07-04 8:50 ` Russell King - ARM Linux
9 siblings, 0 replies; 11+ messages in thread
From: Russell King - ARM Linux @ 2011-07-04 8:50 UTC (permalink / raw)
To: linux-arm-kernel
As the needs_bounce function is passed at DMA bounce register time,
we already know what the device bus type is, so we don't need to check
it each time the needs_bounce function is called.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/common/it8152.c | 3 +--
arch/arm/mach-ixp4xx/common-pci.c | 2 +-
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c
index 80b49e1..14ad62e 100644
--- a/arch/arm/common/it8152.c
+++ b/arch/arm/common/it8152.c
@@ -247,8 +247,7 @@ static int it8152_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t s
{
dev_dbg(dev, "%s: dma_addr %08x, size %08x\n",
__func__, dma_addr, size);
- return dev->bus == &pci_bus_type &&
- (dma_addr + size - PHYS_OFFSET) >= SZ_64M;
+ return (dma_addr + size - PHYS_OFFSET) >= SZ_64M;
}
/*
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c
index d7db10c..e2e98bb 100644
--- a/arch/arm/mach-ixp4xx/common-pci.c
+++ b/arch/arm/mach-ixp4xx/common-pci.c
@@ -318,7 +318,7 @@ static int abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *r
static int ixp4xx_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size)
{
- return dev->bus == &pci_bus_type && (dma_addr + size) >= SZ_64M;
+ return (dma_addr + size) >= SZ_64M;
}
/*
--
1.7.4.4
^ permalink raw reply related [flat|nested] 11+ messages in thread