[PATCH 6/8] mailbox: mpfs-mbox: replace unbounded BUSY polling with bounded waits
Jamie Gibbons
jamie.gibbons at microchip.com
Thu Jun 25 14:23:23 CEST 2026
The MPFS mailbox driver used unbounded polling loops and treated the
BUSY bit as a fatal condition in several paths. On MPFS, BUSY may be
transiently reasserted even after response data is written, which is
observable in U-Boot’s synchronous, polled execution model.
Replace the unbounded loops with a bounded
regmap_read_poll_timeout()-based helper that waits for the controller to
become idle.
This preserves existing behaviour while preventing infinite stalls.
Signed-off-by: Jamie Gibbons <jamie.gibbons at microchip.com>
---
drivers/mailbox/mpfs-mbox.c | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/drivers/mailbox/mpfs-mbox.c b/drivers/mailbox/mpfs-mbox.c
index b1ce377525e..165d9d89630 100644
--- a/drivers/mailbox/mpfs-mbox.c
+++ b/drivers/mailbox/mpfs-mbox.c
@@ -18,6 +18,7 @@
#include <linux/compat.h>
#include <linux/err.h>
#include <linux/errno.h>
+#include <linux/iopoll.h>
#include <log.h>
#include <mailbox-uclass.h>
#include <mpfs-mailbox.h>
@@ -60,6 +61,7 @@ static int mpfs_mbox_send(struct mbox_chan *chan, const void *data)
u32 mailbox_val, cmd_shifted, value;
u8 *byte_buf;
u8 idx, byte_idx, byte_offset;
+ int ret;
u32 *word_buf = (u32 *)msg->cmd_data;
@@ -86,13 +88,19 @@ static int mpfs_mbox_send(struct mbox_chan *chan, const void *data)
regmap_write(mbox->control_scb, SERVICES_CR_OFFSET, cmd_shifted);
- do {
- regmap_read(mbox->control_scb, SERVICES_CR_OFFSET, &value);
- } while (SERVICE_CR_REQ_MASK == (value & SERVICE_CR_REQ_MASK));
+ ret = regmap_read_poll_timeout(mbox->control_scb, SERVICES_CR_OFFSET,
+ value, !(value & SERVICE_CR_REQ_MASK),
+ 1, /* poll every 1 µs */
+ 20); /* timeout 20 ms */
+ if (ret)
+ return ret;
- do {
- regmap_read(mbox->control_scb, SERVICES_SR_OFFSET, &value);
- } while (SERVICE_SR_BUSY_MASK == (value & SERVICE_SR_BUSY_MASK));
+ ret = regmap_read_poll_timeout(mbox->control_scb, SERVICES_SR_OFFSET,
+ value, !(value & SERVICE_SR_BUSY_MASK),
+ 1,
+ 20);
+ if (ret)
+ return ret;
msg->response->resp_status = (value >> SERVICE_SR_STATUS_SHIFT);
if (msg->response->resp_status)
--
2.43.0
More information about the U-Boot
mailing list