Add an iterator abstraction for going through all the EDID blocks. Signed-off-by: Jani Nikula <jani.nikula@xxxxxxxxx> --- drivers/gpu/drm/drm_edid.c | 46 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 6c188539493e..31d132fcd0ca 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -3348,6 +3348,52 @@ add_detailed_modes(struct drm_connector *connector, struct edid *edid, #define EDID_CEA_YCRCB422 (1 << 4) #define EDID_CEA_VCDB_QS (1 << 6) +/* + * EDID base and extension block iterator. + * + * struct drm_edid_iter iter; + * const u8 *block; + * + * drm_edid_iter_begin(edid, &iter); + * drm_edid_iter_for_each(block, &iter) { + * // do stuff with block + * } + * drm_edid_iter_end(&iter); + */ +struct drm_edid_iter { + const struct edid *edid; + + /* Current block index. */ + int index; +}; + +static void drm_edid_iter_begin(const struct edid *edid, + struct drm_edid_iter *iter) +{ + memset(iter, 0, sizeof(*iter)); + + iter->edid = edid; +} + +static const void *__drm_edid_iter_next(struct drm_edid_iter *iter) +{ + if (!iter->edid) + return NULL; + + if (iter->index > drm_edid_extension_block_count(iter->edid)) + return NULL; + + return (const u8 *)iter->edid + EDID_LENGTH * iter->index++; +} + +#define drm_edid_iter_for_each(__block, __iter) \ + while (((__block) = __drm_edid_iter_next(__iter))) + +static void drm_edid_iter_end(struct drm_edid_iter *iter) +{ + memset(iter, 0, sizeof(*iter)); +} + /* * Search EDID for CEA extension block. */ -- 2.30.2