It's such a special case there's no point in keeping it inline in the happy day scenario, confusing matters. Cc: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> Signed-off-by: Jani Nikula <jani.nikula@xxxxxxxxx> --- drivers/gpu/drm/drm_edid.c | 52 ++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index a1be5c3a80e5..dee95332d7e1 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -1821,6 +1821,33 @@ bool drm_edid_is_valid(struct edid *edid) } EXPORT_SYMBOL(drm_edid_is_valid); +static struct edid *edid_filter_invalid_blocks(const struct edid *edid, + int valid_extensions) +{ + struct edid *new, *base; + int i; + + new = kmalloc_array(valid_extensions + 1, EDID_LENGTH, GFP_KERNEL); + if (!new) + goto out; + + base = new; + for (i = 0; i <= edid->extensions; i++) { + const void *block = edid + i; + + if (edid_block_valid(block, i == 0)) + memcpy(base++, block, EDID_LENGTH); + } + + new->checksum += new->extensions - valid_extensions; + new->extensions = valid_extensions; + +out: + kfree(edid); + + return new; +} + #define DDC_SEGMENT_ADDR 0x30 /** * drm_do_probe_ddc_edid() - get EDID information via I2C @@ -2070,32 +2097,9 @@ struct edid *drm_do_get_edid(struct drm_connector *connector, } if (valid_extensions != edid->extensions) { - struct edid *base; - int i; - connector_bad_edid(connector, (u8 *)edid, edid->extensions + 1); - edid->checksum += edid->extensions - valid_extensions; - edid->extensions = valid_extensions; - - new = kmalloc_array(valid_extensions + 1, EDID_LENGTH, - GFP_KERNEL); - if (!new) - goto out; - - base = new; - for (i = 0; i <= edid->extensions; i++) { - void *block = edid + i; - - if (!edid_block_valid(block, i == 0)) - continue; - - memcpy(base, block, EDID_LENGTH); - base++; - } - - kfree(edid); - edid = new; + edid = edid_filter_invalid_blocks(edid, valid_extensions); } return edid; -- 2.30.2