summaryrefslogtreecommitdiff
path: root/linux-core/drm_modes.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@linux.ie>2007-04-23 11:42:29 +1000
committerDave Airlie <airlied@linux.ie>2007-04-23 11:42:29 +1000
commitceb44021ad7755721acc3c0307c54009b666442e (patch)
tree15ec54103ff26a46060145b51ad89dfdeb60dc7f /linux-core/drm_modes.c
parent0f3c5148f02bd98411095fdc8059207fa17b4a7d (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.c39
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);
+ }
+ }
+}