mirror of https://gitee.com/openkylin/linux.git
videobuf2: replace a layering violation with dma_map_resource
vb2_dc_get_userptr pokes into arm direct mapping details to get the resemblance of a dma address for a a physical address that does is not backed by a page struct. Not only is this not portable to other architectures with dma direct mapping offsets, but also not to uses of IOMMUs of any kind. Switch to the proper dma_map_resource / dma_unmap_resource interface instead. Signed-off-by: Christoph Hellwig <hch@lst.de> Acked-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
This commit is contained in:
parent
645386dfe6
commit
55ea54441f
|
@ -439,42 +439,14 @@ static void vb2_dc_put_userptr(void *buf_priv)
|
|||
set_page_dirty_lock(pages[i]);
|
||||
sg_free_table(sgt);
|
||||
kfree(sgt);
|
||||
} else {
|
||||
dma_unmap_resource(buf->dev, buf->dma_addr, buf->size,
|
||||
buf->dma_dir, 0);
|
||||
}
|
||||
vb2_destroy_framevec(buf->vec);
|
||||
kfree(buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* For some kind of reserved memory there might be no struct page available,
|
||||
* so all that can be done to support such 'pages' is to try to convert
|
||||
* pfn to dma address or at the last resort just assume that
|
||||
* dma address == physical address (like it has been assumed in earlier version
|
||||
* of videobuf2-dma-contig
|
||||
*/
|
||||
|
||||
#ifdef __arch_pfn_to_dma
|
||||
static inline dma_addr_t vb2_dc_pfn_to_dma(struct device *dev, unsigned long pfn)
|
||||
{
|
||||
return (dma_addr_t)__arch_pfn_to_dma(dev, pfn);
|
||||
}
|
||||
#elif defined(__pfn_to_bus)
|
||||
static inline dma_addr_t vb2_dc_pfn_to_dma(struct device *dev, unsigned long pfn)
|
||||
{
|
||||
return (dma_addr_t)__pfn_to_bus(pfn);
|
||||
}
|
||||
#elif defined(__pfn_to_phys)
|
||||
static inline dma_addr_t vb2_dc_pfn_to_dma(struct device *dev, unsigned long pfn)
|
||||
{
|
||||
return (dma_addr_t)__pfn_to_phys(pfn);
|
||||
}
|
||||
#else
|
||||
static inline dma_addr_t vb2_dc_pfn_to_dma(struct device *dev, unsigned long pfn)
|
||||
{
|
||||
/* really, we cannot do anything better at this point */
|
||||
return (dma_addr_t)(pfn) << PAGE_SHIFT;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void *vb2_dc_get_userptr(struct device *dev, unsigned long vaddr,
|
||||
unsigned long size, enum dma_data_direction dma_dir)
|
||||
{
|
||||
|
@ -528,7 +500,12 @@ static void *vb2_dc_get_userptr(struct device *dev, unsigned long vaddr,
|
|||
for (i = 1; i < n_pages; i++)
|
||||
if (nums[i-1] + 1 != nums[i])
|
||||
goto fail_pfnvec;
|
||||
buf->dma_addr = vb2_dc_pfn_to_dma(buf->dev, nums[0]);
|
||||
buf->dma_addr = dma_map_resource(buf->dev,
|
||||
__pfn_to_phys(nums[0]), size, buf->dma_dir, 0);
|
||||
if (dma_mapping_error(buf->dev, buf->dma_addr)) {
|
||||
ret = -ENOMEM;
|
||||
goto fail_pfnvec;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue