summaryrefslogtreecommitdiffstats
path: root/drivers/thunderbolt/nhi_regs.h
diff options
context:
space:
mode:
authorMario Limonciello <mario.limonciello@amd.com>2023-03-10 11:20:50 -0600
committerMika Westerberg <mika.westerberg@linux.intel.com>2023-03-20 09:38:40 +0200
commit468c49f44759720a312e52d44a71c3949ed63d7c (patch)
tree1e46bf9682eddc5ada7f3de7b3dd0384682e8d65 /drivers/thunderbolt/nhi_regs.h
parent1716efdb07938bd6510e1127d02012799112c433 (diff)
downloadlinux-stable-468c49f44759720a312e52d44a71c3949ed63d7c.tar.gz
linux-stable-468c49f44759720a312e52d44a71c3949ed63d7c.tar.bz2
linux-stable-468c49f44759720a312e52d44a71c3949ed63d7c.zip
thunderbolt: Disable interrupt auto clear for rings
When interrupt auto clear is programmed, any read to the interrupt status register will clear all interrupts. If two interrupts have come in before one can be serviced then this will cause lost interrupts. On AMD USB4 routers this has manifested in odd problems particularly with long strings of control tranfers such as reading the DROM via bit banging. Instead of clearing interrupts automatically, clear the bit corresponding to the given ring's interrupt in the ISR. Fixes: 7a1808f82a37 ("thunderbolt: Handle ring interrupt by reading interrupt status register") Cc: Sanju Mehta <Sanju.Mehta@amd.com> Cc: stable@vger.kernel.org Tested-by: Anson Tsao <anson.tsao@amd.com> Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Diffstat (limited to 'drivers/thunderbolt/nhi_regs.h')
-rw-r--r--drivers/thunderbolt/nhi_regs.h6
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/thunderbolt/nhi_regs.h b/drivers/thunderbolt/nhi_regs.h
index 0d4970dcef84..faef165a919c 100644
--- a/drivers/thunderbolt/nhi_regs.h
+++ b/drivers/thunderbolt/nhi_regs.h
@@ -77,12 +77,13 @@ struct ring_desc {
/*
* three bitfields: tx, rx, rx overflow
- * Every bitfield contains one bit for every hop (REG_HOP_COUNT). Registers are
- * cleared on read. New interrupts are fired only after ALL registers have been
+ * Every bitfield contains one bit for every hop (REG_HOP_COUNT).
+ * New interrupts are fired only after ALL registers have been
* read (even those containing only disabled rings).
*/
#define REG_RING_NOTIFY_BASE 0x37800
#define RING_NOTIFY_REG_COUNT(nhi) ((31 + 3 * nhi->hop_count) / 32)
+#define REG_RING_INT_CLEAR 0x37808
/*
* two bitfields: rx, tx
@@ -105,6 +106,7 @@ struct ring_desc {
#define REG_DMA_MISC 0x39864
#define REG_DMA_MISC_INT_AUTO_CLEAR BIT(2)
+#define REG_DMA_MISC_DISABLE_AUTO_CLEAR BIT(17)
#define REG_INMAIL_DATA 0x39900