| 1 | --- a/drivers/mtd/chips/cfi_cmdset_0002.c |
| 2 | +++ b/drivers/mtd/chips/cfi_cmdset_0002.c |
| 3 | @@ -52,6 +52,12 @@ |
| 4 | #define SST49LF008A 0x005a |
| 5 | #define AT49BV6416 0x00d6 |
| 6 | |
| 7 | +/* Macronix */ |
| 8 | +#define MX29LV160B 0x2249 /* MX29LV160 Bottom-boot chip */ |
| 9 | +#define MX29LV160T 0x22C4 /* MX29LV160 Top-boot chip */ |
| 10 | +#define MX29LV320B 0x22A8 /* MX29LV320 Bottom-boot chip */ |
| 11 | +#define MX29LV320T 0x22A7 /* MX29LV320 Top-boot chip */ |
| 12 | + |
| 13 | static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); |
| 14 | static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); |
| 15 | static int cfi_amdstd_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); |
| 16 | @@ -282,6 +288,41 @@ static void fixup_s29gl032n_sectors(stru |
| 17 | } |
| 18 | } |
| 19 | |
| 20 | +#ifdef CONFIG_MTD_CFI_FIXUP_MACRONIX_BOOTLOC |
| 21 | +/* |
| 22 | + * Some Macronix chips has no/bad bootblock information in the CFI table |
| 23 | + */ |
| 24 | +static void fixup_macronix_bootloc(struct mtd_info *mtd, void* param) |
| 25 | +{ |
| 26 | + struct map_info *map = mtd->priv; |
| 27 | + struct cfi_private *cfi = map->fldrv_priv; |
| 28 | + struct cfi_pri_amdstd *extp = cfi->cmdset_priv; |
| 29 | + __u8 t; |
| 30 | + |
| 31 | + switch (cfi->id) { |
| 32 | + /* TODO: put affected chip ids here */ |
| 33 | + case MX29LV160B: |
| 34 | + case MX29LV320B: |
| 35 | + t = 2; /* Bottom boot */ |
| 36 | + break; |
| 37 | + case MX29LV160T: |
| 38 | + case MX29LV320T: |
| 39 | + t = 3; /* Top boot */ |
| 40 | + break; |
| 41 | + default: |
| 42 | + return; |
| 43 | + } |
| 44 | + |
| 45 | + if (extp->TopBottom == t) |
| 46 | + /* boot location detected by the CFI layer is correct */ |
| 47 | + return; |
| 48 | + |
| 49 | + extp->TopBottom = t; |
| 50 | + printk("%s: Macronix chip detected, id:0x%04X, boot location forced " |
| 51 | + "to %s\n", map->name, cfi->id, (t == 2) ? "bottom" : "top"); |
| 52 | +} |
| 53 | +#endif /* CONFIG_MTD_CFI_FIXUP_MACRONIX_BOOTLOC */ |
| 54 | + |
| 55 | static struct cfi_fixup cfi_fixup_table[] = { |
| 56 | { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL }, |
| 57 | #ifdef AMD_BOOTLOC_BUG |
| 58 | @@ -318,6 +359,9 @@ static struct cfi_fixup fixup_table[] = |
| 59 | */ |
| 60 | { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_erase_chip, NULL }, |
| 61 | { CFI_MFR_ATMEL, AT49BV6416, fixup_use_atmel_lock, NULL }, |
| 62 | +#ifdef CONFIG_MTD_CFI_FIXUP_MACRONIX_BOOTLOC |
| 63 | + { MANUFACTURER_MACRONIX, CFI_ID_ANY, fixup_macronix_bootloc, NULL, }, |
| 64 | +#endif |
| 65 | { 0, 0, NULL, NULL } |
| 66 | }; |
| 67 | |
| 68 | --- a/drivers/mtd/chips/Kconfig |
| 69 | +++ b/drivers/mtd/chips/Kconfig |
| 70 | @@ -198,6 +198,14 @@ config MTD_CFI_AMDSTD |
| 71 | provides support for one of those command sets, used on chips |
| 72 | including the AMD Am29LV320. |
| 73 | |
| 74 | +config MTD_CFI_FIXUP_MACRONIX_BOOTLOC |
| 75 | + bool "Fix boot-block location for Macronix flash chips" |
| 76 | + depends on MTD_CFI_AMDSTD |
| 77 | + help |
| 78 | + Some Macronix flash chips have no/wrong boot-block location in the |
| 79 | + CFI table, and the driver may detect the type incorrectly. Select |
| 80 | + this if your board has such chip. |
| 81 | + |
| 82 | config MTD_CFI_STAA |
| 83 | tristate "Support for ST (Advanced Architecture) flash chips" |
| 84 | depends on MTD_GEN_PROBE |
| 85 | |