diff options
-rw-r--r-- | drivers/spi/spi-omap2-mcspi.c | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 61eef47ae821..b3db4612b622 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c | |||
@@ -809,6 +809,10 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, | |||
809 | return 0; | 809 | return 0; |
810 | } | 810 | } |
811 | 811 | ||
812 | /* | ||
813 | * Note that we currently allow DMA only if we get a channel | ||
814 | * for both rx and tx. Otherwise we'll do PIO for both rx and tx. | ||
815 | */ | ||
812 | static int omap2_mcspi_request_dma(struct spi_device *spi) | 816 | static int omap2_mcspi_request_dma(struct spi_device *spi) |
813 | { | 817 | { |
814 | struct spi_master *master = spi->master; | 818 | struct spi_master *master = spi->master; |
@@ -827,21 +831,22 @@ static int omap2_mcspi_request_dma(struct spi_device *spi) | |||
827 | dma_cap_set(DMA_SLAVE, mask); | 831 | dma_cap_set(DMA_SLAVE, mask); |
828 | sig = mcspi_dma->dma_rx_sync_dev; | 832 | sig = mcspi_dma->dma_rx_sync_dev; |
829 | mcspi_dma->dma_rx = dma_request_channel(mask, omap_dma_filter_fn, &sig); | 833 | mcspi_dma->dma_rx = dma_request_channel(mask, omap_dma_filter_fn, &sig); |
830 | if (!mcspi_dma->dma_rx) { | 834 | if (!mcspi_dma->dma_rx) |
831 | dev_err(&spi->dev, "no RX DMA engine channel for McSPI\n"); | 835 | goto no_dma; |
832 | return -EAGAIN; | ||
833 | } | ||
834 | 836 | ||
835 | sig = mcspi_dma->dma_tx_sync_dev; | 837 | sig = mcspi_dma->dma_tx_sync_dev; |
836 | mcspi_dma->dma_tx = dma_request_channel(mask, omap_dma_filter_fn, &sig); | 838 | mcspi_dma->dma_tx = dma_request_channel(mask, omap_dma_filter_fn, &sig); |
837 | if (!mcspi_dma->dma_tx) { | 839 | if (!mcspi_dma->dma_tx) { |
838 | dev_err(&spi->dev, "no TX DMA engine channel for McSPI\n"); | ||
839 | dma_release_channel(mcspi_dma->dma_rx); | 840 | dma_release_channel(mcspi_dma->dma_rx); |
840 | mcspi_dma->dma_rx = NULL; | 841 | mcspi_dma->dma_rx = NULL; |
841 | return -EAGAIN; | 842 | goto no_dma; |
842 | } | 843 | } |
843 | 844 | ||
844 | return 0; | 845 | return 0; |
846 | |||
847 | no_dma: | ||
848 | dev_warn(&spi->dev, "not using DMA for McSPI\n"); | ||
849 | return -EAGAIN; | ||
845 | } | 850 | } |
846 | 851 | ||
847 | static int omap2_mcspi_setup(struct spi_device *spi) | 852 | static int omap2_mcspi_setup(struct spi_device *spi) |
@@ -874,7 +879,7 @@ static int omap2_mcspi_setup(struct spi_device *spi) | |||
874 | 879 | ||
875 | if (!mcspi_dma->dma_rx || !mcspi_dma->dma_tx) { | 880 | if (!mcspi_dma->dma_rx || !mcspi_dma->dma_tx) { |
876 | ret = omap2_mcspi_request_dma(spi); | 881 | ret = omap2_mcspi_request_dma(spi); |
877 | if (ret < 0) | 882 | if (ret < 0 && ret != -EAGAIN) |
878 | return ret; | 883 | return ret; |
879 | } | 884 | } |
880 | 885 | ||
@@ -932,6 +937,7 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m) | |||
932 | struct spi_device *spi; | 937 | struct spi_device *spi; |
933 | struct spi_transfer *t = NULL; | 938 | struct spi_transfer *t = NULL; |
934 | struct spi_master *master; | 939 | struct spi_master *master; |
940 | struct omap2_mcspi_dma *mcspi_dma; | ||
935 | int cs_active = 0; | 941 | int cs_active = 0; |
936 | struct omap2_mcspi_cs *cs; | 942 | struct omap2_mcspi_cs *cs; |
937 | struct omap2_mcspi_device_config *cd; | 943 | struct omap2_mcspi_device_config *cd; |
@@ -941,6 +947,7 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m) | |||
941 | 947 | ||
942 | spi = m->spi; | 948 | spi = m->spi; |
943 | master = spi->master; | 949 | master = spi->master; |
950 | mcspi_dma = mcspi->dma_channels + spi->chip_select; | ||
944 | cs = spi->controller_state; | 951 | cs = spi->controller_state; |
945 | cd = spi->controller_data; | 952 | cd = spi->controller_data; |
946 | 953 | ||
@@ -997,7 +1004,8 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m) | |||
997 | __raw_writel(0, cs->base | 1004 | __raw_writel(0, cs->base |
998 | + OMAP2_MCSPI_TX0); | 1005 | + OMAP2_MCSPI_TX0); |
999 | 1006 | ||
1000 | if (m->is_dma_mapped || t->len >= DMA_MIN_BYTES) | 1007 | if ((mcspi_dma->dma_rx && mcspi_dma->dma_tx) && |
1008 | (m->is_dma_mapped || t->len >= DMA_MIN_BYTES)) | ||
1001 | count = omap2_mcspi_txrx_dma(spi, t); | 1009 | count = omap2_mcspi_txrx_dma(spi, t); |
1002 | else | 1010 | else |
1003 | count = omap2_mcspi_txrx_pio(spi, t); | 1011 | count = omap2_mcspi_txrx_pio(spi, t); |
@@ -1044,10 +1052,14 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m) | |||
1044 | static int omap2_mcspi_transfer_one_message(struct spi_master *master, | 1052 | static int omap2_mcspi_transfer_one_message(struct spi_master *master, |
1045 | struct spi_message *m) | 1053 | struct spi_message *m) |
1046 | { | 1054 | { |
1055 | struct spi_device *spi; | ||
1047 | struct omap2_mcspi *mcspi; | 1056 | struct omap2_mcspi *mcspi; |
1057 | struct omap2_mcspi_dma *mcspi_dma; | ||
1048 | struct spi_transfer *t; | 1058 | struct spi_transfer *t; |
1049 | 1059 | ||
1060 | spi = m->spi; | ||
1050 | mcspi = spi_master_get_devdata(master); | 1061 | mcspi = spi_master_get_devdata(master); |
1062 | mcspi_dma = mcspi->dma_channels + spi->chip_select; | ||
1051 | m->actual_length = 0; | 1063 | m->actual_length = 0; |
1052 | m->status = 0; | 1064 | m->status = 0; |
1053 | 1065 | ||
@@ -1082,7 +1094,7 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master, | |||
1082 | if (m->is_dma_mapped || len < DMA_MIN_BYTES) | 1094 | if (m->is_dma_mapped || len < DMA_MIN_BYTES) |
1083 | continue; | 1095 | continue; |
1084 | 1096 | ||
1085 | if (tx_buf != NULL) { | 1097 | if (mcspi_dma->dma_tx && tx_buf != NULL) { |
1086 | t->tx_dma = dma_map_single(mcspi->dev, (void *) tx_buf, | 1098 | t->tx_dma = dma_map_single(mcspi->dev, (void *) tx_buf, |
1087 | len, DMA_TO_DEVICE); | 1099 | len, DMA_TO_DEVICE); |
1088 | if (dma_mapping_error(mcspi->dev, t->tx_dma)) { | 1100 | if (dma_mapping_error(mcspi->dev, t->tx_dma)) { |
@@ -1091,7 +1103,7 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master, | |||
1091 | return -EINVAL; | 1103 | return -EINVAL; |
1092 | } | 1104 | } |
1093 | } | 1105 | } |
1094 | if (rx_buf != NULL) { | 1106 | if (mcspi_dma->dma_rx && rx_buf != NULL) { |
1095 | t->rx_dma = dma_map_single(mcspi->dev, rx_buf, t->len, | 1107 | t->rx_dma = dma_map_single(mcspi->dev, rx_buf, t->len, |
1096 | DMA_FROM_DEVICE); | 1108 | DMA_FROM_DEVICE); |
1097 | if (dma_mapping_error(mcspi->dev, t->rx_dma)) { | 1109 | if (dma_mapping_error(mcspi->dev, t->rx_dma)) { |