aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2014-06-05 00:01:30 -0400
committerDave Airlie <airlied@redhat.com>2014-07-07 21:39:45 -0400
commit65c2a89c30ed63db15fbbdba41b74e5f47278897 (patch)
tree94c1c859f46068da7a64f6175705b2081129a11d
parent2390cd11bfbe8d2b1b28c4e0f01fe7e122f7196d (diff)
drm/fb_helper: allow adding/removing connectors later
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>
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c53
-rw-r--r--include/drm/drm_fb_helper.h4
2 files changed, 57 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index bdee6eb0b24a..3144db9dc0f1 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -119,6 +119,58 @@ fail:
119} 119}
120EXPORT_SYMBOL(drm_fb_helper_single_add_all_connectors); 120EXPORT_SYMBOL(drm_fb_helper_single_add_all_connectors);
121 121
122int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_connector *connector)
123{
124 struct drm_fb_helper_connector **temp;
125 struct drm_fb_helper_connector *fb_helper_connector;
126
127 WARN_ON(!mutex_is_locked(&fb_helper->dev->mode_config.mutex));
128 if (fb_helper->connector_count + 1 > fb_helper->connector_info_alloc_count) {
129 temp = krealloc(fb_helper->connector_info, sizeof(struct drm_fb_helper_connector) * (fb_helper->connector_count + 1), GFP_KERNEL);
130 if (!temp)
131 return -ENOMEM;
132
133 fb_helper->connector_info_alloc_count = fb_helper->connector_count + 1;
134 fb_helper->connector_info = temp;
135 }
136
137
138 fb_helper_connector = kzalloc(sizeof(struct drm_fb_helper_connector), GFP_KERNEL);
139 if (!fb_helper_connector)
140 return -ENOMEM;
141
142 fb_helper_connector->connector = connector;
143 fb_helper->connector_info[fb_helper->connector_count++] = fb_helper_connector;
144 return 0;
145}
146EXPORT_SYMBOL(drm_fb_helper_add_one_connector);
147
148int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
149 struct drm_connector *connector)
150{
151 struct drm_fb_helper_connector *fb_helper_connector;
152 int i, j;
153
154 WARN_ON(!mutex_is_locked(&fb_helper->dev->mode_config.mutex));
155
156 for (i = 0; i < fb_helper->connector_count; i++) {
157 if (fb_helper->connector_info[i]->connector == connector)
158 break;
159 }
160
161 if (i == fb_helper->connector_count)
162 return -EINVAL;
163 fb_helper_connector = fb_helper->connector_info[i];
164
165 for (j = i + 1; j < fb_helper->connector_count; j++) {
166 fb_helper->connector_info[j - 1] = fb_helper->connector_info[j];
167 }
168 fb_helper->connector_count--;
169 kfree(fb_helper_connector);
170 return 0;
171}
172EXPORT_SYMBOL(drm_fb_helper_remove_one_connector);
173
122static int drm_fb_helper_parse_command_line(struct drm_fb_helper *fb_helper) 174static int drm_fb_helper_parse_command_line(struct drm_fb_helper *fb_helper)
123{ 175{
124 struct drm_fb_helper_connector *fb_helper_conn; 176 struct drm_fb_helper_connector *fb_helper_conn;
@@ -596,6 +648,7 @@ int drm_fb_helper_init(struct drm_device *dev,
596 kfree(fb_helper->crtc_info); 648 kfree(fb_helper->crtc_info);
597 return -ENOMEM; 649 return -ENOMEM;
598 } 650 }
651 fb_helper->connector_info_alloc_count = dev->mode_config.num_connector;
599 fb_helper->connector_count = 0; 652 fb_helper->connector_count = 0;
600 653
601 for (i = 0; i < crtc_count; i++) { 654 for (i = 0; i < crtc_count; i++) {
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index 1cf587f1f927..bfd329d613c4 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -86,6 +86,7 @@ struct drm_fb_helper {
86 int crtc_count; 86 int crtc_count;
87 struct drm_fb_helper_crtc *crtc_info; 87 struct drm_fb_helper_crtc *crtc_info;
88 int connector_count; 88 int connector_count;
89 int connector_info_alloc_count;
89 struct drm_fb_helper_connector **connector_info; 90 struct drm_fb_helper_connector **connector_info;
90 const struct drm_fb_helper_funcs *funcs; 91 const struct drm_fb_helper_funcs *funcs;
91 struct fb_info *fbdev; 92 struct fb_info *fbdev;
@@ -130,4 +131,7 @@ struct drm_display_mode *
130drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn, 131drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn,
131 int width, int height); 132 int width, int height);
132 133
134int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_connector *connector);
135int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
136 struct drm_connector *connector);
133#endif 137#endif