diff options
author | Andy Walls <awalls@radix.net> | 2009-04-13 21:42:43 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-06-16 17:20:44 -0400 |
commit | 87116159517ecf6b9cf62a136f2935a63833c485 (patch) | |
tree | 4a52a97e9e740304ed44d4348762836284f4d100 /drivers/media/video/cx18/cx18-driver.h | |
parent | deed75ed9f7576ada4bca02e6c851833a352a38d (diff) |
V4L/DVB (11616): cx18: Add a work queue for deferring empty buffer handoffs to the firmware
This change defers sending all CX18_CPU_DE_SET_MDL commands, for a stream with
an ongoing capture, by adding a work queue to handle sending such commands when
needed. This prevents any sleeps, caused by notifying the firmware of new
usable buffers, when a V4L2 application read() is being satisfied or when
an incoming buffer is processed by the cx18-NN-in work queue thread.
Signed-off-by: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx18/cx18-driver.h')
-rw-r--r-- | drivers/media/video/cx18/cx18-driver.h | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index e6f42d0cb2b3..62dca432fdbb 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h | |||
@@ -254,6 +254,7 @@ struct cx18_options { | |||
254 | #define CX18_F_S_INTERNAL_USE 5 /* this stream is used internally (sliced VBI processing) */ | 254 | #define CX18_F_S_INTERNAL_USE 5 /* this stream is used internally (sliced VBI processing) */ |
255 | #define CX18_F_S_STREAMOFF 7 /* signal end of stream EOS */ | 255 | #define CX18_F_S_STREAMOFF 7 /* signal end of stream EOS */ |
256 | #define CX18_F_S_APPL_IO 8 /* this stream is used read/written by an application */ | 256 | #define CX18_F_S_APPL_IO 8 /* this stream is used read/written by an application */ |
257 | #define CX18_F_S_STOPPING 9 /* telling the fw to stop capturing */ | ||
257 | 258 | ||
258 | /* per-cx18, i_flags */ | 259 | /* per-cx18, i_flags */ |
259 | #define CX18_F_I_LOADED_FW 0 /* Loaded firmware 1st time */ | 260 | #define CX18_F_I_LOADED_FW 0 /* Loaded firmware 1st time */ |
@@ -324,6 +325,33 @@ struct cx18_in_work_order { | |||
324 | char *str; | 325 | char *str; |
325 | }; | 326 | }; |
326 | 327 | ||
328 | /* | ||
329 | * There are 2 types of deferrable tasks that send messages out to the firmware: | ||
330 | * 1. Sending individual buffers back to the firmware | ||
331 | * 2. Sending as many free buffers for a stream from q_free as we can to the fw | ||
332 | * | ||
333 | * The worst case scenario for multiple simultaneous streams is | ||
334 | * TS, YUV, PCM, VBI, MPEG, and IDX all going at once. | ||
335 | * | ||
336 | * We try to load the firmware queue with as many free buffers as possible, | ||
337 | * whenever we get a buffer back for a stream. For the TS we return the single | ||
338 | * buffer to the firmware at that time as well. For all other streams, we | ||
339 | * return single buffers to the firmware as the application drains them. | ||
340 | * | ||
341 | * 6 streams * 2 sets of orders * (1 single buf + 1 load fw from q_free) | ||
342 | * = 24 work orders should cover our needs, provided the applications read | ||
343 | * at a fairly steady rate. If apps don't, we fall back to non-deferred | ||
344 | * operation, when no cx18_out_work_orders are available for use. | ||
345 | */ | ||
346 | #define CX18_MAX_OUT_WORK_ORDERS (24) | ||
347 | |||
348 | struct cx18_out_work_order { | ||
349 | struct work_struct work; | ||
350 | atomic_t pending; | ||
351 | struct cx18_stream *s; | ||
352 | struct cx18_buffer *buf; /* buf == NULL, means load fw from q_free */ | ||
353 | }; | ||
354 | |||
327 | #define CX18_INVALID_TASK_HANDLE 0xffffffff | 355 | #define CX18_INVALID_TASK_HANDLE 0xffffffff |
328 | 356 | ||
329 | struct cx18_stream { | 357 | struct cx18_stream { |
@@ -573,6 +601,10 @@ struct cx18 { | |||
573 | struct cx18_in_work_order in_work_order[CX18_MAX_IN_WORK_ORDERS]; | 601 | struct cx18_in_work_order in_work_order[CX18_MAX_IN_WORK_ORDERS]; |
574 | char epu_debug_str[256]; /* CX18_EPU_DEBUG is rare: use shared space */ | 602 | char epu_debug_str[256]; /* CX18_EPU_DEBUG is rare: use shared space */ |
575 | 603 | ||
604 | struct workqueue_struct *out_work_queue; | ||
605 | char out_workq_name[12]; /* "cx18-NN-out" */ | ||
606 | struct cx18_out_work_order out_work_order[CX18_MAX_OUT_WORK_ORDERS]; | ||
607 | |||
576 | /* i2c */ | 608 | /* i2c */ |
577 | struct i2c_adapter i2c_adap[2]; | 609 | struct i2c_adapter i2c_adap[2]; |
578 | struct i2c_algo_bit_data i2c_algo[2]; | 610 | struct i2c_algo_bit_data i2c_algo[2]; |