diff options
| author | Fionn Cleary <clearyf@tcd.ie> | 2015-04-23 15:13:40 -0400 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2015-04-24 05:55:24 -0400 |
| commit | c5a06e75f38376238db6a38240bac4b27dfe5216 (patch) | |
| tree | 7bb69601a14088ea562caf80f3f762be0aa600cf | |
| parent | c517d838eb7d07bbe9507871fab3931deccff539 (diff) | |
spi/omap2-mcpsi: Always call spi_finalize_current_message()
The spi queue waits forever for spi_finalize_current_message() to be
called, blocking the bus. Ensure that all error paths from
omap2_mcspi_transfer_one_message() call spi_finalize_current_message().
Signed-off-by: Fionn Cleary <fionn.cleary@streamunlimited.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
| -rw-r--r-- | drivers/spi/spi-omap2-mcspi.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 4df8942058de..d1a5b9fc3eba 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c | |||
| @@ -1210,6 +1210,7 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master, | |||
| 1210 | struct omap2_mcspi *mcspi; | 1210 | struct omap2_mcspi *mcspi; |
| 1211 | struct omap2_mcspi_dma *mcspi_dma; | 1211 | struct omap2_mcspi_dma *mcspi_dma; |
| 1212 | struct spi_transfer *t; | 1212 | struct spi_transfer *t; |
| 1213 | int status; | ||
| 1213 | 1214 | ||
| 1214 | spi = m->spi; | 1215 | spi = m->spi; |
| 1215 | mcspi = spi_master_get_devdata(master); | 1216 | mcspi = spi_master_get_devdata(master); |
| @@ -1229,7 +1230,8 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master, | |||
| 1229 | tx_buf ? "tx" : "", | 1230 | tx_buf ? "tx" : "", |
| 1230 | rx_buf ? "rx" : "", | 1231 | rx_buf ? "rx" : "", |
| 1231 | t->bits_per_word); | 1232 | t->bits_per_word); |
| 1232 | return -EINVAL; | 1233 | status = -EINVAL; |
| 1234 | goto out; | ||
| 1233 | } | 1235 | } |
| 1234 | 1236 | ||
| 1235 | if (m->is_dma_mapped || len < DMA_MIN_BYTES) | 1237 | if (m->is_dma_mapped || len < DMA_MIN_BYTES) |
| @@ -1241,7 +1243,8 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master, | |||
| 1241 | if (dma_mapping_error(mcspi->dev, t->tx_dma)) { | 1243 | if (dma_mapping_error(mcspi->dev, t->tx_dma)) { |
| 1242 | dev_dbg(mcspi->dev, "dma %cX %d bytes error\n", | 1244 | dev_dbg(mcspi->dev, "dma %cX %d bytes error\n", |
| 1243 | 'T', len); | 1245 | 'T', len); |
| 1244 | return -EINVAL; | 1246 | status = -EINVAL; |
| 1247 | goto out; | ||
| 1245 | } | 1248 | } |
| 1246 | } | 1249 | } |
| 1247 | if (mcspi_dma->dma_rx && rx_buf != NULL) { | 1250 | if (mcspi_dma->dma_rx && rx_buf != NULL) { |
| @@ -1253,14 +1256,19 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master, | |||
| 1253 | if (tx_buf != NULL) | 1256 | if (tx_buf != NULL) |
| 1254 | dma_unmap_single(mcspi->dev, t->tx_dma, | 1257 | dma_unmap_single(mcspi->dev, t->tx_dma, |
| 1255 | len, DMA_TO_DEVICE); | 1258 | len, DMA_TO_DEVICE); |
| 1256 | return -EINVAL; | 1259 | status = -EINVAL; |
| 1260 | goto out; | ||
| 1257 | } | 1261 | } |
| 1258 | } | 1262 | } |
| 1259 | } | 1263 | } |
| 1260 | 1264 | ||
| 1261 | omap2_mcspi_work(mcspi, m); | 1265 | omap2_mcspi_work(mcspi, m); |
| 1266 | /* spi_finalize_current_message() changes the status inside the | ||
| 1267 | * spi_message, save the status here. */ | ||
| 1268 | status = m->status; | ||
| 1269 | out: | ||
| 1262 | spi_finalize_current_message(master); | 1270 | spi_finalize_current_message(master); |
| 1263 | return 0; | 1271 | return status; |
| 1264 | } | 1272 | } |
| 1265 | 1273 | ||
| 1266 | static int omap2_mcspi_master_setup(struct omap2_mcspi *mcspi) | 1274 | static int omap2_mcspi_master_setup(struct omap2_mcspi *mcspi) |
