Lines Matching refs:ipc
42 static struct ipc_message *msg_get_empty(struct sst_generic_ipc *ipc) in msg_get_empty() argument
46 if (!list_empty(&ipc->empty_list)) { in msg_get_empty()
47 msg = list_first_entry(&ipc->empty_list, struct ipc_message, in msg_get_empty()
55 static int tx_wait_done(struct sst_generic_ipc *ipc, in tx_wait_done() argument
65 spin_lock_irqsave(&ipc->dsp->spinlock, flags); in tx_wait_done()
67 if (ipc->ops.shim_dbg != NULL) in tx_wait_done()
68 ipc->ops.shim_dbg(ipc, "message timeout"); in tx_wait_done()
80 list_add_tail(&msg->list, &ipc->empty_list); in tx_wait_done()
81 spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); in tx_wait_done()
85 static int ipc_tx_message(struct sst_generic_ipc *ipc, u64 header, in ipc_tx_message() argument
92 spin_lock_irqsave(&ipc->dsp->spinlock, flags); in ipc_tx_message()
94 msg = msg_get_empty(ipc); in ipc_tx_message()
96 spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); in ipc_tx_message()
108 if ((tx_bytes) && (ipc->ops.tx_data_copy != NULL)) in ipc_tx_message()
109 ipc->ops.tx_data_copy(msg, tx_data, tx_bytes); in ipc_tx_message()
111 list_add_tail(&msg->list, &ipc->tx_list); in ipc_tx_message()
112 spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); in ipc_tx_message()
114 queue_kthread_work(&ipc->kworker, &ipc->kwork); in ipc_tx_message()
117 return tx_wait_done(ipc, msg, rx_data); in ipc_tx_message()
122 static int msg_empty_list_init(struct sst_generic_ipc *ipc) in msg_empty_list_init() argument
126 ipc->msg = kzalloc(sizeof(struct ipc_message) * in msg_empty_list_init()
128 if (ipc->msg == NULL) in msg_empty_list_init()
132 init_waitqueue_head(&ipc->msg[i].waitq); in msg_empty_list_init()
133 list_add(&ipc->msg[i].list, &ipc->empty_list); in msg_empty_list_init()
141 struct sst_generic_ipc *ipc = in ipc_tx_msgs() local
147 spin_lock_irqsave(&ipc->dsp->spinlock, flags); in ipc_tx_msgs()
149 if (list_empty(&ipc->tx_list) || ipc->pending) { in ipc_tx_msgs()
150 spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); in ipc_tx_msgs()
156 ipcx = sst_dsp_shim_read_unlocked(ipc->dsp, SST_IPCX); in ipc_tx_msgs()
158 spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); in ipc_tx_msgs()
162 msg = list_first_entry(&ipc->tx_list, struct ipc_message, list); in ipc_tx_msgs()
163 list_move(&msg->list, &ipc->rx_list); in ipc_tx_msgs()
165 if (ipc->ops.tx_msg != NULL) in ipc_tx_msgs()
166 ipc->ops.tx_msg(ipc, msg); in ipc_tx_msgs()
168 spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); in ipc_tx_msgs()
171 int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, u64 header, in sst_ipc_tx_message_wait() argument
174 return ipc_tx_message(ipc, header, tx_data, tx_bytes, in sst_ipc_tx_message_wait()
179 int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc, u64 header, in sst_ipc_tx_message_nowait() argument
182 return ipc_tx_message(ipc, header, tx_data, tx_bytes, in sst_ipc_tx_message_nowait()
187 struct ipc_message *sst_ipc_reply_find_msg(struct sst_generic_ipc *ipc, in sst_ipc_reply_find_msg() argument
193 if (ipc->ops.reply_msg_match != NULL) in sst_ipc_reply_find_msg()
194 header = ipc->ops.reply_msg_match(header, &mask); in sst_ipc_reply_find_msg()
196 if (list_empty(&ipc->rx_list)) { in sst_ipc_reply_find_msg()
197 dev_err(ipc->dev, "error: rx list empty but received 0x%llx\n", in sst_ipc_reply_find_msg()
202 list_for_each_entry(msg, &ipc->rx_list, list) { in sst_ipc_reply_find_msg()
212 void sst_ipc_tx_msg_reply_complete(struct sst_generic_ipc *ipc, in sst_ipc_tx_msg_reply_complete() argument
218 list_add_tail(&msg->list, &ipc->empty_list); in sst_ipc_tx_msg_reply_complete()
224 void sst_ipc_drop_all(struct sst_generic_ipc *ipc) in sst_ipc_drop_all() argument
231 spin_lock_irqsave(&ipc->dsp->spinlock, flags); in sst_ipc_drop_all()
233 list_for_each_entry_safe(msg, tmp, &ipc->tx_list, list) { in sst_ipc_drop_all()
234 list_move(&msg->list, &ipc->empty_list); in sst_ipc_drop_all()
238 list_for_each_entry_safe(msg, tmp, &ipc->rx_list, list) { in sst_ipc_drop_all()
239 list_move(&msg->list, &ipc->empty_list); in sst_ipc_drop_all()
243 spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); in sst_ipc_drop_all()
246 dev_err(ipc->dev, "dropped IPC msg RX=%d, TX=%d\n", in sst_ipc_drop_all()
251 int sst_ipc_init(struct sst_generic_ipc *ipc) in sst_ipc_init() argument
255 INIT_LIST_HEAD(&ipc->tx_list); in sst_ipc_init()
256 INIT_LIST_HEAD(&ipc->rx_list); in sst_ipc_init()
257 INIT_LIST_HEAD(&ipc->empty_list); in sst_ipc_init()
258 init_waitqueue_head(&ipc->wait_txq); in sst_ipc_init()
260 ret = msg_empty_list_init(ipc); in sst_ipc_init()
265 init_kthread_worker(&ipc->kworker); in sst_ipc_init()
266 ipc->tx_thread = kthread_run(kthread_worker_fn, in sst_ipc_init()
267 &ipc->kworker, "%s", in sst_ipc_init()
268 dev_name(ipc->dev)); in sst_ipc_init()
269 if (IS_ERR(ipc->tx_thread)) { in sst_ipc_init()
270 dev_err(ipc->dev, "error: failed to create message TX task\n"); in sst_ipc_init()
271 ret = PTR_ERR(ipc->tx_thread); in sst_ipc_init()
272 kfree(ipc->msg); in sst_ipc_init()
276 init_kthread_work(&ipc->kwork, ipc_tx_msgs); in sst_ipc_init()
281 void sst_ipc_fini(struct sst_generic_ipc *ipc) in sst_ipc_fini() argument
283 if (ipc->tx_thread) in sst_ipc_fini()
284 kthread_stop(ipc->tx_thread); in sst_ipc_fini()
286 if (ipc->msg) in sst_ipc_fini()
287 kfree(ipc->msg); in sst_ipc_fini()