static void gsc_m2m_device_run(void *priv) { struct gsc_ctx *ctx = priv; struct gsc_dev *gsc; unsigned long flags; int ret; bool is_set = false; if (WARN(!ctx, "null hardware context\n")) return; gsc = ctx->gsc_dev; spin_lock_irqsave(&gsc->slock, flags); set_bit(ST_M2M_PEND, &gsc->state); /* Reconfigure hardware if the context has changed. */ if (gsc->m2m.ctx != ctx) { pr_debug("gsc->m2m.ctx = 0x%p, current_ctx = 0x%p", gsc->m2m.ctx, ctx); ctx->state |= GSC_PARAMS; gsc->m2m.ctx = ctx; } is_set = ctx->state & GSC_CTX_STOP_REQ; if (is_set) { ctx->state &= ~GSC_CTX_STOP_REQ; ctx->state |= GSC_CTX_ABORT; wake_up(&gsc->irq_queue); goto put_device; } ret = gsc_get_bufs(ctx); if (ret) { pr_err("Wrong address"); goto put_device; } gsc_set_prefbuf(gsc, &ctx->s_frame); gsc_hw_set_input_addr(gsc, &ctx->s_frame.addr, GSC_M2M_BUF_NUM); gsc_hw_set_output_addr(gsc, &ctx->d_frame.addr, GSC_M2M_BUF_NUM); if (ctx->state & GSC_PARAMS) { gsc_hw_set_input_buf_masking(gsc, GSC_M2M_BUF_NUM, false); gsc_hw_set_output_buf_masking(gsc, GSC_M2M_BUF_NUM, false); gsc_hw_set_frm_done_irq_mask(gsc, false); gsc_hw_set_gsc_irq_enable(gsc, true); if (gsc_set_scaler_info(ctx)) { pr_err("Scaler setup error"); goto put_device; } gsc_hw_set_input_path(ctx); gsc_hw_set_in_size(ctx); gsc_hw_set_in_image_format(ctx); gsc_hw_set_output_path(ctx); gsc_hw_set_out_size(ctx); gsc_hw_set_out_image_format(ctx); gsc_hw_set_prescaler(ctx); gsc_hw_set_mainscaler(ctx); gsc_hw_set_rotation(ctx); gsc_hw_set_global_alpha(ctx); } /* update shadow registers */ gsc_hw_set_sfr_update(ctx); ctx->state &= ~GSC_PARAMS; gsc_hw_enable_control(gsc, true); spin_unlock_irqrestore(&gsc->slock, flags); return; put_device: ctx->state &= ~GSC_PARAMS; spin_unlock_irqrestore(&gsc->slock, flags); }
static void gsc_m2m_device_run(void *priv) { struct gsc_ctx *ctx = priv; struct gsc_dev *gsc; unsigned long flags; int ret = 0; bool is_set = false; if (WARN(!ctx, "null hardware context\n")) return; gsc = ctx->gsc_dev; spin_lock_irqsave(&ctx->slock, flags); /* Reconfigure hardware if the context has changed. */ if (gsc->m2m.ctx != ctx) { gsc_dbg("gsc->m2m.ctx = 0x%p, current_ctx = 0x%p", gsc->m2m.ctx, ctx); ctx->state |= GSC_PARAMS; gsc->m2m.ctx = ctx; } is_set = (ctx->state & GSC_CTX_STOP_REQ) ? 1 : 0; ctx->state &= ~GSC_CTX_STOP_REQ; if (is_set) { wake_up(&gsc->irq_queue); goto put_device; } ret = gsc_get_bufs(ctx); if (ret) { gsc_err("Wrong address"); goto put_device; } gsc_set_prefbuf(gsc, ctx->s_frame); gsc_hw_set_input_addr(gsc, &ctx->s_frame.addr, GSC_M2M_BUF_NUM); gsc_hw_set_output_addr(gsc, &ctx->d_frame.addr, GSC_M2M_BUF_NUM); if (ctx->state & GSC_PARAMS) { gsc_hw_set_input_buf_masking(gsc, GSC_M2M_BUF_NUM, false); gsc_hw_set_output_buf_masking(gsc, GSC_M2M_BUF_NUM, false); gsc_hw_set_frm_done_irq_mask(gsc, false); gsc_hw_set_gsc_irq_enable(gsc, true); if (gsc_set_scaler_info(ctx)) { gsc_err("Scaler setup error"); goto put_device; } gsc_hw_set_input_path(ctx); gsc_hw_set_in_size(ctx); gsc_hw_set_in_image_format(ctx); gsc_hw_set_output_path(ctx); gsc_hw_set_out_size(ctx); gsc_hw_set_out_image_format(ctx); gsc_hw_set_prescaler(ctx); gsc_hw_set_mainscaler(ctx); gsc_hw_set_rotation(ctx); gsc_hw_set_global_alpha(ctx); } /* When you update SFRs in the middle of operating gsc_hw_set_sfr_update(ctx); */ ctx->state &= ~GSC_PARAMS; if (!test_and_set_bit(ST_M2M_RUN, &gsc->state)) { /* One frame mode sequence GSCALER_ON on -> GSCALER_OP_STATUS is operating -> GSCALER_ON off */ gsc_hw_enable_control(gsc, true); ret = gsc_wait_operating(gsc); if (ret < 0) { gsc_err("gscaler wait operating timeout"); goto put_device; } gsc_hw_enable_control(gsc, false); } spin_unlock_irqrestore(&ctx->slock, flags); return; put_device: ctx->state &= ~GSC_PARAMS; spin_unlock_irqrestore(&ctx->slock, flags); }