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 ipc->msg[i].tx_data = kzalloc(ipc->tx_data_max_size, GFP_KERNEL); in msg_empty_list_init()
133 if (ipc->msg[i].tx_data == NULL) in msg_empty_list_init()
136 ipc->msg[i].rx_data = kzalloc(ipc->rx_data_max_size, GFP_KERNEL); in msg_empty_list_init()
137 if (ipc->msg[i].rx_data == NULL) { in msg_empty_list_init()
138 kfree(ipc->msg[i].tx_data); in msg_empty_list_init()
142 init_waitqueue_head(&ipc->msg[i].waitq); in msg_empty_list_init()
143 list_add(&ipc->msg[i].list, &ipc->empty_list); in msg_empty_list_init()
150 kfree(ipc->msg[i-1].tx_data); in msg_empty_list_init()
151 kfree(ipc->msg[i-1].rx_data); in msg_empty_list_init()
154 kfree(ipc->msg); in msg_empty_list_init()
161 struct sst_generic_ipc *ipc = in ipc_tx_msgs() local
166 spin_lock_irqsave(&ipc->dsp->spinlock, flags); in ipc_tx_msgs()
168 if (list_empty(&ipc->tx_list) || ipc->pending) { in ipc_tx_msgs()
169 spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); in ipc_tx_msgs()
175 if (ipc->ops.is_dsp_busy && ipc->ops.is_dsp_busy(ipc->dsp)) { in ipc_tx_msgs()
176 dev_dbg(ipc->dev, "ipc_tx_msgs dsp busy\n"); in ipc_tx_msgs()
177 spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); in ipc_tx_msgs()
181 msg = list_first_entry(&ipc->tx_list, struct ipc_message, list); in ipc_tx_msgs()
182 list_move(&msg->list, &ipc->rx_list); in ipc_tx_msgs()
184 if (ipc->ops.tx_msg != NULL) in ipc_tx_msgs()
185 ipc->ops.tx_msg(ipc, msg); in ipc_tx_msgs()
187 spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); in ipc_tx_msgs()
190 int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, u64 header, in sst_ipc_tx_message_wait() argument
193 return ipc_tx_message(ipc, header, tx_data, tx_bytes, in sst_ipc_tx_message_wait()
198 int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc, u64 header, in sst_ipc_tx_message_nowait() argument
201 return ipc_tx_message(ipc, header, tx_data, tx_bytes, in sst_ipc_tx_message_nowait()
206 struct ipc_message *sst_ipc_reply_find_msg(struct sst_generic_ipc *ipc, in sst_ipc_reply_find_msg() argument
212 if (ipc->ops.reply_msg_match != NULL) in sst_ipc_reply_find_msg()
213 header = ipc->ops.reply_msg_match(header, &mask); in sst_ipc_reply_find_msg()
215 if (list_empty(&ipc->rx_list)) { in sst_ipc_reply_find_msg()
216 dev_err(ipc->dev, "error: rx list empty but received 0x%llx\n", in sst_ipc_reply_find_msg()
221 list_for_each_entry(msg, &ipc->rx_list, list) { in sst_ipc_reply_find_msg()
231 void sst_ipc_tx_msg_reply_complete(struct sst_generic_ipc *ipc, in sst_ipc_tx_msg_reply_complete() argument
237 list_add_tail(&msg->list, &ipc->empty_list); in sst_ipc_tx_msg_reply_complete()
243 void sst_ipc_drop_all(struct sst_generic_ipc *ipc) in sst_ipc_drop_all() argument
250 spin_lock_irqsave(&ipc->dsp->spinlock, flags); in sst_ipc_drop_all()
252 list_for_each_entry_safe(msg, tmp, &ipc->tx_list, list) { in sst_ipc_drop_all()
253 list_move(&msg->list, &ipc->empty_list); in sst_ipc_drop_all()
257 list_for_each_entry_safe(msg, tmp, &ipc->rx_list, list) { in sst_ipc_drop_all()
258 list_move(&msg->list, &ipc->empty_list); in sst_ipc_drop_all()
262 spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); in sst_ipc_drop_all()
265 dev_err(ipc->dev, "dropped IPC msg RX=%d, TX=%d\n", in sst_ipc_drop_all()
270 int sst_ipc_init(struct sst_generic_ipc *ipc) in sst_ipc_init() argument
274 INIT_LIST_HEAD(&ipc->tx_list); in sst_ipc_init()
275 INIT_LIST_HEAD(&ipc->rx_list); in sst_ipc_init()
276 INIT_LIST_HEAD(&ipc->empty_list); in sst_ipc_init()
277 init_waitqueue_head(&ipc->wait_txq); in sst_ipc_init()
279 ret = msg_empty_list_init(ipc); in sst_ipc_init()
284 init_kthread_worker(&ipc->kworker); in sst_ipc_init()
285 ipc->tx_thread = kthread_run(kthread_worker_fn, in sst_ipc_init()
286 &ipc->kworker, "%s", in sst_ipc_init()
287 dev_name(ipc->dev)); in sst_ipc_init()
288 if (IS_ERR(ipc->tx_thread)) { in sst_ipc_init()
289 dev_err(ipc->dev, "error: failed to create message TX task\n"); in sst_ipc_init()
290 ret = PTR_ERR(ipc->tx_thread); in sst_ipc_init()
291 kfree(ipc->msg); in sst_ipc_init()
295 init_kthread_work(&ipc->kwork, ipc_tx_msgs); in sst_ipc_init()
300 void sst_ipc_fini(struct sst_generic_ipc *ipc) in sst_ipc_fini() argument
304 if (ipc->tx_thread) in sst_ipc_fini()
305 kthread_stop(ipc->tx_thread); in sst_ipc_fini()
307 if (ipc->msg) { in sst_ipc_fini()
309 kfree(ipc->msg[i].tx_data); in sst_ipc_fini()
310 kfree(ipc->msg[i].rx_data); in sst_ipc_fini()
312 kfree(ipc->msg); in sst_ipc_fini()