linux/drivers/mtd/spi-nor
Mika Westerberg c7d6a82d90 mtd: spi-nor: intel-spi: Fix atomic sequence handling
On many older systems using SW sequencer the PREOP_OPTYPE register
contains two preopcodes as following:

  PREOP_OPTYPE=0xf2785006

The last two bytes are the opcodes decoded to:

  0x50 - Write enable for volatile status register
  0x06 - Write enable

The former is used to modify volatile bits in the status register. For
non-volatile bits the latter is needed. Preopcodes are used in SW
sequencer to send one command "atomically" without anything else
interfering the transfer. The sequence that gets executed is:

  - Send preopcode (write enable) from PREOP_OPTYPE register
  - Send the actual SPI command
  - Poll busy bit in the status register (0x05, RDSR)

Commit 8c473dd61b ("spi-nor: intel-spi: Don't assume OPMENU0/1 to be
programmed by BIOS") enabled atomic sequence handling but because both
preopcodes are programmed, the following happens:

  if (preop >> 8)
  	val |= SSFSTS_CTL_SPOP;

Since on these systems preop >> 8 == 0x50 we end up picking volatile
write enable instead. Because of this the actual write command is pretty
much NOP unless there is a WREN latched in the chip already.

Furthermore we should not really just assume that WREN was issued in
previous call to intel_spi_write_reg() because that might not be the
case.

This updates driver to first check that the opcode is actually available
in PREOP_OPTYPE register and if not return error back to the spi-nor
core (if the controller is not locked we program it now). In addition we
save the opcode to ispi->atomic_preopcode field which is checked in next
call to intel_spi_sw_cycle() to actually enable atomic sequence using
the requested preopcode.

Fixes: 8c473dd61b ("spi-nor: intel-spi: Don't assume OPMENU0/1 to be programmed by BIOS")
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Cc: stable@vger.kernel.org
Reviewed-by: Marek Vasut <marek.vasut@gmail.com>
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
2018-05-18 12:53:05 +02:00
..
aspeed-smc.c mtd: spi-nor: aspeed: set 4B setting for all chips 2017-08-14 17:23:50 +02:00
atmel-quadspi.c mtd: atmel-quadspi: Remove unneeded pinctrl header 2017-08-01 21:23:21 +02:00
cadence-quadspi.c mtd: spi-nor: cadence-quadspi: Add DMA support for direct mode reads 2018-04-20 22:53:52 +02:00
fsl-quadspi.c mtd: fsl-quadspi: Distinguish the mtd device names 2018-03-30 10:04:53 +02:00
hisi-sfc.c mtd: spi-nor: hisi: Avoid generic function names 2018-04-20 22:54:36 +02:00
intel-spi-pci.c mtd: intel-spi: Add Intel Lewisburg PCH SPI super SKU PCI ID 2017-10-30 11:51:18 +01:00
intel-spi-platform.c spi-nor: Add support for Intel SPI serial flash controller 2017-01-03 17:33:36 +00:00
intel-spi.c mtd: spi-nor: intel-spi: Fix atomic sequence handling 2018-05-18 12:53:05 +02:00
intel-spi.h spi-nor: Add support for Intel SPI serial flash controller 2017-01-03 17:33:36 +00:00
Kconfig spi-nor: intel-spi: Remove EXPERT dependency 2017-10-25 00:17:34 +02:00
Makefile License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
mtk-quadspi.c mtd: mtk-nor: modify functions' name more generally 2018-01-14 16:14:06 +01:00
nxp-spifi.c mtd: spi-nor: introduce SPI 1-2-2 and SPI 1-4-4 protocols 2017-05-15 21:56:17 +02:00
spi-nor.c mtd: spi-nor: clear Winbond Extended Address Reg on switch to 3-byte addressing. 2018-04-21 10:05:23 +02:00
stm32-quadspi.c mtd: spi-nor: stm32-quadspi: fix prefetching outside fsize 2017-10-29 18:54:22 +01:00