aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core/pcm_native.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core/pcm_native.c')
-rw-r--r--sound/core/pcm_native.c70
1 files changed, 47 insertions, 23 deletions
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 872887624030..644c2bb17b86 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -36,6 +36,9 @@
#include <sound/timer.h>
#include <sound/minors.h>
#include <asm/io.h>
+#if defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT)
+#include <dma-coherence.h>
+#endif
/*
* Compatibility
@@ -481,11 +484,13 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
snd_pcm_timer_resolution_change(substream);
runtime->status->state = SNDRV_PCM_STATE_SETUP;
- pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY,
- substream->latency_id);
+ if (substream->latency_pm_qos_req) {
+ pm_qos_remove_request(substream->latency_pm_qos_req);
+ substream->latency_pm_qos_req = NULL;
+ }
if ((usecs = period_to_usecs(runtime)) >= 0)
- pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY,
- substream->latency_id, usecs);
+ substream->latency_pm_qos_req = pm_qos_add_request(
+ PM_QOS_CPU_DMA_LATENCY, usecs);
return 0;
_error:
/* hardware might be unuseable from this time,
@@ -540,8 +545,8 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
if (substream->ops->hw_free)
result = substream->ops->hw_free(substream);
runtime->status->state = SNDRV_PCM_STATE_OPEN;
- pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY,
- substream->latency_id);
+ pm_qos_remove_request(substream->latency_pm_qos_req);
+ substream->latency_pm_qos_req = NULL;
return result;
}
@@ -2107,7 +2112,9 @@ static int snd_pcm_open_file(struct file *file,
static int snd_pcm_playback_open(struct inode *inode, struct file *file)
{
struct snd_pcm *pcm;
-
+ int err = nonseekable_open(inode, file);
+ if (err < 0)
+ return err;
pcm = snd_lookup_minor_data(iminor(inode),
SNDRV_DEVICE_TYPE_PCM_PLAYBACK);
return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK);
@@ -2116,7 +2123,9 @@ static int snd_pcm_playback_open(struct inode *inode, struct file *file)
static int snd_pcm_capture_open(struct inode *inode, struct file *file)
{
struct snd_pcm *pcm;
-
+ int err = nonseekable_open(inode, file);
+ if (err < 0)
+ return err;
pcm = snd_lookup_minor_data(iminor(inode),
SNDRV_DEVICE_TYPE_PCM_CAPTURE);
return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE);
@@ -3184,6 +3193,10 @@ static int snd_pcm_default_mmap(struct snd_pcm_substream *substream,
substream->runtime->dma_area,
substream->runtime->dma_addr,
area->vm_end - area->vm_start);
+#elif defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT)
+ if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV &&
+ !plat_device_is_coherent(substream->dma_buffer.dev.dev))
+ area->vm_page_prot = pgprot_noncached(area->vm_page_prot);
#endif /* ARCH_HAS_DMA_MMAP_COHERENT */
/* mmap with fault handler */
area->vm_ops = &snd_pcm_vm_ops_data_fault;
@@ -3303,18 +3316,13 @@ static int snd_pcm_fasync(int fd, struct file * file, int on)
struct snd_pcm_file * pcm_file;
struct snd_pcm_substream *substream;
struct snd_pcm_runtime *runtime;
- int err = -ENXIO;
- lock_kernel();
pcm_file = file->private_data;
substream = pcm_file->substream;
if (PCM_RUNTIME_CHECK(substream))
- goto out;
+ return -ENXIO;
runtime = substream->runtime;
- err = fasync_helper(fd, file, on, &runtime->fasync);
-out:
- unlock_kernel();
- return err;
+ return fasync_helper(fd, file, on, &runtime->fasync);
}
/*
@@ -3434,14 +3442,28 @@ out:
#endif /* CONFIG_SND_SUPPORT_OLD_API */
#ifndef CONFIG_MMU
-unsigned long dummy_get_unmapped_area(struct file *file, unsigned long addr,
- unsigned long len, unsigned long pgoff,
- unsigned long flags)
-{
- return 0;
+static unsigned long snd_pcm_get_unmapped_area(struct file *file,
+ unsigned long addr,
+ unsigned long len,
+ unsigned long pgoff,
+ unsigned long flags)
+{
+ struct snd_pcm_file *pcm_file = file->private_data;
+ struct snd_pcm_substream *substream = pcm_file->substream;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ unsigned long offset = pgoff << PAGE_SHIFT;
+
+ switch (offset) {
+ case SNDRV_PCM_MMAP_OFFSET_STATUS:
+ return (unsigned long)runtime->status;
+ case SNDRV_PCM_MMAP_OFFSET_CONTROL:
+ return (unsigned long)runtime->control;
+ default:
+ return (unsigned long)runtime->dma_area + offset;
+ }
}
#else
-# define dummy_get_unmapped_area NULL
+# define snd_pcm_get_unmapped_area NULL
#endif
/*
@@ -3455,12 +3477,13 @@ const struct file_operations snd_pcm_f_ops[2] = {
.aio_write = snd_pcm_aio_write,
.open = snd_pcm_playback_open,
.release = snd_pcm_release,
+ .llseek = no_llseek,
.poll = snd_pcm_playback_poll,
.unlocked_ioctl = snd_pcm_playback_ioctl,
.compat_ioctl = snd_pcm_ioctl_compat,
.mmap = snd_pcm_mmap,
.fasync = snd_pcm_fasync,
- .get_unmapped_area = dummy_get_unmapped_area,
+ .get_unmapped_area = snd_pcm_get_unmapped_area,
},
{
.owner = THIS_MODULE,
@@ -3468,11 +3491,12 @@ const struct file_operations snd_pcm_f_ops[2] = {
.aio_read = snd_pcm_aio_read,
.open = snd_pcm_capture_open,
.release = snd_pcm_release,
+ .llseek = no_llseek,
.poll = snd_pcm_capture_poll,
.unlocked_ioctl = snd_pcm_capture_ioctl,
.compat_ioctl = snd_pcm_ioctl_compat,
.mmap = snd_pcm_mmap,
.fasync = snd_pcm_fasync,
- .get_unmapped_area = dummy_get_unmapped_area,
+ .get_unmapped_area = snd_pcm_get_unmapped_area,
}
};