summaryrefslogtreecommitdiff
path: root/sound/soc/intel/sst-haswell-ipc.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2014-05-14 14:27:12 +0200
committerTakashi Iwai <tiwai@suse.de>2014-05-14 14:27:12 +0200
commitff2354bc6e54cc7e024744b7b4065a081fd87f6e (patch)
tree56a94347fbe5bb8cbb7998ba2e57f658afca3a02 /sound/soc/intel/sst-haswell-ipc.c
parent7ca33c7a1d7f8566d8b08a0df55b26758d985a15 (diff)
parentcffd6665f57ed18f4be9185c4330c8c98c22e201 (diff)
downloadlwn-ff2354bc6e54cc7e024744b7b4065a081fd87f6e.tar.gz
lwn-ff2354bc6e54cc7e024744b7b4065a081fd87f6e.zip
Merge tag 'asoc-v3.15-rc5-intel' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Intel fixes for v3.15 This is a relatively large batch of fixes for the newly added Haswell/Baytrail drivers from Intel. It's a bit larger than is good for this point in the cycle but it's all for a newly added driver so not so worrying as it might otherwise be. Some of it's integration problems, some of it's the sort of problem usually turned up in stress tests.
Diffstat (limited to 'sound/soc/intel/sst-haswell-ipc.c')
-rw-r--r--sound/soc/intel/sst-haswell-ipc.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/sound/soc/intel/sst-haswell-ipc.c b/sound/soc/intel/sst-haswell-ipc.c
index 50e4246d4b57..e7996b39a484 100644
--- a/sound/soc/intel/sst-haswell-ipc.c
+++ b/sound/soc/intel/sst-haswell-ipc.c
@@ -1159,11 +1159,14 @@ struct sst_hsw_stream *sst_hsw_stream_new(struct sst_hsw *hsw, int id,
void *data)
{
struct sst_hsw_stream *stream;
+ struct sst_dsp *sst = hsw->dsp;
+ unsigned long flags;
stream = kzalloc(sizeof(*stream), GFP_KERNEL);
if (stream == NULL)
return NULL;
+ spin_lock_irqsave(&sst->spinlock, flags);
list_add(&stream->node, &hsw->stream_list);
stream->notify_position = notify_position;
stream->pdata = data;
@@ -1172,6 +1175,7 @@ struct sst_hsw_stream *sst_hsw_stream_new(struct sst_hsw *hsw, int id,
/* work to process notification messages */
INIT_WORK(&stream->notify_work, hsw_notification_work);
+ spin_unlock_irqrestore(&sst->spinlock, flags);
return stream;
}
@@ -1180,6 +1184,8 @@ int sst_hsw_stream_free(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
{
u32 header;
int ret = 0;
+ struct sst_dsp *sst = hsw->dsp;
+ unsigned long flags;
/* dont free DSP streams that are not commited */
if (!stream->commited)
@@ -1201,8 +1207,11 @@ int sst_hsw_stream_free(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
trace_hsw_stream_free_req(stream, &stream->free_req);
out:
+ cancel_work_sync(&stream->notify_work);
+ spin_lock_irqsave(&sst->spinlock, flags);
list_del(&stream->node);
kfree(stream);
+ spin_unlock_irqrestore(&sst->spinlock, flags);
return ret;
}
@@ -1538,10 +1547,28 @@ int sst_hsw_stream_reset(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
}
/* Stream pointer positions */
-int sst_hsw_get_dsp_position(struct sst_hsw *hsw,
+u32 sst_hsw_get_dsp_position(struct sst_hsw *hsw,
struct sst_hsw_stream *stream)
{
- return stream->rpos.position;
+ u32 rpos;
+
+ sst_dsp_read(hsw->dsp, &rpos,
+ stream->reply.read_position_register_address, sizeof(rpos));
+
+ return rpos;
+}
+
+/* Stream presentation (monotonic) positions */
+u64 sst_hsw_get_dsp_presentation_position(struct sst_hsw *hsw,
+ struct sst_hsw_stream *stream)
+{
+ u64 ppos;
+
+ sst_dsp_read(hsw->dsp, &ppos,
+ stream->reply.presentation_position_register_address,
+ sizeof(ppos));
+
+ return ppos;
}
int sst_hsw_stream_set_write_position(struct sst_hsw *hsw,