Re: [PATCH] mailbox: arm_mhuv2: Fix a bug for mhuv2_sender_interrupt

From: Viresh Kumar
Date: Tue Dec 12 2023 - 05:55:24 EST


On 12-12-23, 17:31, xiaowu.ding wrote:
> From: "Xiaowu.ding" <xiaowu.ding@xxxxxxxxxxxxxxx>
>
> Message Handling Unit version is v2.1.
>
> When arm_mhuv2 working with the data protocol transfer mode.
> We have split one mhu into two channels, and every channel
> include four channel windows, the two channels share
> one gic spi interrupt.
>
> There is a problem with the sending scenario.
>
> The first channel will take up 0-3 channel windows, and the second
> channel take up 4-7 channel windows. When the first channel send the
> data, and the receiver will clear all the four channels status.
> Although we only enabled the interrupt on the last channel window with
> register CH_INT_EN,the register CHCOMB_INT_ST0 will be 0xf, not be 0x8.
> Currently we just clear the last channel windows int status with the
> data proctol mode.So after that,the CHCOMB_INT_ST0 status will be 0x7,
> not be the 0x0.
>
> Then the second channel send the data, the receiver read the
> data, clear all the four channel windows status, trigger the sender
> interrupt. But currently the CHCOMB_INT_ST0 register will be 0xf7,
> get_irq_chan_comb function will always return the first channel.
>
> So this patch clear all channel windows int status to avoid this interrupt
> confusion.
>

Fixes: 5a6338cce9f4 ("mailbox: arm_mhuv2: Add driver")

> Signed-off-by: Xiaowu.ding <xiaowu.ding@xxxxxxxxxxxxxxx>
> ---
> drivers/mailbox/arm_mhuv2.c | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mailbox/arm_mhuv2.c b/drivers/mailbox/arm_mhuv2.c
> index c1ef5016f..9191c5b69 100644
> --- a/drivers/mailbox/arm_mhuv2.c
> +++ b/drivers/mailbox/arm_mhuv2.c
> @@ -542,7 +542,7 @@ static irqreturn_t mhuv2_sender_interrupt(int irq, void *data)
> struct mhuv2_mbox_chan_priv *priv;
> struct mbox_chan *chan;
> unsigned long flags;
> - int i, found = 0;
> + int i, j, found = 0;

Please reuse the variable 'i' here.

> u32 stat;
>
> chan = get_irq_chan_comb(mhu, mhu->send->chcomb_int_st);
> @@ -553,7 +553,8 @@ static irqreturn_t mhuv2_sender_interrupt(int irq, void *data)
> priv = chan->con_priv;
>
> if (!IS_PROTOCOL_DOORBELL(priv)) {
> - writel_relaxed(1, &mhu->send->ch_wn[priv->ch_wn_idx + priv->windows - 1].int_clr);

I vaguely remember that only the last bit was required to be set to
clear interrupt for all the channels but I must be wrong, now that you
are reporting a bug here :)

> + for (j = 0; j < priv->windows; j++)
> + writel_relaxed(1, &mhu->send->ch_wn[priv->ch_wn_idx + j].int_clr);
>
> if (chan->cl) {
> mbox_chan_txdone(chan, 0);

--
viresh