aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2013-12-14 06:28:27 -0500
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-01-07 04:37:10 -0500
commitce791139ec7f0e5878221dba8d5773e27bf057d3 (patch)
treec8f0054888ed2256cdc798ed736ce66b99017c61
parentb9f63b25954495b5b3089f89918771e52c1605d8 (diff)
[media] saa7134: share resource management between normal and empress nodes
The empress video node can share resource management with the normal video nodes, thus allowing for code sharing and making the empress node non-exclusive. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
-rw-r--r--drivers/media/pci/saa7134/saa7134-empress.c98
-rw-r--r--drivers/media/pci/saa7134/saa7134-video.c43
-rw-r--r--drivers/media/pci/saa7134/saa7134.h22
3 files changed, 62 insertions, 101 deletions
diff --git a/drivers/media/pci/saa7134/saa7134-empress.c b/drivers/media/pci/saa7134/saa7134-empress.c
index 17e5fcdad32a..2ef670d05bda 100644
--- a/drivers/media/pci/saa7134/saa7134-empress.c
+++ b/drivers/media/pci/saa7134/saa7134-empress.c
@@ -86,20 +86,11 @@ static int ts_open(struct file *file)
86 struct video_device *vdev = video_devdata(file); 86 struct video_device *vdev = video_devdata(file);
87 struct saa7134_dev *dev = video_drvdata(file); 87 struct saa7134_dev *dev = video_drvdata(file);
88 struct saa7134_fh *fh; 88 struct saa7134_fh *fh;
89 int err;
90
91 dprintk("open dev=%s\n", video_device_node_name(vdev));
92 err = -EBUSY;
93 if (!mutex_trylock(&dev->empress_tsq.vb_lock))
94 return err;
95 if (atomic_read(&dev->empress_users))
96 goto done;
97 89
98 /* allocate + initialize per filehandle data */ 90 /* allocate + initialize per filehandle data */
99 fh = kzalloc(sizeof(*fh), GFP_KERNEL); 91 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
100 err = -ENOMEM;
101 if (NULL == fh) 92 if (NULL == fh)
102 goto done; 93 return -ENOMEM;
103 94
104 v4l2_fh_init(&fh->fh, vdev); 95 v4l2_fh_init(&fh->fh, vdev);
105 file->private_data = fh; 96 file->private_data = fh;
@@ -110,12 +101,7 @@ static int ts_open(struct file *file)
110 saa_writeb(SAA7134_AUDIO_MUTE_CTRL, 101 saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
111 saa_readb(SAA7134_AUDIO_MUTE_CTRL) & ~(1 << 6)); 102 saa_readb(SAA7134_AUDIO_MUTE_CTRL) & ~(1 << 6));
112 103
113 atomic_inc(&dev->empress_users); 104 return 0;
114 err = 0;
115
116done:
117 mutex_unlock(&dev->empress_tsq.vb_lock);
118 return err;
119} 105}
120 106
121static int ts_release(struct file *file) 107static int ts_release(struct file *file)
@@ -123,17 +109,17 @@ static int ts_release(struct file *file)
123 struct saa7134_dev *dev = video_drvdata(file); 109 struct saa7134_dev *dev = video_drvdata(file);
124 struct saa7134_fh *fh = file->private_data; 110 struct saa7134_fh *fh = file->private_data;
125 111
126 videobuf_stop(&dev->empress_tsq); 112 if (res_check(fh, RESOURCE_EMPRESS)) {
127 videobuf_mmap_free(&dev->empress_tsq); 113 videobuf_stop(&dev->empress_tsq);
114 videobuf_mmap_free(&dev->empress_tsq);
128 115
129 /* stop the encoder */ 116 /* stop the encoder */
130 ts_reset_encoder(dev); 117 ts_reset_encoder(dev);
131 118
132 /* Mute audio */ 119 /* Mute audio */
133 saa_writeb(SAA7134_AUDIO_MUTE_CTRL, 120 saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
134 saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6)); 121 saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6));
135 122 }
136 atomic_dec(&dev->empress_users);
137 123
138 v4l2_fh_del(&fh->fh); 124 v4l2_fh_del(&fh->fh);
139 v4l2_fh_exit(&fh->fh); 125 v4l2_fh_exit(&fh->fh);
@@ -145,6 +131,8 @@ ts_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
145{ 131{
146 struct saa7134_dev *dev = video_drvdata(file); 132 struct saa7134_dev *dev = video_drvdata(file);
147 133
134 if (res_locked(dev, RESOURCE_EMPRESS))
135 return -EBUSY;
148 if (!dev->empress_started) 136 if (!dev->empress_started)
149 ts_init_encoder(dev); 137 ts_init_encoder(dev);
150 138
@@ -235,53 +223,6 @@ static int empress_try_fmt_vid_cap(struct file *file, void *priv,
235 return 0; 223 return 0;
236} 224}
237 225
238static int empress_reqbufs(struct file *file, void *priv,
239 struct v4l2_requestbuffers *p)
240{
241 struct saa7134_dev *dev = video_drvdata(file);
242
243 return videobuf_reqbufs(&dev->empress_tsq, p);
244}
245
246static int empress_querybuf(struct file *file, void *priv,
247 struct v4l2_buffer *b)
248{
249 struct saa7134_dev *dev = video_drvdata(file);
250
251 return videobuf_querybuf(&dev->empress_tsq, b);
252}
253
254static int empress_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
255{
256 struct saa7134_dev *dev = video_drvdata(file);
257
258 return videobuf_qbuf(&dev->empress_tsq, b);
259}
260
261static int empress_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
262{
263 struct saa7134_dev *dev = video_drvdata(file);
264
265 return videobuf_dqbuf(&dev->empress_tsq, b,
266 file->f_flags & O_NONBLOCK);
267}
268
269static int empress_streamon(struct file *file, void *priv,
270 enum v4l2_buf_type type)
271{
272 struct saa7134_dev *dev = video_drvdata(file);
273
274 return videobuf_streamon(&dev->empress_tsq);
275}
276
277static int empress_streamoff(struct file *file, void *priv,
278 enum v4l2_buf_type type)
279{
280 struct saa7134_dev *dev = video_drvdata(file);
281
282 return videobuf_streamoff(&dev->empress_tsq);
283}
284
285static const struct v4l2_file_operations ts_fops = 226static const struct v4l2_file_operations ts_fops =
286{ 227{
287 .owner = THIS_MODULE, 228 .owner = THIS_MODULE,
@@ -299,12 +240,12 @@ static const struct v4l2_ioctl_ops ts_ioctl_ops = {
299 .vidioc_try_fmt_vid_cap = empress_try_fmt_vid_cap, 240 .vidioc_try_fmt_vid_cap = empress_try_fmt_vid_cap,
300 .vidioc_s_fmt_vid_cap = empress_s_fmt_vid_cap, 241 .vidioc_s_fmt_vid_cap = empress_s_fmt_vid_cap,
301 .vidioc_g_fmt_vid_cap = empress_g_fmt_vid_cap, 242 .vidioc_g_fmt_vid_cap = empress_g_fmt_vid_cap,
302 .vidioc_reqbufs = empress_reqbufs, 243 .vidioc_reqbufs = saa7134_reqbufs,
303 .vidioc_querybuf = empress_querybuf, 244 .vidioc_querybuf = saa7134_querybuf,
304 .vidioc_qbuf = empress_qbuf, 245 .vidioc_qbuf = saa7134_qbuf,
305 .vidioc_dqbuf = empress_dqbuf, 246 .vidioc_dqbuf = saa7134_dqbuf,
306 .vidioc_streamon = empress_streamon, 247 .vidioc_streamon = saa7134_streamon,
307 .vidioc_streamoff = empress_streamoff, 248 .vidioc_streamoff = saa7134_streamoff,
308 .vidioc_g_frequency = saa7134_g_frequency, 249 .vidioc_g_frequency = saa7134_g_frequency,
309 .vidioc_s_frequency = saa7134_s_frequency, 250 .vidioc_s_frequency = saa7134_s_frequency,
310 .vidioc_g_tuner = saa7134_g_tuner, 251 .vidioc_g_tuner = saa7134_g_tuner,
@@ -375,6 +316,7 @@ static int empress_init(struct saa7134_dev *dev)
375 snprintf(dev->empress_dev->name, sizeof(dev->empress_dev->name), 316 snprintf(dev->empress_dev->name, sizeof(dev->empress_dev->name),
376 "%s empress (%s)", dev->name, 317 "%s empress (%s)", dev->name,
377 saa7134_boards[dev->board].name); 318 saa7134_boards[dev->board].name);
319 set_bit(V4L2_FL_USE_FH_PRIO, &dev->empress_dev->flags);
378 v4l2_ctrl_handler_init(hdl, 21); 320 v4l2_ctrl_handler_init(hdl, 21);
379 v4l2_ctrl_add_handler(hdl, &dev->ctrl_handler, empress_ctrl_filter); 321 v4l2_ctrl_add_handler(hdl, &dev->ctrl_handler, empress_ctrl_filter);
380 if (dev->empress_sd) 322 if (dev->empress_sd)
diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c
index 7ba42e2e5a18..5e2d61c1cf3d 100644
--- a/drivers/media/pci/saa7134/saa7134-video.c
+++ b/drivers/media/pci/saa7134/saa7134-video.c
@@ -403,16 +403,6 @@ static int res_get(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int
403 return 1; 403 return 1;
404} 404}
405 405
406static int res_check(struct saa7134_fh *fh, unsigned int bit)
407{
408 return (fh->resources & bit);
409}
410
411static int res_locked(struct saa7134_dev *dev, unsigned int bit)
412{
413 return (dev->resources & bit);
414}
415
416static 406static
417void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bits) 407void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bits)
418{ 408{
@@ -1091,11 +1081,12 @@ static struct videobuf_queue *saa7134_queue(struct file *file)
1091{ 1081{
1092 struct video_device *vdev = video_devdata(file); 1082 struct video_device *vdev = video_devdata(file);
1093 struct saa7134_dev *dev = video_drvdata(file); 1083 struct saa7134_dev *dev = video_drvdata(file);
1084 struct saa7134_fh *fh = file->private_data;
1094 struct videobuf_queue *q = NULL; 1085 struct videobuf_queue *q = NULL;
1095 1086
1096 switch (vdev->vfl_type) { 1087 switch (vdev->vfl_type) {
1097 case VFL_TYPE_GRABBER: 1088 case VFL_TYPE_GRABBER:
1098 q = &dev->cap; 1089 q = fh->is_empress ? &dev->empress_tsq : &dev->cap;
1099 break; 1090 break;
1100 case VFL_TYPE_VBI: 1091 case VFL_TYPE_VBI:
1101 q = &dev->vbi; 1092 q = &dev->vbi;
@@ -1109,9 +1100,10 @@ static struct videobuf_queue *saa7134_queue(struct file *file)
1109static int saa7134_resource(struct file *file) 1100static int saa7134_resource(struct file *file)
1110{ 1101{
1111 struct video_device *vdev = video_devdata(file); 1102 struct video_device *vdev = video_devdata(file);
1103 struct saa7134_fh *fh = file->private_data;
1112 1104
1113 if (vdev->vfl_type == VFL_TYPE_GRABBER) 1105 if (vdev->vfl_type == VFL_TYPE_GRABBER)
1114 return RESOURCE_VIDEO; 1106 return fh->is_empress ? RESOURCE_EMPRESS : RESOURCE_VIDEO;
1115 1107
1116 if (vdev->vfl_type == VFL_TYPE_VBI) 1108 if (vdev->vfl_type == VFL_TYPE_VBI)
1117 return RESOURCE_VBI; 1109 return RESOURCE_VBI;
@@ -1935,30 +1927,34 @@ static int saa7134_overlay(struct file *file, void *priv, unsigned int on)
1935 return 0; 1927 return 0;
1936} 1928}
1937 1929
1938static int saa7134_reqbufs(struct file *file, void *priv, 1930int saa7134_reqbufs(struct file *file, void *priv,
1939 struct v4l2_requestbuffers *p) 1931 struct v4l2_requestbuffers *p)
1940{ 1932{
1941 return videobuf_reqbufs(saa7134_queue(file), p); 1933 return videobuf_reqbufs(saa7134_queue(file), p);
1942} 1934}
1935EXPORT_SYMBOL_GPL(saa7134_reqbufs);
1943 1936
1944static int saa7134_querybuf(struct file *file, void *priv, 1937int saa7134_querybuf(struct file *file, void *priv,
1945 struct v4l2_buffer *b) 1938 struct v4l2_buffer *b)
1946{ 1939{
1947 return videobuf_querybuf(saa7134_queue(file), b); 1940 return videobuf_querybuf(saa7134_queue(file), b);
1948} 1941}
1942EXPORT_SYMBOL_GPL(saa7134_querybuf);
1949 1943
1950static int saa7134_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) 1944int saa7134_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
1951{ 1945{
1952 return videobuf_qbuf(saa7134_queue(file), b); 1946 return videobuf_qbuf(saa7134_queue(file), b);
1953} 1947}
1948EXPORT_SYMBOL_GPL(saa7134_qbuf);
1954 1949
1955static int saa7134_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) 1950int saa7134_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
1956{ 1951{
1957 return videobuf_dqbuf(saa7134_queue(file), b, 1952 return videobuf_dqbuf(saa7134_queue(file), b,
1958 file->f_flags & O_NONBLOCK); 1953 file->f_flags & O_NONBLOCK);
1959} 1954}
1955EXPORT_SYMBOL_GPL(saa7134_dqbuf);
1960 1956
1961static int saa7134_streamon(struct file *file, void *priv, 1957int saa7134_streamon(struct file *file, void *priv,
1962 enum v4l2_buf_type type) 1958 enum v4l2_buf_type type)
1963{ 1959{
1964 struct saa7134_dev *dev = video_drvdata(file); 1960 struct saa7134_dev *dev = video_drvdata(file);
@@ -1974,21 +1970,23 @@ static int saa7134_streamon(struct file *file, void *priv,
1974 * Unfortunately, I lack register-level documentation to check the 1970 * Unfortunately, I lack register-level documentation to check the
1975 * Linux FIFO setup and confirm the perfect value. 1971 * Linux FIFO setup and confirm the perfect value.
1976 */ 1972 */
1977 pm_qos_add_request(&dev->qos_request, 1973 if (res != RESOURCE_EMPRESS)
1978 PM_QOS_CPU_DMA_LATENCY, 1974 pm_qos_add_request(&dev->qos_request,
1979 20); 1975 PM_QOS_CPU_DMA_LATENCY, 20);
1980 1976
1981 return videobuf_streamon(saa7134_queue(file)); 1977 return videobuf_streamon(saa7134_queue(file));
1982} 1978}
1979EXPORT_SYMBOL_GPL(saa7134_streamon);
1983 1980
1984static int saa7134_streamoff(struct file *file, void *priv, 1981int saa7134_streamoff(struct file *file, void *priv,
1985 enum v4l2_buf_type type) 1982 enum v4l2_buf_type type)
1986{ 1983{
1987 struct saa7134_dev *dev = video_drvdata(file); 1984 struct saa7134_dev *dev = video_drvdata(file);
1988 int err; 1985 int err;
1989 int res = saa7134_resource(file); 1986 int res = saa7134_resource(file);
1990 1987
1991 pm_qos_remove_request(&dev->qos_request); 1988 if (res != RESOURCE_EMPRESS)
1989 pm_qos_remove_request(&dev->qos_request);
1992 1990
1993 err = videobuf_streamoff(saa7134_queue(file)); 1991 err = videobuf_streamoff(saa7134_queue(file));
1994 if (err < 0) 1992 if (err < 0)
@@ -1996,6 +1994,7 @@ static int saa7134_streamoff(struct file *file, void *priv,
1996 res_free(dev, priv, res); 1994 res_free(dev, priv, res);
1997 return 0; 1995 return 0;
1998} 1996}
1997EXPORT_SYMBOL_GPL(saa7134_streamoff);
1999 1998
2000#ifdef CONFIG_VIDEO_ADV_DEBUG 1999#ifdef CONFIG_VIDEO_ADV_DEBUG
2001static int vidioc_g_register (struct file *file, void *priv, 2000static int vidioc_g_register (struct file *file, void *priv,
diff --git a/drivers/media/pci/saa7134/saa7134.h b/drivers/media/pci/saa7134/saa7134.h
index d7bef5e292b4..2474e848f2c0 100644
--- a/drivers/media/pci/saa7134/saa7134.h
+++ b/drivers/media/pci/saa7134/saa7134.h
@@ -422,6 +422,7 @@ struct saa7134_board {
422#define RESOURCE_OVERLAY 1 422#define RESOURCE_OVERLAY 1
423#define RESOURCE_VIDEO 2 423#define RESOURCE_VIDEO 2
424#define RESOURCE_VBI 4 424#define RESOURCE_VBI 4
425#define RESOURCE_EMPRESS 8
425 426
426#define INTERLACE_AUTO 0 427#define INTERLACE_AUTO 0
427#define INTERLACE_ON 1 428#define INTERLACE_ON 1
@@ -644,7 +645,6 @@ struct saa7134_dev {
644 struct video_device *empress_dev; 645 struct video_device *empress_dev;
645 struct v4l2_subdev *empress_sd; 646 struct v4l2_subdev *empress_sd;
646 struct videobuf_queue empress_tsq; 647 struct videobuf_queue empress_tsq;
647 atomic_t empress_users;
648 struct work_struct empress_workqueue; 648 struct work_struct empress_workqueue;
649 int empress_started; 649 int empress_started;
650 struct v4l2_ctrl_handler empress_ctrl_handler; 650 struct v4l2_ctrl_handler empress_ctrl_handler;
@@ -705,6 +705,16 @@ struct saa7134_dev {
705 _rc; \ 705 _rc; \
706}) 706})
707 707
708static inline int res_check(struct saa7134_fh *fh, unsigned int bit)
709{
710 return fh->resources & bit;
711}
712
713static inline int res_locked(struct saa7134_dev *dev, unsigned int bit)
714{
715 return dev->resources & bit;
716}
717
708/* ----------------------------------------------------------- */ 718/* ----------------------------------------------------------- */
709/* saa7134-core.c */ 719/* saa7134-core.c */
710 720
@@ -782,6 +792,16 @@ int saa7134_g_frequency(struct file *file, void *priv,
782 struct v4l2_frequency *f); 792 struct v4l2_frequency *f);
783int saa7134_s_frequency(struct file *file, void *priv, 793int saa7134_s_frequency(struct file *file, void *priv,
784 const struct v4l2_frequency *f); 794 const struct v4l2_frequency *f);
795int saa7134_reqbufs(struct file *file, void *priv,
796 struct v4l2_requestbuffers *p);
797int saa7134_querybuf(struct file *file, void *priv,
798 struct v4l2_buffer *b);
799int saa7134_qbuf(struct file *file, void *priv, struct v4l2_buffer *b);
800int saa7134_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b);
801int saa7134_streamon(struct file *file, void *priv,
802 enum v4l2_buf_type type);
803int saa7134_streamoff(struct file *file, void *priv,
804 enum v4l2_buf_type type);
785 805
786int saa7134_videoport_init(struct saa7134_dev *dev); 806int saa7134_videoport_init(struct saa7134_dev *dev);
787void saa7134_set_tvnorm_hw(struct saa7134_dev *dev); 807void saa7134_set_tvnorm_hw(struct saa7134_dev *dev);