From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752868AbdHDXRR (ORCPT ); Fri, 4 Aug 2017 19:17:17 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:46320 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752725AbdHDXRM (ORCPT ); Fri, 4 Aug 2017 19:17:12 -0400 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Laurent Pinchart , thongsyho , Nhan Nguyen Subject: [PATCH 4.9 023/105] drm: rcar-du: Simplify and fix probe error handling Date: Fri, 4 Aug 2017 16:14:51 -0700 Message-Id: <20170804231553.302207819@linuxfoundation.org> X-Mailer: git-send-email 2.13.4 In-Reply-To: <20170804231551.544678194@linuxfoundation.org> References: <20170804231551.544678194@linuxfoundation.org> User-Agent: quilt/0.65 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.9-stable review patch. If anyone has any objections, please let me know. ------------------ From: Laurent Pinchart 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 Signed-off-by: thongsyho Signed-off-by: Nhan Nguyen Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/rcar-du/rcar_du_drv.c | 30 ++++++++++-------------------- drivers/gpu/drm/rcar-du/rcar_du_kms.c | 7 +++++++ 2 files changed, 17 insertions(+), 20 deletions(-) --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c @@ -285,7 +285,6 @@ static int rcar_du_remove(struct platfor drm_kms_helper_poll_fini(ddev); drm_mode_config_cleanup(ddev); - drm_vblank_cleanup(ddev); drm_dev_unref(ddev); @@ -305,7 +304,7 @@ static int rcar_du_probe(struct platform return -ENODEV; } - /* 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; @@ -315,31 +314,22 @@ static int rcar_du_probe(struct platform rcdu->dev = &pdev->dev; rcdu->info = of_match_device(rcar_du_of_table, rcdu->dev)->data; - ddev = drm_dev_alloc(&rcar_du_driver, &pdev->dev); - if (IS_ERR(ddev)) - return PTR_ERR(ddev); - - 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; + 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); + + rcdu->ddev = ddev; + ddev->dev_private = rcdu; + ret = rcar_du_modeset_init(rcdu); if (ret < 0) { if (ret != -EPROBE_DEFER) --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c @@ -567,6 +567,13 @@ int rcar_du_modeset_init(struct rcar_du_ 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);