blob: 9f340bfa0a6047134ce0695de2d1fb1c125bde09 [file] [log] [blame]
Jassi Brar2b6d83e2014-06-12 22:31:19 +05301/*
2 * Mailbox: Common code for Mailbox controllers and users
3 *
4 * Copyright (C) 2013-2014 Linaro Ltd.
5 * Author: Jassi Brar <jassisinghbrar@gmail.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/interrupt.h>
13#include <linux/spinlock.h>
14#include <linux/mutex.h>
15#include <linux/delay.h>
16#include <linux/slab.h>
17#include <linux/err.h>
18#include <linux/module.h>
19#include <linux/device.h>
20#include <linux/bitops.h>
21#include <linux/mailbox_client.h>
22#include <linux/mailbox_controller.h>
23
Ashwin Chaugule86c22f82014-11-12 19:59:38 -050024#include "mailbox.h"
Jassi Brar2b6d83e2014-06-12 22:31:19 +053025
26static LIST_HEAD(mbox_cons);
27static DEFINE_MUTEX(con_mutex);
28
29static int add_to_rbuf(struct mbox_chan *chan, void *mssg)
30{
31 int idx;
32 unsigned long flags;
33
34 spin_lock_irqsave(&chan->lock, flags);
35
36 /* See if there is any space left */
37 if (chan->msg_count == MBOX_TX_QUEUE_LEN) {
38 spin_unlock_irqrestore(&chan->lock, flags);
39 return -ENOBUFS;
40 }
41
42 idx = chan->msg_free;
43 chan->msg_data[idx] = mssg;
44 chan->msg_count++;
45
46 if (idx == MBOX_TX_QUEUE_LEN - 1)
47 chan->msg_free = 0;
48 else
49 chan->msg_free++;
50
51 spin_unlock_irqrestore(&chan->lock, flags);
52
53 return idx;
54}
55
56static void msg_submit(struct mbox_chan *chan)
57{
58 unsigned count, idx;
59 unsigned long flags;
60 void *data;
Andrew Bresticker52a49302014-10-30 13:01:07 -070061 int err = -EBUSY;
Jassi Brar2b6d83e2014-06-12 22:31:19 +053062
Lina Iyer348b2712017-05-30 22:13:59 -060063again:
Jassi Brar2b6d83e2014-06-12 22:31:19 +053064 spin_lock_irqsave(&chan->lock, flags);
65
66 if (!chan->msg_count || chan->active_req)
67 goto exit;
68
69 count = chan->msg_count;
70 idx = chan->msg_free;
71 if (idx >= count)
72 idx -= count;
73 else
74 idx += MBOX_TX_QUEUE_LEN - count;
75
76 data = chan->msg_data[idx];
77
Sudeep Holla97b0c7b2014-11-11 18:33:01 +000078 if (chan->cl->tx_prepare)
79 chan->cl->tx_prepare(chan->cl, data);
Jassi Brar2b6d83e2014-06-12 22:31:19 +053080 /* Try to submit a message to the MBOX controller */
81 err = chan->mbox->ops->send_data(chan, data);
82 if (!err) {
83 chan->active_req = data;
84 chan->msg_count--;
85 }
86exit:
87 spin_unlock_irqrestore(&chan->lock, flags);
Andrew Bresticker52a49302014-10-30 13:01:07 -070088
Lina Iyer348b2712017-05-30 22:13:59 -060089 /*
90 * If the controller returns -EAGAIN, then it means, our spinlock
91 * here is preventing the controller from receiving its interrupt,
92 * that would help clear the controller channels that are currently
93 * blocked waiting on the interrupt response.
94 * Unlock and retry again.
95 */
96 if (err == -EAGAIN)
97 goto again;
98
Jassi Brar01340df2014-12-12 15:22:49 +053099 if (!err && (chan->txdone_method & TXDONE_BY_POLL))
Sudeep Holla0cc67942015-07-31 11:48:05 +0100100 /* kick start the timer immediately to avoid delays */
101 hrtimer_start(&chan->mbox->poll_hrt, ktime_set(0, 0),
102 HRTIMER_MODE_REL);
Jassi Brar2b6d83e2014-06-12 22:31:19 +0530103}
104
105static void tx_tick(struct mbox_chan *chan, int r)
106{
107 unsigned long flags;
108 void *mssg;
109
110 spin_lock_irqsave(&chan->lock, flags);
111 mssg = chan->active_req;
112 chan->active_req = NULL;
113 spin_unlock_irqrestore(&chan->lock, flags);
114
115 /* Submit next message */
116 msg_submit(chan);
117
Sudeep Holla016a6382017-03-21 11:30:16 +0000118 if (!mssg)
119 return;
120
Jassi Brar2b6d83e2014-06-12 22:31:19 +0530121 /* Notify the client */
Sudeep Holla016a6382017-03-21 11:30:16 +0000122 if (chan->cl->tx_done)
Jassi Brar2b6d83e2014-06-12 22:31:19 +0530123 chan->cl->tx_done(chan->cl, mssg, r);
124
Sudeep Hollaabe90902017-03-21 11:30:15 +0000125 if (r != -ETIME && chan->cl->tx_block)
Jassi Brar2b6d83e2014-06-12 22:31:19 +0530126 complete(&chan->tx_complete);
127}
128
Sudeep Holla0cc67942015-07-31 11:48:05 +0100129static enum hrtimer_restart txdone_hrtimer(struct hrtimer *hrtimer)
Jassi Brar2b6d83e2014-06-12 22:31:19 +0530130{
Sudeep Holla0cc67942015-07-31 11:48:05 +0100131 struct mbox_controller *mbox =
132 container_of(hrtimer, struct mbox_controller, poll_hrt);
Jassi Brar2b6d83e2014-06-12 22:31:19 +0530133 bool txdone, resched = false;
134 int i;
135
136 for (i = 0; i < mbox->num_chans; i++) {
137 struct mbox_chan *chan = &mbox->chans[i];
138
139 if (chan->active_req && chan->cl) {
Jassi Brar2b6d83e2014-06-12 22:31:19 +0530140 txdone = chan->mbox->ops->last_tx_done(chan);
141 if (txdone)
142 tx_tick(chan, 0);
Andrew Bresticker52a49302014-10-30 13:01:07 -0700143 else
144 resched = true;
Jassi Brar2b6d83e2014-06-12 22:31:19 +0530145 }
146 }
147
Sudeep Holla0cc67942015-07-31 11:48:05 +0100148 if (resched) {
149 hrtimer_forward_now(hrtimer, ms_to_ktime(mbox->txpoll_period));
150 return HRTIMER_RESTART;
151 }
152 return HRTIMER_NORESTART;
Jassi Brar2b6d83e2014-06-12 22:31:19 +0530153}
154
155/**
156 * mbox_chan_received_data - A way for controller driver to push data
157 * received from remote to the upper layer.
158 * @chan: Pointer to the mailbox channel on which RX happened.
159 * @mssg: Client specific message typecasted as void *
160 *
161 * After startup and before shutdown any data received on the chan
162 * is passed on to the API via atomic mbox_chan_received_data().
163 * The controller should ACK the RX only after this call returns.
164 */
165void mbox_chan_received_data(struct mbox_chan *chan, void *mssg)
166{
167 /* No buffering the received data */
168 if (chan->cl->rx_callback)
169 chan->cl->rx_callback(chan->cl, mssg);
170}
171EXPORT_SYMBOL_GPL(mbox_chan_received_data);
172
173/**
174 * mbox_chan_txdone - A way for controller driver to notify the
175 * framework that the last TX has completed.
176 * @chan: Pointer to the mailbox chan on which TX happened.
177 * @r: Status of last TX - OK or ERROR
178 *
179 * The controller that has IRQ for TX ACK calls this atomic API
180 * to tick the TX state machine. It works only if txdone_irq
181 * is set by the controller.
182 */
183void mbox_chan_txdone(struct mbox_chan *chan, int r)
184{
185 if (unlikely(!(chan->txdone_method & TXDONE_BY_IRQ))) {
186 dev_err(chan->mbox->dev,
187 "Controller can't run the TX ticker\n");
188 return;
189 }
190
191 tx_tick(chan, r);
192}
193EXPORT_SYMBOL_GPL(mbox_chan_txdone);
194
195/**
196 * mbox_client_txdone - The way for a client to run the TX state machine.
197 * @chan: Mailbox channel assigned to this client.
198 * @r: Success status of last transmission.
199 *
200 * The client/protocol had received some 'ACK' packet and it notifies
201 * the API that the last packet was sent successfully. This only works
202 * if the controller can't sense TX-Done.
203 */
204void mbox_client_txdone(struct mbox_chan *chan, int r)
205{
206 if (unlikely(!(chan->txdone_method & TXDONE_BY_ACK))) {
207 dev_err(chan->mbox->dev, "Client can't run the TX ticker\n");
208 return;
209 }
210
211 tx_tick(chan, r);
212}
213EXPORT_SYMBOL_GPL(mbox_client_txdone);
214
215/**
216 * mbox_client_peek_data - A way for client driver to pull data
217 * received from remote by the controller.
218 * @chan: Mailbox channel assigned to this client.
219 *
220 * A poke to controller driver for any received data.
221 * The data is actually passed onto client via the
222 * mbox_chan_received_data()
223 * The call can be made from atomic context, so the controller's
224 * implementation of peek_data() must not sleep.
225 *
226 * Return: True, if controller has, and is going to push after this,
227 * some data.
228 * False, if controller doesn't have any data to be read.
229 */
230bool mbox_client_peek_data(struct mbox_chan *chan)
231{
232 if (chan->mbox->ops->peek_data)
233 return chan->mbox->ops->peek_data(chan);
234
235 return false;
236}
237EXPORT_SYMBOL_GPL(mbox_client_peek_data);
238
239/**
240 * mbox_send_message - For client to submit a message to be
241 * sent to the remote.
242 * @chan: Mailbox channel assigned to this client.
243 * @mssg: Client specific message typecasted.
244 *
245 * For client to submit data to the controller destined for a remote
246 * processor. If the client had set 'tx_block', the call will return
247 * either when the remote receives the data or when 'tx_tout' millisecs
248 * run out.
249 * In non-blocking mode, the requests are buffered by the API and a
250 * non-negative token is returned for each queued request. If the request
251 * is not queued, a negative token is returned. Upon failure or successful
252 * TX, the API calls 'tx_done' from atomic context, from which the client
253 * could submit yet another request.
254 * The pointer to message should be preserved until it is sent
255 * over the chan, i.e, tx_done() is made.
256 * This function could be called from atomic context as it simply
257 * queues the data and returns a token against the request.
258 *
259 * Return: Non-negative integer for successful submission (non-blocking mode)
260 * or transmission over chan (blocking mode).
261 * Negative value denotes failure.
262 */
263int mbox_send_message(struct mbox_chan *chan, void *mssg)
264{
265 int t;
266
267 if (!chan || !chan->cl)
268 return -EINVAL;
269
270 t = add_to_rbuf(chan, mssg);
271 if (t < 0) {
272 dev_err(chan->mbox->dev, "Try increasing MBOX_TX_QUEUE_LEN\n");
273 return t;
274 }
275
276 msg_submit(chan);
277
Sudeep Hollaa23fba82017-03-21 11:30:14 +0000278 if (chan->cl->tx_block) {
Jassi Brar2b6d83e2014-06-12 22:31:19 +0530279 unsigned long wait;
280 int ret;
281
282 if (!chan->cl->tx_tout) /* wait forever */
283 wait = msecs_to_jiffies(3600000);
284 else
285 wait = msecs_to_jiffies(chan->cl->tx_tout);
286
287 ret = wait_for_completion_timeout(&chan->tx_complete, wait);
288 if (ret == 0) {
Sudeep Hollaabe90902017-03-21 11:30:15 +0000289 t = -ETIME;
290 tx_tick(chan, t);
Jassi Brar2b6d83e2014-06-12 22:31:19 +0530291 }
292 }
293
294 return t;
295}
296EXPORT_SYMBOL_GPL(mbox_send_message);
297
Lina Iyerc525b8d2016-08-22 13:19:26 -0600298/**
Lina Iyer3d9bd812017-09-06 11:34:01 -0600299 * mbox_write_controller_data - For client to submit a message to be
300 * written to the controller but not sent to
301 * the remote processor.
Lina Iyerc525b8d2016-08-22 13:19:26 -0600302 * @chan: Mailbox channel assigned to this client.
303 * @mssg: Client specific message typecasted.
304 *
305 * For client to submit data to the controller. There is no ACK expected
306 * from the controller. This request is not buffered in the mailbox framework.
307 *
308 * Return: Non-negative integer for successful submission (non-blocking mode)
309 * or transmission over chan (blocking mode).
310 * Negative value denotes failure.
311 */
Lina Iyer3d9bd812017-09-06 11:34:01 -0600312int mbox_write_controller_data(struct mbox_chan *chan, void *mssg)
Lina Iyerc525b8d2016-08-22 13:19:26 -0600313{
314 unsigned long flags;
315 int err;
316
317 if (!chan || !chan->cl)
318 return -EINVAL;
319
320 spin_lock_irqsave(&chan->lock, flags);
Lina Iyer3d9bd812017-09-06 11:34:01 -0600321 err = chan->mbox->ops->write_controller_data(chan, mssg);
Lina Iyerc525b8d2016-08-22 13:19:26 -0600322 spin_unlock_irqrestore(&chan->lock, flags);
323
324 return err;
325}
Lina Iyer3d9bd812017-09-06 11:34:01 -0600326EXPORT_SYMBOL(mbox_write_controller_data);
Lina Iyerfc86e1a2016-05-26 11:14:41 -0600327
328bool mbox_controller_is_idle(struct mbox_chan *chan)
329{
330 if (!chan || !chan->cl || !chan->mbox->is_idle)
331 return false;
332
333 return chan->mbox->is_idle(chan->mbox);
334}
335EXPORT_SYMBOL(mbox_controller_is_idle);
336
Lina Iyere2f42722017-07-13 12:37:50 -0600337
338void mbox_chan_debug(struct mbox_chan *chan)
339{
340 if (!chan || !chan->cl || !chan->mbox->debug)
341 return;
342
343 return chan->mbox->debug(chan);
344}
345EXPORT_SYMBOL(mbox_chan_debug);
346
Jassi Brar2b6d83e2014-06-12 22:31:19 +0530347/**
348 * mbox_request_channel - Request a mailbox channel.
349 * @cl: Identity of the client requesting the channel.
350 * @index: Index of mailbox specifier in 'mboxes' property.
351 *
352 * The Client specifies its requirements and capabilities while asking for
353 * a mailbox channel. It can't be called from atomic context.
354 * The channel is exclusively allocated and can't be used by another
355 * client before the owner calls mbox_free_channel.
356 * After assignment, any packet received on this channel will be
357 * handed over to the client via the 'rx_callback'.
358 * The framework holds reference to the client, so the mbox_client
359 * structure shouldn't be modified until the mbox_free_channel returns.
360 *
361 * Return: Pointer to the channel assigned to the client if successful.
362 * ERR_PTR for request failure.
363 */
364struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index)
365{
366 struct device *dev = cl->dev;
367 struct mbox_controller *mbox;
368 struct of_phandle_args spec;
369 struct mbox_chan *chan;
370 unsigned long flags;
371 int ret;
372
373 if (!dev || !dev->of_node) {
374 pr_debug("%s: No owner device node\n", __func__);
375 return ERR_PTR(-ENODEV);
376 }
377
378 mutex_lock(&con_mutex);
379
380 if (of_parse_phandle_with_args(dev->of_node, "mboxes",
381 "#mbox-cells", index, &spec)) {
382 dev_dbg(dev, "%s: can't parse \"mboxes\" property\n", __func__);
383 mutex_unlock(&con_mutex);
384 return ERR_PTR(-ENODEV);
385 }
386
Benson Leung2d805fc2015-05-04 10:36:36 -0700387 chan = ERR_PTR(-EPROBE_DEFER);
Jassi Brar2b6d83e2014-06-12 22:31:19 +0530388 list_for_each_entry(mbox, &mbox_cons, node)
389 if (mbox->dev->of_node == spec.np) {
390 chan = mbox->of_xlate(mbox, &spec);
391 break;
392 }
393
394 of_node_put(spec.np);
395
Benson Leung2d805fc2015-05-04 10:36:36 -0700396 if (IS_ERR(chan)) {
397 mutex_unlock(&con_mutex);
398 return chan;
399 }
400
401 if (chan->cl || !try_module_get(mbox->dev->driver->owner)) {
Jassi Brar2b6d83e2014-06-12 22:31:19 +0530402 dev_dbg(dev, "%s: mailbox not free\n", __func__);
403 mutex_unlock(&con_mutex);
404 return ERR_PTR(-EBUSY);
405 }
406
407 spin_lock_irqsave(&chan->lock, flags);
408 chan->msg_free = 0;
409 chan->msg_count = 0;
410 chan->active_req = NULL;
411 chan->cl = cl;
412 init_completion(&chan->tx_complete);
413
414 if (chan->txdone_method == TXDONE_BY_POLL && cl->knows_txdone)
415 chan->txdone_method |= TXDONE_BY_ACK;
416
417 spin_unlock_irqrestore(&chan->lock, flags);
418
419 ret = chan->mbox->ops->startup(chan);
420 if (ret) {
421 dev_err(dev, "Unable to startup the chan (%d)\n", ret);
422 mbox_free_channel(chan);
423 chan = ERR_PTR(ret);
424 }
425
426 mutex_unlock(&con_mutex);
427 return chan;
428}
429EXPORT_SYMBOL_GPL(mbox_request_channel);
430
Lee Jonesdfabde22015-05-11 17:08:50 +0100431struct mbox_chan *mbox_request_channel_byname(struct mbox_client *cl,
432 const char *name)
433{
434 struct device_node *np = cl->dev->of_node;
435 struct property *prop;
436 const char *mbox_name;
437 int index = 0;
438
439 if (!np) {
440 dev_err(cl->dev, "%s() currently only supports DT\n", __func__);
Lee Jones0c44d782016-03-23 14:43:43 +0000441 return ERR_PTR(-EINVAL);
Lee Jonesdfabde22015-05-11 17:08:50 +0100442 }
443
444 if (!of_get_property(np, "mbox-names", NULL)) {
445 dev_err(cl->dev,
446 "%s() requires an \"mbox-names\" property\n", __func__);
Lee Jones0c44d782016-03-23 14:43:43 +0000447 return ERR_PTR(-EINVAL);
Lee Jonesdfabde22015-05-11 17:08:50 +0100448 }
449
450 of_property_for_each_string(np, "mbox-names", prop, mbox_name) {
451 if (!strncmp(name, mbox_name, strlen(name)))
452 break;
453 index++;
454 }
455
456 return mbox_request_channel(cl, index);
457}
458EXPORT_SYMBOL_GPL(mbox_request_channel_byname);
459
Jassi Brar2b6d83e2014-06-12 22:31:19 +0530460/**
461 * mbox_free_channel - The client relinquishes control of a mailbox
462 * channel by this call.
463 * @chan: The mailbox channel to be freed.
464 */
465void mbox_free_channel(struct mbox_chan *chan)
466{
467 unsigned long flags;
468
469 if (!chan || !chan->cl)
470 return;
471
472 chan->mbox->ops->shutdown(chan);
473
474 /* The queued TX requests are simply aborted, no callbacks are made */
475 spin_lock_irqsave(&chan->lock, flags);
476 chan->cl = NULL;
477 chan->active_req = NULL;
478 if (chan->txdone_method == (TXDONE_BY_POLL | TXDONE_BY_ACK))
479 chan->txdone_method = TXDONE_BY_POLL;
480
481 module_put(chan->mbox->dev->driver->owner);
482 spin_unlock_irqrestore(&chan->lock, flags);
483}
484EXPORT_SYMBOL_GPL(mbox_free_channel);
485
486static struct mbox_chan *
487of_mbox_index_xlate(struct mbox_controller *mbox,
488 const struct of_phandle_args *sp)
489{
490 int ind = sp->args[0];
491
492 if (ind >= mbox->num_chans)
Benson Leung2d805fc2015-05-04 10:36:36 -0700493 return ERR_PTR(-EINVAL);
Jassi Brar2b6d83e2014-06-12 22:31:19 +0530494
495 return &mbox->chans[ind];
496}
497
498/**
499 * mbox_controller_register - Register the mailbox controller
500 * @mbox: Pointer to the mailbox controller.
501 *
502 * The controller driver registers its communication channels
503 */
504int mbox_controller_register(struct mbox_controller *mbox)
505{
506 int i, txdone;
507
508 /* Sanity check */
509 if (!mbox || !mbox->dev || !mbox->ops || !mbox->num_chans)
510 return -EINVAL;
511
512 if (mbox->txdone_irq)
513 txdone = TXDONE_BY_IRQ;
514 else if (mbox->txdone_poll)
515 txdone = TXDONE_BY_POLL;
516 else /* It has to be ACK then */
517 txdone = TXDONE_BY_ACK;
518
519 if (txdone == TXDONE_BY_POLL) {
Sudeep Holla0cc67942015-07-31 11:48:05 +0100520 hrtimer_init(&mbox->poll_hrt, CLOCK_MONOTONIC,
521 HRTIMER_MODE_REL);
522 mbox->poll_hrt.function = txdone_hrtimer;
Jassi Brar2b6d83e2014-06-12 22:31:19 +0530523 }
524
525 for (i = 0; i < mbox->num_chans; i++) {
526 struct mbox_chan *chan = &mbox->chans[i];
527
528 chan->cl = NULL;
529 chan->mbox = mbox;
530 chan->txdone_method = txdone;
531 spin_lock_init(&chan->lock);
532 }
533
534 if (!mbox->of_xlate)
535 mbox->of_xlate = of_mbox_index_xlate;
536
537 mutex_lock(&con_mutex);
538 list_add_tail(&mbox->node, &mbox_cons);
539 mutex_unlock(&con_mutex);
540
541 return 0;
542}
543EXPORT_SYMBOL_GPL(mbox_controller_register);
544
545/**
546 * mbox_controller_unregister - Unregister the mailbox controller
547 * @mbox: Pointer to the mailbox controller.
548 */
549void mbox_controller_unregister(struct mbox_controller *mbox)
550{
551 int i;
552
553 if (!mbox)
554 return;
555
556 mutex_lock(&con_mutex);
557
558 list_del(&mbox->node);
559
560 for (i = 0; i < mbox->num_chans; i++)
561 mbox_free_channel(&mbox->chans[i]);
562
563 if (mbox->txdone_poll)
Sudeep Holla0cc67942015-07-31 11:48:05 +0100564 hrtimer_cancel(&mbox->poll_hrt);
Jassi Brar2b6d83e2014-06-12 22:31:19 +0530565
566 mutex_unlock(&con_mutex);
567}
568EXPORT_SYMBOL_GPL(mbox_controller_unregister);