diff options
Diffstat (limited to 'sound/soc/intel/sst-haswell-ipc.c')
-rw-r--r-- | sound/soc/intel/sst-haswell-ipc.c | 31 |
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, | |||
1159 | void *data) | 1159 | void *data) |
1160 | { | 1160 | { |
1161 | struct sst_hsw_stream *stream; | 1161 | struct sst_hsw_stream *stream; |
1162 | struct sst_dsp *sst = hsw->dsp; | ||
1163 | unsigned long flags; | ||
1162 | 1164 | ||
1163 | stream = kzalloc(sizeof(*stream), GFP_KERNEL); | 1165 | stream = kzalloc(sizeof(*stream), GFP_KERNEL); |
1164 | if (stream == NULL) | 1166 | if (stream == NULL) |
1165 | return NULL; | 1167 | return NULL; |
1166 | 1168 | ||
1169 | spin_lock_irqsave(&sst->spinlock, flags); | ||
1167 | list_add(&stream->node, &hsw->stream_list); | 1170 | list_add(&stream->node, &hsw->stream_list); |
1168 | stream->notify_position = notify_position; | 1171 | stream->notify_position = notify_position; |
1169 | stream->pdata = data; | 1172 | stream->pdata = data; |
@@ -1172,6 +1175,7 @@ struct sst_hsw_stream *sst_hsw_stream_new(struct sst_hsw *hsw, int id, | |||
1172 | 1175 | ||
1173 | /* work to process notification messages */ | 1176 | /* work to process notification messages */ |
1174 | INIT_WORK(&stream->notify_work, hsw_notification_work); | 1177 | INIT_WORK(&stream->notify_work, hsw_notification_work); |
1178 | spin_unlock_irqrestore(&sst->spinlock, flags); | ||
1175 | 1179 | ||
1176 | return stream; | 1180 | return stream; |
1177 | } | 1181 | } |
@@ -1180,6 +1184,8 @@ int sst_hsw_stream_free(struct sst_hsw *hsw, struct sst_hsw_stream *stream) | |||
1180 | { | 1184 | { |
1181 | u32 header; | 1185 | u32 header; |
1182 | int ret = 0; | 1186 | int ret = 0; |
1187 | struct sst_dsp *sst = hsw->dsp; | ||
1188 | unsigned long flags; | ||
1183 | 1189 | ||
1184 | /* dont free DSP streams that are not commited */ | 1190 | /* dont free DSP streams that are not commited */ |
1185 | if (!stream->commited) | 1191 | if (!stream->commited) |
@@ -1201,8 +1207,11 @@ int sst_hsw_stream_free(struct sst_hsw *hsw, struct sst_hsw_stream *stream) | |||
1201 | trace_hsw_stream_free_req(stream, &stream->free_req); | 1207 | trace_hsw_stream_free_req(stream, &stream->free_req); |
1202 | 1208 | ||
1203 | out: | 1209 | out: |
1210 | cancel_work_sync(&stream->notify_work); | ||
1211 | spin_lock_irqsave(&sst->spinlock, flags); | ||
1204 | list_del(&stream->node); | 1212 | list_del(&stream->node); |
1205 | kfree(stream); | 1213 | kfree(stream); |
1214 | spin_unlock_irqrestore(&sst->spinlock, flags); | ||
1206 | 1215 | ||
1207 | return ret; | 1216 | return ret; |
1208 | } | 1217 | } |
@@ -1538,10 +1547,28 @@ int sst_hsw_stream_reset(struct sst_hsw *hsw, struct sst_hsw_stream *stream) | |||
1538 | } | 1547 | } |
1539 | 1548 | ||
1540 | /* Stream pointer positions */ | 1549 | /* Stream pointer positions */ |
1541 | int sst_hsw_get_dsp_position(struct sst_hsw *hsw, | 1550 | u32 sst_hsw_get_dsp_position(struct sst_hsw *hsw, |
1542 | struct sst_hsw_stream *stream) | 1551 | struct sst_hsw_stream *stream) |
1543 | { | 1552 | { |
1544 | return stream->rpos.position; | 1553 | u32 rpos; |
1554 | |||
1555 | sst_dsp_read(hsw->dsp, &rpos, | ||
1556 | stream->reply.read_position_register_address, sizeof(rpos)); | ||
1557 | |||
1558 | return rpos; | ||
1559 | } | ||
1560 | |||
1561 | /* Stream presentation (monotonic) positions */ | ||
1562 | u64 sst_hsw_get_dsp_presentation_position(struct sst_hsw *hsw, | ||
1563 | struct sst_hsw_stream *stream) | ||
1564 | { | ||
1565 | u64 ppos; | ||
1566 | |||
1567 | sst_dsp_read(hsw->dsp, &ppos, | ||
1568 | stream->reply.presentation_position_register_address, | ||
1569 | sizeof(ppos)); | ||
1570 | |||
1571 | return ppos; | ||
1545 | } | 1572 | } |
1546 | 1573 | ||
1547 | int sst_hsw_stream_set_write_position(struct sst_hsw *hsw, | 1574 | int sst_hsw_stream_set_write_position(struct sst_hsw *hsw, |