aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Vasut <marex@denx.de>2012-08-23 22:56:27 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-08-27 12:36:53 -0400
commit41682e03d4fdc947dbd22725d70f222cc7746852 (patch)
tree3fa67108671a8be3cb7b806cedc9f3816ab8bca0
parentc895db0fb2c9e77fd94ba7995e2a01652a91910c (diff)
mxs/spi: Fix misuse of init_completion
The init_completion() call does reinit not only the variable carrying the flag that the completion finished, but also initialized the waitqueue associated with the completion. On the contrary, the INIT_COMPLETION() call only reinits the flag. In case there was anything still stuck in the waitqueue, subsequent call to init_completion() would be able to create possible race condition. This patch uses the proper function and moves init_completion() into .probe() call of the driver, to be issued only once. Note that such scenario is impossible, since two threads can never enter the mxs_spi_txrx_dma(), since whole this section is protected by mutex in SPI core. This by no means allows this issue to exit though. Signed-off-by: Marek Vasut <marex@denx.de> Cc: Chris Ball <cjb@laptop.org> Cc: Shawn Guo <shawn.guo@linaro.org> Cc: Mark Brown <broonie@opensource.wolfsonmicro.com> Cc: Fabio Estevam <fabio.estevam@freescale.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--drivers/spi/spi-mxs.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c
index 447f917fe66..4e7801dd571 100644
--- a/drivers/spi/spi-mxs.c
+++ b/drivers/spi/spi-mxs.c
@@ -230,7 +230,7 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi, int cs,
230 return -EINVAL; 230 return -EINVAL;
231 } 231 }
232 232
233 init_completion(&spi->c); 233 INIT_COMPLETION(spi->c);
234 234
235 if (*first) 235 if (*first)
236 pio |= BM_SSP_CTRL0_LOCK_CS; 236 pio |= BM_SSP_CTRL0_LOCK_CS;
@@ -549,6 +549,8 @@ static int __devinit mxs_spi_probe(struct platform_device *pdev)
549 ssp->devid = devid; 549 ssp->devid = devid;
550 ssp->dma_channel = dma_channel; 550 ssp->dma_channel = dma_channel;
551 551
552 init_completion(&spi->c);
553
552 ret = devm_request_irq(&pdev->dev, irq_err, mxs_ssp_irq_handler, 0, 554 ret = devm_request_irq(&pdev->dev, irq_err, mxs_ssp_irq_handler, 0,
553 DRIVER_NAME, ssp); 555 DRIVER_NAME, ssp);
554 if (ret) 556 if (ret)