Lines Matching +full:mbox +full:- +full:tx

1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright (C) 2013-2014 Linaro Ltd.
29 guard(spinlock_irqsave)(&chan->lock);
32 if (chan->msg_count == MBOX_TX_QUEUE_LEN)
33 return -ENOBUFS;
35 idx = chan->msg_free;
36 chan->msg_data[idx] = mssg;
37 chan->msg_count++;
39 if (idx == MBOX_TX_QUEUE_LEN - 1)
40 chan->msg_free = 0;
42 chan->msg_free++;
51 int err = -EBUSY;
53 scoped_guard(spinlock_irqsave, &chan->lock) {
54 if (!chan->msg_count || chan->active_req)
57 count = chan->msg_count;
58 idx = chan->msg_free;
60 idx -= count;
62 idx += MBOX_TX_QUEUE_LEN - count;
64 data = chan->msg_data[idx];
66 if (chan->cl->tx_prepare)
67 chan->cl->tx_prepare(chan->cl, data);
68 /* Try to submit a message to the MBOX controller */
69 err = chan->mbox->ops->send_data(chan, data);
71 chan->active_req = data;
72 chan->msg_count--;
76 if (!err && (chan->txdone_method & TXDONE_BY_POLL)) {
78 scoped_guard(spinlock_irqsave, &chan->mbox->poll_hrt_lock)
79 hrtimer_start(&chan->mbox->poll_hrt, 0, HRTIMER_MODE_REL);
87 scoped_guard(spinlock_irqsave, &chan->lock) {
88 mssg = chan->active_req;
89 chan->active_req = NULL;
99 if (chan->cl->tx_done)
100 chan->cl->tx_done(chan->cl, mssg, r);
102 if (r != -ETIME && chan->cl->tx_block)
103 complete(&chan->tx_complete);
108 struct mbox_controller *mbox =
113 for (i = 0; i < mbox->num_chans; i++) {
114 struct mbox_chan *chan = &mbox->chans[i];
116 if (chan->active_req && chan->cl) {
117 txdone = chan->mbox->ops->last_tx_done(chan);
126 scoped_guard(spinlock_irqsave, &mbox->poll_hrt_lock) {
128 hrtimer_forward_now(hrtimer, ms_to_ktime(mbox->txpoll_period));
137 * mbox_chan_received_data - A way for controller driver to push data
149 if (chan->cl->rx_callback)
150 chan->cl->rx_callback(chan->cl, mssg);
155 * mbox_chan_txdone - A way for controller driver to notify the
156 * framework that the last TX has completed.
157 * @chan: Pointer to the mailbox chan on which TX happened.
158 * @r: Status of last TX - OK or ERROR
160 * The controller that has IRQ for TX ACK calls this atomic API
161 * to tick the TX state machine. It works only if txdone_irq
166 if (unlikely(!(chan->txdone_method & TXDONE_BY_IRQ))) {
167 dev_err(chan->mbox->dev,
168 "Controller can't run the TX ticker\n");
177 * mbox_client_txdone - The way for a client to run the TX state machine.
183 * if the controller can't sense TX-Done.
187 if (unlikely(!(chan->txdone_method & TXDONE_BY_ACK))) {
188 dev_err(chan->mbox->dev, "Client can't run the TX ticker\n");
197 * mbox_client_peek_data - A way for client driver to pull data
213 if (chan->mbox->ops->peek_data)
214 return chan->mbox->ops->peek_data(chan);
221 * mbox_send_message - For client to submit a message to be
230 * In non-blocking mode, the requests are buffered by the API and a
231 * non-negative token is returned for each queued request. If the request
233 * TX, the API calls 'tx_done' from atomic context, from which the client
240 * Return: Non-negative integer for successful submission (non-blocking mode)
248 if (!chan || !chan->cl)
249 return -EINVAL;
253 dev_err(chan->mbox->dev, "Try increasing MBOX_TX_QUEUE_LEN\n");
259 if (chan->cl->tx_block) {
263 if (!chan->cl->tx_tout) /* wait forever */
266 wait = msecs_to_jiffies(chan->cl->tx_tout);
268 ret = wait_for_completion_timeout(&chan->tx_complete, wait);
270 t = -ETIME;
280 * mbox_flush - flush a mailbox channel
285 * ->flush() callback to busy loop until a transmission has been completed.
297 if (!chan->mbox->ops->flush)
298 return -ENOTSUPP;
300 ret = chan->mbox->ops->flush(chan, timeout);
310 struct device *dev = cl->dev;
313 if (chan->cl || !try_module_get(chan->mbox->dev->driver->owner)) {
315 return -EBUSY;
318 scoped_guard(spinlock_irqsave, &chan->lock) {
319 chan->msg_free = 0;
320 chan->msg_count = 0;
321 chan->active_req = NULL;
322 chan->cl = cl;
323 init_completion(&chan->tx_complete);
325 if (chan->txdone_method == TXDONE_BY_POLL && cl->knows_txdone)
326 chan->txdone_method = TXDONE_BY_ACK;
329 if (chan->mbox->ops->startup) {
330 ret = chan->mbox->ops->startup(chan);
343 * mbox_bind_client - Request a mailbox channel.
368 * mbox_request_channel - Request a mailbox channel.
386 struct device *dev = cl->dev;
387 struct mbox_controller *mbox;
392 if (!dev || !dev->of_node) {
394 return ERR_PTR(-ENODEV);
397 ret = of_parse_phandle_with_args(dev->of_node, "mboxes", "#mbox-cells",
405 chan = ERR_PTR(-EPROBE_DEFER);
406 list_for_each_entry(mbox, &mbox_cons, node)
407 if (mbox->dev->of_node == spec.np) {
408 chan = mbox->of_xlate(mbox, &spec);
430 struct device_node *np = cl->dev->of_node;
434 dev_err(cl->dev, "%s() currently only supports DT\n", __func__);
435 return ERR_PTR(-EINVAL);
438 index = of_property_match_string(np, "mbox-names", name);
440 dev_err(cl->dev, "%s() could not locate channel named \"%s\"\n",
449 * mbox_free_channel - The client relinquishes control of a mailbox
455 if (!chan || !chan->cl)
458 if (chan->mbox->ops->shutdown)
459 chan->mbox->ops->shutdown(chan);
461 /* The queued TX requests are simply aborted, no callbacks are made */
462 scoped_guard(spinlock_irqsave, &chan->lock) {
463 chan->cl = NULL;
464 chan->active_req = NULL;
465 if (chan->txdone_method == TXDONE_BY_ACK)
466 chan->txdone_method = TXDONE_BY_POLL;
469 module_put(chan->mbox->dev->driver->owner);
474 of_mbox_index_xlate(struct mbox_controller *mbox,
477 int ind = sp->args[0];
479 if (ind >= mbox->num_chans)
480 return ERR_PTR(-EINVAL);
482 return &mbox->chans[ind];
486 * mbox_controller_register - Register the mailbox controller
487 * @mbox: Pointer to the mailbox controller.
491 int mbox_controller_register(struct mbox_controller *mbox)
496 if (!mbox || !mbox->dev || !mbox->ops || !mbox->num_chans)
497 return -EINVAL;
499 if (mbox->txdone_irq)
501 else if (mbox->txdone_poll)
508 if (!mbox->ops->last_tx_done) {
509 dev_err(mbox->dev, "last_tx_done method is absent\n");
510 return -EINVAL;
513 hrtimer_setup(&mbox->poll_hrt, txdone_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
514 spin_lock_init(&mbox->poll_hrt_lock);
517 for (i = 0; i < mbox->num_chans; i++) {
518 struct mbox_chan *chan = &mbox->chans[i];
520 chan->cl = NULL;
521 chan->mbox = mbox;
522 chan->txdone_method = txdone;
523 spin_lock_init(&chan->lock);
526 if (!mbox->of_xlate)
527 mbox->of_xlate = of_mbox_index_xlate;
530 list_add_tail(&mbox->node, &mbox_cons);
537 * mbox_controller_unregister - Unregister the mailbox controller
538 * @mbox: Pointer to the mailbox controller.
540 void mbox_controller_unregister(struct mbox_controller *mbox)
544 if (!mbox)
548 list_del(&mbox->node);
550 for (i = 0; i < mbox->num_chans; i++)
551 mbox_free_channel(&mbox->chans[i]);
553 if (mbox->txdone_poll)
554 hrtimer_cancel(&mbox->poll_hrt);
561 struct mbox_controller **mbox = res;
563 mbox_controller_unregister(*mbox);
567 * devm_mbox_controller_register() - managed mbox_controller_register()
569 * @mbox: mailbox controller being registered
571 * This function adds a device-managed resource that will make sure that the
574 * device-managed resources upon driver probe failure or driver removal.
579 struct mbox_controller *mbox)
587 return -ENOMEM;
589 err = mbox_controller_register(mbox);
596 *ptr = mbox;