diff options
author | Sourav Poddar <sourav.poddar@ti.com> | 2013-11-06 09:35:34 -0500 |
---|---|---|
committer | Brian Norris <computersforpeace@gmail.com> | 2014-01-03 14:22:07 -0500 |
commit | 8552b439aba7f32063755d23f79ca27b4d0a3115 (patch) | |
tree | 978904ebdf58c81213b92520c29263823aa8d561 | |
parent | 802eee95bde72fd0cd0f3a5b2098375a487d1eda (diff) |
drivers: mtd: m25p80: convert "bool" read check into an enum
This is a cleanup prior to adding quad read support. This will facilitate
easy addition of more read commands check under an enum rather that defining a
separate bool for it.
Signed-off-by: Sourav Poddar <sourav.poddar@ti.com>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
-rw-r--r-- | drivers/mtd/devices/m25p80.c | 71 |
1 files changed, 57 insertions, 14 deletions
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 7eda71dbc183..04f8a245ffef 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c | |||
@@ -84,6 +84,11 @@ | |||
84 | 84 | ||
85 | /****************************************************************************/ | 85 | /****************************************************************************/ |
86 | 86 | ||
87 | enum read_type { | ||
88 | M25P80_NORMAL = 0, | ||
89 | M25P80_FAST, | ||
90 | }; | ||
91 | |||
87 | struct m25p { | 92 | struct m25p { |
88 | struct spi_device *spi; | 93 | struct spi_device *spi; |
89 | struct mutex lock; | 94 | struct mutex lock; |
@@ -94,7 +99,7 @@ struct m25p { | |||
94 | u8 read_opcode; | 99 | u8 read_opcode; |
95 | u8 program_opcode; | 100 | u8 program_opcode; |
96 | u8 *command; | 101 | u8 *command; |
97 | bool fast_read; | 102 | enum read_type flash_read; |
98 | }; | 103 | }; |
99 | 104 | ||
100 | static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd) | 105 | static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd) |
@@ -350,6 +355,24 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
350 | } | 355 | } |
351 | 356 | ||
352 | /* | 357 | /* |
358 | * Dummy Cycle calculation for different type of read. | ||
359 | * It can be used to support more commands with | ||
360 | * different dummy cycle requirements. | ||
361 | */ | ||
362 | static inline int m25p80_dummy_cycles_read(struct m25p *flash) | ||
363 | { | ||
364 | switch (flash->flash_read) { | ||
365 | case M25P80_FAST: | ||
366 | return 1; | ||
367 | case M25P80_NORMAL: | ||
368 | return 0; | ||
369 | default: | ||
370 | dev_err(&flash->spi->dev, "No valid read type supported\n"); | ||
371 | return -1; | ||
372 | } | ||
373 | } | ||
374 | |||
375 | /* | ||
353 | * Read an address range from the flash chip. The address range | 376 | * Read an address range from the flash chip. The address range |
354 | * may be any size provided it is within the physical boundaries. | 377 | * may be any size provided it is within the physical boundaries. |
355 | */ | 378 | */ |
@@ -360,6 +383,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
360 | struct spi_transfer t[2]; | 383 | struct spi_transfer t[2]; |
361 | struct spi_message m; | 384 | struct spi_message m; |
362 | uint8_t opcode; | 385 | uint8_t opcode; |
386 | int dummy; | ||
363 | 387 | ||
364 | pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev), | 388 | pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev), |
365 | __func__, (u32)from, len); | 389 | __func__, (u32)from, len); |
@@ -367,8 +391,14 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
367 | spi_message_init(&m); | 391 | spi_message_init(&m); |
368 | memset(t, 0, (sizeof t)); | 392 | memset(t, 0, (sizeof t)); |
369 | 393 | ||
394 | dummy = m25p80_dummy_cycles_read(flash); | ||
395 | if (dummy < 0) { | ||
396 | dev_err(&flash->spi->dev, "No valid read command supported\n"); | ||
397 | return -EINVAL; | ||
398 | } | ||
399 | |||
370 | t[0].tx_buf = flash->command; | 400 | t[0].tx_buf = flash->command; |
371 | t[0].len = m25p_cmdsz(flash) + (flash->fast_read ? 1 : 0); | 401 | t[0].len = m25p_cmdsz(flash) + dummy; |
372 | spi_message_add_tail(&t[0], &m); | 402 | spi_message_add_tail(&t[0], &m); |
373 | 403 | ||
374 | t[1].rx_buf = buf; | 404 | t[1].rx_buf = buf; |
@@ -391,8 +421,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
391 | 421 | ||
392 | spi_sync(flash->spi, &m); | 422 | spi_sync(flash->spi, &m); |
393 | 423 | ||
394 | *retlen = m.actual_length - m25p_cmdsz(flash) - | 424 | *retlen = m.actual_length - m25p_cmdsz(flash) - dummy; |
395 | (flash->fast_read ? 1 : 0); | ||
396 | 425 | ||
397 | mutex_unlock(&flash->lock); | 426 | mutex_unlock(&flash->lock); |
398 | 427 | ||
@@ -1051,22 +1080,31 @@ static int m25p_probe(struct spi_device *spi) | |||
1051 | flash->page_size = info->page_size; | 1080 | flash->page_size = info->page_size; |
1052 | flash->mtd.writebufsize = flash->page_size; | 1081 | flash->mtd.writebufsize = flash->page_size; |
1053 | 1082 | ||
1054 | if (np) | 1083 | if (np) { |
1055 | /* If we were instantiated by DT, use it */ | 1084 | /* If we were instantiated by DT, use it */ |
1056 | flash->fast_read = of_property_read_bool(np, "m25p,fast-read"); | 1085 | if (of_property_read_bool(np, "m25p,fast-read")) |
1057 | else | 1086 | flash->flash_read = M25P80_FAST; |
1087 | } else { | ||
1058 | /* If we weren't instantiated by DT, default to fast-read */ | 1088 | /* If we weren't instantiated by DT, default to fast-read */ |
1059 | flash->fast_read = true; | 1089 | flash->flash_read = M25P80_FAST; |
1090 | } | ||
1060 | 1091 | ||
1061 | /* Some devices cannot do fast-read, no matter what DT tells us */ | 1092 | /* Some devices cannot do fast-read, no matter what DT tells us */ |
1062 | if (info->flags & M25P_NO_FR) | 1093 | if (info->flags & M25P_NO_FR) |
1063 | flash->fast_read = false; | 1094 | flash->flash_read = M25P80_NORMAL; |
1064 | 1095 | ||
1065 | /* Default commands */ | 1096 | /* Default commands */ |
1066 | if (flash->fast_read) | 1097 | switch (flash->flash_read) { |
1098 | case M25P80_FAST: | ||
1067 | flash->read_opcode = OPCODE_FAST_READ; | 1099 | flash->read_opcode = OPCODE_FAST_READ; |
1068 | else | 1100 | break; |
1101 | case M25P80_NORMAL: | ||
1069 | flash->read_opcode = OPCODE_NORM_READ; | 1102 | flash->read_opcode = OPCODE_NORM_READ; |
1103 | break; | ||
1104 | default: | ||
1105 | dev_err(&flash->spi->dev, "No Read opcode defined\n"); | ||
1106 | return -EINVAL; | ||
1107 | } | ||
1070 | 1108 | ||
1071 | flash->program_opcode = OPCODE_PP; | 1109 | flash->program_opcode = OPCODE_PP; |
1072 | 1110 | ||
@@ -1077,9 +1115,14 @@ static int m25p_probe(struct spi_device *spi) | |||
1077 | flash->addr_width = 4; | 1115 | flash->addr_width = 4; |
1078 | if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) { | 1116 | if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) { |
1079 | /* Dedicated 4-byte command set */ | 1117 | /* Dedicated 4-byte command set */ |
1080 | flash->read_opcode = flash->fast_read ? | 1118 | switch (flash->flash_read) { |
1081 | OPCODE_FAST_READ_4B : | 1119 | case M25P80_FAST: |
1082 | OPCODE_NORM_READ_4B; | 1120 | flash->read_opcode = OPCODE_FAST_READ_4B; |
1121 | break; | ||
1122 | case M25P80_NORMAL: | ||
1123 | flash->read_opcode = OPCODE_NORM_READ_4B; | ||
1124 | break; | ||
1125 | } | ||
1083 | flash->program_opcode = OPCODE_PP_4B; | 1126 | flash->program_opcode = OPCODE_PP_4B; |
1084 | /* No small sector erase for 4-byte command set */ | 1127 | /* No small sector erase for 4-byte command set */ |
1085 | flash->erase_opcode = OPCODE_SE_4B; | 1128 | flash->erase_opcode = OPCODE_SE_4B; |