drm: Convert all helpers to drm_connector_list_iter
authorDaniel Vetter <daniel.vetter@ffwll.ch>
Thu, 15 Dec 2016 15:58:43 +0000 (16:58 +0100)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Sun, 18 Dec 2016 13:33:22 +0000 (14:33 +0100)
Mostly nothing special (except making sure that really all error paths
and friends call iter_put).

v2: Don't forget the raw connector_list walking in
drm_helper_move_panel_connectors_to_head. That one unfortunately can't
be converted to the iterator helpers, but since it's just some list
splicing best to just wrap the entire thing up in one critical
section.

v3: Bail out after iter_put (Harry).

Cc: Harry Wentland <harry.wentland@amd.com>
Reviewed-by: Harry Wentland <harry.wentland@amd.com>
Reviewed-by: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/20161215155843.13408-1-daniel.vetter@ffwll.ch
drivers/gpu/drm/drm_atomic_helper.c
drivers/gpu/drm/drm_crtc_helper.c
drivers/gpu/drm/drm_fb_helper.c
drivers/gpu/drm/drm_modeset_helper.c
drivers/gpu/drm/drm_plane_helper.c
drivers/gpu/drm/drm_probe_helper.c

index 23767df..e2e15a9 100644 (file)
@@ -94,9 +94,10 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
 {
        struct drm_connector_state *conn_state;
        struct drm_connector *connector;
+       struct drm_connector_list_iter conn_iter;
        struct drm_encoder *encoder;
        unsigned encoder_mask = 0;
-       int i, ret;
+       int i, ret = 0;
 
        /*
         * First loop, find all newly assigned encoders from the connectors
@@ -144,7 +145,8 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
         * and the crtc is disabled if no encoder is left. This preserves
         * compatibility with the legacy set_config behavior.
         */
-       drm_for_each_connector(connector, state->dev) {
+       drm_connector_list_iter_get(state->dev, &conn_iter);
+       drm_for_each_connector_iter(connector, &conn_iter) {
                struct drm_crtc_state *crtc_state;
 
                if (drm_atomic_get_existing_connector_state(state, connector))
@@ -160,12 +162,15 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
                                         connector->state->crtc->base.id,
                                         connector->state->crtc->name,
                                         connector->base.id, connector->name);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto out;
                }
 
                conn_state = drm_atomic_get_connector_state(state, connector);
-               if (IS_ERR(conn_state))
-                       return PTR_ERR(conn_state);
+               if (IS_ERR(conn_state)) {
+                       ret = PTR_ERR(conn_state);
+                       goto out;
+               }
 
                DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s], disabling [CONNECTOR:%d:%s]\n",
                                 encoder->base.id, encoder->name,
@@ -176,19 +181,21 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
 
                ret = drm_atomic_set_crtc_for_connector(conn_state, NULL);
                if (ret)
-                       return ret;
+                       goto out;
 
                if (!crtc_state->connector_mask) {
                        ret = drm_atomic_set_mode_prop_for_crtc(crtc_state,
                                                                NULL);
                        if (ret < 0)
-                               return ret;
+                               goto out;
 
                        crtc_state->active = false;
                }
        }
+out:
+       drm_connector_list_iter_put(&conn_iter);
 
-       return 0;
+       return ret;
 }
 
 static void
