diff mbox

s5p-mfc: Fix interrupt error handling routine

Message ID 1355311184-30029-1-git-send-email-k.debski@samsung.com (mailing list archive)
State New, archived
Headers show

Commit Message

Kamil Debski Dec. 12, 2012, 11:19 a.m. UTC
Signed-off-by: Kamil Debski <k.debski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 drivers/media/platform/s5p-mfc/s5p_mfc.c |   88 +++++++++++++-----------------
 1 file changed, 37 insertions(+), 51 deletions(-)

Comments

Sachin Kamat Dec. 13, 2012, 9 a.m. UTC | #1
Hi Kamil,

Please add some description about the fix (in the commit log/message).


On 12 December 2012 16:49, Kamil Debski <k.debski@samsung.com> wrote:
> Signed-off-by: Kamil Debski <k.debski@samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> ---
>  drivers/media/platform/s5p-mfc/s5p_mfc.c |   88 +++++++++++++-----------------
>  1 file 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 3afe879..5448ad1 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:
>  }
>
>  /* Error handling for interrupt */
> -static void s5p_mfc_handle_error(struct s5p_mfc_ctx *ctx,
> -                                unsigned int reason, unsigned int err)
> +static void s5p_mfc_handle_error(struct s5p_mfc_dev *dev,
> +               struct s5p_mfc_ctx *ctx, unsigned int reason, unsigned int err)
>  {
> -       struct s5p_mfc_dev *dev;
>         unsigned long flags;
>
> -       /* If no context is available then all necessary
> -        * processing has been done. */
> -       if (ctx == NULL)
> -               return;
> -
> -       dev = ctx->dev;
>         mfc_err("Interrupt Error: %08x\n", err);
> -       s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
> -       wake_up_dev(dev, reason, err);
>
> -       /* Error recovery is dependent on the state of context */
> -       switch (ctx->state) {
> -       case MFCINST_INIT:
> -               /* This error had to happen while acquireing instance */
> -       case MFCINST_GOT_INST:
> -               /* This error had to happen while parsing the header */
> -       case MFCINST_HEAD_PARSED:
> -               /* This error had to happen while setting dst buffers */
> -       case MFCINST_RETURN_INST:
> -               /* This error had to happen while releasing instance */
> -               clear_work_bit(ctx);
> -               wake_up_ctx(ctx, reason, err);
> -               if (test_and_clear_bit(0, &dev->hw_lock) == 0)
> -                       BUG();
> -               s5p_mfc_clock_off();
> -               ctx->state = MFCINST_ERROR;
> -               break;
> -       case MFCINST_FINISHING:
> -       case MFCINST_FINISHED:
> -       case MFCINST_RUNNING:
> -               /* It is higly probable that an error occured
> -                * while decoding a frame */
> -               clear_work_bit(ctx);
> -               ctx->state = MFCINST_ERROR;
> -               /* Mark all dst buffers as having an error */
> -               spin_lock_irqsave(&dev->irqlock, flags);
> -               s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->dst_queue,
> -                               &ctx->vq_dst);
> -               /* Mark all src buffers as having an error */
> -               s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->src_queue,
> -                               &ctx->vq_src);
> -               spin_unlock_irqrestore(&dev->irqlock, flags);
> -               if (test_and_clear_bit(0, &dev->hw_lock) == 0)
> -                       BUG();
> -               s5p_mfc_clock_off();
> -               break;
> -       default:
> -               mfc_err("Encountered an error interrupt which had not been handled\n");
> -               break;
> +       if (ctx != NULL) {
> +               /* Error recovery is dependent on the state of context */
> +               switch (ctx->state) {
> +               case MFCINST_RES_CHANGE_INIT:
> +               case MFCINST_RES_CHANGE_FLUSH:
> +               case MFCINST_RES_CHANGE_END:
> +               case MFCINST_FINISHING:
> +               case MFCINST_FINISHED:
> +               case MFCINST_RUNNING:
> +                       /* It is higly probable that an error occured
> +                        * while decoding a frame */
> +                       clear_work_bit(ctx);
> +                       ctx->state = MFCINST_ERROR;
> +                       /* Mark all dst buffers as having an error */
> +                       spin_lock_irqsave(&dev->irqlock, flags);
> +                       s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue,
> +                                               &ctx->dst_queue, &ctx->vq_dst);
> +                       /* Mark all src buffers as having an error */
> +                       s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue,
> +                                               &ctx->src_queue, &ctx->vq_src);
> +                       spin_unlock_irqrestore(&dev->irqlock, flags);
> +                       wake_up_ctx(ctx, reason, err);
> +                       break;
> +               default:
> +                       clear_work_bit(ctx);
> +                       ctx->state = MFCINST_ERROR;
> +                       wake_up_ctx(ctx, reason, err);
> +                       break;
> +               }
>         }
> +       if (test_and_clear_bit(0, &dev->hw_lock) == 0)
> +               BUG();
> +       s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
> +       s5p_mfc_clock_off();
> +       wake_up_dev(dev, reason, err);
>         return;
>  }
>
> @@ -632,7 +618,7 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv)
>                                 dev->warn_start)
>                         s5p_mfc_handle_frame(ctx, reason, err);
>                 else
> -                       s5p_mfc_handle_error(ctx, reason, err);
> +                       s5p_mfc_handle_error(dev, ctx, reason, err);
>                 clear_bit(0, &dev->enter_suspend);
>                 break;
>
> --
> 1.7.9.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
Kamil Debski Dec. 13, 2012, 9:17 a.m. UTC | #2
Hi Sachin,

