mailbox: msm_qmp: Add msgram readback

On some device memory used by msm_qmp, there can be an early ack of a
write to memory succeeding. This may cause the outgoing interrupt to be
triggered before the msgram reflects the write.

Add a readback to ensure the data is flushed to device memory before
triggering the ipc interrupt.

Change-Id: I37618f2921dc34d969a04de80badf1820a188351
Signed-off-by: Chris Lew <clew@codeaurora.org>
This commit is contained in:
Chris Lew
2020-01-08 11:31:21 -08:00
parent 2a98f2349d
commit 21652238fe

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*/ */
#include <linux/io.h> #include <linux/io.h>
@@ -377,6 +377,7 @@ static int qmp_send_data(struct mbox_chan *chan, void *data)
struct qmp_pkt *pkt = (struct qmp_pkt *)data; struct qmp_pkt *pkt = (struct qmp_pkt *)data;
void __iomem *addr; void __iomem *addr;
unsigned long flags; unsigned long flags;
u32 size;
int i; int i;
if (!mbox || !data || mbox->local_state != CHANNEL_CONNECTED) if (!mbox || !data || mbox->local_state != CHANNEL_CONNECTED)
@@ -398,13 +399,15 @@ static int qmp_send_data(struct mbox_chan *chan, void *data)
memcpy32_toio(addr + sizeof(pkt->size), pkt->data, pkt->size); memcpy32_toio(addr + sizeof(pkt->size), pkt->data, pkt->size);
iowrite32(pkt->size, addr); iowrite32(pkt->size, addr);
/* readback to ensure write reflects in msgram */
size = ioread32(addr);
mbox->tx_sent = true; mbox->tx_sent = true;
for (i = 0; i < mbox->ctrl.num_chans; i++) { for (i = 0; i < mbox->ctrl.num_chans; i++) {
if (chan == &mbox->ctrl.chans[i]) if (chan == &mbox->ctrl.chans[i])
mbox->idx_in_flight = i; mbox->idx_in_flight = i;
} }
QMP_INFO(mdev->ilc, "Copied buffer to msgram sz:%d i:%d\n", QMP_INFO(mdev->ilc, "Copied buffer to msgram sz:%d i:%d\n",
pkt->size, mbox->idx_in_flight); size, mbox->idx_in_flight);
send_irq(mdev); send_irq(mdev);
qmp_schedule_tx_timeout(mbox); qmp_schedule_tx_timeout(mbox);
spin_unlock_irqrestore(&mbox->tx_lock, flags); spin_unlock_irqrestore(&mbox->tx_lock, flags);