Loading Documentation/devicetree/bindings/mtd/m25p80.txt 0 → 100644 +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; }; drivers/mtd/devices/m25p80.c +21 −13 Original line number Diff line number Diff line Loading @@ -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) /****************************************************************************/ Loading @@ -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) Loading Loading @@ -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); Loading @@ -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; Loading @@ -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); Loading Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -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 { Loading Loading
Documentation/devicetree/bindings/mtd/m25p80.txt 0 → 100644 +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; };
drivers/mtd/devices/m25p80.c +21 −13 Original line number Diff line number Diff line Loading @@ -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) /****************************************************************************/ Loading @@ -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) Loading Loading @@ -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); Loading @@ -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; Loading @@ -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); Loading Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -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 { Loading