No problem. First I would like to see this tested by Arun Kumar (he has
Exynos 5) and Pawel Osciak (he did report the problem to me).

I did test it using my test suite but the more tests we run the better.
If you have some MFC tests then I would appreciate your input too.

Best wishes,
Arun Kumar K Dec. 13, 2012, 10:51 a.m. UTC | #3
Hi Kamil,

>
> No problem. First I would like to see this tested by Arun Kumar (he has
> Exynos 5) and Pawel Osciak (he did report the problem to me).
>

I tested this on Exynos5 with some error streams and found no issues.
If there is any specific error stream to test then please tell me.

Regards
Arun Kumar
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index 3afe879..5448ad1 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:
 }
 
 /* Error handling for interrupt */
-static void s5p_mfc_handle_error(struct s5p_mfc_ctx *ctx,
-				 unsigned int reason, unsigned int err)
+static void s5p_mfc_handle_error(struct s5p_mfc_dev *dev,
+		struct s5p_mfc_ctx *ctx, unsigned int reason, unsigned int err)
 {
-	struct s5p_mfc_dev *dev;
 	unsigned long flags;
 
-	/* If no context is available then all necessary
-	 * processing has been done. */
-	if (ctx == NULL)
-		return;
-
-	dev = ctx->dev;
 	mfc_err("Interrupt Error: %08x\n", err);
-	s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
-	wake_up_dev(dev, reason, err);
 
-	/* Error recovery is dependent on the state of context */
-	switch (ctx->state) {
-	case MFCINST_INIT:
-		/* This error had to happen while acquireing instance */
-	case MFCINST_GOT_INST:
-		/* This error had to happen while parsing the header */
-	case MFCINST_HEAD_PARSED:
-		/* This error had to happen while setting dst buffers */
-	case MFCINST_RETURN_INST:
-		/* This error had to happen while releasing instance */
-		clear_work_bit(ctx);
-		wake_up_ctx(ctx, reason, err);
-		if (test_and_clear_bit(0, &dev->hw_lock) == 0)
-			BUG();
-		s5p_mfc_clock_off();
-		ctx->state = MFCINST_ERROR;
-		break;
-	case MFCINST_FINISHING:
-	case MFCINST_FINISHED:
-	case MFCINST_RUNNING:
-		/* It is higly probable that an error occured
-		 * while decoding a frame */
-		clear_work_bit(ctx);
-		ctx->state = MFCINST_ERROR;
-		/* Mark all dst buffers as having an error */
-		spin_lock_irqsave(&dev->irqlock, flags);
-		s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->dst_queue,
-				&ctx->vq_dst);
-		/* Mark all src buffers as having an error */
-		s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->src_queue,
-				&ctx->vq_src);
-		spin_unlock_irqrestore(&dev->irqlock, flags);
-		if (test_and_clear_bit(0, &dev->hw_lock) == 0)
-			BUG();
-		s5p_mfc_clock_off();
-		break;
-	default:
-		mfc_err("Encountered an error interrupt which had not been handled\n");
-		break;
+	if (ctx != NULL) {
+		/* Error recovery is dependent on the state of context */
+		switch (ctx->state) {
+		case MFCINST_RES_CHANGE_INIT:
+		case MFCINST_RES_CHANGE_FLUSH:
+		case MFCINST_RES_CHANGE_END:
+		case MFCINST_FINISHING:
+		case MFCINST_FINISHED:
+		case MFCINST_RUNNING:
+			/* It is higly probable that an error occured
+			 * while decoding a frame */
+			clear_work_bit(ctx);
+			ctx->state = MFCINST_ERROR;
+			/* Mark all dst buffers as having an error */
+			spin_lock_irqsave(&dev->irqlock, flags);
+			s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue,
+						&ctx->dst_queue, &ctx->vq_dst);
+			/* Mark all src buffers as having an error */
+			s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue,
+						&ctx->src_queue, &ctx->vq_src);
+			spin_unlock_irqrestore(&dev->irqlock, flags);
+			wake_up_ctx(ctx, reason, err);
+			break;
+		default:
+			clear_work_bit(ctx);
+			ctx->state = MFCINST_ERROR;
+			wake_up_ctx(ctx, reason, err);
+			break;
+		}
 	}
+	if (test_and_clear_bit(0, &dev->hw_lock) == 0)
+		BUG();
+	s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
+	s5p_mfc_clock_off();
+	wake_up_dev(dev, reason, err);
 	return;
 }
 
@@ -632,7 +618,7 @@  static irqreturn_t s5p_mfc_irq(int irq, void *priv)
 				dev->warn_start)
 			s5p_mfc_handle_frame(ctx, reason, err);
 		else
-			s5p_mfc_handle_error(ctx, reason, err);
+			s5p_mfc_handle_error(dev, ctx, reason, err);
 		clear_bit(0, &dev->enter_suspend);
 		break;