aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/intel/sst-haswell-ipc.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/intel/sst-haswell-ipc.c')
-rw-r--r--sound/soc/intel/sst-haswell-ipc.c38
1 files changed, 33 insertions, 5 deletions
diff --git a/sound/soc/intel/sst-haswell-ipc.c b/sound/soc/intel/sst-haswell-ipc.c
index f46bb4ddde6f..e7996b39a484 100644
--- a/sound/soc/intel/sst-haswell-ipc.c
+++ b/sound/soc/intel/sst-haswell-ipc.c
@@ -617,7 +617,7 @@ static void hsw_notification_work(struct work_struct *work)
617 case IPC_POSITION_CHANGED: 617 case IPC_POSITION_CHANGED:
618 trace_ipc_notification("DSP stream position changed for", 618 trace_ipc_notification("DSP stream position changed for",
619 stream->reply.stream_hw_id); 619 stream->reply.stream_hw_id);
620 sst_dsp_inbox_read(hsw->dsp, pos, sizeof(pos)); 620 sst_dsp_inbox_read(hsw->dsp, pos, sizeof(*pos));
621 621
622 if (stream->notify_position) 622 if (stream->notify_position)
623 stream->notify_position(stream, stream->pdata); 623 stream->notify_position(stream, stream->pdata);
@@ -991,7 +991,8 @@ int sst_hsw_stream_get_volume(struct sst_hsw *hsw, struct sst_hsw_stream *stream
991 return -EINVAL; 991 return -EINVAL;
992 992
993 sst_dsp_read(hsw->dsp, volume, 993 sst_dsp_read(hsw->dsp, volume,
994 stream->reply.volume_register_address[channel], sizeof(volume)); 994 stream->reply.volume_register_address[channel],
995 sizeof(*volume));
995 996
996 return 0; 997 return 0;
997} 998}
@@ -1158,11 +1159,14 @@ struct sst_hsw_stream *sst_hsw_stream_new(struct sst_hsw *hsw, int id,
1158 void *data) 1159 void *data)
1159{ 1160{
1160 struct sst_hsw_stream *stream; 1161 struct sst_hsw_stream *stream;
1162 struct sst_dsp *sst = hsw->dsp;
1163 unsigned long flags;
1161 1164
1162 stream = kzalloc(sizeof(*stream), GFP_KERNEL); 1165 stream = kzalloc(sizeof(*stream), GFP_KERNEL);
1163 if (stream == NULL) 1166 if (stream == NULL)
1164 return NULL; 1167 return NULL;
1165 1168
1169 spin_lock_irqsave(&sst->spinlock, flags);
1166 list_add(&stream->node, &hsw->stream_list); 1170 list_add(&stream->node, &hsw->stream_list);
1167 stream->notify_position = notify_position; 1171 stream->notify_position = notify_position;
1168 stream->pdata = data; 1172 stream->pdata = data;
@@ -1171,6 +1175,7 @@ struct sst_hsw_stream *sst_hsw_stream_new(struct sst_hsw *hsw, int id,
1171 1175
1172 /* work to process notification messages */ 1176 /* work to process notification messages */
1173 INIT_WORK(&stream->notify_work, hsw_notification_work); 1177 INIT_WORK(&stream->notify_work, hsw_notification_work);
1178 spin_unlock_irqrestore(&sst->spinlock, flags);
1174 1179
1175 return stream; 1180 return stream;
1176} 1181}
@@ -1179,6 +1184,8 @@ int sst_hsw_stream_free(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
1179{ 1184{
1180 u32 header; 1185 u32 header;
1181 int ret = 0; 1186 int ret = 0;
1187 struct sst_dsp *sst = hsw->dsp;
1188 unsigned long flags;
1182 1189
1183 /* dont free DSP streams that are not commited */ 1190 /* dont free DSP streams that are not commited */
1184 if (!stream->commited) 1191 if (!stream->commited)
@@ -1200,8 +1207,11 @@ int sst_hsw_stream_free(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
1200 trace_hsw_stream_free_req(stream, &stream->free_req); 1207 trace_hsw_stream_free_req(stream, &stream->free_req);
1201 1208
1202out: 1209out:
1210 cancel_work_sync(&stream->notify_work);
1211 spin_lock_irqsave(&sst->spinlock, flags);
1203 list_del(&stream->node); 1212 list_del(&stream->node);
1204 kfree(stream); 1213 kfree(stream);
1214 spin_unlock_irqrestore(&sst->spinlock, flags);
1205 1215
1206 return ret; 1216 return ret;
1207} 1217}
@@ -1537,10 +1547,28 @@ int sst_hsw_stream_reset(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
1537} 1547}
1538 1548
1539/* Stream pointer positions */ 1549/* Stream pointer positions */
1540int sst_hsw_get_dsp_position(struct sst_hsw *hsw, 1550u32 sst_hsw_get_dsp_position(struct sst_hsw *hsw,
1541 struct sst_hsw_stream *stream) 1551 struct sst_hsw_stream *stream)
1542{ 1552{
1543 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 */
1562u64 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;
1544} 1572}
1545 1573
1546int sst_hsw_stream_set_write_position(struct sst_hsw *hsw, 1574int sst_hsw_stream_set_write_position(struct sst_hsw *hsw,
@@ -1609,7 +1637,7 @@ int sst_hsw_dx_set_state(struct sst_hsw *hsw,
1609 trace_ipc_request("PM enter Dx state", state); 1637 trace_ipc_request("PM enter Dx state", state);
1610 1638
1611 ret = ipc_tx_message_wait(hsw, header, &state_, sizeof(state_), 1639 ret = ipc_tx_message_wait(hsw, header, &state_, sizeof(state_),
1612 dx, sizeof(dx)); 1640 dx, sizeof(*dx));
1613 if (ret < 0) { 1641 if (ret < 0) {
1614 dev_err(hsw->dev, "ipc: error set dx state %d failed\n", state); 1642 dev_err(hsw->dev, "ipc: error set dx state %d failed\n", state);
1615 return ret; 1643 return ret;