aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2014-10-23 04:56:48 -0400
committerTakashi Iwai <tiwai@suse.de>2014-10-23 04:56:48 -0400
commit805772708741c7bee00aa8a73177375eee50d7e0 (patch)
tree7c728d1e08cf2c1712dde310f4a540bf3cbeb27e /sound/core
parent930352862e9533fecc42c7ed20798a7c9e3aa874 (diff)
parent63825f3a879ea2be569471643bb6aac73d9261f0 (diff)
Merge branch 'topic/pcm-mmap-cleanup' into for-next
This drags a few post-3.18 mmap fixes, a cleanup of dma_mmap_coherent() usages and additional fixups for some architectures.
Diffstat (limited to 'sound/core')
-rw-r--r--sound/core/pcm_native.c53
1 files changed, 21 insertions, 32 deletions
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 815396d8427f..dc9a1355a4ab 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -35,9 +35,6 @@
35#include <sound/timer.h> 35#include <sound/timer.h>
36#include <sound/minors.h> 36#include <sound/minors.h>
37#include <asm/io.h> 37#include <asm/io.h>
38#if defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT)
39#include <dma-coherence.h>
40#endif
41 38
42/* 39/*
43 * Compatibility 40 * Compatibility
@@ -195,6 +192,21 @@ int snd_pcm_info_user(struct snd_pcm_substream *substream,
195 return err; 192 return err;
196} 193}
197 194
195static bool hw_support_mmap(struct snd_pcm_substream *substream)
196{
197 if (!(substream->runtime->hw.info & SNDRV_PCM_INFO_MMAP))
198 return false;
199 /* check architectures that return -EINVAL from dma_mmap_coherent() */
200 /* FIXME: this should be some global flag */
201#if defined(CONFIG_C6X) || defined(CONFIG_FRV) || defined(CONFIG_MN10300) ||\
202 defined(CONFIG_PARISC) || defined(CONFIG_XTENSA)
203 if (!substream->ops->mmap &&
204 substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV)
205 return false;
206#endif
207 return true;
208}
209
198#undef RULES_DEBUG 210#undef RULES_DEBUG
199 211
200#ifdef RULES_DEBUG 212#ifdef RULES_DEBUG
@@ -372,8 +384,12 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream,
372 } 384 }
373 385
374 hw = &substream->runtime->hw; 386 hw = &substream->runtime->hw;
375 if (!params->info) 387 if (!params->info) {
376 params->info = hw->info & ~SNDRV_PCM_INFO_FIFO_IN_FRAMES; 388 params->info = hw->info & ~SNDRV_PCM_INFO_FIFO_IN_FRAMES;
389 if (!hw_support_mmap(substream))
390 params->info &= ~(SNDRV_PCM_INFO_MMAP |
391 SNDRV_PCM_INFO_MMAP_VALID);
392 }
377 if (!params->fifo_size) { 393 if (!params->fifo_size) {
378 m = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); 394 m = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
379 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); 395 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
@@ -2072,7 +2088,7 @@ int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream)
2072 mask |= 1 << SNDRV_PCM_ACCESS_RW_INTERLEAVED; 2088 mask |= 1 << SNDRV_PCM_ACCESS_RW_INTERLEAVED;
2073 if (hw->info & SNDRV_PCM_INFO_NONINTERLEAVED) 2089 if (hw->info & SNDRV_PCM_INFO_NONINTERLEAVED)
2074 mask |= 1 << SNDRV_PCM_ACCESS_RW_NONINTERLEAVED; 2090 mask |= 1 << SNDRV_PCM_ACCESS_RW_NONINTERLEAVED;
2075 if (hw->info & SNDRV_PCM_INFO_MMAP) { 2091 if (hw_support_mmap(substream)) {
2076 if (hw->info & SNDRV_PCM_INFO_INTERLEAVED) 2092 if (hw->info & SNDRV_PCM_INFO_INTERLEAVED)
2077 mask |= 1 << SNDRV_PCM_ACCESS_MMAP_INTERLEAVED; 2093 mask |= 1 << SNDRV_PCM_ACCESS_MMAP_INTERLEAVED;
2078 if (hw->info & SNDRV_PCM_INFO_NONINTERLEAVED) 2094 if (hw->info & SNDRV_PCM_INFO_NONINTERLEAVED)
@@ -3251,20 +3267,6 @@ static inline struct page *
3251snd_pcm_default_page_ops(struct snd_pcm_substream *substream, unsigned long ofs) 3267snd_pcm_default_page_ops(struct snd_pcm_substream *substream, unsigned long ofs)
3252{ 3268{
3253 void *vaddr = substream->runtime->dma_area + ofs; 3269 void *vaddr = substream->runtime->dma_area + ofs;
3254#if defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT)
3255 if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV)
3256 return virt_to_page(CAC_ADDR(vaddr));
3257#endif
3258#if defined(CONFIG_PPC32) && defined(CONFIG_NOT_COHERENT_CACHE)
3259 if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV) {
3260 dma_addr_t addr = substream->runtime->dma_addr + ofs;
3261 addr -= get_dma_offset(substream->dma_buffer.dev.dev);
3262 /* assume dma_handle set via pfn_to_phys() in
3263 * mm/dma-noncoherent.c
3264 */
3265 return pfn_to_page(addr >> PAGE_SHIFT);
3266 }
3267#endif
3268 return virt_to_page(vaddr); 3270 return virt_to_page(vaddr);
3269} 3271}
3270 3272
@@ -3309,13 +3311,6 @@ static const struct vm_operations_struct snd_pcm_vm_ops_data_fault = {
3309 .fault = snd_pcm_mmap_data_fault, 3311 .fault = snd_pcm_mmap_data_fault,
3310}; 3312};
3311 3313
3312#ifndef ARCH_HAS_DMA_MMAP_COHERENT
3313/* This should be defined / handled globally! */
3314#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
3315#define ARCH_HAS_DMA_MMAP_COHERENT
3316#endif
3317#endif
3318
3319/* 3314/*
3320 * mmap the DMA buffer on RAM 3315 * mmap the DMA buffer on RAM
3321 */ 3316 */
@@ -3331,7 +3326,6 @@ int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream,
3331 area->vm_end - area->vm_start, area->vm_page_prot); 3326 area->vm_end - area->vm_start, area->vm_page_prot);
3332 } 3327 }
3333#endif /* CONFIG_GENERIC_ALLOCATOR */ 3328#endif /* CONFIG_GENERIC_ALLOCATOR */
3334#ifdef ARCH_HAS_DMA_MMAP_COHERENT
3335 if (!substream->ops->page && 3329 if (!substream->ops->page &&
3336 substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV) 3330 substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV)
3337 return dma_mmap_coherent(substream->dma_buffer.dev.dev, 3331 return dma_mmap_coherent(substream->dma_buffer.dev.dev,
@@ -3339,11 +3333,6 @@ int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream,
3339 substream->runtime->dma_area, 3333 substream->runtime->dma_area,
3340 substream->runtime->dma_addr, 3334 substream->runtime->dma_addr,
3341 area->vm_end - area->vm_start); 3335 area->vm_end - area->vm_start);
3342#elif defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT)
3343 if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV &&
3344 !plat_device_is_coherent(substream->dma_buffer.dev.dev))
3345 area->vm_page_prot = pgprot_noncached(area->vm_page_prot);
3346#endif /* ARCH_HAS_DMA_MMAP_COHERENT */
3347 /* mmap with fault handler */ 3336 /* mmap with fault handler */
3348 area->vm_ops = &snd_pcm_vm_ops_data_fault; 3337 area->vm_ops = &snd_pcm_vm_ops_data_fault;
3349 return 0; 3338 return 0;