From: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> Wrap the ->fill_modes() call in a small helper that first clears out the stale data from connector->display_info. This should guarantee that we get consistent display_info whether or not the drivers use the EDID based stuff to clear and fill it. TODO: what about just after init, before anyone has called ->fill_modes()? In that case userspace could see stale data if they do the cheap getconnector ioctl. Not sure if that's a valid concern though. Cc: Keith Packard <keithp@xxxxxxxxxx> Cc: Daniel Vetter <daniel.vetter@xxxxxxxx> Signed-off-by: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> --- drivers/gpu/drm/drm_connector.c | 44 +++++++++++++++++++++++++++++++++++++---- drivers/gpu/drm/drm_edid.c | 14 +------------ drivers/gpu/drm/drm_fb_helper.c | 2 +- drivers/gpu/drm/drm_sysfs.c | 6 +++--- include/drm/drm_connector.h | 3 +++ include/drm/drm_edid.h | 1 - 6 files changed, 48 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index d8c3ef4f17da..2bf19a37dbac 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -1389,7 +1389,7 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector, * duplicate it rather than attempt to ensure some arbitrary * ordering of calls. */ - drm_reset_display_info(connector); + drm_connector_reset_display_info(connector); if (edid && drm_edid_is_valid(edid)) drm_add_display_info(connector, edid); @@ -1594,9 +1594,9 @@ int drm_mode_getconnector(struct drm_device *dev, void *data, mutex_lock(&dev->mode_config.mutex); if (out_resp->count_modes == 0) { - connector->funcs->fill_modes(connector, - dev->mode_config.max_width, - dev->mode_config.max_height); + drm_connector_fill_modes(connector, + dev->mode_config.max_width, + dev->mode_config.max_height); } out_resp->mm_width = connector->display_info.width_mm; @@ -1759,3 +1759,39 @@ struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev, return tg; } EXPORT_SYMBOL(drm_mode_create_tile_group); + +/** + * drm_connector_reset_display_info - reset the connector's display info + * @connector: DRM connector + * + * Clear the old display info for @connector allowing the driver to + * repopulate it based on fresh data. + */ +void drm_connector_reset_display_info(struct drm_connector *connector) +{ + struct drm_display_info *info = &connector->display_info; + + memset(info, 0, sizeof(*info)); +} +EXPORT_SYMBOL_GPL(drm_connector_reset_display_info); + +/** + * drm_connector_fill_modes - fill connector mode list and dynamic display info + * @connector: DRM connector + * @max_width: max width for modes + * @max_height: max height for modes + * + * Reset the display info and calls &drm_connector_funcs.fill_modes() vfunc + * repopulate it and and the mode list. + * + * RETURNS: + * The number of modes found on @connector. + */ +int drm_connector_fill_modes(struct drm_connector *connector, + unsigned int max_width, unsigned int max_height) +{ + drm_connector_reset_display_info(connector); + + return connector->funcs->fill_modes(connector, max_width, max_height); +} +EXPORT_SYMBOL(drm_connector_fill_modes); diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 78c1f37be3db..618093c4a039 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -4435,18 +4435,6 @@ static void drm_parse_cea_ext(struct drm_connector *connector, } } -/* A connector has no EDID information, so we've got no EDID to compute quirks from. Reset - * all of the values which would have been set from EDID - */ -void -drm_reset_display_info(struct drm_connector *connector) -{ - struct drm_display_info *info = &connector->display_info; - - memset(info, 0, sizeof(*info)); -} -EXPORT_SYMBOL_GPL(drm_reset_display_info); - u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edid) { struct drm_display_info *info = &connector->display_info; @@ -4665,7 +4653,7 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) int num_modes = 0; u32 quirks; - drm_reset_display_info(connector); + drm_connector_reset_display_info(connector); if (edid == NULL) { clear_eld(connector); diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 18cb63b30e33..f3eddbbd0616 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -2027,7 +2027,7 @@ static int drm_fb_helper_probe_connector_modes(struct drm_fb_helper *fb_helper, drm_fb_helper_for_each_connector(fb_helper, i) { connector = fb_helper->connector_info[i]->connector; - count += connector->funcs->fill_modes(connector, maxX, maxY); + count += drm_connector_fill_modes(connector, maxX, maxY); } return count; diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 1c5b5ce1fd7f..3c6e800b66a0 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -130,9 +130,9 @@ static ssize_t status_store(struct device *device, connector->name, old_force, connector->force); - connector->funcs->fill_modes(connector, - dev->mode_config.max_width, - dev->mode_config.max_height); + drm_connector_fill_modes(connector, + dev->mode_config.max_width, + dev->mode_config.max_height); } mutex_unlock(&dev->mode_config.mutex); diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 8815ef1ce429..bf14474c83f5 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1124,6 +1124,9 @@ void drm_mode_connector_set_link_status_property(struct drm_connector *connector uint64_t link_status); int drm_connector_init_panel_orientation_property( struct drm_connector *connector, int width, int height); +void drm_connector_reset_display_info(struct drm_connector *connector); +int drm_connector_fill_modes(struct drm_connector *connector, + unsigned int max_width, unsigned int max_height); /** * struct drm_tile_group - Tile group metadata diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index 8d89a9c3748d..db5e6a990c2d 100644 --- a/include/drm/drm_edid.h +++ b/include/drm/drm_edid.h @@ -465,7 +465,6 @@ struct edid *drm_get_edid(struct drm_connector *connector, struct edid *drm_get_edid_switcheroo(struct drm_connector *connector, struct i2c_adapter *adapter); struct edid *drm_edid_duplicate(const struct edid *edid); -void drm_reset_display_info(struct drm_connector *connector); u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edid); int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid); -- 2.13.6 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel