Commit 8c6bba10 authored by Mika Westerberg's avatar Mika Westerberg Committed by David S. Miller
Browse files

thunderbolt: Configure interrupt throttling for all interrupts



This will keep the interrupt delivery rate reasonable. The value used
here (128 us) is a recommendation from the hardware people.

This code is based on the work done by Amir Levy and Michael Jamet.

Signed-off-by: default avatarMichael Jamet <michael.jamet@intel.com>
Signed-off-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: default avatarYehezkel Bernat <yehezkel.bernat@intel.com>
Reviewed-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d1ff7024
Loading
Loading
Loading
Loading
+20 −3
Original line number Diff line number Diff line
@@ -651,6 +651,22 @@ static int nhi_suspend_noirq(struct device *dev)
	return tb_domain_suspend_noirq(tb);
}

static void nhi_enable_int_throttling(struct tb_nhi *nhi)
{
	/* Throttling is specified in 256ns increments */
	u32 throttle = DIV_ROUND_UP(128 * NSEC_PER_USEC, 256);
	unsigned int i;

	/*
	 * Configure interrupt throttling for all vectors even if we
	 * only use few.
	 */
	for (i = 0; i < MSIX_MAX_VECS; i++) {
		u32 reg = REG_INT_THROTTLING_RATE + i * 4;
		iowrite32(throttle, nhi->iobase + reg);
	}
}

static int nhi_resume_noirq(struct device *dev)
{
	struct pci_dev *pdev = to_pci_dev(dev);
@@ -663,6 +679,8 @@ static int nhi_resume_noirq(struct device *dev)
	 */
	if (!pci_device_is_present(pdev))
		tb->nhi->going_away = true;
	else
		nhi_enable_int_throttling(tb->nhi);

	return tb_domain_resume_noirq(tb);
}
@@ -717,6 +735,8 @@ static int nhi_init_msi(struct tb_nhi *nhi)
	/* In case someone left them on. */
	nhi_disable_interrupts(nhi);

	nhi_enable_int_throttling(nhi);

	ida_init(&nhi->msix_ida);

	/*
@@ -796,9 +816,6 @@ static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id)

	pci_set_master(pdev);

	/* magic value - clock related? */
	iowrite32(3906250 / 10000, nhi->iobase + 0x38c00);

	tb = icm_probe(nhi);
	if (!tb)
		tb = tb_probe(nhi);
+2 −0
Original line number Diff line number Diff line
@@ -95,6 +95,8 @@ struct ring_desc {
#define REG_RING_INTERRUPT_BASE	0x38200
#define RING_INTERRUPT_REG_COUNT(nhi) ((31 + 2 * nhi->hop_count) / 32)

#define REG_INT_THROTTLING_RATE	0x38c00

/* Interrupt Vector Allocation */
#define REG_INT_VEC_ALLOC_BASE	0x38c40
#define REG_INT_VEC_ALLOC_BITS	4