int g2d_wait_for_finish(struct g2d_global *g2d_dev, g2d_params *params)
{
	if(atomic_read(&g2d_dev->is_mmu_faulted) == 1) {
		FIMG2D_ERROR("error : sysmmu_faulted early\n");
		atomic_set(&g2d_dev->is_mmu_faulted, 0);
		return false;
	}

	if (params->flag.render_mode & G2D_POLLING) {
		g2d_check_fifo_state_wait(g2d_dev);
	} else {
		if(wait_event_interruptible_timeout(g2d_dev->waitq,
			(atomic_read(&g2d_dev->in_use) == 0),
			msecs_to_jiffies(G2D_TIMEOUT)) == 0) {
			if(atomic_read(&g2d_dev->is_mmu_faulted) == 1) {
				FIMG2D_ERROR("error : sysmmu_faulted\n");
				FIMG2D_ERROR("faulted addr: 0x%x\n", g2d_dev->faulted_addr);
			} else {
				g2d_reset(g2d_dev);
				FIMG2D_ERROR("error : waiting for interrupt is timeout\n");
			}
			atomic_set(&g2d_dev->is_mmu_faulted, 0);
			g2d_fail_debug(params);
			return false;
		} else if(atomic_read(&g2d_dev->is_mmu_faulted) == 1) {
			FIMG2D_ERROR("error : sysmmu_faulted but auto recoveried\n");
			atomic_set(&g2d_dev->is_mmu_faulted, 0);
			return false;
		}
	}
	atomic_set(&g2d_dev->in_use, 0);
	return true;
}
Exemple #2
0
static long g2d_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	g2d_params params;
	int ret = -1;

	struct g2d_dma_info dma_info;

	switch(cmd) {
	case G2D_GET_MEMORY :
		ret =  copy_to_user((unsigned int *)arg,
			&(g2d_dev->reserved_mem.base), sizeof(g2d_dev->reserved_mem.base));
		if (ret) {
			FIMG2D_ERROR("error : copy_to_user\n");
			return -EINVAL;
		}
		return 0;

	case G2D_GET_MEMORY_SIZE :
		ret =  copy_to_user((unsigned int *)arg,
			&(g2d_dev->reserved_mem.size), sizeof(g2d_dev->reserved_mem.size));
		if (ret) {
			FIMG2D_ERROR("error : copy_to_user\n");
			return -EINVAL;
		}
		return 0;

	case G2D_DMA_CACHE_CLEAN :
	case G2D_DMA_CACHE_FLUSH :
		mutex_lock(&g2d_dev->lock);
		ret = copy_from_user(&dma_info, (struct g2d_dma_info *)arg, sizeof(dma_info));

		if (ret) {
			FIMG2D_ERROR("error : copy_from_user\n");
			mutex_unlock(&g2d_dev->lock);
			return -EINVAL;
		}

		if (dma_info.addr == 0) {
			FIMG2D_ERROR("addr Null Error!!!\n");
			mutex_unlock(&g2d_dev->lock);
			return -EINVAL;
		}

		g2d_mem_cache_op(cmd, (void *)dma_info.addr, dma_info.size);
		mutex_unlock(&g2d_dev->lock);
		return 0;

	case G2D_SYNC :
		g2d_check_fifo_state_wait(g2d_dev);
		ret = 0;
		goto g2d_ioctl_done;

	case G2D_RESET :
		g2d_reset(g2d_dev);
		FIMG2D_ERROR("G2D TimeOut Error\n");
		ret = 0;
		goto g2d_ioctl_done;

	case G2D_BLIT:
		if  (atomic_read(&g2d_dev->ready_to_run) == 0)
			goto g2d_ioctl_done2;

		mutex_lock(&g2d_dev->lock);

		g2d_clk_enable(g2d_dev);

		if (copy_from_user(&params, (struct g2d_params *)arg, sizeof(g2d_params))) {
			FIMG2D_ERROR("error : copy_from_user\n");
			goto g2d_ioctl_done;
		}

		g2d_dev->irq_handled = 0;
		atomic_set(&g2d_dev->in_use, 1);
		if (atomic_read(&g2d_dev->ready_to_run) == 0)
			goto g2d_ioctl_done;

		if (!g2d_do_blit(g2d_dev, &params)) {
			g2d_dev->irq_handled = 1;
			goto g2d_ioctl_done;
		}

		if (!(params.flag.render_mode & G2D_HYBRID_MODE)) {
			if(!(file->f_flags & O_NONBLOCK)) {
				if (!g2d_wait_for_finish(g2d_dev, &params))
					goto g2d_ioctl_done;
			}
		} else {
			ret = 0;
			goto g2d_ioctl_done2;
		}

		ret = 0;

		break;
	default :
		goto g2d_ioctl_done2;

		break;
	}

g2d_ioctl_done :

	g2d_clk_disable(g2d_dev);

	mutex_unlock(&g2d_dev->lock);

	atomic_set(&g2d_dev->in_use, 0);

g2d_ioctl_done2 :

	return ret;
}