aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Norris <computersforpeace@gmail.com>2014-03-20 08:00:12 -0400
committerBrian Norris <computersforpeace@gmail.com>2014-04-14 14:22:58 -0400
commit03e296f613affcc2671c1e86d8c25ecad867204e (patch)
tree75f35d6d3b5144c861b7e59d8cbeed510a3fb78c
parent1ef391084b22d75110171d34f565f57e4be9b2a6 (diff)
mtd: m25p80: use the SPI nor framework
Use the new SPI nor framework, and rewrite the m25p80: (0) remove all the NOR comands. (1) change the m25p->command to an array. (2) implement the necessary hooks, such as m25p80_read/m25p80_write. Tested with the m25p32. Signed-off-by: Huang Shijie <b32955@freescale.com> Acked-by: Marek Vasut <marex@denx.de> [Brian: rebased] Signed-off-by: Brian Norris <computersforpeace@gmail.com>
-rw-r--r--drivers/mtd/devices/Kconfig2
-rw-r--r--drivers/mtd/devices/m25p80.c1303
2 files changed, 106 insertions, 1199 deletions
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index 1210bc2923b7..48aa1aa5820b 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -80,7 +80,7 @@ config MTD_DATAFLASH_OTP
80 80
81config MTD_M25P80 81config MTD_M25P80
82 tristate "Support most SPI Flash chips (AT26DF, M25P, W25X, ...)" 82 tristate "Support most SPI Flash chips (AT26DF, M25P, W25X, ...)"
83 depends on SPI_MASTER 83 depends on SPI_MASTER && MTD_SPI_NOR_BASE
84 help 84 help
85 This enables access to most modern SPI flash chips, used for 85 This enables access to most modern SPI flash chips, used for
86 program and data storage. Series supported include Atmel AT26DF, 86 program and data storage. Series supported include Atmel AT26DF,
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 524dab3ac938..4af6400ccd95 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -19,485 +19,98 @@
19#include <linux/errno.h> 19#include <linux/errno.h>
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/device.h> 21#include <linux/device.h>
22#include <linux/interrupt.h>
23#include <linux/mutex.h>
24#include <linux/math64.h>
25#include <linux/slab.h>
26#include <linux/sched.h>
27#include <linux/mod_devicetable.h>
28 22
29#include <linux/mtd/cfi.h>
30#include <linux/mtd/mtd.h> 23#include <linux/mtd/mtd.h>
31#include <linux/mtd/partitions.h> 24#include <linux/mtd/partitions.h>
32#include <linux/of_platform.h>
33 25
34#include <linux/spi/spi.h> 26#include <linux/spi/spi.h>
35#include <linux/spi/flash.h> 27#include <linux/spi/flash.h>
28#include <linux/mtd/spi-nor.h>
36 29
37/* Flash opcodes. */
38#define OPCODE_WREN 0x06 /* Write enable */
39#define OPCODE_RDSR 0x05 /* Read status register */
40#define OPCODE_WRSR 0x01 /* Write status register 1 byte */
41#define OPCODE_NORM_READ 0x03 /* Read data bytes (low frequency) */
42#define OPCODE_FAST_READ 0x0b /* Read data bytes (high frequency) */
43#define OPCODE_DUAL_READ 0x3b /* Read data bytes (Dual SPI) */
44#define OPCODE_QUAD_READ 0x6b /* Read data bytes (Quad SPI) */
45#define OPCODE_PP 0x02 /* Page program (up to 256 bytes) */
46#define OPCODE_BE_4K 0x20 /* Erase 4KiB block */
47#define OPCODE_BE_4K_PMC 0xd7 /* Erase 4KiB block on PMC chips */
48#define OPCODE_BE_32K 0x52 /* Erase 32KiB block */
49#define OPCODE_CHIP_ERASE 0xc7 /* Erase whole flash chip */
50#define OPCODE_SE 0xd8 /* Sector erase (usually 64KiB) */
51#define OPCODE_RDID 0x9f /* Read JEDEC ID */
52#define OPCODE_RDCR 0x35 /* Read configuration register */
53
54/* 4-byte address opcodes - used on Spansion and some Macronix flashes. */
55#define OPCODE_NORM_READ_4B 0x13 /* Read data bytes (low frequency) */
56#define OPCODE_FAST_READ_4B 0x0c /* Read data bytes (high frequency) */
57#define OPCODE_DUAL_READ_4B 0x3c /* Read data bytes (Dual SPI) */
58#define OPCODE_QUAD_READ_4B 0x6c /* Read data bytes (Quad SPI) */
59#define OPCODE_PP_4B 0x12 /* Page program (up to 256 bytes) */
60#define OPCODE_SE_4B 0xdc /* Sector erase (usually 64KiB) */
61
62/* Used for SST flashes only. */
63#define OPCODE_BP 0x02 /* Byte program */
64#define OPCODE_WRDI 0x04 /* Write disable */
65#define OPCODE_AAI_WP 0xad /* Auto address increment word program */
66
67/* Used for Macronix and Winbond flashes. */
68#define OPCODE_EN4B 0xb7 /* Enter 4-byte mode */
69#define OPCODE_EX4B 0xe9 /* Exit 4-byte mode */
70
71/* Used for Spansion flashes only. */
72#define OPCODE_BRWR 0x17 /* Bank register write */
73
74/* Status Register bits. */
75#define SR_WIP 1 /* Write in progress */
76#define SR_WEL 2 /* Write enable latch */
77/* meaning of other SR_* bits may differ between vendors */
78#define SR_BP0 4 /* Block protect 0 */
79#define SR_BP1 8 /* Block protect 1 */
80#define SR_BP2 0x10 /* Block protect 2 */
81#define SR_SRWD 0x80 /* SR write protect */
82
83#define SR_QUAD_EN_MX 0x40 /* Macronix Quad I/O */
84
85/* Configuration Register bits. */
86#define CR_QUAD_EN_SPAN 0x2 /* Spansion Quad I/O */
87
88/* Define max times to check status register before we give up. */
89#define MAX_READY_WAIT_JIFFIES (40 * HZ) /* M25P16 specs 40s max chip erase */
90#define MAX_CMD_SIZE 6 30#define MAX_CMD_SIZE 6
91
92#define JEDEC_MFR(_jedec_id) ((_jedec_id) >> 16)
93
94/****************************************************************************/
95
96enum read_type {
97 M25P80_NORMAL = 0,
98 M25P80_FAST,
99 M25P80_DUAL,
100 M25P80_QUAD,
101};
102
103struct m25p { 31struct m25p {
104 struct spi_device *spi; 32 struct spi_device *spi;
105 struct mutex lock; 33 struct spi_nor spi_nor;
106 struct mtd_info mtd; 34 struct mtd_info mtd;
107 u16 page_size; 35 u8 command[MAX_CMD_SIZE];
108 u16 addr_width;
109 u8 erase_opcode;
110 u8 read_opcode;
111 u8 program_opcode;
112 u8 *command;
113 enum read_type flash_read;
114}; 36};
115 37
116static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd) 38static int m25p80_read_reg(struct spi_nor *nor, u8 code, u8 *val, int len)
117{
118 return container_of(mtd, struct m25p, mtd);
119}
120
121/****************************************************************************/
122
123/*
124 * Internal helper functions
125 */
126
127/*
128 * Read the status register, returning its value in the location
129 * Return the status register value.
130 * Returns negative if error occurred.
131 */
132static int read_sr(struct m25p *flash)
133{
134 ssize_t retval;
135 u8 code = OPCODE_RDSR;
136 u8 val;
137
138 retval = spi_write_then_read(flash->spi, &code, 1, &val, 1);
139
140 if (retval < 0) {
141 dev_err(&flash->spi->dev, "error %d reading SR\n",
142 (int) retval);
143 return retval;
144 }
145
146 return val;
147}
148
149/*
150 * Read configuration register, returning its value in the
151 * location. Return the configuration register value.
152 * Returns negative if error occured.
153 */
154static int read_cr(struct m25p *flash)
155{
156 u8 code = OPCODE_RDCR;
157 int ret;
158 u8 val;
159
160 ret = spi_write_then_read(flash->spi, &code, 1, &val, 1);
161 if (ret < 0) {
162 dev_err(&flash->spi->dev, "error %d reading CR\n", ret);
163 return ret;
164 }
165
166 return val;
167}
168
169/*
170 * Write status register 1 byte
171 * Returns negative if error occurred.
172 */
173static int write_sr(struct m25p *flash, u8 val)
174{
175 flash->command[0] = OPCODE_WRSR;
176 flash->command[1] = val;
177
178 return spi_write(flash->spi, flash->command, 2);
179}
180
181/*
182 * Set write enable latch with Write Enable command.
183 * Returns negative if error occurred.