@@ -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;
@@ -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);
+ }
+ }
+}
@@ -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);