Lines Matching full:flash

2  * MTD SPI driver for ST M25Pxx (and similar) serial flash chips
36 #include <linux/spi/flash.h>
38 /* Flash opcodes. */
47 #define OPCODE_CHIP_ERASE 0xc7 /* Erase whole flash chip */
114 static int read_sr(struct m25p *flash) in read_sr() argument
120 retval = spi_write_then_read(flash->spi, &code, 1, &val, 1); in read_sr()
123 dev_err(&flash->spi->dev, "error %d reading SR\n", in read_sr()
135 static int write_sr(struct m25p *flash, u8 val) in write_sr() argument
137 flash->command[0] = OPCODE_WRSR; in write_sr()
138 flash->command[1] = val; in write_sr()
140 return spi_write(flash->spi, flash->command, 2); in write_sr()
147 static inline int write_enable(struct m25p *flash) in write_enable() argument
151 return spi_write_then_read(flash->spi, &code, 1, NULL, 0); in write_enable()
157 static inline int write_disable(struct m25p *flash) in write_disable() argument
161 return spi_write_then_read(flash->spi, &code, 1, NULL, 0); in write_disable()
167 static inline int set_4byte(struct m25p *flash, u32 jedec_id, int enable) in set_4byte() argument
171 flash->command[0] = enable ? OPCODE_EN4B : OPCODE_EX4B; in set_4byte()
172 return spi_write(flash->spi, flash->command, 1); in set_4byte()
175 flash->command[0] = OPCODE_BRWR; in set_4byte()
176 flash->command[1] = enable << 7; in set_4byte()
177 return spi_write(flash->spi, flash->command, 2); in set_4byte()
185 static int wait_till_ready(struct m25p *flash) in wait_till_ready() argument
193 if ((sr = read_sr(flash)) < 0) in wait_till_ready()
206 * Erase the whole flash memory
210 static int erase_chip(struct m25p *flash) in erase_chip() argument
212 pr_debug("%s: %s %lldKiB\n", dev_name(&flash->spi->dev), __func__, in erase_chip()
213 (long long)(flash->mtd.size >> 10)); in erase_chip()
216 if (wait_till_ready(flash)) in erase_chip()
220 write_enable(flash); in erase_chip()
223 flash->command[0] = OPCODE_CHIP_ERASE; in erase_chip()
225 spi_write(flash->spi, flash->command, 1); in erase_chip()
230 static void m25p_addr2cmd(struct m25p *flash, unsigned int addr, u8 *cmd) in m25p_addr2cmd() argument
233 cmd[1] = addr >> (flash->addr_width * 8 - 8); in m25p_addr2cmd()
234 cmd[2] = addr >> (flash->addr_width * 8 - 16); in m25p_addr2cmd()
235 cmd[3] = addr >> (flash->addr_width * 8 - 24); in m25p_addr2cmd()
236 cmd[4] = addr >> (flash->addr_width * 8 - 32); in m25p_addr2cmd()
239 static int m25p_cmdsz(struct m25p *flash) in m25p_cmdsz() argument
241 return 1 + flash->addr_width; in m25p_cmdsz()
245 * Erase one sector of flash memory at offset ``offset'' which is any
250 static int erase_sector(struct m25p *flash, u32 offset) in erase_sector() argument
252 pr_debug("%s: %s %dKiB at 0x%08x\n", dev_name(&flash->spi->dev), in erase_sector()
253 __func__, flash->mtd.erasesize / 1024, offset); in erase_sector()
256 if (wait_till_ready(flash)) in erase_sector()
260 write_enable(flash); in erase_sector()
263 flash->command[0] = flash->erase_opcode; in erase_sector()
264 m25p_addr2cmd(flash, offset, flash->command); in erase_sector()
266 spi_write(flash->spi, flash->command, m25p_cmdsz(flash)); in erase_sector()
278 * Erase an address range on the flash chip. The address range may extend
283 struct m25p *flash = mtd_to_m25p(mtd); in m25p80_erase() local
287 pr_debug("%s: %s at 0x%llx, len %lld\n", dev_name(&flash->spi->dev), in m25p80_erase()
292 if (instr->addr + instr->len > flash->mtd.size) in m25p80_erase()
301 mutex_lock(&flash->lock); in m25p80_erase()
304 if (len == flash->mtd.size) { in m25p80_erase()
305 if (erase_chip(flash)) { in m25p80_erase()
307 mutex_unlock(&flash->lock); in m25p80_erase()
319 if (erase_sector(flash, addr)) { in m25p80_erase()
321 mutex_unlock(&flash->lock); in m25p80_erase()
330 mutex_unlock(&flash->lock); in m25p80_erase()
339 * Read an address range from the flash chip. The address range
345 struct m25p *flash = mtd_to_m25p(mtd); in m25p80_read() local
349 pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev), in m25p80_read()
356 if (from + len > flash->mtd.size) in m25p80_read()
366 t[0].tx_buf = flash->command; in m25p80_read()
367 t[0].len = m25p_cmdsz(flash) + FAST_READ_DUMMY_BYTE; in m25p80_read()
377 mutex_lock(&flash->lock); in m25p80_read()
380 if (wait_till_ready(flash)) { in m25p80_read()
382 mutex_unlock(&flash->lock); in m25p80_read()
392 flash->command[0] = OPCODE_READ; in m25p80_read()
393 m25p_addr2cmd(flash, from, flash->command); in m25p80_read()
395 spi_sync(flash->spi, &m); in m25p80_read()
397 *retlen = m.actual_length - m25p_cmdsz(flash) - FAST_READ_DUMMY_BYTE; in m25p80_read()
399 mutex_unlock(&flash->lock); in m25p80_read()
405 * Write an address range to the flash chip. Data must be written in
412 struct m25p *flash = mtd_to_m25p(mtd); in m25p80_write() local
417 pr_debug("%s: %s to 0x%08x, len %zd\n", dev_name(&flash->spi->dev), in m25p80_write()
426 if (to + len > flash->mtd.size) in m25p80_write()
432 t[0].tx_buf = flash->command; in m25p80_write()
433 t[0].len = m25p_cmdsz(flash); in m25p80_write()
439 mutex_lock(&flash->lock); in m25p80_write()
442 if (wait_till_ready(flash)) { in m25p80_write()
443 mutex_unlock(&flash->lock); in m25p80_write()
447 write_enable(flash); in m25p80_write()
450 flash->command[0] = OPCODE_PP; in m25p80_write()
451 m25p_addr2cmd(flash, to, flash->command); in m25p80_write()
453 page_offset = to & (flash->page_size - 1); in m25p80_write()
456 if (page_offset + len <= flash->page_size) { in m25p80_write()
459 spi_sync(flash->spi, &m); in m25p80_write()
461 *retlen = m.actual_length - m25p_cmdsz(flash); in m25p80_write()
466 page_size = flash->page_size - page_offset; in m25p80_write()
469 spi_sync(flash->spi, &m); in m25p80_write()
471 *retlen = m.actual_length - m25p_cmdsz(flash); in m25p80_write()
473 /* write everything in flash->page_size chunks */ in m25p80_write()
476 if (page_size > flash->page_size) in m25p80_write()
477 page_size = flash->page_size; in m25p80_write()
479 /* write the next page to flash */ in m25p80_write()
480 m25p_addr2cmd(flash, to + i, flash->command); in m25p80_write()
485 wait_till_ready(flash); in m25p80_write()
487 write_enable(flash); in m25p80_write()
489 spi_sync(flash->spi, &m); in m25p80_write()
491 *retlen += m.actual_length - m25p_cmdsz(flash); in m25p80_write()
495 mutex_unlock(&flash->lock); in m25p80_write()
503 struct m25p *flash = mtd_to_m25p(mtd); in sst_write() local
509 pr_debug("%s: %s to 0x%08x, len %zd\n", dev_name(&flash->spi->dev), in sst_write()
518 if (to + len > flash->mtd.size) in sst_write()
524 t[0].tx_buf = flash->command; in sst_write()
525 t[0].len = m25p_cmdsz(flash); in sst_write()
531 mutex_lock(&flash->lock); in sst_write()
534 ret = wait_till_ready(flash); in sst_write()
538 write_enable(flash); in sst_write()
543 flash->command[0] = OPCODE_BP; in sst_write()
544 m25p_addr2cmd(flash, to, flash->command); in sst_write()
548 spi_sync(flash->spi, &m); in sst_write()
549 ret = wait_till_ready(flash); in sst_write()
552 *retlen += m.actual_length - m25p_cmdsz(flash); in sst_write()
556 flash->command[0] = OPCODE_AAI_WP; in sst_write()
557 m25p_addr2cmd(flash, to, flash->command); in sst_write()
560 cmd_sz = m25p_cmdsz(flash); in sst_write()
567 spi_sync(flash->spi, &m); in sst_write()
568 ret = wait_till_ready(flash); in sst_write()
575 write_disable(flash); in sst_write()
576 ret = wait_till_ready(flash); in sst_write()
582 write_enable(flash); in sst_write()
583 flash->command[0] = OPCODE_BP; in sst_write()
584 m25p_addr2cmd(flash, to, flash->command); in sst_write()
585 t[0].len = m25p_cmdsz(flash); in sst_write()
589 spi_sync(flash->spi, &m); in sst_write()
590 ret = wait_till_ready(flash); in sst_write()
593 *retlen += m.actual_length - m25p_cmdsz(flash); in sst_write()
594 write_disable(flash); in sst_write()
598 mutex_unlock(&flash->lock); in sst_write()
650 * more flash chips. This current list focusses on newer chips, which
822 struct m25p *flash; in m25p_probe() local
877 flash = kzalloc(sizeof *flash, GFP_KERNEL); in m25p_probe()
878 if (!flash) in m25p_probe()
880 flash->command = kmalloc(MAX_CMD_SIZE + FAST_READ_DUMMY_BYTE, GFP_KERNEL); in m25p_probe()
881 if (!flash->command) { in m25p_probe()
882 kfree(flash); in m25p_probe()
886 flash->spi = spi; in m25p_probe()
887 mutex_init(&flash->lock); in m25p_probe()
888 dev_set_drvdata(&spi->dev, flash); in m25p_probe()
891 * Atmel, SST and Intel/Numonyx serial flash tend to power in m25p_probe()
898 write_enable(flash); in m25p_probe()
899 write_sr(flash, 0); in m25p_probe()
903 flash->mtd.name = data->name; in m25p_probe()
905 flash->mtd.name = dev_name(&spi->dev); in m25p_probe()
907 flash->mtd.type = MTD_NORFLASH; in m25p_probe()
908 flash->mtd.writesize = 1; in m25p_probe()
909 flash->mtd.flags = MTD_CAP_NORFLASH; in m25p_probe()
910 flash->mtd.size = info->sector_size * info->n_sectors; in m25p_probe()
911 flash->mtd.erase = m25p80_erase; in m25p_probe()
912 flash->mtd.read = m25p80_read; in m25p_probe()
914 /* sst flash chips use AAI word program */ in m25p_probe()
916 flash->mtd.write = sst_write; in m25p_probe()
918 flash->mtd.write = m25p80_write; in m25p_probe()
922 flash->erase_opcode = OPCODE_BE_4K; in m25p_probe()
923 flash->mtd.erasesize = 4096; in m25p_probe()
925 flash->erase_opcode = OPCODE_SE; in m25p_probe()
926 flash->mtd.erasesize = info->sector_size; in m25p_probe()
930 flash->mtd.flags |= MTD_NO_ERASE; in m25p_probe()
933 flash->mtd.dev.parent = &spi->dev; in m25p_probe()
934 flash->page_size = info->page_size; in m25p_probe()
937 flash->addr_width = info->addr_width; in m25p_probe()
940 if (flash->mtd.size > 0x1000000) { in m25p_probe()
941 flash->addr_width = 4; in m25p_probe()
942 set_4byte(flash, info->jedec_id, 1); in m25p_probe()
944 flash->addr_width = 3; in m25p_probe()
948 (long long)flash->mtd.size >> 10); in m25p_probe()
952 flash->mtd.name, in m25p_probe()
953 (long long)flash->mtd.size, (long long)(flash->mtd.size >> 20), in m25p_probe()
954 flash->mtd.erasesize, flash->mtd.erasesize / 1024, in m25p_probe()
955 flash->mtd.numeraseregions); in m25p_probe()
957 if (flash->mtd.numeraseregions) in m25p_probe()
958 for (i = 0; i < flash->mtd.numeraseregions; i++) in m25p_probe()
962 i, (long long)flash->mtd.eraseregions[i].offset, in m25p_probe()
963 flash->mtd.eraseregions[i].erasesize, in m25p_probe()
964 flash->mtd.eraseregions[i].erasesize / 1024, in m25p_probe()
965 flash->mtd.eraseregions[i].numblocks); in m25p_probe()
971 return mtd_device_parse_register(&flash->mtd, NULL, &ppdata, in m25p_probe()
979 struct m25p *flash = dev_get_drvdata(&spi->dev); in m25p_remove() local
983 status = mtd_device_unregister(&flash->mtd); in m25p_remove()
985 kfree(flash->command); in m25p_remove()
986 kfree(flash); in m25p_remove()
1025 MODULE_DESCRIPTION("MTD SPI driver for ST M25Pxx flash chips");