diff options
author | Andy Walls <awalls@md.metrocast.net> | 2010-12-11 18:38:20 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-12-29 05:17:10 -0500 |
commit | 754f9969c323559a12bce1475f3c1e6574129856 (patch) | |
tree | 3345067e0920d27112b1449152d83e291fd348b3 /drivers/media/video/cx18 | |
parent | fa98447f09641adeeaf02b94133649f03b74d159 (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.h | 9 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-dvb.c | 32 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-mailbox.c | 6 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-streams.c | 45 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-streams.h | 3 |
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 | ||
328 | struct cx18_stream; /* forward reference */ | ||
329 | |||
328 | struct cx18_dvb { | 330 | struct 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 | ||
367 | struct cx18_stream { | 370 | struct 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 | ||
405 | struct cx18_open_id { | 406 | struct 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) | |||
316 | int cx18_dvb_register(struct cx18_stream *stream) | 316 | int 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: | |||
405 | void cx18_dvb_unregister(struct cx18_stream *stream) | 408 | void 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 | */ |
433 | static int dvb_register(struct cx18_stream *stream) | 439 | static 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 | ||
34 | static inline bool cx18_stream_enabled(struct cx18_stream *s) | 34 | static 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 | } |