diff options
author | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2009-06-24 15:31:25 +0200 |
---|---|---|
committer | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2009-06-24 15:31:25 +0200 |
commit | 23fc368d1e39ccddfbbf74673e172d7c3e8391aa (patch) | |
tree | 06525a5bd57555c4c15d2bd295f3bd4927e5e270 /linux/drivers/media/video/soc_camera.c | |
parent | 12ca65f34438319e101f46e652524f0229f5bb74 (diff) | |
download | mediapointer-dvb-s2-23fc368d1e39ccddfbbf74673e172d7c3e8391aa.tar.gz mediapointer-dvb-s2-23fc368d1e39ccddfbbf74673e172d7c3e8391aa.tar.bz2 |
soc-camera: fix missing clean up on error path
From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
If soc_camera_init_user_formats() fails in soc_camera_probe(), we have to call
client's .remove() method to unregister the video device.
Reported-by: Kuninori Morimoto <morimoto.kuninori@renesas.com>
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Priority: high
---
drivers/media/video/soc_camera.c | 10 +++++++---
1 files changed, 7 insertions(+), 3 deletions(-)
Diffstat (limited to 'linux/drivers/media/video/soc_camera.c')
-rw-r--r-- | linux/drivers/media/video/soc_camera.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/linux/drivers/media/video/soc_camera.c b/linux/drivers/media/video/soc_camera.c index 711e14109..4f315c1b7 100644 --- a/linux/drivers/media/video/soc_camera.c +++ b/linux/drivers/media/video/soc_camera.c @@ -878,8 +878,11 @@ static int soc_camera_probe(struct device *dev) (unsigned short)~0; ret = soc_camera_init_user_formats(icd); - if (ret < 0) + if (ret < 0) { + if (icd->ops->remove) + icd->ops->remove(icd); goto eiufmt; + } icd->height = DEFAULT_HEIGHT; icd->width = DEFAULT_WIDTH; @@ -903,8 +906,10 @@ static int soc_camera_remove(struct device *dev) { struct soc_camera_device *icd = to_soc_camera_dev(dev); + mutex_lock(&icd->video_lock); if (icd->ops->remove) icd->ops->remove(icd); + mutex_unlock(&icd->video_lock); soc_camera_free_user_formats(icd); @@ -1146,6 +1151,7 @@ evidallocd: } EXPORT_SYMBOL(soc_camera_video_start); +/* Called from client .remove() methods with .video_lock held */ void soc_camera_video_stop(struct soc_camera_device *icd) { struct video_device *vdev = icd->vdev; @@ -1155,10 +1161,8 @@ void soc_camera_video_stop(struct soc_camera_device *icd) if (!icd->dev.parent || !vdev) return; - mutex_lock(&icd->video_lock); video_unregister_device(vdev); icd->vdev = NULL; - mutex_unlock(&icd->video_lock); } EXPORT_SYMBOL(soc_camera_video_stop); |