mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-27 17:18:59 +00:00
50 lines
1.8 KiB
Diff
50 lines
1.8 KiB
Diff
|
From edbbc60ed86f4b690838e6c4b0aed48803e334cc Mon Sep 17 00:00:00 2001
|
||
|
From: Jonathan Bell <jonathan@raspberrypi.org>
|
||
|
Date: Mon, 13 Jan 2020 15:54:55 +0000
|
||
|
Subject: [PATCH] dwc_otg: fiq_fsm: add a barrier on entry into FIQ
|
||
|
handler(s)
|
||
|
|
||
|
On BCM2835, there is no hardware guarantee that multiple outstanding
|
||
|
reads to different peripherals will complete in-order. The FIQ code
|
||
|
uses peripheral reads without barriers for performance, so in the case
|
||
|
where a read to a slow peripheral was issued immediately prior to FIQ
|
||
|
entry, the first peripheral read that the FIQ did could end up with
|
||
|
wrong read data returned.
|
||
|
|
||
|
Add dsb(sy) on entry so that all outstanding reads are retired.
|
||
|
|
||
|
The FIQ only issues reads to the dwc_otg core, so per-read barriers
|
||
|
in the handler itself are not required.
|
||
|
|
||
|
On BCM2836 and BCM2837 the barrier is not strictly required due to
|
||
|
differences in how the peripheral bus is implemented, but having
|
||
|
arch-specific handlers that introduce different latencies is risky.
|
||
|
|
||
|
Signed-off-by: Jonathan Bell <jonathan@raspberrypi.org>
|
||
|
---
|
||
|
drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c | 6 ++++++
|
||
|
1 file changed, 6 insertions(+)
|
||
|
|
||
|
--- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c
|
||
|
+++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c
|
||
|
@@ -1259,6 +1259,9 @@ void notrace dwc_otg_fiq_fsm(struct fiq_
|
||
|
haintmsk_data_t haintmsk;
|
||
|
int kick_irq = 0;
|
||
|
|
||
|
+ /* Ensure peripheral reads issued prior to FIQ entry are complete */
|
||
|
+ dsb(sy);
|
||
|
+
|
||
|
gintsts_handled.d32 = 0;
|
||
|
haint_handled.d32 = 0;
|
||
|
|
||
|
@@ -1379,6 +1382,9 @@ void notrace dwc_otg_fiq_nop(struct fiq_
|
||
|
gintmsk_data_t gintmsk;
|
||
|
hfnum_data_t hfnum;
|
||
|
|
||
|
+ /* Ensure peripheral reads issued prior to FIQ entry are complete */
|
||
|
+ dsb(sy);
|
||
|
+
|
||
|
fiq_fsm_spin_lock(&state->lock);
|
||
|
hfnum.d32 = FIQ_READ(state->dwc_regs_base + HFNUM);
|
||
|
gintsts.d32 = FIQ_READ(state->dwc_regs_base + GINTSTS);
|