
From: "Antonino A. Daplas" <adaplas@hotpop.com>

Check first if EDID block came from a broken display before fixing.

Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/drivers/video/fbmon.c |   69 ++++++++++++++++++++++++++++--------------
 1 files changed, 46 insertions(+), 23 deletions(-)

diff -puN drivers/video/fbmon.c~fbdev-cleanup-broken-edid-fixup-code drivers/video/fbmon.c
--- 25/drivers/video/fbmon.c~fbdev-cleanup-broken-edid-fixup-code	Thu Jan 13 15:40:47 2005
+++ 25-akpm/drivers/video/fbmon.c	Thu Jan 13 15:40:47 2005
@@ -89,11 +89,12 @@ static void copy_string(unsigned char *c
   while (i-- && (*--s == 0x20)) *s = 0;
 }
 
-static void fix_edid(unsigned char *edid)
+static int check_edid(unsigned char *edid)
 {
 	unsigned char *block = edid + ID_MANUFACTURER_NAME, manufacturer[4];
 	unsigned char *b;
-	u32 model, i;
+	u32 model;
+	int i, fix = 0, ret = 0;
 
 	manufacturer[0] = ((block[0] & 0x7c) >> 2) + '@';
 	manufacturer[1] = ((block[0] & 0x03) << 3) +
@@ -105,36 +106,57 @@ static void fix_edid(unsigned char *edid
 	for (i = 0; i < ARRAY_SIZE(brokendb); i++) {
 		if (!strncmp(manufacturer, brokendb[i].manufacturer, 4) &&
 			brokendb[i].model == model) {
-
 			printk("fbmon: The EDID Block of "
 			       "Manufacturer: %s Model: 0x%x is known to "
 			       "be broken,\n",  manufacturer, model);
-			switch (brokendb[i].fix) {
-			case FBMON_FIX_HEADER:
-				printk("fbmon: trying a header "
-				       "reconstruct\n");
-				memcpy(edid, edid_v1_header, 8);
-				break;
-			case FBMON_FIX_INPUT:
-				printk("fbmon: trying to fix input type\n");
-				b = edid + EDID_STRUCT_DISPLAY;
-				/* Only if display is GTF capable will
-				   the input type be reset to analog */
-				if (b[4] & 0x01) {
-					b[0] &= ~0x80;
-					edid[127] += 0x80;
-				}
-			}
+ 			fix = brokendb[i].fix;
+ 			break;
+		}
+	}
+
+	switch (fix) {
+	case FBMON_FIX_HEADER:
+		for (i = 0; i < 8; i++) {
+			if (edid[i] != edid_v1_header[i])
+				ret = fix;
 		}
+		break;
+	case FBMON_FIX_INPUT:
+		b = edid + EDID_STRUCT_DISPLAY;
+		/* Only if display is GTF capable will
+		   the input type be reset to analog */
+		if (b[4] & 0x01 && b[0] & 0x80)
+			ret = fix;
+		break;
+	}
+
+	return ret;
+}
+
+static void fix_edid(unsigned char *edid, int fix)
+{
+	unsigned char *b;
+
+	switch (fix) {
+	case FBMON_FIX_HEADER:
+		printk("fbmon: trying a header reconstruct\n");
+		memcpy(edid, edid_v1_header, 8);
+		break;
+	case FBMON_FIX_INPUT:
+		printk("fbmon: trying to fix input type\n");
+		b = edid + EDID_STRUCT_DISPLAY;
+		b[0] &= ~0x80;
+		edid[127] += 0x80;
 	}
 }
 
 static int edid_checksum(unsigned char *edid)
 {
 	unsigned char i, csum = 0, all_null = 0;
-	int err = 0;
+	int err = 0, fix = check_edid(edid);
 
-	fix_edid(edid);
+	if (fix)
+		fix_edid(edid, fix);
 
 	for (i = 0; i < EDID_LENGTH; i++) {
 		csum += edid[i];
@@ -151,9 +173,10 @@ static int edid_checksum(unsigned char *
 
 static int edid_check_header(unsigned char *edid)
 {
-	int i, err = 1;
+	int i, err = 1, fix = check_edid(edid);
 
-	fix_edid(edid);
+	if (fix)
+		fix_edid(edid, fix);
 
 	for (i = 0; i < 8; i++) {
 		if (edid[i] != edid_v1_header[i])
_
