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

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
* 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;
};
...@@ -73,14 +73,6 @@ ...@@ -73,14 +73,6 @@
#define MAX_READY_WAIT_JIFFIES (40 * HZ) /* M25P16 specs 40s max chip erase */ #define MAX_READY_WAIT_JIFFIES (40 * HZ) /* M25P16 specs 40s max chip erase */
#define MAX_CMD_SIZE 5 #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) #define JEDEC_MFR(_jedec_id) ((_jedec_id) >> 16)
/****************************************************************************/ /****************************************************************************/
...@@ -93,6 +85,7 @@ struct m25p { ...@@ -93,6 +85,7 @@ struct m25p {
u16 addr_width; u16 addr_width;
u8 erase_opcode; u8 erase_opcode;
u8 *command; u8 *command;
bool fast_read;
}; };
static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd) 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, ...@@ -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 m25p *flash = mtd_to_m25p(mtd);
struct spi_transfer t[2]; struct spi_transfer t[2];
struct spi_message m; struct spi_message m;
uint8_t opcode;
pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev), pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
__func__, (u32)from, len); __func__, (u32)from, len);
...@@ -354,7 +348,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t 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. * Should add 1 byte DUMMY_BYTE.
*/ */
t[0].tx_buf = flash->command; 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); spi_message_add_tail(&t[0], &m);
t[1].rx_buf = buf; t[1].rx_buf = buf;
...@@ -376,12 +370,14 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, ...@@ -376,12 +370,14 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
*/ */
/* Set up the write data buffer. */ /* 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); m25p_addr2cmd(flash, from, flash->command);
spi_sync(flash->spi, &m); 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); mutex_unlock(&flash->lock);
...@@ -809,9 +805,10 @@ static int __devinit m25p_probe(struct spi_device *spi) ...@@ -809,9 +805,10 @@ static int __devinit m25p_probe(struct spi_device *spi)
struct flash_info *info; struct flash_info *info;
unsigned i; unsigned i;
struct mtd_part_parser_data ppdata; struct mtd_part_parser_data ppdata;
struct device_node __maybe_unused *np = spi->dev.of_node;
#ifdef CONFIG_MTD_OF_PARTS #ifdef CONFIG_MTD_OF_PARTS
if (!of_device_is_available(spi->dev.of_node)) if (!of_device_is_available(np))
return -ENODEV; return -ENODEV;
#endif #endif
...@@ -863,7 +860,8 @@ static int __devinit m25p_probe(struct spi_device *spi) ...@@ -863,7 +860,8 @@ static int __devinit m25p_probe(struct spi_device *spi)
flash = kzalloc(sizeof *flash, GFP_KERNEL); flash = kzalloc(sizeof *flash, GFP_KERNEL);
if (!flash) if (!flash)
return -ENOMEM; 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) { if (!flash->command) {
kfree(flash); kfree(flash);
return -ENOMEM; return -ENOMEM;
...@@ -920,6 +918,16 @@ static int __devinit m25p_probe(struct spi_device *spi) ...@@ -920,6 +918,16 @@ static int __devinit m25p_probe(struct spi_device *spi)
flash->page_size = info->page_size; flash->page_size = info->page_size;
flash->mtd.writebufsize = flash->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) if (info->addr_width)
flash->addr_width = info->addr_width; flash->addr_width = info->addr_width;
else { else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment