--- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -48,6 +48,12 @@ #define SST49LF008A 0x005a #define AT49BV6416 0x00d6 +/* Macronix */ +#define MX29LV160B 0x2249 /* MX29LV160 Bottom-boot chip */ +#define MX29LV160T 0x22C4 /* MX29LV160 Top-boot chip */ +#define MX29LV320B 0x22A8 /* MX29LV320 Bottom-boot chip */ +#define MX29LV320T 0x22A7 /* MX29LV320 Top-boot chip */ + static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); static int cfi_amdstd_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); @@ -342,6 +348,41 @@ static struct cfi_fixup cfi_nopri_fixup_ { 0, 0, NULL } }; +#ifdef CONFIG_MTD_CFI_FIXUP_MACRONIX_BOOTLOC +/* + * Some Macronix chips has no/bad bootblock information in the CFI table + */ +static void fixup_macronix_bootloc(struct mtd_info *mtd) +{ + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; + struct cfi_pri_amdstd *extp = cfi->cmdset_priv; + __u8 t; + + switch (cfi->id) { + /* TODO: put affected chip ids here */ + case MX29LV160B: + case MX29LV320B: + t = 2; /* Bottom boot */ + break; + case MX29LV160T: + case MX29LV320T: + t = 3; /* Top boot */ + break; + default: + return; + } + + if (extp->TopBottom == t) + /* boot location detected by the CFI layer is correct */ + return; + + extp->TopBottom = t; + printk("%s: Macronix chip detected, id:0x%04X, boot location forced " + "to %s\n", map->name, cfi->id, (t == 2) ? "bottom" : "top"); +} +#endif /* CONFIG_MTD_CFI_FIXUP_MACRONIX_BOOTLOC */ + static struct cfi_fixup cfi_fixup_table[] = { { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri }, #ifdef AMD_BOOTLOC_BUG @@ -383,6 +424,9 @@ static struct cfi_fixup fixup_table[] = */ { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_erase_chip }, { CFI_MFR_ATMEL, AT49BV6416, fixup_use_atmel_lock }, +#ifdef CONFIG_MTD_CFI_FIXUP_MACRONIX_BOOTLOC + { CFI_MFR_MACRONIX, CFI_ID_ANY, fixup_macronix_bootloc }, +#endif { 0, 0, NULL } }; --- a/drivers/mtd/chips/Kconfig +++ b/drivers/mtd/chips/Kconfig @@ -196,6 +196,14 @@ config MTD_CFI_AMDSTD provides support for one of those command sets, used on chips including the AMD Am29LV320. +config MTD_CFI_FIXUP_MACRONIX_BOOTLOC + bool "Fix boot-block location for Macronix flash chips" + depends on MTD_CFI_AMDSTD + help + Some Macronix flash chips have no/wrong boot-block location in the + CFI table, and the driver may detect the type incorrectly. Select + this if your board has such chip. + config MTD_CFI_STAA tristate "Support for ST (Advanced Architecture) flash chips" depends on MTD_GEN_PROBE