提交 01934c2a 编写于 作者: T Thierry Reding 提交者: Daniel Vetter

drm/fb-helper: Propagate errors from initial config failure

Make drm_fb_helper_initial_config() return an int rather than a bool so
that the error can be properly propagated. While at it, update drivers
to propagate errors further rather than just ignore them.

v2:
- cirrus: No cleanup is required, the top-level cirrus_driver_load()
  will do it as part of cirrus_driver_unload() in its cleanup path.
Reported-by: NFengguang Wu <fengguang.wu@intel.com>

Cc: David Airlie <airlied@linux.ie>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
Cc: Rob Clark <robdclark@gmail.com>
Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Christian König <christian.koenig@amd.com>
Cc: Ben Skeggs <bskeggs@redhat.com>
Signed-off-by: NThierry Reding <treding@nvidia.com>
Reviewed-by: NAlex Deucher <alexander.deucher@amd.com>
Reviewed-by: NPatrik Jakobsson <patrik.r.jakobsson@gmail.com>
Reviewed-by: NChristian König <christian.koenig@amd.com>
[danvet: Squash in simplification patch from kbuild.]
Signed-off-by: NDaniel Vetter <daniel.vetter@ffwll.ch>
上级 7119ad5f
...@@ -335,18 +335,27 @@ int ast_fbdev_init(struct drm_device *dev) ...@@ -335,18 +335,27 @@ int ast_fbdev_init(struct drm_device *dev)
ret = drm_fb_helper_init(dev, &afbdev->helper, ret = drm_fb_helper_init(dev, &afbdev->helper,
1, 1); 1, 1);
if (ret) { if (ret)
kfree(afbdev); goto free;
return ret;
}
drm_fb_helper_single_add_all_connectors(&afbdev->helper); ret = drm_fb_helper_single_add_all_connectors(&afbdev->helper);
if (ret)
goto fini;
/* disable all the possible outputs/crtcs before entering KMS mode */ /* disable all the possible outputs/crtcs before entering KMS mode */
drm_helper_disable_unused_functions(dev); drm_helper_disable_unused_functions(dev);
drm_fb_helper_initial_config(&afbdev->helper, 32); ret = drm_fb_helper_initial_config(&afbdev->helper, 32);
if (ret)
goto fini;
return 0; return 0;
fini:
drm_fb_helper_fini(&afbdev->helper);
free:
kfree(afbdev);
return ret;
} }
void ast_fbdev_fini(struct drm_device *dev) void ast_fbdev_fini(struct drm_device *dev)
......
...@@ -207,12 +207,22 @@ int bochs_fbdev_init(struct bochs_device *bochs) ...@@ -207,12 +207,22 @@ int bochs_fbdev_init(struct bochs_device *bochs)
if (ret) if (ret)
return ret; return ret;
drm_fb_helper_single_add_all_connectors(&bochs->fb.helper); ret = drm_fb_helper_single_add_all_connectors(&bochs->fb.helper);
if (ret)
goto fini;
drm_helper_disable_unused_functions(bochs->dev); drm_helper_disable_unused_functions(bochs->dev);
drm_fb_helper_initial_config(&bochs->fb.helper, 32);
ret = drm_fb_helper_initial_config(&bochs->fb.helper, 32);
if (ret)
goto fini;
bochs->fb.initialized = true; bochs->fb.initialized = true;
return 0; return 0;
fini:
drm_fb_helper_fini(&bochs->fb.helper);
return ret;
} }
void bochs_fbdev_fini(struct bochs_device *bochs) void bochs_fbdev_fini(struct bochs_device *bochs)
......
...@@ -317,17 +317,17 @@ int cirrus_fbdev_init(struct cirrus_device *cdev) ...@@ -317,17 +317,17 @@ int cirrus_fbdev_init(struct cirrus_device *cdev)
ret = drm_fb_helper_init(cdev->dev, &gfbdev->helper, ret = drm_fb_helper_init(cdev->dev, &gfbdev->helper,
cdev->num_crtc, CIRRUSFB_CONN_LIMIT); cdev->num_crtc, CIRRUSFB_CONN_LIMIT);
if (ret) { if (ret)
kfree(gfbdev); return ret;
ret = drm_fb_helper_single_add_all_connectors(&gfbdev->helper);
if (ret)
return ret; return ret;
}
drm_fb_helper_single_add_all_connectors(&gfbdev->helper);
/* disable all the possible outputs/crtcs before entering KMS mode */ /* disable all the possible outputs/crtcs before entering KMS mode */
drm_helper_disable_unused_functions(cdev->dev); drm_helper_disable_unused_functions(cdev->dev);
drm_fb_helper_initial_config(&gfbdev->helper, bpp_sel);
return 0; return drm_fb_helper_initial_config(&gfbdev->helper, bpp_sel);
} }
void cirrus_fbdev_fini(struct cirrus_device *cdev) void cirrus_fbdev_fini(struct cirrus_device *cdev)
......
...@@ -1688,7 +1688,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) ...@@ -1688,7 +1688,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)
* RETURNS: * RETURNS:
* Zero if everything went ok, nonzero otherwise. * Zero if everything went ok, nonzero otherwise.
*/ */
bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel) int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel)
{ {
struct drm_device *dev = fb_helper->dev; struct drm_device *dev = fb_helper->dev;
int count = 0; int count = 0;
......
...@@ -593,6 +593,7 @@ int psb_fbdev_init(struct drm_device *dev) ...@@ -593,6 +593,7 @@ int psb_fbdev_init(struct drm_device *dev)
{ {
struct psb_fbdev *fbdev; struct psb_fbdev *fbdev;
struct drm_psb_private *dev_priv = dev->dev_private; struct drm_psb_private *dev_priv = dev->dev_private;
int ret;
fbdev = kzalloc(sizeof(struct psb_fbdev), GFP_KERNEL); fbdev = kzalloc(sizeof(struct psb_fbdev), GFP_KERNEL);
if (!fbdev) { if (!fbdev) {
...@@ -604,16 +605,29 @@ int psb_fbdev_init(struct drm_device *dev) ...@@ -604,16 +605,29 @@ int psb_fbdev_init(struct drm_device *dev)
drm_fb_helper_prepare(dev, &fbdev->psb_fb_helper, &psb_fb_helper_funcs); drm_fb_helper_prepare(dev, &fbdev->psb_fb_helper, &psb_fb_helper_funcs);
drm_fb_helper_init(dev, &fbdev->psb_fb_helper, dev_priv->ops->crtcs, ret = drm_fb_helper_init(dev, &fbdev->psb_fb_helper,
INTELFB_CONN_LIMIT); dev_priv->ops->crtcs, INTELFB_CONN_LIMIT);
if (ret)
goto free;
drm_fb_helper_single_add_all_connectors(&fbdev->psb_fb_helper); ret = drm_fb_helper_single_add_all_connectors(&fbdev->psb_fb_helper);
if (ret)
goto fini;
/* disable all the possible outputs/crtcs before entering KMS mode */ /* disable all the possible outputs/crtcs before entering KMS mode */
drm_helper_disable_unused_functions(dev); drm_helper_disable_unused_functions(dev);
drm_fb_helper_initial_config(&fbdev->psb_fb_helper, 32); ret = drm_fb_helper_initial_config(&fbdev->psb_fb_helper, 32);
if (ret)
goto fini;
return 0; return 0;
fini:
drm_fb_helper_fini(&fbdev->psb_fb_helper);
free:
kfree(fbdev);
return ret;
} }
static void psb_fbdev_fini(struct drm_device *dev) static void psb_fbdev_fini(struct drm_device *dev)
......
...@@ -303,14 +303,22 @@ int mgag200_fbdev_init(struct mga_device *mdev) ...@@ -303,14 +303,22 @@ int mgag200_fbdev_init(struct mga_device *mdev)
if (ret) if (ret)
return ret; return ret;
drm_fb_helper_single_add_all_connectors(&mfbdev->helper); ret = drm_fb_helper_single_add_all_connectors(&mfbdev->helper);
if (ret)
goto fini;
/* disable all the possible outputs/crtcs before entering KMS mode */ /* disable all the possible outputs/crtcs before entering KMS mode */
drm_helper_disable_unused_functions(mdev->dev); drm_helper_disable_unused_functions(mdev->dev);
drm_fb_helper_initial_config(&mfbdev->helper, bpp_sel); ret = drm_fb_helper_initial_config(&mfbdev->helper, bpp_sel);
if (ret)
goto fini;
return 0; return 0;
fini:
drm_fb_helper_fini(&mfbdev->helper);
return ret;
} }
void mgag200_fbdev_fini(struct mga_device *mdev) void mgag200_fbdev_fini(struct mga_device *mdev)
......
...@@ -241,17 +241,23 @@ struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev) ...@@ -241,17 +241,23 @@ struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev)
goto fail; goto fail;
} }
drm_fb_helper_single_add_all_connectors(helper); ret = drm_fb_helper_single_add_all_connectors(helper);
if (ret)
goto fini;
/* disable all the possible outputs/crtcs before entering KMS mode */ /* disable all the possible outputs/crtcs before entering KMS mode */
drm_helper_disable_unused_functions(dev); drm_helper_disable_unused_functions(dev);
drm_fb_helper_initial_config(helper, 32); ret = drm_fb_helper_initial_config(helper, 32);
if (ret)
goto fini;
priv->fbdev = helper; priv->fbdev = helper;
return helper; return helper;
fini:
drm_fb_helper_fini(helper);
fail: fail:
kfree(fbdev); kfree(fbdev);
return NULL; return NULL;
......
...@@ -539,12 +539,12 @@ nouveau_fbcon_init(struct drm_device *dev) ...@@ -539,12 +539,12 @@ nouveau_fbcon_init(struct drm_device *dev)
ret = drm_fb_helper_init(dev, &fbcon->helper, ret = drm_fb_helper_init(dev, &fbcon->helper,
dev->mode_config.num_crtc, 4); dev->mode_config.num_crtc, 4);
if (ret) { if (ret)
kfree(fbcon); goto free;
return ret;
}
drm_fb_helper_single_add_all_connectors(&fbcon->helper); ret = drm_fb_helper_single_add_all_connectors(&fbcon->helper);
if (ret)
goto fini;
if (drm->device.info.ram_size <= 32 * 1024 * 1024) if (drm->device.info.ram_size <= 32 * 1024 * 1024)
preferred_bpp = 8; preferred_bpp = 8;
...@@ -557,8 +557,17 @@ nouveau_fbcon_init(struct drm_device *dev) ...@@ -557,8 +557,17 @@ nouveau_fbcon_init(struct drm_device *dev)
/* disable all the possible outputs/crtcs before entering KMS mode */ /* disable all the possible outputs/crtcs before entering KMS mode */
drm_helper_disable_unused_functions(dev); drm_helper_disable_unused_functions(dev);
drm_fb_helper_initial_config(&fbcon->helper, preferred_bpp); ret = drm_fb_helper_initial_config(&fbcon->helper, preferred_bpp);
if (ret)
goto fini;
return 0; return 0;
fini:
drm_fb_helper_fini(&fbcon->helper);
free:
kfree(fbcon);
return ret;
} }
void void
......
...@@ -334,17 +334,23 @@ struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev) ...@@ -334,17 +334,23 @@ struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev)
goto fail; goto fail;
} }
drm_fb_helper_single_add_all_connectors(helper); ret = drm_fb_helper_single_add_all_connectors(helper);
if (ret)
goto fini;
/* disable all the possible outputs/crtcs before entering KMS mode */ /* disable all the possible outputs/crtcs before entering KMS mode */
drm_helper_disable_unused_functions(dev); drm_helper_disable_unused_functions(dev);
drm_fb_helper_initial_config(helper, 32); ret = drm_fb_helper_initial_config(helper, 32);
if (ret)
goto fini;
priv->fbdev = helper; priv->fbdev = helper;
return helper; return helper;
fini:
drm_fb_helper_fini(helper);
fail: fail:
kfree(fbdev); kfree(fbdev);
return NULL; return NULL;
......
...@@ -686,14 +686,24 @@ int qxl_fbdev_init(struct qxl_device *qdev) ...@@ -686,14 +686,24 @@ int qxl_fbdev_init(struct qxl_device *qdev)
ret = drm_fb_helper_init(qdev->ddev, &qfbdev->helper, ret = drm_fb_helper_init(qdev->ddev, &qfbdev->helper,
qxl_num_crtc /* num_crtc - QXL supports just 1 */, qxl_num_crtc /* num_crtc - QXL supports just 1 */,
QXLFB_CONN_LIMIT); QXLFB_CONN_LIMIT);
if (ret) { if (ret)
kfree(qfbdev); goto free;
return ret;
} ret = drm_fb_helper_single_add_all_connectors(&qfbdev->helper);
if (ret)
goto fini;
ret = drm_fb_helper_initial_config(&qfbdev->helper, bpp_sel);
if (ret)
goto fini;
drm_fb_helper_single_add_all_connectors(&qfbdev->helper);
drm_fb_helper_initial_config(&qfbdev->helper, bpp_sel);
return 0; return 0;
fini:
drm_fb_helper_fini(&qfbdev->helper);
free:
kfree(qfbdev);
return ret;
} }
void qxl_fbdev_fini(struct qxl_device *qdev) void qxl_fbdev_fini(struct qxl_device *qdev)
......
...@@ -390,18 +390,27 @@ int radeon_fbdev_init(struct radeon_device *rdev) ...@@ -390,18 +390,27 @@ int radeon_fbdev_init(struct radeon_device *rdev)
ret = drm_fb_helper_init(rdev->ddev, &rfbdev->helper, ret = drm_fb_helper_init(rdev->ddev, &rfbdev->helper,
rdev->num_crtc, rdev->num_crtc,
RADEONFB_CONN_LIMIT); RADEONFB_CONN_LIMIT);
if (ret) { if (ret)
kfree(rfbdev); goto free;
return ret;
}
drm_fb_helper_single_add_all_connectors(&rfbdev->helper); ret = drm_fb_helper_single_add_all_connectors(&rfbdev->helper);
if (ret)
goto fini;
/* disable all the possible outputs/crtcs before entering KMS mode */ /* disable all the possible outputs/crtcs before entering KMS mode */
drm_helper_disable_unused_functions(rdev->ddev); drm_helper_disable_unused_functions(rdev->ddev);
drm_fb_helper_initial_config(&rfbdev->helper, bpp_sel); ret = drm_fb_helper_initial_config(&rfbdev->helper, bpp_sel);
if (ret)
goto fini;
return 0; return 0;
fini:
drm_fb_helper_fini(&rfbdev->helper);
free:
kfree(rfbdev);
return ret;
} }
void radeon_fbdev_fini(struct radeon_device *rdev) void radeon_fbdev_fini(struct radeon_device *rdev)
......
...@@ -589,19 +589,27 @@ int udl_fbdev_init(struct drm_device *dev) ...@@ -589,19 +589,27 @@ int udl_fbdev_init(struct drm_device *dev)
ret = drm_fb_helper_init(dev, &ufbdev->helper, ret = drm_fb_helper_init(dev, &ufbdev->helper,
1, 1); 1, 1);
if (ret) { if (ret)
kfree(ufbdev); goto free;
return ret;
}
drm_fb_helper_single_add_all_connectors(&ufbdev->helper); ret = drm_fb_helper_single_add_all_connectors(&ufbdev->helper);
if (ret)
goto fini;
/* disable all the possible outputs/crtcs before entering KMS mode */ /* disable all the possible outputs/crtcs before entering KMS mode */
drm_helper_disable_unused_functions(dev); drm_helper_disable_unused_functions(dev);
drm_fb_helper_initial_config(&ufbdev->helper, bpp_sel); ret = drm_fb_helper_initial_config(&ufbdev->helper, bpp_sel);
if (ret)
goto fini;
return 0; return 0;
fini:
drm_fb_helper_fini(&ufbdev->helper);
free:
kfree(ufbdev);
return ret;
} }
void udl_fbdev_cleanup(struct drm_device *dev) void udl_fbdev_cleanup(struct drm_device *dev)
......
...@@ -125,7 +125,7 @@ void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch, ...@@ -125,7 +125,7 @@ void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info); int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper); int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel); int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel);
int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper); int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper);
int drm_fb_helper_debug_enter(struct fb_info *info); int drm_fb_helper_debug_enter(struct fb_info *info);
int drm_fb_helper_debug_leave(struct fb_info *info); int drm_fb_helper_debug_leave(struct fb_info *info);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册