diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-10 18:25:41 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-10 18:25:41 -0400 |
commit | f0d5e12bd42b7173ebbbf59279c867605f859814 (patch) | |
tree | f4018a726ecd2cf520afdf27210bfec1f3181718 /drivers/pci | |
parent | 0fea615e526b4b7eff0363ee02d5753e5f924089 (diff) | |
parent | 103428e57be323c3c5545db8ad12667099bc6005 (diff) |
Merge branch 'irq-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'irq-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (76 commits)
x86, apic: Fix dummy apic read operation together with broken MP handling
x86, apic: Restore irqs on fail paths
x86: Print real IOAPIC version for x86-64
x86: enable_update_mptable should be a macro
sparseirq: Allow early irq_desc allocation
x86, io-apic: Don't mark pin_programmed early
x86, irq: don't call mp_config_acpi_gsi() if update_mptable is not enabled
x86, irq: update_mptable needs pci_routeirq
x86: don't call read_apic_id if !cpu_has_apic
x86, apic: introduce io_apic_irq_attr
x86/pci: add 4 more return parameters to IO_APIC_get_PCI_irq_vector(), fix
x86: read apic ID in the !acpi_lapic case
x86: apic: Fixmap apic address even if apic disabled
x86: display extended apic registers with print_local_APIC and cpu_debug code
x86: read apic ID in the !acpi_lapic case
x86: clean up and fix setup_clear/force_cpu_cap handling
x86: apic: Check rev 3 fadt correctly for physical_apic bit
x86/pci: update pirq_enable_irq() to setup io apic routing
x86/acpi: move setup io apic routing out of CONFIG_ACPI scope
x86/pci: add 4 more return parameters to IO_APIC_get_PCI_irq_vector()
...
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/hotplug/ibmphp_core.c | 54 | ||||
-rw-r--r-- | drivers/pci/htirq.c | 4 | ||||
-rw-r--r-- | drivers/pci/intel-iommu.c | 9 | ||||
-rw-r--r-- | drivers/pci/intr_remapping.c | 54 |
4 files changed, 62 insertions, 59 deletions
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index dd18f857dfb0..42e4260c3b12 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c | |||
@@ -153,45 +153,47 @@ int ibmphp_init_devno(struct slot **cur_slot) | |||
153 | return -1; | 153 | return -1; |
154 | } | 154 | } |
155 | for (loop = 0; loop < len; loop++) { | 155 | for (loop = 0; loop < len; loop++) { |
156 | if ((*cur_slot)->number == rtable->slots[loop].slot) { | 156 | if ((*cur_slot)->number == rtable->slots[loop].slot && |
157 | if ((*cur_slot)->bus == rtable->slots[loop].bus) { | 157 | (*cur_slot)->bus == rtable->slots[loop].bus) { |
158 | struct io_apic_irq_attr irq_attr; | ||
159 | |||
158 | (*cur_slot)->device = PCI_SLOT(rtable->slots[loop].devfn); | 160 | (*cur_slot)->device = PCI_SLOT(rtable->slots[loop].devfn); |
159 | for (i = 0; i < 4; i++) | 161 | for (i = 0; i < 4; i++) |
160 | (*cur_slot)->irq[i] = IO_APIC_get_PCI_irq_vector((int) (*cur_slot)->bus, | 162 | (*cur_slot)->irq[i] = IO_APIC_get_PCI_irq_vector((int) (*cur_slot)->bus, |
161 | (int) (*cur_slot)->device, i); | 163 | (int) (*cur_slot)->device, i, |
162 | 164 | &irq_attr); | |
163 | debug("(*cur_slot)->irq[0] = %x\n", | 165 | |
164 | (*cur_slot)->irq[0]); | 166 | debug("(*cur_slot)->irq[0] = %x\n", |
165 | debug("(*cur_slot)->irq[1] = %x\n", | 167 | (*cur_slot)->irq[0]); |
166 | (*cur_slot)->irq[1]); | 168 | debug("(*cur_slot)->irq[1] = %x\n", |
167 | debug("(*cur_slot)->irq[2] = %x\n", | 169 | (*cur_slot)->irq[1]); |
168 | (*cur_slot)->irq[2]); | 170 | debug("(*cur_slot)->irq[2] = %x\n", |
169 | debug("(*cur_slot)->irq[3] = %x\n", | 171 | (*cur_slot)->irq[2]); |
170 | (*cur_slot)->irq[3]); | 172 | debug("(*cur_slot)->irq[3] = %x\n", |
171 | 173 | (*cur_slot)->irq[3]); | |
172 | debug("rtable->exlusive_irqs = %x\n", | 174 | |
175 | debug("rtable->exlusive_irqs = %x\n", | ||
173 | rtable->exclusive_irqs); | 176 | rtable->exclusive_irqs); |
174 | debug("rtable->slots[loop].irq[0].bitmap = %x\n", | 177 | debug("rtable->slots[loop].irq[0].bitmap = %x\n", |
175 | rtable->slots[loop].irq[0].bitmap); | 178 | rtable->slots[loop].irq[0].bitmap); |
176 | debug("rtable->slots[loop].irq[1].bitmap = %x\n", | 179 | debug("rtable->slots[loop].irq[1].bitmap = %x\n", |
177 | rtable->slots[loop].irq[1].bitmap); | 180 | rtable->slots[loop].irq[1].bitmap); |
178 | debug("rtable->slots[loop].irq[2].bitmap = %x\n", | 181 | debug("rtable->slots[loop].irq[2].bitmap = %x\n", |
179 | rtable->slots[loop].irq[2].bitmap); | 182 | rtable->slots[loop].irq[2].bitmap); |
180 | debug("rtable->slots[loop].irq[3].bitmap = %x\n", | 183 | debug("rtable->slots[loop].irq[3].bitmap = %x\n", |
181 | rtable->slots[loop].irq[3].bitmap); | 184 | rtable->slots[loop].irq[3].bitmap); |
182 | 185 | ||
183 | debug("rtable->slots[loop].irq[0].link = %x\n", | 186 | debug("rtable->slots[loop].irq[0].link = %x\n", |
184 | rtable->slots[loop].irq[0].link); | 187 | rtable->slots[loop].irq[0].link); |
185 | debug("rtable->slots[loop].irq[1].link = %x\n", | 188 | debug("rtable->slots[loop].irq[1].link = %x\n", |
186 | rtable->slots[loop].irq[1].link); | 189 | rtable->slots[loop].irq[1].link); |
187 | debug("rtable->slots[loop].irq[2].link = %x\n", | 190 | debug("rtable->slots[loop].irq[2].link = %x\n", |
188 | rtable->slots[loop].irq[2].link); | 191 | rtable->slots[loop].irq[2].link); |
189 | debug("rtable->slots[loop].irq[3].link = %x\n", | 192 | debug("rtable->slots[loop].irq[3].link = %x\n", |
190 | rtable->slots[loop].irq[3].link); | 193 | rtable->slots[loop].irq[3].link); |
191 | debug("end of init_devno\n"); | 194 | debug("end of init_devno\n"); |
192 | kfree(rtable); | 195 | kfree(rtable); |
193 | return 0; | 196 | return 0; |
194 | } | ||
195 | } | 197 | } |
196 | } | 198 | } |
197 | 199 | ||
diff --git a/drivers/pci/htirq.c b/drivers/pci/htirq.c index 6808d8333ecc..737a1c44b07a 100644 --- a/drivers/pci/htirq.c +++ b/drivers/pci/htirq.c | |||
@@ -98,6 +98,7 @@ int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update) | |||
98 | int max_irq; | 98 | int max_irq; |
99 | int pos; | 99 | int pos; |
100 | int irq; | 100 | int irq; |
101 | int node; | ||
101 | 102 | ||
102 | pos = pci_find_ht_capability(dev, HT_CAPTYPE_IRQ); | 103 | pos = pci_find_ht_capability(dev, HT_CAPTYPE_IRQ); |
103 | if (!pos) | 104 | if (!pos) |
@@ -125,7 +126,8 @@ int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update) | |||
125 | cfg->msg.address_lo = 0xffffffff; | 126 | cfg->msg.address_lo = 0xffffffff; |
126 | cfg->msg.address_hi = 0xffffffff; | 127 | cfg->msg.address_hi = 0xffffffff; |
127 | 128 | ||
128 | irq = create_irq(); | 129 | node = dev_to_node(&dev->dev); |
130 | irq = create_irq_nr(0, node); | ||
129 | 131 | ||
130 | if (irq <= 0) { | 132 | if (irq <= 0) { |
131 | kfree(cfg); | 133 | kfree(cfg); |
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index a563fbe559d0..cd389162735f 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
@@ -1972,15 +1972,6 @@ static int __init init_dmars(void) | |||
1972 | } | 1972 | } |
1973 | } | 1973 | } |
1974 | 1974 | ||
1975 | #ifdef CONFIG_INTR_REMAP | ||
1976 | if (!intr_remapping_enabled) { | ||
1977 | ret = enable_intr_remapping(0); | ||
1978 | if (ret) | ||
1979 | printk(KERN_ERR | ||
1980 | "IOMMU: enable interrupt remapping failed\n"); | ||
1981 | } | ||
1982 | #endif | ||
1983 | |||
1984 | /* | 1975 | /* |
1985 | * For each rmrr | 1976 | * For each rmrr |
1986 | * for each dev attached to rmrr | 1977 | * for each dev attached to rmrr |
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c index f5e0ea724a6f..3a0cb0bb0593 100644 --- a/drivers/pci/intr_remapping.c +++ b/drivers/pci/intr_remapping.c | |||
@@ -15,6 +15,14 @@ static struct ioapic_scope ir_ioapic[MAX_IO_APICS]; | |||
15 | static int ir_ioapic_num; | 15 | static int ir_ioapic_num; |
16 | int intr_remapping_enabled; | 16 | int intr_remapping_enabled; |
17 | 17 | ||
18 | static int disable_intremap; | ||
19 | static __init int setup_nointremap(char *str) | ||
20 | { | ||
21 | disable_intremap = 1; | ||
22 | return 0; | ||
23 | } | ||
24 | early_param("nointremap", setup_nointremap); | ||
25 | |||
18 | struct irq_2_iommu { | 26 | struct irq_2_iommu { |
19 | struct intel_iommu *iommu; | 27 | struct intel_iommu *iommu; |
20 | u16 irte_index; | 28 | u16 irte_index; |
@@ -23,15 +31,12 @@ struct irq_2_iommu { | |||
23 | }; | 31 | }; |
24 | 32 | ||
25 | #ifdef CONFIG_GENERIC_HARDIRQS | 33 | #ifdef CONFIG_GENERIC_HARDIRQS |
26 | static struct irq_2_iommu *get_one_free_irq_2_iommu(int cpu) | 34 | static struct irq_2_iommu *get_one_free_irq_2_iommu(int node) |
27 | { | 35 | { |
28 | struct irq_2_iommu *iommu; | 36 | struct irq_2_iommu *iommu; |
29 | int node; | ||
30 | |||
31 | node = cpu_to_node(cpu); | ||
32 | 37 | ||
33 | iommu = kzalloc_node(sizeof(*iommu), GFP_ATOMIC, node); | 38 | iommu = kzalloc_node(sizeof(*iommu), GFP_ATOMIC, node); |
34 | printk(KERN_DEBUG "alloc irq_2_iommu on cpu %d node %d\n", cpu, node); | 39 | printk(KERN_DEBUG "alloc irq_2_iommu on node %d\n", node); |
35 | 40 | ||
36 | return iommu; | 41 | return iommu; |
37 | } | 42 | } |
@@ -48,7 +53,7 @@ static struct irq_2_iommu *irq_2_iommu(unsigned int irq) | |||
48 | return desc->irq_2_iommu; | 53 | return desc->irq_2_iommu; |
49 | } | 54 | } |
50 | 55 | ||
51 | static struct irq_2_iommu *irq_2_iommu_alloc_cpu(unsigned int irq, int cpu) | 56 | static struct irq_2_iommu *irq_2_iommu_alloc_node(unsigned int irq, int node) |
52 | { | 57 | { |
53 | struct irq_desc *desc; | 58 | struct irq_desc *desc; |
54 | struct irq_2_iommu *irq_iommu; | 59 | struct irq_2_iommu *irq_iommu; |
@@ -56,7 +61,7 @@ static struct irq_2_iommu *irq_2_iommu_alloc_cpu(unsigned int irq, int cpu) | |||
56 | /* | 61 | /* |
57 | * alloc irq desc if not allocated already. | 62 | * alloc irq desc if not allocated already. |
58 | */ | 63 | */ |
59 | desc = irq_to_desc_alloc_cpu(irq, cpu); | 64 | desc = irq_to_desc_alloc_node(irq, node); |
60 | if (!desc) { | 65 | if (!desc) { |
61 | printk(KERN_INFO "can not get irq_desc for %d\n", irq); | 66 | printk(KERN_INFO "can not get irq_desc for %d\n", irq); |
62 | return NULL; | 67 | return NULL; |
@@ -65,14 +70,14 @@ static struct irq_2_iommu *irq_2_iommu_alloc_cpu(unsigned int irq, int cpu) | |||
65 | irq_iommu = desc->irq_2_iommu; | 70 | irq_iommu = desc->irq_2_iommu; |
66 | 71 | ||
67 | if (!irq_iommu) | 72 | if (!irq_iommu) |
68 | desc->irq_2_iommu = get_one_free_irq_2_iommu(cpu); | 73 | desc->irq_2_iommu = get_one_free_irq_2_iommu(node); |
69 | 74 | ||
70 | return desc->irq_2_iommu; | 75 | return desc->irq_2_iommu; |
71 | } | 76 | } |
72 | 77 | ||
73 | static struct irq_2_iommu *irq_2_iommu_alloc(unsigned int irq) | 78 | static struct irq_2_iommu *irq_2_iommu_alloc(unsigned int irq) |
74 | { | 79 | { |
75 | return irq_2_iommu_alloc_cpu(irq, boot_cpu_id); | 80 | return irq_2_iommu_alloc_node(irq, cpu_to_node(boot_cpu_id)); |
76 | } | 81 | } |
77 | 82 | ||
78 | #else /* !CONFIG_SPARSE_IRQ */ | 83 | #else /* !CONFIG_SPARSE_IRQ */ |
@@ -423,20 +428,6 @@ static void iommu_set_intr_remapping(struct intel_iommu *iommu, int mode) | |||
423 | readl, (sts & DMA_GSTS_IRTPS), sts); | 428 | readl, (sts & DMA_GSTS_IRTPS), sts); |
424 | spin_unlock_irqrestore(&iommu->register_lock, flags); | 429 | spin_unlock_irqrestore(&iommu->register_lock, flags); |
425 | 430 | ||
426 | if (mode == 0) { | ||
427 | spin_lock_irqsave(&iommu->register_lock, flags); | ||
428 | |||
429 | /* enable comaptiblity format interrupt pass through */ | ||
430 | cmd = iommu->gcmd | DMA_GCMD_CFI; | ||
431 | iommu->gcmd |= DMA_GCMD_CFI; | ||
432 | writel(cmd, iommu->reg + DMAR_GCMD_REG); | ||
433 | |||
434 | IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, | ||
435 | readl, (sts & DMA_GSTS_CFIS), sts); | ||
436 | |||
437 | spin_unlock_irqrestore(&iommu->register_lock, flags); | ||
438 | } | ||
439 | |||
440 | /* | 431 | /* |
441 | * global invalidation of interrupt entry cache before enabling | 432 | * global invalidation of interrupt entry cache before enabling |
442 | * interrupt-remapping. | 433 | * interrupt-remapping. |
@@ -516,6 +507,23 @@ end: | |||
516 | spin_unlock_irqrestore(&iommu->register_lock, flags); | 507 | spin_unlock_irqrestore(&iommu->register_lock, flags); |
517 | } | 508 | } |
518 | 509 | ||
510 | int __init intr_remapping_supported(void) | ||
511 | { | ||
512 | struct dmar_drhd_unit *drhd; | ||
513 | |||
514 | if (disable_intremap) | ||
515 | return 0; | ||
516 | |||
517 | for_each_drhd_unit(drhd) { | ||
518 | struct intel_iommu *iommu = drhd->iommu; | ||
519 | |||
520 | if (!ecap_ir_support(iommu->ecap)) | ||
521 | return 0; | ||
522 | } | ||
523 | |||
524 | return 1; | ||
525 | } | ||
526 | |||
519 | int __init enable_intr_remapping(int eim) | 527 | int __init enable_intr_remapping(int eim) |
520 | { | 528 | { |
521 | struct dmar_drhd_unit *drhd; | 529 | struct dmar_drhd_unit *drhd; |