diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 6a472d534522..e8cd6832f08e 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -493,7 +493,6 @@ void drm_connector_cleanup(struct drm_connector *connector) list_for_each_entry_safe(mode, t, &connector->user_modes, head) drm_mode_remove(connector, mode); - kfree(connector->fb_helper_private); mutex_lock(&dev->mode_config.mutex); drm_mode_object_put(dev, &connector->base); list_del(&connector->head); diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 2515563063ce..9808f6e37a9d 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -41,15 +41,33 @@ MODULE_LICENSE("GPL and additional rights"); static LIST_HEAD(kernel_fb_helper_list); -int drm_fb_helper_add_connector(struct drm_connector *connector) +/* simple single crtc case helper function */ +int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper) { - connector->fb_helper_private = kzalloc(sizeof(struct drm_fb_helper_connector), GFP_KERNEL); - if (!connector->fb_helper_private) - return -ENOMEM; + struct drm_device *dev = fb_helper->dev; + struct drm_connector *connector; + int i; + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + struct drm_fb_helper_connector *fb_helper_connector; + + fb_helper_connector = kzalloc(sizeof(struct drm_fb_helper_connector), GFP_KERNEL); + if (!fb_helper_connector) + goto fail; + + fb_helper_connector->connector = connector; + fb_helper->connector_info[fb_helper->connector_count++] = fb_helper_connector; + } return 0; +fail: + for (i = 0; i < fb_helper->connector_count; i++) { + kfree(fb_helper->connector_info[i]); + fb_helper->connector_info[i] = NULL; + } + fb_helper->connector_count = 0; + return -ENOMEM; } -EXPORT_SYMBOL(drm_fb_helper_add_connector); +EXPORT_SYMBOL(drm_fb_helper_single_add_all_connectors); /** * drm_fb_helper_connector_parse_command_line - parse command line for connector @@ -64,7 +82,7 @@ EXPORT_SYMBOL(drm_fb_helper_add_connector); * * enable/enable Digital/disable bit at the end */ -static bool drm_fb_helper_connector_parse_command_line(struct drm_connector *connector, +static bool drm_fb_helper_connector_parse_command_line(struct drm_fb_helper_connector *fb_helper_conn, const char *mode_option) { const char *name; @@ -74,13 +92,13 @@ static bool drm_fb_helper_connector_parse_command_line(struct drm_connector *con int yres_specified = 0, cvt = 0, rb = 0, interlace = 0, margins = 0; int i; enum drm_connector_force force = DRM_FORCE_UNSPECIFIED; - struct drm_fb_helper_connector *fb_help_conn = connector->fb_helper_private; struct drm_fb_helper_cmdline_mode *cmdline_mode; + struct drm_connector *connector = fb_helper_conn->connector; - if (!fb_help_conn) + if (!fb_helper_conn) return false; - cmdline_mode = &fb_help_conn->cmdline_mode; + cmdline_mode = &fb_helper_conn->cmdline_mode; if (!mode_option) mode_option = fb_mode_option; @@ -203,18 +221,21 @@ done: return true; } -int drm_fb_helper_parse_command_line(struct drm_device *dev) +static int drm_fb_helper_parse_command_line(struct drm_fb_helper *fb_helper) { - struct drm_connector *connector; + struct drm_fb_helper_connector *fb_helper_conn; + int i; - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + for (i = 0; i < fb_helper->connector_count; i++) { char *option = NULL; + fb_helper_conn = fb_helper->connector_info[i]; + /* do something on return - turn off connector maybe */ - if (fb_get_options(drm_get_connector_name(connector), &option)) + if (fb_get_options(drm_get_connector_name(fb_helper_conn->connector), &option)) continue; - drm_fb_helper_connector_parse_command_line(connector, option); + drm_fb_helper_connector_parse_command_line(fb_helper_conn, option); } return 0; } @@ -391,6 +412,9 @@ static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper) { int i; + for (i = 0; i < helper->connector_count; i++) + kfree(helper->connector_info[i]); + kfree(helper->connector_info); for (i = 0; i < helper->crtc_count; i++) kfree(helper->crtc_info[i].mode_set.connectors); kfree(helper->crtc_info); @@ -411,6 +435,13 @@ int drm_fb_helper_init_crtc_count(struct drm_device *dev, return -ENOMEM; helper->crtc_count = crtc_count; + helper->connector_info = kcalloc(dev->mode_config.num_connector, sizeof(struct drm_fb_helper_connector *), GFP_KERNEL); + if (!helper->connector_info) { + kfree(helper->crtc_info); + return -ENOMEM; + } + helper->connector_count = 0; + for (i = 0; i < crtc_count; i++) { helper->crtc_info[i].mode_set.connectors = kcalloc(max_conn_count, @@ -672,14 +703,10 @@ int drm_fb_helper_set_par(struct fb_info *info) mutex_lock(&dev->mode_config.mutex); for (i = 0; i < fb_helper->crtc_count; i++) { crtc = fb_helper->crtc_info[i].mode_set.crtc; - - if (crtc->fb != fb_helper->crtc_info[i].mode_set.fb) { - ret = crtc->funcs->set_config(&fb_helper->crtc_info[i].mode_set); - - if (ret) { - mutex_unlock(&dev->mode_config.mutex); - return ret; - } + ret = crtc->funcs->set_config(&fb_helper->crtc_info[i].mode_set); + if (ret) { + mutex_unlock(&dev->mode_config.mutex); + return ret; } } mutex_unlock(&dev->mode_config.mutex); @@ -722,8 +749,6 @@ EXPORT_SYMBOL(drm_fb_helper_pan_display); int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, int preferred_bpp) { - struct drm_device *dev = fb_helper->dev; - struct drm_connector *connector; int new_fb = 0; int crtc_count = 0; int ret, i; @@ -743,14 +768,11 @@ int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, sizes.surface_depth = sizes.surface_bpp = preferred_bpp; } /* first up get a count of crtcs now in use and new min/maxes width/heights */ - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - struct drm_fb_helper_connector *fb_help_conn = connector->fb_helper_private; + for (i = 0; i < fb_helper->connector_count; i++) { + struct drm_fb_helper_connector *fb_helper_conn = fb_helper->connector_info[i]; struct drm_fb_helper_cmdline_mode *cmdline_mode; - if (!fb_help_conn) - continue; - - cmdline_mode = &fb_help_conn->cmdline_mode; + cmdline_mode = &fb_helper_conn->cmdline_mode; if (cmdline_mode->bpp_specified) { switch (cmdline_mode->bpp) { @@ -954,24 +976,27 @@ void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helpe } EXPORT_SYMBOL(drm_fb_helper_fill_var); -static int drm_helper_probe_connector_modes(struct drm_device *dev, uint32_t maxX, - uint32_t maxY) +static int drm_fb_helper_probe_connector_modes(struct drm_fb_helper *fb_helper, + uint32_t maxX, + uint32_t maxY) { struct drm_connector *connector; int count = 0; + int i; - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + for (i = 0; i < fb_helper->connector_count; i++) { + connector = fb_helper->connector_info[i]->connector; count += connector->funcs->fill_modes(connector, maxX, maxY); } return count; } -static struct drm_display_mode *drm_has_preferred_mode(struct drm_connector *connector, int width, int height) +static struct drm_display_mode *drm_has_preferred_mode(struct drm_fb_helper_connector *fb_connector, int width, int height) { struct drm_display_mode *mode; - list_for_each_entry(mode, &connector->modes, head) { + list_for_each_entry(mode, &fb_connector->connector->modes, head) { if (drm_mode_width(mode) > width || drm_mode_height(mode) > height) continue; @@ -981,28 +1006,20 @@ static struct drm_display_mode *drm_has_preferred_mode(struct drm_connector *con return NULL; } -static bool drm_has_cmdline_mode(struct drm_connector *connector) +static bool drm_has_cmdline_mode(struct drm_fb_helper_connector *fb_connector) { - struct drm_fb_helper_connector *fb_help_conn = connector->fb_helper_private; struct drm_fb_helper_cmdline_mode *cmdline_mode; - - if (!fb_help_conn) - return false; - - cmdline_mode = &fb_help_conn->cmdline_mode; + cmdline_mode = &fb_connector->cmdline_mode; return cmdline_mode->specified; } -static struct drm_display_mode *drm_pick_cmdline_mode(struct drm_connector *connector, int width, int height) +static struct drm_display_mode *drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn, + int width, int height) { - struct drm_fb_helper_connector *fb_help_conn = connector->fb_helper_private; struct drm_fb_helper_cmdline_mode *cmdline_mode; struct drm_display_mode *mode = NULL; - if (!fb_help_conn) - return mode; - - cmdline_mode = &fb_help_conn->cmdline_mode; + cmdline_mode = &fb_helper_conn->cmdline_mode; if (cmdline_mode->specified == false) return mode; @@ -1012,7 +1029,7 @@ static struct drm_display_mode *drm_pick_cmdline_mode(struct drm_connector *conn if (cmdline_mode->rb || cmdline_mode->margins) goto create_mode; - list_for_each_entry(mode, &connector->modes, head) { + list_for_each_entry(mode, &fb_helper_conn->connector->modes, head) { /* check width/height */ if (mode->hdisplay != cmdline_mode->xres || mode->vdisplay != cmdline_mode->yres) @@ -1031,13 +1048,13 @@ static struct drm_display_mode *drm_pick_cmdline_mode(struct drm_connector *conn } create_mode: - mode = drm_cvt_mode(connector->dev, cmdline_mode->xres, + mode = drm_cvt_mode(fb_helper_conn->connector->dev, cmdline_mode->xres, cmdline_mode->yres, cmdline_mode->refresh_specified ? cmdline_mode->refresh : 60, cmdline_mode->rb, cmdline_mode->interlace, cmdline_mode->margins); drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); - list_add(&mode->head, &connector->modes); + list_add(&mode->head, &fb_helper_conn->connector->modes); return mode; } @@ -1053,62 +1070,60 @@ static bool drm_connector_enabled(struct drm_connector *connector, bool strict) return enable; } -static void drm_enable_connectors(struct drm_device *dev, bool *enabled) +static void drm_enable_connectors(struct drm_fb_helper *fb_helper, + bool *enabled) { bool any_enabled = false; struct drm_connector *connector; int i = 0; - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + for (i = 0; i < fb_helper->connector_count; i++) { + connector = fb_helper->connector_info[i]->connector; enabled[i] = drm_connector_enabled(connector, true); DRM_DEBUG_KMS("connector %d enabled? %s\n", connector->base.id, enabled[i] ? "yes" : "no"); any_enabled |= enabled[i]; - i++; } if (any_enabled) return; - i = 0; - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + for (i = 0; i < fb_helper->connector_count; i++) { + connector = fb_helper->connector_info[i]->connector; enabled[i] = drm_connector_enabled(connector, false); - i++; } } -static bool drm_target_preferred(struct drm_device *dev, +static bool drm_target_preferred(struct drm_fb_helper *fb_helper, struct drm_display_mode **modes, bool *enabled, int width, int height) { - struct drm_connector *connector; - int i = 0; + struct drm_fb_helper_connector *fb_helper_conn; + int i; - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + for (i = 0; i < fb_helper->connector_count; i++) { + fb_helper_conn = fb_helper->connector_info[i]; - if (enabled[i] == false) { - i++; + if (enabled[i] == false) continue; - } DRM_DEBUG_KMS("looking for cmdline mode on connector %d\n", - connector->base.id); + fb_helper_conn->connector->base.id); /* got for command line mode first */ - modes[i] = drm_pick_cmdline_mode(connector, width, height); + modes[i] = drm_pick_cmdline_mode(fb_helper_conn, width, height); if (!modes[i]) { DRM_DEBUG_KMS("looking for preferred mode on connector %d\n", - connector->base.id); - modes[i] = drm_has_preferred_mode(connector, width, height); + fb_helper_conn->connector->base.id); + modes[i] = drm_has_preferred_mode(fb_helper_conn, width, height); } /* No preferred modes, pick one off the list */ - if (!modes[i] && !list_empty(&connector->modes)) { - list_for_each_entry(modes[i], &connector->modes, head) + if (!modes[i] && !list_empty(&fb_helper_conn->connector->modes)) { + list_for_each_entry(modes[i], &fb_helper_conn->connector->modes, head) break; } DRM_DEBUG_KMS("found mode %s\n", modes[i] ? modes[i]->name : "none"); - i++; } return true; } @@ -1126,15 +1141,13 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, struct drm_fb_helper_crtc *best_crtc; int my_score, best_score, score; struct drm_fb_helper_crtc **crtcs, *crtc; + struct drm_fb_helper_connector *fb_helper_conn; - if (n == fb_helper->dev->mode_config.num_connector) + if (n == fb_helper->connector_count) return 0; - c = 0; - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (c == n) - break; - c++; - } + + fb_helper_conn = fb_helper->connector_info[n]; + connector = fb_helper_conn->connector; best_crtcs[n] = NULL; best_crtc = NULL; @@ -1150,9 +1163,9 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, my_score = 1; if (connector->status == connector_status_connected) my_score++; - if (drm_has_cmdline_mode(connector)) + if (drm_has_cmdline_mode(fb_helper_conn)) my_score++; - if (drm_has_preferred_mode(connector, width, height)) + if (drm_has_preferred_mode(fb_helper_conn, width, height)) my_score++; connector_funcs = connector->helper_private; @@ -1201,7 +1214,6 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) struct drm_fb_helper_crtc **crtcs; struct drm_display_mode **modes; struct drm_encoder *encoder; - struct drm_connector *connector; struct drm_mode_set *modeset; bool *enabled; int width, height; @@ -1224,9 +1236,9 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) enabled = kcalloc(dev->mode_config.num_connector, sizeof(bool), GFP_KERNEL); - drm_enable_connectors(dev, enabled); + drm_enable_connectors(fb_helper, enabled); - ret = drm_target_preferred(dev, modes, enabled, width, height); + ret = drm_target_preferred(fb_helper, modes, enabled, width, height); if (!ret) DRM_ERROR("Unable to find initial modes\n"); @@ -1241,8 +1253,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) modeset->num_connectors = 0; } - i = 0; - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + for (i = 0; i < fb_helper->connector_count; i++) { struct drm_display_mode *mode = modes[i]; struct drm_fb_helper_crtc *fb_crtc = crtcs[i]; modeset = &fb_crtc->mode_set; @@ -1255,9 +1266,8 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) drm_mode_destroy(dev, modeset->mode); modeset->mode = drm_mode_duplicate(dev, fb_crtc->desired_mode); - modeset->connectors[modeset->num_connectors++] = connector; + modeset->connectors[modeset->num_connectors++] = fb_helper->connector_info[i]->connector; } - i++; } kfree(crtcs); @@ -1287,11 +1297,11 @@ bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper) /* disable all the possible outputs/crtcs before entering KMS mode */ drm_helper_disable_unused_functions(fb_helper->dev); - drm_fb_helper_parse_command_line(fb_helper->dev); + drm_fb_helper_parse_command_line(fb_helper); - count = drm_helper_probe_connector_modes(dev, - dev->mode_config.max_width, - dev->mode_config.max_height); + count = drm_fb_helper_probe_connector_modes(fb_helper, + dev->mode_config.max_width, + dev->mode_config.max_height); /* * we shouldn't end up with no modes here. @@ -1310,8 +1320,8 @@ bool drm_helper_fb_hotplug_event(struct drm_fb_helper *fb_helper, { DRM_DEBUG_KMS("\n"); - drm_helper_probe_connector_modes(fb_helper->dev, max_width, - max_height); + drm_fb_helper_probe_connector_modes(fb_helper, max_width, + max_height); drm_setup_crtcs(fb_helper); diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index ff6912edf0c6..8f7a7c476098 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c @@ -249,6 +249,7 @@ int intel_fbdev_init(struct drm_device *dev) drm_fb_helper_init_crtc_count(dev, &ifbdev->helper, 2, INTELFB_CONN_LIMIT); + drm_fb_helper_single_add_all_connectors(&ifbdev->helper); ifbdev->helper.fb_probe = intel_fb_find_or_create_single; drm_fb_helper_initial_config(&ifbdev->helper); intelfb_probe(ifbdev); diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 90843b62d9b1..fd5d3cde0a07 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -435,6 +435,8 @@ int nouveau_fbcon_init(struct drm_device *dev) drm_fb_helper_init_crtc_count(dev, &nfbdev->helper, 2, 4); nfbdev->helper.fb_probe = nouveau_fbcon_find_or_create_single; + drm_fb_helper_single_add_all_connectors(&nfbdev->helper); + drm_fb_helper_initial_config(&nfbdev->helper); nouveau_fbcon_probe(nfbdev); return 0; diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 3fba50540f72..47bd98521bec 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -1032,7 +1032,6 @@ radeon_add_atom_connector(struct drm_device *dev, struct radeon_connector_atom_dig *radeon_dig_connector; uint32_t subpixel_order = SubPixelNone; bool shared_ddc = false; - int ret; /* fixme - tv/cv/din */ if (connector_type == DRM_MODE_CONNECTOR_Unknown) @@ -1067,9 +1066,7 @@ radeon_add_atom_connector(struct drm_device *dev, switch (connector_type) { case DRM_MODE_CONNECTOR_VGA: drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); - ret = drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); - if (ret) - goto failed; + drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); if (i2c_bus->valid) { radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA"); if (!radeon_connector->ddc_bus) @@ -1082,9 +1079,7 @@ radeon_add_atom_connector(struct drm_device *dev, break; case DRM_MODE_CONNECTOR_DVIA: drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); - ret = drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); - if (ret) - goto failed; + drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); if (i2c_bus->valid) { radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); if (!radeon_connector->ddc_bus) @@ -1104,9 +1099,7 @@ radeon_add_atom_connector(struct drm_device *dev, radeon_dig_connector->igp_lane_info = igp_lane_info; radeon_connector->con_priv = radeon_dig_connector; drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); - ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); - if (ret) - goto failed; + drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); if (i2c_bus->valid) { radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); if (!radeon_connector->ddc_bus) @@ -1132,9 +1125,7 @@ radeon_add_atom_connector(struct drm_device *dev, radeon_dig_connector->igp_lane_info = igp_lane_info; radeon_connector->con_priv = radeon_dig_connector; drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); - ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); - if (ret) - goto failed; + drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); if (i2c_bus->valid) { radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "HDMI"); if (!radeon_connector->ddc_bus) @@ -1154,9 +1145,7 @@ radeon_add_atom_connector(struct drm_device *dev, radeon_dig_connector->igp_lane_info = igp_lane_info; radeon_connector->con_priv = radeon_dig_connector; drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type); - ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs); - if (ret) - goto failed; + drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs); if (i2c_bus->valid) { /* add DP i2c bus */ if (connector_type == DRM_MODE_CONNECTOR_eDP) @@ -1182,9 +1171,7 @@ radeon_add_atom_connector(struct drm_device *dev, case DRM_MODE_CONNECTOR_9PinDIN: if (radeon_tv == 1) { drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); - ret = drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); - if (ret) - goto failed; + drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); radeon_connector->dac_load_detect = true; drm_connector_attach_property(&radeon_connector->base, rdev->mode_info.load_detect_property, @@ -1202,9 +1189,7 @@ radeon_add_atom_connector(struct drm_device *dev, radeon_dig_connector->igp_lane_info = igp_lane_info; radeon_connector->con_priv = radeon_dig_connector; drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); - ret = drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs); - if (ret) - goto failed; + drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs); if (i2c_bus->valid) { radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS"); if (!radeon_connector->ddc_bus) @@ -1241,7 +1226,6 @@ radeon_add_legacy_connector(struct drm_device *dev, struct drm_connector *connector; struct radeon_connector *radeon_connector; uint32_t subpixel_order = SubPixelNone; - int ret; /* fixme - tv/cv/din */ if (connector_type == DRM_MODE_CONNECTOR_Unknown) @@ -1269,9 +1253,7 @@ radeon_add_legacy_connector(struct drm_device *dev, switch (connector_type) { case DRM_MODE_CONNECTOR_VGA: drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); - ret = drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); - if (ret) - goto failed; + drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); if (i2c_bus->valid) { radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA"); if (!radeon_connector->ddc_bus) @@ -1284,9 +1266,7 @@ radeon_add_legacy_connector(struct drm_device *dev, break; case DRM_MODE_CONNECTOR_DVIA: drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); - ret = drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); - if (ret) - goto failed; + drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); if (i2c_bus->valid) { radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); if (!radeon_connector->ddc_bus) @@ -1300,9 +1280,7 @@ radeon_add_legacy_connector(struct drm_device *dev, case DRM_MODE_CONNECTOR_DVII: case DRM_MODE_CONNECTOR_DVID: drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); - ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); - if (ret) - goto failed; + drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); if (i2c_bus->valid) { radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); if (!radeon_connector->ddc_bus) @@ -1319,9 +1297,7 @@ radeon_add_legacy_connector(struct drm_device *dev, case DRM_MODE_CONNECTOR_9PinDIN: if (radeon_tv == 1) { drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); - ret = drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); - if (ret) - goto failed; + drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); radeon_connector->dac_load_detect = true; /* RS400,RC410,RS480 chipset seems to report a lot * of false positive on load detect, we haven't yet @@ -1340,9 +1316,7 @@ radeon_add_legacy_connector(struct drm_device *dev, break; case DRM_MODE_CONNECTOR_LVDS: drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); - ret = drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs); - if (ret) - goto failed; + drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs); if (i2c_bus->valid) { radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS"); if (!radeon_connector->ddc_bus) diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index 705425defba0..7275b2e09444 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c @@ -274,8 +274,6 @@ out_unref: drm_framebuffer_cleanup(fb); kfree(fb); } - -out: return ret; } @@ -380,6 +378,9 @@ int radeon_fbdev_init(struct radeon_device *rdev) rdev->num_crtc, RADEONFB_CONN_LIMIT); rfbdev->helper.fb_probe = radeon_fb_find_or_create_single; + + drm_fb_helper_single_add_all_connectors(&rfbdev->helper); + drm_fb_helper_initial_config(&rfbdev->helper); radeonfb_probe(rfbdev); return 0; diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index e4e34bae22cd..fce2042ad0a5 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -514,7 +514,6 @@ struct drm_connector { uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER]; uint32_t force_encoder_id; struct drm_encoder *encoder; /* currently active encoder */ - void *fb_helper_private; }; /** diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h index ce7aab77f7dc..b1fa0f8cfa60 100644 --- a/include/drm/drm_crtc_helper.h +++ b/include/drm/drm_crtc_helper.h @@ -39,7 +39,6 @@ #include -#include "drm_fb_helper.h" struct drm_crtc_helper_funcs { /* * Control power levels on the CRTC. If the mode passed in is @@ -96,7 +95,6 @@ struct drm_connector_helper_funcs { extern int drm_helper_probe_single_connector_modes(struct drm_connector *connector, uint32_t maxX, uint32_t maxY); extern void drm_helper_disable_unused_functions(struct drm_device *dev); -extern int drm_helper_hotplug_stage_two(struct drm_device *dev); extern int drm_crtc_helper_set_config(struct drm_mode_set *set); extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode, @@ -122,11 +120,10 @@ static inline void drm_encoder_helper_add(struct drm_encoder *encoder, encoder->helper_private = (void *)funcs; } -static inline int drm_connector_helper_add(struct drm_connector *connector, +static inline void drm_connector_helper_add(struct drm_connector *connector, const struct drm_connector_helper_funcs *funcs) { connector->helper_private = (void *)funcs; - return drm_fb_helper_add_connector(connector); } extern int drm_helper_resume_force_mode(struct drm_device *dev); diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index b1ea66f11ded..50094f94d4ca 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -69,6 +69,7 @@ struct drm_fb_helper_surface_size { struct drm_fb_helper_connector { struct drm_fb_helper_cmdline_mode cmdline_mode; + struct drm_connector *connector; }; struct drm_fb_helper { @@ -77,6 +78,8 @@ struct drm_fb_helper { struct drm_display_mode *mode; int crtc_count; struct drm_fb_helper_crtc *crtc_info; + int connector_count; + struct drm_fb_helper_connector **connector_info; struct drm_fb_helper_funcs *funcs; int conn_limit; struct fb_info *fbdev; @@ -113,12 +116,11 @@ void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helpe void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch, uint32_t depth); -int drm_fb_helper_add_connector(struct drm_connector *connector); -int drm_fb_helper_parse_command_line(struct drm_device *dev); int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info); bool drm_helper_fb_hotplug_event(struct drm_fb_helper *fb_helper, u32 max_width, u32 max_height); bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper); +int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper); #endif