aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu
diff options
context:
space:
mode:
authorJoerg Roedel <joerg.roedel@amd.com>2012-03-30 14:47:00 -0400
committerJoerg Roedel <joerg.roedel@amd.com>2012-05-07 08:34:59 -0400
commit736baef4472d00574089f295bc759ac002b9558c (patch)
treed4c9c69b1a0eecd6d87b3378a27396384e4b08f0 /drivers/iommu
parenteef93fdb7cd41ae36794db0e765059dc1039e940 (diff)
iommu/vt-d: Make intr-remapping initialization generic
This patch introduces irq_remap_ops to hold implementation specific function pointer to handle interrupt remapping. As the first part the initialization functions for VT-d are converted to these ops. Signed-off-by: Joerg Roedel <joerg.roedel@amd.com> Acked-by: Yinghai Lu <yinghai@kernel.org> Cc: David Woodhouse <dwmw2@infradead.org> Cc: Alex Williamson <alex.williamson@redhat.com> Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Diffstat (limited to 'drivers/iommu')
-rw-r--r--drivers/iommu/Makefile2
-rw-r--r--drivers/iommu/dmar.c1
-rw-r--r--drivers/iommu/intel-iommu.c1
-rw-r--r--drivers/iommu/intel_intr_remapping.c52
-rw-r--r--drivers/iommu/intr_remapping.c76
-rw-r--r--drivers/iommu/intr_remapping.h46
6 files changed, 137 insertions, 41 deletions
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 1533ebf1d68e..823e1cf8708f 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -4,7 +4,7 @@ obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o
4obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o 4obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
5obj-$(CONFIG_DMAR_TABLE) += dmar.o 5obj-$(CONFIG_DMAR_TABLE) += dmar.o
6obj-$(CONFIG_INTEL_IOMMU) += iova.o intel-iommu.o 6obj-$(CONFIG_INTEL_IOMMU) += iova.o intel-iommu.o
7obj-$(CONFIG_IRQ_REMAP) += intel_intr_remapping.o 7obj-$(CONFIG_IRQ_REMAP) += intel_intr_remapping.o intr_remapping.o
8obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o 8obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
9obj-$(CONFIG_OMAP_IOVMM) += omap-iovmm.o 9obj-$(CONFIG_OMAP_IOVMM) += omap-iovmm.o
10obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o 10obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o
diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index 35c1e17fce1d..647e366403dc 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -36,6 +36,7 @@
36#include <linux/tboot.h> 36#include <linux/tboot.h>
37#include <linux/dmi.h> 37#include <linux/dmi.h>
38#include <linux/slab.h> 38#include <linux/slab.h>
39#include <asm/intr_remapping.h>
39#include <asm/iommu_table.h> 40#include <asm/iommu_table.h>
40 41
41#define PREFIX "DMAR: " 42#define PREFIX "DMAR: "
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index f93d5ac8f81c..e1439808192c 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -42,6 +42,7 @@
42#include <linux/dmi.h> 42#include <linux/dmi.h>
43#include <linux/pci-ats.h> 43#include <linux/pci-ats.h>
44#include <linux/memblock.h> 44#include <linux/memblock.h>
45#include <asm/intr_remapping.h>
45#include <asm/cacheflush.h> 46#include <asm/cacheflush.h>
46#include <asm/iommu.h> 47#include <asm/iommu.h>
47 48
diff --git a/drivers/iommu/intel_intr_remapping.c b/drivers/iommu/intel_intr_remapping.c
index 212fff0c24b5..9c742fb111b6 100644
--- a/drivers/iommu/intel_intr_remapping.c
+++ b/drivers/iommu/intel_intr_remapping.c
@@ -11,8 +11,11 @@
11#include <asm/cpu.h> 11#include <asm/cpu.h>
12#include <linux/intel-iommu.h> 12#include <linux/intel-iommu.h>
13#include <acpi/acpi.h> 13#include <acpi/acpi.h>
14#include <asm/intr_remapping.h>
14#include <asm/pci-direct.h> 15#include <asm/pci-direct.h>
15 16
17#include "intr_remapping.h"
18
16struct ioapic_scope { 19struct ioapic_scope {
17 struct intel_iommu *iommu; 20 struct intel_iommu *iommu;
18 unsigned int id; 21 unsigned int id;
@@ -32,42 +35,6 @@ struct hpet_scope {
32static struct ioapic_scope ir_ioapic[MAX_IO_APICS]; 35static struct ioapic_scope ir_ioapic[MAX_IO_APICS];
33static struct hpet_scope ir_hpet[MAX_HPET_TBS]; 36static struct hpet_scope ir_hpet[MAX_HPET_TBS];
34static int ir_ioapic_num, ir_hpet_num; 37static int ir_ioapic_num, ir_hpet_num;
35int intr_remapping_enabled;
36
37static int disable_intremap;
38static int disable_sourceid_checking;
39static int no_x2apic_optout;
40
41static __init int setup_nointremap(char *str)
42{
43 disable_intremap = 1;
44 return 0;
45}
46early_param("nointremap", setup_nointremap);
47
48static __init int setup_intremap(char *str)
49{
50 if (!str)
51 return -EINVAL;
52
53 while (*str) {
54 if (!strncmp(str, "on", 2))
55 disable_intremap = 0;
56 else if (!strncmp(str, "off", 3))
57 disable_intremap = 1;
58 else if (!strncmp(str, "nosid", 5))
59 disable_sourceid_checking = 1;
60 else if (!strncmp(str, "no_x2apic_optout", 16))
61 no_x2apic_optout = 1;
62
63 str += strcspn(str, ",");
64 while (*str == ',')
65 str++;
66 }
67
68 return 0;
69}
70early_param("intremap", setup_intremap);
71 38
72static DEFINE_RAW_SPINLOCK(irq_2_ir_lock); 39static DEFINE_RAW_SPINLOCK(irq_2_ir_lock);
73 40
@@ -465,7 +432,7 @@ static void iommu_set_intr_remapping(struct intel_iommu *iommu, int mode)
465} 432}
466 433
467 434
468static int setup_intr_remapping(struct intel_iommu *iommu, int mode) 435static int intel_setup_intr_remapping(struct intel_iommu *iommu, int mode)
469{ 436{
470 struct ir_table *ir_table; 437 struct ir_table *ir_table;
471 struct page *pages; 438 struct page *pages;
@@ -534,7 +501,7 @@ static int __init dmar_x2apic_optout(void)
534 return dmar->flags & DMAR_X2APIC_OPT_OUT; 501 return dmar->flags & DMAR_X2APIC_OPT_OUT;
535} 502}
536 503
537int __init intr_remapping_supported(void) 504static int __init intel_intr_remapping_supported(void)
538{ 505{
539 struct dmar_drhd_unit *drhd; 506 struct dmar_drhd_unit *drhd;
540 507
@@ -554,7 +521,7 @@ int __init intr_remapping_supported(void)
554 return 1; 521 return 1;
555} 522}
556 523
557int __init enable_intr_remapping(void) 524static int __init intel_enable_intr_remapping(void)
558{ 525{
559 struct dmar_drhd_unit *drhd; 526 struct dmar_drhd_unit *drhd;
560 int setup = 0; 527 int setup = 0;
@@ -638,7 +605,7 @@ int __init enable_intr_remapping(void)
638 if (!ecap_ir_support(iommu->ecap)) 605 if (!ecap_ir_support(iommu->ecap))
639 continue; 606 continue;
640 607
641 if (setup_intr_remapping(iommu, eim)) 608 if (intel_setup_intr_remapping(iommu, eim))
642 goto error; 609 goto error;
643 610
644 setup = 1; 611 setup = 1;
@@ -847,3 +814,8 @@ error:
847 return -1; 814 return -1;
848} 815}
849 816
817struct irq_remap_ops intel_irq_remap_ops = {
818 .supported = intel_intr_remapping_supported,
819 .hardware_init = dmar_table_init,
820 .hardware_enable = intel_enable_intr_remapping,
821};
diff --git a/drivers/iommu/intr_remapping.c b/drivers/iommu/intr_remapping.c
new file mode 100644
index 000000000000..670c69a80afd
--- /dev/null
+++ b/drivers/iommu/intr_remapping.c
@@ -0,0 +1,76 @@
1#include <linux/kernel.h>
2#include <linux/string.h>
3#include <linux/errno.h>
4
5#include "intr_remapping.h"
6
7int intr_remapping_enabled;
8
9int disable_intremap;
10int disable_sourceid_checking;
11int no_x2apic_optout;
12
13static struct irq_remap_ops *remap_ops;
14
15static __init int setup_nointremap(char *str)
16{
17 disable_intremap = 1;
18 return 0;
19}
20early_param("nointremap", setup_nointremap);
21
22static __init int setup_intremap(char *str)
23{
24 if (!str)
25 return -EINVAL;
26
27 while (*str) {
28 if (!strncmp(str, "on", 2))
29 disable_intremap = 0;
30 else if (!strncmp(str, "off", 3))
31 disable_intremap = 1;
32 else if (!strncmp(str, "nosid", 5))
33 disable_sourceid_checking = 1;
34 else if (!strncmp(str, "no_x2apic_optout", 16))
35 no_x2apic_optout = 1;
36
37 str += strcspn(str, ",");
38 while (*str == ',')
39 str++;
40 }
41
42 return 0;
43}
44early_param("intremap", setup_intremap);
45
46void __init setup_intr_remapping(void)
47{
48 remap_ops = &intel_irq_remap_ops;
49}
50
51int intr_remapping_supported(void)
52{
53 if (disable_intremap)
54 return 0;
55
56 if (!remap_ops || !remap_ops->supported)
57 return 0;
58
59 return remap_ops->supported();
60}
61
62int __init intr_hardware_init(void)
63{
64 if (!remap_ops || !remap_ops->hardware_init)
65 return -ENODEV;
66
67 return remap_ops->hardware_init();
68}
69
70int __init intr_hardware_enable(void)
71{
72 if (!remap_ops || !remap_ops->hardware_enable)
73 return -ENODEV;
74
75 return remap_ops->hardware_enable();
76}
diff --git a/drivers/iommu/intr_remapping.h b/drivers/iommu/intr_remapping.h
new file mode 100644
index 000000000000..d6df732e001f
--- /dev/null
+++ b/drivers/iommu/intr_remapping.h
@@ -0,0 +1,46 @@
1/*
2 * Copyright (C) 2012 Advanced Micro Devices, Inc.
3 * Author: Joerg Roedel <joerg.roedel@amd.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published
7 * by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * This header file contains stuff that is shared between different interrupt
19 * remapping drivers but with no need to be visible outside of the IOMMU layer.
20 */
21
22#ifndef __INTR_REMAPPING_H
23#define __INTR_REMAPPING_H
24
25#ifdef CONFIG_IRQ_REMAP
26
27extern int disable_intremap;
28extern int disable_sourceid_checking;
29extern int no_x2apic_optout;
30
31struct irq_remap_ops {
32 /* Check whether Interrupt Remapping is supported */
33 int (*supported)(void);
34
35 /* Initializes hardware and makes it ready for remapping interrupts */
36 int (*hardware_init)(void);
37
38 /* Enables the remapping hardware */
39 int (*hardware_enable)(void);
40};
41
42extern struct irq_remap_ops intel_irq_remap_ops;
43
44#endif /* CONFIG_IRQ_REMAP */
45
46#endif /* __INTR_REMAPPING_H */