linux/drivers/spi
Alexander Sverdlin 766afbabcb spi: pl022: Fix race in giveback() leading to driver lock-up
[ Upstream commit cd6fa8d2ca ]

Commit fd316941c ("spi/pl022: disable port when unused") introduced a race,
which leads to possible driver lock up (easily reproducible on SMP).

The problem happens in giveback() function where the completion of the transfer
is signalled to SPI subsystem and then the HW SPI controller is disabled. Another
transfer might be setup in between, which brings driver in locked-up state.

Exact event sequence on SMP:

core0                                   core1

                                        => pump_transfers()
                                        /* message->state == STATE_DONE */
                                          => giveback()
                                            => spi_finalize_current_message()

=> pl022_unprepare_transfer_hardware()
=> pl022_transfer_one_message
  => flush()
  => do_interrupt_dma_transfer()
    => set_up_next_transfer()
    /* Enable SSP, turn on interrupts */
    writew((readw(SSP_CR1(pl022->virtbase)) |
           SSP_CR1_MASK_SSE), SSP_CR1(pl022->virtbase));

...

=> pl022_interrupt_handler()
  => readwriter()

                                        /* disable the SPI/SSP operation */
                                        => writew((readw(SSP_CR1(pl022->virtbase)) &
                                                  (~SSP_CR1_MASK_SSE)), SSP_CR1(pl022->virtbase));

Lockup! SPI controller is disabled and the data will never be received. Whole
SPI subsystem is waiting for transfer ACK and blocked.

So, only signal transfer completion after disabling the controller.

