Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Jiang 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: Thomas Gleixner <tglx@linutronix.de>

authored by

Jiang Liu and committed by
Thomas Gleixner
34742db8 b1855c75

+39 -43
-2
arch/ia64/include/asm/irq_remapping.h
··· 1 1 #ifndef __IA64_INTR_REMAPPING_H 2 2 #define __IA64_INTR_REMAPPING_H 3 3 #define irq_remapping_enabled 0 4 - #define dmar_alloc_hwirq create_irq 5 - #define dmar_free_hwirq destroy_irq 6 4 #endif
+19 -11
arch/ia64/kernel/msi_ia64.c
··· 165 165 .irq_retrigger = ia64_msi_retrigger_irq, 166 166 }; 167 167 168 - static int 168 + static void 169 169 msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg) 170 170 { 171 171 struct irq_cfg *cfg = irq_cfg + irq; ··· 186 186 MSI_DATA_LEVEL_ASSERT | 187 187 MSI_DATA_DELIVERY_FIXED | 188 188 MSI_DATA_VECTOR(cfg->vector); 189 - return 0; 190 189 } 191 190 192 - int arch_setup_dmar_msi(unsigned int irq) 191 + int dmar_alloc_hwirq(int id, int node, void *arg) 193 192 { 194 - int ret; 193 + int irq; 195 194 struct msi_msg msg; 196 195 197 - ret = msi_compose_msg(NULL, irq, &msg); 198 - if (ret < 0) 199 - return ret; 200 - dmar_msi_write(irq, &msg); 201 - irq_set_chip_and_handler_name(irq, &dmar_msi_type, handle_edge_irq, 202 - "edge"); 203 - return 0; 196 + irq = create_irq(); 197 + if (irq > 0) { 198 + irq_set_handler_data(irq, arg); 199 + irq_set_chip_and_handler_name(irq, &dmar_msi_type, 200 + handle_edge_irq, "edge"); 201 + msi_compose_msg(NULL, irq, &msg); 202 + dmar_msi_write(irq, &msg); 203 + } 204 + 205 + return irq; 206 + } 207 + 208 + void dmar_free_hwirq(int irq) 209 + { 210 + irq_set_handler_data(irq, NULL); 211 + destroy_irq(irq); 204 212 } 205 213 #endif /* CONFIG_INTEL_IOMMU */ 206 214
-4
arch/x86/include/asm/irq_remapping.h
··· 117 117 118 118 #define irq_remapping_print_chip NULL 119 119 #endif /* CONFIG_IRQ_REMAP */ 120 - 121 - extern int dmar_alloc_hwirq(void); 122 - extern void dmar_free_hwirq(int irq); 123 - 124 120 #endif /* __X86_IRQ_REMAPPING_H */
+13 -11
arch/x86/kernel/apic/msi.c
··· 228 228 .flags = IRQCHIP_SKIP_SET_WAKE, 229 229 }; 230 230 231 - int arch_setup_dmar_msi(unsigned int irq) 231 + int dmar_alloc_hwirq(int id, int node, void *arg) 232 232 { 233 + int irq; 233 234 struct msi_msg msg; 234 - struct irq_cfg *cfg = irq_cfg(irq); 235 235 236 - native_compose_msi_msg(cfg, &msg); 237 - dmar_msi_write(irq, &msg); 238 - irq_set_chip_and_handler_name(irq, &dmar_msi_type, handle_edge_irq, 239 - "edge"); 240 - return 0; 241 - } 236 + irq = irq_domain_alloc_irqs(NULL, 1, node, NULL); 237 + if (irq > 0) { 238 + irq_set_handler_data(irq, arg); 239 + irq_set_chip_and_handler_name(irq, &dmar_msi_type, 240 + handle_edge_irq, "edge"); 241 + native_compose_msi_msg(irq_cfg(irq), &msg); 242 + dmar_msi_write(irq, &msg); 243 + } 242 244 243 - int dmar_alloc_hwirq(void) 244 - { 245 - return irq_domain_alloc_irqs(NULL, 1, NUMA_NO_NODE, NULL); 245 + return irq; 246 246 } 247 247 248 248 void dmar_free_hwirq(int irq) 249 249 { 250 + irq_set_handler_data(irq, NULL); 251 + irq_set_handler(irq, NULL); 250 252 irq_domain_free_irqs(irq, 1); 251 253 } 252 254 #endif
+5 -14
drivers/iommu/dmar.c
··· 1087 1087 1088 1088 if (iommu->irq) { 1089 1089 free_irq(iommu->irq, iommu); 1090 - irq_set_handler_data(iommu->irq, NULL); 1091 1090 dmar_free_hwirq(iommu->irq); 1091 + iommu->irq = 0; 1092 1092 } 1093 1093 1094 1094 if (iommu->qi) { ··· 1642 1642 if (iommu->irq) 1643 1643 return 0; 1644 1644 1645 - irq = dmar_alloc_hwirq(); 1646 - if (irq <= 0) { 1645 + irq = dmar_alloc_hwirq(iommu->seq_id, iommu->node, iommu); 1646 + if (irq > 0) { 1647 + iommu->irq = irq; 1648 + } else { 1647 1649 pr_err("IOMMU: no free vectors\n"); 1648 1650 return -EINVAL; 1649 - } 1650 - 1651 - irq_set_handler_data(irq, iommu); 1652 - iommu->irq = irq; 1653 - 1654 - ret = arch_setup_dmar_msi(irq); 1655 - if (ret) { 1656 - irq_set_handler_data(irq, NULL); 1657 - iommu->irq = 0; 1658 - dmar_free_hwirq(irq); 1659 - return ret; 1660 1651 } 1661 1652 1662 1653 ret = request_irq(irq, dmar_fault, IRQF_NO_THREAD, iommu->name, iommu);
+2 -1
include/linux/dmar.h
··· 227 227 extern void dmar_msi_write(int irq, struct msi_msg *msg); 228 228 extern int dmar_set_interrupt(struct intel_iommu *iommu); 229 229 extern irqreturn_t dmar_fault(int irq, void *dev_id); 230 - extern int arch_setup_dmar_msi(unsigned int irq); 230 + extern int dmar_alloc_hwirq(int id, int node, void *arg); 231 + extern void dmar_free_hwirq(int irq); 231 232 232 233 #endif /* __DMAR_H__ */