Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+57
+53
drivers/gpu/drm/drm_fb_helper.c
··· 119 119 } 120 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 174 static int drm_fb_helper_parse_command_line(struct drm_fb_helper *fb_helper) 123 175 { 124 176 struct drm_fb_helper_connector *fb_helper_conn; ··· 648 596 kfree(fb_helper->crtc_info); 649 597 return -ENOMEM; 650 598 } 599 + fb_helper->connector_info_alloc_count = dev->mode_config.num_connector; 651 600 fb_helper->connector_count = 0; 652 601 653 602 for (i = 0; i < crtc_count; i++) {
+4
include/drm/drm_fb_helper.h
··· 86 86 int crtc_count; 87 87 struct drm_fb_helper_crtc *crtc_info; 88 88 int connector_count; 89 + int connector_info_alloc_count; 89 90 struct drm_fb_helper_connector **connector_info; 90 91 const struct drm_fb_helper_funcs *funcs; 91 92 struct fb_info *fbdev; ··· 131 130 drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn, 132 131 int width, int height); 133 132 133 + int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_connector *connector); 134 + int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper, 135 + struct drm_connector *connector); 134 136 #endif