diff options
author | Dave Airlie <airlied@linux.ie> | 2007-04-23 11:42:29 +1000 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2007-04-23 11:42:29 +1000 |
commit | ceb44021ad7755721acc3c0307c54009b666442e (patch) | |
tree | 15ec54103ff26a46060145b51ad89dfdeb60dc7f /linux-core/drm_modes.c | |
parent | 0f3c5148f02bd98411095fdc8059207fa17b4a7d (diff) |
drm: make mode numbers no change by comparing probed modes
The mode list sets all the output modes to UNVERIFIED, then probes a new list,
If a mode is on the new list and not on the old, it adds it to the old,
if a mode is on the new list and old, it just updates the status to the new
mode status.
If a mode is on the old list and not on the new, prune invalid modes should
remove all UNVERIFIED modes
Diffstat (limited to 'linux-core/drm_modes.c')
-rw-r--r-- | linux-core/drm_modes.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/linux-core/drm_modes.c b/linux-core/drm_modes.c index 54c25137..3293f91d 100644 --- a/linux-core/drm_modes.c +++ b/linux-core/drm_modes.c @@ -517,3 +517,42 @@ void drm_mode_sort(struct list_head *mode_list) { list_sort(mode_list, drm_mode_compare); } + + +/** + * drm_mode_output_list_update - update the mode list for the output + * @output: the output to update + * + * LOCKING: + * Caller must hold a lock protecting @mode_list. + * + * This moves the modes from the @output probed_modes list + * to the actual mode list. It compares the probed mode against the current + * list and only adds different modes. All modes unverified after this point + * will be removed by the prune invalid modes. + */ +void drm_mode_output_list_update(struct drm_output *output) +{ + struct drm_display_mode *mode, *t; + struct drm_display_mode *pmode, *pt; + int found_it; + list_for_each_entry_safe(pmode, pt, &output->probed_modes, + head) { + found_it = 0; + /* go through current modes checking for the new probed mode */ + list_for_each_entry(mode, &output->modes, head) { + if (drm_mode_equal(pmode, mode)) { + found_it = 1; + /* if equal delete the probed mode */ + mode->status = pmode->status; + list_del(&pmode->head); + kfree(pmode); + break; + } + } + + if (!found_it) { + list_move_tail(&pmode->head, &output->modes); + } + } +} |