diff options
Diffstat (limited to 'drivers/mtd/devices/m25p80.c')
| -rw-r--r-- | drivers/mtd/devices/m25p80.c | 69 |
1 files changed, 40 insertions, 29 deletions
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 47486fbd7777..e6892851e813 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c | |||
| @@ -709,6 +709,14 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi) | |||
| 709 | jedec = jedec << 8; | 709 | jedec = jedec << 8; |
| 710 | jedec |= id[2]; | 710 | jedec |= id[2]; |
| 711 | 711 | ||
| 712 | /* | ||
| 713 | * Some chips (like Numonyx M25P80) have JEDEC and non-JEDEC variants, | ||
| 714 | * which depend on technology process. Officially RDID command doesn't | ||
| 715 | * exist for non-JEDEC chips, but for compatibility they return ID 0. | ||
| 716 | */ | ||
| 717 | if (jedec == 0) | ||
| 718 | return NULL; | ||
| 719 | |||
| 712 | ext_jedec = id[3] << 8 | id[4]; | 720 | ext_jedec = id[3] << 8 | id[4]; |
| 713 | 721 | ||
| 714 | for (tmp = 0; tmp < ARRAY_SIZE(m25p_ids) - 1; tmp++) { | 722 | for (tmp = 0; tmp < ARRAY_SIZE(m25p_ids) - 1; tmp++) { |
| @@ -730,7 +738,7 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi) | |||
| 730 | */ | 738 | */ |
| 731 | static int __devinit m25p_probe(struct spi_device *spi) | 739 | static int __devinit m25p_probe(struct spi_device *spi) |
| 732 | { | 740 | { |
| 733 | const struct spi_device_id *id; | 741 | const struct spi_device_id *id = spi_get_device_id(spi); |
| 734 | struct flash_platform_data *data; | 742 | struct flash_platform_data *data; |
| 735 | struct m25p *flash; | 743 | struct m25p *flash; |
| 736 | struct flash_info *info; | 744 | struct flash_info *info; |
| @@ -743,41 +751,44 @@ static int __devinit m25p_probe(struct spi_device *spi) | |||
| 743 | */ | 751 | */ |
| 744 | data = spi->dev.platform_data; | 752 | data = spi->dev.platform_data; |
| 745 | if (data && data->type) { | 753 | if (data && data->type) { |
| 754 | const struct spi_device_id *plat_id; | ||
| 755 | |||
| 746 | for (i = 0; i < ARRAY_SIZE(m25p_ids) - 1; i++) { | 756 | for (i = 0; i < ARRAY_SIZE(m25p_ids) - 1; i++) { |
| 747 | id = &m25p_ids[i]; | 757 | plat_id = &m25p_ids[i]; |
| 748 | info = (void *)m25p_ids[i].driver_data; | 758 | if (strcmp(data->type, plat_id->name)) |
| 749 | if (strcmp(data->type, id->name)) | ||
| 750 | continue; | 759 | continue; |
| 751 | break; | 760 | break; |
| 752 | } | 761 | } |
| 753 | 762 | ||
| 754 | /* unrecognized chip? */ | 763 | if (plat_id) |
| 755 | if (i == ARRAY_SIZE(m25p_ids) - 1) { | 764 | id = plat_id; |
| 756 | DEBUG(MTD_DEBUG_LEVEL0, "%s: unrecognized id %s\n", | 765 | else |
| 757 | dev_name(&spi->dev), data->type); | 766 | dev_warn(&spi->dev, "unrecognized id %s\n", data->type); |
| 758 | info = NULL; | ||
| 759 | |||
| 760 | /* recognized; is that chip really what's there? */ | ||
| 761 | } else if (info->jedec_id) { | ||
| 762 | id = jedec_probe(spi); | ||
| 763 | |||
| 764 | if (id != &m25p_ids[i]) { | ||
| 765 | dev_warn(&spi->dev, "found %s, expected %s\n", | ||
| 766 | id ? id->name : "UNKNOWN", | ||
| 767 | m25p_ids[i].name); | ||
| 768 | info = NULL; | ||
| 769 | } | ||
| 770 | } | ||
| 771 | } else { | ||
| 772 | id = jedec_probe(spi); | ||
| 773 | if (!id) | ||
| 774 | id = spi_get_device_id(spi); | ||
| 775 | |||
| 776 | info = (void *)id->driver_data; | ||
| 777 | } | 767 | } |
| 778 | 768 | ||
| 779 | if (!info) | 769 | info = (void *)id->driver_data; |
| 780 | return -ENODEV; | 770 | |
| 771 | if (info->jedec_id) { | ||
| 772 | const struct spi_device_id *jid; | ||
| 773 | |||
| 774 | jid = jedec_probe(spi); | ||
| 775 | if (!jid) { | ||
| 776 | dev_info(&spi->dev, "non-JEDEC variant of %s\n", | ||
| 777 | id->name); | ||
| 778 | } else if (jid != id) { | ||
| 779 | /* | ||
| 780 | * JEDEC knows better, so overwrite platform ID. We | ||
| 781 | * can't trust partitions any longer, but we'll let | ||
| 782 | * mtd apply them anyway, since some partitions may be | ||
| 783 | * marked read-only, and we don't want to lose that | ||
| 784 | * information, even if it's not 100% accurate. | ||
| 785 | */ | ||
| 786 | dev_warn(&spi->dev, "found %s, expected %s\n", | ||
| 787 | jid->name, id->name); | ||
| 788 | id = jid; | ||
| 789 | info = (void *)jid->driver_data; | ||
| 790 | } | ||
| 791 | } | ||
| 781 | 792 | ||
| 782 | flash = kzalloc(sizeof *flash, GFP_KERNEL); | 793 | flash = kzalloc(sizeof *flash, GFP_KERNEL); |
| 783 | if (!flash) | 794 | if (!flash) |
