drivers: mailbox: fix race resulting in multiple message submission

The mailbox sends a request to the controller and the tx_done callback
received for that request clears the active_req pointer. The callback
sends the next request in the queue, if there is one. When a controller
is busy and cannot accept any more requests until the interrupt is
cleared, it would return -EAGAIN. The mailbox controller must unlock its
spinlock and retry again.

Change-Id: Id58c7365be8c6bfc7f90fe9445c88c1246d2d7f8
Signed-off-by: Lina Iyer <ilina@codeaurora.org>
This commit is contained in:
Lina Iyer 2017-12-08 19:36:13 +00:00 • committed by Chris Lew
commit 36d1eee8b0

View file

@ -50,7 +50,7 @@ static int add_to_rbuf(struct mbox_chan *chan, void *mssg)
return idx;
}
static void msg_submit(struct mbox_chan *chan)
static int __msg_submit(struct mbox_chan *chan)
{
unsigned count, idx;
unsigned long flags;
@ -82,6 +82,24 @@ static void msg_submit(struct mbox_chan *chan)
exit:
spin_unlock_irqrestore(&chan->lock, flags);
return err;
}
static void msg_submit(struct mbox_chan *chan)
{
int err = 0;
/*
* If the controller returns -EAGAIN, then it means, our spinlock
* here is preventing the controller from receiving its interrupt,
* that would help clear the controller channels that are currently
* blocked waiting on the interrupt response.
* Retry again.
*/
do {
err = __msg_submit(chan);
} while (err == -EAGAIN);
if (!err && (chan->txdone_method & TXDONE_BY_POLL))
/* kick start the timer immediately to avoid delays */
hrtimer_start(&chan->mbox->poll_hrt, 0, HRTIMER_MODE_REL);