From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-eopbgr730108.outbound.protection.outlook.com ([40.107.73.108]:57545 "EHLO NAM05-DM3-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728769AbeIQI0W (ORCPT ); Mon, 17 Sep 2018 04:26:22 -0400 From: Sasha Levin To: "stable@vger.kernel.org" , "linux-kernel@vger.kernel.org" CC: Alexey Khoroshilov , Hans Verkuil , Mauro Carvalho Chehab , Sasha Levin Subject: [PATCH AUTOSEL 4.18 037/136] media: fsl-viu: fix error handling in viu_of_probe() Date: Mon, 17 Sep 2018 03:00:35 +0000 Message-ID: <20180917030006.245495-37-alexander.levin@microsoft.com> References: <20180917030006.245495-1-alexander.levin@microsoft.com> In-Reply-To: <20180917030006.245495-1-alexander.levin@microsoft.com> Content-Language: en-US Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Sender: stable-owner@vger.kernel.org List-ID: From: Alexey Khoroshilov [ Upstream commit 662a99e145661c2b35155cf375044deae9b79896 ] viu_of_probe() ignores fails in i2c_get_adapter(), tries to unlock uninitialized mutex on error path. The patch streamlining the error handling in viu_of_probe(). Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/platform/fsl-viu.c | 38 +++++++++++++++++++------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/drivers/media/platform/fsl-viu.c b/drivers/media/platform/fsl-= viu.c index e41510ce69a4..0273302aa741 100644 --- a/drivers/media/platform/fsl-viu.c +++ b/drivers/media/platform/fsl-viu.c @@ -1414,7 +1414,7 @@ static int viu_of_probe(struct platform_device *op) sizeof(struct viu_reg), DRV_NAME)) { dev_err(&op->dev, "Error while requesting mem region\n"); ret =3D -EBUSY; - goto err; + goto err_irq; } =20 /* remap registers */ @@ -1422,7 +1422,7 @@ static int viu_of_probe(struct platform_device *op) if (!viu_regs) { dev_err(&op->dev, "Can't map register set\n"); ret =3D -ENOMEM; - goto err; + goto err_irq; } =20 /* Prepare our private structure */ @@ -1430,7 +1430,7 @@ static int viu_of_probe(struct platform_device *op) if (!viu_dev) { dev_err(&op->dev, "Can't allocate private structure\n"); ret =3D -ENOMEM; - goto err; + goto err_irq; } =20 viu_dev->vr =3D viu_regs; @@ -1446,16 +1446,21 @@ static int viu_of_probe(struct platform_device *op) ret =3D v4l2_device_register(viu_dev->dev, &viu_dev->v4l2_dev); if (ret < 0) { dev_err(&op->dev, "v4l2_device_register() failed: %d\n", ret); - goto err; + goto err_irq; } =20 ad =3D i2c_get_adapter(0); + if (!ad) { + ret =3D -EFAULT; + dev_err(&op->dev, "couldn't get i2c adapter\n"); + goto err_v4l2; + } =20 v4l2_ctrl_handler_init(&viu_dev->hdl, 5); if (viu_dev->hdl.error) { ret =3D viu_dev->hdl.error; dev_err(&op->dev, "couldn't register control\n"); - goto err_vdev; + goto err_i2c; } /* This control handler will inherit the control(s) from the sub-device(s). */ @@ -1471,7 +1476,7 @@ static int viu_of_probe(struct platform_device *op) vdev =3D video_device_alloc(); if (vdev =3D=3D NULL) { ret =3D -ENOMEM; - goto err_vdev; + goto err_hdl; } =20 *vdev =3D viu_template; @@ -1492,7 +1497,7 @@ static int viu_of_probe(struct platform_device *op) ret =3D video_register_device(viu_dev->vdev, VFL_TYPE_GRABBER, -1); if (ret < 0) { video_device_release(viu_dev->vdev); - goto err_vdev; + goto err_unlock; } =20 /* enable VIU clock */ @@ -1500,12 +1505,12 @@ static int viu_of_probe(struct platform_device *op) if (IS_ERR(clk)) { dev_err(&op->dev, "failed to lookup the clock!\n"); ret =3D PTR_ERR(clk); - goto err_clk; + goto err_vdev; } ret =3D clk_prepare_enable(clk); if (ret) { dev_err(&op->dev, "failed to enable the clock!\n"); - goto err_clk; + goto err_vdev; } viu_dev->clk =3D clk; =20 @@ -1516,7 +1521,7 @@ static int viu_of_probe(struct platform_device *op) if (request_irq(viu_dev->irq, viu_intr, 0, "viu", (void *)viu_dev)) { dev_err(&op->dev, "Request VIU IRQ failed.\n"); ret =3D -ENODEV; - goto err_irq; + goto err_clk; } =20 mutex_unlock(&viu_dev->lock); @@ -1524,16 +1529,19 @@ static int viu_of_probe(struct platform_device *op) dev_info(&op->dev, "Freescale VIU Video Capture Board\n"); return ret; =20 -err_irq: - clk_disable_unprepare(viu_dev->clk); err_clk: - video_unregister_device(viu_dev->vdev); + clk_disable_unprepare(viu_dev->clk); err_vdev: - v4l2_ctrl_handler_free(&viu_dev->hdl); + video_unregister_device(viu_dev->vdev); +err_unlock: mutex_unlock(&viu_dev->lock); +err_hdl: + v4l2_ctrl_handler_free(&viu_dev->hdl); +err_i2c: i2c_put_adapter(ad); +err_v4l2: v4l2_device_unregister(&viu_dev->v4l2_dev); -err: +err_irq: irq_dispose_mapping(viu_irq); return ret; } --=20 2.17.1