aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/devices/m25p80.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/devices/m25p80.c')
-rw-r--r--drivers/mtd/devices/m25p80.c69
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 */
731static int __devinit m25p_probe(struct spi_device *spi) 739static 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)