diff options
author | Dave Airlie <airlied@redhat.com> | 2014-06-05 00:01:30 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2014-07-07 21:39:45 -0400 |
commit | 65c2a89c30ed63db15fbbdba41b74e5f47278897 (patch) | |
tree | 94c1c859f46068da7a64f6175705b2081129a11d | |
parent | 2390cd11bfbe8d2b1b28c4e0f01fe7e122f7196d (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.c | 53 | ||||
-rw-r--r-- | include/drm/drm_fb_helper.h | 4 |
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 | } |
120 | EXPORT_SYMBOL(drm_fb_helper_single_add_all_connectors); | 120 | EXPORT_SYMBOL(drm_fb_helper_single_add_all_connectors); |
121 | 121 | ||
122 | int 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 | } | ||
146 | EXPORT_SYMBOL(drm_fb_helper_add_one_connector); | ||
147 | |||
148 | int 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 | } | ||
172 | EXPORT_SYMBOL(drm_fb_helper_remove_one_connector); | ||
173 | |||
122 | static int drm_fb_helper_parse_command_line(struct drm_fb_helper *fb_helper) | 174 | static 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 * | |||
130 | drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn, | 131 | drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn, |
131 | int width, int height); | 132 | int width, int height); |
132 | 133 | ||
134 | int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_connector *connector); | ||
135 | int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper, | ||
136 | struct drm_connector *connector); | ||
133 | #endif | 137 | #endif |