diff options
| author | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-07-03 17:28:32 -0400 |
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-07-03 18:27:49 -0400 |
| commit | 23bc9873ba60ee661d8e9f3a6b22fc3bcc4b7015 (patch) | |
| tree | 74419df7fa856a7b261ea1914810b21c281e4fa0 | |
| parent | 71695dd8b9eacfcda1b548a5b1780d34213ad654 (diff) | |
ARM: dmabounce: separate out decision to bounce
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>
| -rw-r--r-- | 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 3e0fa1548582..643e1d660677 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, | |||
| 219 | return find_safe_buffer(dev->archdata.dmabounce, dma_addr); | 219 | return find_safe_buffer(dev->archdata.dmabounce, dma_addr); |
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | static inline dma_addr_t map_single(struct device *dev, void *ptr, size_t size, | 222 | static int needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size) |
| 223 | enum dma_data_direction dir) | ||
| 224 | { | 223 | { |
| 225 | struct dmabounce_device_info *device_info = dev->archdata.dmabounce; | 224 | if (!dev || !dev->archdata.dmabounce) |
| 226 | dma_addr_t dma_addr; | 225 | return 0; |
| 227 | int needs_bounce = 0; | ||
| 228 | |||
| 229 | if (device_info) | ||
| 230 | DO_STATS ( device_info->map_op_count++ ); | ||
| 231 | |||
| 232 | dma_addr = virt_to_dma(dev, ptr); | ||
| 233 | 226 | ||
| 234 | if (dev->dma_mask) { | 227 | if (dev->dma_mask) { |
| 235 | unsigned long mask = *dev->dma_mask; | 228 | unsigned long limit, mask = *dev->dma_mask; |
| 236 | unsigned long limit; | ||
| 237 | 229 | ||
| 238 | limit = (mask + 1) & ~mask; | 230 | limit = (mask + 1) & ~mask; |
| 239 | if (limit && size > limit) { | 231 | if (limit && size > limit) { |
| 240 | dev_err(dev, "DMA mapping too big (requested %#x " | 232 | dev_err(dev, "DMA mapping too big (requested %#x " |
| 241 | "mask %#Lx)\n", size, *dev->dma_mask); | 233 | "mask %#Lx)\n", size, *dev->dma_mask); |
| 242 | return ~0; | 234 | return -E2BIG; |
| 243 | } | 235 | } |
| 244 | 236 | ||
| 245 | /* | 237 | /* Figure out if we need to bounce from the DMA mask. */ |
| 246 | * Figure out if we need to bounce from the DMA mask. | 238 | if ((dma_addr | (dma_addr + size - 1)) & ~mask) |
| 247 | */ | 239 | return 1; |
| 248 | needs_bounce = (dma_addr | (dma_addr + size - 1)) & ~mask; | ||
| 249 | } | 240 | } |
| 250 | 241 | ||
| 251 | if (device_info && (needs_bounce || dma_needs_bounce(dev, dma_addr, size))) { | 242 | return dma_needs_bounce(dev, dma_addr, size) ? 1 : 0; |
| 243 | } | ||
| 244 | |||
| 245 | static inline dma_addr_t map_single(struct device *dev, void *ptr, size_t size, | ||
| 246 | enum dma_data_direction dir) | ||
| 247 | { | ||
| 248 | struct dmabounce_device_info *device_info = dev->archdata.dmabounce; | ||
| 249 | dma_addr_t dma_addr; | ||
| 250 | int ret; | ||
| 251 | |||
| 252 | if (device_info) | ||
| 253 | DO_STATS ( device_info->map_op_count++ ); | ||
| 254 | |||
| 255 | dma_addr = virt_to_dma(dev, ptr); | ||
| 256 | |||
| 257 | ret = needs_bounce(dev, dma_addr, size); | ||
| 258 | if (ret < 0) | ||
| 259 | return ~0; | ||
| 260 | |||
| 261 | if (ret > 0) { | ||
| 252 | struct safe_buffer *buf; | 262 | struct safe_buffer *buf; |
| 253 | 263 | ||
| 254 | buf = alloc_safe_buffer(device_info, ptr, size, dir); | 264 | buf = alloc_safe_buffer(device_info, ptr, size, dir); |
