diff options
author | Maxime Ripard <maxime.ripard@free-electrons.com> | 2014-11-17 08:42:04 -0500 |
---|---|---|
committer | Vinod Koul <vinod.koul@intel.com> | 2014-12-22 01:58:56 -0500 |
commit | cb8cea513c80db1dfe2dce468d2d0772005bb9a1 (patch) | |
tree | 44dcb2103f8b2023d0c6b1bab113bfeacdfd5165 /include/linux/dmaengine.h | |
parent | 4f8ef9f4140cc286d7d1cf9237da7a7439e4fc0b (diff) |
dmaengine: Create a generic dma_slave_caps callback
dma_slave_caps is very important to the generic layers that might interact with
dmaengine, such as ASoC. Unfortunately, it has been added as yet another
dma_device callback, and most of the existing drivers haven't implemented it,
reducing its reliability.
Introduce a generic behaviour to implement this, that rely on both the split of
device_control to derive which functions are supported and on new variables to
be set in the dma_device structure.
These variables holds what used to be the capabilities, that were set
per-channel. However, this proved to be a bit overkill, since every driver
filling these so far were hardcoding it, disregarding which channel was
actually given.
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'include/linux/dmaengine.h')
-rw-r--r-- | include/linux/dmaengine.h | 41 |
1 files changed, 37 insertions, 4 deletions
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index ded5161653aa..adf22089cc93 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h | |||
@@ -594,6 +594,14 @@ struct dma_tx_state { | |||
594 | * @fill_align: alignment shift for memset operations | 594 | * @fill_align: alignment shift for memset operations |
595 | * @dev_id: unique device ID | 595 | * @dev_id: unique device ID |
596 | * @dev: struct device reference for dma mapping api | 596 | * @dev: struct device reference for dma mapping api |
597 | * @src_addr_widths: bit mask of src addr widths the device supports | ||
598 | * @dst_addr_widths: bit mask of dst addr widths the device supports | ||
599 | * @directions: bit mask of slave direction the device supports since | ||
600 | * the enum dma_transfer_direction is not defined as bits for | ||
601 | * each type of direction, the dma controller should fill (1 << | ||
602 | * <TYPE>) and same should be checked by controller as well | ||
603 | * @residue_granularity: granularity of the transfer residue reported | ||
604 | * by tx_status | ||
597 | * @device_alloc_chan_resources: allocate resources and return the | 605 | * @device_alloc_chan_resources: allocate resources and return the |
598 | * number of allocated descriptors | 606 | * number of allocated descriptors |
599 | * @device_free_chan_resources: release DMA channel's resources | 607 | * @device_free_chan_resources: release DMA channel's resources |
@@ -643,6 +651,11 @@ struct dma_device { | |||
643 | int dev_id; | 651 | int dev_id; |
644 | struct device *dev; | 652 | struct device *dev; |
645 | 653 | ||
654 | u32 src_addr_widths; | ||
655 | u32 dst_addr_widths; | ||
656 | u32 directions; | ||
657 | enum dma_residue_granularity residue_granularity; | ||
658 | |||
646 | int (*device_alloc_chan_resources)(struct dma_chan *chan); | 659 | int (*device_alloc_chan_resources)(struct dma_chan *chan); |
647 | void (*device_free_chan_resources)(struct dma_chan *chan); | 660 | void (*device_free_chan_resources)(struct dma_chan *chan); |
648 | 661 | ||
@@ -784,17 +797,37 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_dma_sg( | |||
784 | 797 | ||
785 | static inline int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps) | 798 | static inline int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps) |
786 | { | 799 | { |
800 | struct dma_device *device; | ||
801 | |||
787 | if (!chan || !caps) | 802 | if (!chan || !caps) |
788 | return -EINVAL; | 803 | return -EINVAL; |
789 | 804 | ||
805 | device = chan->device; | ||
806 | |||
790 | /* check if the channel supports slave transactions */ | 807 | /* check if the channel supports slave transactions */ |
791 | if (!test_bit(DMA_SLAVE, chan->device->cap_mask.bits)) | 808 | if (!test_bit(DMA_SLAVE, device->cap_mask.bits)) |
809 | return -ENXIO; | ||
810 | |||
811 | if (device->device_slave_caps) | ||
812 | return device->device_slave_caps(chan, caps); | ||
813 | |||
814 | /* | ||
815 | * Check whether it reports it uses the generic slave | ||
816 | * capabilities, if not, that means it doesn't support any | ||
817 | * kind of slave capabilities reporting. | ||
818 | */ | ||
819 | if (!device->directions) | ||
792 | return -ENXIO; | 820 | return -ENXIO; |
793 | 821 | ||
794 | if (chan->device->device_slave_caps) | 822 | caps->src_addr_widths = device->src_addr_widths; |
795 | return chan->device->device_slave_caps(chan, caps); | 823 | caps->dst_addr_widths = device->dst_addr_widths; |
824 | caps->directions = device->directions; | ||
825 | caps->residue_granularity = device->residue_granularity; | ||
826 | |||
827 | caps->cmd_pause = !!device->device_pause; | ||
828 | caps->cmd_terminate = !!device->device_terminate_all; | ||
796 | 829 | ||
797 | return -ENXIO; | 830 | return 0; |
798 | } | 831 | } |
799 | 832 | ||
800 | static inline int dmaengine_terminate_all(struct dma_chan *chan) | 833 | static inline int dmaengine_terminate_all(struct dma_chan *chan) |