summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/drm_edid.c30
-rw-r--r--include/drm/drm_edid.h1
2 files changed, 31 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 616c1cdc7507..c3cf942186b7 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2040,6 +2040,36 @@ bool drm_edid_is_valid(struct edid *edid)
}
EXPORT_SYMBOL(drm_edid_is_valid);
+/**
+ * drm_edid_valid - sanity check EDID data
+ * @drm_edid: EDID data
+ *
+ * Sanity check an EDID. Cross check block count against allocated size and
+ * checksum the blocks.
+ *
+ * Return: True if the EDID data is valid, false otherwise.
+ */
+bool drm_edid_valid(const struct drm_edid *drm_edid)
+{
+ int i;
+
+ if (!drm_edid)
+ return false;
+
+ if (edid_size_by_blocks(__drm_edid_block_count(drm_edid)) != drm_edid->size)
+ return false;
+
+ for (i = 0; i < drm_edid_block_count(drm_edid); i++) {
+ const void *block = drm_edid_block_data(drm_edid, i);
+
+ if (!edid_block_valid(block, i == 0))
+ return false;
+ }
+
+ return true;
+}
+EXPORT_SYMBOL(drm_edid_valid);
+
static struct edid *edid_filter_invalid_blocks(struct edid *edid,
size_t *alloc_size)
{
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 05380681a4fb..a2e25e7e6ee5 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -606,6 +606,7 @@ drm_display_mode_from_cea_vic(struct drm_device *dev,
const struct drm_edid *drm_edid_alloc(const void *edid, size_t size);
const struct drm_edid *drm_edid_dup(const struct drm_edid *drm_edid);
void drm_edid_free(const struct drm_edid *drm_edid);
+bool drm_edid_valid(const struct drm_edid *drm_edid);
const struct edid *drm_edid_raw(const struct drm_edid *drm_edid);
const struct drm_edid *drm_edid_read(struct drm_connector *connector);
const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,