Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 12ad2be9 authored by Marek Vasut's avatar Marek Vasut Committed by Artem Bityutskiy
Browse files

mtd: m25p80: Make fast read configurable via DT



Add DT property "m25p,fast-read" that signalises the particular
chip supports "fast read" opcode.

Signed-off-by: default avatarMarek Vasut <marex@denx.de>
Signed-off-by: default avatarArtem Bityutskiy <artem.bityutskiy@linux.intel.com>
parent 2d350e5a
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
* MTD SPI driver for ST M25Pxx (and similar) serial flash chips

Required properties:
- #address-cells, #size-cells : Must be present if the device has sub-nodes
  representing partitions.
- compatible : Should be the manufacturer and the name of the chip. Bear in mind
               the DT binding is not Linux-only, but in case of Linux, see the
               "m25p_ids" table in drivers/mtd/devices/m25p80.c for the list of
               supported chips.
- reg : Chip-Select number
- spi-max-frequency : Maximum frequency of the SPI bus the chip can operate at

Optional properties:
- m25p,fast-read : Use the "fast read" opcode to read data from the chip instead
                   of the usual "read" opcode. This opcode is not supported by
                   all chips and support for it can not be detected at runtime.
                   Refer to your chips' datasheet to check if this is supported
                   by your chip.

Example:

	flash: m25p80@0 {
		#address-cells = <1>;
		#size-cells = <1>;
		compatible = "spansion,m25p80";
		reg = <0>;
		spi-max-frequency = <40000000>;
		m25p,fast-read;
	};
+21 −13
Original line number Diff line number Diff line
@@ -73,14 +73,6 @@
#define	MAX_READY_WAIT_JIFFIES	(40 * HZ)	/* M25P16 specs 40s max chip erase */
#define	MAX_CMD_SIZE		5

#ifdef CONFIG_M25PXX_USE_FAST_READ
#define OPCODE_READ 	OPCODE_FAST_READ
#define FAST_READ_DUMMY_BYTE 1
#else
#define OPCODE_READ 	OPCODE_NORM_READ
#define FAST_READ_DUMMY_BYTE 0
#endif

#define JEDEC_MFR(_jedec_id)	((_jedec_id) >> 16)

/****************************************************************************/
@@ -93,6 +85,7 @@ struct m25p {
	u16			addr_width;
	u8			erase_opcode;
	u8			*command;
	bool			fast_read;
};

static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)
@@ -342,6 +335,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
	struct m25p *flash = mtd_to_m25p(mtd);
	struct spi_transfer t[2];
	struct spi_message m;
	uint8_t opcode;

	pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
			__func__, (u32)from, len);
@@ -354,7 +348,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
	 * Should add 1 byte DUMMY_BYTE.
	 */
	t[0].tx_buf = flash->command;
	t[0].len = m25p_cmdsz(flash) + FAST_READ_DUMMY_BYTE;
	t[0].len = m25p_cmdsz(flash) + (flash->fast_read ? 1 : 0);
	spi_message_add_tail(&t[0], &m);

	t[1].rx_buf = buf;
@@ -376,12 +370,14 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
	 */

	/* Set up the write data buffer. */
	flash->command[0] = OPCODE_READ;
	opcode = flash->fast_read ? OPCODE_FAST_READ : OPCODE_NORM_READ;
	flash->command[0] = opcode;
	m25p_addr2cmd(flash, from, flash->command);

	spi_sync(flash->spi, &m);

	*retlen = m.actual_length - m25p_cmdsz(flash) - FAST_READ_DUMMY_BYTE;
	*retlen = m.actual_length - m25p_cmdsz(flash) -
			(flash->fast_read ? 1 : 0);

	mutex_unlock(&flash->lock);

@@ -809,9 +805,10 @@ static int __devinit m25p_probe(struct spi_device *spi)
	struct flash_info		*info;
	unsigned			i;
	struct mtd_part_parser_data	ppdata;
	struct device_node __maybe_unused *np = spi->dev.of_node;

#ifdef CONFIG_MTD_OF_PARTS
	if (!of_device_is_available(spi->dev.of_node))
	if (!of_device_is_available(np))
		return -ENODEV;
#endif

@@ -863,7 +860,8 @@ static int __devinit m25p_probe(struct spi_device *spi)
	flash = kzalloc(sizeof *flash, GFP_KERNEL);
	if (!flash)
		return -ENOMEM;
	flash->command = kmalloc(MAX_CMD_SIZE + FAST_READ_DUMMY_BYTE, GFP_KERNEL);
	flash->command = kmalloc(MAX_CMD_SIZE + (flash->fast_read ? 1 : 0),
					GFP_KERNEL);
	if (!flash->command) {
		kfree(flash);
		return -ENOMEM;
@@ -920,6 +918,16 @@ static int __devinit m25p_probe(struct spi_device *spi)
	flash->page_size = info->page_size;
	flash->mtd.writebufsize = flash->page_size;

	flash->fast_read = false;
#ifdef CONFIG_OF
	if (np && of_property_read_bool(np, "m25p,fast-read"))
		flash->fast_read = true;
#endif

#ifdef CONFIG_M25PXX_USE_FAST_READ
	flash->fast_read = true;
#endif

	if (info->addr_width)
		flash->addr_width = info->addr_width;
	else {