From: Cho KyongHo Date: Mon, 9 Jan 2017 08:29:12 +0000 (+0900) Subject: [COMMON] media: scaler: fix possible clk enable after shutdown X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=cab3e82cfa4f190bf207c0e9ed93ecb784156813;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git [COMMON] media: scaler: fix possible clk enable after shutdown sc_shutdown() is called during system shutdown and it marks drvdata that it is under shutdown state. However, a task is requested to be processed after sc_shutdown() is called, sc_run_next_job() enables the power and the clocks of Scaler even though the power domain is already detached. Change-Id: Ib90ac0d870a381a4e3a99455a749ff42ff0d5565 Signed-off-by: Cho KyongHo --- diff --git a/drivers/media/platform/exynos/scaler/scaler-core.c b/drivers/media/platform/exynos/scaler/scaler-core.c index a64587095de0..fcc201035f3b 100644 --- a/drivers/media/platform/exynos/scaler/scaler-core.c +++ b/drivers/media/platform/exynos/scaler/scaler-core.c @@ -2468,15 +2468,10 @@ static int sc_run_next_job(struct sc_dev *sc) unsigned int h_shift, v_shift; int ret; - ret = sc_power_clk_enable(sc); - if (ret) - return ret; - spin_lock_irqsave(&sc->ctxlist_lock, flags); if (sc->current_ctx || list_empty(&sc->context_list)) { /* a job is currently being processed or no job is to run */ - sc_clk_power_disable(sc); spin_unlock_irqrestore(&sc->ctxlist_lock, flags); return 0; } @@ -2491,7 +2486,6 @@ static int sc_run_next_job(struct sc_dev *sc) if (test_bit(DEV_SUSPEND, &sc->state)) { clear_bit(DEV_RUN, &sc->state); - sc_clk_power_disable(sc); spin_unlock_irqrestore(&sc->ctxlist_lock, flags); return 0; } @@ -2505,6 +2499,34 @@ static int sc_run_next_job(struct sc_dev *sc) spin_unlock_irqrestore(&sc->ctxlist_lock, flags); + ret = sc_power_clk_enable(sc); + if (ret) { + /* + * Failed to enable the power and the clock. Let's push the task + * again for the later retry. + */ + spin_lock_irqsave(&sc->ctxlist_lock, flags); + + list_add(&ctx->node, &sc->context_list); + sc->current_ctx = NULL; + + clear_bit(CTX_RUN, &ctx->flags); + + spin_unlock_irqrestore(&sc->ctxlist_lock, flags); + + clear_bit(DEV_RUN, &sc->state); + + /* + * V4L2 mem2mem assumes that the tasks in device_run() are + * always succeed in processing in H/W while m2m1shot accepts + * failure in device_run(). m2m1shot2 returns failure to the + * users if devce_run() fails. To prevent returning failure to + * users and losing a task to run, we should assume that + * processing a task always succeeds. + */ + return 0; + } + s_frame = &ctx->s_frame; d_frame = &ctx->d_frame;