diff options
Diffstat (limited to 'drivers/gpu/drm/drm_mode_config.c')
-rw-r--r-- | drivers/gpu/drm/drm_mode_config.c | 34 |
1 files changed, 15 insertions, 19 deletions
diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index a9a40dc629d3..649f1da3596f 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -94,6 +94,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data, uint32_t __user *crtc_id; uint32_t __user *connector_id; uint32_t __user *encoder_id; + struct drm_connector_list_iter conn_iter; if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; @@ -113,9 +114,6 @@ int drm_mode_getresources(struct drm_device *dev, void *data, card_res->count_fbs = count; mutex_unlock(&file_priv->fbs_lock); - /* mode_config.mutex protects the connector list against e.g. DP MST - * connector hot-adding. CRTC/Plane lists are invariant. */ - mutex_lock(&dev->mode_config.mutex); card_res->max_height = dev->mode_config.max_height; card_res->min_height = dev->mode_config.min_height; card_res->max_width = dev->mode_config.max_width; @@ -125,10 +123,8 @@ int drm_mode_getresources(struct drm_device *dev, void *data, crtc_id = u64_to_user_ptr(card_res->crtc_id_ptr); drm_for_each_crtc(crtc, dev) { if (count < card_res->count_crtcs && - put_user(crtc->base.id, crtc_id + count)) { - ret = -EFAULT; - goto out; - } + put_user(crtc->base.id, crtc_id + count)) + return -EFAULT; count++; } card_res->count_crtcs = count; @@ -137,28 +133,26 @@ int drm_mode_getresources(struct drm_device *dev, void *data, encoder_id = u64_to_user_ptr(card_res->encoder_id_ptr); drm_for_each_encoder(encoder, dev) { if (count < card_res->count_encoders && - put_user(encoder->base.id, encoder_id + count)) { - ret = -EFAULT; - goto out; - } + put_user(encoder->base.id, encoder_id + count)) + return -EFAULT; count++; } card_res->count_encoders = count; + drm_connector_list_iter_get(dev, &conn_iter); count = 0; connector_id = u64_to_user_ptr(card_res->connector_id_ptr); - drm_for_each_connector(connector, dev) { + drm_for_each_connector_iter(connector, &conn_iter) { if (count < card_res->count_connectors && put_user(connector->base.id, connector_id + count)) { - ret = -EFAULT; - goto out; + drm_connector_list_iter_put(&conn_iter); + return -EFAULT; } count++; } card_res->count_connectors = count; + drm_connector_list_iter_put(&conn_iter); -out: - mutex_unlock(&dev->mode_config.mutex); return ret; } @@ -176,6 +170,7 @@ void drm_mode_config_reset(struct drm_device *dev) struct drm_plane *plane; struct drm_encoder *encoder; struct drm_connector *connector; + struct drm_connector_list_iter conn_iter; drm_for_each_plane(plane, dev) if (plane->funcs->reset) @@ -189,11 +184,11 @@ void drm_mode_config_reset(struct drm_device *dev) if (encoder->funcs->reset) encoder->funcs->reset(encoder); - 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) if (connector->funcs->reset) connector->funcs->reset(connector); - mutex_unlock(&dev->mode_config.mutex); + drm_connector_list_iter_put(&conn_iter); } EXPORT_SYMBOL(drm_mode_config_reset); @@ -374,6 +369,7 @@ void drm_mode_config_init(struct drm_device *dev) idr_init(&dev->mode_config.crtc_idr); idr_init(&dev->mode_config.tile_idr); ida_init(&dev->mode_config.connector_ida); + spin_lock_init(&dev->mode_config.connector_list_lock); drm_mode_create_standard_properties(dev); |