--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -47,12 +47,19 @@
 #define MANUFACTURER_AMD	0x0001
 #define MANUFACTURER_ATMEL	0x001F
 #define MANUFACTURER_SST	0x00BF
+#define MANUFACTURER_MACRONIX	0x00C2
 #define SST49LF004B	        0x0060
 #define SST49LF040B	        0x0050
 #define SST49LF008A		0x005a
 #define AT49BV6416		0x00d6
 #define MANUFACTURER_SAMSUNG	0x00ec
 
+/* 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 *);
@@ -243,6 +250,41 @@
 	}
 }
 
+#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, void* param)
+{
+	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, NULL },
 #ifdef AMD_BOOTLOC_BUG
@@ -278,6 +320,9 @@
 	 */
 	{ CFI_MFR_ANY, CFI_ID_ANY, fixup_use_erase_chip, NULL },
 	{ CFI_MFR_ATMEL, AT49BV6416, fixup_use_atmel_lock, NULL },
+#ifdef CONFIG_MTD_CFI_FIXUP_MACRONIX_BOOTLOC
+	{ MANUFACTURER_MACRONIX, CFI_ID_ANY, fixup_macronix_bootloc, NULL, },
+#endif
 	{ 0, 0, NULL, NULL }
 };
 
--- a/drivers/mtd/chips/Kconfig
+++ b/drivers/mtd/chips/Kconfig
@@ -196,6 +196,14 @@
 	  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