Fixes: fd316941c (spi/pl022: disable port when unused)
Signed-off-by: Alexander Sverdlin <alexander.sverdlin@nokia.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
History 2015-03-28 09:49:32 -04:00
..
Kconfig Merge remote-tracking branches 'spi/topic/pl022', 'spi/topic/pxa2xx', 'spi/topic/rspi', 'spi/topic/sh-msiof' and 'spi/topic/sirf' into spi-next 2014-10-03 16:33:42 +01:00
Makefile spi: bcm53xx: driver for SPI controller on Broadcom bcma SoC 2014-08-19 11:30:55 -05:00
spi-adi-v3.c spi: spi-adi-v3: Remove redundant OOM message 2014-06-21 11:14:02 +01:00
spi-altera.c Merge remote-tracking branches 'spi/topic/imx', 'spi/topic/init', 'spi/topic/mpc512x-psc', 'spi/topic/mpc52xx', 'spi/topic/mxs', 'spi/topic/nuc900', 'spi/topic/oc-tiny' and 'spi/topic/octeon' into spi-next 2014-03-30 00:51:17 +00:00
spi-ath79.c spi: Remove unneeded include of linux/workqueue.h 2014-04-14 17:20:15 +01:00
spi-atmel.c spi: atmel: Fix interrupt setup for PDC transfers 2015-03-28 09:44:58 -04:00
spi-au1550.c spi: spi-au1550: fix build failure 2014-08-19 16:17:57 -05:00
spi-bcm53xx.c spi: bcm53xx: Add missing module information 2014-09-26 09:08:10 +01:00
spi-bcm53xx.h spi: bcm53xx: driver for SPI controller on Broadcom bcma SoC 2014-08-19 11:30:55 -05:00
spi-bcm63xx-hsspi.c spi: Remove unneeded include of linux/workqueue.h 2014-04-14 17:20:15 +01:00
spi-bcm63xx.c spi: Remove unneeded include of linux/workqueue.h 2014-04-14 17:20:15 +01:00
spi-bcm2835.c spi: Remove explictly set bus_num and num_chipselect to default setting 2014-02-16 09:51:02 +08:00
spi-bfin-sport.c spi: delete non-required instances of include <linux/init.h> 2014-02-03 12:20:35 +00:00
spi-bfin5xx.c spi: bfin5xx: fix build error 2014-04-14 20:44:15 +01:00
spi-bitbang-txrx.h spi: bitbang: Grammar s/make to make/to make/ 2014-01-13 11:24:21 +00:00
spi-bitbang.c Merge remote-tracking branches 'spi/topic/imx', 'spi/topic/init', 'spi/topic/mpc512x-psc', 'spi/topic/mpc52xx', 'spi/topic/mxs', 'spi/topic/nuc900', 'spi/topic/oc-tiny' and 'spi/topic/octeon' into spi-next 2014-03-30 00:51:17 +00:00
spi-butterfly.c spi: bitbang: Make spi_bitbang_stop() return void 2014-03-29 11:09:26 +00:00
spi-cadence.c spi: cadence: Remove .owner field for driver 2014-08-16 17:11:32 -05:00
spi-clps711x.c spi: clps711x: Migrate to the new clk subsystem 2014-09-24 09:40:24 +01:00
spi-coldfire-qspi.c Merge remote-tracking branches 'spi/topic/bus-num', 'spi/topic/cleanup', 'spi/topic/clps711x', 'spi/topic/coldfire', 'spi/topic/completion' and 'spi/topic/davinci' into spi-next 2014-03-30 00:51:03 +00:00
spi-davinci.c Merge remote-tracking branches 'spi/topic/davinci', 'spi/topic/doc', 'spi/topic/dw' and 'spi/topic/fsl' into spi-next 2014-10-03 16:33:39 +01:00
spi-dw-mid.c spi: dw-mid: avoid potential NULL dereference 2015-03-28 09:49:22 -04:00
spi-dw-mmio.c spi: dw-mmio: add devicetree support 2014-07-03 19:44:04 +01:00
spi-dw-pci.c Merge remote-tracking branches 'spi/topic/davinci', 'spi/topic/doc', 'spi/topic/dw' and 'spi/topic/fsl' into spi-next 2014-10-03 16:33:39 +01:00
spi-dw.c spi: dw: Fix detecting FIFO depth 2015-02-05 22:36:00 -08:00
spi-dw.h spi: dw-mid: change magic numbers to the constants 2014-10-02 17:06:26 +01:00
spi-efm32.c spi: efm32: correct namespacing of location property 2014-07-11 13:39:36 +01:00
spi-ep93xx.c spi: ep93xx: Fix checkpatch issue 2014-09-02 11:47:12 +01:00
spi-falcon.c spi: falcon: Remove unnecessary platform_set_drvdata() 2014-06-06 11:14:29 +01:00
spi-fsl-cpm.c spi: fsl: Sort include headers alphabetically 2014-09-29 18:14:08 +01:00
spi-fsl-cpm.h spi/spi-fsl-spi: Make driver usable in CPU mode outside of an FSL_SOC environment 2013-04-07 10:07:54 +01:00
spi-fsl-dspi.c spi: spi-fsl-dspi: Remove usage of devm_kzalloc 2015-02-11 15:00:50 +08:00
spi-fsl-espi.c Merge remote-tracking branches 'spi/topic/davinci', 'spi/topic/doc', 'spi/topic/dw' and 'spi/topic/fsl' into spi-next 2014-10-03 16:33:39 +01:00
spi-fsl-lib.c spi: fsl: Sort include headers alphabetically 2014-09-29 18:14:08 +01:00
spi-fsl-lib.h spi: fsl: Kill mpc8xxx_spi_cleanup and convert fsl_espi_setup to use devm_kzalloc 2014-04-14 17:18:55 +01:00
spi-fsl-spi.c Merge remote-tracking branches 'spi/topic/davinci', 'spi/topic/doc', 'spi/topic/dw' and 'spi/topic/fsl' into spi-next 2014-10-03 16:33:39 +01:00
spi-fsl-spi.h spi/spi-fsl-spi: Add support for Aeroflex Gaisler GRLIB cores normally running on SPARC 2013-04-07 10:07:56 +01:00
spi-gpio.c spi: spi-gpio: Make of_device_id array const 2014-05-07 20:53:04 +01:00
spi-imx.c spi: imx: use pio mode for i.mx6dl 2015-02-11 15:00:51 +08:00
spi-lm70llp.c spi: bitbang: Let spi_bitbang_start() take a reference to master 2013-10-07 14:50:43 +01:00
spi-mpc52xx-psc.c Merge remote-tracking branches 'spi/fix/complete', 'spi/fix/efm32', 'spi/fix/omap2-mcspi' and 'spi/fix/qup' into spi-linus 2014-04-10 23:39:52 +01:00
spi-mpc52xx.c Merge remote-tracking branches 'spi/fix/complete', 'spi/fix/efm32', 'spi/fix/omap2-mcspi' and 'spi/fix/qup' into spi-linus 2014-04-10 23:39:52 +01:00
spi-mpc512x-psc.c Merge remote-tracking branches 'spi/fix/complete', 'spi/fix/efm32', 'spi/fix/omap2-mcspi' and 'spi/fix/qup' into spi-linus 2014-04-10 23:39:52 +01:00
spi-mxs.c Merge remote-tracking branches 'spi/topic/fsl-dspi', 'spi/topic/imx', 'spi/topic/mxs', 'spi/topic/omap-100k' and 'spi/topic/orion' into spi-next 2014-10-03 16:33:41 +01:00
spi-nuc900.c spi: Remove unneeded include of linux/workqueue.h 2014-04-14 17:20:15 +01:00
spi-oc-tiny.c Merge remote-tracking branches 'spi/topic/imx', 'spi/topic/init', 'spi/topic/mpc512x-psc', 'spi/topic/mpc52xx', 'spi/topic/mxs', 'spi/topic/nuc900', 'spi/topic/oc-tiny' and 'spi/topic/octeon' into spi-next 2014-03-30 00:51:17 +00:00
spi-octeon.c Merge remote-tracking branches 'spi/topic/imx', 'spi/topic/init', 'spi/topic/mpc512x-psc', 'spi/topic/mpc52xx', 'spi/topic/mxs', 'spi/topic/nuc900', 'spi/topic/oc-tiny' and 'spi/topic/octeon' into spi-next 2014-03-30 00:51:17 +00:00
spi-omap-100k.c spi: omap-100k: Remove unused definitions 2014-08-16 17:12:14 -05:00
spi-omap-uwire.c spi: omap-uwire: Fix build error 2014-06-24 16:25:48 +01:00
spi-omap2-mcspi.c spi/omap-mcspi: Fix the spi task hangs waiting dma_rx 2014-08-11 19:55:51 +01:00
spi-orion.c spi: orion: fix potential NULL pointer de-reference 2014-10-22 11:05:54 +01:00
spi-pl022.c spi: pl022: Fix race in giveback() leading to driver lock-up 2015-03-28 09:49:32 -04:00
spi-ppc4xx.c spi: delete non-required instances of include <linux/init.h> 2014-02-03 12:20:35 +00:00
spi-pxa2xx-dma.c spi/pxa2xx: Don't use slave_id of dma_slave_config 2014-09-18 11:54:07 +05:30
spi-pxa2xx-pci.c Merge branch 'for-linus' of git://git.infradead.org/users/vkoul/slave-dma 2014-10-18 18:11:04 -07:00
spi-pxa2xx-pxadma.c spi: delete non-required instances of include <linux/init.h> 2014-02-03 12:20:35 +00:00
spi-pxa2xx.c spi/pxa2xx: Clear cur_chip pointer before starting next message 2015-02-05 22:36:07 -08:00
spi-pxa2xx.h spi/pxa2xx: add support for Intel Low Power Subsystem SPI 2013-02-08 13:14:40 +00:00
spi-qup.c Merge remote-tracking branches 'spi/topic/orion', 'spi/topic/pl022', 'spi/topic/qup', 'spi/topic/rockchip' and 'spi/topic/rspi' into spi-next 2014-08-04 17:21:12 +01:00
spi-rockchip.c spi/rockchip: spi controller must be disabled in tx callback too 2014-10-17 14:29:22 +02:00
spi-rspi.c spi: rspi: Add support for new R-Car Gen2 SoCs 2014-08-28 15:33:17 +01:00
spi-s3c24xx-fiq.h spi: reorganize drivers 2011-06-06 01:16:30 -06:00
spi-s3c24xx-fiq.S spi: reorganize drivers 2011-06-06 01:16:30 -06:00
spi-s3c24xx.c Merge remote-tracking branch 'spi/topic/workqueue' into spi-next 2014-06-02 17:08:43 +01:00
spi-s3c64xx.c ARM: SoC cleanups for 3.17 2014-08-08 11:00:26 -07:00
spi-sc18is602.c spi: sc18is602: Convert to let spi core validate transfer speed 2014-03-13 09:47:05 +00:00
spi-sh-hspi.c spi: sh-hspi: Make of_device_id array const 2014-06-06 12:37:41 +01:00
spi-sh-msiof.c spi: sh-msiof: Add runtime PM lock in initializing 2015-01-16 06:59:56 -08:00
spi-sh-sci.c spi: sh-sci: fix use-after-free in sh_sci_spi_remove() 2014-06-17 15:47:31 +01:00
spi-sh.c spi/spi-sh: Use devm_ioremap 2014-07-07 12:50:52 +02:00
spi-sirf.c spi: sirf: fix word width configuration 2014-11-18 14:43:22 +00:00
spi-sun4i.c spi: Remove unneeded include of linux/workqueue.h 2014-04-14 17:20:15 +01:00
spi-sun6i.c spi: Remove unneeded include of linux/workqueue.h 2014-04-14 17:20:15 +01:00
spi-tegra20-sflash.c spi: tegra20-sflash: Fix checkpatch issue 2014-09-03 19:30:27 +01:00
spi-tegra20-slink.c spi: tegra20-slink: Make of_device_id array const 2014-05-07 20:53:05 +01:00
spi-tegra114.c spi: tegra114: Fix checkpatch issue 2014-09-03 19:30:26 +01:00
spi-ti-qspi.c Merge remote-tracking branches 'spi/topic/sunxi', 'spi/topic/tegra114', 'spi/topic/ti-qspi', 'spi/topic/ti-ssp', 'spi/topic/topcliff-pch', 'spi/topic/txx9', 'spi/topic/xcomm' and 'spi/topic/xfer' into spi-next 2014-03-30 00:51:41 +00:00
spi-tle62x0.c spi: tle62x0: remove unnecessary OOM messages 2014-04-29 12:01:42 -07:00
spi-topcliff-pch.c spi: topcliff-pch: don't hardcode PCI slot to get DMA device 2014-07-31 00:03:42 +01:00
spi-txx9.c spi: txx9: Fix checkpatch issue 2014-09-03 19:30:27 +01:00
spi-xcomm.c Merge remote-tracking branches 'spi/topic/sunxi', 'spi/topic/tegra114', 'spi/topic/ti-qspi', 'spi/topic/ti-ssp', 'spi/topic/topcliff-pch', 'spi/topic/txx9', 'spi/topic/xcomm' and 'spi/topic/xfer' into spi-next 2014-03-30 00:51:41 +00:00
spi-xilinx.c spi: xilinx: Remove .owner field for driver 2014-08-16 17:15:47 -05:00
spi-xtensa-xtfpga.c spi: xtensa-xtfpga: Fix checkpatch issue 2014-09-02 11:47:12 +01:00
spi.c spi: Fix mapping from vmalloc-ed buffer to scatter list 2014-11-17 10:40:10 +00:00
spidev.c spi: spidev: Use separate TX and RX bounce buffers 2014-10-13 13:07:12 +02:00