[media] em28xx-v4l: fix the freeing of the video devices memory

Remove some dead code from em28xx_v4l2_fini() and fix the leaking of the video,
vbi and radio video_device struct memories.

Signed-off-by: Frank Schäfer <fschaefer.oss@googlemail.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
This commit is contained in:
Frank Schaefer 2014-01-12 13:24:25 -03:00 committed by Mauro Carvalho Chehab
parent 5a620c7c1c
commit e847022a8e
1 changed files with 30 additions and 26 deletions

View File

@ -1899,29 +1899,19 @@ static int em28xx_v4l2_fini(struct em28xx *dev)
em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE); em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE);
if (dev->radio_dev) { if (dev->radio_dev) {
if (video_is_registered(dev->radio_dev)) em28xx_info("V4L2 device %s deregistered\n",
video_unregister_device(dev->radio_dev); video_device_node_name(dev->radio_dev));
else video_unregister_device(dev->radio_dev);
video_device_release(dev->radio_dev);
dev->radio_dev = NULL;
} }
if (dev->vbi_dev) { if (dev->vbi_dev) {
em28xx_info("V4L2 device %s deregistered\n", em28xx_info("V4L2 device %s deregistered\n",
video_device_node_name(dev->vbi_dev)); video_device_node_name(dev->vbi_dev));
if (video_is_registered(dev->vbi_dev)) video_unregister_device(dev->vbi_dev);
video_unregister_device(dev->vbi_dev);
else
video_device_release(dev->vbi_dev);
dev->vbi_dev = NULL;
} }
if (dev->vdev) { if (dev->vdev) {
em28xx_info("V4L2 device %s deregistered\n", em28xx_info("V4L2 device %s deregistered\n",
video_device_node_name(dev->vdev)); video_device_node_name(dev->vdev));
if (video_is_registered(dev->vdev)) video_unregister_device(dev->vdev);
video_unregister_device(dev->vdev);
else
video_device_release(dev->vdev);
dev->vdev = NULL;
} }
if (dev->clk) { if (dev->clk) {
@ -1955,9 +1945,7 @@ static int em28xx_v4l2_close(struct file *filp)
mutex_lock(&dev->lock); mutex_lock(&dev->lock);
if (dev->users == 1) { if (dev->users == 1) {
/* the device is already disconnect, /* free the remaining resources if device is disconnected */
free the remaining resources */
if (dev->disconnected) { if (dev->disconnected) {
kfree(dev->alt_max_pkt_size_isoc); kfree(dev->alt_max_pkt_size_isoc);
goto exit; goto exit;
@ -1985,6 +1973,23 @@ exit:
return 0; return 0;
} }
/*
* em28xx_videodevice_release()
* called when the last user of the video device exits and frees the memeory
*/
static void em28xx_videodevice_release(struct video_device *vdev)
{
struct em28xx *dev = video_get_drvdata(vdev);
video_device_release(vdev);
if (vdev == dev->vdev)
dev->vdev = NULL;
else if (vdev == dev->vbi_dev)
dev->vbi_dev = NULL;
else if (vdev == dev->radio_dev)
dev->radio_dev = NULL;
}
static const struct v4l2_file_operations em28xx_v4l_fops = { static const struct v4l2_file_operations em28xx_v4l_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.open = em28xx_v4l2_open, .open = em28xx_v4l2_open,
@ -2039,11 +2044,10 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
}; };
static const struct video_device em28xx_video_template = { static const struct video_device em28xx_video_template = {
.fops = &em28xx_v4l_fops, .fops = &em28xx_v4l_fops,
.release = video_device_release_empty, .ioctl_ops = &video_ioctl_ops,
.ioctl_ops = &video_ioctl_ops, .release = em28xx_videodevice_release,
.tvnorms = V4L2_STD_ALL,
.tvnorms = V4L2_STD_ALL,
}; };
static const struct v4l2_file_operations radio_fops = { static const struct v4l2_file_operations radio_fops = {
@ -2069,9 +2073,9 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = {
}; };
static struct video_device em28xx_radio_template = { static struct video_device em28xx_radio_template = {
.name = "em28xx-radio", .fops = &radio_fops,
.fops = &radio_fops, .ioctl_ops = &radio_ioctl_ops,
.ioctl_ops = &radio_ioctl_ops, .release = em28xx_videodevice_release,
}; };
/* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */ /* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */