diff options
Diffstat (limited to 'drivers/gpu/drm/drm_crtc.c')
-rw-r--r-- | drivers/gpu/drm/drm_crtc.c | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 3f5c603f9a2c..37d34ad3a0b8 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -2421,24 +2421,40 @@ static void drm_mode_attachmode(struct drm_device *dev, | |||
2421 | } | 2421 | } |
2422 | 2422 | ||
2423 | int drm_mode_attachmode_crtc(struct drm_device *dev, struct drm_crtc *crtc, | 2423 | int drm_mode_attachmode_crtc(struct drm_device *dev, struct drm_crtc *crtc, |
2424 | struct drm_display_mode *mode) | 2424 | const struct drm_display_mode *mode) |
2425 | { | 2425 | { |
2426 | struct drm_connector *connector; | 2426 | struct drm_connector *connector; |
2427 | struct drm_display_mode *dup_mode; | 2427 | int ret = 0; |
2428 | int need_dup = 0; | 2428 | struct drm_display_mode *dup_mode, *next; |
2429 | LIST_HEAD(list); | ||
2430 | |||
2429 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 2431 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
2430 | if (!connector->encoder) | 2432 | if (!connector->encoder) |
2431 | break; | 2433 | continue; |
2432 | if (connector->encoder->crtc == crtc) { | 2434 | if (connector->encoder->crtc == crtc) { |
2433 | if (need_dup) | 2435 | dup_mode = drm_mode_duplicate(dev, mode); |
2434 | dup_mode = drm_mode_duplicate(dev, mode); | 2436 | if (!dup_mode) { |
2435 | else | 2437 | ret = -ENOMEM; |
2436 | dup_mode = mode; | 2438 | goto out; |
2437 | drm_mode_attachmode(dev, connector, dup_mode); | 2439 | } |
2438 | need_dup = 1; | 2440 | list_add_tail(&dup_mode->head, &list); |
2439 | } | 2441 | } |
2440 | } | 2442 | } |
2441 | return 0; | 2443 | |
2444 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
2445 | if (!connector->encoder) | ||
2446 | continue; | ||
2447 | if (connector->encoder->crtc == crtc) | ||
2448 | list_move_tail(list.next, &connector->user_modes); | ||
2449 | } | ||
2450 | |||
2451 | WARN_ON(!list_empty(&list)); | ||
2452 | |||
2453 | out: | ||
2454 | list_for_each_entry_safe(dup_mode, next, &list, head) | ||
2455 | drm_mode_destroy(dev, dup_mode); | ||
2456 | |||
2457 | return ret; | ||
2442 | } | 2458 | } |
2443 | EXPORT_SYMBOL(drm_mode_attachmode_crtc); | 2459 | EXPORT_SYMBOL(drm_mode_attachmode_crtc); |
2444 | 2460 | ||