diff options
author | Benoit Parrot <bparrot@ti.com> | 2015-07-15 18:00:06 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2015-07-22 11:03:54 -0300 |
commit | c99235fa3ef833c3c23926085f2bb68851c8460a (patch) | |
tree | f9b3705506eb91fc040bbd2e861f75aba5e899fe /drivers/media/platform/am437x | |
parent | 2091f5181c66b3617a977e79843aba10e087be6c (diff) | |
download | linux-c99235fa3ef833c3c23926085f2bb68851c8460a.tar.bz2 |
[media] media: am437x-vpfe: Fix a race condition during release
There was a race condition where during cleanup/release operation
on-going streaming would cause a kernel panic because the hardware
module was disabled prematurely with IRQ still pending.
Fixes: 417d2e507edc ("[media] media: platform: add VPFE capture driver support for AM437X")
Cc: <stable@vger.kernel.org> # v4.0+
Signed-off-by: Benoit Parrot <bparrot@ti.com>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/platform/am437x')
-rw-r--r-- | drivers/media/platform/am437x/am437x-vpfe.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c index 1fed7a56c8ae..c8447fa3fd91 100644 --- a/drivers/media/platform/am437x/am437x-vpfe.c +++ b/drivers/media/platform/am437x/am437x-vpfe.c @@ -1186,14 +1186,24 @@ static int vpfe_initialize_device(struct vpfe_device *vpfe) static int vpfe_release(struct file *file) { struct vpfe_device *vpfe = video_drvdata(file); + bool fh_singular; int ret; mutex_lock(&vpfe->lock); - if (v4l2_fh_is_singular_file(file)) - vpfe_ccdc_close(&vpfe->ccdc, vpfe->pdev); + /* Save the singular status before we call the clean-up helper */ + fh_singular = v4l2_fh_is_singular_file(file); + + /* the release helper will cleanup any on-going streaming */ ret = _vb2_fop_release(file, NULL); + /* + * If this was the last open file. + * Then de-initialize hw module. + */ + if (fh_singular) + vpfe_ccdc_close(&vpfe->ccdc, vpfe->pdev); + mutex_unlock(&vpfe->lock); return ret; |