aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/devices/m25p80.c
diff options
context:
space:
mode:
authorAnton Vorontsov <avorontsov@ru.mvista.com>2009-10-12 12:24:38 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2009-11-30 06:26:15 -0500
commit18c6182bae0acca220ed6611f741034d563cd19f (patch)
treec2d2f380c3a603ba13a5c6891aaf8324af524435 /drivers/mtd/devices/m25p80.c
parentb34bc037b26e621e5fc13466767e4da110a7b3d3 (diff)
mtd: m25p80: Rework probing/JEDEC code
Previosly the driver always tried JEDEC probing, assuming that non-JEDEC chips will return '0'. But truly non-JEDEC chips (like CAT25) won't do that, their behaviour on RDID command is undefined, so the driver should not call jedec_probe() for these chips. Also, be less strict on error conditions, don't fail to probe if JEDEC found a chip that is different from what platform code told, instead just print some warnings and use an information obtained via JEDEC. In that case we should not trust partitions any longer, but they might be still useful (i.e. they could protect some parts of the chip). Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
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)