aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKamil Debski <k.debski@samsung.com>2012-12-21 03:32:59 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-01-06 06:21:00 -0500
commit7296e25f6e76bedc96cb1f16c200e9ac7a87323b (patch)
treeb6c191aedf389ae2981d87b890c34dd2b5ef68a2
parenta26860bdbd632278bbbcc2261b4c28f965472741 (diff)
[media] s5p-mfc: Fix interrupt error handling routine
New context states were added but handling in s5p_mfc_handle_error for these states was not. After this patch these states are be handled correctly. Signed-off-by: Kamil Debski <k.debski@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc.c88
1 files changed, 37 insertions, 51 deletions
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index 3afe879d54d7..5448ad1ea248 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -412,62 +412,48 @@ leave_handle_frame:
412} 412}
413 413
414/* Error handling for interrupt */ 414/* Error handling for interrupt */
415static void s5p_mfc_handle_error(struct s5p_mfc_ctx *ctx, 415static void s5p_mfc_handle_error(struct s5p_mfc_dev *dev,
416 unsigned int reason, unsigned int err) 416 struct s5p_mfc_ctx *ctx, unsigned int reason, unsigned int err)
417{ 417{
418 struct s5p_mfc_dev *dev;
419 unsigned long flags; 418 unsigned long flags;
420 419
421 /* If no context is available then all necessary
422 * processing has been done. */
423 if (ctx == NULL)
424 return;
425
426 dev = ctx->dev;
427 mfc_err("Interrupt Error: %08x\n", err); 420 mfc_err("Interrupt Error: %08x\n", err);
428 s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
429 wake_up_dev(dev, reason, err);
430 421
431 /* Error recovery is dependent on the state of context */ 422 if (ctx != NULL) {
432 switch (ctx->state) { 423 /* Error recovery is dependent on the state of context */
433 case MFCINST_INIT: 424 switch (ctx->state) {
434 /* This error had to happen while acquireing instance */ 425 case MFCINST_RES_CHANGE_INIT:
435 case MFCINST_GOT_INST: 426 case MFCINST_RES_CHANGE_FLUSH:
436 /* This error had to happen while parsing the header */ 427 case MFCINST_RES_CHANGE_END:
437 case MFCINST_HEAD_PARSED: 428 case MFCINST_FINISHING:
438 /* This error had to happen while setting dst buffers */ 429 case MFCINST_FINISHED:
439 case MFCINST_RETURN_INST: 430 case MFCINST_RUNNING:
440 /* This error had to happen while releasing instance */ 431 /* It is higly probable that an error occured
441 clear_work_bit(ctx); 432 * while decoding a frame */
442 wake_up_ctx(ctx, reason, err); 433 clear_work_bit(ctx);
443 if (test_and_clear_bit(0, &dev->hw_lock) == 0) 434 ctx->state = MFCINST_ERROR;
444 BUG(); 435 /* Mark all dst buffers as having an error */
445 s5p_mfc_clock_off(); 436 spin_lock_irqsave(&dev->irqlock, flags);
446 ctx->state = MFCINST_ERROR; 437 s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue,
447 break; 438 &ctx->dst_queue, &ctx->vq_dst);
448 case MFCINST_FINISHING: 439 /* Mark all src buffers as having an error */
449 case MFCINST_FINISHED: 440 s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue,
450 case MFCINST_RUNNING: 441 &ctx->src_queue, &ctx->vq_src);
451 /* It is higly probable that an error occured 442 spin_unlock_irqrestore(&dev->irqlock, flags);
452 * while decoding a frame */ 443 wake_up_ctx(ctx, reason, err);
453 clear_work_bit(ctx); 444 break;
454 ctx->state = MFCINST_ERROR; 445 default:
455 /* Mark all dst buffers as having an error */ 446 clear_work_bit(ctx);
456 spin_lock_irqsave(&dev->irqlock, flags); 447 ctx->state = MFCINST_ERROR;
457 s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->dst_queue, 448 wake_up_ctx(ctx, reason, err);
458 &ctx->vq_dst); 449 break;
459 /* Mark all src buffers as having an error */ 450 }
460 s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->src_queue,
461 &ctx->vq_src);
462 spin_unlock_irqrestore(&dev->irqlock, flags);
463 if (test_and_clear_bit(0, &dev->hw_lock) == 0)
464 BUG();
465 s5p_mfc_clock_off();
466 break;
467 default:
468 mfc_err("Encountered an error interrupt which had not been handled\n");
469 break;
470 } 451 }
452 if (test_and_clear_bit(0, &dev->hw_lock) == 0)
453 BUG();
454 s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
455 s5p_mfc_clock_off();
456 wake_up_dev(dev, reason, err);
471 return; 457 return;
472} 458}
473 459
@@ -632,7 +618,7 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv)
632 dev->warn_start) 618 dev->warn_start)
633 s5p_mfc_handle_frame(ctx, reason, err); 619 s5p_mfc_handle_frame(ctx, reason, err);
634 else 620 else
635 s5p_mfc_handle_error(ctx, reason, err); 621 s5p_mfc_handle_error(dev, ctx, reason, err);
636 clear_bit(0, &dev->enter_suspend); 622 clear_bit(0, &dev->enter_suspend);
637 break; 623 break;
638 624