mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-05 18:39:59 +00:00
drm: rcar-du: Simplify and fix probe error handling
It isn't safe to call drm_dev_unregister() without first initializing mode setting with drm_mode_config_init(). This leads to a crash if either IO memory can't be remapped or vblank initialization fails. Fix this by reordering the initialization sequence. Move vblank initialization after the drm_mode_config_init() call, and move IO remapping before drm_dev_alloc() to avoid the need to perform clean up in case of failure. While at it remove the explicit drm_vblank_cleanup() call from rcar_du_remove() as the drm_dev_unregister() function already cleans up vblank. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
This commit is contained in:
parent
05ee29e94a
commit
4f7b0d2638
2 changed files with 17 additions and 20 deletions
|
@ -285,7 +285,6 @@ static int rcar_du_remove(struct platform_device *pdev)
|
|||
|
||||
drm_kms_helper_poll_fini(ddev);
|
||||
drm_mode_config_cleanup(ddev);
|
||||
drm_vblank_cleanup(ddev);
|
||||
|
||||
drm_dev_unref(ddev);
|
||||
|
||||
|
@ -299,7 +298,7 @@ static int rcar_du_probe(struct platform_device *pdev)
|
|||
struct resource *mem;
|
||||
int ret;
|
||||
|
||||
/* Allocate and initialize the DRM and R-Car device structures. */
|
||||
/* Allocate and initialize the R-Car device structure. */
|
||||
rcdu = devm_kzalloc(&pdev->dev, sizeof(*rcdu), GFP_KERNEL);
|
||||
if (rcdu == NULL)
|
||||
return -ENOMEM;
|
||||
|
@ -309,6 +308,15 @@ static int rcar_du_probe(struct platform_device *pdev)
|
|||
rcdu->dev = &pdev->dev;
|
||||
rcdu->info = of_match_device(rcar_du_of_table, rcdu->dev)->data;
|
||||
|
||||
platform_set_drvdata(pdev, rcdu);
|
||||
|
||||
/* I/O resources */
|
||||
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
rcdu->mmio = devm_ioremap_resource(&pdev->dev, mem);
|
||||
if (IS_ERR(rcdu->mmio))
|
||||
return PTR_ERR(rcdu->mmio);
|
||||
|
||||
/* DRM/KMS objects */
|
||||
ddev = drm_dev_alloc(&rcar_du_driver, &pdev->dev);
|
||||
if (IS_ERR(ddev))
|
||||
return PTR_ERR(ddev);
|
||||
|
@ -316,24 +324,6 @@ static int rcar_du_probe(struct platform_device *pdev)
|
|||
rcdu->ddev = ddev;
|
||||
ddev->dev_private = rcdu;
|
||||
|
||||
platform_set_drvdata(pdev, rcdu);
|
||||
|
||||
/* I/O resources */
|
||||
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
rcdu->mmio = devm_ioremap_resource(&pdev->dev, mem);
|
||||
if (IS_ERR(rcdu->mmio)) {
|
||||
ret = PTR_ERR(rcdu->mmio);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Initialize vertical blanking interrupts handling. Start with vblank
|
||||
* disabled for all CRTCs.
|
||||
*/
|
||||
ret = drm_vblank_init(ddev, (1 << rcdu->info->num_crtcs) - 1);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
/* DRM/KMS objects */
|
||||
ret = rcar_du_modeset_init(rcdu);
|
||||
if (ret < 0) {
|
||||
if (ret != -EPROBE_DEFER)
|
||||
|
|
|
@ -559,6 +559,13 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Initialize vertical blanking interrupts handling. Start with vblank
|
||||
* disabled for all CRTCs.
|
||||
*/
|
||||
ret = drm_vblank_init(dev, (1 << rcdu->info->num_crtcs) - 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Initialize the groups. */
|
||||
num_groups = DIV_ROUND_UP(rcdu->num_crtcs, 2);
|
||||
|
||||
|
|
Loading…
Reference in a new issue