aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/ssb/ssb.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/ssb/ssb.h')
-rw-r--r--include/linux/ssb/ssb.h144
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. */
404extern u32 ssb_dma_translation(struct ssb_device *dev); 406extern 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
408extern int ssb_dma_set_mask(struct ssb_device *ssb_dev, u64 mask); 410extern int ssb_dma_set_mask(struct ssb_device *dev, u64 mask);
411
412extern void * ssb_dma_alloc_consistent(struct ssb_device *dev, size_t size,
413 dma_addr_t *dma_handle, gfp_t gfp_flags);
414extern 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
418static 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
426static 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
439static 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
453static 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
468static 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
486static 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
504static 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
525static 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