Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 34742db8 authored by Jiang Liu's avatar Jiang Liu Committed by Thomas Gleixner
Browse files

iommu/vt-d: Refine the interfaces to create IRQ for DMAR unit



Refine the interfaces to create IRQ for DMAR unit. It's a preparation
for converting DMAR IRQ to hierarchical irqdomain on x86.

It also moves dmar_alloc_hwirq()/dmar_free_hwirq() from irq_remapping.h
to dmar.h. They are not irq_remapping specific.

Signed-off-by: default avatarJiang Liu <jiang.liu@linux.intel.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: David Cohen <david.a.cohen@linux.intel.com>
Cc: Sander Eikelenboom <linux@eikelenboom.it>
Cc: David Vrabel <david.vrabel@citrix.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: iommu@lists.linux-foundation.org
Cc: Vinod Koul <vinod.koul@intel.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dimitri Sivanich <sivanich@sgi.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Joerg Roedel <joro@8bytes.org>
Link: http://lkml.kernel.org/r/1428905519-23704-20-git-send-email-jiang.liu@linux.intel.com


Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent b1855c75
Loading
Loading
Loading
Loading
+0 −2
Original line number Original line Diff line number Diff line
#ifndef __IA64_INTR_REMAPPING_H
#ifndef __IA64_INTR_REMAPPING_H
#define __IA64_INTR_REMAPPING_H
#define __IA64_INTR_REMAPPING_H
#define irq_remapping_enabled 0
#define irq_remapping_enabled 0
#define dmar_alloc_hwirq	create_irq
#define dmar_free_hwirq		destroy_irq
#endif
#endif
+19 −11
Original line number Original line Diff line number Diff line
@@ -165,7 +165,7 @@ static struct irq_chip dmar_msi_type = {
	.irq_retrigger = ia64_msi_retrigger_irq,
	.irq_retrigger = ia64_msi_retrigger_irq,
};
};


static int
static void
msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
{
{
	struct irq_cfg *cfg = irq_cfg + irq;
	struct irq_cfg *cfg = irq_cfg + irq;
@@ -186,21 +186,29 @@ msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
		MSI_DATA_LEVEL_ASSERT |
		MSI_DATA_LEVEL_ASSERT |
		MSI_DATA_DELIVERY_FIXED |
		MSI_DATA_DELIVERY_FIXED |
		MSI_DATA_VECTOR(cfg->vector);
		MSI_DATA_VECTOR(cfg->vector);
	return 0;
}
}


int arch_setup_dmar_msi(unsigned int irq)
int dmar_alloc_hwirq(int id, int node, void *arg)
{
{
	int ret;
	int irq;
	struct msi_msg msg;
	struct msi_msg msg;


	ret = msi_compose_msg(NULL, irq, &msg);
	irq = create_irq();
	if (ret < 0)
	if (irq > 0) {
		return ret;
		irq_set_handler_data(irq, arg);
		irq_set_chip_and_handler_name(irq, &dmar_msi_type,
					      handle_edge_irq, "edge");
		msi_compose_msg(NULL, irq, &msg);
		dmar_msi_write(irq, &msg);
		dmar_msi_write(irq, &msg);
	irq_set_chip_and_handler_name(irq, &dmar_msi_type, handle_edge_irq,
	}
				      "edge");

	return 0;
	return irq;
}

void dmar_free_hwirq(int irq)
{
	irq_set_handler_data(irq, NULL);
	destroy_irq(irq);
}
}
#endif /* CONFIG_INTEL_IOMMU */
#endif /* CONFIG_INTEL_IOMMU */
+0 −4
Original line number Original line Diff line number Diff line
@@ -117,8 +117,4 @@ irq_remapping_get_irq_domain(struct irq_alloc_info *info)


#define	irq_remapping_print_chip	NULL
#define	irq_remapping_print_chip	NULL
#endif /* CONFIG_IRQ_REMAP */
#endif /* CONFIG_IRQ_REMAP */

extern int dmar_alloc_hwirq(void);
extern void dmar_free_hwirq(int irq);

#endif /* __X86_IRQ_REMAPPING_H */
#endif /* __X86_IRQ_REMAPPING_H */
+13 −11
Original line number Original line Diff line number Diff line
@@ -228,25 +228,27 @@ static struct irq_chip dmar_msi_type = {
	.flags			= IRQCHIP_SKIP_SET_WAKE,
	.flags			= IRQCHIP_SKIP_SET_WAKE,
};
};


int arch_setup_dmar_msi(unsigned int irq)
int dmar_alloc_hwirq(int id, int node, void *arg)
{
{
	int irq;
	struct msi_msg msg;
	struct msi_msg msg;
	struct irq_cfg *cfg = irq_cfg(irq);


	native_compose_msi_msg(cfg, &msg);
	irq = irq_domain_alloc_irqs(NULL, 1, node, NULL);
	if (irq > 0) {
		irq_set_handler_data(irq, arg);
		irq_set_chip_and_handler_name(irq, &dmar_msi_type,
					      handle_edge_irq, "edge");
		native_compose_msi_msg(irq_cfg(irq), &msg);
		dmar_msi_write(irq, &msg);
		dmar_msi_write(irq, &msg);
	irq_set_chip_and_handler_name(irq, &dmar_msi_type, handle_edge_irq,
				      "edge");
	return 0;
	}
	}


int dmar_alloc_hwirq(void)
	return irq;
{
	return irq_domain_alloc_irqs(NULL, 1, NUMA_NO_NODE, NULL);
}
}


void dmar_free_hwirq(int irq)
void dmar_free_hwirq(int irq)
{
{
	irq_set_handler_data(irq, NULL);
	irq_set_handler(irq, NULL);
	irq_domain_free_irqs(irq, 1);
	irq_domain_free_irqs(irq, 1);
}
}
#endif
#endif
+5 −14
Original line number Original line Diff line number Diff line
@@ -1087,8 +1087,8 @@ static void free_iommu(struct intel_iommu *iommu)


	if (iommu->irq) {
	if (iommu->irq) {
		free_irq(iommu->irq, iommu);
		free_irq(iommu->irq, iommu);
		irq_set_handler_data(iommu->irq, NULL);
		dmar_free_hwirq(iommu->irq);
		dmar_free_hwirq(iommu->irq);
		iommu->irq = 0;
	}
	}


	if (iommu->qi) {
	if (iommu->qi) {
@@ -1642,23 +1642,14 @@ int dmar_set_interrupt(struct intel_iommu *iommu)
	if (iommu->irq)
	if (iommu->irq)
		return 0;
		return 0;


	irq = dmar_alloc_hwirq();
	irq = dmar_alloc_hwirq(iommu->seq_id, iommu->node, iommu);
	if (irq <= 0) {
	if (irq > 0) {
		iommu->irq = irq;
	} else {
		pr_err("IOMMU: no free vectors\n");
		pr_err("IOMMU: no free vectors\n");
		return -EINVAL;
		return -EINVAL;
	}
	}


	irq_set_handler_data(irq, iommu);
	iommu->irq = irq;

	ret = arch_setup_dmar_msi(irq);
	if (ret) {
		irq_set_handler_data(irq, NULL);
		iommu->irq = 0;
		dmar_free_hwirq(irq);
		return ret;
	}

	ret = request_irq(irq, dmar_fault, IRQF_NO_THREAD, iommu->name, iommu);
	ret = request_irq(irq, dmar_fault, IRQF_NO_THREAD, iommu->name, iommu);
	if (ret)
	if (ret)
		pr_err("IOMMU: can't request irq\n");
		pr_err("IOMMU: can't request irq\n");
Loading