[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20211209031424.17842-2-chunfeng.yun@mediatek.com>
Date: Thu, 9 Dec 2021 11:14:23 +0800
From: Chunfeng Yun <chunfeng.yun@...iatek.com>
To: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
CC: Chunfeng Yun <chunfeng.yun@...iatek.com>,
Matthias Brugger <matthias.bgg@...il.com>,
<linux-usb@...r.kernel.org>,
<linux-arm-kernel@...ts.infradead.org>,
<linux-mediatek@...ts.infradead.org>,
<linux-kernel@...r.kernel.org>,
Eddie Hung <eddie.hung@...iatek.com>,
Yuwen Ng <yuwen.ng@...iatek.com>, <stable@...r.kernel.org>
Subject: [PATCH 2/3] usb: mtu3: add memory barrier before set GPD's HWO
There is a seldom issue that the controller access invalid address
and trigger devapc or emimpu violation. That is due to memory access
is out of order and cause gpd data is not correct.
Make sure GPD is fully written before giving it to HW by setting its
HWO.
Fixes: 48e0d3735aa5 ("usb: mtu3: supports new QMU format")
Cc: stable@...r.kernel.org
Reported-by: Eddie Hung <eddie.hung@...iatek.com>
Signed-off-by: Chunfeng Yun <chunfeng.yun@...iatek.com>
---
drivers/usb/mtu3/mtu3_qmu.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/mtu3/mtu3_qmu.c b/drivers/usb/mtu3/mtu3_qmu.c
index 3f414f91b589..34bb5ac67efe 100644
--- a/drivers/usb/mtu3/mtu3_qmu.c
+++ b/drivers/usb/mtu3/mtu3_qmu.c
@@ -273,6 +273,8 @@ static int mtu3_prepare_tx_gpd(struct mtu3_ep *mep, struct mtu3_request *mreq)
gpd->dw3_info |= cpu_to_le32(GPD_EXT_FLAG_ZLP);
}
+ /* make sure GPD is fully written before giving it to HW */
+ mb();
gpd->dw0_info |= cpu_to_le32(GPD_FLAGS_IOC | GPD_FLAGS_HWO);
mreq->gpd = gpd;
@@ -306,6 +308,8 @@ static int mtu3_prepare_rx_gpd(struct mtu3_ep *mep, struct mtu3_request *mreq)
gpd->next_gpd = cpu_to_le32(lower_32_bits(enq_dma));
ext_addr |= GPD_EXT_NGP(mtu, upper_32_bits(enq_dma));
gpd->dw3_info = cpu_to_le32(ext_addr);
+ /* make sure GPD is fully written before giving it to HW */
+ mb();
gpd->dw0_info |= cpu_to_le32(GPD_FLAGS_IOC | GPD_FLAGS_HWO);
mreq->gpd = gpd;
@@ -445,7 +449,8 @@ static void qmu_tx_zlp_error_handler(struct mtu3 *mtu, u8 epnum)
return;
}
mtu3_setbits(mbase, MU3D_EP_TXCR0(mep->epnum), TX_TXPKTRDY);
-
+ /* make sure GPD is fully written before giving it to HW */
+ mb();
/* by pass the current GDP */
gpd_current->dw0_info |= cpu_to_le32(GPD_FLAGS_BPS | GPD_FLAGS_HWO);
--
2.18.0
Powered by blists - more mailing lists