aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2016-04-26 21:24:51 -0400
committerDave Airlie <airlied@redhat.com>2016-05-04 22:51:57 -0400
commit6e86d58be3d175ca950eb0dde05f175debc10ef3 (patch)
tree731589d7e6f58d9fc10ff0029f129f31a2dea002
parentb164d31f50b2923a7a92c2a40cb46973a6ba8c36 (diff)
drm/fb_helper: add connector reference counting. (v2)
This takes a reference count when fbdev adds the connector, and drops it when it removes the connector. It also drops the now unneeded code to find connectors and remove the from the modeset as they are reference counted. v2: drop references when removing all connectors at end. Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Daniel Stone <daniels@collabora.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c38
1 files changed, 5 insertions, 33 deletions
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 62f849f2fe44..0bb3d4bee24c 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -162,40 +162,13 @@ int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_
162 if (!fb_helper_connector) 162 if (!fb_helper_connector)
163 return -ENOMEM; 163 return -ENOMEM;
164 164
165 drm_connector_reference(connector);
165 fb_helper_connector->connector = connector; 166 fb_helper_connector->connector = connector;
166 fb_helper->connector_info[fb_helper->connector_count++] = fb_helper_connector; 167 fb_helper->connector_info[fb_helper->connector_count++] = fb_helper_connector;
167 return 0; 168 return 0;
168} 169}
169EXPORT_SYMBOL(drm_fb_helper_add_one_connector); 170EXPORT_SYMBOL(drm_fb_helper_add_one_connector);
170 171
171static void remove_from_modeset(struct drm_mode_set *set,
172 struct drm_connector *connector)
173{
174 int i, j;
175
176 for (i = 0; i < set->num_connectors; i++) {
177 if (set->connectors[i] == connector)
178 break;
179 }
180
181 if (i == set->num_connectors)
182 return;
183
184 for (j = i + 1; j < set->num_connectors; j++) {
185 set->connectors[j - 1] = set->connectors[j];
186 }
187 set->num_connectors--;
188
189 /*
190 * TODO maybe need to makes sure we set it back to !=NULL somewhere?
191 */
192 if (set->num_connectors == 0) {
193 set->fb = NULL;
194 drm_mode_destroy(connector->dev, set->mode);
195 set->mode = NULL;
196 }
197}
198
199int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper, 172int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
200 struct drm_connector *connector) 173 struct drm_connector *connector)
201{ 174{
@@ -215,6 +188,7 @@ int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
215 if (i == fb_helper->connector_count) 188 if (i == fb_helper->connector_count)
216 return -EINVAL; 189 return -EINVAL;
217 fb_helper_connector = fb_helper->connector_info[i]; 190 fb_helper_connector = fb_helper->connector_info[i];
191 drm_connector_unreference(fb_helper_connector->connector);
218 192
219 for (j = i + 1; j < fb_helper->connector_count; j++) { 193 for (j = i + 1; j < fb_helper->connector_count; j++) {
220 fb_helper->connector_info[j - 1] = fb_helper->connector_info[j]; 194 fb_helper->connector_info[j - 1] = fb_helper->connector_info[j];
@@ -222,10 +196,6 @@ int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
222 fb_helper->connector_count--; 196 fb_helper->connector_count--;
223 kfree(fb_helper_connector); 197 kfree(fb_helper_connector);
224 198
225 /* also cleanup dangling references to the connector: */
226 for (i = 0; i < fb_helper->crtc_count; i++)
227 remove_from_modeset(&fb_helper->crtc_info[i].mode_set, connector);
228
229 return 0; 199 return 0;
230} 200}
231EXPORT_SYMBOL(drm_fb_helper_remove_one_connector); 201EXPORT_SYMBOL(drm_fb_helper_remove_one_connector);
@@ -635,8 +605,10 @@ static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper)
635{ 605{
636 int i; 606 int i;
637 607
638 for (i = 0; i < helper->connector_count; i++) 608 for (i = 0; i < helper->connector_count; i++) {
609 drm_connector_unreference(helper->connector_info[i]->connector);
639 kfree(helper->connector_info[i]); 610 kfree(helper->connector_info[i]);
611 }
640 kfree(helper->connector_info); 612 kfree(helper->connector_info);
641 for (i = 0; i < helper->crtc_count; i++) { 613 for (i = 0; i < helper->crtc_count; i++) {
642 kfree(helper->crtc_info[i].mode_set.connectors); 614 kfree(helper->crtc_info[i].mode_set.connectors);