diff options
-rw-r--r-- | drivers/media/platform/exynos-gsc/gsc-core.h | 1 | ||||
-rw-r--r-- | drivers/media/platform/exynos-gsc/gsc-m2m.c | 29 |
2 files changed, 17 insertions, 13 deletions
diff --git a/drivers/media/platform/exynos-gsc/gsc-core.h b/drivers/media/platform/exynos-gsc/gsc-core.h index 76435d3bf62d..ef0a6564cef9 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.h +++ b/drivers/media/platform/exynos-gsc/gsc-core.h | |||
@@ -45,6 +45,7 @@ | |||
45 | #define GSC_DST_FMT (1 << 2) | 45 | #define GSC_DST_FMT (1 << 2) |
46 | #define GSC_CTX_M2M (1 << 3) | 46 | #define GSC_CTX_M2M (1 << 3) |
47 | #define GSC_CTX_STOP_REQ (1 << 6) | 47 | #define GSC_CTX_STOP_REQ (1 << 6) |
48 | #define GSC_CTX_ABORT (1 << 7) | ||
48 | 49 | ||
49 | enum gsc_dev_flags { | 50 | enum gsc_dev_flags { |
50 | /* for global */ | 51 | /* for global */ |
diff --git a/drivers/media/platform/exynos-gsc/gsc-m2m.c b/drivers/media/platform/exynos-gsc/gsc-m2m.c index e576ff2de3de..810c3e13970c 100644 --- a/drivers/media/platform/exynos-gsc/gsc-m2m.c +++ b/drivers/media/platform/exynos-gsc/gsc-m2m.c | |||
@@ -46,6 +46,17 @@ static int gsc_m2m_ctx_stop_req(struct gsc_ctx *ctx) | |||
46 | return ret == 0 ? -ETIMEDOUT : ret; | 46 | return ret == 0 ? -ETIMEDOUT : ret; |
47 | } | 47 | } |
48 | 48 | ||
49 | static void __gsc_m2m_job_abort(struct gsc_ctx *ctx) | ||
50 | { | ||
51 | int ret; | ||
52 | |||
53 | ret = gsc_m2m_ctx_stop_req(ctx); | ||
54 | if ((ret == -ETIMEDOUT) || (ctx->state & GSC_CTX_ABORT)) { | ||
55 | gsc_ctx_state_lock_clear(GSC_CTX_STOP_REQ | GSC_CTX_ABORT, ctx); | ||
56 | gsc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR); | ||
57 | } | ||
58 | } | ||
59 | |||
49 | static int gsc_m2m_start_streaming(struct vb2_queue *q, unsigned int count) | 60 | static int gsc_m2m_start_streaming(struct vb2_queue *q, unsigned int count) |
50 | { | 61 | { |
51 | struct gsc_ctx *ctx = q->drv_priv; | 62 | struct gsc_ctx *ctx = q->drv_priv; |
@@ -58,11 +69,8 @@ static int gsc_m2m_start_streaming(struct vb2_queue *q, unsigned int count) | |||
58 | static int gsc_m2m_stop_streaming(struct vb2_queue *q) | 69 | static int gsc_m2m_stop_streaming(struct vb2_queue *q) |
59 | { | 70 | { |
60 | struct gsc_ctx *ctx = q->drv_priv; | 71 | struct gsc_ctx *ctx = q->drv_priv; |
61 | int ret; | ||
62 | 72 | ||
63 | ret = gsc_m2m_ctx_stop_req(ctx); | 73 | __gsc_m2m_job_abort(ctx); |
64 | if (ret == -ETIMEDOUT) | ||
65 | gsc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR); | ||
66 | 74 | ||
67 | pm_runtime_put(&ctx->gsc_dev->pdev->dev); | 75 | pm_runtime_put(&ctx->gsc_dev->pdev->dev); |
68 | 76 | ||
@@ -91,15 +99,9 @@ void gsc_m2m_job_finish(struct gsc_ctx *ctx, int vb_state) | |||
91 | } | 99 | } |
92 | } | 100 | } |
93 | 101 | ||
94 | |||
95 | static void gsc_m2m_job_abort(void *priv) | 102 | static void gsc_m2m_job_abort(void *priv) |
96 | { | 103 | { |
97 | struct gsc_ctx *ctx = priv; | 104 | __gsc_m2m_job_abort((struct gsc_ctx *)priv); |
98 | int ret; | ||
99 | |||
100 | ret = gsc_m2m_ctx_stop_req(ctx); | ||
101 | if (ret == -ETIMEDOUT) | ||
102 | gsc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR); | ||
103 | } | 105 | } |
104 | 106 | ||
105 | static int gsc_get_bufs(struct gsc_ctx *ctx) | 107 | static int gsc_get_bufs(struct gsc_ctx *ctx) |
@@ -150,9 +152,10 @@ static void gsc_m2m_device_run(void *priv) | |||
150 | gsc->m2m.ctx = ctx; | 152 | gsc->m2m.ctx = ctx; |
151 | } | 153 | } |
152 | 154 | ||
153 | is_set = (ctx->state & GSC_CTX_STOP_REQ) ? 1 : 0; | 155 | is_set = ctx->state & GSC_CTX_STOP_REQ; |
154 | ctx->state &= ~GSC_CTX_STOP_REQ; | ||
155 | if (is_set) { | 156 | if (is_set) { |
157 | ctx->state &= ~GSC_CTX_STOP_REQ; | ||
158 | ctx->state |= GSC_CTX_ABORT; | ||
156 | wake_up(&gsc->irq_queue); | 159 | wake_up(&gsc->irq_queue); |
157 | goto put_device; | 160 | goto put_device; |
158 | } | 161 | } |