diff options
| -rw-r--r-- | arch/x86/kernel/pci-nommu.c | 19 | ||||
| -rw-r--r-- | include/asm-x86/dma-mapping.h | 32 |
2 files changed, 30 insertions, 21 deletions
diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c index ada1c87cafc..8e398b56f50 100644 --- a/arch/x86/kernel/pci-nommu.c +++ b/arch/x86/kernel/pci-nommu.c | |||
| @@ -80,26 +80,11 @@ nommu_alloc_coherent(struct device *hwdev, size_t size, | |||
| 80 | int node; | 80 | int node; |
| 81 | struct page *page; | 81 | struct page *page; |
| 82 | 82 | ||
| 83 | gfp |= __GFP_ZERO; | 83 | dma_mask = dma_alloc_coherent_mask(hwdev, gfp); |
| 84 | |||
| 85 | dma_mask = hwdev->coherent_dma_mask; | ||
| 86 | if (!dma_mask) | ||
| 87 | dma_mask = *(hwdev->dma_mask); | ||
| 88 | 84 | ||
| 89 | if (dma_mask < DMA_24BIT_MASK) | 85 | gfp |= __GFP_ZERO; |
| 90 | return NULL; | ||
| 91 | 86 | ||
| 92 | node = dev_to_node(hwdev); | 87 | node = dev_to_node(hwdev); |
| 93 | |||
| 94 | #ifdef CONFIG_X86_64 | ||
| 95 | if (dma_mask <= DMA_32BIT_MASK && !(gfp & GFP_DMA)) | ||
| 96 | gfp |= GFP_DMA32; | ||
| 97 | #endif | ||
| 98 | |||
| 99 | /* No alloc-free penalty for ISA devices */ | ||
| 100 | if (dma_mask == DMA_24BIT_MASK) | ||
| 101 | gfp |= GFP_DMA; | ||
| 102 | |||
| 103 | again: | 88 | again: |
| 104 | page = alloc_pages_node(node, gfp, get_order(size)); | 89 | page = alloc_pages_node(node, gfp, get_order(size)); |
| 105 | if (!page) | 90 | if (!page) |
diff --git a/include/asm-x86/dma-mapping.h b/include/asm-x86/dma-mapping.h index ad8b49032d1..0cc022b9a4a 100644 --- a/include/asm-x86/dma-mapping.h +++ b/include/asm-x86/dma-mapping.h | |||
| @@ -239,6 +239,29 @@ static inline int dma_get_cache_alignment(void) | |||
| 239 | return boot_cpu_data.x86_clflush_size; | 239 | return boot_cpu_data.x86_clflush_size; |
| 240 | } | 240 | } |
| 241 | 241 | ||
| 242 | static inline unsigned long dma_alloc_coherent_mask(struct device *dev, | ||
| 243 | gfp_t gfp) | ||
| 244 | { | ||
| 245 | unsigned long dma_mask = 0; | ||
| 246 | |||
| 247 | dma_mask = dev->coherent_dma_mask; | ||
| 248 | if (!dma_mask) | ||
| 249 | dma_mask = (gfp & GFP_DMA) ? DMA_24BIT_MASK : DMA_32BIT_MASK; | ||
| 250 | |||
| 251 | return dma_mask; | ||
| 252 | } | ||
| 253 | |||
| 254 | static inline gfp_t dma_alloc_coherent_gfp_flags(struct device *dev, gfp_t gfp) | ||
| 255 | { | ||
| 256 | unsigned long dma_mask = dma_alloc_coherent_mask(dev, gfp); | ||
| 257 | |||
| 258 | #ifdef CONFIG_X86_64 | ||
| 259 | if (dma_mask <= DMA_32BIT_MASK && !(gfp & GFP_DMA)) | ||
| 260 | gfp |= GFP_DMA32; | ||
| 261 | #endif | ||
| 262 | return gfp; | ||
| 263 | } | ||
| 264 | |||
| 242 | static inline void * | 265 | static inline void * |
| 243 | dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, | 266 | dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, |
| 244 | gfp_t gfp) | 267 | gfp_t gfp) |
| @@ -259,10 +282,11 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, | |||
| 259 | if (!dev->dma_mask) | 282 | if (!dev->dma_mask) |
| 260 | return NULL; | 283 | return NULL; |
| 261 | 284 | ||
| 262 | if (ops->alloc_coherent) | 285 | if (!ops->alloc_coherent) |
| 263 | return ops->alloc_coherent(dev, size, | 286 | return NULL; |
| 264 | dma_handle, gfp); | 287 | |
| 265 | return NULL; | 288 | return ops->alloc_coherent(dev, size, dma_handle, |
| 289 | dma_alloc_coherent_gfp_flags(dev, gfp)); | ||
| 266 | } | 290 | } |
| 267 | 291 | ||
| 268 | static inline void dma_free_coherent(struct device *dev, size_t size, | 292 | static inline void dma_free_coherent(struct device *dev, size_t size, |
