[PATCH] mailbox: Only reset txdone_method to POLL if controller supports polling

From: Douglas Anderson

Date: Tue Nov 03 2026 - 19:43:36 EST


In mbox_controller_register(), a mailbox controller's default
txdone_method is initialized to MBOX_TXDONE_BY_IRQ if mbox->txdone_irq
is set, MBOX_TXDONE_BY_POLL if mbox->txdone_poll is set, or
MBOX_TXDONE_BY_ACK if neither is set. Only controllers with
mbox->txdone_poll set initialize mbox->poll_hrt and require
mbox->ops->last_tx_done to be implemented.

When a client with cl->knows_txdone = true binds to a channel whose
controller uses MBOX_TXDONE_BY_POLL, __mbox_bind_client() overrides
chan->txdone_method to MBOX_TXDONE_BY_ACK. Commit 33cd7123ac0b
("mailbox: reset txdone_method TXDONE_BY_POLL if client knows_txdone")
attempted to restore chan->txdone_method to MBOX_TXDONE_BY_POLL when
the channel is released, but did so unconditionally whenever
chan->txdone_method == MBOX_TXDONE_BY_ACK:

if (chan->txdone_method == MBOX_TXDONE_BY_ACK)
chan->txdone_method = MBOX_TXDONE_BY_POLL;

For controllers whose native txdone_method is MBOX_TXDONE_BY_ACK
(!txdone_irq && !txdone_poll), releasing a channel (or failing in the
controller's startup() callback) corrupts chan->txdone_method to
MBOX_TXDONE_BY_POLL even though the controller does not support
polling and has not initialized poll_hrt or ops->last_tx_done.

Check chan->mbox->txdone_poll before resetting chan->txdone_method to
MBOX_TXDONE_BY_POLL in mbox_clean_and_put_channel().

Fixes: 33cd7123ac0b ("mailbox: reset txdone_method TXDONE_BY_POLL if client knows_txdone")
Signed-off-by: Douglas Anderson <dianders@xxxxxxxxxxxx>
---
Found by code inspection and only compile-tested.

drivers/mailbox/mailbox.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
index efacd24a085d..cfc49cfb057c 100644
--- a/drivers/mailbox/mailbox.c
+++ b/drivers/mailbox/mailbox.c
@@ -343,7 +343,7 @@ static void mbox_clean_and_put_channel(struct mbox_chan *chan)
scoped_guard(spinlock_irqsave, &chan->lock) {
chan->cl = NULL;
chan->active_req = MBOX_NO_MSG;
- if (chan->txdone_method == MBOX_TXDONE_BY_ACK)
+ if (chan->txdone_method == MBOX_TXDONE_BY_ACK && chan->mbox->txdone_poll)
chan->txdone_method = MBOX_TXDONE_BY_POLL;
}

--
2.56.0.385.gac671c819a-goog