diff mbox

[RFC,v4,14/25] drm/fb-helper: Remove struct drm_fb_helper_connector

Message ID 20180413165354.8331-15-noralf@tronnes.org (mailing list archive)
State New, archived
Headers show

Commit Message

Noralf Trønnes April 13, 2018, 4:53 p.m. UTC
No need to maintain a list of registered connectors. Just use the
connector iterator.

TODO: Remove:
- drm_fb_helper_add_one_connector()
- drm_fb_helper_single_add_all_connectors()
- drm_fb_helper_remove_one_connector()

Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
---
 drivers/gpu/drm/drm_fb_helper.c | 359 ++++++++++------------------------------
 include/drm/drm_fb_helper.h     |  13 --
 2 files changed, 86 insertions(+), 286 deletions(-)
diff mbox

Patch

diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index ce38eadcb346..6ee61f195321 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -112,59 +112,10 @@  static DEFINE_MUTEX(kernel_fb_helper_lock);
  * deferred I/O (coupled with drm_fb_helper_fbdev_teardown()).
  */
 
-#define drm_fb_helper_for_each_connector(fbh, i__) \
-	for (({ lockdep_assert_held(&(fbh)->lock); }), \
-	     i__ = 0; i__ < (fbh)->connector_count; i__++)
-
-static int __drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper,
-					     struct drm_connector *connector)
-{
-	struct drm_fb_helper_connector *fb_conn;
-	struct drm_fb_helper_connector **temp;
-	unsigned int count;
-
-	if (!drm_fbdev_emulation)
-		return 0;
-
-	lockdep_assert_held(&fb_helper->lock);
-
-	count = fb_helper->connector_count + 1;
-
-	if (count > fb_helper->connector_info_alloc_count) {
-		size_t size = count * sizeof(fb_conn);
-
-		temp = krealloc(fb_helper->connector_info, size, GFP_KERNEL);
-		if (!temp)
-			return -ENOMEM;
-
-		fb_helper->connector_info_alloc_count = count;
-		fb_helper->connector_info = temp;
-	}
-
-	fb_conn = kzalloc(sizeof(*fb_conn), GFP_KERNEL);
-	if (!fb_conn)
-		return -ENOMEM;
-
-	drm_connector_get(connector);
-	fb_conn->connector = connector;
-	fb_helper->connector_info[fb_helper->connector_count++] = fb_conn;
-
-	return 0;
-}
-
 int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper,
 				    struct drm_connector *connector)
 {
-	int err;
-
-	if (!fb_helper)
-		return 0;
-
-	mutex_lock(&fb_helper->lock);
-	err = __drm_fb_helper_add_one_connector(fb_helper, connector);
-	mutex_unlock(&fb_helper->lock);
-
-	return err;
+	return 0;
 }
 EXPORT_SYMBOL(drm_fb_helper_add_one_connector);
 
@@ -184,87 +135,14 @@  EXPORT_SYMBOL(drm_fb_helper_add_one_connector);
  */
 int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
 {
-	struct drm_device *dev;
-	struct drm_connector *connector;
-	struct drm_connector_list_iter conn_iter;
-	int i, ret = 0;
-
-	if (!drm_fbdev_emulation || !fb_helper)
-		return 0;
-
-	dev = fb_helper->dev;
-
-	mutex_lock(&fb_helper->lock);
-	drm_connector_list_iter_begin(dev, &conn_iter);
-	drm_for_each_connector_iter(connector, &conn_iter) {
-		ret = __drm_fb_helper_add_one_connector(fb_helper, connector);
-		if (ret)
-			goto fail;
-	}
-	goto out;
-
-fail:
-	drm_fb_helper_for_each_connector(fb_helper, i) {
-		struct drm_fb_helper_connector *fb_helper_connector =
-			fb_helper->connector_info[i];
-
-		drm_connector_put(fb_helper_connector->connector);
-
-		kfree(fb_helper_connector);
-		fb_helper->connector_info[i] = NULL;
-	}
-	fb_helper->connector_count = 0;
-out:
-	drm_connector_list_iter_end(&conn_iter);
-	mutex_unlock(&fb_helper->lock);
-
-	return ret;
-}
-EXPORT_SYMBOL(drm_fb_helper_single_add_all_connectors);
-
-static int __drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
-						struct drm_connector *connector)
-{
-	struct drm_fb_helper_connector *fb_helper_connector;
-	int i, j;
-
-	if (!drm_fbdev_emulation)
-		return 0;
-
-	lockdep_assert_held(&fb_helper->lock);
-
-	drm_fb_helper_for_each_connector(fb_helper, i) {
-		if (fb_helper->connector_info[i]->connector == connector)
-			break;
-	}
-
-	if (i == fb_helper->connector_count)
-		return -EINVAL;
-	fb_helper_connector = fb_helper->connector_info[i];
-	drm_connector_put(fb_helper_connector->connector);
-
-	for (j = i + 1; j < fb_helper->connector_count; j++)
-		fb_helper->connector_info[j - 1] = fb_helper->connector_info[j];
-
-	fb_helper->connector_count--;
-	kfree(fb_helper_connector);
-
 	return 0;
 }
