| From foo@baz Wed Feb 28 16:16:23 CET 2018 |
| From: Radu Pirea <radu.pirea@microchip.com> |
| Date: Fri, 15 Dec 2017 17:40:17 +0200 |
| Subject: spi: atmel: fixed spin_lock usage inside atmel_spi_remove |
| |
| From: Radu Pirea <radu.pirea@microchip.com> |
| |
| |
| [ Upstream commit 66e900a3d225575c8b48b59ae1fe74bb6e5a65cc ] |
| |
| The only part of atmel_spi_remove which needs to be atomic is hardware |
| reset. |
| |
| atmel_spi_stop_dma calls dma_terminate_all and this needs interrupts |
| enabled. |
| atmel_spi_release_dma calls dma_release_channel and dma_release_channel |
| locks a mutex inside of spin_lock. |
| |
| So the call of these functions can't be inside a spin_lock. |
| |
| Reported-by: Jia-Ju Bai <baijiaju1990@gmail.com> |
| Signed-off-by: Radu Pirea <radu.pirea@microchip.com> |
| Signed-off-by: Mark Brown <broonie@kernel.org> |
| Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/spi/spi-atmel.c | 2 +- |
| 1 file changed, 1 insertion(+), 1 deletion(-) |
| |
| --- a/drivers/spi/spi-atmel.c |
| +++ b/drivers/spi/spi-atmel.c |
| @@ -1416,12 +1416,12 @@ static int atmel_spi_remove(struct platf |
| struct atmel_spi *as = spi_master_get_devdata(master); |
| |
| /* reset the hardware and block queue progress */ |
| - spin_lock_irq(&as->lock); |
| if (as->use_dma) { |
| atmel_spi_stop_dma(as); |
| atmel_spi_release_dma(as); |
| } |
| |
| + spin_lock_irq(&as->lock); |
| spi_writel(as, CR, SPI_BIT(SWRST)); |
| spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ |
| spi_readl(as, SR); |