aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Vasut <marex@denx.de>2012-09-23 21:39:39 -0400
committerArtem Bityutskiy <artem.bityutskiy@linux.intel.com>2012-11-15 08:37:46 -0500
commit12ad2be9d1db3dcce08f29bdc5415db3af58fa60 (patch)
treefed5730ae8874534d8ccdcebaf05634f8f822f7c
parent2d350e5adb44b3fbc3b6d7ff5b8d086e7730c9b4 (diff)
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: Marek Vasut <marex@denx.de> Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
-rw-r--r--Documentation/devicetree/bindings/mtd/m25p80.txt29
-rw-r--r--drivers/mtd/devices/m25p80.c34
2 files changed, 50 insertions, 13 deletions
diff --git a/Documentation/devicetree/bindings/mtd/m25p80.txt b/Documentation/devicetree/bindings/mtd/m25p80.txt
new file mode 100644
index 000000000000..6d3d57609470
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/m25p80.txt
@@ -0,0 +1,29 @@
1* MTD SPI driver for ST M25Pxx (and similar) serial flash chips
2
3Required properties:
4- #address-cells, #size-cells : Must be present if the device has sub-nodes
5 representing partitions.
6- compatible : Should be the manufacturer and the name of the chip. Bear in mind
7 the DT binding is not Linux-only, but in case of Linux, see the
8 "m25p_ids" table in drivers/mtd/devices/m25p80.c for the list of
9 supported chips.
10- reg : Chip-Select number
11- spi-max-frequency : Maximum frequency of the SPI bus the chip can operate at
12
13Optional properties:
14- m25p,fast-read : Use the "fast read" opcode to read data from the chip instead
15 of the usual "read" opcode. This opcode is not supported by
16 all chips and support for it can not be detected at runtime.
17 Refer to your chips' datasheet to check if this is supported
18 by your chip.
19
20Example:
21
22 flash: m25p80@0 {
23 #address-cells = <1>;
24 #size-cells = <1>;
25 compatible = "spansion,m25p80";
26 reg = <0>;
27 spi-max-frequency = <40000000>;
28 m25p,fast-read;
29 };
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 03838bab1f59..82f977456b88 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -73,14 +73,6 @@
73#define MAX_READY_WAIT_JIFFIES (40 * HZ) /* M25P16 specs 40s max chip erase */ 73#define MAX_READY_WAIT_JIFFIES (40 * HZ) /* M25P16 specs 40s max chip erase */
74#define MAX_CMD_SIZE 5 74#define MAX_CMD_SIZE 5
75 75
76#ifdef CONFIG_M25PXX_USE_FAST_READ
77#define OPCODE_READ OPCODE_FAST_READ
78#define FAST_READ_DUMMY_BYTE 1
79#else
80#define OPCODE_READ OPCODE_NORM_READ
81#define FAST_READ_DUMMY_BYTE 0
82#endif
83
84#define JEDEC_MFR(_jedec_id) ((_jedec_id) >> 16) 76#define JEDEC_MFR(_jedec_id) ((_jedec_id) >> 16)
85 77
86/****************************************************************************/ 78/****************************************************************************/
@@ -93,6 +85,7 @@ struct m25p {
93 u16 addr_width; 85 u16 addr_width;
94 u8 erase_opcode; 86 u8 erase_opcode;
95 u8 *command; 87 u8 *command;
88 bool fast_read;
96}; 89};
97 90
98static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd) 91static 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 struct m25p *flash = mtd_to_m25p(mtd); 335 struct m25p *flash = mtd_to_m25p(mtd);
343 struct spi_transfer t[2]; 336 struct spi_transfer t[2];
344 struct spi_message m; 337 struct spi_message m;
338 uint8_t opcode;
345 339
346 pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev), 340 pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
347 __func__, (u32)from, len); 341 __func__, (u32)from, len);
@@ -354,7 +348,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
354 * Should add 1 byte DUMMY_BYTE. 348 * Should add 1 byte DUMMY_BYTE.
355 */ 349 */
356 t[0].tx_buf = flash->command; 350 t[0].tx_buf = flash->command;
357 t[0].len = m25p_cmdsz(flash) + FAST_READ_DUMMY_BYTE; 351 t[0].len = m25p_cmdsz(flash) + (flash->fast_read ? 1 : 0);
358 spi_message_add_tail(&t[0], &m); 352 spi_message_add_tail(&t[0], &m);
359 353
360 t[1].rx_buf = buf; 354 t[1].rx_buf = buf;
@@ -376,12 +370,14 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
376 */ 370 */
377 371
378 /* Set up the write data buffer. */ 372 /* Set up the write data buffer. */
379 flash->command[0] = OPCODE_READ; 373 opcode = flash->fast_read ? OPCODE_FAST_READ : OPCODE_NORM_READ;
374 flash->command[0] = opcode;
380 m25p_addr2cmd(flash, from, flash->command); 375 m25p_addr2cmd(flash, from, flash->command);
381 376
382 spi_sync(flash->spi, &m); 377 spi_sync(flash->spi, &m);
383 378
384 *retlen = m.actual_length - m25p_cmdsz(flash) - FAST_READ_DUMMY_BYTE; 379 *retlen = m.actual_length - m25p_cmdsz(flash) -
380 (flash->fast_read ? 1 : 0);
385 381
386 mutex_unlock(&flash->lock); 382 mutex_unlock(&flash->lock);
387 383
@@ -809,9 +805,10 @@ static int __devinit m25p_probe(struct spi_device *spi)
809 struct flash_info *info; 805 struct flash_info *info;
810 unsigned i; 806 unsigned i;
811 struct mtd_part_parser_data ppdata; 807 struct mtd_part_parser_data ppdata;
808 struct device_node __maybe_unused *np = spi->dev.of_node;
812 809
813#ifdef CONFIG_MTD_OF_PARTS 810#ifdef CONFIG_MTD_OF_PARTS
814 if (!of_device_is_available(spi->dev.of_node)) 811 if (!of_device_is_available(np))
815 return -ENODEV; 812 return -ENODEV;
816#endif 813#endif
817 814
@@ -863,7 +860,8 @@ static int __devinit m25p_probe(struct spi_device *spi)
863 flash = kzalloc(sizeof *flash, GFP_KERNEL); 860 flash = kzalloc(sizeof *flash, GFP_KERNEL);
864 if (!flash) 861 if (!flash)
865 return -ENOMEM; 862 return -ENOMEM;
866 flash->command = kmalloc(MAX_CMD_SIZE + FAST_READ_DUMMY_BYTE, GFP_KERNEL); 863 flash->command = kmalloc(MAX_CMD_SIZE + (flash->fast_read ? 1 : 0),
864 GFP_KERNEL);
867 if (!flash->command) { 865 if (!flash->command) {
868 kfree(flash); 866 kfree(flash);
869 return -ENOMEM; 867 return -ENOMEM;
@@ -920,6 +918,16 @@ static int __devinit m25p_probe(struct spi_device *spi)
920 flash->page_size = info->page_size; 918 flash->page_size = info->page_size;
921 flash->mtd.writebufsize = flash->page_size; 919 flash->mtd.writebufsize = flash->page_size;
922 920
921 flash->fast_read = false;
922#ifdef CONFIG_OF
923 if (np && of_property_read_bool(np, "m25p,fast-read"))
924 flash->fast_read = true;
925#endif
926
927#ifdef CONFIG_M25PXX_USE_FAST_READ
928 flash->fast_read = true;
929#endif
930
923 if (info->addr_width) 931 if (info->addr_width)
924 flash->addr_width = info->addr_width; 932 flash->addr_width = info->addr_width;
925 else { 933 else {