@@ -2442,6 +2449,7 @@ int drm_atomic_helper_disable_all(struct drm_device *dev,
 {
        struct drm_atomic_state *state;
        struct drm_connector *conn;
+       struct drm_connector_list_iter conn_iter;
        int err;
 
        state = drm_atomic_state_alloc(dev);
@@ -2450,7 +2458,8 @@ int drm_atomic_helper_disable_all(struct drm_device *dev,
 
        state->acquire_ctx = ctx;
 
-       drm_for_each_connector(conn, dev) {
+       drm_connector_list_iter_get(dev, &conn_iter);
+       drm_for_each_connector_iter(conn, &conn_iter) {
                struct drm_crtc *crtc = conn->state->crtc;
                struct drm_crtc_state *crtc_state;
 
@@ -2468,6 +2477,7 @@ int drm_atomic_helper_disable_all(struct drm_device *dev,
 
        err = drm_atomic_commit(state);
 free:
+       drm_connector_list_iter_put(&conn_iter);
        drm_atomic_state_put(state);
        return err;
 }
@@ -2840,6 +2850,7 @@ int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
        struct drm_crtc_state *crtc_state;
        struct drm_crtc *crtc;
        struct drm_connector *tmp_connector;
+       struct drm_connector_list_iter conn_iter;
        int ret;
        bool active = false;
        int old_mode = connector->dpms;
@@ -2867,7 +2878,8 @@ retry:
 
        WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
 
-       drm_for_each_connector(tmp_connector, connector->dev) {
+       drm_connector_list_iter_get(connector->dev, &conn_iter);
+       drm_for_each_connector_iter(tmp_connector, &conn_iter) {
                if (tmp_connector->state->crtc != crtc)
                        continue;
 
@@ -2876,6 +2888,7 @@ retry:
                        break;
                }
        }
+       drm_connector_list_iter_put(&conn_iter);
        crtc_state->active = active;
 
        ret = drm_atomic_commit(state);
@@ -3253,6 +3266,7 @@ drm_atomic_helper_duplicate_state(struct drm_device *dev,
 {
        struct drm_atomic_state *state;
        struct drm_connector *conn;
+       struct drm_connector_list_iter conn_iter;
        struct drm_plane *plane;
        struct drm_crtc *crtc;
        int err = 0;
@@ -3283,15 +3297,18 @@ drm_atomic_helper_duplicate_state(struct drm_device *dev,
                }
        }
 
-       drm_for_each_connector(conn, dev) {
+       drm_connector_list_iter_get(dev, &conn_iter);
+       drm_for_each_connector_iter(conn, &conn_iter) {
                struct drm_connector_state *conn_state;
 
                conn_state = drm_atomic_get_connector_state(state, conn);
                if (IS_ERR(conn_state)) {
                        err = PTR_ERR(conn_state);
+                       drm_connector_list_iter_put(&conn_iter);
                        goto free;
                }
        }
+       drm_connector_list_iter_put(&conn_iter);
 
        /* clear the acquire context so that it isn't accidentally reused */
        state->acquire_ctx = NULL;
index 2606175..923a17c 100644 (file)
@@ -89,6 +89,7 @@
 bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
 {
        struct drm_connector *connector;
+       struct drm_connector_list_iter conn_iter;
        struct drm_device *dev = encoder->dev;
 
        /*
@@ -100,9 +101,15 @@ bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
                WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
        }
 
-       drm_for_each_connector(connector, dev)
-               if (connector->encoder == encoder)
+
+       drm_connector_list_iter_get(dev, &conn_iter);
+       drm_for_each_connector_iter(connector, &conn_iter) {
+               if (connector->encoder == encoder) {
+                       drm_connector_list_iter_put(&conn_iter);
                        return true;
+               }
+       }
+       drm_connector_list_iter_put(&conn_iter);
        return false;
 }
 EXPORT_SYMBOL(drm_helper_encoder_in_use);
@@ -437,10 +444,13 @@ drm_crtc_helper_disable(struct drm_crtc *crtc)
 
        /* Decouple all encoders and their attached connectors from this crtc */
        drm_for_each_encoder(encoder, dev) {
+               struct drm_connector_list_iter conn_iter;
+
                if (encoder->crtc != crtc)
                        continue;
 
-               drm_for_each_connector(connector, dev) {
+               drm_connector_list_iter_get(dev, &conn_iter);
+               drm_for_each_connector_iter(connector, &conn_iter) {
                        if (connector->encoder != encoder)
                                continue;
 
@@ -457,6 +467,7 @@ drm_crtc_helper_disable(struct drm_crtc *crtc)
                        /* we keep a reference while the encoder is bound */
                        drm_connector_unreference(connector);
                }
+               drm_connector_list_iter_put(&conn_iter);
        }
 
        __drm_helper_disable_unused_functions(dev);
@@ -508,6 +519,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
        bool mode_changed = false; /* if true do a full mode set */
        bool fb_changed = false; /* if true and !mode_changed just do a flip */
        struct drm_connector *connector;
+       struct drm_connector_list_iter conn_iter;
        int count = 0, ro, fail = 0;
        const struct drm_crtc_helper_funcs *crtc_funcs;
        struct drm_mode_set save_set;
@@ -572,9 +584,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
        }
 
        count = 0;
-       drm_for_each_connector(connector, dev) {
+       drm_connector_list_iter_get(dev, &conn_iter);
+       drm_for_each_connector_iter(connector, &conn_iter)
                save_connector_encoders[count++] = connector->encoder;
-       }
+       drm_connector_list_iter_put(&conn_iter);
 
        save_set.crtc = set->crtc;
        save_set.mode = &set->crtc->mode;
@@ -616,7 +629,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 
        /* a) traverse passed in connector list and get encoders for them */
        count = 0;
-       drm_for_each_connector(connector, dev) {
+       drm_connector_list_iter_get(dev, &conn_iter);
+       drm_for_each_connector_iter(connector, &conn_iter) {
                const struct drm_connector_helper_funcs *connector_funcs =
                        connector->helper_private;
                new_encoder = connector->encoder;
@@ -649,6 +663,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
                        connector->encoder = new_encoder;
                }
        }
+       drm_connector_list_iter_put(&conn_iter);
 
        if (fail) {
                ret = -EINVAL;
@@ -656,7 +671,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
        }
 
        count = 0;
-       drm_for_each_connector(connector, dev) {
+       drm_connector_list_iter_get(dev, &conn_iter);
+       drm_for_each_connector_iter(connector, &conn_iter) {
                if (!connector->encoder)
                        continue;
 
@@ -674,6 +690,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
                if (new_crtc &&
                    !drm_encoder_crtc_ok(connector->encoder, new_crtc)) {
                        ret = -EINVAL;
+                       drm_connector_list_iter_put(&conn_iter);
                        goto fail;
                }
                if (new_crtc != connector->encoder->crtc) {
@@ -690,6 +707,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
                                      connector->base.id, connector->name);
                }
        }
+       drm_connector_list_iter_put(&conn_iter);
 
        /* mode_set_base is not a required function */
        if (fb_changed && !crtc_funcs->mode_set_base)
@@ -744,9 +762,10 @@ fail:
        }
 
        count = 0;
-       drm_for_each_connector(connector, dev) {
+       drm_connector_list_iter_get(dev, &conn_iter);
+       drm_for_each_connector_iter(connector, &conn_iter)
                connector->encoder = save_connector_encoders[count++];
-       }
+       drm_connector_list_iter_put(&conn_iter);
 
        /* after fail drop reference on all unbound connectors in set, let
         * bound connectors keep their reference
@@ -773,12 +792,16 @@ static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder)
 {
        int dpms = DRM_MODE_DPMS_OFF;
        struct drm_connector *connector;
+       struct drm_connector_list_iter conn_iter;
        struct drm_device *dev = encoder->dev;
 
-       drm_for_each_connector(connector, dev)
+       drm_connector_list_iter_get(dev, &conn_iter);
+       drm_for_each_connector_iter(connector, &conn_iter)
                if (connector->encoder == encoder)
                        if (connector->dpms < dpms)
                                dpms = connector->dpms;
+       drm_connector_list_iter_put(&conn_iter);
+
        return dpms;
 }
 
@@ -810,12 +833,16 @@ static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
 {
        int dpms = DRM_MODE_DPMS_OFF;
        struct drm_connector *connector;
+       struct drm_connector_list_iter conn_iter;
        struct drm_device *dev = crtc->dev;
 
-       drm_for_each_connector(connector, dev)
+       drm_connector_list_iter_get(dev, &conn_iter);
+       drm_for_each_connector_iter(connector, &conn_iter)
                if (connector->encoder && connector->encoder->crtc == crtc)
                        if (connector->dpms < dpms)
                                dpms = connector->dpms;
+       drm_connector_list_iter_put(&conn_iter);
+
        return dpms;
 }
 
index bee5e41..145d55f 100644 (file)
@@ -120,20 +120,22 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
 {
        struct drm_device *dev = fb_helper->dev;
        struct drm_connector *connector;
-       int i, ret;
+       struct drm_connector_list_iter conn_iter;
+       int i, ret = 0;
 
        if (!drm_fbdev_emulation)
                return 0;
 
        mutex_lock(&dev->mode_config.mutex);
-       drm_for_each_connector(connector, dev) {
+       drm_connector_list_iter_get(dev, &conn_iter);
+       drm_for_each_connector_iter(connector, &conn_iter) {
                ret = drm_fb_helper_add_one_connector(fb_helper, connector);
 
                if (ret)
                        goto fail;
        }
-       mutex_unlock(&dev->mode_config.mutex);
-       return 0;
+       goto out;
+
 fail:
        drm_fb_helper_for_each_connector(fb_helper, i) {
                struct drm_fb_helper_connector *fb_helper_connector =
@@ -145,6 +147,8 @@ fail:
                fb_helper->connector_info[i] = NULL;
        }
        fb_helper->connector_count = 0;
+out:
+       drm_connector_list_iter_put(&conn_iter);
        mutex_unlock(&dev->mode_config.mutex);
 
        return ret;
index b4f3665..cc44a9a 100644 (file)
@@ -48,6 +48,7 @@ void drm_helper_move_panel_connectors_to_head(struct drm_device *dev)
 
        INIT_LIST_HEAD(&panel_list);
 
+       spin_lock_irq(&dev->mode_config.connector_list_lock);
        list_for_each_entry_safe(connector, tmp,
                                 &dev->mode_config.connector_list, head) {
                if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS ||
@@ -57,6 +58,7 @@ void drm_helper_move_panel_connectors_to_head(struct drm_device *dev)
        }
 
        list_splice(&panel_list, &dev->mode_config.connector_list);
+       spin_unlock_irq(&dev->mode_config.connector_list_lock);
 }
 EXPORT_SYMBOL(drm_helper_move_panel_connectors_to_head);
 
index 191a5f0..8b042a1 100644 (file)
@@ -75,6 +75,7 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc,
 {
        struct drm_device *dev = crtc->dev;
        struct drm_connector *connector;
+       struct drm_connector_list_iter conn_iter;
        int count = 0;
 
        /*
@@ -84,7 +85,8 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc,
         */
        WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
 
-       drm_for_each_connector(connector, dev) {
+       drm_connector_list_iter_get(dev, &conn_iter);
+       drm_for_each_connector_iter(connector, &conn_iter) {
                if (connector->encoder && connector->encoder->crtc == crtc) {
                        if (connector_list != NULL && count < num_connectors)
                                *(connector_list++) = connector;
@@ -92,6 +94,7 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc,
                        count++;
                }
        }
+       drm_connector_list_iter_put(&conn_iter);
 
        return count;
 }
index ac953f0..7cff91e 100644 (file)
@@ -129,6 +129,7 @@ void drm_kms_helper_poll_enable_locked(struct drm_device *dev)
 {
        bool poll = false;
        struct drm_connector *connector;
+       struct drm_connector_list_iter conn_iter;
        unsigned long delay = DRM_OUTPUT_POLL_PERIOD;
 
        WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
@@ -136,11 +137,13 @@ void drm_kms_helper_poll_enable_locked(struct drm_device *dev)
        if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
                return;
 
-       drm_for_each_connector(connector, dev) {
+       drm_connector_list_iter_get(dev, &conn_iter);
+       drm_for_each_connector_iter(connector, &conn_iter) {
                if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT |
                                         DRM_CONNECTOR_POLL_DISCONNECT))
                        poll = true;
        }
+       drm_connector_list_iter_put(&conn_iter);
 
        if (dev->mode_config.delayed_event) {
                poll = true;
@@ -382,6 +385,7 @@ static void output_poll_execute(struct work_struct *work)
        struct delayed_work *delayed_work = to_delayed_work(work);
        struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work);
        struct drm_connector *connector;
+       struct drm_connector_list_iter conn_iter;
        enum drm_connector_status old_status;
        bool repoll = false, changed;
 
@@ -397,8 +401,8 @@ static void output_poll_execute(struct work_struct *work)
                goto out;
        }
 
-       drm_for_each_connector(connector, dev) {
-
+       drm_connector_list_iter_get(dev, &conn_iter);
+       drm_for_each_connector_iter(connector, &conn_iter) {
                /* Ignore forced connectors. */
                if (connector->force)
                        continue;
@@ -451,6 +455,7 @@ static void output_poll_execute(struct work_struct *work)
                        changed = true;
                }
        }
+       drm_connector_list_iter_put(&conn_iter);
 
        mutex_unlock(&dev->mode_config.mutex);
 
@@ -562,6 +567,7 @@ EXPORT_SYMBOL(drm_kms_helper_poll_fini);
 bool drm_helper_hpd_irq_event(struct drm_device *dev)
 {
        struct drm_connector *connector;
+       struct drm_connector_list_iter conn_iter;
        enum drm_connector_status old_status;
        bool changed = false;
 
@@ -569,8 +575,8 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev)
                return false;
 
        mutex_lock(&dev->mode_config.mutex);
-       drm_for_each_connector(connector, dev) {
-
+       drm_connector_list_iter_get(dev, &conn_iter);
+       drm_for_each_connector_iter(connector, &conn_iter) {
                /* Only handle HPD capable connectors. */
                if (!(connector->polled & DRM_CONNECTOR_POLL_HPD))
                        continue;
@@ -586,7 +592,7 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev)
                if (old_status != connector->status)
                        changed = true;
        }
-
+       drm_connector_list_iter_put(&conn_iter);
        mutex_unlock(&dev->mode_config.mutex);
 
        if (changed)