drm: Clean up connectors by unreferencing them
authorDaniel Vetter <daniel.vetter@ffwll.ch>
Tue, 13 Dec 2016 23:08:08 +0000 (00:08 +0100)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Sun, 18 Dec 2016 13:33:51 +0000 (14:33 +0100)
Only static connectors should be left at this point, and we should be
able to clean them out by simply dropping that last reference still
around from drm_connector_init.

If that leaves anything behind then we have a driver bug.

Doing the final cleanup this way also allows us to use
drm_connector_iter, removing the very last place where we walk
connector_list explicitly in drm core&helpers.

Reviewed-by: Harry Wentland <harry.wentland@amd.com>
Reviewed-by: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20161213230814.19598-8-daniel.vetter@ffwll.ch
drivers/gpu/drm/drm_mode_config.c

index 649f1da3596fb8ffc5d2376861dd84c8022771b0..ed1ee5a44a7ba78b885ea78567ad82ecf23e5c51 100644 (file)
@@ -398,7 +398,8 @@ EXPORT_SYMBOL(drm_mode_config_init);
  */
 void drm_mode_config_cleanup(struct drm_device *dev)
 {
-       struct drm_connector *connector, *ot;
+       struct drm_connector *connector;
+       struct drm_connector_list_iter conn_iter;
        struct drm_crtc *crtc, *ct;
        struct drm_encoder *encoder, *enct;
        struct drm_framebuffer *fb, *fbt;
@@ -411,10 +412,16 @@ void drm_mode_config_cleanup(struct drm_device *dev)
                encoder->funcs->destroy(encoder);
        }
 
-       list_for_each_entry_safe(connector, ot,
-                                &dev->mode_config.connector_list, head) {
-               connector->funcs->destroy(connector);
+       drm_connector_list_iter_get(dev, &conn_iter);
+       drm_for_each_connector_iter(connector, &conn_iter) {
+               /* drm_connector_list_iter holds an full reference to the
+                * current connector itself, which means it is inherently safe
+                * against unreferencing the current connector - but not against
+                * deleting it right away. */
+               drm_connector_unreference(connector);
        }
+       drm_connector_list_iter_put(&conn_iter);
+       WARN_ON(!list_empty(&dev->mode_config.connector_list));
 
        list_for_each_entry_safe(property, pt, &dev->mode_config.property_list,
                                 head) {