Lines Matching refs:vioch
114 static void scmi_vio_channel_ready(struct scmi_vio_channel *vioch, in scmi_vio_channel_ready() argument
119 spin_lock_irqsave(&vioch->lock, flags); in scmi_vio_channel_ready()
120 cinfo->transport_info = vioch; in scmi_vio_channel_ready()
122 vioch->cinfo = cinfo; in scmi_vio_channel_ready()
123 spin_unlock_irqrestore(&vioch->lock, flags); in scmi_vio_channel_ready()
125 refcount_set(&vioch->users, 1); in scmi_vio_channel_ready()
128 static inline bool scmi_vio_channel_acquire(struct scmi_vio_channel *vioch) in scmi_vio_channel_acquire() argument
130 return refcount_inc_not_zero(&vioch->users); in scmi_vio_channel_acquire()
133 static inline void scmi_vio_channel_release(struct scmi_vio_channel *vioch) in scmi_vio_channel_release() argument
135 if (refcount_dec_and_test(&vioch->users)) { in scmi_vio_channel_release()
138 spin_lock_irqsave(&vioch->lock, flags); in scmi_vio_channel_release()
139 if (vioch->shutdown_done) { in scmi_vio_channel_release()
140 vioch->cinfo = NULL; in scmi_vio_channel_release()
141 complete(vioch->shutdown_done); in scmi_vio_channel_release()
143 spin_unlock_irqrestore(&vioch->lock, flags); in scmi_vio_channel_release()
147 static void scmi_vio_channel_cleanup_sync(struct scmi_vio_channel *vioch) in scmi_vio_channel_cleanup_sync() argument
156 spin_lock_irqsave(&vioch->lock, flags); in scmi_vio_channel_cleanup_sync()
157 if (!vioch->cinfo || vioch->shutdown_done) { in scmi_vio_channel_cleanup_sync()
158 spin_unlock_irqrestore(&vioch->lock, flags); in scmi_vio_channel_cleanup_sync()
162 vioch->shutdown_done = &vioch_shutdown_done; in scmi_vio_channel_cleanup_sync()
163 virtio_break_device(vioch->vqueue->vdev); in scmi_vio_channel_cleanup_sync()
164 if (!vioch->is_rx && vioch->deferred_tx_wq) in scmi_vio_channel_cleanup_sync()
166 vioch->deferred_tx_wq = NULL; in scmi_vio_channel_cleanup_sync()
167 spin_unlock_irqrestore(&vioch->lock, flags); in scmi_vio_channel_cleanup_sync()
169 scmi_vio_channel_release(vioch); in scmi_vio_channel_cleanup_sync()
172 wait_for_completion(vioch->shutdown_done); in scmi_vio_channel_cleanup_sync()
177 scmi_virtio_get_free_msg(struct scmi_vio_channel *vioch) in scmi_virtio_get_free_msg() argument
182 spin_lock_irqsave(&vioch->free_lock, flags); in scmi_virtio_get_free_msg()
183 if (list_empty(&vioch->free_list)) { in scmi_virtio_get_free_msg()
184 spin_unlock_irqrestore(&vioch->free_lock, flags); in scmi_virtio_get_free_msg()
188 msg = list_first_entry(&vioch->free_list, typeof(*msg), list); in scmi_virtio_get_free_msg()
190 spin_unlock_irqrestore(&vioch->free_lock, flags); in scmi_virtio_get_free_msg()
205 static inline bool scmi_vio_msg_release(struct scmi_vio_channel *vioch, in scmi_vio_msg_release() argument
214 spin_lock_irqsave(&vioch->free_lock, flags); in scmi_vio_msg_release()
215 list_add_tail(&msg->list, &vioch->free_list); in scmi_vio_msg_release()
216 spin_unlock_irqrestore(&vioch->free_lock, flags); in scmi_vio_msg_release()
227 static int scmi_vio_feed_vq_rx(struct scmi_vio_channel *vioch, in scmi_vio_feed_vq_rx() argument
233 struct device *dev = &vioch->vqueue->vdev->dev; in scmi_vio_feed_vq_rx()
237 spin_lock_irqsave(&vioch->lock, flags); in scmi_vio_feed_vq_rx()
239 rc = virtqueue_add_inbuf(vioch->vqueue, &sg_in, 1, msg, GFP_ATOMIC); in scmi_vio_feed_vq_rx()
243 virtqueue_kick(vioch->vqueue); in scmi_vio_feed_vq_rx()
245 spin_unlock_irqrestore(&vioch->lock, flags); in scmi_vio_feed_vq_rx()
254 static void scmi_finalize_message(struct scmi_vio_channel *vioch, in scmi_finalize_message() argument
257 if (vioch->is_rx) in scmi_finalize_message()
258 scmi_vio_feed_vq_rx(vioch, msg); in scmi_finalize_message()
260 scmi_vio_msg_release(vioch, msg); in scmi_finalize_message()
267 struct scmi_vio_channel *vioch; in scmi_vio_complete_cb() local
273 vioch = &((struct scmi_vio_channel *)vqueue->vdev->priv)[vqueue->index]; in scmi_vio_complete_cb()
276 if (!scmi_vio_channel_acquire(vioch)) in scmi_vio_complete_cb()
279 spin_lock_irqsave(&vioch->lock, flags); in scmi_vio_complete_cb()
288 spin_unlock_irqrestore(&vioch->lock, flags); in scmi_vio_complete_cb()
289 scmi_vio_channel_release(vioch); in scmi_vio_complete_cb()
294 spin_unlock_irqrestore(&vioch->lock, flags); in scmi_vio_complete_cb()
298 scmi_rx_callback(vioch->cinfo, in scmi_vio_complete_cb()
301 scmi_finalize_message(vioch, msg); in scmi_vio_complete_cb()
311 scmi_vio_channel_release(vioch); in scmi_vio_complete_cb()
318 struct scmi_vio_channel *vioch; in scmi_vio_deferred_tx_worker() local
321 vioch = container_of(work, struct scmi_vio_channel, deferred_tx_work); in scmi_vio_deferred_tx_worker()
323 if (!scmi_vio_channel_acquire(vioch)) in scmi_vio_deferred_tx_worker()
332 spin_lock_irqsave(&vioch->pending_lock, flags); in scmi_vio_deferred_tx_worker()
335 list_for_each_entry_safe(msg, tmp, &vioch->pending_cmds_list, list) { in scmi_vio_deferred_tx_worker()
343 scmi_rx_callback(vioch->cinfo, in scmi_vio_deferred_tx_worker()
347 scmi_vio_msg_release(vioch, msg); in scmi_vio_deferred_tx_worker()
350 spin_unlock_irqrestore(&vioch->pending_lock, flags); in scmi_vio_deferred_tx_worker()
353 scmi_vio_complete_cb(vioch->vqueue); in scmi_vio_deferred_tx_worker()
355 scmi_vio_channel_release(vioch); in scmi_vio_deferred_tx_worker()
367 struct scmi_vio_channel *vioch = base_cinfo->transport_info; in virtio_get_max_msg() local
369 return vioch->max_msg; in virtio_get_max_msg()
391 struct scmi_vio_channel *channels, *vioch = NULL; in virtio_chan_available() local
400 vioch = &channels[VIRTIO_SCMI_VQ_TX]; in virtio_chan_available()
404 vioch = &channels[VIRTIO_SCMI_VQ_RX]; in virtio_chan_available()
410 return vioch && !vioch->cinfo; in virtio_chan_available()
421 struct scmi_vio_channel *vioch; in virtio_chan_setup() local
428 vioch = &((struct scmi_vio_channel *)scmi_vdev->priv)[index]; in virtio_chan_setup()
431 if (tx && !vioch->deferred_tx_wq) { in virtio_chan_setup()
434 vioch->deferred_tx_wq = in virtio_chan_setup()
438 if (!vioch->deferred_tx_wq) in virtio_chan_setup()
442 vioch->deferred_tx_wq); in virtio_chan_setup()
446 INIT_WORK(&vioch->deferred_tx_work, in virtio_chan_setup()
450 for (i = 0; i < vioch->max_msg; i++) { in virtio_chan_setup()
472 scmi_finalize_message(vioch, msg); in virtio_chan_setup()
475 scmi_vio_channel_ready(vioch, cinfo); in virtio_chan_setup()
483 struct scmi_vio_channel *vioch = cinfo->transport_info; in virtio_chan_free() local
485 scmi_vio_channel_cleanup_sync(vioch); in virtio_chan_free()
495 struct scmi_vio_channel *vioch = cinfo->transport_info; in virtio_send_message() local
503 if (!scmi_vio_channel_acquire(vioch)) in virtio_send_message()
506 msg = scmi_virtio_get_free_msg(vioch); in virtio_send_message()
508 scmi_vio_channel_release(vioch); in virtio_send_message()
517 spin_lock_irqsave(&vioch->lock, flags); in virtio_send_message()
526 msg->poll_idx = virtqueue_enable_cb_prepare(vioch->vqueue); in virtio_send_message()
534 rc = virtqueue_add_sgs(vioch->vqueue, sgs, 1, 1, msg, GFP_ATOMIC); in virtio_send_message()
536 dev_err(vioch->cinfo->dev, in virtio_send_message()
539 virtqueue_kick(vioch->vqueue); in virtio_send_message()
541 spin_unlock_irqrestore(&vioch->lock, flags); in virtio_send_message()
547 scmi_vio_msg_release(vioch, msg); in virtio_send_message()
548 scmi_vio_msg_release(vioch, msg); in virtio_send_message()
551 scmi_vio_channel_release(vioch); in virtio_send_message()
613 struct scmi_vio_channel *vioch = cinfo->transport_info; in virtio_mark_txdone() local
616 if (!msg || !scmi_vio_channel_acquire(vioch)) in virtio_mark_txdone()
623 if (!xfer->hdr.poll_completion || scmi_vio_msg_release(vioch, msg)) { in virtio_mark_txdone()
624 scmi_vio_channel_release(vioch); in virtio_mark_txdone()
631 scmi_vio_msg_release(vioch, msg); in virtio_mark_txdone()
636 scmi_vio_channel_release(vioch); in virtio_mark_txdone()
683 struct scmi_vio_channel *vioch = cinfo->transport_info; in virtio_poll_done() local
706 if (!scmi_vio_channel_acquire(vioch)) in virtio_poll_done()
710 pending = virtqueue_poll(vioch->vqueue, msg->poll_idx); in virtio_poll_done()
712 scmi_vio_channel_release(vioch); in virtio_poll_done()
716 spin_lock_irqsave(&vioch->lock, flags); in virtio_poll_done()
717 virtqueue_disable_cb(vioch->vqueue); in virtio_poll_done()
723 while ((next_msg = virtqueue_get_buf(vioch->vqueue, &length))) { in virtio_poll_done()
757 spin_lock(&vioch->pending_lock); in virtio_poll_done()
759 &vioch->pending_cmds_list); in virtio_poll_done()
760 spin_unlock(&vioch->pending_lock); in virtio_poll_done()
775 pending = !virtqueue_enable_cb(vioch->vqueue); in virtio_poll_done()
777 msg->poll_idx = virtqueue_enable_cb_prepare(vioch->vqueue); in virtio_poll_done()
778 pending = virtqueue_poll(vioch->vqueue, msg->poll_idx); in virtio_poll_done()
781 if (vioch->deferred_tx_wq && (any_prefetched || pending)) in virtio_poll_done()
782 queue_work(vioch->deferred_tx_wq, &vioch->deferred_tx_work); in virtio_poll_done()
784 spin_unlock_irqrestore(&vioch->lock, flags); in virtio_poll_done()
786 scmi_vio_channel_release(vioch); in virtio_poll_done()