提交 6e86d58b 编写于 作者: D Dave Airlie

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: NDaniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: NDaniel Stone <daniels@collabora.com>
Signed-off-by: NDave Airlie <airlied@redhat.com>
上级 b164d31f
...@@ -162,40 +162,13 @@ int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_ ...@@ -162,40 +162,13 @@ int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_
if (!fb_helper_connector) if (!fb_helper_connector)
return -ENOMEM; return -ENOMEM;
drm_connector_reference(connector);
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;
return 0; return 0;
} }
EXPORT_SYMBOL(drm_fb_helper_add_one_connector); EXPORT_SYMBOL(drm_fb_helper_add_one_connector);
static void remove_from_modeset(struct drm_mode_set *set,
struct drm_connector *connector)
{
int i, j;
for (i = 0; i < set->num_connectors; i++) {
if (set->connectors[i] == connector)
break;
}
if (i == set->num_connectors)
return;
for (j = i + 1; j < set->num_connectors; j++) {
set->connectors[j - 1] = set->connectors[j];
}
set->num_connectors--;
/*
* TODO maybe need to makes sure we set it back to !=NULL somewhere?
*/
if (set->num_connectors == 0) {
set->fb = NULL;
drm_mode_destroy(connector->dev, set->mode);
set->mode = NULL;
}
}
int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper, int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
struct drm_connector *connector) struct drm_connector *connector)
{ {
...@@ -215,6 +188,7 @@ int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper, ...@@ -215,6 +188,7 @@ int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
if (i == fb_helper->connector_count) if (i == fb_helper->connector_count)
return -EINVAL; return -EINVAL;
fb_helper_connector = fb_helper->connector_info[i]; fb_helper_connector = fb_helper->connector_info[i];
drm_connector_unreference(fb_helper_connector->connector);
for (j = i + 1; j < fb_helper->connector_count; j++) { for (j = i + 1; j < fb_helper->connector_count; j++) {
fb_helper->connector_info[j - 1] = fb_helper->connector_info[j]; 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,10 +196,6 @@ int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
fb_helper->connector_count--; fb_helper->connector_count--;
kfree(fb_helper_connector); kfree(fb_helper_connector);
/* also cleanup dangling references to the connector: */
for (i = 0; i < fb_helper->crtc_count; i++)
remove_from_modeset(&fb_helper->crtc_info[i].mode_set, connector);
return 0; return 0;
} }
EXPORT_SYMBOL(drm_fb_helper_remove_one_connector); EXPORT_SYMBOL(drm_fb_helper_remove_one_connector);
...@@ -635,8 +605,10 @@ static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper) ...@@ -635,8 +605,10 @@ static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper)
{ {
int i; int i;
for (i = 0; i < helper->connector_count; i++) for (i = 0; i < helper->connector_count; i++) {
drm_connector_unreference(helper->connector_info[i]->connector);
kfree(helper->connector_info[i]); kfree(helper->connector_info[i]);
}
kfree(helper->connector_info); kfree(helper->connector_info);
for (i = 0; i < helper->crtc_count; i++) { for (i = 0; i < helper->crtc_count; i++) {
kfree(helper->crtc_info[i].mode_set.connectors); kfree(helper->crtc_info[i].mode_set.connectors);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册