Commit dcd14dd9 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'topic/connector-locking-2015-07-23' of...

Merge tag 'topic/connector-locking-2015-07-23' of git://anongit.freedesktop.org/drm-intel into drm-next

connector hotplug locking cleanup and fixes to make it save against
atomic. Note that because of depencies this is based on top of the
drm-intel-next pull, so that one needs to go in before this one.

I've also thrown in the mode_group removal on top since it's defunct,
never worked really, no one seems to care and the code can be resurrected
easily.

* tag 'topic/connector-locking-2015-07-23' of git://anongit.freedesktop.org/drm-intel:
  drm: gc now dead mode_group code
  drm: Stop filtering according to mode_group in getresources
  drm: Roll out drm_for_each_{plane,crtc,encoder}
  drm/cma-helper: Fix locking in drm_fb_cma_debugfs_show
  drm: Roll out drm_for_each_connector more
  drm: Amend connector list locking rules
  drm/radeon: Take all modeset locks for DP MST hotplug
  drm/i915: Take all modeset locks for DP MST hotplug
  drm: Check locking in drm_for_each_fb
  drm/i915: Use drm_for_each_fb in i915_debugfs.c
  drm: Check locking in drm_for_each_connector
  drm/fbdev-helper: Grab mode_config.mutex in drm_fb_helper_single_add_all_connectors
  drm/probe-helper: Grab mode_config.mutex in poll_init/enable
  drm: Add modeset object iterators
  drm: Simplify drm_for_each_legacy_plane arguments
