Skip to content

Commit

Permalink
drm/fb_helper: allow adding/removing connectors later
Browse files Browse the repository at this point in the history
This is required to get fbcon probing to work on new connectors,
callers should acquire the mode config lock before calling these.

Reviewed-by: Todd Previte <tprevite@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
  • Loading branch information
Dave Airlie committed Jul 8, 2014
1 parent 2390cd1 commit 65c2a89
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 0 deletions.
53 changes: 53 additions & 0 deletions drivers/gpu/drm/drm_fb_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,58 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
}
EXPORT_SYMBOL(drm_fb_helper_single_add_all_connectors);

int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_connector *connector)
{
struct drm_fb_helper_connector **temp;
struct drm_fb_helper_connector *fb_helper_connector;

WARN_ON(!mutex_is_locked(&fb_helper->dev->mode_config.mutex));
if (fb_helper->connector_count + 1 > fb_helper->connector_info_alloc_count) {
temp = krealloc(fb_helper->connector_info, sizeof(struct drm_fb_helper_connector) * (fb_helper->connector_count + 1), GFP_KERNEL);
if (!temp)
return -ENOMEM;

fb_helper->connector_info_alloc_count = fb_helper->connector_count + 1;
fb_helper->connector_info = temp;
}


fb_helper_connector = kzalloc(sizeof(struct drm_fb_helper_connector), GFP_KERNEL);
if (!fb_helper_connector)
return -ENOMEM;

fb_helper_connector->connector = connector;
fb_helper->connector_info[fb_helper->connector_count++] = fb_helper_connector;
return 0;
}
EXPORT_SYMBOL(drm_fb_helper_add_one_connector);

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;

WARN_ON(!mutex_is_locked(&fb_helper->dev->mode_config.mutex));

for (i = 0; i < fb_helper->connector_count; 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];

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_remove_one_connector);

static int drm_fb_helper_parse_command_line(struct drm_fb_helper *fb_helper)
{
struct drm_fb_helper_connector *fb_helper_conn;
Expand Down Expand Up @@ -596,6 +648,7 @@ int drm_fb_helper_init(struct drm_device *dev,
kfree(fb_helper->crtc_info);
return -ENOMEM;
}
fb_helper->connector_info_alloc_count = dev->mode_config.num_connector;
fb_helper->connector_count = 0;

for (i = 0; i < crtc_count; i++) {
Expand Down
4 changes: 4 additions & 0 deletions include/drm/drm_fb_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ struct drm_fb_helper {
int crtc_count;
struct drm_fb_helper_crtc *crtc_info;
int connector_count;
int connector_info_alloc_count;
struct drm_fb_helper_connector **connector_info;
const struct drm_fb_helper_funcs *funcs;
struct fb_info *fbdev;
Expand Down Expand Up @@ -130,4 +131,7 @@ struct drm_display_mode *
drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn,
int width, int height);

int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_connector *connector);
int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
struct drm_connector *connector);
#endif

0 comments on commit 65c2a89

Please sign in to comment.