[MTD] m25p80: add FAST_READ access support to M25Pxx
authorBryan Wu <cooloney@kernel.org>
Fri, 25 Apr 2008 04:07:32 +0000 (12:07 +0800)
committerDavid Woodhouse <dwmw2@infradead.org>
Fri, 25 Apr 2008 08:13:52 +0000 (09:13 +0100)
Signed-off-by: Bryan Wu <cooloney@kernel.org>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
drivers/mtd/devices/Kconfig
drivers/mtd/devices/m25p80.c

index 811d56fd890f6da79135d854ae52fc8d581d167f..35ed1103dbb22096c183eb0a903072ec8ef73e1a 100644 (file)
@@ -77,6 +77,13 @@ config MTD_M25P80
          if you want to specify device partitioning or to use a device which
          doesn't support the JEDEC ID instruction.
 
+config M25PXX_USE_FAST_READ
+       bool "Use FAST_READ OPCode allowing SPI CLK <= 50MHz"
+       depends on MTD_M25P80
+       default y
+       help
+         This option enables FAST_READ access supported by ST M25Pxx.
+
 config MTD_SLRAM
        tristate "Uncached system RAM"
        help
index 60408c955a13f25d1eb4dd37bced9bb02f49f15b..3f5041d39f24ed4433bc4b095eeb428721bc40f2 100644 (file)
@@ -33,7 +33,7 @@
 /* Flash opcodes. */
 #define        OPCODE_WREN             0x06    /* Write enable */
 #define        OPCODE_RDSR             0x05    /* Read status register */
-#define        OPCODE_READ             0x03    /* Read data bytes (low frequency) */
+#define        OPCODE_NORM_READ        0x03    /* Read data bytes (low frequency) */
 #define        OPCODE_FAST_READ        0x0b    /* Read data bytes (high frequency) */
 #define        OPCODE_PP               0x02    /* Page program (up to 256 bytes) */
 #define        OPCODE_BE_4K            0x20    /* Erase 4KiB block */
 
 /* Define max times to check status register before we give up. */
 #define        MAX_READY_WAIT_COUNT    100000
+#define        CMD_SIZE                4
 
+#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
 
 #ifdef CONFIG_MTD_PARTITIONS
 #define        mtd_has_partitions()    (1)
@@ -68,7 +76,7 @@ struct m25p {
        struct mtd_info         mtd;
        unsigned                partitioned:1;
        u8                      erase_opcode;
-       u8                      command[4];
+       u8                      command[CMD_SIZE + FAST_READ_DUMMY_BYTE];
 };
 
 static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)
@@ -167,7 +175,7 @@ static int erase_sector(struct m25p *flash, u32 offset)
        flash->command[2] = offset >> 8;
        flash->command[3] = offset;
 
-       spi_write(flash->spi, flash->command, sizeof(flash->command));
+       spi_write(flash->spi, flash->command, CMD_SIZE);
 
        return 0;
 }
@@ -253,8 +261,12 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
        spi_message_init(&m);
        memset(t, 0, (sizeof t));
 
+       /* NOTE:
+        * OPCODE_FAST_READ (if available) is faster.
+        * Should add 1 byte DUMMY_BYTE.
+        */
        t[0].tx_buf = flash->command;
-       t[0].len = sizeof(flash->command);
+       t[0].len = CMD_SIZE + FAST_READ_DUMMY_BYTE;
        spi_message_add_tail(&t[0], &m);
 
        t[1].rx_buf = buf;
@@ -287,7 +299,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
 
        spi_sync(flash->spi, &m);
 
-       *retlen = m.actual_length - sizeof(flash->command);
+       *retlen = m.actual_length - CMD_SIZE - FAST_READ_DUMMY_BYTE;
 
        mutex_unlock(&flash->lock);
 
@@ -325,7 +337,7 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
        memset(t, 0, (sizeof t));
 
        t[0].tx_buf = flash->command;
-       t[0].len = sizeof(flash->command);
+       t[0].len = CMD_SIZE;
        spi_message_add_tail(&t[0], &m);
 
        t[1].tx_buf = buf;
@@ -354,7 +366,7 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
 
                spi_sync(flash->spi, &m);
 
-               *retlen = m.actual_length - sizeof(flash->command);
+               *retlen = m.actual_length - CMD_SIZE;
        } else {
                u32 i;
 
@@ -364,7 +376,7 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
                t[1].len = page_size;
                spi_sync(flash->spi, &m);
 
-               *retlen = m.actual_length - sizeof(flash->command);
+               *retlen = m.actual_length - CMD_SIZE;
 
                /* write everything in PAGESIZE chunks */
                for (i = page_size; i < len; i += page_size) {
@@ -387,8 +399,7 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
                        spi_sync(flash->spi, &m);
 
                        if (retlen)
-                               *retlen += m.actual_length
-                                       - sizeof(flash->command);
+                               *retlen += m.actual_length - CMD_SIZE;
                }
        }