aboutsummaryrefslogtreecommitdiffstats
path: root/recipes-kernel/linux/linux-yocto-3.10/patches/patches-mtd/collie-match-cfi-qry.patch
blob: 1333f94672241425ac190e4476be1644de2d2f45 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
diff --git a/drivers/mtd/chips/cfi_util.c b/drivers/mtd/chips/cfi_util.c
index f992418..7139d028 100644
--- a/drivers/mtd/chips/cfi_util.c
+++ b/drivers/mtd/chips/cfi_util.c
@@ -38,6 +38,24 @@ int __xipram cfi_qry_present(struct map_info *map, __u32 base,
 	val[1] = map_read(map, base + osf*0x11);
 	val[2] = map_read(map, base + osf*0x12);
 
+	/* Apparently only one of the 2 interleaved LH28F640BFHE 16 bit chips on
+	 * a 32 bit wide bus is answering to the CFI Query.
+	 * Using the expected map bankwidth=4 and chip interleave=2 we get wrong
+	 * readings like 0xffff0051 instead of 0x00510051 etc.
+	 * We take the valid bytes and recreate the expected answer as workaround.
+	 */
+	unsigned long mask;
+	mask = (1 << (cfi->device_type * 8)) - 1;
+	
+	if (((val[0].x[0] >> (cfi->device_type * 8)) == mask) &&
+	    ((val[1].x[0] >> (cfi->device_type * 8)) == mask) &&
+	    ((val[2].x[0] >> (cfi->device_type * 8)) == mask))
+	{
+	val[0].x[0] = (val[0].x[0] & mask) + ((val[0].x[0] & mask) << (cfi->device_type * 8));
+	val[1].x[0] = (val[1].x[0] & mask) + ((val[1].x[0] & mask) << (cfi->device_type * 8));
+	val[2].x[0] = (val[2].x[0] & mask) + ((val[2].x[0] & mask) << (cfi->device_type * 8));
+	}
+
 	if (!map_word_equal(map, qry[0], val[0]))
 		return 0;