aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-11-02 17:45:52 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-11-02 17:45:52 -0500
commit81d92dc117bf9954f24a8d88c2d1ef26bd13ecc7 (patch)
treeefe80084a1b48c80017c70b7adf338b6e7e13250
parentad2be3796ff4c834e5c102d5455e76ee07dcf71d (diff)
parent89cf38dd536a7301d6b5f5ddd73f42074c01bfaa (diff)
Merge tag 'for-linus-20141102' of git://git.infradead.org/linux-mtd
Pull MTD fixes from Brian Norris: "Three main MTD fixes for 3.18: - A regression from 3.16 which was noticed in 3.17. With the restructuring of the m25p80.c driver and the SPI NOR library framework, we omitted proper listing of the SPI device IDs. This means m25p80.c wouldn't auto-load (modprobe) properly when built as a module. For now, we duplicate the device IDs into both modules. - The OMAP / ELM modules were depending on an implicit link ordering. Use deferred probing so that the new link order (in 3.18-rc) can still allow for successful probing. - Fix suspend/resume support for LH28F640BF NOR flash" * tag 'for-linus-20141102' of git://git.infradead.org/linux-mtd: mtd: cfi_cmdset_0001.c: fix resume for LH28F640BF chips mtd: omap: fix mtd devices not showing up mtd: m25p80,spi-nor: Fix module aliases for m25p80 mtd: spi-nor: make spi_nor_scan() take a chip type name, not spi_device_id mtd: m25p80: get rid of spi_get_device_id
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c2
-rw-r--r--drivers/mtd/devices/m25p80.c64
-rw-r--r--drivers/mtd/nand/omap_elm.c2
-rw-r--r--drivers/mtd/spi-nor/fsl-quadspi.c7
-rw-r--r--drivers/mtd/spi-nor/spi-nor.c16
-rw-r--r--include/linux/mtd/spi-nor.h21
6 files changed, 73 insertions, 39 deletions
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index a7543ba3e190..3096f3ded3ad 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -2590,6 +2590,8 @@ static void cfi_intelext_resume(struct mtd_info *mtd)
2590 2590
2591 /* Go to known state. Chip may have been power cycled */ 2591 /* Go to known state. Chip may have been power cycled */
2592 if (chip->state == FL_PM_SUSPENDED) { 2592 if (chip->state == FL_PM_SUSPENDED) {
2593 /* Refresh LH28F640BF Partition Config. Register */
2594 fixup_LH28F640BF(mtd);
2593 map_write(map, CMD(0xFF), cfi->chips[i].start); 2595 map_write(map, CMD(0xFF), cfi->chips[i].start);
2594 chip->oldstate = chip->state = FL_READY; 2596 chip->oldstate = chip->state = FL_READY;
2595 wake_up(&chip->wq); 2597 wake_up(&chip->wq);
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index dcda6287228d..ed827cf894e4 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -193,10 +193,10 @@ static int m25p_probe(struct spi_device *spi)
193{ 193{
194 struct mtd_part_parser_data ppdata; 194 struct mtd_part_parser_data ppdata;
195 struct flash_platform_data *data; 195 struct flash_platform_data *data;
196 const struct spi_device_id *id = NULL;
197 struct m25p *flash; 196 struct m25p *flash;
198 struct spi_nor *nor; 197 struct spi_nor *nor;
199 enum read_mode mode = SPI_NOR_NORMAL; 198 enum read_mode mode = SPI_NOR_NORMAL;
199 char *flash_name = NULL;
200 int ret; 200 int ret;
201 201
202 data = dev_get_platdata(&spi->dev); 202 data = dev_get_platdata(&spi->dev);
@@ -236,13 +236,11 @@ static int m25p_probe(struct spi_device *spi)
236 * If that's the case, respect "type" and ignore a "name". 236 * If that's the case, respect "type" and ignore a "name".
237 */ 237 */
238 if (data && data->type) 238 if (data && data->type)
239 id = spi_nor_match_id(data->type); 239 flash_name = data->type;
240 else
241 flash_name = spi->modalias;
240 242
241 /* If we didn't get name from platform, simply use "modalias". */ 243 ret = spi_nor_scan(nor, flash_name, mode);
242 if (!id)
243 id = spi_get_device_id(spi);
244
245 ret = spi_nor_scan(nor, id, mode);
246 if (ret) 244 if (ret)
247 return ret; 245 return ret;
248 246
@@ -263,12 +261,62 @@ static int m25p_remove(struct spi_device *spi)
263} 261}
264 262
265 263
264/*
265 * XXX This needs to be kept in sync with spi_nor_ids. We can't share
266 * it with spi-nor, because if this is built as a module then modpost
267 * won't be able to read it and add appropriate aliases.
268 */
269static const struct spi_device_id m25p_ids[] = {
270 {"at25fs010"}, {"at25fs040"}, {"at25df041a"}, {"at25df321a"},
271 {"at25df641"}, {"at26f004"}, {"at26df081a"}, {"at26df161a"},
272 {"at26df321"}, {"at45db081d"},
273 {"en25f32"}, {"en25p32"}, {"en25q32b"}, {"en25p64"},
274 {"en25q64"}, {"en25qh128"}, {"en25qh256"},
275 {"f25l32pa"},
276 {"mr25h256"}, {"mr25h10"},
277 {"gd25q32"}, {"gd25q64"},
278 {"160s33b"}, {"320s33b"}, {"640s33b"},
279 {"mx25l2005a"}, {"mx25l4005a"}, {"mx25l8005"}, {"mx25l1606e"},
280 {"mx25l3205d"}, {"mx25l3255e"}, {"mx25l6405d"}, {"mx25l12805d"},
281 {"mx25l12855e"},{"mx25l25635e"},{"mx25l25655e"},{"mx66l51235l"},
282 {"mx66l1g55g"},
283 {"n25q064"}, {"n25q128a11"}, {"n25q128a13"}, {"n25q256a"},
284 {"n25q512a"}, {"n25q512ax3"}, {"n25q00"},
285 {"pm25lv512"}, {"pm25lv010"}, {"pm25lq032"},
286 {"s25sl032p"}, {"s25sl064p"}, {"s25fl256s0"}, {"s25fl256s1"},
287 {"s25fl512s"}, {"s70fl01gs"}, {"s25sl12800"}, {"s25sl12801"},
288 {"s25fl129p0"}, {"s25fl129p1"}, {"s25sl004a"}, {"s25sl008a"},
289 {"s25sl016a"}, {"s25sl032a"}, {"s25sl064a"}, {"s25fl008k"},
290 {"s25fl016k"}, {"s25fl064k"},
291 {"sst25vf040b"},{"sst25vf080b"},{"sst25vf016b"},{"sst25vf032b"},
292 {"sst25vf064c"},{"sst25wf512"}, {"sst25wf010"}, {"sst25wf020"},
293 {"sst25wf040"},
294 {"m25p05"}, {"m25p10"}, {"m25p20"}, {"m25p40"},
295 {"m25p80"}, {"m25p16"}, {"m25p32"}, {"m25p64"},
296 {"m25p128"}, {"n25q032"},
297 {"m25p05-nonjedec"}, {"m25p10-nonjedec"}, {"m25p20-nonjedec"},
298 {"m25p40-nonjedec"}, {"m25p80-nonjedec"}, {"m25p16-nonjedec"},
299 {"m25p32-nonjedec"}, {"m25p64-nonjedec"}, {"m25p128-nonjedec"},
300 {"m45pe10"}, {"m45pe80"}, {"m45pe16"},
301 {"m25pe20"}, {"m25pe80"}, {"m25pe16"},
302 {"m25px16"}, {"m25px32"}, {"m25px32-s0"}, {"m25px32-s1"},
303 {"m25px64"},
304 {"w25x10"}, {"w25x20"}, {"w25x40"}, {"w25x80"},
305 {"w25x16"}, {"w25x32"}, {"w25q32"}, {"w25q32dw"},
306 {"w25x64"}, {"w25q64"}, {"w25q128"}, {"w25q80"},
307 {"w25q80bl"}, {"w25q128"}, {"w25q256"}, {"cat25c11"},
308 {"cat25c03"}, {"cat25c09"}, {"cat25c17"}, {"cat25128"},
309 { },
310};
311MODULE_DEVICE_TABLE(spi, m25p_ids);
312
313
266static struct spi_driver m25p80_driver = { 314static struct spi_driver m25p80_driver = {
267 .driver = { 315 .driver = {
268 .name = "m25p80", 316 .name = "m25p80",
269 .owner = THIS_MODULE, 317 .owner = THIS_MODULE,
270 }, 318 },
271 .id_table = spi_nor_ids, 319 .id_table = m25p_ids,
272 .probe = m25p_probe, 320 .probe = m25p_probe,
273 .remove = m25p_remove, 321 .remove = m25p_remove,
274 322
diff --git a/drivers/mtd/nand/omap_elm.c b/drivers/mtd/nand/omap_elm.c
index b4f61c7fc161..058531044ceb 100644
--- a/drivers/mtd/nand/omap_elm.c
+++ b/drivers/mtd/nand/omap_elm.c
@@ -115,7 +115,7 @@ int elm_config(struct device *dev, enum bch_ecc bch_type,
115 115
116 if (!info) { 116 if (!info) {
117 dev_err(dev, "Unable to configure elm - device not probed?\n"); 117 dev_err(dev, "Unable to configure elm - device not probed?\n");
118 return -ENODEV; 118 return -EPROBE_DEFER;
119 } 119 }
120 /* ELM cannot detect ECC errors for chunks > 1KB */ 120 /* ELM cannot detect ECC errors for chunks > 1KB */
121 if (ecc_step_size > ((ELM_ECC_SIZE + 1) / 2)) { 121 if (ecc_step_size > ((ELM_ECC_SIZE + 1) / 2)) {
diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 8d659a2888d5..d5269a26c839 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -881,7 +881,6 @@ static int fsl_qspi_probe(struct platform_device *pdev)
881 881
882 /* iterate the subnodes. */ 882 /* iterate the subnodes. */
883 for_each_available_child_of_node(dev->of_node, np) { 883 for_each_available_child_of_node(dev->of_node, np) {
884 const struct spi_device_id *id;
885 char modalias[40]; 884 char modalias[40];
886 885
887 /* skip the holes */ 886 /* skip the holes */
@@ -909,10 +908,6 @@ static int fsl_qspi_probe(struct platform_device *pdev)
909 if (of_modalias_node(np, modalias, sizeof(modalias)) < 0) 908 if (of_modalias_node(np, modalias, sizeof(modalias)) < 0)
910 goto map_failed; 909 goto map_failed;
911 910
912 id = spi_nor_match_id(modalias);
913 if (!id)
914 goto map_failed;
915
916 ret = of_property_read_u32(np, "spi-max-frequency", 911 ret = of_property_read_u32(np, "spi-max-frequency",
917 &q->clk_rate); 912 &q->clk_rate);
918 if (ret < 0) 913 if (ret < 0)
@@ -921,7 +916,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
921 /* set the chip address for READID */ 916 /* set the chip address for READID */
922 fsl_qspi_set_base_addr(q, nor); 917 fsl_qspi_set_base_addr(q, nor);
923 918
924 ret = spi_nor_scan(nor, id, SPI_NOR_QUAD); 919 ret = spi_nor_scan(nor, modalias, SPI_NOR_QUAD);
925 if (ret) 920 if (ret)
926 goto map_failed; 921 goto map_failed;
927 922
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index ae16aa2f6885..c51ee52386a7 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -28,6 +28,8 @@
28 28
29#define JEDEC_MFR(_jedec_id) ((_jedec_id) >> 16) 29#define JEDEC_MFR(_jedec_id) ((_jedec_id) >> 16)
30 30
31static const struct spi_device_id *spi_nor_match_id(const char *name);
32
31/* 33/*
32 * Read the status register, returning its value in the location 34 * Read the status register, returning its value in the location
33 * Return the status register value. 35 * Return the status register value.
@@ -473,7 +475,7 @@ struct flash_info {
473 * more nor chips. This current list focusses on newer chips, which 475 * more nor chips. This current list focusses on newer chips, which
474 * have been converging on command sets which including JEDEC ID. 476 * have been converging on command sets which including JEDEC ID.
475 */ 477 */
476const struct spi_device_id spi_nor_ids[] = { 478static const struct spi_device_id spi_nor_ids[] = {
477 /* Atmel -- some are (confusingly) marketed as "DataFlash" */ 479 /* Atmel -- some are (confusingly) marketed as "DataFlash" */
478 { "at25fs010", INFO(0x1f6601, 0, 32 * 1024, 4, SECT_4K) }, 480 { "at25fs010", INFO(0x1f6601, 0, 32 * 1024, 4, SECT_4K) },
479 { "at25fs040", INFO(0x1f6604, 0, 64 * 1024, 8, SECT_4K) }, 481 { "at25fs040", INFO(0x1f6604, 0, 64 * 1024, 8, SECT_4K) },
@@ -637,7 +639,6 @@ const struct spi_device_id spi_nor_ids[] = {
637 { "cat25128", CAT25_INFO(2048, 8, 64, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, 639 { "cat25128", CAT25_INFO(2048, 8, 64, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
638 { }, 640 { },
639}; 641};
640EXPORT_SYMBOL_GPL(spi_nor_ids);
641 642
642static const struct spi_device_id *spi_nor_read_id(struct spi_nor *nor) 643static const struct spi_device_id *spi_nor_read_id(struct spi_nor *nor)
643{ 644{
@@ -911,9 +912,9 @@ static int spi_nor_check(struct spi_nor *nor)
911 return 0; 912 return 0;
912} 913}
913 914
914int spi_nor_scan(struct spi_nor *nor, const struct spi_device_id *id, 915int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
915 enum read_mode mode)
916{ 916{
917 const struct spi_device_id *id = NULL;
917 struct flash_info *info; 918 struct flash_info *info;
918 struct device *dev = nor->dev; 919 struct device *dev = nor->dev;
919 struct mtd_info *mtd = nor->mtd; 920 struct mtd_info *mtd = nor->mtd;
@@ -925,6 +926,10 @@ int spi_nor_scan(struct spi_nor *nor, const struct spi_device_id *id,
925 if (ret) 926 if (ret)
926 return ret; 927 return ret;
927 928
929 id = spi_nor_match_id(name);
930 if (!id)
931 return -ENOENT;
932
928 info = (void *)id->driver_data; 933 info = (void *)id->driver_data;
929 934
930 if (info->jedec_id) { 935 if (info->jedec_id) {
@@ -1113,7 +1118,7 @@ int spi_nor_scan(struct spi_nor *nor, const struct spi_device_id *id,
1113} 1118}
1114EXPORT_SYMBOL_GPL(spi_nor_scan); 1119EXPORT_SYMBOL_GPL(spi_nor_scan);
1115 1120
1116const struct spi_device_id *spi_nor_match_id(char *name) 1121static const struct spi_device_id *spi_nor_match_id(const char *name)
1117{ 1122{
1118 const struct spi_device_id *id = spi_nor_ids; 1123 const struct spi_device_id *id = spi_nor_ids;
1119 1124
@@ -1124,7 +1129,6 @@ const struct spi_device_id *spi_nor_match_id(char *name)
1124 } 1129 }
1125 return NULL; 1130 return NULL;
1126} 1131}
1127EXPORT_SYMBOL_GPL(spi_nor_match_id);
1128 1132
1129MODULE_LICENSE("GPL"); 1133MODULE_LICENSE("GPL");
1130MODULE_AUTHOR("Huang Shijie <shijie8@gmail.com>"); 1134MODULE_AUTHOR("Huang Shijie <shijie8@gmail.com>");
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index 9e6294f32ba8..046a0a2e4c4e 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -187,32 +187,17 @@ struct spi_nor {
187/** 187/**
188 * spi_nor_scan() - scan the SPI NOR 188 * spi_nor_scan() - scan the SPI NOR
189 * @nor: the spi_nor structure 189 * @nor: the spi_nor structure
190 * @id: the spi_device_id provided by the driver 190 * @name: the chip type name
191 * @mode: the read mode supported by the driver 191 * @mode: the read mode supported by the driver
192 * 192 *
193 * The drivers can use this fuction to scan the SPI NOR. 193 * The drivers can use this fuction to scan the SPI NOR.
194 * In the scanning, it will try to get all the necessary information to 194 * In the scanning, it will try to get all the necessary information to
195 * fill the mtd_info{} and the spi_nor{}. 195 * fill the mtd_info{} and the spi_nor{}.
196 * 196 *
197 * The board may assigns a spi_device_id with @id which be used to compared with 197 * The chip type name can be provided through the @name parameter.
198 * the spi_device_id detected by the scanning.
199 * 198 *
200 * Return: 0 for success, others for failure. 199 * Return: 0 for success, others for failure.
201 */ 200 */
202int spi_nor_scan(struct spi_nor *nor, const struct spi_device_id *id, 201int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode);
203 enum read_mode mode);
204extern const struct spi_device_id spi_nor_ids[];
205
206/**
207 * spi_nor_match_id() - find the spi_device_id by the name
208 * @name: the name of the spi_device_id
209 *
210 * The drivers use this function to find the spi_device_id
211 * specified by the @name.
212 *
213 * Return: returns the right spi_device_id pointer on success,
214 * and returns NULL on failure.
215 */
216const struct spi_device_id *spi_nor_match_id(char *name);
217 202
218#endif 203#endif