Skip to content

Commit

Permalink
Merge tag 'for-linus-20141102' of git://git.infradead.org/linux-mtd
Browse files Browse the repository at this point in the history
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
  • Loading branch information
torvalds committed Nov 2, 2014
2 parents ad2be37 + 89cf38d commit 81d92dc
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 39 deletions.
2 changes: 2 additions & 0 deletions drivers/mtd/chips/cfi_cmdset_0001.c
Original file line number Diff line number Diff line change
Expand Up @@ -2590,6 +2590,8 @@ static void cfi_intelext_resume(struct mtd_info *mtd)

/* Go to known state. Chip may have been power cycled */
if (chip->state == FL_PM_SUSPENDED) {
/* Refresh LH28F640BF Partition Config. Register */
fixup_LH28F640BF(mtd);
map_write(map, CMD(0xFF), cfi->chips[i].start);
chip->oldstate = chip->state = FL_READY;
wake_up(&chip->wq);
Expand Down
64 changes: 56 additions & 8 deletions drivers/mtd/devices/m25p80.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,10 +193,10 @@ static int m25p_probe(struct spi_device *spi)
{
struct mtd_part_parser_data ppdata;
struct flash_platform_data *data;
const struct spi_device_id *id = NULL;
struct m25p *flash;
struct spi_nor *nor;
enum read_mode mode = SPI_NOR_NORMAL;
char *flash_name = NULL;
int ret;

data = dev_get_platdata(&spi->dev);
Expand Down Expand Up @@ -236,13 +236,11 @@ static int m25p_probe(struct spi_device *spi)
* If that's the case, respect "type" and ignore a "name".
*/
if (data && data->type)
id = spi_nor_match_id(data->type);
flash_name = data->type;
else
flash_name = spi->modalias;

/* If we didn't get name from platform, simply use "modalias". */
if (!id)
id = spi_get_device_id(spi);

ret = spi_nor_scan(nor, id, mode);
ret = spi_nor_scan(nor, flash_name, mode);
if (ret)
return ret;

Expand All @@ -263,12 +261,62 @@ static int m25p_remove(struct spi_device *spi)
}


/*
* XXX This needs to be kept in sync with spi_nor_ids. We can't share
* it with spi-nor, because if this is built as a module then modpost
* won't be able to read it and add appropriate aliases.
*/
static const struct spi_device_id m25p_ids[] = {
{"at25fs010"}, {"at25fs040"}, {"at25df041a"}, {"at25df321a"},
{"at25df641"}, {"at26f004"}, {"at26df081a"}, {"at26df161a"},
{"at26df321"}, {"at45db081d"},
{"en25f32"}, {"en25p32"}, {"en25q32b"}, {"en25p64"},
{"en25q64"}, {"en25qh128"}, {"en25qh256"},
{"f25l32pa"},
{"mr25h256"}, {"mr25h10"},
{"gd25q32"}, {"gd25q64"},
{"160s33b"}, {"320s33b"}, {"640s33b"},
{"mx25l2005a"}, {"mx25l4005a"}, {"mx25l8005"}, {"mx25l1606e"},
{"mx25l3205d"}, {"mx25l3255e"}, {"mx25l6405d"}, {"mx25l12805d"},
{"mx25l12855e"},{"mx25l25635e"},{"mx25l25655e"},{"mx66l51235l"},
{"mx66l1g55g"},
{"n25q064"}, {"n25q128a11"}, {"n25q128a13"}, {"n25q256a"},
{"n25q512a"}, {"n25q512ax3"}, {"n25q00"},
{"pm25lv512"}, {"pm25lv010"}, {"pm25lq032"},
{"s25sl032p"}, {"s25sl064p"}, {"s25fl256s0"}, {"s25fl256s1"},
{"s25fl512s"}, {"s70fl01gs"}, {"s25sl12800"}, {"s25sl12801"},
{"s25fl129p0"}, {"s25fl129p1"}, {"s25sl004a"}, {"s25sl008a"},
{"s25sl016a"}, {"s25sl032a"}, {"s25sl064a"}, {"s25fl008k"},
{"s25fl016k"}, {"s25fl064k"},
{"sst25vf040b"},{"sst25vf080b"},{"sst25vf016b"},{"sst25vf032b"},
{"sst25vf064c"},{"sst25wf512"}, {"sst25wf010"}, {"sst25wf020"},
{"sst25wf040"},
{"m25p05"}, {"m25p10"}, {"m25p20"}, {"m25p40"},
{"m25p80"}, {"m25p16"}, {"m25p32"}, {"m25p64"},
{"m25p128"}, {"n25q032"},
{"m25p05-nonjedec"}, {"m25p10-nonjedec"}, {"m25p20-nonjedec"},
{"m25p40-nonjedec"}, {"m25p80-nonjedec"}, {"m25p16-nonjedec"},
{"m25p32-nonjedec"}, {"m25p64-nonjedec"}, {"m25p128-nonjedec"},
{"m45pe10"}, {"m45pe80"}, {"m45pe16"},
{"m25pe20"}, {"m25pe80"}, {"m25pe16"},
{"m25px16"}, {"m25px32"}, {"m25px32-s0"}, {"m25px32-s1"},
{"m25px64"},
{"w25x10"}, {"w25x20"}, {"w25x40"}, {"w25x80"},
{"w25x16"}, {"w25x32"}, {"w25q32"}, {"w25q32dw"},
{"w25x64"}, {"w25q64"}, {"w25q128"}, {"w25q80"},
{"w25q80bl"}, {"w25q128"}, {"w25q256"}, {"cat25c11"},
{"cat25c03"}, {"cat25c09"}, {"cat25c17"}, {"cat25128"},
{ },
};
MODULE_DEVICE_TABLE(spi, m25p_ids);


static struct spi_driver m25p80_driver = {
.driver = {
.name = "m25p80",
.owner = THIS_MODULE,
},
.id_table = spi_nor_ids,
.id_table = m25p_ids,
.probe = m25p_probe,
.remove = m25p_remove,

Expand Down
2 changes: 1 addition & 1 deletion drivers/mtd/nand/omap_elm.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ int elm_config(struct device *dev, enum bch_ecc bch_type,

if (!info) {
dev_err(dev, "Unable to configure elm - device not probed?\n");
return -ENODEV;
return -EPROBE_DEFER;
}
/* ELM cannot detect ECC errors for chunks > 1KB */
if (ecc_step_size > ((ELM_ECC_SIZE + 1) / 2)) {
Expand Down
7 changes: 1 addition & 6 deletions drivers/mtd/spi-nor/fsl-quadspi.c
Original file line number Diff line number Diff line change
Expand Up @@ -881,7 +881,6 @@ static int fsl_qspi_probe(struct platform_device *pdev)

/* iterate the subnodes. */
for_each_available_child_of_node(dev->of_node, np) {
const struct spi_device_id *id;
char modalias[40];

/* skip the holes */
Expand Down Expand Up @@ -909,10 +908,6 @@ static int fsl_qspi_probe(struct platform_device *pdev)
if (of_modalias_node(np, modalias, sizeof(modalias)) < 0)
goto map_failed;

id = spi_nor_match_id(modalias);
if (!id)
goto map_failed;

ret = of_property_read_u32(np, "spi-max-frequency",
&q->clk_rate);
if (ret < 0)
Expand All @@ -921,7 +916,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
/* set the chip address for READID */
fsl_qspi_set_base_addr(q, nor);

ret = spi_nor_scan(nor, id, SPI_NOR_QUAD);
ret = spi_nor_scan(nor, modalias, SPI_NOR_QUAD);
if (ret)
goto map_failed;

Expand Down
16 changes: 10 additions & 6 deletions drivers/mtd/spi-nor/spi-nor.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@

#define JEDEC_MFR(_jedec_id) ((_jedec_id) >> 16)

static const struct spi_device_id *spi_nor_match_id(const char *name);

/*
* Read the status register, returning its value in the location
* Return the status register value.
Expand Down Expand Up @@ -473,7 +475,7 @@ struct flash_info {
* more nor chips. This current list focusses on newer chips, which
* have been converging on command sets which including JEDEC ID.
*/
const struct spi_device_id spi_nor_ids[] = {
static const struct spi_device_id spi_nor_ids[] = {
/* Atmel -- some are (confusingly) marketed as "DataFlash" */
{ "at25fs010", INFO(0x1f6601, 0, 32 * 1024, 4, SECT_4K) },
{ "at25fs040", INFO(0x1f6604, 0, 64 * 1024, 8, SECT_4K) },
Expand Down Expand Up @@ -637,7 +639,6 @@ const struct spi_device_id spi_nor_ids[] = {
{ "cat25128", CAT25_INFO(2048, 8, 64, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
{ },
};
EXPORT_SYMBOL_GPL(spi_nor_ids);

static const struct spi_device_id *spi_nor_read_id(struct spi_nor *nor)
{
Expand Down Expand Up @@ -911,9 +912,9 @@ static int spi_nor_check(struct spi_nor *nor)
return 0;
}

int spi_nor_scan(struct spi_nor *nor, const struct spi_device_id *id,
enum read_mode mode)
int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
{
const struct spi_device_id *id = NULL;
struct flash_info *info;
struct device *dev = nor->dev;
struct mtd_info *mtd = nor->mtd;
Expand All @@ -925,6 +926,10 @@ int spi_nor_scan(struct spi_nor *nor, const struct spi_device_id *id,
if (ret)
return ret;

id = spi_nor_match_id(name);
if (!id)
return -ENOENT;

info = (void *)id->driver_data;

if (info->jedec_id) {
Expand Down Expand Up @@ -1113,7 +1118,7 @@ int spi_nor_scan(struct spi_nor *nor, const struct spi_device_id *id,
}
EXPORT_SYMBOL_GPL(spi_nor_scan);

const struct spi_device_id *spi_nor_match_id(char *name)
static const struct spi_device_id *spi_nor_match_id(const char *name)
{
const struct spi_device_id *id = spi_nor_ids;

Expand All @@ -1124,7 +1129,6 @@ const struct spi_device_id *spi_nor_match_id(char *name)
}
return NULL;
}
EXPORT_SYMBOL_GPL(spi_nor_match_id);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Huang Shijie <[email protected]>");
Expand Down
21 changes: 3 additions & 18 deletions include/linux/mtd/spi-nor.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,32 +187,17 @@ struct spi_nor {
/**
* spi_nor_scan() - scan the SPI NOR
* @nor: the spi_nor structure
* @id: the spi_device_id provided by the driver
* @name: the chip type name
* @mode: the read mode supported by the driver
*
* The drivers can use this fuction to scan the SPI NOR.
* In the scanning, it will try to get all the necessary information to
* fill the mtd_info{} and the spi_nor{}.
*
* The board may assigns a spi_device_id with @id which be used to compared with
* the spi_device_id detected by the scanning.
* The chip type name can be provided through the @name parameter.
*
* Return: 0 for success, others for failure.
*/
int spi_nor_scan(struct spi_nor *nor, const struct spi_device_id *id,
enum read_mode mode);
extern const struct spi_device_id spi_nor_ids[];

/**
* spi_nor_match_id() - find the spi_device_id by the name
* @name: the name of the spi_device_id
*
* The drivers use this function to find the spi_device_id
* specified by the @name.
*
* Return: returns the right spi_device_id pointer on success,
* and returns NULL on failure.
*/
const struct spi_device_id *spi_nor_match_id(char *name);
int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode);

#endif

0 comments on commit 81d92dc

Please sign in to comment.