diff options
Diffstat (limited to 'drivers/gpu/drm/drm_crtc_helper.c')
-rw-r--r-- | drivers/gpu/drm/drm_crtc_helper.c | 49 |
1 files changed, 38 insertions, 11 deletions
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 26061753f3bf..923a17c05e01 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -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; } |