diff options
Diffstat (limited to 'drivers/media/platform/davinci/vpif_display.c')
-rw-r--r-- | drivers/media/platform/davinci/vpif_display.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c index e5109ae0593d..9f2b603be9c9 100644 --- a/drivers/media/platform/davinci/vpif_display.c +++ b/drivers/media/platform/davinci/vpif_display.c | |||
@@ -177,11 +177,14 @@ static void vpif_buffer_queue(struct vb2_buffer *vb) | |||
177 | struct vpif_disp_buffer, vb); | 177 | struct vpif_disp_buffer, vb); |
178 | struct channel_obj *ch = fh->channel; | 178 | struct channel_obj *ch = fh->channel; |
179 | struct common_obj *common; | 179 | struct common_obj *common; |
180 | unsigned long flags; | ||
180 | 181 | ||
181 | common = &ch->common[VPIF_VIDEO_INDEX]; | 182 | common = &ch->common[VPIF_VIDEO_INDEX]; |
182 | 183 | ||
183 | /* add the buffer to the DMA queue */ | 184 | /* add the buffer to the DMA queue */ |
185 | spin_lock_irqsave(&common->irqlock, flags); | ||
184 | list_add_tail(&buf->list, &common->dma_queue); | 186 | list_add_tail(&buf->list, &common->dma_queue); |
187 | spin_unlock_irqrestore(&common->irqlock, flags); | ||
185 | } | 188 | } |
186 | 189 | ||
187 | /* | 190 | /* |
@@ -246,10 +249,13 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
246 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | 249 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; |
247 | struct vpif_params *vpif = &ch->vpifparams; | 250 | struct vpif_params *vpif = &ch->vpifparams; |
248 | unsigned long addr = 0; | 251 | unsigned long addr = 0; |
252 | unsigned long flags; | ||
249 | int ret; | 253 | int ret; |
250 | 254 | ||
251 | /* If buffer queue is empty, return error */ | 255 | /* If buffer queue is empty, return error */ |
256 | spin_lock_irqsave(&common->irqlock, flags); | ||
252 | if (list_empty(&common->dma_queue)) { | 257 | if (list_empty(&common->dma_queue)) { |
258 | spin_unlock_irqrestore(&common->irqlock, flags); | ||
253 | vpif_err("buffer queue is empty\n"); | 259 | vpif_err("buffer queue is empty\n"); |
254 | return -EIO; | 260 | return -EIO; |
255 | } | 261 | } |
@@ -260,6 +266,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
260 | struct vpif_disp_buffer, list); | 266 | struct vpif_disp_buffer, list); |
261 | 267 | ||
262 | list_del(&common->cur_frm->list); | 268 | list_del(&common->cur_frm->list); |
269 | spin_unlock_irqrestore(&common->irqlock, flags); | ||
263 | /* Mark state of the current frame to active */ | 270 | /* Mark state of the current frame to active */ |
264 | common->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE; | 271 | common->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE; |
265 | 272 | ||
@@ -330,6 +337,7 @@ static int vpif_stop_streaming(struct vb2_queue *vq) | |||
330 | struct vpif_fh *fh = vb2_get_drv_priv(vq); | 337 | struct vpif_fh *fh = vb2_get_drv_priv(vq); |
331 | struct channel_obj *ch = fh->channel; | 338 | struct channel_obj *ch = fh->channel; |
332 | struct common_obj *common; | 339 | struct common_obj *common; |
340 | unsigned long flags; | ||
333 | 341 | ||
334 | if (!vb2_is_streaming(vq)) | 342 | if (!vb2_is_streaming(vq)) |
335 | return 0; | 343 | return 0; |
@@ -337,12 +345,14 @@ static int vpif_stop_streaming(struct vb2_queue *vq) | |||
337 | common = &ch->common[VPIF_VIDEO_INDEX]; | 345 | common = &ch->common[VPIF_VIDEO_INDEX]; |
338 | 346 | ||
339 | /* release all active buffers */ | 347 | /* release all active buffers */ |
348 | spin_lock_irqsave(&common->irqlock, flags); | ||
340 | while (!list_empty(&common->dma_queue)) { | 349 | while (!list_empty(&common->dma_queue)) { |
341 | common->next_frm = list_entry(common->dma_queue.next, | 350 | common->next_frm = list_entry(common->dma_queue.next, |
342 | struct vpif_disp_buffer, list); | 351 | struct vpif_disp_buffer, list); |
343 | list_del(&common->next_frm->list); | 352 | list_del(&common->next_frm->list); |
344 | vb2_buffer_done(&common->next_frm->vb, VB2_BUF_STATE_ERROR); | 353 | vb2_buffer_done(&common->next_frm->vb, VB2_BUF_STATE_ERROR); |
345 | } | 354 | } |
355 | spin_unlock_irqrestore(&common->irqlock, flags); | ||
346 | 356 | ||
347 | return 0; | 357 | return 0; |
348 | } | 358 | } |
@@ -363,11 +373,13 @@ static void process_progressive_mode(struct common_obj *common) | |||
363 | { | 373 | { |
364 | unsigned long addr = 0; | 374 | unsigned long addr = 0; |
365 | 375 | ||
376 | spin_lock(&common->irqlock); | ||
366 | /* Get the next buffer from buffer queue */ | 377 | /* Get the next buffer from buffer queue */ |
367 | common->next_frm = list_entry(common->dma_queue.next, | 378 | common->next_frm = list_entry(common->dma_queue.next, |
368 | struct vpif_disp_buffer, list); | 379 | struct vpif_disp_buffer, list); |
369 | /* Remove that buffer from the buffer queue */ | 380 | /* Remove that buffer from the buffer queue */ |
370 | list_del(&common->next_frm->list); | 381 | list_del(&common->next_frm->list); |
382 | spin_unlock(&common->irqlock); | ||
371 | /* Mark status of the buffer as active */ | 383 | /* Mark status of the buffer as active */ |
372 | common->next_frm->vb.state = VB2_BUF_STATE_ACTIVE; | 384 | common->next_frm->vb.state = VB2_BUF_STATE_ACTIVE; |
373 | 385 | ||
@@ -398,16 +410,18 @@ static void process_interlaced_mode(int fid, struct common_obj *common) | |||
398 | common->cur_frm = common->next_frm; | 410 | common->cur_frm = common->next_frm; |
399 | 411 | ||
400 | } else if (1 == fid) { /* odd field */ | 412 | } else if (1 == fid) { /* odd field */ |
413 | spin_lock(&common->irqlock); | ||
401 | if (list_empty(&common->dma_queue) | 414 | if (list_empty(&common->dma_queue) |
402 | || (common->cur_frm != common->next_frm)) { | 415 | || (common->cur_frm != common->next_frm)) { |
416 | spin_unlock(&common->irqlock); | ||
403 | return; | 417 | return; |
404 | } | 418 | } |
419 | spin_unlock(&common->irqlock); | ||
405 | /* one field is displayed configure the next | 420 | /* one field is displayed configure the next |
406 | * frame if it is available else hold on current | 421 | * frame if it is available else hold on current |
407 | * frame */ | 422 | * frame */ |
408 | /* Get next from the buffer queue */ | 423 | /* Get next from the buffer queue */ |
409 | process_progressive_mode(common); | 424 | process_progressive_mode(common); |
410 | |||
411 | } | 425 | } |
412 | } | 426 | } |
413 | 427 | ||
@@ -437,8 +451,12 @@ static irqreturn_t vpif_channel_isr(int irq, void *dev_id) | |||
437 | continue; | 451 | continue; |
438 | 452 | ||
439 | if (1 == ch->vpifparams.std_info.frm_fmt) { | 453 | if (1 == ch->vpifparams.std_info.frm_fmt) { |
440 | if (list_empty(&common->dma_queue)) | 454 | spin_lock(&common->irqlock); |
455 | if (list_empty(&common->dma_queue)) { | ||
456 | spin_unlock(&common->irqlock); | ||
441 | continue; | 457 | continue; |
458 | } | ||
459 | spin_unlock(&common->irqlock); | ||
442 | 460 | ||
443 | /* Progressive mode */ | 461 | /* Progressive mode */ |
444 | if (!channel_first_int[i][channel_id]) { | 462 | if (!channel_first_int[i][channel_id]) { |