@@ -361,73 +361,21 @@ static struct dma_buf_ops vb2_dc_dmabuf_ops = {
.release = vb2_dc_dmabuf_ops_release,
};
-/**
- * vb2_dc_kaddr_to_pages() - extract list of struct pages from a kernel
- * pointer. This function is a workaround to extract pages from a pointer
- * returned by dma_alloc_coherent. The pages are obtained by creating an
- * artificial vma and using follow_pfn to do a page walk to find a PFN
- */
-static int vb2_dc_kaddr_to_pages(unsigned long kaddr,
- struct page **pages, unsigned int n_pages)
-{
- unsigned int i;
- unsigned long pfn;
- /* create an artificial VMA */
- struct vm_area_struct vma = {
- .vm_flags = VM_IO | VM_PFNMAP,
- .vm_mm = &init_mm,
- };
-
- for (i = 0; i < n_pages; ++i, kaddr += PAGE_SIZE) {
- if (follow_pfn(&vma, kaddr, &pfn))
- break;
- pages[i] = pfn_to_page(pfn);
- }
-
- return i;
-}
-
static struct sg_table *vb2_dc_get_base_sgt(struct vb2_dc_buf *buf)
{
- int n_pages;
- struct page **pages = NULL;
int ret;
struct sg_table *sgt;
- n_pages = PAGE_ALIGN(buf->size) >> PAGE_SHIFT;
-
- pages = kmalloc(n_pages * sizeof pages[0], GFP_KERNEL);
- if (!pages) {
- dev_err(buf->dev, "failed to alloc page table\n");
- return ERR_PTR(-ENOMEM);
- }
-
- ret = vb2_dc_kaddr_to_pages((unsigned long)buf->vaddr, pages, n_pages);
- if (ret < 0) {
- dev_err(buf->dev, "failed to get buffer pages from DMA API\n");
- kfree(pages);
- return ERR_PTR(ret);
- }
- if (ret != n_pages) {
- dev_err(buf->dev, "got only %d of %d pages from DMA API\n",
- ret, n_pages);
- kfree(pages);
- return ERR_PTR(-EFAULT);
- }
-
sgt = kmalloc(sizeof *sgt, GFP_KERNEL);
if (!sgt) {
dev_err(buf->dev, "failed to alloc sg table\n");
- kfree(pages);
return ERR_PTR(-ENOMEM);
}
- ret = sg_alloc_table_from_pages(sgt, pages, n_pages, 0,
- buf->size, GFP_KERNEL);
- /* failure or not, pages are no longer needed */
- kfree(pages);
- if (ret) {
- dev_err(buf->dev, "failed to covert pages to sg table\n");
+ ret = dma_get_sgtable(buf->dev, sgt, buf->vaddr, buf->dma_addr,
+ buf->size, NULL);
+ if (ret < 0) {
+ dev_err(buf->dev, "failed to get scatterlist from DMA API\n");
kfree(sgt);
return ERR_PTR(ret);
}