void m2m1shot_dma_addr_unmap(struct device *dev,
			struct m2m1shot_buffer_dma *buf, int plane_idx)
{
	struct m2m1shot_buffer_plane_dma *plane = &buf->plane[plane_idx];

	if (plane->dmabuf)
		ion_iovmm_unmap(plane->attachment, plane->dma_addr);
	else
		iovmm_unmap(dev, plane->dma_addr);

	plane->dma_addr = 0;
}
Example #2
0
static void fimg2d_unmap_dma_buf(struct fimg2d_control *info,
		struct fimg2d_dma *dma)
{
	if (!dma->dma_addr)
		return;

	iovmm_unmap(info->dev, dma->dma_addr);
	dma_buf_unmap_attachment(dma->attachment, dma->sg_table,
			dma->direction);
	dma_buf_detach(dma->dma_buf, dma->attachment);
	dma_buf_put(dma->dma_buf);
	memset(dma, 0, sizeof(struct fimg2d_dma));
}
Example #3
0
static void vb2_ion_put(void *buf_priv)
{
	struct vb2_ion_buf *buf = buf_priv;
	struct vb2_ion_conf *conf = buf->conf;

	dbg(6, "released: buf_refcnt(%d)\n", atomic_read(&buf->ref) - 1);

	if (atomic_dec_and_test(&buf->ref)) {
		if (conf->use_mmu)
			iovmm_unmap(conf->dev, buf->dva);

		ion_unmap_dma(conf->client, buf->handle);

		if (buf->kva)
			ion_unmap_kernel(conf->client, buf->handle);

		ion_free(conf->client, buf->handle);

		kfree(buf);
	}
}
Example #4
0
static void vb2_ion_put_userptr(void *mem_priv)
{
	struct vb2_ion_buf *buf = mem_priv;
	struct vb2_ion_conf *conf = buf->conf;

	if (!buf) {
		pr_err("No buffer to put\n");
		return;
	}

	/* Unmap DVA, KVA */
	if (conf->use_mmu)
		iovmm_unmap(conf->dev, buf->dva);

	ion_unmap_dma(conf->client, buf->handle);
	if (buf->kva)
		ion_unmap_kernel(conf->client, buf->handle);

	ion_free(conf->client, buf->handle);

	vb2_put_vma(buf->vma);

	kfree(buf);
}
Example #5
0
static void *vb2_ion_get_userptr(void *alloc_ctx, unsigned long vaddr,
				 unsigned long size, int write)
{
	struct vb2_ion_conf *conf = alloc_ctx;
	struct vb2_ion_buf *buf = NULL;
	struct mm_struct *mm = current->mm;
	struct vm_area_struct *vma = NULL;
	size_t len;
	int ret = 0;
	bool malloced = false;
	struct scatterlist *sg;

	/* Create vb2_ion_buf */
	buf = kzalloc(sizeof *buf, GFP_KERNEL);
	if (!buf) {
		pr_err("kzalloc failed\n");
		return ERR_PTR(-ENOMEM);
	}

	/* Getting handle, client from DVA */
	buf->handle = ion_import_uva(conf->client, vaddr);
	if (IS_ERR(buf->handle)) {
		if ((PTR_ERR(buf->handle) == -ENXIO) && conf->use_mmu) {
			int flags = ION_HEAP_EXYNOS_USER_MASK;

			if (write)
				flags |= ION_EXYNOS_WRITE_MASK;

			buf->handle = ion_exynos_get_user_pages(conf->client,
							vaddr, size, flags);
			if (IS_ERR(buf->handle))
				ret = PTR_ERR(buf->handle);
		} else {
			ret = -EINVAL;
		}

		if (ret) {
			pr_err("%s: Failed to retrieving non-ion user buffer @ "
				"0x%lx (size:0x%lx, dev:%s, errno %ld)\n",
				__func__, vaddr, size, dev_name(conf->dev),
					PTR_ERR(buf->handle));
			goto err_import_uva;
		}

		malloced = true;
	}

	/* TODO: Need to check whether already DVA is created or not */

	buf->sg = ion_map_dma(conf->client, buf->handle);
	if (IS_ERR(buf->sg)) {
		ret = -ENOMEM;
		goto err_map_dma;
	}
	dbg(6, "PA(0x%x) size(%x)\n", buf->sg->dma_address, buf->sg->length);

	sg = buf->sg;
	do {
		buf->nents++;
	} while ((sg = sg_next(sg)));

	/* Map DVA */
	if (conf->use_mmu) {
		buf->dva = iovmm_map(conf->dev, buf->sg);
		if (!buf->dva) {
			pr_err("iovmm_map: conf->name(%s)\n", conf->name);
			goto err_ion_map_dva;
		}
		dbg(6, "DVA(0x%x)\n", buf->dva);
	} else {
		ret = ion_phys(conf->client, buf->handle,
			       (unsigned long *)&buf->dva, &len);
		if (ret) {
			pr_err("ion_phys: conf->name(%s)\n", conf->name);
			goto err_ion_map_dva;
		}
	}

	if (!malloced) {
		/* Get offset from the start */
		down_read(&mm->mmap_sem);
		vma = find_vma(mm, vaddr);
		if (vma == NULL) {
			pr_err("Failed acquiring VMA to get offset 0x%08lx\n",
					vaddr);
			up_read(&mm->mmap_sem);

			if (conf->use_mmu)
				iovmm_unmap(conf->dev, buf->dva);

			goto err_get_vma;
		}
		buf->offset = vaddr - vma->vm_start;
		up_read(&mm->mmap_sem);
	}
	dbg(6, "dva(0x%x), size(0x%x), offset(0x%x)\n",
			(u32)buf->dva, (u32)size, (u32)buf->offset);

	/* Set vb2_ion_buf */
	ret = _vb2_ion_get_vma(vaddr, size, &vma);
	if (ret) {
		pr_err("Failed acquiring VMA 0x%08lx\n", vaddr);

		if (conf->use_mmu)
			iovmm_unmap(conf->dev, buf->dva);

		goto err_get_vma;
	}

	buf->vma = vma;
	buf->conf = conf;
	buf->size = size;
	buf->cacheable = conf->cacheable;

	return buf;

err_get_vma:	/* fall through */
err_ion_map_dva:
	ion_unmap_dma(conf->client, buf->handle);

err_map_dma:
	ion_free(conf->client, buf->handle);

err_import_uva:
	kfree(buf);

	return ERR_PTR(ret);
}