parents ce4c464b 3fdefa39
...@@ -1063,7 +1063,7 @@ drm_atomic_add_affected_connectors(struct drm_atomic_state *state, ...@@ -1063,7 +1063,7 @@ drm_atomic_add_affected_connectors(struct drm_atomic_state *state,
* Changed connectors are already in @state, so only need to look at the * Changed connectors are already in @state, so only need to look at the
* current configuration. * current configuration.
*/ */
list_for_each_entry(connector, &config->connector_list, head) { drm_for_each_connector(connector, state->dev) {
if (connector->state->crtc != crtc) if (connector->state->crtc != crtc)
continue; continue;
......
...@@ -89,7 +89,7 @@ get_current_crtc_for_encoder(struct drm_device *dev, ...@@ -89,7 +89,7 @@ get_current_crtc_for_encoder(struct drm_device *dev,
WARN_ON(!drm_modeset_is_locked(&config->connection_mutex)); WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
list_for_each_entry(connector, &config->connector_list, head) { drm_for_each_connector(connector, dev) {
if (connector->state->best_encoder != encoder) if (connector->state->best_encoder != encoder)
continue; continue;
...@@ -1988,7 +1988,7 @@ void drm_atomic_helper_connector_dpms(struct drm_connector *connector, ...@@ -1988,7 +1988,7 @@ void drm_atomic_helper_connector_dpms(struct drm_connector *connector,
WARN_ON(!drm_modeset_is_locked(&config->connection_mutex)); WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
list_for_each_entry(tmp_connector, &config->connector_list, head) { drm_for_each_connector(tmp_connector, connector->dev) {
if (tmp_connector->state->crtc != crtc) if (tmp_connector->state->crtc != crtc)
continue; continue;
......
This diff is collapsed.
...@@ -121,7 +121,7 @@ bool drm_helper_encoder_in_use(struct drm_encoder *encoder) ...@@ -121,7 +121,7 @@ bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
} }
list_for_each_entry(connector, &dev->mode_config.connector_list, head) drm_for_each_connector(connector, dev)
if (connector->encoder == encoder) if (connector->encoder == encoder)
return true; return true;
return false; return false;
...@@ -151,7 +151,7 @@ bool drm_helper_crtc_in_use(struct drm_crtc *crtc) ...@@ -151,7 +151,7 @@ bool drm_helper_crtc_in_use(struct drm_crtc *crtc)
if (!oops_in_progress) if (!oops_in_progress)
WARN_ON(!mutex_is_locked(&dev->mode_config.mutex)); WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) drm_for_each_encoder(encoder, dev)
if (encoder->crtc == crtc && drm_helper_encoder_in_use(encoder)) if (encoder->crtc == crtc && drm_helper_encoder_in_use(encoder))
return true; return true;
return false; return false;
...@@ -180,7 +180,7 @@ static void __drm_helper_disable_unused_functions(struct drm_device *dev) ...@@ -180,7 +180,7 @@ static void __drm_helper_disable_unused_functions(struct drm_device *dev)
drm_warn_on_modeset_not_all_locked(dev); drm_warn_on_modeset_not_all_locked(dev);
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { drm_for_each_encoder(encoder, dev) {
if (!drm_helper_encoder_in_use(encoder)) { if (!drm_helper_encoder_in_use(encoder)) {
drm_encoder_disable(encoder); drm_encoder_disable(encoder);
/* disconnect encoder from any connector */ /* disconnect encoder from any connector */
...@@ -188,7 +188,7 @@ static void __drm_helper_disable_unused_functions(struct drm_device *dev) ...@@ -188,7 +188,7 @@ static void __drm_helper_disable_unused_functions(struct drm_device *dev)
} }
} }
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { drm_for_each_crtc(crtc, dev) {
const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
crtc->enabled = drm_helper_crtc_in_use(crtc); crtc->enabled = drm_helper_crtc_in_use(crtc);
if (!crtc->enabled) { if (!crtc->enabled) {
...@@ -230,7 +230,7 @@ drm_crtc_prepare_encoders(struct drm_device *dev) ...@@ -230,7 +230,7 @@ drm_crtc_prepare_encoders(struct drm_device *dev)
const struct drm_encoder_helper_funcs *encoder_funcs; const struct drm_encoder_helper_funcs *encoder_funcs;
struct drm_encoder *encoder; struct drm_encoder *encoder;
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { drm_for_each_encoder(encoder, dev) {
encoder_funcs = encoder->helper_private; encoder_funcs = encoder->helper_private;
/* Disable unused encoders */ /* Disable unused encoders */
if (encoder->crtc == NULL) if (encoder->crtc == NULL)
...@@ -305,7 +305,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, ...@@ -305,7 +305,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
* adjust it according to limitations or connector properties, and also * adjust it according to limitations or connector properties, and also
* a chance to reject the mode entirely. * a chance to reject the mode entirely.
*/ */
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { drm_for_each_encoder(encoder, dev) {
if (encoder->crtc != crtc) if (encoder->crtc != crtc)
continue; continue;
...@@ -334,7 +334,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, ...@@ -334,7 +334,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
crtc->hwmode = *adjusted_mode; crtc->hwmode = *adjusted_mode;
/* Prepare the encoders and CRTCs before setting the mode. */ /* Prepare the encoders and CRTCs before setting the mode. */
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { drm_for_each_encoder(encoder, dev) {
if (encoder->crtc != crtc) if (encoder->crtc != crtc)
continue; continue;
...@@ -359,7 +359,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, ...@@ -359,7 +359,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
if (!ret) if (!ret)
goto done; goto done;
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { drm_for_each_encoder(encoder, dev) {
if (encoder->crtc != crtc) if (encoder->crtc != crtc)
continue; continue;
...@@ -376,7 +376,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, ...@@ -376,7 +376,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
/* Now enable the clocks, plane, pipe, and connectors that we set up. */ /* Now enable the clocks, plane, pipe, and connectors that we set up. */
crtc_funcs->commit(crtc); crtc_funcs->commit(crtc);
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { drm_for_each_encoder(encoder, dev) {
if (encoder->crtc != crtc) if (encoder->crtc != crtc)
continue; continue;
...@@ -418,11 +418,11 @@ drm_crtc_helper_disable(struct drm_crtc *crtc) ...@@ -418,11 +418,11 @@ drm_crtc_helper_disable(struct drm_crtc *crtc)
struct drm_encoder *encoder; struct drm_encoder *encoder;
/* Decouple all encoders and their attached connectors from this crtc */ /* Decouple all encoders and their attached connectors from this crtc */
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { drm_for_each_encoder(encoder, dev) {
if (encoder->crtc != crtc) if (encoder->crtc != crtc)
continue; continue;
list_for_each_entry(connector, &dev->mode_config.connector_list, head) { drm_for_each_connector(connector, dev) {
if (connector->encoder != encoder) if (connector->encoder != encoder)
continue; continue;
...@@ -519,12 +519,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) ...@@ -519,12 +519,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
* restored, not the drivers personal bookkeeping. * restored, not the drivers personal bookkeeping.
*/ */
count = 0; count = 0;
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { drm_for_each_encoder(encoder, dev) {
save_encoders[count++] = *encoder; save_encoders[count++] = *encoder;
} }
count = 0; count = 0;
list_for_each_entry(connector, &dev->mode_config.connector_list, head) { drm_for_each_connector(connector, dev) {
save_connectors[count++] = *connector; save_connectors[count++] = *connector;
} }
...@@ -562,7 +562,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) ...@@ -562,7 +562,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
/* a) traverse passed in connector list and get encoders for them */ /* a) traverse passed in connector list and get encoders for them */
count = 0; count = 0;
list_for_each_entry(connector, &dev->mode_config.connector_list, head) { drm_for_each_connector(connector, dev) {
const struct drm_connector_helper_funcs *connector_funcs = const struct drm_connector_helper_funcs *connector_funcs =
connector->helper_private; connector->helper_private;
new_encoder = connector->encoder; new_encoder = connector->encoder;
...@@ -602,7 +602,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) ...@@ -602,7 +602,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
} }
count = 0; count = 0;
list_for_each_entry(connector, &dev->mode_config.connector_list, head) { drm_for_each_connector(connector, dev) {
if (!connector->encoder) if (!connector->encoder)
continue; continue;
...@@ -685,12 +685,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) ...@@ -685,12 +685,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
fail: fail:
/* Restore all previous data. */ /* Restore all previous data. */
count = 0; count = 0;
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { drm_for_each_encoder(encoder, dev) {
*encoder = save_encoders[count++]; *encoder = save_encoders[count++];
} }
count = 0; count = 0;
list_for_each_entry(connector, &dev->mode_config.connector_list, head) { drm_for_each_connector(connector, dev) {
*connector = save_connectors[count++]; *connector = save_connectors[count++];
} }
...@@ -712,7 +712,7 @@ static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder) ...@@ -712,7 +712,7 @@ static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder)
struct drm_connector *connector; struct drm_connector *connector;
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
list_for_each_entry(connector, &dev->mode_config.connector_list, head) drm_for_each_connector(connector, dev)
if (connector->encoder == encoder) if (connector->encoder == encoder)
if (connector->dpms < dpms) if (connector->dpms < dpms)
dpms = connector->dpms; dpms = connector->dpms;
...@@ -746,7 +746,7 @@ static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc) ...@@ -746,7 +746,7 @@ static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
struct drm_connector *connector; struct drm_connector *connector;
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
list_for_each_entry(connector, &dev->mode_config.connector_list, head) drm_for_each_connector(connector, dev)
if (connector->encoder && connector->encoder->crtc == crtc) if (connector->encoder && connector->encoder->crtc == crtc)
if (connector->dpms < dpms) if (connector->dpms < dpms)
dpms = connector->dpms; dpms = connector->dpms;
...@@ -862,7 +862,7 @@ void drm_helper_resume_force_mode(struct drm_device *dev) ...@@ -862,7 +862,7 @@ void drm_helper_resume_force_mode(struct drm_device *dev)
bool ret; bool ret;
drm_modeset_lock_all(dev); drm_modeset_lock_all(dev);
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { drm_for_each_crtc(crtc, dev) {
if (!crtc->enabled) if (!crtc->enabled)
continue; continue;
...@@ -876,7 +876,7 @@ void drm_helper_resume_force_mode(struct drm_device *dev) ...@@ -876,7 +876,7 @@ void drm_helper_resume_force_mode(struct drm_device *dev)
/* Turn off outputs that were already powered off */ /* Turn off outputs that were already powered off */
if (drm_helper_choose_crtc_dpms(crtc)) { if (drm_helper_choose_crtc_dpms(crtc)) {
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { drm_for_each_encoder(encoder, dev) {
if(encoder->crtc != crtc) if(encoder->crtc != crtc)
continue; continue;
......
...@@ -285,7 +285,6 @@ static void drm_minor_free(struct drm_device *dev, unsigned int type) ...@@ -285,7 +285,6 @@ static void drm_minor_free(struct drm_device *dev, unsigned int type)
if (!minor) if (!minor)
return; return;
drm_mode_group_destroy(&minor->mode_group);
put_device(minor->kdev); put_device(minor->kdev);
spin_lock_irqsave(&drm_minor_lock, flags); spin_lock_irqsave(&drm_minor_lock, flags);
...@@ -700,20 +699,9 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags) ...@@ -700,20 +699,9 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags)
goto err_minors; goto err_minors;
} }
/* setup grouping for legacy outputs */
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
ret = drm_mode_group_init_legacy_group(dev,
&dev->primary->mode_group);
if (ret)
goto err_unload;
}
ret = 0; ret = 0;
goto out_unlock; goto out_unlock;
err_unload:
if (dev->driver->unload)
dev->driver->unload(dev);
err_minors: err_minors:
drm_minor_unregister(dev, DRM_MINOR_LEGACY); drm_minor_unregister(dev, DRM_MINOR_LEGACY);
drm_minor_unregister(dev, DRM_MINOR_RENDER); drm_minor_unregister(dev, DRM_MINOR_RENDER);
......
...@@ -3413,7 +3413,7 @@ struct drm_connector *drm_select_eld(struct drm_encoder *encoder, ...@@ -3413,7 +3413,7 @@ struct drm_connector *drm_select_eld(struct drm_encoder *encoder,
WARN_ON(!mutex_is_locked(&dev->mode_config.mutex)); WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
list_for_each_entry(connector, &dev->mode_config.connector_list, head) drm_for_each_connector(connector, dev)
if (connector->encoder == encoder && connector->eld[0]) if (connector->encoder == encoder && connector->eld[0])
return connector; return connector;
......
...@@ -209,23 +209,11 @@ int drm_fb_cma_debugfs_show(struct seq_file *m, void *arg) ...@@ -209,23 +209,11 @@ int drm_fb_cma_debugfs_show(struct seq_file *m, void *arg)
struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev; struct drm_device *dev = node->minor->dev;
struct drm_framebuffer *fb; struct drm_framebuffer *fb;
int ret;
ret = mutex_lock_interruptible(&dev->mode_config.mutex);
if (ret)
return ret;
ret = mutex_lock_interruptible(&dev->struct_mutex);
if (ret) {
mutex_unlock(&dev->mode_config.mutex);
return ret;
}
list_for_each_entry(fb, &dev->mode_config.fb_list, head) mutex_lock(&dev->mode_config.fb_lock);
drm_for_each_fb(fb, dev)
drm_fb_cma_describe(fb, m); drm_fb_cma_describe(fb, m);
mutex_unlock(&dev->mode_config.fb_lock);
mutex_unlock(&dev->struct_mutex);
mutex_unlock(&dev->mode_config.mutex);
return 0; return 0;
} }
......
...@@ -89,8 +89,9 @@ static LIST_HEAD(kernel_fb_helper_list); ...@@ -89,8 +89,9 @@ static LIST_HEAD(kernel_fb_helper_list);
* connectors to the fbdev, e.g. if some are reserved for special purposes or * connectors to the fbdev, e.g. if some are reserved for special purposes or
* not adequate to be used for the fbcon. * not adequate to be used for the fbcon.
* *
* Since this is part of the initial setup before the fbdev is published, no * This function is protected against concurrent connector hotadds/removals
* locking is required. * using drm_fb_helper_add_one_connector() and
* drm_fb_helper_remove_one_connector().
*/ */
int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper) int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
{ {
...@@ -98,7 +99,8 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper) ...@@ -98,7 +99,8 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
struct drm_connector *connector; struct drm_connector *connector;
int i; int i;
list_for_each_entry(connector, &dev->mode_config.connector_list, head) { mutex_lock(&dev->mode_config.mutex);
drm_for_each_connector(connector, dev) {
struct drm_fb_helper_connector *fb_helper_connector; struct drm_fb_helper_connector *fb_helper_connector;
fb_helper_connector = kzalloc(sizeof(struct drm_fb_helper_connector), GFP_KERNEL); fb_helper_connector = kzalloc(sizeof(struct drm_fb_helper_connector), GFP_KERNEL);
...@@ -108,6 +110,7 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper) ...@@ -108,6 +110,7 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
fb_helper_connector->connector = connector; fb_helper_connector->connector = connector;
fb_helper->connector_info[fb_helper->connector_count++] = fb_helper_connector; fb_helper->connector_info[fb_helper->connector_count++] = fb_helper_connector;
} }
mutex_unlock(&dev->mode_config.mutex);
return 0; return 0;
fail: fail:
for (i = 0; i < fb_helper->connector_count; i++) { for (i = 0; i < fb_helper->connector_count; i++) {
...@@ -115,6 +118,8 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper) ...@@ -115,6 +118,8 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
fb_helper->connector_info[i] = NULL; fb_helper->connector_info[i] = NULL;
} }
fb_helper->connector_count = 0; fb_helper->connector_count = 0;
mutex_unlock(&dev->mode_config.mutex);
return -ENOMEM; return -ENOMEM;
} }
EXPORT_SYMBOL(drm_fb_helper_single_add_all_connectors); EXPORT_SYMBOL(drm_fb_helper_single_add_all_connectors);
...@@ -269,7 +274,7 @@ static struct drm_framebuffer *drm_mode_config_fb(struct drm_crtc *crtc) ...@@ -269,7 +274,7 @@ static struct drm_framebuffer *drm_mode_config_fb(struct drm_crtc *crtc)
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct drm_crtc *c; struct drm_crtc *c;
list_for_each_entry(c, &dev->mode_config.crtc_list, head) { drm_for_each_crtc(c, dev) {
if (crtc->base.id == c->base.id) if (crtc->base.id == c->base.id)
return c->primary->fb; return c->primary->fb;
} }
...@@ -321,7 +326,7 @@ static bool restore_fbdev_mode(struct drm_fb_helper *fb_helper) ...@@ -321,7 +326,7 @@ static bool restore_fbdev_mode(struct drm_fb_helper *fb_helper)
drm_warn_on_modeset_not_all_locked(dev); drm_warn_on_modeset_not_all_locked(dev);
list_for_each_entry(plane, &dev->mode_config.plane_list, head) { drm_for_each_plane(plane, dev) {
if (plane->type != DRM_PLANE_TYPE_PRIMARY) if (plane->type != DRM_PLANE_TYPE_PRIMARY)
drm_plane_force_disable(plane); drm_plane_force_disable(plane);
...@@ -440,7 +445,7 @@ static bool drm_fb_helper_is_bound(struct drm_fb_helper *fb_helper) ...@@ -440,7 +445,7 @@ static bool drm_fb_helper_is_bound(struct drm_fb_helper *fb_helper)
if (dev->primary->master) if (dev->primary->master)
return false; return false;
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { drm_for_each_crtc(crtc, dev) {
if (crtc->primary->fb) if (crtc->primary->fb)
crtcs_bound++; crtcs_bound++;
if (crtc->primary->fb == fb_helper->fb) if (crtc->primary->fb == fb_helper->fb)
...@@ -637,7 +642,7 @@ int drm_fb_helper_init(struct drm_device *dev, ...@@ -637,7 +642,7 @@ int drm_fb_helper_init(struct drm_device *dev,
} }
i = 0; i = 0;
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { drm_for_each_crtc(crtc, dev) {
fb_helper->crtc_info[i].mode_set.crtc = crtc; fb_helper->crtc_info[i].mode_set.crtc = crtc;
i++; i++;
} }
......
...@@ -381,11 +381,8 @@ void drm_gem_cma_describe(struct drm_gem_cma_object *cma_obj, ...@@ -381,11 +381,8 @@ void drm_gem_cma_describe(struct drm_gem_cma_object *cma_obj,
struct seq_file *m) struct seq_file *m)
{ {
struct drm_gem_object *obj = &cma_obj->base; struct drm_gem_object *obj = &cma_obj->base;
struct drm_device *dev = obj->dev;
uint64_t off; uint64_t off;
WARN_ON(!mutex_is_locked(&dev->struct_mutex));
off = drm_vma_node_start(&obj->vma_node); off = drm_vma_node_start(&obj->vma_node);
seq_printf(m, "%2d (%2d) %08llx %pad %p %zu", seq_printf(m, "%2d (%2d) %08llx %pad %p %zu",
......
...@@ -276,7 +276,7 @@ void drm_warn_on_modeset_not_all_locked(struct drm_device *dev) ...@@ -276,7 +276,7 @@ void drm_warn_on_modeset_not_all_locked(struct drm_device *dev)
if (oops_in_progress) if (oops_in_progress)
return; return;
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) drm_for_each_crtc(crtc, dev)
WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
...@@ -464,18 +464,17 @@ EXPORT_SYMBOL(drm_modeset_unlock); ...@@ -464,18 +464,17 @@ EXPORT_SYMBOL(drm_modeset_unlock);
int drm_modeset_lock_all_crtcs(struct drm_device *dev, int drm_modeset_lock_all_crtcs(struct drm_device *dev,
struct drm_modeset_acquire_ctx *ctx) struct drm_modeset_acquire_ctx *ctx)
{ {
struct drm_mode_config *config = &dev->mode_config;
struct drm_crtc *crtc; struct drm_crtc *crtc;
struct drm_plane *plane; struct drm_plane *plane;
int ret = 0; int ret = 0;
list_for_each_entry(crtc, &config->crtc_list, head) { drm_for_each_crtc(crtc, dev) {
ret = drm_modeset_lock(&crtc->mutex, ctx); ret = drm_modeset_lock(&crtc->mutex, ctx);
if (ret) if (ret)
return ret; return ret;
} }
list_for_each_entry(plane, &config->plane_list, head) { drm_for_each_plane(plane, dev) {
ret = drm_modeset_lock(&plane->mutex, ctx); ret = drm_modeset_lock(&plane->mutex, ctx);
if (ret) if (ret)
return ret; return ret;
......
...@@ -19,7 +19,7 @@ static uint32_t drm_crtc_port_mask(struct drm_device *dev, ...@@ -19,7 +19,7 @@ static uint32_t drm_crtc_port_mask(struct drm_device *dev,
unsigned int index = 0; unsigned int index = 0;
struct drm_crtc *tmp; struct drm_crtc *tmp;
list_for_each_entry(tmp, &dev->mode_config.crtc_list, head) { drm_for_each_crtc(tmp, dev) {
if (tmp->port == port) if (tmp->port == port)
return 1 << index; return 1 << index;
......
...@@ -91,13 +91,14 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc, ...@@ -91,13 +91,14 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc,
*/ */
WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
list_for_each_entry(connector, &dev->mode_config.connector_list, head) drm_for_each_connector(connector, dev) {
if (connector->encoder && connector->encoder->crtc == crtc) { if (connector->encoder && connector->encoder->crtc == crtc) {
if (connector_list != NULL && count < num_connectors) if (connector_list != NULL && count < num_connectors)
*(connector_list++) = connector; *(connector_list++) = connector;
count++; count++;
} }
}
return count; return count;
} }
......
...@@ -93,6 +93,27 @@ static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector) ...@@ -93,6 +93,27 @@ static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector)
return 1; return 1;
} }
#define DRM_OUTPUT_POLL_PERIOD (10*HZ)
static void __drm_kms_helper_poll_enable(struct drm_device *dev)
{
bool poll = false;
struct drm_connector *connector;
WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
return;
drm_for_each_connector(connector, dev) {
if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT |
DRM_CONNECTOR_POLL_DISCONNECT))
poll = true;
}
if (poll)
schedule_delayed_work(&dev->mode_config.output_poll_work, DRM_OUTPUT_POLL_PERIOD);
}
static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connector *connector, static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connector *connector,
uint32_t maxX, uint32_t maxY, bool merge_type_bits) uint32_t maxX, uint32_t maxY, bool merge_type_bits)
{ {
...@@ -153,7 +174,7 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect ...@@ -153,7 +174,7 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
/* Re-enable polling in case the global poll config changed. */ /* Re-enable polling in case the global poll config changed. */
if (drm_kms_helper_poll != dev->mode_config.poll_running) if (drm_kms_helper_poll != dev->mode_config.poll_running)
drm_kms_helper_poll_enable(dev); __drm_kms_helper_poll_enable(dev);
dev->mode_config.poll_running = drm_kms_helper_poll; dev->mode_config.poll_running = drm_kms_helper_poll;
...@@ -295,7 +316,6 @@ void drm_kms_helper_hotplug_event(struct drm_device *dev) ...@@ -295,7 +316,6 @@ void drm_kms_helper_hotplug_event(struct drm_device *dev)
} }
EXPORT_SYMBOL(drm_kms_helper_hotplug_event); EXPORT_SYMBOL(drm_kms_helper_hotplug_event);
#define DRM_OUTPUT_POLL_PERIOD (10*HZ)
static void output_poll_execute(struct work_struct *work) static void output_poll_execute(struct work_struct *work)
{ {
struct delayed_work *delayed_work = to_delayed_work(work); struct delayed_work *delayed_work = to_delayed_work(work);
...@@ -312,7 +332,7 @@ static void output_poll_execute(struct work_struct *work) ...@@ -312,7 +332,7 @@ static void output_poll_execute(struct work_struct *work)
goto out; goto out;
mutex_lock(&dev->mode_config.mutex); mutex_lock(&dev->mode_config.mutex);
list_for_each_entry(connector, &dev->mode_config.connector_list, head) { drm_for_each_connector(connector, dev) {
/* Ignore forced connectors. */ /* Ignore forced connectors. */
if (connector->force) if (connector->force)
...@@ -407,20 +427,9 @@ EXPORT_SYMBOL(drm_kms_helper_poll_disable); ...@@ -407,20 +427,9 @@ EXPORT_SYMBOL(drm_kms_helper_poll_disable);
*/ */
void drm_kms_helper_poll_enable(struct drm_device *dev) void drm_kms_helper_poll_enable(struct drm_device *dev)
{ {
bool poll = false; mutex_lock(&dev->mode_config.mutex);
struct drm_connector *connector; __drm_kms_helper_poll_enable(dev);
mutex_unlock(&dev->mode_config.mutex);
if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
return;
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT |
DRM_CONNECTOR_POLL_DISCONNECT))
poll = true;
}
if (poll)
schedule_delayed_work(&dev->mode_config.output_poll_work, DRM_OUTPUT_POLL_PERIOD);
} }
EXPORT_SYMBOL(drm_kms_helper_poll_enable); EXPORT_SYMBOL(drm_kms_helper_poll_enable);
...@@ -495,7 +504,7 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev) ...@@ -495,7 +504,7 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev)
return false; return false;
mutex_lock(&dev->mode_config.mutex); mutex_lock(&dev->mode_config.mutex);
list_for_each_entry(connector, &dev->mode_config.connector_list, head) { drm_for_each_connector(connector, dev) {
/* Only handle HPD capable connectors. */ /* Only handle HPD capable connectors. */
if (!(connector->polled & DRM_CONNECTOR_POLL_HPD)) if (!(connector->polled & DRM_CONNECTOR_POLL_HPD))
......
...@@ -1866,6 +1866,7 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data) ...@@ -1866,6 +1866,7 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
struct drm_device *dev = node->minor->dev; struct drm_device *dev = node->minor->dev;
struct intel_fbdev *ifbdev = NULL; struct intel_fbdev *ifbdev = NULL;
struct intel_framebuffer *fb; struct intel_framebuffer *fb;
struct drm_framebuffer *drm_fb;
#ifdef CONFIG_DRM_I915_FBDEV #ifdef CONFIG_DRM_I915_FBDEV
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
...@@ -1885,7 +1886,8 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data) ...@@ -1885,7 +1886,8 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
#endif #endif
mutex_lock(&dev->mode_config.fb_lock); mutex_lock(&dev->mode_config.fb_lock);
list_for_each_entry(fb, &dev->mode_config.fb_list, base.head) { drm_for_each_fb(drm_fb, dev) {
fb = to_intel_framebuffer(drm_fb);
if (ifbdev && &fb->base == ifbdev->helper.fb) if (ifbdev && &fb->base == ifbdev->helper.fb)
continue; continue;
......
...@@ -441,10 +441,9 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo ...@@ -441,10 +441,9 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
drm_object_attach_property(&connector->base, dev->mode_config.tile_property, 0); drm_object_attach_property(&connector->base, dev->mode_config.tile_property, 0);
drm_mode_connector_set_path_property(connector, pathprop); drm_mode_connector_set_path_property(connector, pathprop);
drm_reinit_primary_mode_group(dev); drm_modeset_lock_all(dev);
mutex_lock(&dev->mode_config.mutex);
intel_connector_add_to_fbdev(intel_connector); intel_connector_add_to_fbdev(intel_connector);
mutex_unlock(&dev->mode_config.mutex); drm_modeset_unlock_all(dev);
drm_connector_register(&intel_connector->base); drm_connector_register(&intel_connector->base);
return connector; return connector;
} }
...@@ -455,18 +454,16 @@ static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, ...@@ -455,18 +454,16 @@ static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
struct intel_connector *intel_connector = to_intel_connector(connector); struct intel_connector *intel_connector = to_intel_connector(connector);
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
/* need to nuke the connector */ /* need to nuke the connector */
mutex_lock(&dev->mode_config.mutex); drm_modeset_lock_all(dev);
intel_connector_dpms(connector, DRM_MODE_DPMS_OFF); intel_connector_dpms(connector, DRM_MODE_DPMS_OFF);
mutex_unlock(&dev->mode_config.mutex); drm_modeset_unlock_all(dev);
intel_connector->unregister(intel_connector); intel_connector->unregister(intel_connector);
mutex_lock(&dev->mode_config.mutex); drm_modeset_lock_all(dev);
intel_connector_remove_from_fbdev(intel_connector); intel_connector_remove_from_fbdev(intel_connector);
drm_connector_cleanup(connector); drm_connector_cleanup(connector);
mutex_unlock(&dev->mode_config.mutex); drm_modeset_unlock_all(dev);
drm_reinit_primary_mode_group(dev);
kfree(intel_connector); kfree(intel_connector);
DRM_DEBUG_KMS("\n"); DRM_DEBUG_KMS("\n");
......
...@@ -2356,7 +2356,7 @@ static void ilk_compute_wm_parameters(struct drm_crtc *crtc, ...@@ -2356,7 +2356,7 @@ static void ilk_compute_wm_parameters(struct drm_crtc *crtc,
p->pri.horiz_pixels = intel_crtc->config->pipe_src_w; p->pri.horiz_pixels = intel_crtc->config->pipe_src_w;
p->cur.horiz_pixels = intel_crtc->base.cursor->state->crtc_w; p->cur.horiz_pixels = intel_crtc->base.cursor->state->crtc_w;
drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) { drm_for_each_legacy_plane(plane, dev) {
struct intel_plane *intel_plane = to_intel_plane(plane); struct intel_plane *intel_plane = to_intel_plane(plane);
if (intel_plane->pipe == pipe) { if (intel_plane->pipe == pipe) {
......
...@@ -284,11 +284,10 @@ static struct drm_connector *radeon_dp_add_mst_connector(struct drm_dp_mst_topol ...@@ -284,11 +284,10 @@ static struct drm_connector *radeon_dp_add_mst_connector(struct drm_dp_mst_topol
drm_object_attach_property(&connector->base, dev->mode_config.path_property, 0); drm_object_attach_property(&connector->base, dev->mode_config.path_property, 0);
drm_mode_connector_set_path_property(connector, pathprop); drm_mode_connector_set_path_property(connector, pathprop);
drm_reinit_primary_mode_group(dev);
mutex_lock(&dev->mode_config.mutex); drm_modeset_lock_all(dev);
radeon_fb_add_connector(rdev, connector); radeon_fb_add_connector(rdev, connector);
mutex_unlock(&dev->mode_config.mutex); drm_modeset_unlock_all(dev);
drm_connector_register(connector); drm_connector_register(connector);
return connector; return connector;
...@@ -303,14 +302,12 @@ static void radeon_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, ...@@ -303,14 +302,12 @@ static void radeon_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
drm_connector_unregister(connector); drm_connector_unregister(connector);
/* need to nuke the connector */ /* need to nuke the connector */
mutex_lock(&dev->mode_config.mutex); drm_modeset_lock_all(dev);
/* dpms off */ /* dpms off */
radeon_fb_remove_connector(rdev, connector); radeon_fb_remove_connector(rdev, connector);
drm_connector_cleanup(connector); drm_connector_cleanup(connector);
mutex_unlock(&dev->mode_config.mutex); drm_modeset_unlock_all(dev);
drm_reinit_primary_mode_group(dev);
kfree(connector); kfree(connector);
DRM_DEBUG_KMS("\n"); DRM_DEBUG_KMS("\n");
......
...@@ -248,7 +248,7 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc) ...@@ -248,7 +248,7 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
lcdc_write(sdev, LDDDSR, value); lcdc_write(sdev, LDDDSR, value);
/* Setup planes. */ /* Setup planes. */
drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) { drm_for_each_legacy_plane(plane, dev) {
if (plane->crtc == crtc) if (plane->crtc == crtc)
shmob_drm_plane_setup(plane); shmob_drm_plane_setup(plane);
} }
......
...@@ -676,7 +676,6 @@ struct drm_minor { ...@@ -676,7 +676,6 @@ struct drm_minor {
/* currently active master for this node. Protected by master_mutex */ /* currently active master for this node. Protected by master_mutex */
struct drm_master *master; struct drm_master *master;
struct drm_mode_group mode_group;
}; };
......
...@@ -1017,29 +1017,6 @@ struct drm_mode_config_funcs { ...@@ -1017,29 +1017,6 @@ struct drm_mode_config_funcs {
void (*atomic_state_free)(struct drm_atomic_state *state); void (*atomic_state_free)(struct drm_atomic_state *state);
}; };
/**
* struct drm_mode_group - group of mode setting resources for potential sub-grouping
* @num_crtcs: CRTC count
* @num_encoders: encoder count
* @num_connectors: connector count
* @num_bridges: bridge count
* @id_list: list of KMS object IDs in this group
*
* Currently this simply tracks the global mode setting state. But in the
* future it could allow groups of objects to be set aside into independent
* control groups for use by different user level processes (e.g. two X servers
* running simultaneously on different heads, each with their own mode
* configuration and freedom of mode setting).
*/
struct drm_mode_group {
uint32_t num_crtcs;
uint32_t num_encoders;
uint32_t num_connectors;
/* list of object IDs for this group */
uint32_t *id_list;
};
/** /**
* struct drm_mode_config - Mode configuration control structure * struct drm_mode_config - Mode configuration control structure
* @mutex: mutex protecting KMS related lists and structures * @mutex: mutex protecting KMS related lists and structures
...@@ -1324,9 +1301,6 @@ extern const char *drm_get_tv_select_name(int val); ...@@ -1324,9 +1301,6 @@ extern const char *drm_get_tv_select_name(int val);
extern void drm_fb_release(struct drm_file *file_priv); extern void drm_fb_release(struct drm_file *file_priv);
extern void drm_property_destroy_user_blobs(struct drm_device *dev, extern void drm_property_destroy_user_blobs(struct drm_device *dev,
struct drm_file *file_priv); struct drm_file *file_priv);
extern int drm_mode_group_init_legacy_group(struct drm_device *dev, struct drm_mode_group *group);
extern void drm_mode_group_destroy(struct drm_mode_group *group);
extern void drm_reinit_primary_mode_group(struct drm_device *dev);
extern bool drm_probe_ddc(struct i2c_adapter *adapter); extern bool drm_probe_ddc(struct i2c_adapter *adapter);
extern struct edid *drm_get_edid(struct drm_connector *connector, extern struct edid *drm_get_edid(struct drm_connector *connector,
struct i2c_adapter *adapter); struct i2c_adapter *adapter);
...@@ -1579,8 +1553,45 @@ static inline struct drm_property *drm_property_find(struct drm_device *dev, ...@@ -1579,8 +1553,45 @@ static inline struct drm_property *drm_property_find(struct drm_device *dev,
} }
/* Plane list iterator for legacy (overlay only) planes. */ /* Plane list iterator for legacy (overlay only) planes. */
#define drm_for_each_legacy_plane(plane, planelist) \ #define drm_for_each_legacy_plane(plane, dev) \
list_for_each_entry(plane, planelist, head) \ list_for_each_entry(plane, &(dev)->mode_config.plane_list, head) \
if (plane->type == DRM_PLANE_TYPE_OVERLAY) if (plane->type == DRM_PLANE_TYPE_OVERLAY)
#define drm_for_each_plane(plane, dev) \
list_for_each_entry(plane, &(dev)->mode_config.plane_list, head)
#define drm_for_each_crtc(crtc, dev) \
list_for_each_entry(crtc, &(dev)->mode_config.crtc_list, head)
static inline void
assert_drm_connector_list_read_locked(struct drm_mode_config *mode_config)
{
/*
* The connector hotadd/remove code currently grabs both locks when
* updating lists. Hence readers need only hold either of them to be
* safe and the check amounts to
*
* WARN_ON(not_holding(A) && not_holding(B)).
*/
WARN_ON(!mutex_is_locked(&mode_config->mutex) &&
!drm_modeset_is_locked(&mode_config->connection_mutex));
}
#define drm_for_each_connector(connector, dev) \
for (assert_drm_connector_list_read_locked(&(dev)->mode_config), \
connector = list_first_entry(&(dev)->mode_config.connector_list, \
struct drm_connector, head); \
&connector->head != (&(dev)->mode_config.connector_list); \
connector = list_next_entry(connector, head))
#define drm_for_each_encoder(encoder, dev) \
list_for_each_entry(encoder, &(dev)->mode_config.encoder_list, head)
#define drm_for_each_fb(fb, dev) \
for (WARN_ON(!mutex_is_locked(&(dev)->mode_config.fb_lock)), \
fb = list_first_entry(&(dev)->mode_config.fb_list, \
struct drm_framebuffer, head); \
&fb->head != (&(dev)->mode_config.fb_list); \
fb = list_next_entry(fb, head))
#endif /* __DRM_CRTC_H__ */ #endif /* __DRM_CRTC_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment