summaryrefslogtreecommitdiff
path: root/drivers/media/platform/ti-vpe/vpe.c
diff options
context:
space:
mode:
authorNikhil Devshatwar <nikhil.nd@ti.com>2016-11-18 21:20:35 -0200
committerMauro Carvalho Chehab <mchehab@s-opensource.com>2016-11-22 08:07:28 -0200
commitc786595beb89d74ff709b2ee382f34a1e0040d88 (patch)
treec6fb4a1e79b33c750f9e3f78b4b714df06f7eb66 /drivers/media/platform/ti-vpe/vpe.c
parentdfe1349dc805aa3113e6fba9db55761d24ce63fe (diff)
[media] media: ti-vpe: vpdma: Fix race condition for firmware loading
vpdma_create API is supposed to allocated the struct vpdma_data and return it to the driver. Also, it would call the callback function when the VPDMA firmware is loaded. Typically, VPE driver have following function call: dev->vpdma = vpdma_create(pdev, firmware_load_callback); And the callback implementation would continue the probe further. Also, the dev->vpdma is accessed from the callback implementation. This may lead to race condition between assignment of dev->vpdma and the callback function being triggered. This would lead to kernel crash because of NULL pointer access. Fix this by passing a driver wrapped &vpdma_data instead of allocating inside vpdma_create. Change the vpdma_create prototype accordingly and fix return paths. Also, update the VPE driver to use the updated API and initialize the dev->vpdma before hand so that the race condition is avoided. Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com> Signed-off-by: Benoit Parrot <bparrot@ti.com> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Diffstat (limited to 'drivers/media/platform/ti-vpe/vpe.c')
-rw-r--r--drivers/media/platform/ti-vpe/vpe.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index f92ad7a473c1..15e846b95719 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -383,6 +383,7 @@ struct vpe_dev {
void __iomem *base;
struct resource *res;
+ struct vpdma_data vpdma_data;
struct vpdma_data *vpdma; /* vpdma data handle */
struct sc_data *sc; /* scaler data handle */
struct csc_data *csc; /* csc data handle */
@@ -2462,11 +2463,10 @@ static int vpe_probe(struct platform_device *pdev)
goto runtime_put;
}
- dev->vpdma = vpdma_create(pdev, vpe_fw_cb);
- if (IS_ERR(dev->vpdma)) {
- ret = PTR_ERR(dev->vpdma);
+ dev->vpdma = &dev->vpdma_data;
+ ret = vpdma_create(pdev, dev->vpdma, vpe_fw_cb);
+ if (ret)
goto runtime_put;
- }
return 0;