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; }
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)); }
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); } }
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); }
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); }