Commit a2e10b5a authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

[media] wl128x: remove V4L2_FL_LOCK_ALL_FOPS

Add proper locking to the file operations, allowing for the removal
of the V4L2_FL_LOCK_ALL_FOPS flag.
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 0d0c1596
...@@ -56,23 +56,29 @@ static ssize_t fm_v4l2_fops_read(struct file *file, char __user * buf, ...@@ -56,23 +56,29 @@ static ssize_t fm_v4l2_fops_read(struct file *file, char __user * buf,
return -EIO; return -EIO;
} }
/* Turn on RDS mode , if it is disabled */ if (mutex_lock_interruptible(&fmdev->mutex))
return -ERESTARTSYS;
/* Turn on RDS mode if it is disabled */
ret = fm_rx_get_rds_mode(fmdev, &rds_mode); ret = fm_rx_get_rds_mode(fmdev, &rds_mode);
if (ret < 0) { if (ret < 0) {
fmerr("Unable to read current rds mode\n"); fmerr("Unable to read current rds mode\n");
return ret; goto read_unlock;
} }
if (rds_mode == FM_RDS_DISABLE) { if (rds_mode == FM_RDS_DISABLE) {
ret = fmc_set_rds_mode(fmdev, FM_RDS_ENABLE); ret = fmc_set_rds_mode(fmdev, FM_RDS_ENABLE);
if (ret < 0) { if (ret < 0) {
fmerr("Failed to enable rds mode\n"); fmerr("Failed to enable rds mode\n");
return ret; goto read_unlock;
} }
} }
/* Copy RDS data from internal buffer to user buffer */ /* Copy RDS data from internal buffer to user buffer */
return fmc_transfer_rds_from_internal_buff(fmdev, file, buf, count); ret = fmc_transfer_rds_from_internal_buff(fmdev, file, buf, count);
read_unlock:
mutex_unlock(&fmdev->mutex);
return ret;
} }
/* Write TX RDS data */ /* Write TX RDS data */
...@@ -91,8 +97,11 @@ static ssize_t fm_v4l2_fops_write(struct file *file, const char __user * buf, ...@@ -91,8 +97,11 @@ static ssize_t fm_v4l2_fops_write(struct file *file, const char __user * buf,
return -EFAULT; return -EFAULT;
fmdev = video_drvdata(file); fmdev = video_drvdata(file);
if (mutex_lock_interruptible(&fmdev->mutex))
return -ERESTARTSYS;
fm_tx_set_radio_text(fmdev, rds.text, rds.text_type); fm_tx_set_radio_text(fmdev, rds.text, rds.text_type);
fm_tx_set_af(fmdev, rds.af_freq); fm_tx_set_af(fmdev, rds.af_freq);
mutex_unlock(&fmdev->mutex);
return sizeof(rds); return sizeof(rds);
} }
...@@ -103,7 +112,9 @@ static u32 fm_v4l2_fops_poll(struct file *file, struct poll_table_struct *pts) ...@@ -103,7 +112,9 @@ static u32 fm_v4l2_fops_poll(struct file *file, struct poll_table_struct *pts)
struct fmdev *fmdev; struct fmdev *fmdev;
fmdev = video_drvdata(file); fmdev = video_drvdata(file);
mutex_lock(&fmdev->mutex);
ret = fmc_is_rds_data_available(fmdev, file, pts); ret = fmc_is_rds_data_available(fmdev, file, pts);
mutex_unlock(&fmdev->mutex);
if (ret < 0) if (ret < 0)
return POLLIN | POLLRDNORM; return POLLIN | POLLRDNORM;
...@@ -127,10 +138,12 @@ static int fm_v4l2_fops_open(struct file *file) ...@@ -127,10 +138,12 @@ static int fm_v4l2_fops_open(struct file *file)
fmdev = video_drvdata(file); fmdev = video_drvdata(file);
if (mutex_lock_interruptible(&fmdev->mutex))
return -ERESTARTSYS;
ret = fmc_prepare(fmdev); ret = fmc_prepare(fmdev);
if (ret < 0) { if (ret < 0) {
fmerr("Unable to prepare FM CORE\n"); fmerr("Unable to prepare FM CORE\n");
return ret; goto open_unlock;
} }
fmdbg("Load FM RX firmware..\n"); fmdbg("Load FM RX firmware..\n");
...@@ -138,10 +151,12 @@ static int fm_v4l2_fops_open(struct file *file) ...@@ -138,10 +151,12 @@ static int fm_v4l2_fops_open(struct file *file)
ret = fmc_set_mode(fmdev, FM_MODE_RX); ret = fmc_set_mode(fmdev, FM_MODE_RX);
if (ret < 0) { if (ret < 0) {
fmerr("Unable to load FM RX firmware\n"); fmerr("Unable to load FM RX firmware\n");
return ret; goto open_unlock;
} }
radio_disconnected = 1; radio_disconnected = 1;
open_unlock:
mutex_unlock(&fmdev->mutex);
return ret; return ret;
} }
...@@ -156,19 +171,22 @@ static int fm_v4l2_fops_release(struct file *file) ...@@ -156,19 +171,22 @@ static int fm_v4l2_fops_release(struct file *file)
return 0; return 0;
} }
mutex_lock(&fmdev->mutex);
ret = fmc_set_mode(fmdev, FM_MODE_OFF); ret = fmc_set_mode(fmdev, FM_MODE_OFF);
if (ret < 0) { if (ret < 0) {
fmerr("Unable to turn off the chip\n"); fmerr("Unable to turn off the chip\n");
return ret; goto release_unlock;
} }
ret = fmc_release(fmdev); ret = fmc_release(fmdev);
if (ret < 0) { if (ret < 0) {
fmerr("FM CORE release failed\n"); fmerr("FM CORE release failed\n");
return ret; goto release_unlock;
} }
radio_disconnected = 0; radio_disconnected = 0;
release_unlock:
mutex_unlock(&fmdev->mutex);
return ret; return ret;
} }
...@@ -520,10 +538,6 @@ int fm_v4l2_init_video_device(struct fmdev *fmdev, int radio_nr) ...@@ -520,10 +538,6 @@ int fm_v4l2_init_video_device(struct fmdev *fmdev, int radio_nr)
video_set_drvdata(gradio_dev, fmdev); video_set_drvdata(gradio_dev, fmdev);
gradio_dev->lock = &fmdev->mutex; gradio_dev->lock = &fmdev->mutex;
/* Locking in file operations other than ioctl should be done
by the driver, not the V4L2 core.
This driver needs auditing so that this flag can be removed. */
set_bit(V4L2_FL_LOCK_ALL_FOPS, &gradio_dev->flags);
/* Register with V4L2 subsystem as RADIO device */ /* Register with V4L2 subsystem as RADIO device */
if (video_register_device(gradio_dev, VFL_TYPE_RADIO, radio_nr)) { if (video_register_device(gradio_dev, VFL_TYPE_RADIO, radio_nr)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment