static irqreturn_t rotator_irq_handler(int irq, void *arg) { struct rot_context *rot = arg; struct exynos_drm_ippdrv *ippdrv = &rot->ippdrv; struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node; struct drm_exynos_ipp_event_work *event_work = c_node->event_work; enum rot_irq_status irq_status; u32 val; /* Get execution result */ irq_status = rotator_reg_get_irq_status(rot); /* clear status */ val = rot_read(ROT_STATUS); val |= ROT_STATUS_IRQ_PENDING((u32)irq_status); rot_write(val, ROT_STATUS); if (irq_status == ROT_IRQ_STATUS_COMPLETE) { event_work->ippdrv = ippdrv; event_work->buf_id[EXYNOS_DRM_OPS_DST] = rot->cur_buf_id[EXYNOS_DRM_OPS_DST]; queue_work(ippdrv->event_workq, &event_work->work); } else { DRM_ERROR("the SFR is set illegally\n"); } return IRQ_HANDLED; }
static void rotator_reg_set_irq_status_clear(struct rot_context *rot, enum rot_irq_status status) { u32 value = readl(rot->regs + ROT_STATUS); value |= ROT_STATUS_IRQ_PENDING((u32)status); writel(value, rot->regs + ROT_STATUS); }