diff options
Diffstat (limited to 'include/linux/ssb/ssb.h')
-rw-r--r-- | include/linux/ssb/ssb.h | 144 |
1 files changed, 140 insertions, 4 deletions
diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index 50dfd0dc4093..4bf8cade9dbc 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <linux/spinlock.h> | 7 | #include <linux/spinlock.h> |
8 | #include <linux/pci.h> | 8 | #include <linux/pci.h> |
9 | #include <linux/mod_devicetable.h> | 9 | #include <linux/mod_devicetable.h> |
10 | #include <linux/dma-mapping.h> | ||
10 | 11 | ||
11 | #include <linux/ssb/ssb_regs.h> | 12 | #include <linux/ssb/ssb_regs.h> |
12 | 13 | ||
@@ -137,9 +138,6 @@ struct ssb_device { | |||
137 | const struct ssb_bus_ops *ops; | 138 | const struct ssb_bus_ops *ops; |
138 | 139 | ||
139 | struct device *dev; | 140 | struct device *dev; |
140 | /* Pointer to the device that has to be used for | ||
141 | * any DMA related operation. */ | ||
142 | struct device *dma_dev; | ||
143 | 141 | ||
144 | struct ssb_bus *bus; | 142 | struct ssb_bus *bus; |
145 | struct ssb_device_id id; | 143 | struct ssb_device_id id; |
@@ -399,13 +397,151 @@ static inline void ssb_block_write(struct ssb_device *dev, const void *buffer, | |||
399 | #endif /* CONFIG_SSB_BLOCKIO */ | 397 | #endif /* CONFIG_SSB_BLOCKIO */ |
400 | 398 | ||
401 | 399 | ||
400 | /* The SSB DMA API. Use this API for any DMA operation on the device. | ||
401 | * This API basically is a wrapper that calls the correct DMA API for | ||
402 | * the host device type the SSB device is attached to. */ | ||
403 | |||
402 | /* Translation (routing) bits that need to be ORed to DMA | 404 | /* Translation (routing) bits that need to be ORed to DMA |
403 | * addresses before they are given to a device. */ | 405 | * addresses before they are given to a device. */ |
404 | extern u32 ssb_dma_translation(struct ssb_device *dev); | 406 | extern u32 ssb_dma_translation(struct ssb_device *dev); |
405 | #define SSB_DMA_TRANSLATION_MASK 0xC0000000 | 407 | #define SSB_DMA_TRANSLATION_MASK 0xC0000000 |
406 | #define SSB_DMA_TRANSLATION_SHIFT 30 | 408 | #define SSB_DMA_TRANSLATION_SHIFT 30 |
407 | 409 | ||
408 | extern int ssb_dma_set_mask(struct ssb_device *ssb_dev, u64 mask); | 410 | extern int ssb_dma_set_mask(struct ssb_device *dev, u64 mask); |
411 | |||
412 | extern void * ssb_dma_alloc_consistent(struct ssb_device *dev, size_t size, | ||
413 | dma_addr_t *dma_handle, gfp_t gfp_flags); | ||
414 | extern void ssb_dma_free_consistent(struct ssb_device *dev, size_t size, | ||
415 | void *vaddr, dma_addr_t dma_handle, | ||
416 | gfp_t gfp_flags); | ||
417 | |||
418 | static inline void __cold __ssb_dma_not_implemented(struct ssb_device *dev) | ||
419 | { | ||
420 | #ifdef CONFIG_SSB_DEBUG | ||
421 | printk(KERN_ERR "SSB: BUG! Calling DMA API for " | ||
422 | "unsupported bustype %d\n", dev->bus->bustype); | ||
423 | #endif /* DEBUG */ | ||
424 | } | ||
425 | |||
426 | static inline int ssb_dma_mapping_error(struct ssb_device *dev, dma_addr_t addr) | ||
427 | { | ||
428 | switch (dev->bus->bustype) { | ||
429 | case SSB_BUSTYPE_PCI: | ||
430 | return pci_dma_mapping_error(addr); | ||
431 | case SSB_BUSTYPE_SSB: | ||
432 | return dma_mapping_error(addr); | ||
433 | default: | ||
434 | __ssb_dma_not_implemented(dev); | ||
435 | } | ||
436 | return -ENOSYS; | ||
437 | } | ||
438 | |||
439 | static inline dma_addr_t ssb_dma_map_single(struct ssb_device *dev, void *p, | ||
440 | size_t size, enum dma_data_direction dir) | ||
441 | { | ||
442 | switch (dev->bus->bustype) { | ||
443 | case SSB_BUSTYPE_PCI: | ||
444 | return pci_map_single(dev->bus->host_pci, p, size, dir); | ||
445 | case SSB_BUSTYPE_SSB: | ||
446 | return dma_map_single(dev->dev, p, size, dir); | ||
447 | default: | ||
448 | __ssb_dma_not_implemented(dev); | ||
449 | } | ||
450 | return 0; | ||
451 | } | ||
452 | |||
453 | static inline void ssb_dma_unmap_single(struct ssb_device *dev, dma_addr_t dma_addr, | ||
454 | size_t size, enum dma_data_direction dir) | ||
455 | { | ||
456 | switch (dev->bus->bustype) { | ||
457 | case SSB_BUSTYPE_PCI: | ||
458 | pci_unmap_single(dev->bus->host_pci, dma_addr, size, dir); | ||
459 | return; | ||
460 | case SSB_BUSTYPE_SSB: | ||
461 | dma_unmap_single(dev->dev, dma_addr, size, dir); | ||
462 | return; | ||
463 | default: | ||
464 | __ssb_dma_not_implemented(dev); | ||
465 | } | ||
466 | } | ||
467 | |||
468 | static inline void ssb_dma_sync_single_for_cpu(struct ssb_device *dev, | ||
469 | dma_addr_t dma_addr, | ||
470 | size_t size, | ||
471 | enum dma_data_direction dir) | ||
472 | { | ||
473 | switch (dev->bus->bustype) { | ||
474 | case SSB_BUSTYPE_PCI: | ||
475 | pci_dma_sync_single_for_cpu(dev->bus->host_pci, dma_addr, | ||
476 | size, dir); | ||
477 | return; | ||
478 | case SSB_BUSTYPE_SSB: | ||
479 | dma_sync_single_for_cpu(dev->dev, dma_addr, size, dir); | ||
480 | return; | ||
481 | default: | ||
482 | __ssb_dma_not_implemented(dev); | ||
483 | } | ||
484 | } | ||
485 | |||
486 | static inline void ssb_dma_sync_single_for_device(struct ssb_device *dev, | ||
487 | dma_addr_t dma_addr, | ||
488 | size_t size, | ||
489 | enum dma_data_direction dir) | ||
490 | { | ||
491 | switch (dev->bus->bustype) { | ||
492 | case SSB_BUSTYPE_PCI: | ||
493 | pci_dma_sync_single_for_device(dev->bus->host_pci, dma_addr, | ||
494 | size, dir); | ||
495 | return; | ||
496 | case SSB_BUSTYPE_SSB: | ||
497 | dma_sync_single_for_device(dev->dev, dma_addr, size, dir); | ||
498 | return; | ||
499 | default: | ||
500 | __ssb_dma_not_implemented(dev); | ||
501 | } | ||
502 | } | ||
503 | |||
504 | static inline void ssb_dma_sync_single_range_for_cpu(struct ssb_device *dev, | ||
505 | dma_addr_t dma_addr, | ||
506 | unsigned long offset, | ||
507 | size_t size, | ||
508 | enum dma_data_direction dir) | ||
509 | { | ||
510 | switch (dev->bus->bustype) { | ||
511 | case SSB_BUSTYPE_PCI: | ||
512 | /* Just sync everything. That's all the PCI API can do. */ | ||
513 | pci_dma_sync_single_for_cpu(dev->bus->host_pci, dma_addr, | ||
514 | offset + size, dir); | ||
515 | return; | ||
516 | case SSB_BUSTYPE_SSB: | ||
517 | dma_sync_single_range_for_cpu(dev->dev, dma_addr, offset, | ||
518 | size, dir); | ||
519 | return; | ||
520 | default: | ||
521 | __ssb_dma_not_implemented(dev); | ||
522 | } | ||
523 | } | ||
524 | |||
525 | static inline void ssb_dma_sync_single_range_for_device(struct ssb_device *dev, | ||
526 | dma_addr_t dma_addr, | ||
527 | unsigned long offset, | ||
528 | size_t size, | ||
529 | enum dma_data_direction dir) | ||
530 | { | ||
531 | switch (dev->bus->bustype) { | ||
532 | case SSB_BUSTYPE_PCI: | ||
533 | /* Just sync everything. That's all the PCI API can do. */ | ||
534 | pci_dma_sync_single_for_device(dev->bus->host_pci, dma_addr, | ||
535 | offset + size, dir); | ||
536 | return; | ||
537 | case SSB_BUSTYPE_SSB: | ||
538 | dma_sync_single_range_for_device(dev->dev, dma_addr, offset, | ||
539 | size, dir); | ||
540 | return; | ||
541 | default: | ||
542 | __ssb_dma_not_implemented(dev); | ||
543 | } | ||
544 | } | ||
409 | 545 | ||
410 | 546 | ||
411 | #ifdef CONFIG_SSB_PCIHOST | 547 | #ifdef CONFIG_SSB_PCIHOST |