Lines Matching refs:chan
25 static int add_to_rbuf(struct mbox_chan *chan, void *mssg) in add_to_rbuf() argument
29 guard(spinlock_irqsave)(&chan->lock); in add_to_rbuf()
32 if (chan->msg_count == MBOX_TX_QUEUE_LEN) in add_to_rbuf()
35 idx = chan->msg_free; in add_to_rbuf()
36 chan->msg_data[idx] = mssg; in add_to_rbuf()
37 chan->msg_count++; in add_to_rbuf()
40 chan->msg_free = 0; in add_to_rbuf()
42 chan->msg_free++; in add_to_rbuf()
47 static void msg_submit(struct mbox_chan *chan) in msg_submit() argument
53 scoped_guard(spinlock_irqsave, &chan->lock) { in msg_submit()
54 if (!chan->msg_count || chan->active_req) in msg_submit()
57 count = chan->msg_count; in msg_submit()
58 idx = chan->msg_free; in msg_submit()
64 data = chan->msg_data[idx]; in msg_submit()
66 if (chan->cl->tx_prepare) in msg_submit()
67 chan->cl->tx_prepare(chan->cl, data); in msg_submit()
69 err = chan->mbox->ops->send_data(chan, data); in msg_submit()
71 chan->active_req = data; in msg_submit()
72 chan->msg_count--; in msg_submit()
76 if (!err && (chan->txdone_method & TXDONE_BY_POLL)) { in msg_submit()
78 scoped_guard(spinlock_irqsave, &chan->mbox->poll_hrt_lock) in msg_submit()
79 hrtimer_start(&chan->mbox->poll_hrt, 0, HRTIMER_MODE_REL); in msg_submit()
83 static void tx_tick(struct mbox_chan *chan, int r) in tx_tick() argument
87 scoped_guard(spinlock_irqsave, &chan->lock) { in tx_tick()
88 mssg = chan->active_req; in tx_tick()
89 chan->active_req = NULL; in tx_tick()
93 msg_submit(chan); in tx_tick()
99 if (chan->cl->tx_done) in tx_tick()
100 chan->cl->tx_done(chan->cl, mssg, r); in tx_tick()
102 if (r != -ETIME && chan->cl->tx_block) in tx_tick()
103 complete(&chan->tx_complete); in tx_tick()
114 struct mbox_chan *chan = &mbox->chans[i]; in txdone_hrtimer() local
116 if (chan->active_req && chan->cl) { in txdone_hrtimer()
117 txdone = chan->mbox->ops->last_tx_done(chan); in txdone_hrtimer()
119 tx_tick(chan, 0); in txdone_hrtimer()
146 void mbox_chan_received_data(struct mbox_chan *chan, void *mssg) in mbox_chan_received_data() argument
149 if (chan->cl->rx_callback) in mbox_chan_received_data()
150 chan->cl->rx_callback(chan->cl, mssg); in mbox_chan_received_data()
164 void mbox_chan_txdone(struct mbox_chan *chan, int r) in mbox_chan_txdone() argument
166 if (unlikely(!(chan->txdone_method & TXDONE_BY_IRQ))) { in mbox_chan_txdone()
167 dev_err(chan->mbox->dev, in mbox_chan_txdone()
172 tx_tick(chan, r); in mbox_chan_txdone()
185 void mbox_client_txdone(struct mbox_chan *chan, int r) in mbox_client_txdone() argument
187 if (unlikely(!(chan->txdone_method & TXDONE_BY_ACK))) { in mbox_client_txdone()
188 dev_err(chan->mbox->dev, "Client can't run the TX ticker\n"); in mbox_client_txdone()
192 tx_tick(chan, r); in mbox_client_txdone()
211 bool mbox_client_peek_data(struct mbox_chan *chan) in mbox_client_peek_data() argument
213 if (chan->mbox->ops->peek_data) in mbox_client_peek_data()
214 return chan->mbox->ops->peek_data(chan); in mbox_client_peek_data()
244 int mbox_send_message(struct mbox_chan *chan, void *mssg) in mbox_send_message() argument
248 if (!chan || !chan->cl) in mbox_send_message()
251 t = add_to_rbuf(chan, mssg); in mbox_send_message()
253 dev_err(chan->mbox->dev, "Try increasing MBOX_TX_QUEUE_LEN\n"); in mbox_send_message()
257 msg_submit(chan); in mbox_send_message()
259 if (chan->cl->tx_block) { in mbox_send_message()
263 if (!chan->cl->tx_tout) /* wait forever */ in mbox_send_message()
266 wait = msecs_to_jiffies(chan->cl->tx_tout); in mbox_send_message()
268 ret = wait_for_completion_timeout(&chan->tx_complete, wait); in mbox_send_message()
271 tx_tick(chan, t); in mbox_send_message()
293 int mbox_flush(struct mbox_chan *chan, unsigned long timeout) in mbox_flush() argument
297 if (!chan->mbox->ops->flush) in mbox_flush()
300 ret = chan->mbox->ops->flush(chan, timeout); in mbox_flush()
302 tx_tick(chan, ret); in mbox_flush()
308 static int __mbox_bind_client(struct mbox_chan *chan, struct mbox_client *cl) in __mbox_bind_client() argument
313 if (chan->cl || !try_module_get(chan->mbox->dev->driver->owner)) { in __mbox_bind_client()
318 scoped_guard(spinlock_irqsave, &chan->lock) { in __mbox_bind_client()
319 chan->msg_free = 0; in __mbox_bind_client()
320 chan->msg_count = 0; in __mbox_bind_client()
321 chan->active_req = NULL; in __mbox_bind_client()
322 chan->cl = cl; in __mbox_bind_client()
323 init_completion(&chan->tx_complete); in __mbox_bind_client()
325 if (chan->txdone_method == TXDONE_BY_POLL && cl->knows_txdone) in __mbox_bind_client()
326 chan->txdone_method = TXDONE_BY_ACK; in __mbox_bind_client()
329 if (chan->mbox->ops->startup) { in __mbox_bind_client()
330 ret = chan->mbox->ops->startup(chan); in __mbox_bind_client()
334 mbox_free_channel(chan); in __mbox_bind_client()
359 int mbox_bind_client(struct mbox_chan *chan, struct mbox_client *cl) in mbox_bind_client() argument
363 return __mbox_bind_client(chan, cl); in mbox_bind_client()
389 struct mbox_chan *chan; in mbox_request_channel() local
405 chan = ERR_PTR(-EPROBE_DEFER); in mbox_request_channel()
408 chan = mbox->of_xlate(mbox, &spec); in mbox_request_channel()
409 if (!IS_ERR(chan)) in mbox_request_channel()
415 if (IS_ERR(chan)) in mbox_request_channel()
416 return chan; in mbox_request_channel()
418 ret = __mbox_bind_client(chan, cl); in mbox_request_channel()
420 chan = ERR_PTR(ret); in mbox_request_channel()
423 return chan; in mbox_request_channel()
453 void mbox_free_channel(struct mbox_chan *chan) in mbox_free_channel() argument
455 if (!chan || !chan->cl) in mbox_free_channel()
458 if (chan->mbox->ops->shutdown) in mbox_free_channel()
459 chan->mbox->ops->shutdown(chan); in mbox_free_channel()
462 scoped_guard(spinlock_irqsave, &chan->lock) { in mbox_free_channel()
463 chan->cl = NULL; in mbox_free_channel()
464 chan->active_req = NULL; in mbox_free_channel()
465 if (chan->txdone_method == TXDONE_BY_ACK) in mbox_free_channel()
466 chan->txdone_method = TXDONE_BY_POLL; in mbox_free_channel()
469 module_put(chan->mbox->dev->driver->owner); in mbox_free_channel()
518 struct mbox_chan *chan = &mbox->chans[i]; in mbox_controller_register() local
520 chan->cl = NULL; in mbox_controller_register()
521 chan->mbox = mbox; in mbox_controller_register()
522 chan->txdone_method = txdone; in mbox_controller_register()
523 spin_lock_init(&chan->lock); in mbox_controller_register()