summaryrefslogtreecommitdiff
path: root/drivers/media
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2020-07-06 20:36:18 +0200
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>2020-07-19 09:39:01 +0200
commitd3665f3b7c08bc50f97b2f308f4b745f7e80b3e8 (patch)
treec6de29827329bcd4349b8b20bc3338d85ceaeb15 /drivers/media
parent6675e871ca4dab14e849298767d34c2722f3ee1e (diff)
media: ti-vpe: cal: Add cal_camerarx_destroy() to cleanup CAMERARX
The cal_camerarx_create() function allocates resources with devm_*, and thus doesn't need any manual cleanup. Those won't hold true for long, as we will need to store resources that have no devm_* allocation variant in cal_camerarx. Furthermore, devm_kzalloc() is the wrong memory allocation API for structures that can be accessed from userspace, as device nodes can be kept open across device removal. Add a cal_camerarx_destroy() function to destroy a CAMERARX instance explicitly, and switch to kzalloc() for memory allocation. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/platform/ti-vpe/cal.c36
1 files changed, 30 insertions, 6 deletions
diff --git a/drivers/media/platform/ti-vpe/cal.c b/drivers/media/platform/ti-vpe/cal.c
index 5580913a1356..492141f07d69 100644
--- a/drivers/media/platform/ti-vpe/cal.c
+++ b/drivers/media/platform/ti-vpe/cal.c
@@ -932,7 +932,7 @@ static struct cal_camerarx *cal_camerarx_create(struct cal_dev *cal,
struct cal_camerarx *phy;
int ret;
- phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
+ phy = kzalloc(sizeof(*phy), GFP_KERNEL);
if (!phy)
return ERR_PTR(-ENOMEM);
@@ -947,7 +947,8 @@ static struct cal_camerarx *cal_camerarx_create(struct cal_dev *cal,
phy->base = devm_ioremap_resource(&pdev->dev, phy->res);
if (IS_ERR(phy->base)) {
cal_err(cal, "failed to ioremap\n");
- return ERR_CAST(phy->base);
+ ret = PTR_ERR(phy->base);
+ goto error;
}
cal_dbg(1, cal, "ioresource %s at %pa - %pa\n",
@@ -955,9 +956,21 @@ static struct cal_camerarx *cal_camerarx_create(struct cal_dev *cal,
ret = cal_camerarx_regmap_init(cal, phy);
if (ret)
- return ERR_PTR(ret);
+ goto error;
return phy;
+
+error:
+ kfree(phy);
+ return ERR_PTR(ret);
+}
+
+static void cal_camerarx_destroy(struct cal_camerarx *phy)
+{
+ if (!phy)
+ return;
+
+ kfree(phy);
}
static int cal_camerarx_init_regmap(struct cal_dev *cal)
@@ -2253,15 +2266,18 @@ static int cal_probe(struct platform_device *pdev)
/* Create CAMERARX PHYs. */
for (i = 0; i < cal->data->num_csi2_phy; ++i) {
cal->phy[i] = cal_camerarx_create(cal, i);
- if (IS_ERR(cal->phy[i]))
- return PTR_ERR(cal->phy[i]);
+ if (IS_ERR(cal->phy[i])) {
+ ret = PTR_ERR(cal->phy[i]);
+ cal->phy[i] = NULL;
+ goto error_camerarx;
+ }
}
/* Register the V4L2 device. */
ret = v4l2_device_register(&pdev->dev, &cal->v4l2_dev);
if (ret) {
cal_err(cal, "Failed to register V4L2 device\n");
- return ret;
+ goto error_camerarx;
}
/* Create contexts. */
@@ -2302,6 +2318,11 @@ error_pm_runtime:
error_v4l2:
v4l2_device_unregister(&cal->v4l2_dev);
+
+error_camerarx:
+ for (i = 0; i < ARRAY_SIZE(cal->phy); i++)
+ cal_camerarx_destroy(cal->phy[i]);
+
return ret;
}
@@ -2330,6 +2351,9 @@ static int cal_remove(struct platform_device *pdev)
v4l2_device_unregister(&cal->v4l2_dev);
+ for (i = 0; i < ARRAY_SIZE(cal->phy); i++)
+ cal_camerarx_destroy(cal->phy[i]);
+
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);