[PATCH 3/3] drm/edid: Only print the bad edid when aborting

Chris Wilson chris at chris-wilson.co.uk
Mon Oct 17 08:35:14 UTC 2016


Currently, if drm.debug is enabled, we get a DRM_ERROR message on the
intermediate edid reads. This causes transient failures in CI which
flags up the sporadic EDID read failures, which are recovered by
rereading the EDID automatically. This patch combines the reporting done
by drm_do_get_edid() itself with the bad block printing from
get_edid_block(), into a single warning associated with the connector
once all attempts to retrieve the EDID fail.

References: https://bugs.freedesktop.org/show_bug.cgi?id=98228
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 drivers/gpu/drm/drm_edid.c | 42 +++++++++++++++++++++++++-----------------
 1 file changed, 25 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 95de47ba1e77..51dd10c65b53 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1260,6 +1260,26 @@ drm_do_probe_ddc_edid(void *data, u8 *buf, unsigned int block, size_t len)
 	return ret == xfers ? 0 : -1;
 }
 
+static void connector_add_bad_edid(struct drm_connector *connector,
+				   u8 *block, int num)
+{
+	if (connector->bad_edid_counter++ && !(drm_debug & DRM_UT_KMS))
+		return;
+
+	if (drm_edid_is_zero(block, EDID_LENGTH)) {
+		dev_warn(connector->dev->dev,
+			 "%s: EDID block %d is all zeroes.\n",
+			 connector->name, num);
+	} else {
+		dev_warn(connector->dev->dev,
+			 "%s: EDID block %d invalid:\n",
+			 connector->name, num);
+		print_hex_dump(KERN_WARNING,
+			       " \t", DUMP_PREFIX_NONE, 16, 1,
+			       block, EDID_LENGTH, false);
+	}
+}
+
 /**
  * drm_do_get_edid - get EDID data using a custom EDID block read function
  * @connector: connector we're probing
@@ -1283,7 +1303,6 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 {
 	int i, j = 0, valid_extensions = 0;
 	u8 *edid, *new;
-	bool print_bad_edid = !connector->bad_edid_counter || (drm_debug & DRM_UT_KMS);
 
 	if ((edid = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL)
 		return NULL;
@@ -1292,7 +1311,7 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 	for (i = 0; i < 4; i++) {
 		if (get_edid_block(data, edid, 0, EDID_LENGTH))
 			goto out;
-		if (drm_edid_block_valid(edid, 0, print_bad_edid,
+		if (drm_edid_block_valid(edid, 0, false,
 					 &connector->edid_corrupt))
 			break;
 		if (i == 0 && drm_edid_is_zero(edid, EDID_LENGTH)) {
@@ -1318,20 +1337,14 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 		for (i = 0; i < 4; i++) {
 			if (get_edid_block(data, block, j, EDID_LENGTH))
 				goto out;
-			if (drm_edid_block_valid(block, j,
-						 print_bad_edid, NULL)) {
+			if (drm_edid_block_valid(block, j, false, NULL)) {
 				valid_extensions++;
 				break;
 			}
 		}
 
-		if (i == 4 && print_bad_edid) {
-			dev_warn(connector->dev->dev,
-			 "%s: Ignoring invalid EDID block %d.\n",
-			 connector->name, j);
-
-			connector->bad_edid_counter++;
-		}
+		if (i == 4)
+			connector_add_bad_edid(connector, block, j);
 	}
 
 	if (valid_extensions != edid[0x7e]) {
@@ -1346,12 +1359,7 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 	return (struct edid *)edid;
 
 carp:
-	if (print_bad_edid) {
-		dev_warn(connector->dev->dev, "%s: EDID block %d invalid.\n",
-			 connector->name, j);
-	}
-	connector->bad_edid_counter++;
-
+	connector_add_bad_edid(connector, edid, 0);
 out:
 	kfree(edid);
 	return NULL;
-- 
2.9.3



More information about the dri-devel mailing list