+EXPORT_SYMBOL(drm_fb_helper_single_add_all_connectors);
 
 int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
 				       struct drm_connector *connector)
 {
-	int err;
-
-	if (!fb_helper)
-		return 0;
-
-	mutex_lock(&fb_helper->lock);
-	err = __drm_fb_helper_remove_one_connector(fb_helper, connector);
-	mutex_unlock(&fb_helper->lock);
-
-	return err;
+	return 0;
 }
 EXPORT_SYMBOL(drm_fb_helper_remove_one_connector);
 
@@ -443,17 +321,6 @@  int drm_fb_helper_blank(int blank, struct fb_info *info)
 }
 EXPORT_SYMBOL(drm_fb_helper_blank);
 
-static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper)
-{
-	int i;
-
-	for (i = 0; i < helper->connector_count; i++) {
-		drm_connector_put(helper->connector_info[i]->connector);
-		kfree(helper->connector_info[i]);
-	}
-	kfree(helper->connector_info);
-}
-
 static void drm_fb_helper_resume_worker(struct work_struct *work)
 {
 	struct drm_fb_helper *helper = container_of(work, struct drm_fb_helper,
@@ -531,23 +398,13 @@  int drm_fb_helper_init(struct drm_device *dev,
 		return 0;
 	}
 
-	fb_helper->connector_info = kcalloc(dev->mode_config.num_connector, sizeof(struct drm_fb_helper_connector *), GFP_KERNEL);
-	if (!fb_helper->connector_info)
-		return -ENOMEM;
-
-	fb_helper->connector_info_alloc_count = dev->mode_config.num_connector;
-	fb_helper->connector_count = 0;
-
 	fb_helper->display = drm_client_display_create(dev);
 	if (IS_ERR(fb_helper->display))
-		goto out_free;
+		return PTR_ERR(fb_helper->display);
 
 	dev->fb_helper = fb_helper;
 
 	return 0;
-out_free:
-	drm_fb_helper_crtc_free(fb_helper);
-	return -ENOMEM;
 }
 EXPORT_SYMBOL(drm_fb_helper_init);
 
@@ -651,8 +508,6 @@  void drm_fb_helper_fini(struct drm_fb_helper *fb_helper)
 
 	mutex_destroy(&fb_helper->lock);
 	drm_client_display_free(fb_helper->display);
-	drm_fb_helper_crtc_free(fb_helper);
-
 }
 EXPORT_SYMBOL(drm_fb_helper_fini);
 
