diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-17 11:26:17 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-17 11:26:17 -0500 |
commit | 3c2e81ef344a90bb0a39d84af6878b4aeff568a2 (patch) | |
tree | bd8c8b23466174899d2fe4d35af6e1e838edb068 /arch | |
parent | 221392c3ad0432e39fd74a349364f66cb0ed78f6 (diff) | |
parent | 55bde6b1442fed8af67b92d21acce67db454c9f9 (diff) |
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
...
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mm/dma-mapping.c | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 5383bc018571..6b2fb87c8698 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c | |||
@@ -1034,7 +1034,8 @@ static inline void __free_iova(struct dma_iommu_mapping *mapping, | |||
1034 | spin_unlock_irqrestore(&mapping->lock, flags); | 1034 | spin_unlock_irqrestore(&mapping->lock, flags); |
1035 | } | 1035 | } |
1036 | 1036 | ||
1037 | static struct page **__iommu_alloc_buffer(struct device *dev, size_t size, gfp_t gfp) | 1037 | static struct page **__iommu_alloc_buffer(struct device *dev, size_t size, |
1038 | gfp_t gfp, struct dma_attrs *attrs) | ||
1038 | { | 1039 | { |
1039 | struct page **pages; | 1040 | struct page **pages; |
1040 | int count = size >> PAGE_SHIFT; | 1041 | int count = size >> PAGE_SHIFT; |
@@ -1048,6 +1049,23 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size, gfp_t | |||
1048 | if (!pages) | 1049 | if (!pages) |
1049 | return NULL; | 1050 | return NULL; |
1050 | 1051 | ||
1052 | if (dma_get_attr(DMA_ATTR_FORCE_CONTIGUOUS, attrs)) | ||
1053 | { | ||
1054 | unsigned long order = get_order(size); | ||
1055 | struct page *page; | ||
1056 | |||
1057 | page = dma_alloc_from_contiguous(dev, count, order); | ||
1058 | if (!page) | ||
1059 | goto error; | ||
1060 | |||
1061 | __dma_clear_buffer(page, size); | ||
1062 | |||
1063 | for (i = 0; i < count; i++) | ||
1064 | pages[i] = page + i; | ||
1065 | |||
1066 | return pages; | ||
1067 | } | ||
1068 | |||
1051 | while (count) { | 1069 | while (count) { |
1052 | int j, order = __fls(count); | 1070 | int j, order = __fls(count); |
1053 | 1071 | ||
@@ -1081,14 +1099,21 @@ error: | |||
1081 | return NULL; | 1099 | return NULL; |
1082 | } | 1100 | } |
1083 | 1101 | ||
1084 | static int __iommu_free_buffer(struct device *dev, struct page **pages, size_t size) | 1102 | static int __iommu_free_buffer(struct device *dev, struct page **pages, |
1103 | size_t size, struct dma_attrs *attrs) | ||
1085 | { | 1104 | { |
1086 | int count = size >> PAGE_SHIFT; | 1105 | int count = size >> PAGE_SHIFT; |
1087 | int array_size = count * sizeof(struct page *); | 1106 | int array_size = count * sizeof(struct page *); |
1088 | int i; | 1107 | int i; |
1089 | for (i = 0; i < count; i++) | 1108 | |
1090 | if (pages[i]) | 1109 | if (dma_get_attr(DMA_ATTR_FORCE_CONTIGUOUS, attrs)) { |
1091 | __free_pages(pages[i], 0); | 1110 | dma_release_from_contiguous(dev, pages[0], count); |
1111 | } else { | ||
1112 | for (i = 0; i < count; i++) | ||
1113 | if (pages[i]) | ||
1114 | __free_pages(pages[i], 0); | ||
1115 | } | ||
1116 | |||
1092 | if (array_size <= PAGE_SIZE) | 1117 | if (array_size <= PAGE_SIZE) |
1093 | kfree(pages); | 1118 | kfree(pages); |
1094 | else | 1119 | else |
@@ -1250,7 +1275,7 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size, | |||
1250 | if (gfp & GFP_ATOMIC) | 1275 | if (gfp & GFP_ATOMIC) |
1251 | return __iommu_alloc_atomic(dev, size, handle); | 1276 | return __iommu_alloc_atomic(dev, size, handle); |
1252 | 1277 | ||
1253 | pages = __iommu_alloc_buffer(dev, size, gfp); | 1278 | pages = __iommu_alloc_buffer(dev, size, gfp, attrs); |
1254 | if (!pages) | 1279 | if (!pages) |
1255 | return NULL; | 1280 | return NULL; |
1256 | 1281 | ||
@@ -1271,7 +1296,7 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size, | |||
1271 | err_mapping: | 1296 | err_mapping: |
1272 | __iommu_remove_mapping(dev, *handle, size); | 1297 | __iommu_remove_mapping(dev, *handle, size); |
1273 | err_buffer: | 1298 | err_buffer: |
1274 | __iommu_free_buffer(dev, pages, size); | 1299 | __iommu_free_buffer(dev, pages, size, attrs); |
1275 | return NULL; | 1300 | return NULL; |
1276 | } | 1301 | } |
1277 | 1302 | ||
@@ -1327,7 +1352,7 @@ void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr, | |||
1327 | } | 1352 | } |
1328 | 1353 | ||
1329 | __iommu_remove_mapping(dev, handle, size); | 1354 | __iommu_remove_mapping(dev, handle, size); |
1330 | __iommu_free_buffer(dev, pages, size); | 1355 | __iommu_free_buffer(dev, pages, size, attrs); |
1331 | } | 1356 | } |
1332 | 1357 | ||
1333 | static int arm_iommu_get_sgtable(struct device *dev, struct sg_table *sgt, | 1358 | static int arm_iommu_get_sgtable(struct device *dev, struct sg_table *sgt, |