diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-07-04 03:32:21 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-07-04 03:39:55 -0400 |
commit | 0703ed2a6b260cd743adf49a8281eb064d728832 (patch) | |
tree | 95740f9e1beb8901f163c7168b3e2666eb2158c9 | |
parent | c289b2e0ccff1142908e20398930dc2e14697e74 (diff) |
ARM: dmabounce: get rid of dma_needs_bounce global function
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>
-rw-r--r-- | arch/arm/common/dmabounce.c | 8 | ||||
-rw-r--r-- | arch/arm/common/it8152.c | 17 | ||||
-rw-r--r-- | arch/arm/common/sa1111.c | 60 | ||||
-rw-r--r-- | arch/arm/include/asm/dma-mapping.h | 22 | ||||
-rw-r--r-- | 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 4f13505ac936..595ecd290ebf 100644 --- a/arch/arm/common/dmabounce.c +++ b/arch/arm/common/dmabounce.c | |||
@@ -79,6 +79,8 @@ struct dmabounce_device_info { | |||
79 | struct dmabounce_pool large; | 79 | struct dmabounce_pool large; |
80 | 80 | ||
81 | rwlock_t lock; | 81 | rwlock_t lock; |
82 | |||
83 | int (*needs_bounce)(struct device *, dma_addr_t, size_t); | ||
82 | }; | 84 | }; |
83 | 85 | ||
84 | #ifdef STATS | 86 | #ifdef STATS |
@@ -236,7 +238,7 @@ static int needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size) | |||
236 | return 1; | 238 | return 1; |
237 | } | 239 | } |
238 | 240 | ||
239 | return dma_needs_bounce(dev, dma_addr, size) ? 1 : 0; | 241 | return !!dev->archdata.dmabounce->needs_bounce(dev, dma_addr, size); |
240 | } | 242 | } |
241 | 243 | ||
242 | static inline dma_addr_t map_single(struct device *dev, void *ptr, size_t size, | 244 | 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, | |||
430 | } | 432 | } |
431 | 433 | ||
432 | int dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size, | 434 | int dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size, |
433 | unsigned long large_buffer_size) | 435 | unsigned long large_buffer_size, |
436 | int (*needs_bounce_fn)(struct device *, dma_addr_t, size_t)) | ||
434 | { | 437 | { |
435 | struct dmabounce_device_info *device_info; | 438 | struct dmabounce_device_info *device_info; |
436 | int ret; | 439 | int ret; |
@@ -466,6 +469,7 @@ int dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size, | |||
466 | device_info->dev = dev; | 469 | device_info->dev = dev; |
467 | INIT_LIST_HEAD(&device_info->safe_buffers); | 470 | INIT_LIST_HEAD(&device_info->safe_buffers); |
468 | rwlock_init(&device_info->lock); | 471 | rwlock_init(&device_info->lock); |
472 | device_info->needs_bounce = needs_bounce_fn; | ||
469 | 473 | ||
470 | #ifdef STATS | 474 | #ifdef STATS |
471 | device_info->total_allocs = 0; | 475 | device_info->total_allocs = 0; |
diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c index 7a21927c52e1..80b49e1e0992 100644 --- a/arch/arm/common/it8152.c +++ b/arch/arm/common/it8152.c | |||
@@ -243,6 +243,13 @@ static struct resource it8152_mem = { | |||
243 | * ITE8152 chip can address up to 64MByte, so all the devices | 243 | * ITE8152 chip can address up to 64MByte, so all the devices |
244 | * connected to ITE8152 (PCI and USB) should have limited DMA window | 244 | * connected to ITE8152 (PCI and USB) should have limited DMA window |
245 | */ | 245 | */ |
246 | static int it8152_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size) | ||
247 | { | ||
248 | dev_dbg(dev, "%s: dma_addr %08x, size %08x\n", | ||
249 | __func__, dma_addr, size); | ||
250 | return dev->bus == &pci_bus_type && | ||
251 | (dma_addr + size - PHYS_OFFSET) >= SZ_64M; | ||
252 | } | ||
246 | 253 | ||
247 | /* | 254 | /* |
248 | * Setup DMA mask to 64MB on devices connected to ITE8152. Ignore all | 255 | * 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) | |||
254 | if (dev->dma_mask) | 261 | if (dev->dma_mask) |
255 | *dev->dma_mask = (SZ_64M - 1) | PHYS_OFFSET; | 262 | *dev->dma_mask = (SZ_64M - 1) | PHYS_OFFSET; |
256 | dev->coherent_dma_mask = (SZ_64M - 1) | PHYS_OFFSET; | 263 | dev->coherent_dma_mask = (SZ_64M - 1) | PHYS_OFFSET; |
257 | dmabounce_register_dev(dev, 2048, 4096); | 264 | dmabounce_register_dev(dev, 2048, 4096, it8152_needs_bounce); |
258 | } | 265 | } |
259 | return 0; | 266 | return 0; |
260 | } | 267 | } |
@@ -267,14 +274,6 @@ static int it8152_pci_platform_notify_remove(struct device *dev) | |||
267 | return 0; | 274 | return 0; |
268 | } | 275 | } |
269 | 276 | ||
270 | int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size) | ||
271 | { | ||
272 | dev_dbg(dev, "%s: dma_addr %08x, size %08x\n", | ||
273 | __func__, dma_addr, size); | ||
274 | return (dev->bus == &pci_bus_type) && | ||
275 | ((dma_addr + size - PHYS_OFFSET) >= SZ_64M); | ||
276 | } | ||
277 | |||
278 | int dma_set_coherent_mask(struct device *dev, u64 mask) | 277 | int dma_set_coherent_mask(struct device *dev, u64 mask) |
279 | { | 278 | { |
280 | if (mask >= PHYS_OFFSET + SZ_64M - 1) | 279 | if (mask >= PHYS_OFFSET + SZ_64M - 1) |
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 9c49a46a2b7a..0569de6acfba 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, | |||
579 | 579 | ||
580 | sachip->dev->coherent_dma_mask &= sa1111_dma_mask[drac >> 2]; | 580 | sachip->dev->coherent_dma_mask &= sa1111_dma_mask[drac >> 2]; |
581 | } | 581 | } |
582 | #endif | ||
582 | 583 | ||
584 | #ifdef CONFIG_DMABOUNCE | ||
585 | /* | ||
586 | * According to the "Intel StrongARM SA-1111 Microprocessor Companion | ||
587 | * Chip Specification Update" (June 2000), erratum #7, there is a | ||
588 | * significant bug in the SA1111 SDRAM shared memory controller. If | ||
589 | * an access to a region of memory above 1MB relative to the bank base, | ||
590 | * it is important that address bit 10 _NOT_ be asserted. Depending | ||
591 | * on the configuration of the RAM, bit 10 may correspond to one | ||
592 | * of several different (processor-relative) address bits. | ||
593 | * | ||
594 | * This routine only identifies whether or not a given DMA address | ||
595 | * is susceptible to the bug. | ||
596 | * | ||
597 | * This should only get called for sa1111_device types due to the | ||
598 | * way we configure our device dma_masks. | ||
599 | */ | ||
600 | static int sa1111_needs_bounce(struct device *dev, dma_addr_t addr, size_t size) | ||
601 | { | ||
602 | /* | ||
603 | * Section 4.6 of the "Intel StrongARM SA-1111 Development Module | ||
604 | * User's Guide" mentions that jumpers R51 and R52 control the | ||
605 | * target of SA-1111 DMA (either SDRAM bank 0 on Assabet, or | ||
606 | * SDRAM bank 1 on Neponset). The default configuration selects | ||
607 | * Assabet, so any address in bank 1 is necessarily invalid. | ||
608 | */ | ||
609 | return (machine_is_assabet() || machine_is_pfs168()) && | ||
610 | (addr >= 0xc8000000 || (addr + size) >= 0xc8000000); | ||
611 | } | ||
583 | #endif | 612 | #endif |
584 | 613 | ||
585 | static void sa1111_dev_release(struct device *_dev) | 614 | static void sa1111_dev_release(struct device *_dev) |
@@ -644,7 +673,8 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent, | |||
644 | dev->dev.dma_mask = &dev->dma_mask; | 673 | dev->dev.dma_mask = &dev->dma_mask; |
645 | 674 | ||
646 | if (dev->dma_mask != 0xffffffffUL) { | 675 | if (dev->dma_mask != 0xffffffffUL) { |
647 | ret = dmabounce_register_dev(&dev->dev, 1024, 4096); | 676 | ret = dmabounce_register_dev(&dev->dev, 1024, 4096, |
677 | sa1111_needs_bounce); | ||
648 | if (ret) { | 678 | if (ret) { |
649 | dev_err(&dev->dev, "SA1111: Failed to register" | 679 | dev_err(&dev->dev, "SA1111: Failed to register" |
650 | " with dmabounce\n"); | 680 | " with dmabounce\n"); |
@@ -818,34 +848,6 @@ static void __sa1111_remove(struct sa1111 *sachip) | |||
818 | kfree(sachip); | 848 | kfree(sachip); |
819 | } | 849 | } |
820 | 850 | ||
821 | /* | ||
822 | * According to the "Intel StrongARM SA-1111 Microprocessor Companion | ||
823 | * Chip Specification Update" (June 2000), erratum #7, there is a | ||
824 | * significant bug in the SA1111 SDRAM shared memory controller. If | ||
825 | * an access to a region of memory above 1MB relative to the bank base, | ||
826 | * it is important that address bit 10 _NOT_ be asserted. Depending | ||
827 | * on the configuration of the RAM, bit 10 may correspond to one | ||
828 | * of several different (processor-relative) address bits. | ||
829 | * | ||
830 | * This routine only identifies whether or not a given DMA address | ||
831 | * is susceptible to the bug. | ||
832 | * | ||
833 | * This should only get called for sa1111_device types due to the | ||
834 | * way we configure our device dma_masks. | ||
835 | */ | ||
836 | int dma_needs_bounce(struct device *dev, dma_addr_t addr, size_t size) | ||
837 | { | ||
838 | /* | ||
839 | * Section 4.6 of the "Intel StrongARM SA-1111 Development Module | ||
840 | * User's Guide" mentions that jumpers R51 and R52 control the | ||
841 | * target of SA-1111 DMA (either SDRAM bank 0 on Assabet, or | ||
842 | * SDRAM bank 1 on Neponset). The default configuration selects | ||
843 | * Assabet, so any address in bank 1 is necessarily invalid. | ||
844 | */ | ||
845 | return ((machine_is_assabet() || machine_is_pfs168()) && | ||
846 | (addr >= 0xc8000000 || (addr + size) >= 0xc8000000)); | ||
847 | } | ||
848 | |||
849 | struct sa1111_save_data { | 851 | struct sa1111_save_data { |
850 | unsigned int skcr; | 852 | unsigned int skcr; |
851 | unsigned int skpcr; | 853 | unsigned int skpcr; |
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h index d2903d0c3085..4ad25337f927 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 *, | |||
256 | * @dev: valid struct device pointer | 256 | * @dev: valid struct device pointer |
257 | * @small_buf_size: size of buffers to use with small buffer pool | 257 | * @small_buf_size: size of buffers to use with small buffer pool |
258 | * @large_buf_size: size of buffers to use with large buffer pool (can be 0) | 258 | * @large_buf_size: size of buffers to use with large buffer pool (can be 0) |
259 | * @needs_bounce_fn: called to determine whether buffer needs bouncing | ||
259 | * | 260 | * |
260 | * This function should be called by low-level platform code to register | 261 | * This function should be called by low-level platform code to register |
261 | * a device as requireing DMA buffer bouncing. The function will allocate | 262 | * a device as requireing DMA buffer bouncing. The function will allocate |
262 | * appropriate DMA pools for the device. | 263 | * appropriate DMA pools for the device. |
263 | * | ||
264 | */ | 264 | */ |
265 | extern int dmabounce_register_dev(struct device *, unsigned long, | 265 | extern int dmabounce_register_dev(struct device *, unsigned long, |
266 | unsigned long); | 266 | unsigned long, int (*)(struct device *, dma_addr_t, size_t)); |
267 | 267 | ||
268 | /** | 268 | /** |
269 | * dmabounce_unregister_dev | 269 | * dmabounce_unregister_dev |
@@ -277,24 +277,6 @@ extern int dmabounce_register_dev(struct device *, unsigned long, | |||
277 | */ | 277 | */ |
278 | extern void dmabounce_unregister_dev(struct device *); | 278 | extern void dmabounce_unregister_dev(struct device *); |
279 | 279 | ||
280 | /** | ||
281 | * dma_needs_bounce | ||
282 | * | ||
283 | * @dev: valid struct device pointer | ||
284 | * @dma_handle: dma_handle of unbounced buffer | ||
285 | * @size: size of region being mapped | ||
286 | * | ||
287 | * Platforms that utilize the dmabounce mechanism must implement | ||
288 | * this function. | ||
289 | * | ||
290 | * The dmabounce routines call this function whenever a dma-mapping | ||
291 | * is requested to determine whether a given buffer needs to be bounced | ||
292 | * or not. The function must return 0 if the buffer is OK for | ||
293 | * DMA access and 1 if the buffer needs to be bounced. | ||
294 | * | ||
295 | */ | ||
296 | extern int dma_needs_bounce(struct device*, dma_addr_t, size_t); | ||
297 | |||
298 | /* | 280 | /* |
299 | * The DMA API, implemented by dmabounce.c. See below for descriptions. | 281 | * The DMA API, implemented by dmabounce.c. See below for descriptions. |
300 | */ | 282 | */ |
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index e9a589395723..d7db10cfe53d 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 | |||
316 | } | 316 | } |
317 | 317 | ||
318 | 318 | ||
319 | static int ixp4xx_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size) | ||
320 | { | ||
321 | return dev->bus == &pci_bus_type && (dma_addr + size) >= SZ_64M; | ||
322 | } | ||
323 | |||
319 | /* | 324 | /* |
320 | * Setup DMA mask to 64MB on PCI devices. Ignore all other devices. | 325 | * Setup DMA mask to 64MB on PCI devices. Ignore all other devices. |
321 | */ | 326 | */ |
@@ -324,7 +329,7 @@ static int ixp4xx_pci_platform_notify(struct device *dev) | |||
324 | if(dev->bus == &pci_bus_type) { | 329 | if(dev->bus == &pci_bus_type) { |
325 | *dev->dma_mask = SZ_64M - 1; | 330 | *dev->dma_mask = SZ_64M - 1; |
326 | dev->coherent_dma_mask = SZ_64M - 1; | 331 | dev->coherent_dma_mask = SZ_64M - 1; |
327 | dmabounce_register_dev(dev, 2048, 4096); | 332 | dmabounce_register_dev(dev, 2048, 4096, ixp4xx_needs_bounce); |
328 | } | 333 | } |
329 | return 0; | 334 | return 0; |
330 | } | 335 | } |
@@ -337,11 +342,6 @@ static int ixp4xx_pci_platform_notify_remove(struct device *dev) | |||
337 | return 0; | 342 | return 0; |
338 | } | 343 | } |
339 | 344 | ||
340 | int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size) | ||
341 | { | ||
342 | return (dev->bus == &pci_bus_type ) && ((dma_addr + size) >= SZ_64M); | ||
343 | } | ||
344 | |||
345 | void __init ixp4xx_pci_preinit(void) | 345 | void __init ixp4xx_pci_preinit(void) |
346 | { | 346 | { |
347 | unsigned long cpuid = read_cpuid_id(); | 347 | unsigned long cpuid = read_cpuid_id(); |