diff options
author | Vinod Koul <vinod.koul@intel.com> | 2013-09-02 08:10:40 -0400 |
---|---|---|
committer | Vinod Koul <vinod.koul@intel.com> | 2013-09-02 08:10:40 -0400 |
commit | 355cdafe14d72c616dc804a756f3af4f4df4fe8c (patch) | |
tree | 592ef60b65da9a539daa84f5d1cf52cf483b362b | |
parent | 4770ee44359ad454992d544cf14f8d330a93f5ca (diff) | |
parent | ca38ff133eb85b64e62b508a7726ea0247edd359 (diff) |
Merge branch 'topic/api_caps' into for-linus
-rw-r--r-- | drivers/dma/pl330.c | 27 | ||||
-rw-r--r-- | include/linux/dmaengine.h | 44 |
2 files changed, 71 insertions, 0 deletions
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index cfd2d703fcb5..36ed30116ee0 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c | |||
@@ -2870,6 +2870,32 @@ static irqreturn_t pl330_irq_handler(int irq, void *data) | |||
2870 | return IRQ_NONE; | 2870 | return IRQ_NONE; |
2871 | } | 2871 | } |
2872 | 2872 | ||
2873 | #define PL330_DMA_BUSWIDTHS \ | ||
2874 | BIT(DMA_SLAVE_BUSWIDTH_UNDEFINED) | \ | ||
2875 | BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \ | ||
2876 | BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \ | ||
2877 | BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | \ | ||
2878 | BIT(DMA_SLAVE_BUSWIDTH_8_BYTES) | ||
2879 | |||
2880 | static int pl330_dma_device_slave_caps(struct dma_chan *dchan, | ||
2881 | struct dma_slave_caps *caps) | ||
2882 | { | ||
2883 | caps->src_addr_widths = PL330_DMA_BUSWIDTHS; | ||
2884 | caps->dstn_addr_widths = PL330_DMA_BUSWIDTHS; | ||
2885 | caps->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); | ||
2886 | caps->cmd_pause = false; | ||
2887 | caps->cmd_terminate = true; | ||
2888 | |||
2889 | /* | ||
2890 | * This is the limit for transfers with a buswidth of 1, larger | ||
2891 | * buswidths will have larger limits. | ||
2892 | */ | ||
2893 | caps->max_sg_len = 1900800; | ||
2894 | caps->max_sg_nr = 0; | ||
2895 | |||
2896 | return 0; | ||
2897 | } | ||
2898 | |||
2873 | static int | 2899 | static int |
2874 | pl330_probe(struct amba_device *adev, const struct amba_id *id) | 2900 | pl330_probe(struct amba_device *adev, const struct amba_id *id) |
2875 | { | 2901 | { |
@@ -2975,6 +3001,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) | |||
2975 | pd->device_prep_slave_sg = pl330_prep_slave_sg; | 3001 | pd->device_prep_slave_sg = pl330_prep_slave_sg; |
2976 | pd->device_control = pl330_control; | 3002 | pd->device_control = pl330_control; |
2977 | pd->device_issue_pending = pl330_issue_pending; | 3003 | pd->device_issue_pending = pl330_issue_pending; |
3004 | pd->device_slave_caps = pl330_dma_device_slave_caps; | ||
2978 | 3005 | ||
2979 | ret = dma_async_device_register(pd); | 3006 | ret = dma_async_device_register(pd); |
2980 | if (ret) { | 3007 | if (ret) { |
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index c271608e862e..13ac4f553227 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h | |||
@@ -370,6 +370,33 @@ struct dma_slave_config { | |||
370 | unsigned int slave_id; | 370 | unsigned int slave_id; |
371 | }; | 371 | }; |
372 | 372 | ||
373 | /* struct dma_slave_caps - expose capabilities of a slave channel only | ||
374 | * | ||
375 | * @src_addr_widths: bit mask of src addr widths the channel supports | ||
376 | * @dstn_addr_widths: bit mask of dstn addr widths the channel supports | ||
377 | * @directions: bit mask of slave direction the channel supported | ||
378 | * since the enum dma_transfer_direction is not defined as bits for each | ||
379 | * type of direction, the dma controller should fill (1 << <TYPE>) and same | ||
380 | * should be checked by controller as well | ||
381 | * @cmd_pause: true, if pause and thereby resume is supported | ||
382 | * @cmd_terminate: true, if terminate cmd is supported | ||
383 | * | ||
384 | * @max_sg_nr: maximum number of SG segments supported | ||
385 | * 0 for no maximum | ||
386 | * @max_sg_len: maximum length of a SG segment supported | ||
387 | * 0 for no maximum | ||
388 | */ | ||
389 | struct dma_slave_caps { | ||
390 | u32 src_addr_widths; | ||
391 | u32 dstn_addr_widths; | ||
392 | u32 directions; | ||
393 | bool cmd_pause; | ||
394 | bool cmd_terminate; | ||
395 | |||
396 | u32 max_sg_nr; | ||
397 | u32 max_sg_len; | ||
398 | }; | ||
399 | |||
373 | static inline const char *dma_chan_name(struct dma_chan *chan) | 400 | static inline const char *dma_chan_name(struct dma_chan *chan) |
374 | { | 401 | { |
375 | return dev_name(&chan->dev->device); | 402 | return dev_name(&chan->dev->device); |
@@ -532,6 +559,7 @@ struct dma_tx_state { | |||
532 | * struct with auxiliary transfer status information, otherwise the call | 559 | * struct with auxiliary transfer status information, otherwise the call |
533 | * will just return a simple status code | 560 | * will just return a simple status code |
534 | * @device_issue_pending: push pending transactions to hardware | 561 | * @device_issue_pending: push pending transactions to hardware |
562 | * @device_slave_caps: return the slave channel capabilities | ||
535 | */ | 563 | */ |
536 | struct dma_device { | 564 | struct dma_device { |
537 | 565 | ||
@@ -597,6 +625,7 @@ struct dma_device { | |||
597 | dma_cookie_t cookie, | 625 | dma_cookie_t cookie, |
598 | struct dma_tx_state *txstate); | 626 | struct dma_tx_state *txstate); |
599 | void (*device_issue_pending)(struct dma_chan *chan); | 627 | void (*device_issue_pending)(struct dma_chan *chan); |
628 | int (*device_slave_caps)(struct dma_chan *chan, struct dma_slave_caps *caps); | ||
600 | }; | 629 | }; |
601 | 630 | ||
602 | static inline int dmaengine_device_control(struct dma_chan *chan, | 631 | static inline int dmaengine_device_control(struct dma_chan *chan, |
@@ -670,6 +699,21 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_interleaved_dma( | |||
670 | return chan->device->device_prep_interleaved_dma(chan, xt, flags); | 699 | return chan->device->device_prep_interleaved_dma(chan, xt, flags); |
671 | } | 700 | } |
672 | 701 | ||
702 | static inline int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps) | ||
703 | { | ||
704 | if (!chan || !caps) | ||
705 | return -EINVAL; | ||
706 | |||
707 | /* check if the channel supports slave transactions */ | ||
708 | if (!test_bit(DMA_SLAVE, chan->device->cap_mask.bits)) | ||
709 | return -ENXIO; | ||
710 | |||
711 | if (chan->device->device_slave_caps) | ||
712 | return chan->device->device_slave_caps(chan, caps); | ||
713 | |||
714 | return -ENXIO; | ||
715 | } | ||
716 | |||
673 | static inline int dmaengine_terminate_all(struct dma_chan *chan) | 717 | static inline int dmaengine_terminate_all(struct dma_chan *chan) |
674 | { | 718 | { |
675 | return dmaengine_device_control(chan, DMA_TERMINATE_ALL, 0); | 719 | return dmaengine_device_control(chan, DMA_TERMINATE_ALL, 0); |