diff options
| author | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-01-03 06:29:28 -0500 |
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-01-06 17:31:11 -0500 |
| commit | 24056f525051a9e186af28904b396320e18bf9a0 (patch) | |
| tree | a8580f24820e21ad48333fce6b5f03be55edd561 /arch/arm/include/asm | |
| parent | 9eedd96301cad8ab58ee8c1e579677d0a75c2ba1 (diff) | |
ARM: DMA: add support for DMA debugging
Add ARM support for the DMA debug infrastructure, which allows the
DMA API usage to be debugged.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/include/asm')
| -rw-r--r-- | arch/arm/include/asm/dma-mapping.h | 65 |
1 files changed, 53 insertions, 12 deletions
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h index 8f69b98f68fc..4fff837363ed 100644 --- a/arch/arm/include/asm/dma-mapping.h +++ b/arch/arm/include/asm/dma-mapping.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | 5 | ||
| 6 | #include <linux/mm_types.h> | 6 | #include <linux/mm_types.h> |
| 7 | #include <linux/scatterlist.h> | 7 | #include <linux/scatterlist.h> |
| 8 | #include <linux/dma-debug.h> | ||
| 8 | 9 | ||
| 9 | #include <asm-generic/dma-coherent.h> | 10 | #include <asm-generic/dma-coherent.h> |
| 10 | #include <asm/memory.h> | 11 | #include <asm/memory.h> |
| @@ -297,13 +298,13 @@ extern int dma_needs_bounce(struct device*, dma_addr_t, size_t); | |||
| 297 | /* | 298 | /* |
| 298 | * The DMA API, implemented by dmabounce.c. See below for descriptions. | 299 | * The DMA API, implemented by dmabounce.c. See below for descriptions. |
| 299 | */ | 300 | */ |
| 300 | extern dma_addr_t dma_map_single(struct device *, void *, size_t, | 301 | extern dma_addr_t __dma_map_single(struct device *, void *, size_t, |
| 301 | enum dma_data_direction); | 302 | enum dma_data_direction); |
| 302 | extern void dma_unmap_single(struct device *, dma_addr_t, size_t, | 303 | extern void __dma_unmap_single(struct device *, dma_addr_t, size_t, |
| 303 | enum dma_data_direction); | 304 | enum dma_data_direction); |
| 304 | extern dma_addr_t dma_map_page(struct device *, struct page *, | 305 | extern dma_addr_t __dma_map_page(struct device *, struct page *, |
| 305 | unsigned long, size_t, enum dma_data_direction); | 306 | unsigned long, size_t, enum dma_data_direction); |
| 306 | extern void dma_unmap_page(struct device *, dma_addr_t, size_t, | 307 | extern void __dma_unmap_page(struct device *, dma_addr_t, size_t, |
| 307 | enum dma_data_direction); | 308 | enum dma_data_direction); |
| 308 | 309 | ||
| 309 | /* | 310 | /* |
| @@ -327,6 +328,34 @@ static inline int dmabounce_sync_for_device(struct device *d, dma_addr_t addr, | |||
| 327 | } | 328 | } |
| 328 | 329 | ||
| 329 | 330 | ||
| 331 | static inline dma_addr_t __dma_map_single(struct device *dev, void *cpu_addr, | ||
| 332 | size_t size, enum dma_data_direction dir) | ||
| 333 | { | ||
| 334 | __dma_single_cpu_to_dev(cpu_addr, size, dir); | ||
| 335 | return virt_to_dma(dev, cpu_addr); | ||
| 336 | } | ||
| 337 | |||
| 338 | static inline dma_addr_t __dma_map_page(struct device *dev, struct page *page, | ||
| 339 | unsigned long offset, size_t size, enum dma_data_direction dir) | ||
| 340 | { | ||
| 341 | __dma_page_cpu_to_dev(page, offset, size, dir); | ||
| 342 | return pfn_to_dma(dev, page_to_pfn(page)) + offset; | ||
| 343 | } | ||
| 344 | |||
| 345 | static inline void __dma_unmap_single(struct device *dev, dma_addr_t handle, | ||
| 346 | size_t size, enum dma_data_direction dir) | ||
| 347 | { | ||
| 348 | __dma_single_dev_to_cpu(dma_to_virt(dev, handle), size, dir); | ||
| 349 | } | ||
| 350 | |||
| 351 | static inline void __dma_unmap_page(struct device *dev, dma_addr_t handle, | ||
| 352 | size_t size, enum dma_data_direction dir) | ||
| 353 | { | ||
| 354 | __dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, handle)), | ||
| 355 | handle & ~PAGE_MASK, size, dir); | ||
| 356 | } | ||
| 357 | #endif /* CONFIG_DMABOUNCE */ | ||
| 358 | |||
| 330 | /** | 359 | /** |
| 331 | * dma_map_single - map a single buffer for streaming DMA | 360 | * dma_map_single - map a single buffer for streaming DMA |
| 332 | * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices | 361 | * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices |
| @@ -344,11 +373,16 @@ static inline int dmabounce_sync_for_device(struct device *d, dma_addr_t addr, | |||
| 344 | static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, | 373 | static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, |
| 345 | size_t size, enum dma_data_direction dir) | 374 | size_t size, enum dma_data_direction dir) |
| 346 | { | 375 | { |
| 376 | dma_addr_t addr; | ||
| 377 | |||
| 347 | BUG_ON(!valid_dma_direction(dir)); | 378 | BUG_ON(!valid_dma_direction(dir)); |
| 348 | 379 | ||
| 349 | __dma_single_cpu_to_dev(cpu_addr, size, dir); | 380 | addr = __dma_map_single(dev, cpu_addr, size, dir); |
| 381 | debug_dma_map_page(dev, virt_to_page(cpu_addr), | ||
| 382 | (unsigned long)cpu_addr & ~PAGE_MASK, size, | ||
| 383 | dir, addr, true); | ||
| 350 | 384 | ||
| 351 | return virt_to_dma(dev, cpu_addr); | 385 | return addr; |
| 352 | } | 386 | } |
| 353 | 387 | ||
| 354 | /** | 388 | /** |
| @@ -368,11 +402,14 @@ static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, | |||
| 368 | static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, | 402 | static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, |
| 369 | unsigned long offset, size_t size, enum dma_data_direction dir) | 403 | unsigned long offset, size_t size, enum dma_data_direction dir) |
| 370 | { | 404 | { |
| 405 | dma_addr_t addr; | ||
| 406 | |||
| 371 | BUG_ON(!valid_dma_direction(dir)); | 407 | BUG_ON(!valid_dma_direction(dir)); |
| 372 | 408 | ||
| 373 | __dma_page_cpu_to_dev(page, offset, size, dir); | 409 | addr = __dma_map_page(dev, page, offset, size, dir); |
| 410 | debug_dma_map_page(dev, page, offset, size, dir, addr, false); | ||
| 374 | 411 | ||
| 375 | return pfn_to_dma(dev, page_to_pfn(page)) + offset; | 412 | return addr; |
| 376 | } | 413 | } |
| 377 | 414 | ||
| 378 | /** | 415 | /** |
| @@ -392,7 +429,8 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, | |||
| 392 | static inline void dma_unmap_single(struct device *dev, dma_addr_t handle, | 429 | static inline void dma_unmap_single(struct device *dev, dma_addr_t handle, |
| 393 | size_t size, enum dma_data_direction dir) | 430 | size_t size, enum dma_data_direction dir) |
| 394 | { | 431 | { |
| 395 | __dma_single_dev_to_cpu(dma_to_virt(dev, handle), size, dir); | 432 | debug_dma_unmap_page(dev, handle, size, dir, true); |
| 433 | __dma_unmap_single(dev, handle, size, dir); | ||
| 396 | } | 434 | } |
| 397 | 435 | ||
| 398 | /** | 436 | /** |
| @@ -412,10 +450,9 @@ static inline void dma_unmap_single(struct device *dev, dma_addr_t handle, | |||
| 412 | static inline void dma_unmap_page(struct device *dev, dma_addr_t handle, | 450 | static inline void dma_unmap_page(struct device *dev, dma_addr_t handle, |
| 413 | size_t size, enum dma_data_direction dir) | 451 | size_t size, enum dma_data_direction dir) |
| 414 | { | 452 | { |
| 415 | __dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, handle)), | 453 | debug_dma_unmap_page(dev, handle, size, dir, false); |
| 416 | handle & ~PAGE_MASK, size, dir); | 454 | __dma_unmap_page(dev, handle, size, dir); |
| 417 | } | 455 | } |
| 418 | #endif /* CONFIG_DMABOUNCE */ | ||
| 419 | 456 | ||
| 420 | /** | 457 | /** |
| 421 | * dma_sync_single_range_for_cpu | 458 | * dma_sync_single_range_for_cpu |
| @@ -441,6 +478,8 @@ static inline void dma_sync_single_range_for_cpu(struct device *dev, | |||
| 441 | { | 478 | { |
| 442 | BUG_ON(!valid_dma_direction(dir)); | 479 | BUG_ON(!valid_dma_direction(dir)); |
| 443 | 480 | ||
| 481 | debug_dma_sync_single_for_cpu(dev, handle + offset, size, dir); | ||
| 482 | |||
| 444 | if (!dmabounce_sync_for_cpu(dev, handle, offset, size, dir)) | 483 | if (!dmabounce_sync_for_cpu(dev, handle, offset, size, dir)) |
| 445 | return; | 484 | return; |
| 446 | 485 | ||
| @@ -453,6 +492,8 @@ static inline void dma_sync_single_range_for_device(struct device *dev, | |||
| 453 | { | 492 | { |
| 454 | BUG_ON(!valid_dma_direction(dir)); | 493 | BUG_ON(!valid_dma_direction(dir)); |
| 455 | 494 | ||
| 495 | debug_dma_sync_single_for_device(dev, handle + offset, size, dir); | ||
| 496 | |||
| 456 | if (!dmabounce_sync_for_device(dev, handle, offset, size, dir)) | 497 | if (!dmabounce_sync_for_device(dev, handle, offset, size, dir)) |
| 457 | return; | 498 | return; |
| 458 | 499 | ||
