static int fimg2d_sysmmu_fault_handler(enum S5P_SYSMMU_INTERRUPT_TYPE itype, unsigned long pgtable_base, unsigned long fault_addr) { struct fimg2d_bltcmd *cmd; if (itype == SYSMMU_PAGEFAULT) { printk(KERN_ERR "[%s] sysmmu page fault(0x%lx), pgd(0x%lx)\n", __func__, fault_addr, pgtable_base); } else { printk(KERN_ERR "[%s] sysmmu interrupt " "type(%d) pgd(0x%lx) addr(0x%lx)\n", __func__, itype, pgtable_base, fault_addr); } cmd = fimg2d_get_first_command(info); if (!cmd) { printk(KERN_ERR "[%s] null command\n", __func__); goto next; } if (cmd->ctx->mm->pgd != phys_to_virt(pgtable_base)) { printk(KERN_ERR "[%s] pgtable base is different from current command\n", __func__); goto next; } fimg2d_dump_command(cmd); next: fimg2d_clk_dump(info); info->dump(info); BUG(); return 0; }
static int fimg2d_sysmmu_fault_handler(struct device *dev, const char *mmuname, enum exynos_sysmmu_inttype itype, unsigned long pgtable_base, unsigned long fault_addr) { struct fimg2d_bltcmd *cmd; if (itype == SYSMMU_PAGEFAULT) { fimg2d_err("sysmmu page fault(0x%lx), pgd(0x%lx)\n", fault_addr, pgtable_base); } else { fimg2d_err("sysmmu fault type(%d) pgd(0x%lx) addr(0x%lx)\n", itype, pgtable_base, fault_addr); } cmd = fimg2d_get_command(ctrl); if (WARN_ON(!cmd)) goto next; if (cmd->ctx->mm->pgd != phys_to_virt(pgtable_base)) { fimg2d_err("pgtable base invalid\n"); goto next; } fimg2d_dump_command(cmd); next: ctrl->dump(ctrl); BUG(); return 0; }
static inline void fimg2d4x_blit_wait(struct fimg2d_control *info, struct fimg2d_bltcmd *cmd) { if (!wait_event_timeout(info->wait_q, !atomic_read(&info->busy), BLIT_TIMEOUT)) { printk(KERN_ERR "[%s] blit wait timeout\n", __func__); fimg2d_dump_command(cmd); if (!fimg2d4x_blit_done_status(info)) info->err = true; /* device error */ } }
static inline void fimg2d4x_blit_wait(struct fimg2d_control *info, struct fimg2d_bltcmd *cmd) { if (!wait_event_timeout(info->wait_q, !atomic_read(&info->busy), BLIT_TIMEOUT)) { printk(KERN_ERR "[%s] blit wait timeout\n", __func__); fimg2d_dump_command(cmd); if (!fimg2d4x_blit_done_status(info)) printk(KERN_ERR "[%s] G2D operation is not finished", __func__); fimg2d4x_sw_reset(info); } }
static int fimg2d4x_blit_wait(struct fimg2d_control *ctrl, struct fimg2d_bltcmd *cmd) { int ret; ret = wait_event_timeout(ctrl->wait_q, !atomic_read(&ctrl->busy), BLIT_TIMEOUT); if (!ret) { fimg2d4x_disable_irq(ctrl); fimg2d_err("blit wait timeout\n"); if (!fimg2d4x_blit_done_status(ctrl)) fimg2d_err("blit not finished\n"); fimg2d_dump_command(cmd); fimg2d4x_reset(ctrl); return -1; } return 0; }
int fimg2d_add_command(struct fimg2d_control *ctrl, struct fimg2d_context *ctx, struct fimg2d_blit __user *buf) { unsigned long flags; struct fimg2d_blit *blt; struct fimg2d_bltcmd *cmd; int len = sizeof(struct fimg2d_image); int ret = 0; cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); if (!cmd) return -ENOMEM; if (copy_from_user(&cmd->blt, buf, sizeof(cmd->blt))) { ret = -EFAULT; goto err; } cmd->ctx = ctx; blt = &cmd->blt; if (blt->src) { if (copy_from_user(&cmd->image[ISRC], blt->src, len)) { ret = -EFAULT; goto err; } blt->src = &cmd->image[ISRC]; } if (blt->msk) { if (copy_from_user(&cmd->image[IMSK], blt->msk, len)) { ret = -EFAULT; goto err; } blt->msk = &cmd->image[IMSK]; } if (blt->tmp) { if (copy_from_user(&cmd->image[ITMP], blt->tmp, len)) { ret = -EFAULT; goto err; } blt->tmp = &cmd->image[ITMP]; } if (blt->dst) { if (copy_from_user(&cmd->image[IDST], blt->dst, len)) { ret = -EFAULT; goto err; } blt->dst = &cmd->image[IDST]; } fimg2d_dump_command(cmd); perf_start(cmd, PERF_TOTAL); if (fimg2d_check_params(cmd)) { ret = -EINVAL; goto err; } fimg2d_fixup_params(cmd); if (fimg2d_check_dma_sync(cmd)) { ret = -EFAULT; goto err; } /* add command node and increase ncmd */ g2d_spin_lock(&ctrl->bltlock, flags); if (atomic_read(&ctrl->drvact) || atomic_read(&ctrl->suspended)) { fimg2d_debug("driver is unavailable, do sw fallback\n"); g2d_spin_unlock(&ctrl->bltlock, flags); ret = -EPERM; goto err; } atomic_inc(&ctx->ncmd); fimg2d_enqueue(&cmd->node, &ctrl->cmd_q); fimg2d_debug("ctx %p pgd %p ncmd(%d) seq_no(%u)\n", cmd->ctx, (unsigned long *)cmd->ctx->mm->pgd, atomic_read(&ctx->ncmd), cmd->blt.seq_no); g2d_spin_unlock(&ctrl->bltlock, flags); return 0; err: kfree(cmd); return ret; }
int fimg2d_add_command(struct fimg2d_control *info, struct fimg2d_context *ctx, struct fimg2d_blit *blit) { int i, ret; struct fimg2d_image *buf[MAX_IMAGES] = image_table(blit); struct fimg2d_bltcmd *cmd; cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); if (!cmd) return -ENOMEM; cmd->ctx = ctx; cmd->op = blit->op; cmd->sync = blit->sync; cmd->seq_no = blit->seq_no; memcpy(&cmd->param, &blit->param, sizeof(cmd->param)); for (i = 0; i < MAX_IMAGES; i++) { if (!buf[i]) continue; if (copy_from_user(&cmd->image[i], buf[i], sizeof(struct fimg2d_image))) { ret = -EFAULT; goto err_user; } } #ifdef CONFIG_VIDEO_FIMG2D_DEBUG fimg2d_dump_command(cmd); #endif if (fimg2d_check_params(info, cmd)) { printk(KERN_ERR "[%s] invalid params\n", __func__); fimg2d_dump_command(cmd); ret = -EINVAL; goto err_user; } fimg2d_fixup_params(cmd); ret = fimg2d_import_bufs(info, cmd); if (ret) goto err_user; /* add command node and increase ncmd */ spin_lock(&info->bltlock); if (atomic_read(&info->suspended)) { fimg2d_debug("fimg2d suspended, do sw fallback\n"); spin_unlock(&info->bltlock); ret = -EFAULT; goto err_user; } atomic_inc(&ctx->ncmd); fimg2d_enqueue(&cmd->node, &info->cmd_q); fimg2d_debug("ctx %p ncmd(%d) seq_no(%u)\n", cmd->ctx, atomic_read(&ctx->ncmd), cmd->seq_no); spin_unlock(&info->bltlock); return 0; err_user: kfree(cmd); return ret; }
int fimg2d_add_command(struct fimg2d_control *info, struct fimg2d_context *ctx, struct fimg2d_blit *blit) { int i, ret; struct fimg2d_image *buf[MAX_IMAGES] = image_table(blit); struct fimg2d_bltcmd *cmd; struct fimg2d_image dst; if (blit->dst) if (copy_from_user(&dst, (void *)blit->dst, sizeof(dst))) return -EFAULT; if ((blit->dst) && (dst.addr.type == ADDR_USER)) up_write(&page_alloc_slow_rwsem); cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); if ((blit->dst) && (dst.addr.type == ADDR_USER)) down_write(&page_alloc_slow_rwsem); if (!cmd) return -ENOMEM; for (i = 0; i < MAX_IMAGES; i++) { if (!buf[i]) continue; if (copy_from_user(&cmd->image[i], buf[i], sizeof(struct fimg2d_image))) { ret = -EFAULT; goto err_user; } } cmd->ctx = ctx; cmd->op = blit->op; cmd->sync = blit->sync; cmd->seq_no = blit->seq_no; memcpy(&cmd->param, &blit->param, sizeof(cmd->param)); #ifdef CONFIG_VIDEO_FIMG2D_DEBUG fimg2d_dump_command(cmd); #endif if (fimg2d_check_params(cmd)) { printk(KERN_ERR "[%s] invalid params\n", __func__); fimg2d_dump_command(cmd); ret = -EINVAL; goto err_user; } fimg2d_fixup_params(cmd); if (fimg2d_check_dma_sync(cmd)) { ret = -EFAULT; goto err_user; } /* add command node and increase ncmd */ spin_lock(&info->bltlock); if (atomic_read(&info->suspended)) { fimg2d_debug("fimg2d suspended, do sw fallback\n"); spin_unlock(&info->bltlock); ret = -EFAULT; goto err_user; } atomic_inc(&ctx->ncmd); fimg2d_enqueue(&cmd->node, &info->cmd_q); fimg2d_debug("ctx %p pgd %p ncmd(%d) seq_no(%u)\n", cmd->ctx, (unsigned long *)cmd->ctx->mm->pgd, atomic_read(&ctx->ncmd), cmd->seq_no); spin_unlock(&info->bltlock); return 0; err_user: kfree(cmd); return ret; }