diff options
Diffstat (limited to 'drivers/mtd/devices/m25p80.c')
-rw-r--r-- | drivers/mtd/devices/m25p80.c | 48 |
1 files changed, 30 insertions, 18 deletions
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 03838bab1f59..4eeeb2d7f6ea 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 | ||
98 | static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd) | 91 | static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd) |
@@ -168,6 +161,7 @@ static inline int set_4byte(struct m25p *flash, u32 jedec_id, int enable) | |||
168 | { | 161 | { |
169 | switch (JEDEC_MFR(jedec_id)) { | 162 | switch (JEDEC_MFR(jedec_id)) { |
170 | case CFI_MFR_MACRONIX: | 163 | case CFI_MFR_MACRONIX: |
164 | case 0xEF /* winbond */: | ||
171 | flash->command[0] = enable ? OPCODE_EN4B : OPCODE_EX4B; | 165 | flash->command[0] = enable ? OPCODE_EN4B : OPCODE_EX4B; |
172 | return spi_write(flash->spi, flash->command, 1); | 166 | return spi_write(flash->spi, flash->command, 1); |
173 | default: | 167 | default: |
@@ -342,6 +336,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
342 | struct m25p *flash = mtd_to_m25p(mtd); | 336 | struct m25p *flash = mtd_to_m25p(mtd); |
343 | struct spi_transfer t[2]; | 337 | struct spi_transfer t[2]; |
344 | struct spi_message m; | 338 | struct spi_message m; |
339 | uint8_t opcode; | ||
345 | 340 | ||
346 | pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev), | 341 | pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev), |
347 | __func__, (u32)from, len); | 342 | __func__, (u32)from, len); |
@@ -354,7 +349,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
354 | * Should add 1 byte DUMMY_BYTE. | 349 | * Should add 1 byte DUMMY_BYTE. |
355 | */ | 350 | */ |
356 | t[0].tx_buf = flash->command; | 351 | t[0].tx_buf = flash->command; |
357 | t[0].len = m25p_cmdsz(flash) + FAST_READ_DUMMY_BYTE; | 352 | t[0].len = m25p_cmdsz(flash) + (flash->fast_read ? 1 : 0); |
358 | spi_message_add_tail(&t[0], &m); | 353 | spi_message_add_tail(&t[0], &m); |
359 | 354 | ||
360 | t[1].rx_buf = buf; | 355 | t[1].rx_buf = buf; |
@@ -376,12 +371,14 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
376 | */ | 371 | */ |
377 | 372 | ||
378 | /* Set up the write data buffer. */ | 373 | /* Set up the write data buffer. */ |
379 | flash->command[0] = OPCODE_READ; | 374 | opcode = flash->fast_read ? OPCODE_FAST_READ : OPCODE_NORM_READ; |
375 | flash->command[0] = opcode; | ||
380 | m25p_addr2cmd(flash, from, flash->command); | 376 | m25p_addr2cmd(flash, from, flash->command); |
381 | 377 | ||
382 | spi_sync(flash->spi, &m); | 378 | spi_sync(flash->spi, &m); |
383 | 379 | ||
384 | *retlen = m.actual_length - m25p_cmdsz(flash) - FAST_READ_DUMMY_BYTE; | 380 | *retlen = m.actual_length - m25p_cmdsz(flash) - |
381 | (flash->fast_read ? 1 : 0); | ||
385 | 382 | ||
386 | mutex_unlock(&flash->lock); | 383 | mutex_unlock(&flash->lock); |
387 | 384 | ||
@@ -664,7 +661,8 @@ static const struct spi_device_id m25p_ids[] = { | |||
664 | { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) }, | 661 | { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) }, |
665 | 662 | ||
666 | /* Micron */ | 663 | /* Micron */ |
667 | { "n25q128", INFO(0x20ba18, 0, 64 * 1024, 256, 0) }, | 664 | { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, 0) }, |
665 | { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, 0) }, | ||
668 | { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K) }, | 666 | { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K) }, |
669 | 667 | ||
670 | /* Spansion -- single (large) sector size only, at least | 668 | /* Spansion -- single (large) sector size only, at least |
@@ -745,6 +743,8 @@ static const struct spi_device_id m25p_ids[] = { | |||
745 | { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) }, | 743 | { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) }, |
746 | { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, | 744 | { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, |
747 | { "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) }, | 745 | { "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) }, |
746 | { "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) }, | ||
747 | { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K) }, | ||
748 | 748 | ||
749 | /* Catalyst / On Semiconductor -- non-JEDEC */ | 749 | /* Catalyst / On Semiconductor -- non-JEDEC */ |
750 | { "cat25c11", CAT25_INFO( 16, 8, 16, 1) }, | 750 | { "cat25c11", CAT25_INFO( 16, 8, 16, 1) }, |
@@ -756,7 +756,7 @@ static const struct spi_device_id m25p_ids[] = { | |||
756 | }; | 756 | }; |
757 | MODULE_DEVICE_TABLE(spi, m25p_ids); | 757 | MODULE_DEVICE_TABLE(spi, m25p_ids); |
758 | 758 | ||
759 | static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi) | 759 | static const struct spi_device_id *jedec_probe(struct spi_device *spi) |
760 | { | 760 | { |
761 | int tmp; | 761 | int tmp; |
762 | u8 code = OPCODE_RDID; | 762 | u8 code = OPCODE_RDID; |
@@ -801,7 +801,7 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi) | |||
801 | * matches what the READ command supports, at least until this driver | 801 | * matches what the READ command supports, at least until this driver |
802 | * understands FAST_READ (for clocks over 25 MHz). | 802 | * understands FAST_READ (for clocks over 25 MHz). |
803 | */ | 803 | */ |
804 | static int __devinit m25p_probe(struct spi_device *spi) | 804 | static int m25p_probe(struct spi_device *spi) |
805 | { | 805 | { |
806 | const struct spi_device_id *id = spi_get_device_id(spi); | 806 | const struct spi_device_id *id = spi_get_device_id(spi); |
807 | struct flash_platform_data *data; | 807 | struct flash_platform_data *data; |
@@ -809,9 +809,10 @@ static int __devinit m25p_probe(struct spi_device *spi) | |||
809 | struct flash_info *info; | 809 | struct flash_info *info; |
810 | unsigned i; | 810 | unsigned i; |
811 | struct mtd_part_parser_data ppdata; | 811 | struct mtd_part_parser_data ppdata; |
812 | struct device_node __maybe_unused *np = spi->dev.of_node; | ||
812 | 813 | ||
813 | #ifdef CONFIG_MTD_OF_PARTS | 814 | #ifdef CONFIG_MTD_OF_PARTS |
814 | if (!of_device_is_available(spi->dev.of_node)) | 815 | if (!of_device_is_available(np)) |
815 | return -ENODEV; | 816 | return -ENODEV; |
816 | #endif | 817 | #endif |
817 | 818 | ||
@@ -863,7 +864,8 @@ static int __devinit m25p_probe(struct spi_device *spi) | |||
863 | flash = kzalloc(sizeof *flash, GFP_KERNEL); | 864 | flash = kzalloc(sizeof *flash, GFP_KERNEL); |
864 | if (!flash) | 865 | if (!flash) |
865 | return -ENOMEM; | 866 | return -ENOMEM; |
866 | flash->command = kmalloc(MAX_CMD_SIZE + FAST_READ_DUMMY_BYTE, GFP_KERNEL); | 867 | flash->command = kmalloc(MAX_CMD_SIZE + (flash->fast_read ? 1 : 0), |
868 | GFP_KERNEL); | ||
867 | if (!flash->command) { | 869 | if (!flash->command) { |
868 | kfree(flash); | 870 | kfree(flash); |
869 | return -ENOMEM; | 871 | return -ENOMEM; |
@@ -920,6 +922,16 @@ static int __devinit m25p_probe(struct spi_device *spi) | |||
920 | flash->page_size = info->page_size; | 922 | flash->page_size = info->page_size; |
921 | flash->mtd.writebufsize = flash->page_size; | 923 | flash->mtd.writebufsize = flash->page_size; |
922 | 924 | ||
925 | flash->fast_read = false; | ||
926 | #ifdef CONFIG_OF | ||
927 | if (np && of_property_read_bool(np, "m25p,fast-read")) | ||
928 | flash->fast_read = true; | ||
929 | #endif | ||
930 | |||
931 | #ifdef CONFIG_M25PXX_USE_FAST_READ | ||
932 | flash->fast_read = true; | ||
933 | #endif | ||
934 | |||
923 | if (info->addr_width) | 935 | if (info->addr_width) |
924 | flash->addr_width = info->addr_width; | 936 | flash->addr_width = info->addr_width; |
925 | else { | 937 | else { |
@@ -961,7 +973,7 @@ static int __devinit m25p_probe(struct spi_device *spi) | |||
961 | } | 973 | } |
962 | 974 | ||
963 | 975 | ||
964 | static int __devexit m25p_remove(struct spi_device *spi) | 976 | static int m25p_remove(struct spi_device *spi) |
965 | { | 977 | { |
966 | struct m25p *flash = dev_get_drvdata(&spi->dev); | 978 | struct m25p *flash = dev_get_drvdata(&spi->dev); |
967 | int status; | 979 | int status; |
@@ -983,7 +995,7 @@ static struct spi_driver m25p80_driver = { | |||
983 | }, | 995 | }, |
984 | .id_table = m25p_ids, | 996 | .id_table = m25p_ids, |
985 | .probe = m25p_probe, | 997 | .probe = m25p_probe, |
986 | .remove = __devexit_p(m25p_remove), | 998 | .remove = m25p_remove, |
987 | 999 | ||
988 | /* REVISIT: many of these chips have deep power-down modes, which | 1000 | /* REVISIT: many of these chips have deep power-down modes, which |
989 | * should clearly be entered on suspend() to minimize power use. | 1001 | * should clearly be entered on suspend() to minimize power use. |