From patchwork Wed Apr 6 09:45:52 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sjoerd Simons X-Patchwork-Id: 8760121 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id EC9F7C0553 for ; Wed, 6 Apr 2016 09:46:00 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id F1063201EC for ; Wed, 6 Apr 2016 09:45:59 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 175D2201E4 for ; Wed, 6 Apr 2016 09:45:59 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 286AB6E8BF; Wed, 6 Apr 2016 09:45:58 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e3e3]) by gabe.freedesktop.org (Postfix) with ESMTPS id 7B72A6E3D9 for ; Wed, 6 Apr 2016 09:45:56 +0000 (UTC) Received: from dusk.luon.net (unknown [IPv6:2001:1af8:fe00:8421:f2de:f1ff:fe93:2ee]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: sjoerd) by bhuna.collabora.co.uk (Postfix) with ESMTPSA id 472D12609FE; Wed, 6 Apr 2016 10:45:55 +0100 (BST) Received: by dusk.luon.net (Postfix, from userid 1000) id E07F720BDC; Wed, 6 Apr 2016 11:45:52 +0200 (CEST) From: Sjoerd Simons To: Laurent Pinchart Subject: [PATCH] drm: rcar-du: Only unwindow as necessary on probe failure Date: Wed, 6 Apr 2016 11:45:52 +0200 Message-Id: <1459935952-4639-1-git-send-email-sjoerd.simons@collabora.co.uk> X-Mailer: git-send-email 2.8.0.rc3 Cc: linux-renesas-soc@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Spam-Status: No, score=-5.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Simply calling rcar_du_remove on any error can cause unbalanced calls to various functions (e.g. drm_connector_register/unregister, drm_dev_register/drm_dev_unref). This can be seen at bootup of my Porter boards with current next: [ 2.789322] rcar-du feb00000.display: failed to initialize DRM/KMS (-517) [ 2.796267] ------------[ cut here ]------------ [ 2.800996] WARNING: CPU: 1 PID: 1 at include/drm/drm_crtc.h:2623 drm_connector_unregister_all+0x60/0x68 [ 2.810689] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 4.6.0-rc2-next-20160405-dirty #11 [ 2.818864] Hardware name: Generic R8A7791 (Flattened Device Tree) [ 2.825174] Backtrace: [ 2.827699] [] (dump_backtrace) from [] (show_stack+0x18/0x1c) [ 2.835430] r7:c042da78 r6:00000009 r5:60000013 r4:00000000 [ 2.841251] [] (show_stack) from [] (dump_stack+0x84/0xa4) [ 2.848632] [] (dump_stack) from [] (__warn+0xd0/0x100) [ 2.855739] r5:00000000 r4:00000000 [ 2.859409] [] (__warn) from [] (warn_slowpath_null+0x28/0x30) [ 2.867139] r9:00000001 r8:ef1dc610 r7:ef114010 r6:ef1dc600 r5:ef114010 r4:ef2f2400 [ 2.875096] [] (warn_slowpath_null) from [] (drm_connector_unregister_all+0x60/0x68) [ 2.884785] [] (drm_connector_unregister_all) from [] (rcar_du_remove+0x1c/0x5c) [ 2.894111] r5:ef114010 r4:ef2f2400 [ 2.897780] [] (rcar_du_remove) from [] (rcar_du_probe+0x1d0/0x210) [ 2.905953] r5:ef2f2400 r4:fffffdfb [ 2.909625] [] (rcar_du_probe) from [] (platform_drv_probe+0x58/0xa8) [ 2.917976] r9:00000000 r8:c0a1cca4 r7:c0a71a48 r6:c0a1cca4 r5:ef1dc610 r4:c0440b80 Adjust the code to only unwind as necessary on probe failures Signed-off-by: Sjoerd Simons --- drivers/gpu/drm/rcar-du/rcar_du_drv.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c index 644db36..deb75fa 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c @@ -333,7 +333,7 @@ static int rcar_du_probe(struct platform_device *pdev) rcdu->mmio = devm_ioremap_resource(&pdev->dev, mem); if (IS_ERR(rcdu->mmio)) { ret = PTR_ERR(rcdu->mmio); - goto error; + goto error_dev; } /* Initialize vertical blanking interrupts handling. Start with vblank @@ -342,14 +342,17 @@ static int rcar_du_probe(struct platform_device *pdev) 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; + goto error_dev; } /* DRM/KMS objects */ ret = rcar_du_modeset_init(rcdu); if (ret < 0) { + /* modeset_init could have failed partway through and doesn't + * do its own cleanup, so needs to be completely undone. + */ dev_err(&pdev->dev, "failed to initialize DRM/KMS (%d)\n", ret); - goto error; + goto error_modeset; } ddev->irq_enabled = 1; @@ -359,7 +362,7 @@ static int rcar_du_probe(struct platform_device *pdev) */ ret = drm_dev_register(ddev, 0); if (ret) - goto error; + goto error_modeset; mutex_lock(&ddev->mode_config.mutex); drm_for_each_connector(connector, ddev) { @@ -369,15 +372,30 @@ static int rcar_du_probe(struct platform_device *pdev) } mutex_unlock(&ddev->mode_config.mutex); + /* One or more connects could have been registered, so unregister all + * connectors. + */ if (ret < 0) - goto error; + goto error_connector; DRM_INFO("Device %s probed\n", dev_name(&pdev->dev)); return 0; -error: - rcar_du_remove(pdev); +error_connector: + drm_connector_unregister_all(ddev); + drm_dev_unregister(ddev); + +error_modeset: + if (rcdu->fbdev) + drm_fbdev_cma_fini(rcdu->fbdev); + + drm_kms_helper_poll_fini(ddev); + drm_mode_config_cleanup(ddev); + drm_vblank_cleanup(ddev); + +error_dev: + drm_dev_unref(ddev); return ret; }