summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/drm_fb_helper.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2015-07-24 14:30:29 +1000
committerDave Airlie <airlied@redhat.com>2015-07-24 14:30:29 +1000
commitdcd14dd957f02ef679c61325a2221a0574bdcab3 (patch)
tree225a38a705ba692065c17b39f04c95fe7258e663 /drivers/gpu/drm/drm_fb_helper.c
parentce4c464b93187d3faffd9048f0ee0ec7bf9aa2a9 (diff)
parent3fdefa399e4644399ce3e74e65a75122d52dba6a (diff)
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
Diffstat (limited to 'drivers/gpu/drm/drm_fb_helper.c')
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index eaf652b389d9..73f90f7e2f74 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -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
* not adequate to be used for the fbcon.
*
- * Since this is part of the initial setup before the fbdev is published, no
- * locking is required.
+ * This function is protected against concurrent connector hotadds/removals
+ * 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)
{
@@ -98,7 +99,8 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
struct drm_connector *connector;
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;
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)
fb_helper_connector->connector = connector;
fb_helper->connector_info[fb_helper->connector_count++] = fb_helper_connector;
}
+ mutex_unlock(&dev->mode_config.mutex);
return 0;
fail:
for (i = 0; i < fb_helper->connector_count; i++) {
@@ -115,6 +118,8 @@ fail:
fb_helper->connector_info[i] = NULL;
}
fb_helper->connector_count = 0;
+ mutex_unlock(&dev->mode_config.mutex);
+
return -ENOMEM;
}
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)
struct drm_device *dev = crtc->dev;
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)
return c->primary->fb;
}
@@ -321,7 +326,7 @@ static bool restore_fbdev_mode(struct drm_fb_helper *fb_helper)
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)
drm_plane_force_disable(plane);
@@ -440,7 +445,7 @@ static bool drm_fb_helper_is_bound(struct drm_fb_helper *fb_helper)
if (dev->primary->master)
return false;
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+ drm_for_each_crtc(crtc, dev) {
if (crtc->primary->fb)
crtcs_bound++;
if (crtc->primary->fb == fb_helper->fb)
@@ -637,7 +642,7 @@ int drm_fb_helper_init(struct drm_device *dev,
}
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;
i++;
}