diff options
author | Geert Uytterhoeven <geert+renesas@glider.be> | 2014-06-02 09:38:09 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-06-02 10:49:33 -0400 |
commit | 65bf220571f131a7c3a564a88793bd0f16fd7c96 (patch) | |
tree | 112cd6651ff046bc62cba333ad01ee5c7bfdd857 | |
parent | 27e105a6006b8ce1b55709c5e24f63959981475d (diff) |
spi: rspi: Extract rspi_request_dma_chan()
Setup of the receive and transmit DMA channels is very similar, so let's
consolidate.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r-- | drivers/spi/spi-rspi.c | 89 |
1 files changed, 55 insertions, 34 deletions
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index 94a99ec7d989..0a7a2d618f0f 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c | |||
@@ -942,52 +942,73 @@ static irqreturn_t rspi_irq_tx(int irq, void *_sr) | |||
942 | return 0; | 942 | return 0; |
943 | } | 943 | } |
944 | 944 | ||
945 | static int rspi_request_dma(struct rspi_data *rspi, | 945 | static struct dma_chan *rspi_request_dma_chan(struct device *dev, |
946 | struct platform_device *pdev) | 946 | enum dma_transfer_direction dir, |
947 | unsigned int id, | ||
948 | dma_addr_t port_addr) | ||
947 | { | 949 | { |
948 | const struct rspi_plat_data *rspi_pd = dev_get_platdata(&pdev->dev); | ||
949 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
950 | dma_cap_mask_t mask; | 950 | dma_cap_mask_t mask; |
951 | struct dma_chan *chan; | ||
951 | struct dma_slave_config cfg; | 952 | struct dma_slave_config cfg; |
952 | int ret; | 953 | int ret; |
953 | 954 | ||
955 | dma_cap_zero(mask); | ||
956 | dma_cap_set(DMA_SLAVE, mask); | ||
957 | |||
958 | chan = dma_request_channel(mask, shdma_chan_filter, | ||
959 | (void *)(unsigned long)id); | ||
960 | if (!chan) { | ||
961 | dev_warn(dev, "dma_request_channel failed\n"); | ||
962 | return NULL; | ||
963 | } | ||
964 | |||
965 | memset(&cfg, 0, sizeof(cfg)); | ||
966 | cfg.slave_id = id; | ||
967 | cfg.direction = dir; | ||
968 | if (dir == DMA_MEM_TO_DEV) | ||
969 | cfg.dst_addr = port_addr; | ||
970 | else | ||
971 | cfg.src_addr = port_addr; | ||
972 | |||
973 | ret = dmaengine_slave_config(chan, &cfg); | ||
974 | if (ret) { | ||
975 | dev_warn(dev, "dmaengine_slave_config failed %d\n", ret); | ||
976 | dma_release_channel(chan); | ||
977 | return NULL; | ||
978 | } | ||
979 | |||
980 | return chan; | ||
981 | } | ||
982 | |||
983 | static int rspi_request_dma(struct rspi_data *rspi, | ||
984 | struct platform_device *pdev) | ||
985 | { | ||
986 | const struct rspi_plat_data *rspi_pd = dev_get_platdata(&pdev->dev); | ||
987 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
988 | |||
954 | if (!res || !rspi_pd) | 989 | if (!res || !rspi_pd) |
955 | return 0; /* The driver assumes no error. */ | 990 | return 0; /* The driver assumes no error. */ |
956 | 991 | ||
957 | /* If the module receives data by DMAC, it also needs TX DMAC */ | 992 | /* If the module receives data by DMAC, it also needs TX DMAC */ |
958 | if (rspi_pd->dma_rx_id && rspi_pd->dma_tx_id) { | 993 | if (rspi_pd->dma_rx_id && rspi_pd->dma_tx_id) { |
959 | dma_cap_zero(mask); | 994 | rspi->chan_rx = rspi_request_dma_chan(&pdev->dev, |
960 | dma_cap_set(DMA_SLAVE, mask); | 995 | DMA_DEV_TO_MEM, |
961 | rspi->chan_rx = dma_request_channel(mask, shdma_chan_filter, | 996 | rspi_pd->dma_rx_id, |
962 | (void *)rspi_pd->dma_rx_id); | 997 | res->start + RSPI_SPDR); |
963 | if (rspi->chan_rx) { | 998 | if (!rspi->chan_rx) |
964 | cfg.slave_id = rspi_pd->dma_rx_id; | 999 | return -ENODEV; |
965 | cfg.direction = DMA_DEV_TO_MEM; | 1000 | |
966 | cfg.dst_addr = 0; | 1001 | dev_info(&pdev->dev, "Use DMA when rx.\n"); |
967 | cfg.src_addr = res->start + RSPI_SPDR; | ||
968 | ret = dmaengine_slave_config(rspi->chan_rx, &cfg); | ||
969 | if (!ret) | ||
970 | dev_info(&pdev->dev, "Use DMA when rx.\n"); | ||
971 | else | ||
972 | return ret; | ||
973 | } | ||
974 | } | 1002 | } |
975 | if (rspi_pd->dma_tx_id) { | 1003 | if (rspi_pd->dma_tx_id) { |
976 | dma_cap_zero(mask); | 1004 | rspi->chan_tx = rspi_request_dma_chan(&pdev->dev, |
977 | dma_cap_set(DMA_SLAVE, mask); | 1005 | DMA_MEM_TO_DEV, |
978 | rspi->chan_tx = dma_request_channel(mask, shdma_chan_filter, | 1006 | rspi_pd->dma_tx_id, |
979 | (void *)rspi_pd->dma_tx_id); | 1007 | res->start + RSPI_SPDR); |
980 | if (rspi->chan_tx) { | 1008 | if (!rspi->chan_tx) |
981 | cfg.slave_id = rspi_pd->dma_tx_id; | 1009 | return -ENODEV; |
982 | cfg.direction = DMA_MEM_TO_DEV; | 1010 | |
983 | cfg.dst_addr = res->start + RSPI_SPDR; | 1011 | dev_info(&pdev->dev, "Use DMA when tx\n"); |
984 | cfg.src_addr = 0; | ||
985 | ret = dmaengine_slave_config(rspi->chan_tx, &cfg); | ||
986 | if (!ret) | ||
987 | dev_info(&pdev->dev, "Use DMA when tx\n"); | ||
988 | else | ||
989 | return ret; | ||
990 | } | ||
991 | } | 1012 | } |
992 | 1013 | ||
993 | return 0; | 1014 | return 0; |