Skip to content

Commit

Permalink
drm: Fix drm_mode_attachmode_crtc()
Browse files Browse the repository at this point in the history
Change drm_mode_attachmode_crtc() to take an "all or nothing" approach.
If an error is returned, there are no side effects visible.

Also change the function to always duplicate the mode passed in.

Also change the function to not give up when it finds the first
connector without and encoder.

A simpler approach would be to just remove the function completely as
it's unused currently.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
  • Loading branch information
Ville Syrjälä authored and Dave Airlie committed Mar 15, 2012
1 parent 5f61bb4 commit ac235da
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 12 deletions.
38 changes: 27 additions & 11 deletions drivers/gpu/drm/drm_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2421,24 +2421,40 @@ static void drm_mode_attachmode(struct drm_device *dev,
}

int drm_mode_attachmode_crtc(struct drm_device *dev, struct drm_crtc *crtc,
struct drm_display_mode *mode)
const struct drm_display_mode *mode)
{
struct drm_connector *connector;
struct drm_display_mode *dup_mode;
int need_dup = 0;
int ret = 0;
struct drm_display_mode *dup_mode, *next;
LIST_HEAD(list);

list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
if (!connector->encoder)
break;
continue;
if (connector->encoder->crtc == crtc) {
if (need_dup)
dup_mode = drm_mode_duplicate(dev, mode);
else
dup_mode = mode;
drm_mode_attachmode(dev, connector, dup_mode);
need_dup = 1;
dup_mode = drm_mode_duplicate(dev, mode);
if (!dup_mode) {
ret = -ENOMEM;
goto out;
}
list_add_tail(&dup_mode->head, &list);
}
}
return 0;

list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
if (!connector->encoder)
continue;
if (connector->encoder->crtc == crtc)
list_move_tail(list.next, &connector->user_modes);
}

WARN_ON(!list_empty(&list));

out:
list_for_each_entry_safe(dup_mode, next, &list, head)
drm_mode_destroy(dev, dup_mode);

return ret;
}
EXPORT_SYMBOL(drm_mode_attachmode_crtc);

Expand Down
2 changes: 1 addition & 1 deletion include/drm/drm_crtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -869,7 +869,7 @@ extern int drm_mode_height(struct drm_display_mode *mode);
/* for us by fb module */
extern int drm_mode_attachmode_crtc(struct drm_device *dev,
struct drm_crtc *crtc,
struct drm_display_mode *mode);
const struct drm_display_mode *mode);
extern int drm_mode_detachmode_crtc(struct drm_device *dev, struct drm_display_mode *mode);

extern struct drm_display_mode *drm_mode_create(struct drm_device *dev);
Expand Down

0 comments on commit ac235da

Please sign in to comment.