Commit b5e16170 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'for-linus-20170713' of git://git.infradead.org/linux-mtd

Pull MTD updates from Brian Norris:
 "General updates:
   - Cleanups and additional flash support for "dataflash" driver
   - new driver for mchp23k256 SPI SRAM device
   - improve handling of MTDs without eraseblocks (i.e., MTD_NO_ERASE)
   - refactor and improve "sub-partition" handling with TRX partition
     parser; partitions can now be created as sub-partitions of another
     partition

  SPINOR updates, from Cyrille Pitchen and Marek Vasut:
   - introduce support to the SPI 1-2-2 and 1-4-4 protocols.
   - introduce support to the Double Data Rate (DDR) mode.
   - introduce support to the Octo SPI protocols.
   - add support to new memory parts for Spansion, Macronix and Winbond.
   - add fixes for the Aspeed, STM32 and Cadence QSPI controler drivers.
   - clean up the st_spi_fsm driver.

  NAND updates, from Boris Brezillon:
   - addition of on-die ECC support to Micron driver
   - addition of helpers to help drivers choose most appropriate ECC
     settings
   - deletion of dead-code (cached programming and ->errstat() hook)
   - make sure drivers that do not support the SET/GET FEATURES command
     return ENOTSUPP use a dummy ->set/get_features implementation
     returning -ENOTSUPP (required for Micron on-die ECC)
   - change the semantic of ecc->write_page() for drivers setting the
     NAND_ECC_CUSTOM_PAGE_ACCESS flag
   - support exiting 'GET STATUS' command in default ->cmdfunc()
     implementations
   - change the prototype of ->setup_data_interface()

  A bunch of driver related changes:
   - various cleanup, fixes and improvements of the MTK driver
   - OMAP DT bindings fixes
   - support for ->setup_data_interface() in the fsmc driver
   - support for imx7 in the gpmi driver
   - finalization of the denali driver rework (thanks to Masahiro for
     the work he's done on this driver)
   - fix "bitflips in erased pages" handling in the ifc driver
   - addition of PM ops and dynamic timing configuration to the atmel
     driver"

* tag 'for-linus-20170713' of git://git.infradead.org/linux-mtd: (118 commits)
  Documentation: ABI: mtd: describe "offset" more precisely
  mtd: Fix check in mtd_unpoint()
  mtd: nand: mtk: release lock on error path
  mtd: st_spi_fsm: remove SPINOR_OP_RDSR2 and use SPINOR_OP_RDCR instead
  mtd: spi-nor: cqspi: remove duplicate const
  mtd: spi-nor: Add support for Spansion S25FL064L
  mtd: spi-nor: Add support for mx66u51235f
  mtd: nand: mtk: add ->setup_data_interface() hook
  mtd: nand: mtk: remove unneeded mtk_ecc_hw_init from mtk_ecc_resume
  mtd: nand: mtk: remove unneeded mtk_nfc_hw_init from mtk_nfc_resume
  mtd: nand: mtk: disable ecc irq when writing page with hwecc
  mtd: nand: mtk: fix incorrect register setting order about ecc irq
  mtd: partitions: fixup some allocate_partition() whitespace
  mtd: parsers: trx: fix pr_err format for printing offset
  MAINTAINERS: Update SPI NOR subsystem git repositories
  mtd: extract TRX parser out of bcm47xxpart into a separated module
  mtd: partitions: add support for partition parsers
  mtd: partitions: add support for subpartitions
  mtd: partitions: rename "master" to the "parent" where appropriate
  mtd: partitions: remove sysfs files when deleting all master's partitions
  ...
parents da16dd97 7d84120b
......@@ -229,6 +229,6 @@ KernelVersion: 4.1
Contact: linux-mtd@lists.infradead.org
Description:
For a partition, the offset of that partition from the start
of the master device in bytes. This attribute is absent on
main devices, so it can be used to distinguish between
partitions and devices that aren't partitions.
of the parent (another partition or a flash device) in bytes.
This attribute is absent on flash devices, so it can be used
to distinguish them from partitions.
......@@ -3,10 +3,23 @@
Required properties:
- compatible : should be one of the following:
"altr,socfpga-denali-nand" - for Altera SOCFPGA
"socionext,uniphier-denali-nand-v5a" - for Socionext UniPhier (v5a)
"socionext,uniphier-denali-nand-v5b" - for Socionext UniPhier (v5b)
- reg : should contain registers location and length for data and reg.
- reg-names: Should contain the reg names "nand_data" and "denali_reg"
- interrupts : The interrupt number.
Optional properties:
- nand-ecc-step-size: see nand.txt for details. If present, the value must be
512 for "altr,socfpga-denali-nand"
1024 for "socionext,uniphier-denali-nand-v5a"
1024 for "socionext,uniphier-denali-nand-v5b"
- nand-ecc-strength: see nand.txt for details. Valid values are:
8, 15 for "altr,socfpga-denali-nand"
8, 16, 24 for "socionext,uniphier-denali-nand-v5a"
8, 16 for "socionext,uniphier-denali-nand-v5b"
- nand-ecc-maximize: see nand.txt for details
The device tree may optionally contain sub-nodes describing partitions of the
address space. See partition.txt for more detail.
......
Error location module
Required properties:
- compatible: Must be "ti,am33xx-elm"
- compatible: Must be "ti,am3352-elm"
- reg: physical base address and size of the registers map.
- interrupts: Interrupt number for the elm.
......
......@@ -5,7 +5,7 @@ the GPMC controller with a name of "nand".
All timing relevant properties as well as generic gpmc child properties are
explained in a separate documents - please refer to
Documentation/devicetree/bindings/bus/ti-gpmc.txt
Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
For NAND specific properties such as ECC modes or bus width, please refer to
Documentation/devicetree/bindings/mtd/nand.txt
......
......@@ -5,7 +5,7 @@ child nodes of the GPMC controller with a name of "nor".
All timing relevant properties as well as generic GPMC child properties are
explained in a separate documents. Please refer to
Documentation/devicetree/bindings/bus/ti-gpmc.txt
Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
Required properties:
- bank-width: Width of NOR flash in bytes. GPMC supports 8-bit and
......@@ -28,7 +28,7 @@ Required properties:
Optional properties:
- gpmc,XXX Additional GPMC timings and settings parameters. See
Documentation/devicetree/bindings/bus/ti-gpmc.txt
Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
Optional properties for partition table parsing:
- #address-cells: should be set to 1
......
......@@ -5,7 +5,7 @@ the GPMC controller with a name of "onenand".
All timing relevant properties as well as generic gpmc child properties are
explained in a separate documents - please refer to
Documentation/devicetree/bindings/bus/ti-gpmc.txt
Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
Required properties:
......
......@@ -4,7 +4,12 @@ The GPMI nand controller provides an interface to control the
NAND flash chips.
Required properties:
- compatible : should be "fsl,<chip>-gpmi-nand"
- compatible : should be "fsl,<chip>-gpmi-nand", chip can be:
* imx23
* imx28
* imx6q
* imx6sx
* imx7d
- reg : should contain registers location and length for gpmi and bch.
- reg-names: Should contain the reg names "gpmi-nand" and "bch"
- interrupts : BCH interrupt number.
......@@ -13,6 +18,13 @@ Required properties:
and GPMI DMA channel ID.
Refer to dma.txt and fsl-mxs-dma.txt for details.
- dma-names: Must be "rx-tx".
- clocks : clocks phandle and clock specifier corresponding to each clock
specified in clock-names.
- clock-names : The "gpmi_io" clock is always required. Which clocks are
exactly required depends on chip:
* imx23/imx28 : "gpmi_io"
* imx6q/sx : "gpmi_io", "gpmi_apb", "gpmi_bch", "gpmi_bch_apb", "per1_bch"
* imx7d : "gpmi_io", "gpmi_bch_apb"
Optional properties:
- nand-on-flash-bbt: boolean to enable on flash bbt option if not
......
* MTD SPI driver for Microchip 23K256 (and similar) serial SRAM
Required properties:
- #address-cells, #size-cells : Must be present if the device has sub-nodes
representing partitions.
- compatible : Must be one of "microchip,mchp23k256" or "microchip,mchp23lcv1024"
- reg : Chip-Select number
- spi-max-frequency : Maximum frequency of the SPI bus the chip can operate at
Example:
spi-sram@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "microchip,mchp23k256";
reg = <0>;
spi-max-frequency = <20000000>;
};
......@@ -12,7 +12,8 @@ tree nodes.
The first part of NFC is NAND Controller Interface (NFI) HW.
Required NFI properties:
- compatible: Should be "mediatek,mtxxxx-nfc".
- compatible: Should be one of "mediatek,mt2701-nfc",
"mediatek,mt2712-nfc".
- reg: Base physical address and size of NFI.
- interrupts: Interrupts of NFI.
- clocks: NFI required clocks.
......@@ -141,7 +142,7 @@ Example:
==============
Required BCH properties:
- compatible: Should be "mediatek,mtxxxx-ecc".
- compatible: Should be one of "mediatek,mt2701-ecc", "mediatek,mt2712-ecc".
- reg: Base physical address and size of ECC.
- interrupts: Interrupts of ECC.
- clocks: ECC required clocks.
......
......@@ -21,7 +21,7 @@ Optional NAND chip properties:
- nand-ecc-mode : String, operation mode of the NAND ecc mode.
Supported values are: "none", "soft", "hw", "hw_syndrome",
"hw_oob_first".
"hw_oob_first", "on-die".
Deprecated values:
"soft_bch": use "soft" and nand-ecc-algo instead
- nand-ecc-algo: string, algorithm of NAND ECC.
......
Representing flash partitions in devicetree
Flash partitions in device tree
===============================
Partitions can be represented by sub-nodes of an mtd device. This can be used
Flash devices can be partitioned into one or more functional ranges (e.g. "boot
code", "nvram", "kernel").
Different devices may be partitioned in a different ways. Some may use a fixed
flash layout set at production time. Some may use on-flash table that describes
the geometry and naming/purpose of each functional region. It is also possible
to see these methods mixed.
To assist system software in locating partitions, we allow describing which
method is used for a given flash device. To describe the method there should be
a subnode of the flash device that is named 'partitions'. It must have a
'compatible' property, which is used to identify the method to use.
We currently only document a binding for fixed layouts.
Fixed Partitions
================
Partitions can be represented by sub-nodes of a flash device. This can be used
on platforms which have strong conventions about which portions of a flash are
used for what purposes, but which don't use an on-flash partition table such
as RedBoot.
The partition table should be a subnode of the mtd node and should be named
The partition table should be a subnode of the flash node and should be named
'partitions'. This node should have the following property:
- compatible : (required) must be "fixed-partitions"
Partitions are then defined in subnodes of the partitions node.
For backwards compatibility partitions as direct subnodes of the mtd device are
For backwards compatibility partitions as direct subnodes of the flash device are
supported. This use is discouraged.
NOTE: also for backwards compatibility, direct subnodes that have a compatible
string are not considered partitions, as they may be used for other bindings.
#address-cells & #size-cells must both be present in the partitions subnode of the
mtd device. There are two valid values for both:
flash device. There are two valid values for both:
<1>: for partitions that require a single 32-bit cell to represent their
size/address (aka the value is below 4 GiB)
<2>: for partitions that require two 32-bit cells to represent their
size/address (aka the value is 4 GiB or greater).
Required properties:
- reg : The partition's offset and size within the mtd bank.
- reg : The partition's offset and size within the flash
Optional properties:
- label : The label / name for this partition. If omitted, the label is taken
......
......@@ -9,7 +9,7 @@ the GPMC controller with an "ethernet" name.
All timing relevant properties as well as generic GPMC child properties are
explained in a separate documents. Please refer to
Documentation/devicetree/bindings/bus/ti-gpmc.txt
Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
For the properties relevant to the ethernet controller connected to the GPMC
refer to the binding documentation of the device. For example, the documentation
......@@ -43,7 +43,7 @@ Required properties:
Optional properties:
- gpmc,XXX Additional GPMC timings and settings parameters. See
Documentation/devicetree/bindings/bus/ti-gpmc.txt
Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
Example:
......
......@@ -3974,6 +3974,12 @@ M: Pali Rohár <pali.rohar@gmail.com>
S: Maintained
F: drivers/platform/x86/dell-wmi.c
DENALI NAND DRIVER
M: Masahiro Yamada <yamada.masahiro@socionext.com>
L: linux-mtd@lists.infradead.org
S: Supported
F: drivers/mtd/nand/denali*
DESIGNWARE USB2 DRD IP DRIVER
M: John Youn <johnyoun@synopsys.com>
L: linux-usb@vger.kernel.org
......@@ -12464,7 +12470,8 @@ M: Marek Vasut <marek.vasut@gmail.com>
L: linux-mtd@lists.infradead.org
W: http://www.linux-mtd.infradead.org/
Q: http://patchwork.ozlabs.org/project/linux-mtd/list/
T: git git://github.com/spi-nor/linux.git
T: git git://git.infradead.org/linux-mtd.git spi-nor/fixes
T: git git://git.infradead.org/l2-mtd.git spi-nor/next
S: Maintained
F: drivers/mtd/spi-nor/
F: include/linux/mtd/spi-nor.h
......
......@@ -155,6 +155,10 @@ config MTD_BCM47XX_PARTS
This provides partitions parser for devices based on BCM47xx
boards.
menu "Partition parsers"
source "drivers/mtd/parsers/Kconfig"
endmenu
comment "User Modules And Translation Layers"
#
......
......@@ -13,6 +13,7 @@ obj-$(CONFIG_MTD_AFS_PARTS) += afs.o
obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o
obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o
obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm47xxpart.o
obj-y += parsers/
# 'Users' - code which presents functionality to userspace.
obj-$(CONFIG_MTD_BLKDEVS) += mtd_blkdevs.o
......
......@@ -43,7 +43,8 @@
#define ML_MAGIC2 0x26594131
#define TRX_MAGIC 0x30524448
#define SHSQ_MAGIC 0x71736873 /* shsq (weird ZTE H218N endianness) */
#define UBI_EC_MAGIC 0x23494255 /* UBI# */
static const char * const trx_types[] = { "trx", NULL };
struct trx_header {
uint32_t magic;
......@@ -62,89 +63,6 @@ static void bcm47xxpart_add_part(struct mtd_partition *part, const char *name,
part->mask_flags = mask_flags;
}
static const char *bcm47xxpart_trx_data_part_name(struct mtd_info *master,
size_t offset)
{
uint32_t buf;
size_t bytes_read;
int err;
err = mtd_read(master, offset, sizeof(buf), &bytes_read,
(uint8_t *)&buf);
if (err && !mtd_is_bitflip(err)) {
pr_err("mtd_read error while parsing (offset: 0x%X): %d\n",
offset, err);
goto out_default;
}
if (buf == UBI_EC_MAGIC)
return "ubi";
out_default:
return "rootfs";
}
static int bcm47xxpart_parse_trx(struct mtd_info *master,
struct mtd_partition *trx,
struct mtd_partition *parts,
size_t parts_len)
{
struct trx_header header;
size_t bytes_read;
int curr_part = 0;
int i, err;
if (parts_len < 3) {
pr_warn("No enough space to add TRX partitions!\n");
return -ENOMEM;
}
err = mtd_read(master, trx->offset, sizeof(header), &bytes_read,
(uint8_t *)&header);
if (err && !mtd_is_bitflip(err)) {
pr_err("mtd_read error while reading TRX header: %d\n", err);
return err;
}
i = 0;
/* We have LZMA loader if offset[2] points to sth */
if (header.offset[2]) {
bcm47xxpart_add_part(&parts[curr_part++], "loader",
trx->offset + header.offset[i], 0);
i++;
}
if (header.offset[i]) {
bcm47xxpart_add_part(&parts[curr_part++], "linux",
trx->offset + header.offset[i], 0);
i++;
}
if (header.offset[i]) {
size_t offset = trx->offset + header.offset[i];
const char *name = bcm47xxpart_trx_data_part_name(master,
offset);
bcm47xxpart_add_part(&parts[curr_part++], name, offset, 0);
i++;
}
/*
* Assume that every partition ends at the beginning of the one it is
* followed by.
*/
for (i = 0; i < curr_part; i++) {
u64 next_part_offset = (i < curr_part - 1) ?
parts[i + 1].offset :
trx->offset + trx->size;
parts[i].size = next_part_offset - parts[i].offset;
}
return curr_part;
}
/**
* bcm47xxpart_bootpartition - gets index of TRX partition used by bootloader
*
......@@ -362,17 +280,10 @@ static int bcm47xxpart_parse(struct mtd_info *master,
for (i = 0; i < trx_num; i++) {
struct mtd_partition *trx = &parts[trx_parts[i]];
if (i == bcm47xxpart_bootpartition()) {
int num_parts;
num_parts = bcm47xxpart_parse_trx(master, trx,
parts + curr_part,
BCM47XXPART_MAX_PARTS - curr_part);
if (num_parts > 0)
curr_part += num_parts;
} else {
if (i == bcm47xxpart_bootpartition())
trx->types = trx_types;
else
trx->name = "failsafe";
}
}
*pparts = parts;
......
......@@ -666,7 +666,7 @@ cfi_staa_writev(struct mtd_info *mtd, const struct kvec *vecs,
size_t totlen = 0, thislen;
int ret = 0;
size_t buflen = 0;
static char *buffer;
char *buffer;
if (!ECCBUF_SIZE) {
/* We should fall back to a general writev implementation.
......
......@@ -95,6 +95,16 @@ config MTD_M25P80
if you want to specify device partitioning or to use a device which
doesn't support the JEDEC ID instruction.
config MTD_MCHP23K256
tristate "Microchip 23K256 SRAM"
depends on SPI_MASTER
help
This enables access to Microchip 23K256 SRAM chips, using SPI.
Set up your spi devices with the right board-specific
platform data, or a device tree description if you want to
specify device partitioning
config MTD_SPEAR_SMI
tristate "SPEAR MTD NOR Support through SMI controller"
depends on PLAT_SPEAR
......
......@@ -12,6 +12,7 @@ obj-$(CONFIG_MTD_LART) += lart.o
obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o
obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o
obj-$(CONFIG_MTD_M25P80) += m25p80.o
obj-$(CONFIG_MTD_MCHP23K256) += mchp23k256.o
obj-$(CONFIG_MTD_SPEAR_SMI) += spear_smi.o
obj-$(CONFIG_MTD_SST25L) += sst25l.o
obj-$(CONFIG_MTD_BCM47XXSFLASH) += bcm47xxsflash.o
......
......@@ -78,11 +78,17 @@ static ssize_t m25p80_write(struct spi_nor *nor, loff_t to, size_t len,
{
struct m25p *flash = nor->priv;
struct spi_device *spi = flash->spi;
struct spi_transfer t[2] = {};
unsigned int inst_nbits, addr_nbits, data_nbits, data_idx;
struct spi_transfer t[3] = {};
struct spi_message m;
int cmd_sz = m25p_cmdsz(nor);
ssize_t ret;
/* get transfer protocols. */
inst_nbits = spi_nor_get_protocol_inst_nbits(nor->write_proto);
addr_nbits = spi_nor_get_protocol_addr_nbits(nor->write_proto);
data_nbits = spi_nor_get_protocol_data_nbits(nor->write_proto);
spi_message_init(&m);
if (nor->program_opcode == SPINOR_OP_AAI_WP && nor->sst_write_second)
......@@ -92,12 +98,27 @@ static ssize_t m25p80_write(struct spi_nor *nor, loff_t to, size_t len,
m25p_addr2cmd(nor, to, flash->command);
t[0].tx_buf = flash->command;
t[0].tx_nbits = inst_nbits;
t[0].len = cmd_sz;
spi_message_add_tail(&t[0], &m);
t[1].tx_buf = buf;
t[1].len = len;
spi_message_add_tail(&t[1], &m);
/* split the op code and address bytes into two transfers if needed. */
data_idx = 1;
if (addr_nbits != inst_nbits) {
t[0].len = 1;
t[1].tx_buf = &flash->command[1];
t[1].tx_nbits = addr_nbits;
t[1].len = cmd_sz - 1;
spi_message_add_tail(&t[1], &m);
data_idx = 2;
}
t[data_idx].tx_buf = buf;
t[data_idx].tx_nbits = data_nbits;
t[data_idx].len = len;
spi_message_add_tail(&t[data_idx], &m);
ret = spi_sync(spi, &m);
if (ret)
......@@ -109,18 +130,6 @@ static ssize_t m25p80_write(struct spi_nor *nor, loff_t to, size_t len,
return ret;
}
static inline unsigned int m25p80_rx_nbits(struct spi_nor *nor)
{
switch (nor->flash_read) {
case SPI_NOR_DUAL:
return 2;
case SPI_NOR_QUAD:
return 4;
default:
return 0;
}
}
/*
* Read an address range from the nor chip. The address range
* may be any size provided it is within the physical boundaries.
......@@ -130,13 +139,20 @@ static ssize_t m25p80_read(struct spi_nor *nor, loff_t from, size_t len,
{
struct m25p *flash = nor->priv;
struct spi_device *spi = flash->spi;
struct spi_transfer t[2];
unsigned int inst_nbits, addr_nbits, data_nbits, data_idx;
struct spi_transfer t[3];
struct spi_message m;
unsigned int dummy = nor->read_dummy;
ssize_t ret;
int cmd_sz;
/* get transfer protocols. */
inst_nbits = spi_nor_get_protocol_inst_nbits(nor->read_proto);
addr_nbits = spi_nor_get_protocol_addr_nbits(nor->read_proto);
data_nbits = spi_nor_get_protocol_data_nbits(nor->read_proto);
/* convert the dummy cycles to the number of bytes */
dummy /= 8;
dummy = (dummy * addr_nbits) / 8;
if (spi_flash_read_supported(spi)) {
struct spi_flash_read_message msg;
......@@ -149,10 +165,9 @@ static ssize_t m25p80_read(struct spi_nor *nor, loff_t from, size_t len,
msg.read_opcode = nor->read_opcode;
msg.addr_width = nor->addr_width;
msg.dummy_bytes = dummy;
/* TODO: Support other combinations */
msg.opcode_nbits = SPI_NBITS_SINGLE;
msg.addr_nbits = SPI_NBITS_SINGLE;
msg.data_nbits = m25p80_rx_nbits(nor);
msg.opcode_nbits = inst_nbits;
msg.addr_nbits = addr_nbits;
msg.data_nbits = data_nbits;
ret = spi_flash_read(spi, &msg);
if (ret < 0)
......@@ -167,20 +182,45 @@ static ssize_t m25p80_read(struct spi_nor *nor, loff_t from, size_t len,
m25p_addr2cmd(nor, from, flash->command);
t[0].tx_buf = flash->command;
t[0].tx_nbits = inst_nbits;
t[0].len = m25p_cmdsz(nor) + dummy;
spi_message_add_tail(&t[0], &m);
t[1].rx_buf = buf;
t[1].rx_nbits = m25p80_rx_nbits(nor);
t[1].len = min3(len, spi_max_transfer_size(spi),
spi_max_message_size(spi) - t[0].len);
spi_message_add_tail(&t[1], &m);
/*
* Set all dummy/mode cycle bits to avoid sending some manufacturer
* specific pattern, which might make the memory enter its Continuous
* Read mode by mistake.
* Based on the different mode cycle bit patterns listed and described
* in the JESD216B specification, the 0xff value works for all memories
* and all manufacturers.
*/
cmd_sz = t[0].len;
memset(flash->command + cmd_sz - dummy, 0xff, dummy);
/* split the op code and address bytes into two transfers if needed. */
data_idx = 1;
if (addr_nbits != inst_nbits) {
t[0].len = 1;
t[1].tx_buf = &flash->command[1];
t[1].tx_nbits = addr_nbits;
t[1].len = cmd_sz - 1;
spi_message_add_tail(&t[1], &m);
data_idx = 2;
}
t[data_idx].rx_buf = buf;
t[data_idx].rx_nbits = data_nbits;
t[data_idx].len = min3(len, spi_max_transfer_size(spi),
spi_max_message_size(spi) - cmd_sz);
spi_message_add_tail(&t[data_idx], &m);
ret = spi_sync(spi, &m);
if (ret)
return ret;
ret = m.actual_length - m25p_cmdsz(nor) - dummy;
ret = m.actual_length - cmd_sz;
if (ret < 0)
return -EIO;
return ret;
......@@ -196,7 +236,11 @@ static int m25p_probe(struct spi_device *spi)
struct flash_platform_data *data;
struct m25p *flash;
struct spi_nor *nor;
enum read_mode mode = SPI_NOR_NORMAL;
struct spi_nor_hwcaps hwcaps = {
.mask = SNOR_HWCAPS_READ |
SNOR_HWCAPS_READ_FAST |
SNOR_HWCAPS_PP,
};
char *flash_name;
int ret;
......@@ -221,10 +265,19 @@ static int m25p_probe(struct spi_device *spi)
spi_set_drvdata(spi, flash);
flash->spi = spi;
if (spi->mode & SPI_RX_QUAD)
mode = SPI_NOR_QUAD;
else if (spi->mode & SPI_RX_DUAL)
mode = SPI_NOR_DUAL;
if (spi->mode & SPI_RX_QUAD) {
hwcaps.mask |= SNOR_HWCAPS_READ_1_1_4;
if (spi->mode & SPI_TX_QUAD)
hwcaps.mask |= (SNOR_HWCAPS_READ_1_4_4 |
SNOR_HWCAPS_PP_1_1_4 |
SNOR_HWCAPS_PP_1_4_4);
} else if (spi->mode & SPI_RX_DUAL) {