@@ -1474,8 +1329,9 @@  static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
 {
 	int ret = 0;
 	int crtc_count = 0;
-	int i;
+	struct drm_connector_list_iter conn_iter;
 	struct drm_fb_helper_surface_size sizes;
+	struct drm_connector *connector;
 	struct drm_mode_set *mode_set;
 	int gamma_size = 0;
 
@@ -1490,11 +1346,9 @@  static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
 		sizes.surface_depth = sizes.surface_bpp = preferred_bpp;
 
 	/* first up get a count of crtcs now in use and new min/maxes width/heights */
-	drm_fb_helper_for_each_connector(fb_helper, i) {
-		struct drm_fb_helper_connector *fb_helper_conn = fb_helper->connector_info[i];
-		struct drm_cmdline_mode *cmdline_mode;
-
-		cmdline_mode = &fb_helper_conn->connector->cmdline_mode;
+	drm_connector_list_iter_begin(fb_helper->dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
+		struct drm_cmdline_mode *cmdline_mode = &connector->cmdline_mode;
 
 		if (cmdline_mode->bpp_specified) {
 			switch (cmdline_mode->bpp) {
@@ -1519,6 +1373,7 @@  static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
 			break;
 		}
 	}
+	drm_connector_list_iter_end(&conn_iter);
 
 	crtc_count = 0;
 	drm_client_display_for_each_modeset(mode_set, fb_helper->display) {
@@ -1707,70 +1562,28 @@  static int drm_fb_helper_probe_connector_modes(struct drm_fb_helper *fb_helper,
 						uint32_t maxX,
 						uint32_t maxY)
 {
+	struct drm_connector_list_iter conn_iter;
 	struct drm_connector *connector;
-	int i, count = 0;
+	int count = 0;
 
-	drm_fb_helper_for_each_connector(fb_helper, i) {
-		connector = fb_helper->connector_info[i]->connector;
+	drm_connector_list_iter_begin(fb_helper->dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		count += connector->funcs->fill_modes(connector, maxX, maxY);
 	}
+	drm_connector_list_iter_end(&conn_iter);
 
 	return count;
 }
 
-static bool drm_has_cmdline_mode(struct drm_fb_helper_connector *fb_connector)
-{
-	return fb_connector->connector->cmdline_mode.specified;
-}
-
-static bool drm_connector_enabled(struct drm_connector *connector, bool strict)
-{
-	bool enable;
-
-	if (connector->display_info.non_desktop)
-		return false;
-
-	if (strict)
-		enable = connector->status == connector_status_connected;
-	else
-		enable = connector->status != connector_status_disconnected;
-
-	return enable;
-}
-
-static void drm_enable_connectors(struct drm_fb_helper *fb_helper,
-				  bool *enabled)
-{
-	bool any_enabled = false;
-	struct drm_connector *connector;
-	int i = 0;
-
-	drm_fb_helper_for_each_connector(fb_helper, i) {
-		connector = fb_helper->connector_info[i]->connector;
-		enabled[i] = drm_connector_enabled(connector, true);
-		DRM_DEBUG_KMS("connector %d enabled? %s\n", connector->base.id,
-			      connector->display_info.non_desktop ? "non desktop" : enabled[i] ? "yes" : "no");
-
-		any_enabled |= enabled[i];
-	}
-
-	if (any_enabled)
-		return;
-
-	drm_fb_helper_for_each_connector(fb_helper, i) {
-		connector = fb_helper->connector_info[i]->connector;
-		enabled[i] = drm_connector_enabled(connector, false);
-	}
-}
-
 static bool drm_target_cloned(struct drm_fb_helper *fb_helper,
+			      struct drm_connector **connectors,
+			      unsigned int connector_count,
 			      struct drm_display_mode **modes,
 			      struct drm_fb_offset *offsets,
 			      bool *enabled, int width, int height)
 {
 	int count, i, j;
 	bool can_clone = false;
-	struct drm_fb_helper_connector *fb_helper_conn;
 	struct drm_display_mode *dmt_mode, *mode;
 
 	/* only contemplate cloning in the single crtc case */
@@ -1778,7 +1591,7 @@  static bool drm_target_cloned(struct drm_fb_helper *fb_helper,
 		return false;
 
 	count = 0;
-	drm_fb_helper_for_each_connector(fb_helper, i) {
+	for (i = 0; i < connector_count; i++) {
 		if (enabled[i])
 			count++;
 	}
@@ -1789,11 +1602,10 @@  static bool drm_target_cloned(struct drm_fb_helper *fb_helper,
 
 	/* check the command line or if nothing common pick 1024x768 */
 	can_clone = true;
-	drm_fb_helper_for_each_connector(fb_helper, i) {
+	for (i = 0; i < connector_count; i++) {
 		if (!enabled[i])
 			continue;
-		fb_helper_conn = fb_helper->connector_info[i];
-		modes[i] = drm_connector_pick_cmdline_mode(fb_helper_conn->connector);
+		modes[i] = drm_connector_pick_cmdline_mode(connectors[i]);
 		if (!modes[i]) {
 			can_clone = false;
 			break;
@@ -1815,12 +1627,11 @@  static bool drm_target_cloned(struct drm_fb_helper *fb_helper,
 	can_clone = true;
 	dmt_mode = drm_mode_find_dmt(fb_helper->dev, 1024, 768, 60, false);
 
-	drm_fb_helper_for_each_connector(fb_helper, i) {
+	for (i = 0; i < connector_count; i++) {
 		if (!enabled[i])
 			continue;
 
-		fb_helper_conn = fb_helper->connector_info[i];
-		list_for_each_entry(mode, &fb_helper_conn->connector->modes, head) {
+		list_for_each_entry(mode, &connectors[i]->modes, head) {
 			if (drm_mode_equal(mode, dmt_mode))
 				modes[i] = mode;
 		}
@@ -1836,30 +1647,31 @@  static bool drm_target_cloned(struct drm_fb_helper *fb_helper,
 	return false;
 }
 
-static int drm_get_tile_offsets(struct drm_fb_helper *fb_helper,
+static int drm_get_tile_offsets(struct drm_connector **connectors,
+				unsigned int connector_count,
 				struct drm_display_mode **modes,
 				struct drm_fb_offset *offsets,
 				int idx,
 				int h_idx, int v_idx)
 {
-	struct drm_fb_helper_connector *fb_helper_conn;
 	int i;
 	int hoffset = 0, voffset = 0;
 
-	drm_fb_helper_for_each_connector(fb_helper, i) {
-		fb_helper_conn = fb_helper->connector_info[i];
-		if (!fb_helper_conn->connector->has_tile)
+	for (i = 0; i < connector_count; i++) {
+		struct drm_connector *connector = connectors[i];
+
+		if (!connector->has_tile)
 			continue;
 
 		if (!modes[i] && (h_idx || v_idx)) {
 			DRM_DEBUG_KMS("no modes for connector tiled %d %d\n", i,
-				      fb_helper_conn->connector->base.id);
+				      connector->base.id);
 			continue;
 		}
-		if (fb_helper_conn->connector->tile_h_loc < h_idx)
+		if (connector->tile_h_loc < h_idx)
 			hoffset += modes[i]->hdisplay;
 
-		if (fb_helper_conn->connector->tile_v_loc < v_idx)
+		if (connector->tile_v_loc < v_idx)
 			voffset += modes[i]->vdisplay;
 	}
 	offsets[idx].x = hoffset;
@@ -1868,20 +1680,20 @@  static int drm_get_tile_offsets(struct drm_fb_helper *fb_helper,
 	return 0;
 }
 
-static bool drm_target_preferred(struct drm_fb_helper *fb_helper,
+static bool drm_target_preferred(struct drm_connector **connectors,
+				 unsigned int connector_count,
 				 struct drm_display_mode **modes,
 				 struct drm_fb_offset *offsets,
 				 bool *enabled, int width, int height)
 {
-	struct drm_fb_helper_connector *fb_helper_conn;
-	const u64 mask = BIT_ULL(fb_helper->connector_count) - 1;
+	const u64 mask = BIT_ULL(connector_count) - 1;
 	u64 conn_configured = 0;
 	int tile_pass = 0;
 	int i;
 
 retry:
-	drm_fb_helper_for_each_connector(fb_helper, i) {
-		fb_helper_conn = fb_helper->connector_info[i];
+	for (i = 0; i < connector_count; i++) {
+		struct drm_connector *connector = connectors[i];
 
 		if (conn_configured & BIT_ULL(i))
 			continue;
@@ -1892,17 +1704,17 @@  static bool drm_target_preferred(struct drm_fb_helper *fb_helper,
 		}
 
 		/* first pass over all the untiled connectors */
-		if (tile_pass == 0 && fb_helper_conn->connector->has_tile)
+		if (tile_pass == 0 && connector->has_tile)
 			continue;
 
 		if (tile_pass == 1) {
-			if (fb_helper_conn->connector->tile_h_loc != 0 ||
-			    fb_helper_conn->connector->tile_v_loc != 0)
+			if (connector->tile_h_loc != 0 ||
+			    connector->tile_v_loc != 0)
 				continue;
 
 		} else {
-			if (fb_helper_conn->connector->tile_h_loc != tile_pass - 1 &&
-			    fb_helper_conn->connector->tile_v_loc != tile_pass - 1)
+			if (connector->tile_h_loc != tile_pass - 1 &&
+			    connector->tile_v_loc != tile_pass - 1)
 			/* if this tile_pass doesn't cover any of the tiles - keep going */
 				continue;
 
@@ -1910,24 +1722,23 @@  static bool drm_target_preferred(struct drm_fb_helper *fb_helper,
 			 * find the tile offsets for this pass - need to find
 			 * all tiles left and above
 			 */
-			drm_get_tile_offsets(fb_helper, modes, offsets,
-					     i, fb_helper_conn->connector->tile_h_loc, fb_helper_conn->connector->tile_v_loc);
+			drm_get_tile_offsets(connectors, connector_count, modes, offsets,
+					     i, connector->tile_h_loc, connector->tile_v_loc);
 		}
 		DRM_DEBUG_KMS("looking for cmdline mode on connector %d\n",
-			      fb_helper_conn->connector->base.id);
+			      connector->base.id);
 
 		/* got for command line mode first */
-		modes[i] = drm_connector_pick_cmdline_mode(fb_helper_conn->connector);
+		modes[i] = drm_connector_pick_cmdline_mode(connector);
 		if (!modes[i]) {
 			DRM_DEBUG_KMS("looking for preferred mode on connector %d %d\n",
-				      fb_helper_conn->connector->base.id, fb_helper_conn->connector->tile_group ? fb_helper_conn->connector->tile_group->id : 0);
-			modes[i] = drm_connector_has_preferred_mode(fb_helper_conn->connector, width, height);
+				      connector->base.id, connector->tile_group ? connector->tile_group->id : 0);
+			modes[i] = drm_connector_has_preferred_mode(connector, width, height);
 		}
 		/* No preferred modes, pick one off the list */
-		if (!modes[i] && !list_empty(&fb_helper_conn->connector->modes)) {
-			list_for_each_entry(modes[i], &fb_helper_conn->connector->modes, head)
-				break;
-		}
+		if (!modes[i])
+			modes[i] = list_first_entry_or_null(&connector->modes, struct drm_display_mode, head);
+
 		DRM_DEBUG_KMS("found mode %s\n", modes[i] ? modes[i]->name :
 			  "none");
 		conn_configured |= BIT_ULL(i);
@@ -1940,12 +1751,13 @@  static bool drm_target_preferred(struct drm_fb_helper *fb_helper,
 	return true;
 }
 
-static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
+static int drm_pick_crtcs(struct drm_client_display *display,
+			  struct drm_connector **connectors,
+			  unsigned int connector_count,
 			  struct drm_crtc **best_crtcs,
 			  struct drm_display_mode **modes,
 			  int n, int width, int height)
 {
-	struct drm_client_display *display = fb_helper->display;
 	struct drm_device *dev = display->dev;
 	int o, my_score, best_score, score;
 	struct drm_connector *connector;
@@ -1953,27 +1765,26 @@  static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
 	struct drm_mode_set *modeset;
 	struct drm_encoder *encoder;
 	struct drm_crtc **crtcs;
-	struct drm_fb_helper_connector *fb_helper_conn;
 
-	if (n == fb_helper->connector_count)
+	if (n == connector_count)
 		return 0;
 
-	fb_helper_conn = fb_helper->connector_info[n];
-	connector = fb_helper_conn->connector;
+	connector = connectors[n];
 
 	best_crtcs[n] = NULL;
-	best_score = drm_pick_crtcs(fb_helper, best_crtcs, modes, n+1, width, height);
+	best_score = drm_pick_crtcs(display, connectors, connector_count,
+				    best_crtcs, modes, n + 1, width, height);
 	if (modes[n] == NULL)
 		return best_score;
 
-	crtcs = kcalloc(fb_helper->connector_count, sizeof(*crtcs), GFP_KERNEL);
+	crtcs = kcalloc(connector_count, sizeof(*crtcs), GFP_KERNEL);
 	if (!crtcs)
 		return best_score;
 
 	my_score = 1;
 	if (connector->status == connector_status_connected)
 		my_score++;
-	if (drm_has_cmdline_mode(fb_helper_conn))
+	if (connector->cmdline_mode.specified)
 		my_score++;
 	if (drm_connector_has_preferred_mode(connector, width, height))
 		my_score++;
@@ -1985,7 +1796,7 @@  static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
 	 * NULL we fallback to the default drm_atomic_helper_best_encoder()
 	 * helper.
 	 */
-	if (drm_drv_uses_atomic_modeset(fb_helper->dev) &&
+	if (drm_drv_uses_atomic_modeset(dev) &&
 	    !connector_funcs->best_encoder)
 		encoder = drm_atomic_helper_best_encoder(connector);
 	else
@@ -2019,12 +1830,12 @@  static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
 
 		crtcs[n] = crtc;
 		memcpy(crtcs, best_crtcs, n * sizeof(*crtcs));
-		score = my_score + drm_pick_crtcs(fb_helper, crtcs, modes, n + 1,
-						  width, height);
+		score = my_score + drm_pick_crtcs(display, connectors, connector_count,
+						  crtcs, modes, n + 1, width, height);
 		if (score > best_score) {
 			best_score = score;
 			memcpy(best_crtcs, crtcs,
-			       fb_helper->connector_count * sizeof(*crtcs));
+			       connector_count * sizeof(*crtcs));
 		}
 	}
 out:
@@ -2037,11 +1848,12 @@  static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
 {
 	struct drm_device *dev = fb_helper->dev;
 	struct drm_client_display *display;
+	struct drm_connector **connectors;
 	struct drm_display_mode **modes;
 	struct drm_fb_offset *offsets;
 	struct drm_crtc **crtcs;
+	int i, connector_count;
 	bool *enabled;
-	int i;
 
 	DRM_DEBUG_KMS("\n");
 	/* prevent concurrent modification of connector_count by hotplug */
@@ -2061,13 +1873,14 @@  static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
 		}
 	}
 
-	crtcs = kcalloc(fb_helper->connector_count, sizeof(*crtcs), GFP_KERNEL);
-	modes = kcalloc(fb_helper->connector_count,
-			sizeof(struct drm_display_mode *), GFP_KERNEL);
-	offsets = kcalloc(fb_helper->connector_count,
-			  sizeof(struct drm_fb_offset), GFP_KERNEL);
-	enabled = kcalloc(fb_helper->connector_count,
-			  sizeof(bool), GFP_KERNEL);
+	connector_count = drm_connector_get_all(dev, &connectors);
+	if (connector_count < 1)
+		return;
+
+	enabled = drm_connector_get_enabled_status(connectors, connector_count);
+	crtcs = kcalloc(connector_count, sizeof(*crtcs), GFP_KERNEL);
+	modes = kcalloc(connector_count, sizeof(*modes), GFP_KERNEL);
+	offsets = kcalloc(connector_count, sizeof(*offsets), GFP_KERNEL);
 	if (!crtcs || !modes || !enabled || !offsets) {
 		DRM_ERROR("Memory allocation failed\n");
 		goto out;
@@ -2077,27 +1890,26 @@  static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
 	if (IS_ERR(display))
 		goto out;
 
-	drm_enable_connectors(fb_helper, enabled);
-
-	if (!drm_target_cloned(fb_helper, modes, offsets, enabled, width, height) &&
-	    !drm_target_preferred(fb_helper, modes, offsets, enabled, width, height))
+	if (!drm_target_cloned(fb_helper, connectors, connector_count,
+			       modes, offsets, enabled, width, height) &&
+	    !drm_target_preferred(connectors, connector_count,
+				  modes, offsets, enabled, width, height))
 		DRM_ERROR("Unable to find initial modes\n");
 
 	DRM_DEBUG_KMS("picking CRTCs for %dx%d config\n", width, height);
 
-	drm_pick_crtcs(fb_helper, crtcs, modes, 0, width, height);
+	drm_pick_crtcs(display, connectors, connector_count, crtcs, modes, 0, width, height);
 
 	/* need to set the modesets up here for use later */
 	/* fill out the connector<->crtc mappings into the modesets */
 
-	drm_fb_helper_for_each_connector(fb_helper, i) {
+	for (i = 0; i < connector_count; i++) {
+		struct drm_connector *connector = connectors[i];
 		struct drm_display_mode *mode = modes[i];
 		struct drm_crtc *crtc = crtcs[i];
 		struct drm_fb_offset *offset = &offsets[i];
 
 		if (mode && crtc) {
-			struct drm_connector *connector =
-				fb_helper->connector_info[i]->connector;
 			struct drm_mode_set *modeset;
 
 			modeset = drm_client_display_find_modeset(display, crtc);
@@ -2121,6 +1933,7 @@  static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
 	fb_helper->display = display;
 out:
 	mutex_unlock(&dev->mode_config.mutex);
+	drm_connector_put_all(connectors, connector_count);
 	kfree(crtcs);
 	kfree(modes);
 	kfree(offsets);
@@ -2136,10 +1949,11 @@  static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
  */
 static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper)
 {
+	struct drm_connector_list_iter conn_iter;
 	struct fb_info *info = fb_helper->fbdev;
 	unsigned int rotation, sw_rotations = 0;
+	struct drm_connector *connector;
 	struct drm_mode_set *modeset;
-	int i;
 
 	drm_client_display_for_each_modeset(modeset, fb_helper->display) {
 		if (!modeset->num_connectors)
@@ -2156,10 +1970,8 @@  static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper)
 	}
 
 	mutex_lock(&fb_helper->dev->mode_config.mutex);
-	drm_fb_helper_for_each_connector(fb_helper, i) {
-		struct drm_connector *connector =
-					fb_helper->connector_info[i]->connector;
-
+	drm_connector_list_iter_begin(fb_helper->dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		/* use first connected connector for the physical dimensions */
 		if (connector->status == connector_status_connected) {
 			info->var.width = connector->display_info.width_mm;
@@ -2167,6 +1979,7 @@  static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper)
 			break;
 		}
 	}
+	drm_connector_list_iter_end(&conn_iter);
 	mutex_unlock(&fb_helper->dev->mode_config.mutex);
 
 	switch (sw_rotations) {
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index 408931f7613f..a1e1ab1247c5 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -97,10 +97,6 @@  struct drm_fb_helper_funcs {
 			struct drm_fb_helper_surface_size *sizes);
 };
 
-struct drm_fb_helper_connector {
-	struct drm_connector *connector;
-};
-
 /**
  * struct drm_fb_helper - main structure to emulate fbdev on top of KMS
  * @fb: Scanout framebuffer object
@@ -134,15 +130,6 @@  struct drm_fb_helper {
 	 */
 	struct drm_client_display *display;
 
-	int connector_count;
-	int connector_info_alloc_count;
-	/**
-	 * @connector_info:
-	 *
-	 * Array of per-connector information. Do not iterate directly, but use
-	 * drm_fb_helper_for_each_connector.
-	 */
-	struct drm_fb_helper_connector **connector_info;
 	const struct drm_fb_helper_funcs *funcs;
 	struct fb_info *fbdev;
 	u32 pseudo_palette[17];