Message ID | 20241202100559.57984-1-kkartik@nvidia.com |
---|---|
State | New |
Headers | show |
Series | [v3] mailbox: tegra-hsp: Clear mailbox before using message | expand |
On Mon, Dec 02, 2024 at 03:35:59PM +0530, Kartik Rajput wrote: > From: Pekka Pessi <ppessi@nvidia.com> > > The Tegra RCE (Camera) driver expects the mailbox to be empty before > processing the IVC messages. On RT kernel, the threads processing the > IVC messages (which are invoked after `mbox_chan_received_data()` is > called) may be on a different CPU or running with a higher priority > than the HSP interrupt handler thread. This can cause it to act on the > message before the mailbox gets cleared in the HSP interrupt handler > resulting in a loss of IVC notification. > > Fix this by clearing the mailbox data register before calling > `mbox_chan_received_data()`. > > Fixes: 8f585d14030d ("mailbox: tegra-hsp: Add tegra_hsp_sm_ops") > Fixes: 74c20dd0f892 ("mailbox: tegra-hsp: Add 128-bit shared mailbox support") > Cc: stable@vger.kernel.org > Signed-off-by: Pekka Pessi <ppessi@nvidia.com> > Signed-off-by: Kartik Rajput <kkartik@nvidia.com> > --- > v2 -> v3: > * Updated commit description. > v1 -> v2: > * Added "Fixes:" tag in the commit message. > * Made similar change for 128-bit shared mailboxes. > --- > drivers/mailbox/tegra-hsp.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) Acked-by: Thierry Reding <treding@nvidia.com>
diff --git a/drivers/mailbox/tegra-hsp.c b/drivers/mailbox/tegra-hsp.c index 8d5e2d7dc03b..c1981f091bd1 100644 --- a/drivers/mailbox/tegra-hsp.c +++ b/drivers/mailbox/tegra-hsp.c @@ -388,7 +388,6 @@ static void tegra_hsp_sm_recv32(struct tegra_hsp_channel *channel) value = tegra_hsp_channel_readl(channel, HSP_SM_SHRD_MBOX); value &= ~HSP_SM_SHRD_MBOX_FULL; msg = (void *)(unsigned long)value; - mbox_chan_received_data(channel->chan, msg); /* * Need to clear all bits here since some producers, such as TCU, depend @@ -398,6 +397,8 @@ static void tegra_hsp_sm_recv32(struct tegra_hsp_channel *channel) * explicitly, so we have to make sure we cover all possible cases. */ tegra_hsp_channel_writel(channel, 0x0, HSP_SM_SHRD_MBOX); + + mbox_chan_received_data(channel->chan, msg); } static const struct tegra_hsp_sm_ops tegra_hsp_sm_32bit_ops = { @@ -433,7 +434,6 @@ static void tegra_hsp_sm_recv128(struct tegra_hsp_channel *channel) value[3] = tegra_hsp_channel_readl(channel, HSP_SHRD_MBOX_TYPE1_DATA3); msg = (void *)(unsigned long)value; - mbox_chan_received_data(channel->chan, msg); /* * Clear data registers and tag. @@ -443,6 +443,8 @@ static void tegra_hsp_sm_recv128(struct tegra_hsp_channel *channel) tegra_hsp_channel_writel(channel, 0x0, HSP_SHRD_MBOX_TYPE1_DATA2); tegra_hsp_channel_writel(channel, 0x0, HSP_SHRD_MBOX_TYPE1_DATA3); tegra_hsp_channel_writel(channel, 0x0, HSP_SHRD_MBOX_TYPE1_TAG); + + mbox_chan_received_data(channel->chan, msg); } static const struct tegra_hsp_sm_ops tegra_hsp_sm_128bit_ops = {