diff options
author | Takashi Iwai <tiwai@suse.de> | 2014-10-23 04:56:48 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2014-10-23 04:56:48 -0400 |
commit | 805772708741c7bee00aa8a73177375eee50d7e0 (patch) | |
tree | 7c728d1e08cf2c1712dde310f4a540bf3cbeb27e /sound/core | |
parent | 930352862e9533fecc42c7ed20798a7c9e3aa874 (diff) | |
parent | 63825f3a879ea2be569471643bb6aac73d9261f0 (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.c | 53 |
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 | ||
195 | static 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 * | |||
3251 | snd_pcm_default_page_ops(struct snd_pcm_substream *substream, unsigned long ofs) | 3267 | snd_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; |