diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2012-06-24 05:33:26 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-09 19:10:10 -0400 |
commit | f135a8a224294fa0f60ec1b8bc120813b7cfc804 (patch) | |
tree | 872a34c0373a0a3ccecf4afa84368961259ee1b7 /drivers | |
parent | 954f5bcb390c8d8a7357fe4f5e0ba264058574fb (diff) |
[media] sh_vou: 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: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/sh_vou.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/drivers/media/video/sh_vou.c b/drivers/media/video/sh_vou.c index 8fd1874382c6..9f62fd89ab57 100644 --- a/drivers/media/video/sh_vou.c +++ b/drivers/media/video/sh_vou.c | |||
@@ -1171,6 +1171,8 @@ static int sh_vou_open(struct file *file) | |||
1171 | 1171 | ||
1172 | file->private_data = vou_file; | 1172 | file->private_data = vou_file; |
1173 | 1173 | ||
1174 | if (mutex_lock_interruptible(&vou_dev->fop_lock)) | ||
1175 | return -ERESTARTSYS; | ||
1174 | if (atomic_inc_return(&vou_dev->use_count) == 1) { | 1176 | if (atomic_inc_return(&vou_dev->use_count) == 1) { |
1175 | int ret; | 1177 | int ret; |
1176 | /* First open */ | 1178 | /* First open */ |
@@ -1181,6 +1183,7 @@ static int sh_vou_open(struct file *file) | |||
1181 | atomic_dec(&vou_dev->use_count); | 1183 | atomic_dec(&vou_dev->use_count); |
1182 | pm_runtime_put(vdev->v4l2_dev->dev); | 1184 | pm_runtime_put(vdev->v4l2_dev->dev); |
1183 | vou_dev->status = SH_VOU_IDLE; | 1185 | vou_dev->status = SH_VOU_IDLE; |
1186 | mutex_unlock(&vou_dev->fop_lock); | ||
1184 | return ret; | 1187 | return ret; |
1185 | } | 1188 | } |
1186 | } | 1189 | } |
@@ -1191,6 +1194,7 @@ static int sh_vou_open(struct file *file) | |||
1191 | V4L2_FIELD_NONE, | 1194 | V4L2_FIELD_NONE, |
1192 | sizeof(struct videobuf_buffer), vdev, | 1195 | sizeof(struct videobuf_buffer), vdev, |
1193 | &vou_dev->fop_lock); | 1196 | &vou_dev->fop_lock); |
1197 | mutex_unlock(&vou_dev->fop_lock); | ||
1194 | 1198 | ||
1195 | return 0; | 1199 | return 0; |
1196 | } | 1200 | } |
@@ -1204,10 +1208,12 @@ static int sh_vou_release(struct file *file) | |||
1204 | dev_dbg(vou_file->vbq.dev, "%s()\n", __func__); | 1208 | dev_dbg(vou_file->vbq.dev, "%s()\n", __func__); |
1205 | 1209 | ||
1206 | if (!atomic_dec_return(&vou_dev->use_count)) { | 1210 | if (!atomic_dec_return(&vou_dev->use_count)) { |
1211 | mutex_lock(&vou_dev->fop_lock); | ||
1207 | /* Last close */ | 1212 | /* Last close */ |
1208 | vou_dev->status = SH_VOU_IDLE; | 1213 | vou_dev->status = SH_VOU_IDLE; |
1209 | sh_vou_reg_a_set(vou_dev, VOUER, 0, 0x101); | 1214 | sh_vou_reg_a_set(vou_dev, VOUER, 0, 0x101); |
1210 | pm_runtime_put(vdev->v4l2_dev->dev); | 1215 | pm_runtime_put(vdev->v4l2_dev->dev); |
1216 | mutex_unlock(&vou_dev->fop_lock); | ||
1211 | } | 1217 | } |
1212 | 1218 | ||
1213 | file->private_data = NULL; | 1219 | file->private_data = NULL; |
@@ -1218,20 +1224,31 @@ static int sh_vou_release(struct file *file) | |||
1218 | 1224 | ||
1219 | static int sh_vou_mmap(struct file *file, struct vm_area_struct *vma) | 1225 | static int sh_vou_mmap(struct file *file, struct vm_area_struct *vma) |
1220 | { | 1226 | { |
1227 | struct sh_vou_device *vou_dev = video_get_drvdata(vdev); | ||
1221 | struct sh_vou_file *vou_file = file->private_data; | 1228 | struct sh_vou_file *vou_file = file->private_data; |
1229 | int ret; | ||
1222 | 1230 | ||
1223 | dev_dbg(vou_file->vbq.dev, "%s()\n", __func__); | 1231 | dev_dbg(vou_file->vbq.dev, "%s()\n", __func__); |
1224 | 1232 | ||
1225 | return videobuf_mmap_mapper(&vou_file->vbq, vma); | 1233 | if (mutex_lock_interruptible(&vou_dev->fop_lock)) |
1234 | return -ERESTARTSYS; | ||
1235 | ret = videobuf_mmap_mapper(&vou_file->vbq, vma); | ||
1236 | mutex_unlock(&vou_dev->fop_lock); | ||
1237 | return ret; | ||
1226 | } | 1238 | } |
1227 | 1239 | ||
1228 | static unsigned int sh_vou_poll(struct file *file, poll_table *wait) | 1240 | static unsigned int sh_vou_poll(struct file *file, poll_table *wait) |
1229 | { | 1241 | { |
1242 | struct sh_vou_device *vou_dev = video_get_drvdata(vdev); | ||
1230 | struct sh_vou_file *vou_file = file->private_data; | 1243 | struct sh_vou_file *vou_file = file->private_data; |
1244 | unsigned int res; | ||
1231 | 1245 | ||
1232 | dev_dbg(vou_file->vbq.dev, "%s()\n", __func__); | 1246 | dev_dbg(vou_file->vbq.dev, "%s()\n", __func__); |
1233 | 1247 | ||
1234 | return videobuf_poll_stream(file, &vou_file->vbq, wait); | 1248 | mutex_lock(&vou_dev->fop_lock); |
1249 | res = videobuf_poll_stream(file, &vou_file->vbq, wait); | ||
1250 | mutex_unlock(&vou_dev->fop_lock); | ||
1251 | return res; | ||
1235 | } | 1252 | } |
1236 | 1253 | ||
1237 | static int sh_vou_g_chip_ident(struct file *file, void *fh, | 1254 | static int sh_vou_g_chip_ident(struct file *file, void *fh, |
@@ -1390,10 +1407,6 @@ static int __devinit sh_vou_probe(struct platform_device *pdev) | |||
1390 | vdev->v4l2_dev = &vou_dev->v4l2_dev; | 1407 | vdev->v4l2_dev = &vou_dev->v4l2_dev; |
1391 | vdev->release = video_device_release; | 1408 | vdev->release = video_device_release; |
1392 | vdev->lock = &vou_dev->fop_lock; | 1409 | vdev->lock = &vou_dev->fop_lock; |
1393 | /* Locking in file operations other than ioctl should be done | ||
1394 | by the driver, not the V4L2 core. | ||
1395 | This driver needs auditing so that this flag can be removed. */ | ||
1396 | set_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags); | ||
1397 | 1410 | ||
1398 | vou_dev->vdev = vdev; | 1411 | vou_dev->vdev = vdev; |
1399 | video_set_drvdata(vdev, vou_dev); | 1412 | video_set_drvdata(vdev, vou_dev); |