diff options
Diffstat (limited to 'drivers/dma/fsldma.c')
-rw-r--r-- | drivers/dma/fsldma.c | 97 |
1 files changed, 37 insertions, 60 deletions
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 38821cdf862b..300f821f1890 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c | |||
@@ -941,84 +941,56 @@ fail: | |||
941 | return NULL; | 941 | return NULL; |
942 | } | 942 | } |
943 | 943 | ||
944 | /** | 944 | static int fsl_dma_device_terminate_all(struct dma_chan *dchan) |
945 | * fsl_dma_prep_slave_sg - prepare descriptors for a DMA_SLAVE transaction | ||
946 | * @chan: DMA channel | ||
947 | * @sgl: scatterlist to transfer to/from | ||
948 | * @sg_len: number of entries in @scatterlist | ||
949 | * @direction: DMA direction | ||
950 | * @flags: DMAEngine flags | ||
951 | * @context: transaction context (ignored) | ||
952 | * | ||
953 | * Prepare a set of descriptors for a DMA_SLAVE transaction. Following the | ||
954 | * DMA_SLAVE API, this gets the device-specific information from the | ||
955 | * chan->private variable. | ||
956 | */ | ||
957 | static struct dma_async_tx_descriptor *fsl_dma_prep_slave_sg( | ||
958 | struct dma_chan *dchan, struct scatterlist *sgl, unsigned int sg_len, | ||
959 | enum dma_transfer_direction direction, unsigned long flags, | ||
960 | void *context) | ||
961 | { | 945 | { |
962 | /* | ||
963 | * This operation is not supported on the Freescale DMA controller | ||
964 | * | ||
965 | * However, we need to provide the function pointer to allow the | ||
966 | * device_control() method to work. | ||
967 | */ | ||
968 | return NULL; | ||
969 | } | ||
970 | |||
971 | static int fsl_dma_device_control(struct dma_chan *dchan, | ||
972 | enum dma_ctrl_cmd cmd, unsigned long arg) | ||
973 | { | ||
974 | struct dma_slave_config *config; | ||
975 | struct fsldma_chan *chan; | 946 | struct fsldma_chan *chan; |
976 | int size; | ||
977 | 947 | ||
978 | if (!dchan) | 948 | if (!dchan) |
979 | return -EINVAL; | 949 | return -EINVAL; |
980 | 950 | ||
981 | chan = to_fsl_chan(dchan); | 951 | chan = to_fsl_chan(dchan); |
982 | 952 | ||
983 | switch (cmd) { | 953 | spin_lock_bh(&chan->desc_lock); |
984 | case DMA_TERMINATE_ALL: | ||
985 | spin_lock_bh(&chan->desc_lock); | ||
986 | |||
987 | /* Halt the DMA engine */ | ||
988 | dma_halt(chan); | ||
989 | 954 | ||
990 | /* Remove and free all of the descriptors in the LD queue */ | 955 | /* Halt the DMA engine */ |
991 | fsldma_free_desc_list(chan, &chan->ld_pending); | 956 | dma_halt(chan); |
992 | fsldma_free_desc_list(chan, &chan->ld_running); | ||
993 | fsldma_free_desc_list(chan, &chan->ld_completed); | ||
994 | chan->idle = true; | ||
995 | 957 | ||
996 | spin_unlock_bh(&chan->desc_lock); | 958 | /* Remove and free all of the descriptors in the LD queue */ |
997 | return 0; | 959 | fsldma_free_desc_list(chan, &chan->ld_pending); |
960 | fsldma_free_desc_list(chan, &chan->ld_running); | ||
961 | fsldma_free_desc_list(chan, &chan->ld_completed); | ||
962 | chan->idle = true; | ||
998 | 963 | ||
999 | case DMA_SLAVE_CONFIG: | 964 | spin_unlock_bh(&chan->desc_lock); |
1000 | config = (struct dma_slave_config *)arg; | 965 | return 0; |
966 | } | ||
1001 | 967 | ||
1002 | /* make sure the channel supports setting burst size */ | 968 | static int fsl_dma_device_config(struct dma_chan *dchan, |
1003 | if (!chan->set_request_count) | 969 | struct dma_slave_config *config) |
1004 | return -ENXIO; | 970 | { |
971 | struct fsldma_chan *chan; | ||
972 | int size; | ||
1005 | 973 | ||
1006 | /* we set the controller burst size depending on direction */ | 974 | if (!dchan) |
1007 | if (config->direction == DMA_MEM_TO_DEV) | 975 | return -EINVAL; |
1008 | size = config->dst_addr_width * config->dst_maxburst; | ||
1009 | else | ||
1010 | size = config->src_addr_width * config->src_maxburst; | ||
1011 | 976 | ||
1012 | chan->set_request_count(chan, size); | 977 | chan = to_fsl_chan(dchan); |
1013 | return 0; | ||
1014 | 978 | ||
1015 | default: | 979 | /* make sure the channel supports setting burst size */ |
980 | if (!chan->set_request_count) | ||
1016 | return -ENXIO; | 981 | return -ENXIO; |
1017 | } | ||
1018 | 982 | ||
983 | /* we set the controller burst size depending on direction */ | ||
984 | if (config->direction == DMA_MEM_TO_DEV) | ||
985 | size = config->dst_addr_width * config->dst_maxburst; | ||
986 | else | ||
987 | size = config->src_addr_width * config->src_maxburst; | ||
988 | |||
989 | chan->set_request_count(chan, size); | ||
1019 | return 0; | 990 | return 0; |
1020 | } | 991 | } |
1021 | 992 | ||
993 | |||
1022 | /** | 994 | /** |
1023 | * fsl_dma_memcpy_issue_pending - Issue the DMA start command | 995 | * fsl_dma_memcpy_issue_pending - Issue the DMA start command |
1024 | * @chan : Freescale DMA channel | 996 | * @chan : Freescale DMA channel |
@@ -1395,10 +1367,15 @@ static int fsldma_of_probe(struct platform_device *op) | |||
1395 | fdev->common.device_prep_dma_sg = fsl_dma_prep_sg; | 1367 | fdev->common.device_prep_dma_sg = fsl_dma_prep_sg; |
1396 | fdev->common.device_tx_status = fsl_tx_status; | 1368 | fdev->common.device_tx_status = fsl_tx_status; |
1397 | fdev->common.device_issue_pending = fsl_dma_memcpy_issue_pending; | 1369 | fdev->common.device_issue_pending = fsl_dma_memcpy_issue_pending; |
1398 | fdev->common.device_prep_slave_sg = fsl_dma_prep_slave_sg; | 1370 | fdev->common.device_config = fsl_dma_device_config; |
1399 | fdev->common.device_control = fsl_dma_device_control; | 1371 | fdev->common.device_terminate_all = fsl_dma_device_terminate_all; |
1400 | fdev->common.dev = &op->dev; | 1372 | fdev->common.dev = &op->dev; |
1401 | 1373 | ||
1374 | fdev->common.src_addr_widths = FSL_DMA_BUSWIDTHS; | ||
1375 | fdev->common.dst_addr_widths = FSL_DMA_BUSWIDTHS; | ||
1376 | fdev->common.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); | ||
1377 | fdev->common.residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR; | ||
1378 | |||
1402 | dma_set_mask(&(op->dev), DMA_BIT_MASK(36)); | 1379 | dma_set_mask(&(op->dev), DMA_BIT_MASK(36)); |
1403 | 1380 | ||
1404 | platform_set_drvdata(op, fdev); | 1381 | platform_set_drvdata(op, fdev); |