From: Sanjay R Mehta <sanju.mehta@xxxxxxx> REG_DMA_MISC_INT_AUTO_CLEAR which is bit 2 in that register is actually Intel specific. As per the USB4 spec bit 17 is used for interrupt auto clear and by default its enabled. Hence limit usage of REG_DMA_MISC_INT_AUTO_CLEAR for Intel controllers and moved this to quirk. Fixes: 046bee1f9ab8 ("thunderbolt: Add MSI-X support") Suggested-by: Mika Westerberg <mika.westerberg@xxxxxxxxxxxxxxx> Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@xxxxxxx> Signed-off-by: Sanjay R Mehta <sanju.mehta@xxxxxxx> --- drivers/thunderbolt/nhi.c | 8 ++------ drivers/thunderbolt/quirks.c | 14 ++++++++++++++ drivers/thunderbolt/tb.h | 1 + 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c index fa44332..ef01aa6 100644 --- a/drivers/thunderbolt/nhi.c +++ b/drivers/thunderbolt/nhi.c @@ -57,8 +57,8 @@ static void ring_interrupt_active(struct tb_ring *ring, bool active) u32 old, new; if (ring->irq > 0) { - u32 step, shift, ivr, misc; void __iomem *ivr_base; + u32 step, shift, ivr; int index; if (ring->is_tx) @@ -70,11 +70,7 @@ static void ring_interrupt_active(struct tb_ring *ring, bool active) * Ask the hardware to clear interrupt status bits automatically * since we already know which interrupt was triggered. */ - misc = ioread32(ring->nhi->iobase + REG_DMA_MISC); - if (!(misc & REG_DMA_MISC_INT_AUTO_CLEAR)) { - misc |= REG_DMA_MISC_INT_AUTO_CLEAR; - iowrite32(misc, ring->nhi->iobase + REG_DMA_MISC); - } + quirk_enable_intr_auto_clr(ring); ivr_base = ring->nhi->iobase + REG_INT_VEC_ALLOC_BASE; step = index / REG_INT_VEC_ALLOC_REGS * REG_INT_VEC_ALLOC_BITS; diff --git a/drivers/thunderbolt/quirks.c b/drivers/thunderbolt/quirks.c index b5f2ec7..af6dab9 100644 --- a/drivers/thunderbolt/quirks.c +++ b/drivers/thunderbolt/quirks.c @@ -6,6 +6,7 @@ */ #include "tb.h" +#include "nhi_regs.h" static void quirk_force_power_link(struct tb_switch *sw) { @@ -64,3 +65,16 @@ void tb_check_quirks(struct tb_switch *sw) q->hook(sw); } } + +void quirk_enable_intr_auto_clr(struct tb_ring *ring) +{ + u32 misc; + + if (ring->nhi->pdev->vendor == PCI_VENDOR_ID_INTEL) { + misc = ioread32(ring->nhi->iobase + REG_DMA_MISC); + if (!(misc & REG_DMA_MISC_INT_AUTO_CLEAR)) { + misc |= REG_DMA_MISC_INT_AUTO_CLEAR; + iowrite32(misc, ring->nhi->iobase + REG_DMA_MISC); + } + } +} diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h index 725104c..0b8f9d3 100644 --- a/drivers/thunderbolt/tb.h +++ b/drivers/thunderbolt/tb.h @@ -1122,6 +1122,7 @@ int usb4_port_device_resume(struct usb4_port *usb4); #define QUIRK_FORCE_POWER_LINK_CONTROLLER BIT(0) void tb_check_quirks(struct tb_switch *sw); +void quirk_enable_intr_auto_clr(struct tb_ring *ring); #ifdef CONFIG_ACPI void tb_acpi_add_links(struct tb_nhi *nhi); -- 2.7.4