aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx18
diff options
context:
space:
mode:
authorAndy Walls <awalls@md.metrocast.net>2010-12-11 18:38:20 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-12-29 05:17:10 -0500
commit754f9969c323559a12bce1475f3c1e6574129856 (patch)
tree3345067e0920d27112b1449152d83e291fd348b3 /drivers/media/video/cx18
parentfa98447f09641adeeaf02b94133649f03b74d159 (diff)
[media] cx18: Only allocate a struct cx18_dvb for the DVB TS stream
The cx18_stream struct contained a struct cx18_dvb for every stream object, most of which were for analog capture. Now we only allocate the cx18_dvb object for the DTV TS stream. Signed-off-by: Andy Walls <awalls@md.metrocast.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx18')
-rw-r--r--drivers/media/video/cx18/cx18-driver.h9
-rw-r--r--drivers/media/video/cx18/cx18-dvb.c32
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c6
-rw-r--r--drivers/media/video/cx18/cx18-streams.c45
-rw-r--r--drivers/media/video/cx18/cx18-streams.h3
5 files changed, 60 insertions, 35 deletions
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index cf4f20e91858..f6f3e50d4bdf 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -325,7 +325,10 @@ struct cx18_queue {
325 spinlock_t lock; 325 spinlock_t lock;
326}; 326};
327 327
328struct cx18_stream; /* forward reference */
329
328struct cx18_dvb { 330struct cx18_dvb {
331 struct cx18_stream *stream;
329 struct dmx_frontend hw_frontend; 332 struct dmx_frontend hw_frontend;
330 struct dmx_frontend mem_frontend; 333 struct dmx_frontend mem_frontend;
331 struct dmxdev dmxdev; 334 struct dmxdev dmxdev;
@@ -365,9 +368,10 @@ struct cx18_in_work_order {
365#define CX18_INVALID_TASK_HANDLE 0xffffffff 368#define CX18_INVALID_TASK_HANDLE 0xffffffff
366 369
367struct cx18_stream { 370struct cx18_stream {
368 /* These first four fields are always set, even if the stream 371 /* These first five fields are always set, even if the stream
369 is not actually created. */ 372 is not actually created. */
370 struct video_device *video_dev; /* NULL when stream not created */ 373 struct video_device *video_dev; /* NULL when stream not created */
374 struct cx18_dvb *dvb; /* DVB / Digital Transport */
371 struct cx18 *cx; /* for ease of use */ 375 struct cx18 *cx; /* for ease of use */
372 const char *name; /* name of the stream */ 376 const char *name; /* name of the stream */
373 int type; /* stream type */ 377 int type; /* stream type */
@@ -397,9 +401,6 @@ struct cx18_stream {
397 struct cx18_queue q_idle; /* idle - not in rotation */ 401 struct cx18_queue q_idle; /* idle - not in rotation */
398 402
399 struct work_struct out_work_order; 403 struct work_struct out_work_order;
400
401 /* DVB / Digital Transport */
402 struct cx18_dvb dvb;
403}; 404};
404 405
405struct cx18_open_id { 406struct cx18_open_id {
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
index c7f0bad39ad0..f0381d62518d 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -137,7 +137,7 @@ static int yuan_mpc718_mt352_init(struct dvb_frontend *fe)
137{ 137{
138 struct cx18_dvb *dvb = container_of(fe->dvb, 138 struct cx18_dvb *dvb = container_of(fe->dvb,
139 struct cx18_dvb, dvb_adapter); 139 struct cx18_dvb, dvb_adapter);
140 struct cx18_stream *stream = container_of(dvb, struct cx18_stream, dvb); 140 struct cx18_stream *stream = dvb->stream;
141 const struct firmware *fw = NULL; 141 const struct firmware *fw = NULL;
142 int ret; 142 int ret;
143 int i; 143 int i;
@@ -266,22 +266,22 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
266 if (!demux->dmx.frontend) 266 if (!demux->dmx.frontend)
267 return -EINVAL; 267 return -EINVAL;
268 268
269 mutex_lock(&stream->dvb.feedlock); 269 mutex_lock(&stream->dvb->feedlock);
270 if (stream->dvb.feeding++ == 0) { 270 if (stream->dvb->feeding++ == 0) {
271 CX18_DEBUG_INFO("Starting Transport DMA\n"); 271 CX18_DEBUG_INFO("Starting Transport DMA\n");
272 mutex_lock(&cx->serialize_lock); 272 mutex_lock(&cx->serialize_lock);
273 set_bit(CX18_F_S_STREAMING, &stream->s_flags); 273 set_bit(CX18_F_S_STREAMING, &stream->s_flags);
274 ret = cx18_start_v4l2_encode_stream(stream); 274 ret = cx18_start_v4l2_encode_stream(stream);
275 if (ret < 0) { 275 if (ret < 0) {
276 CX18_DEBUG_INFO("Failed to start Transport DMA\n"); 276 CX18_DEBUG_INFO("Failed to start Transport DMA\n");
277 stream->dvb.feeding--; 277 stream->dvb->feeding--;
278 if (stream->dvb.feeding == 0) 278 if (stream->dvb->feeding == 0)
279 clear_bit(CX18_F_S_STREAMING, &stream->s_flags); 279 clear_bit(CX18_F_S_STREAMING, &stream->s_flags);
280 } 280 }
281 mutex_unlock(&cx->serialize_lock); 281 mutex_unlock(&cx->serialize_lock);
282 } else 282 } else
283 ret = 0; 283 ret = 0;
284 mutex_unlock(&stream->dvb.feedlock); 284 mutex_unlock(&stream->dvb->feedlock);
285 285
286 return ret; 286 return ret;
287} 287}
@@ -299,15 +299,15 @@ static int cx18_dvb_stop_feed(struct dvb_demux_feed *feed)
299 CX18_DEBUG_INFO("Stop feed: pid = 0x%x index = %d\n", 299 CX18_DEBUG_INFO("Stop feed: pid = 0x%x index = %d\n",
300 feed->pid, feed->index); 300 feed->pid, feed->index);
301 301
302 mutex_lock(&stream->dvb.feedlock); 302 mutex_lock(&stream->dvb->feedlock);
303 if (--stream->dvb.feeding == 0) { 303 if (--stream->dvb->feeding == 0) {
304 CX18_DEBUG_INFO("Stopping Transport DMA\n"); 304 CX18_DEBUG_INFO("Stopping Transport DMA\n");
305 mutex_lock(&cx->serialize_lock); 305 mutex_lock(&cx->serialize_lock);
306 ret = cx18_stop_v4l2_encode_stream(stream, 0); 306 ret = cx18_stop_v4l2_encode_stream(stream, 0);
307 mutex_unlock(&cx->serialize_lock); 307 mutex_unlock(&cx->serialize_lock);
308 } else 308 } else
309 ret = 0; 309 ret = 0;
310 mutex_unlock(&stream->dvb.feedlock); 310 mutex_unlock(&stream->dvb->feedlock);
311 } 311 }
312 312
313 return ret; 313 return ret;
@@ -316,7 +316,7 @@ static int cx18_dvb_stop_feed(struct dvb_demux_feed *feed)
316int cx18_dvb_register(struct cx18_stream *stream) 316int cx18_dvb_register(struct cx18_stream *stream)
317{ 317{
318 struct cx18 *cx = stream->cx; 318 struct cx18 *cx = stream->cx;
319 struct cx18_dvb *dvb = &stream->dvb; 319 struct cx18_dvb *dvb = stream->dvb;
320 struct dvb_adapter *dvb_adapter; 320 struct dvb_adapter *dvb_adapter;
321 struct dvb_demux *dvbdemux; 321 struct dvb_demux *dvbdemux;
322 struct dmx_demux *dmx; 322 struct dmx_demux *dmx;
@@ -325,6 +325,9 @@ int cx18_dvb_register(struct cx18_stream *stream)
325 if (!dvb) 325 if (!dvb)
326 return -EINVAL; 326 return -EINVAL;
327 327
328 dvb->enabled = 0;
329 dvb->stream = stream;
330
328 ret = dvb_register_adapter(&dvb->dvb_adapter, 331 ret = dvb_register_adapter(&dvb->dvb_adapter,
329 CX18_DRIVER_NAME, 332 CX18_DRIVER_NAME,
330 THIS_MODULE, &cx->pci_dev->dev, adapter_nr); 333 THIS_MODULE, &cx->pci_dev->dev, adapter_nr);
@@ -378,7 +381,7 @@ int cx18_dvb_register(struct cx18_stream *stream)
378 381
379 CX18_INFO("DVB Frontend registered\n"); 382 CX18_INFO("DVB Frontend registered\n");
380 CX18_INFO("Registered DVB adapter%d for %s (%d x %d.%02d kB)\n", 383 CX18_INFO("Registered DVB adapter%d for %s (%d x %d.%02d kB)\n",
381 stream->dvb.dvb_adapter.num, stream->name, 384 stream->dvb->dvb_adapter.num, stream->name,
382 stream->buffers, stream->buf_size/1024, 385 stream->buffers, stream->buf_size/1024,
383 (stream->buf_size * 100 / 1024) % 100); 386 (stream->buf_size * 100 / 1024) % 100);
384 387
@@ -405,13 +408,16 @@ err_out:
405void cx18_dvb_unregister(struct cx18_stream *stream) 408void cx18_dvb_unregister(struct cx18_stream *stream)
406{ 409{
407 struct cx18 *cx = stream->cx; 410 struct cx18 *cx = stream->cx;
408 struct cx18_dvb *dvb = &stream->dvb; 411 struct cx18_dvb *dvb = stream->dvb;
409 struct dvb_adapter *dvb_adapter; 412 struct dvb_adapter *dvb_adapter;
410 struct dvb_demux *dvbdemux; 413 struct dvb_demux *dvbdemux;
411 struct dmx_demux *dmx; 414 struct dmx_demux *dmx;
412 415
413 CX18_INFO("unregister DVB\n"); 416 CX18_INFO("unregister DVB\n");
414 417
418 if (dvb == NULL || !dvb->enabled)
419 return;
420
415 dvb_adapter = &dvb->dvb_adapter; 421 dvb_adapter = &dvb->dvb_adapter;
416 dvbdemux = &dvb->demux; 422 dvbdemux = &dvb->demux;
417 dmx = &dvbdemux->dmx; 423 dmx = &dvbdemux->dmx;
@@ -432,7 +438,7 @@ void cx18_dvb_unregister(struct cx18_stream *stream)
432 */ 438 */
433static int dvb_register(struct cx18_stream *stream) 439static int dvb_register(struct cx18_stream *stream)
434{ 440{
435 struct cx18_dvb *dvb = &stream->dvb; 441 struct cx18_dvb *dvb = stream->dvb;
436 struct cx18 *cx = stream->cx; 442 struct cx18 *cx = stream->cx;
437 int ret = 0; 443 int ret = 0;
438 444
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index 956aa190ecca..c545f3beef78 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -136,7 +136,7 @@ static void cx18_mdl_send_to_dvb(struct cx18_stream *s, struct cx18_mdl *mdl)
136{ 136{
137 struct cx18_buffer *buf; 137 struct cx18_buffer *buf;
138 138
139 if (!s->dvb.enabled || mdl->bytesused == 0) 139 if (s->dvb == NULL || !s->dvb->enabled || mdl->bytesused == 0)
140 return; 140 return;
141 141
142 /* We ignore mdl and buf readpos accounting here - it doesn't matter */ 142 /* We ignore mdl and buf readpos accounting here - it doesn't matter */
@@ -146,7 +146,7 @@ static void cx18_mdl_send_to_dvb(struct cx18_stream *s, struct cx18_mdl *mdl)
146 buf = list_first_entry(&mdl->buf_list, struct cx18_buffer, 146 buf = list_first_entry(&mdl->buf_list, struct cx18_buffer,
147 list); 147 list);
148 if (buf->bytesused) 148 if (buf->bytesused)
149 dvb_dmx_swfilter(&s->dvb.demux, 149 dvb_dmx_swfilter(&s->dvb->demux,
150 buf->buf, buf->bytesused); 150 buf->buf, buf->bytesused);
151 return; 151 return;
152 } 152 }
@@ -154,7 +154,7 @@ static void cx18_mdl_send_to_dvb(struct cx18_stream *s, struct cx18_mdl *mdl)
154 list_for_each_entry(buf, &mdl->buf_list, list) { 154 list_for_each_entry(buf, &mdl->buf_list, list) {
155 if (buf->bytesused == 0) 155 if (buf->bytesused == 0)
156 break; 156 break;
157 dvb_dmx_swfilter(&s->dvb.demux, buf->buf, buf->bytesused); 157 dvb_dmx_swfilter(&s->dvb->demux, buf->buf, buf->bytesused);
158 } 158 }
159} 159}
160 160
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index ab461e27d9dd..94f5d7967c5c 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -107,6 +107,7 @@ static void cx18_stream_init(struct cx18 *cx, int type)
107 s->video_dev = video_dev; 107 s->video_dev = video_dev;
108 108
109 /* initialize cx18_stream fields */ 109 /* initialize cx18_stream fields */
110 s->dvb = NULL;
110 s->cx = cx; 111 s->cx = cx;
111 s->type = type; 112 s->type = type;
112 s->name = cx18_stream_info[type].name; 113 s->name = cx18_stream_info[type].name;
@@ -140,10 +141,15 @@ static int cx18_prep_dev(struct cx18 *cx, int type)
140 int num_offset = cx18_stream_info[type].num_offset; 141 int num_offset = cx18_stream_info[type].num_offset;
141 int num = cx->instance + cx18_first_minor + num_offset; 142 int num = cx->instance + cx18_first_minor + num_offset;
142 143
143 /* These four fields are always initialized. If video_dev == NULL, then 144 /*
144 this stream is not in use. In that case no other fields but these 145 * These five fields are always initialized.
145 four can be used. */ 146 * For analog capture related streams, if video_dev == NULL then the
147 * stream is not in use.
148 * For the TS stream, if dvb == NULL then the stream is not in use.
149 * In those cases no other fields but these four can be used.
150 */
146 s->video_dev = NULL; 151 s->video_dev = NULL;
152 s->dvb = NULL;
147 s->cx = cx; 153 s->cx = cx;
148 s->type = type; 154 s->type = type;
149 s->name = cx18_stream_info[type].name; 155 s->name = cx18_stream_info[type].name;
@@ -167,6 +173,21 @@ static int cx18_prep_dev(struct cx18 *cx, int type)
167 173
168 cx18_stream_init(cx, type); 174 cx18_stream_init(cx, type);
169 175
176 /* Allocate the cx18_dvb struct only for the TS on cards with DTV */
177 if (type == CX18_ENC_STREAM_TYPE_TS) {
178 if (cx->card->hw_all & CX18_HW_DVB) {
179 s->dvb = kzalloc(sizeof(struct cx18_dvb), GFP_KERNEL);
180 if (s->dvb == NULL) {
181 CX18_ERR("Couldn't allocate cx18_dvb structure"
182 " for %s\n", s->name);
183 return -ENOMEM;
184 }
185 } else {
186 /* Don't need buffers for the TS, if there is no DVB */
187 s->buffers = 0;
188 }
189 }
190
170 if (num_offset == -1) 191 if (num_offset == -1)
171 return 0; 192 return 0;
172 193
@@ -222,13 +243,7 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
222 const char *name; 243 const char *name;
223 int num, ret; 244 int num, ret;
224 245
225 /* TODO: Shouldn't this be a VFL_TYPE_TRANSPORT or something? 246 if (type == CX18_ENC_STREAM_TYPE_TS && s->dvb != NULL) {
226 * We need a VFL_TYPE_TS defined.
227 */
228 if (strcmp("TS", s->name) == 0) {
229 /* just return if no DVB is supported */
230 if ((cx->card->hw_all & CX18_HW_DVB) == 0)
231 return 0;
232 ret = cx18_dvb_register(s); 247 ret = cx18_dvb_register(s);
233 if (ret < 0) { 248 if (ret < 0) {
234 CX18_ERR("DVB failed to register\n"); 249 CX18_ERR("DVB failed to register\n");
@@ -320,11 +335,13 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister)
320 /* Teardown all streams */ 335 /* Teardown all streams */
321 for (type = 0; type < CX18_MAX_STREAMS; type++) { 336 for (type = 0; type < CX18_MAX_STREAMS; type++) {
322 337
323 /* No struct video_device, but can have buffers allocated */ 338 /* The TS has a cx18_dvb structure, not a video_device */
324 if (type == CX18_ENC_STREAM_TYPE_TS) { 339 if (type == CX18_ENC_STREAM_TYPE_TS) {
325 if (cx->streams[type].dvb.enabled) { 340 if (cx->streams[type].dvb != NULL) {
326 cx18_dvb_unregister(&cx->streams[type]); 341 if (unregister)
327 cx->streams[type].dvb.enabled = false; 342 cx18_dvb_unregister(&cx->streams[type]);
343 kfree(cx->streams[type].dvb);
344 cx->streams[type].dvb = NULL;
328 cx18_stream_free(&cx->streams[type]); 345 cx18_stream_free(&cx->streams[type]);
329 } 346 }
330 continue; 347 continue;
diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h
index 77412bee5963..51765eb12d39 100644
--- a/drivers/media/video/cx18/cx18-streams.h
+++ b/drivers/media/video/cx18/cx18-streams.h
@@ -33,7 +33,8 @@ void cx18_stream_rotate_idx_mdls(struct cx18 *cx);
33 33
34static inline bool cx18_stream_enabled(struct cx18_stream *s) 34static inline bool cx18_stream_enabled(struct cx18_stream *s)
35{ 35{
36 return s->video_dev || s->dvb.enabled || 36 return s->video_dev ||
37 (s->dvb && s->dvb->enabled) ||
37 (s->type == CX18_ENC_STREAM_TYPE_IDX && 38 (s->type == CX18_ENC_STREAM_TYPE_IDX &&
38 s->cx->stream_buffers[CX18_ENC_STREAM_TYPE_IDX] != 0); 39 s->cx->stream_buffers[CX18_ENC_STREAM_TYPE_IDX] != 0);
39} 40}