Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Pull DRM updates from Dave Airlie: "This is the one and only next pull for 3.8, we had a regression we found last week, so I was waiting for that to resolve itself, and I ended up with some Intel fixes on top as well. Highlights: - new driver: nvidia tegra 20/30/hdmi support - radeon: add support for previously unused DMA engines, more HDMI regs, eviction speeds ups and fixes - i915: HSW support enable, agp removal on GEN6, seqno wrapping - exynos: IPP subsystem support (image post proc), HDMI - nouveau: display class reworking, nv20->40 z compression - ttm: start of locking fixes, rcu usage for lookups, - core: documentation updates, docbook integration, monotonic clock usage, move from connector to object properties" * 'drm-next' of git://people.freedesktop.org/~airlied/linux: (590 commits) drm/exynos: add gsc ipp driver drm/exynos: add rotator ipp driver drm/exynos: add fimc ipp driver drm/exynos: add iommu support for ipp drm/exynos: add ipp subsystem drm/exynos: support device tree for fimd radeon: fix regression with eviction since evict caching changes drm/radeon: add more pedantic checks in the CP DMA checker drm/radeon: bump version for CS ioctl support for async DMA drm/radeon: enable the async DMA rings in the CS ioctl drm/radeon: add VM CS parser support for async DMA on cayman/TN/SI drm/radeon/kms: add evergreen/cayman CS parser for async DMA (v2) drm/radeon/kms: add 6xx/7xx CS parser for async DMA (v2) drm/radeon: fix htile buffer size computation for command stream checker drm/radeon: fix fence locking in the pageflip callback drm/radeon: make indirect register access concurrency-safe drm/radeon: add W|RREG32_IDX for MM_INDEX|DATA based mmio accesss drm/exynos: support extended screen coordinate of fimd drm/exynos: fix x, y coordinates for right bottom pixel drm/exynos: fix fb offset calculation for plane ...
This commit is contained in:
@@ -1034,7 +1034,8 @@ static inline void __free_iova(struct dma_iommu_mapping *mapping,
|
||||
spin_unlock_irqrestore(&mapping->lock, flags);
|
||||
}
|
||||
|
||||
static struct page **__iommu_alloc_buffer(struct device *dev, size_t size, gfp_t gfp)
|
||||
static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
|
||||
gfp_t gfp, struct dma_attrs *attrs)
|
||||
{
|
||||
struct page **pages;
|
||||
int count = size >> PAGE_SHIFT;
|
||||
@@ -1048,6 +1049,23 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size, gfp_t
|
||||
if (!pages)
|
||||
return NULL;
|
||||
|
||||
if (dma_get_attr(DMA_ATTR_FORCE_CONTIGUOUS, attrs))
|
||||
{
|
||||
unsigned long order = get_order(size);
|
||||
struct page *page;
|
||||
|
||||
page = dma_alloc_from_contiguous(dev, count, order);
|
||||
if (!page)
|
||||
goto error;
|
||||
|
||||
__dma_clear_buffer(page, size);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
pages[i] = page + i;
|
||||
|
||||
return pages;
|
||||
}
|
||||
|
||||
while (count) {
|
||||
int j, order = __fls(count);
|
||||
|
||||
@@ -1081,14 +1099,21 @@ error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int __iommu_free_buffer(struct device *dev, struct page **pages, size_t size)
|
||||
static int __iommu_free_buffer(struct device *dev, struct page **pages,
|
||||
size_t size, struct dma_attrs *attrs)
|
||||
{
|
||||
int count = size >> PAGE_SHIFT;
|
||||
int array_size = count * sizeof(struct page *);
|
||||
int i;
|
||||
for (i = 0; i < count; i++)
|
||||
if (pages[i])
|
||||
__free_pages(pages[i], 0);
|
||||
|
||||
if (dma_get_attr(DMA_ATTR_FORCE_CONTIGUOUS, attrs)) {
|
||||
dma_release_from_contiguous(dev, pages[0], count);
|
||||
} else {
|
||||
for (i = 0; i < count; i++)
|
||||
if (pages[i])
|
||||
__free_pages(pages[i], 0);
|
||||
}
|
||||
|
||||
if (array_size <= PAGE_SIZE)
|
||||
kfree(pages);
|
||||
else
|
||||
@@ -1250,7 +1275,7 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
|
||||
if (gfp & GFP_ATOMIC)
|
||||
return __iommu_alloc_atomic(dev, size, handle);
|
||||
|
||||
pages = __iommu_alloc_buffer(dev, size, gfp);
|
||||
pages = __iommu_alloc_buffer(dev, size, gfp, attrs);
|
||||
if (!pages)
|
||||
return NULL;
|
||||
|
||||
@@ -1271,7 +1296,7 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
|
||||
err_mapping:
|
||||
__iommu_remove_mapping(dev, *handle, size);
|
||||
err_buffer:
|
||||
__iommu_free_buffer(dev, pages, size);
|
||||
__iommu_free_buffer(dev, pages, size, attrs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1327,7 +1352,7 @@ void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
|
||||
}
|
||||
|
||||
__iommu_remove_mapping(dev, handle, size);
|
||||
__iommu_free_buffer(dev, pages, size);
|
||||
__iommu_free_buffer(dev, pages, size, attrs);
|
||||
}
|
||||
|
||||
static int arm_iommu_get_sgtable(struct device *dev, struct sg_table *sgt,
|
||||
|
Reference in New Issue
Block a user