[PATCH 1/2] mtd: m25p80: Rework probing/JEDEC code
Barry Song
21cnbao at gmail.com
Sat Jun 12 16:27:12 EST 2010
On Wed, Aug 19, 2009 at 5:46 AM, Anton Vorontsov
<avorontsov at ru.mvista.com> wrote:
>
> 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
This patch caused a problem:
even though the external flash doesn't exist, it will still pass the
probe() and be registerred into kernel and given the partition table.
You may refer to this bug report:
http://blackfin.uclinux.org/gf/project/uclinux-dist/tracker/?action=TrackerItemEdit&tracker_item_id=5975&start=0
> 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 at ru.mvista.com>
> ---
> 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 0d74b38..b75e319 100644
> --- a/drivers/mtd/devices/m25p80.c
> +++ b/drivers/mtd/devices/m25p80.c
> @@ -581,6 +581,14 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi)
> jedec = jedec << 8;
> jedec |= id[2];
>
> + /*
> + * Some chips (like Numonyx M25P80) have JEDEC and non-JEDEC variants,
> + * which depend on technology process. Officially RDID command doesn't
> + * exist for non-JEDEC chips, but for compatibility they return ID 0.
> + */
> + if (jedec == 0)
> + return NULL;
> +
> ext_jedec = id[3] << 8 | id[4];
>
> for (tmp = 0; tmp < ARRAY_SIZE(m25p_ids) - 1; tmp++) {
> @@ -602,7 +610,7 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi)
> */
> static int __devinit m25p_probe(struct spi_device *spi)
> {
> - const struct spi_device_id *id;
> + const struct spi_device_id *id = spi_get_device_id(spi);
> struct flash_platform_data *data;
> struct m25p *flash;
> struct flash_info *info;
> @@ -615,41 +623,44 @@ static int __devinit m25p_probe(struct spi_device *spi)
> */
> data = spi->dev.platform_data;
> if (data && data->type) {
> + const struct spi_device_id *plat_id;
> +
> for (i = 0; i < ARRAY_SIZE(m25p_ids) - 1; i++) {
> - id = &m25p_ids[i];
> - info = (void *)m25p_ids[i].driver_data;
> - if (strcmp(data->type, id->name))
> + plat_id = &m25p_ids[i];
> + if (strcmp(data->type, plat_id->name))
> continue;
> break;
> }
>
> - /* unrecognized chip? */
> - if (i == ARRAY_SIZE(m25p_ids) - 1) {
> - DEBUG(MTD_DEBUG_LEVEL0, "%s: unrecognized id %s\n",
> - dev_name(&spi->dev), data->type);
> - info = NULL;
> -
> - /* recognized; is that chip really what's there? */
> - } else if (info->jedec_id) {
> - id = jedec_probe(spi);
> -
> - if (id != &m25p_ids[i]) {
> - dev_warn(&spi->dev, "found %s, expected %s\n",
> - id ? id->name : "UNKNOWN",
> - m25p_ids[i].name);
> - info = NULL;
> - }
> - }
> - } else {
> - id = jedec_probe(spi);
> - if (!id)
> - id = spi_get_device_id(spi);
> -
> - info = (void *)id->driver_data;
> + if (plat_id)
> + id = plat_id;
> + else
> + dev_warn(&spi->dev, "unrecognized id %s\n", data->type);
> }
>
> - if (!info)
> - return -ENODEV;
> + info = (void *)id->driver_data;
> +
> + if (info->jedec_id) {
> + const struct spi_device_id *jid;
> +
> + jid = jedec_probe(spi);
> + if (!jid) {
> + dev_info(&spi->dev, "non-JEDEC variant of %s\n",
> + id->name);
> + } else if (jid != id) {
> + /*
> + * JEDEC knows better, so overwrite platform ID. We
> + * can't trust partitions any longer, but we'll let
> + * mtd apply them anyway, since some partitions may be
> + * marked read-only, and we don't want to lose that
> + * information, even if it's not 100% accurate.
> + */
> + dev_warn(&spi->dev, "found %s, expected %s\n",
> + jid->name, id->name);
> + id = jid;
> + info = (void *)jid->driver_data;
> + }
> + }
>
> flash = kzalloc(sizeof *flash, GFP_KERNEL);
> if (!flash)
> --
> 1.6.3.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
More information about the Linuxppc-dev
mailing list