From 94b9ce6870f9c90ac92505482689818b254312f7 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Thu, 25 Jun 2020 22:19:47 +0200 Subject: [PATCH] media: s5p-g2d: Fix a memory leak in an error handling path in 'g2d_probe()' Memory allocated with 'v4l2_m2m_init()' must be freed by a corresponding call to 'v4l2_m2m_release()' Also reorder the code at the end of the probe function so that 'video_register_device()' is called last. Update the error handling path accordingly. Fixes: 5ce60d790a24 ("[media] s5p-g2d: Add DT based discovery support") Fixes: 918847341af0 ("[media] v4l: add G2D driver for s5p device family") Signed-off-by: Christophe JAILLET Signed-off-by: Hans Verkuil [hverkuil-cisco@xs4all.nl: checkpatch: align with parenthesis] Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-g2d/g2d.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/drivers/media/platform/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c index 6932fd47071b..15bcb7f6e113 100644 --- a/drivers/media/platform/s5p-g2d/g2d.c +++ b/drivers/media/platform/s5p-g2d/g2d.c @@ -695,21 +695,13 @@ static int g2d_probe(struct platform_device *pdev) vfd->lock = &dev->mutex; vfd->v4l2_dev = &dev->v4l2_dev; vfd->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; - ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0); - if (ret) { - v4l2_err(&dev->v4l2_dev, "Failed to register video device\n"); - goto rel_vdev; - } - video_set_drvdata(vfd, dev); - dev->vfd = vfd; - v4l2_info(&dev->v4l2_dev, "device registered as /dev/video%d\n", - vfd->num); + platform_set_drvdata(pdev, dev); dev->m2m_dev = v4l2_m2m_init(&g2d_m2m_ops); if (IS_ERR(dev->m2m_dev)) { v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n"); ret = PTR_ERR(dev->m2m_dev); - goto unreg_video_dev; + goto rel_vdev; } def_frame.stride = (def_frame.width * def_frame.fmt->depth) >> 3; @@ -717,14 +709,24 @@ static int g2d_probe(struct platform_device *pdev) of_id = of_match_node(exynos_g2d_match, pdev->dev.of_node); if (!of_id) { ret = -ENODEV; - goto unreg_video_dev; + goto free_m2m; } dev->variant = (struct g2d_variant *)of_id->data; + ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0); + if (ret) { + v4l2_err(&dev->v4l2_dev, "Failed to register video device\n"); + goto free_m2m; + } + video_set_drvdata(vfd, dev); + dev->vfd = vfd; + v4l2_info(&dev->v4l2_dev, "device registered as /dev/video%d\n", + vfd->num); + return 0; -unreg_video_dev: - video_unregister_device(dev->vfd); +free_m2m: + v4l2_m2m_release(dev->m2m_dev); rel_vdev: video_device_release(vfd); unreg_v4l2_dev: