OSDN Git Service

drm: rcar-du: Simplify and fix probe error handling
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tue, 18 Oct 2016 21:51:35 +0000 (00:51 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 7 Aug 2017 02:19:40 +0000 (19:19 -0700)
commit 4f7b0d263833928e947e172eff2d2997179c5cb9 upstream.

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>
Signed-off-by: thongsyho <thong.ho.px@rvc.renesas.com>
Signed-off-by: Nhan Nguyen <nhan.nguyen.yb@renesas.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/gpu/drm/rcar-du/rcar_du_drv.c
drivers/gpu/drm/rcar-du/rcar_du_kms.c

index aad5533..bf4674a 100644 (file)
@@ -260,7 +260,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);
 
@@ -291,6 +290,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))
+               ret = PTR_ERR(rcdu->mmio);
+
+       /* DRM/KMS objects */
        ddev = drm_dev_alloc(&rcar_du_driver, &pdev->dev);
        if (!ddev)
                return -ENOMEM;
@@ -300,26 +308,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) {
-               dev_err(&pdev->dev, "failed to initialize vblank\n");
-               goto error;
-       }
-
-       /* DRM/KMS objects */
        ret = rcar_du_modeset_init(rcdu);
        if (ret < 0) {
                dev_err(&pdev->dev, "failed to initialize DRM/KMS (%d)\n", ret);
index ca12e8c..46429c4 100644 (file)
@@ -761,6 +761,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);