diff options
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/hotplug/acpiphp.h | 1 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 63 | ||||
-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 | ||||
-rw-r--r-- | drivers/pci/probe.c | 2 |
7 files changed, 90 insertions, 97 deletions
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index 4fc168b70095..e68d5f20ffb3 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h | |||
@@ -129,7 +129,6 @@ struct acpiphp_func { | |||
129 | struct acpiphp_bridge *bridge; /* Ejectable PCI-to-PCI bridge */ | 129 | struct acpiphp_bridge *bridge; /* Ejectable PCI-to-PCI bridge */ |
130 | 130 | ||
131 | struct list_head sibling; | 131 | struct list_head sibling; |
132 | struct pci_dev *pci_dev; | ||
133 | struct notifier_block nb; | 132 | struct notifier_block nb; |
134 | acpi_handle handle; | 133 | acpi_handle handle; |
135 | 134 | ||
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index a33794d9e0dc..3a6064bce561 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -32,9 +32,6 @@ | |||
32 | 32 | ||
33 | /* | 33 | /* |
34 | * Lifetime rules for pci_dev: | 34 | * Lifetime rules for pci_dev: |
35 | * - The one in acpiphp_func has its refcount elevated by pci_get_slot() | ||
36 | * when the driver is loaded or when an insertion event occurs. It loses | ||
37 | * a refcount when its ejected or the driver unloads. | ||
38 | * - The one in acpiphp_bridge has its refcount elevated by pci_get_slot() | 35 | * - The one in acpiphp_bridge has its refcount elevated by pci_get_slot() |
39 | * when the bridge is scanned and it loses a refcount when the bridge | 36 | * when the bridge is scanned and it loses a refcount when the bridge |
40 | * is removed. | 37 | * is removed. |
@@ -130,6 +127,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
130 | unsigned long long adr, sun; | 127 | unsigned long long adr, sun; |
131 | int device, function, retval; | 128 | int device, function, retval; |
132 | struct pci_bus *pbus = bridge->pci_bus; | 129 | struct pci_bus *pbus = bridge->pci_bus; |
130 | struct pci_dev *pdev; | ||
133 | 131 | ||
134 | if (!acpi_pci_check_ejectable(pbus, handle) && !is_dock_device(handle)) | 132 | if (!acpi_pci_check_ejectable(pbus, handle) && !is_dock_device(handle)) |
135 | return AE_OK; | 133 | return AE_OK; |
@@ -213,10 +211,10 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
213 | newfunc->slot = slot; | 211 | newfunc->slot = slot; |
214 | list_add_tail(&newfunc->sibling, &slot->funcs); | 212 | list_add_tail(&newfunc->sibling, &slot->funcs); |
215 | 213 | ||
216 | /* associate corresponding pci_dev */ | 214 | pdev = pci_get_slot(pbus, PCI_DEVFN(device, function)); |
217 | newfunc->pci_dev = pci_get_slot(pbus, PCI_DEVFN(device, function)); | 215 | if (pdev) { |
218 | if (newfunc->pci_dev) { | ||
219 | slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON); | 216 | slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON); |
217 | pci_dev_put(pdev); | ||
220 | } | 218 | } |
221 | 219 | ||
222 | if (is_dock_device(handle)) { | 220 | if (is_dock_device(handle)) { |
@@ -617,7 +615,6 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) | |||
617 | if (ACPI_FAILURE(status)) | 615 | if (ACPI_FAILURE(status)) |
618 | err("failed to remove notify handler\n"); | 616 | err("failed to remove notify handler\n"); |
619 | } | 617 | } |
620 | pci_dev_put(func->pci_dev); | ||
621 | list_del(list); | 618 | list_del(list); |
622 | kfree(func); | 619 | kfree(func); |
623 | } | 620 | } |
@@ -1101,22 +1098,24 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
1101 | pci_enable_bridges(bus); | 1098 | pci_enable_bridges(bus); |
1102 | pci_bus_add_devices(bus); | 1099 | pci_bus_add_devices(bus); |
1103 | 1100 | ||
1104 | /* associate pci_dev to our representation */ | ||
1105 | list_for_each (l, &slot->funcs) { | 1101 | list_for_each (l, &slot->funcs) { |
1106 | func = list_entry(l, struct acpiphp_func, sibling); | 1102 | func = list_entry(l, struct acpiphp_func, sibling); |
1107 | func->pci_dev = pci_get_slot(bus, PCI_DEVFN(slot->device, | 1103 | dev = pci_get_slot(bus, PCI_DEVFN(slot->device, |
1108 | func->function)); | 1104 | func->function)); |
1109 | if (!func->pci_dev) | 1105 | if (!dev) |
1110 | continue; | 1106 | continue; |
1111 | 1107 | ||
1112 | if (func->pci_dev->hdr_type != PCI_HEADER_TYPE_BRIDGE && | 1108 | if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE && |
1113 | func->pci_dev->hdr_type != PCI_HEADER_TYPE_CARDBUS) | 1109 | dev->hdr_type != PCI_HEADER_TYPE_CARDBUS) { |
1110 | pci_dev_put(dev); | ||
1114 | continue; | 1111 | continue; |
1112 | } | ||
1115 | 1113 | ||
1116 | status = find_p2p_bridge(func->handle, (u32)1, bus, NULL); | 1114 | status = find_p2p_bridge(func->handle, (u32)1, bus, NULL); |
1117 | if (ACPI_FAILURE(status)) | 1115 | if (ACPI_FAILURE(status)) |
1118 | warn("find_p2p_bridge failed (error code = 0x%x)\n", | 1116 | warn("find_p2p_bridge failed (error code = 0x%x)\n", |
1119 | status); | 1117 | status); |
1118 | pci_dev_put(dev); | ||
1120 | } | 1119 | } |
1121 | 1120 | ||
1122 | slot->flags |= SLOT_ENABLED; | 1121 | slot->flags |= SLOT_ENABLED; |
@@ -1142,17 +1141,14 @@ static void disable_bridges(struct pci_bus *bus) | |||
1142 | */ | 1141 | */ |
1143 | static int disable_device(struct acpiphp_slot *slot) | 1142 | static int disable_device(struct acpiphp_slot *slot) |
1144 | { | 1143 | { |
1145 | int retval = 0; | ||
1146 | struct acpiphp_func *func; | 1144 | struct acpiphp_func *func; |
1147 | struct list_head *l; | 1145 | struct pci_dev *pdev; |
1148 | 1146 | ||
1149 | /* is this slot already disabled? */ | 1147 | /* is this slot already disabled? */ |
1150 | if (!(slot->flags & SLOT_ENABLED)) | 1148 | if (!(slot->flags & SLOT_ENABLED)) |
1151 | goto err_exit; | 1149 | goto err_exit; |
1152 | 1150 | ||
1153 | list_for_each (l, &slot->funcs) { | 1151 | list_for_each_entry(func, &slot->funcs, sibling) { |
1154 | func = list_entry(l, struct acpiphp_func, sibling); | ||
1155 | |||
1156 | if (func->bridge) { | 1152 | if (func->bridge) { |
1157 | /* cleanup p2p bridges under this P2P bridge */ | 1153 | /* cleanup p2p bridges under this P2P bridge */ |
1158 | cleanup_p2p_bridge(func->bridge->handle, | 1154 | cleanup_p2p_bridge(func->bridge->handle, |
@@ -1160,35 +1156,28 @@ static int disable_device(struct acpiphp_slot *slot) | |||
1160 | func->bridge = NULL; | 1156 | func->bridge = NULL; |
1161 | } | 1157 | } |
1162 | 1158 | ||
1163 | if (func->pci_dev) { | 1159 | pdev = pci_get_slot(slot->bridge->pci_bus, |
1164 | pci_stop_bus_device(func->pci_dev); | 1160 | PCI_DEVFN(slot->device, func->function)); |
1165 | if (func->pci_dev->subordinate) { | 1161 | if (pdev) { |
1166 | disable_bridges(func->pci_dev->subordinate); | 1162 | pci_stop_bus_device(pdev); |
1167 | pci_disable_device(func->pci_dev); | 1163 | if (pdev->subordinate) { |
1164 | disable_bridges(pdev->subordinate); | ||
1165 | pci_disable_device(pdev); | ||
1168 | } | 1166 | } |
1167 | pci_remove_bus_device(pdev); | ||
1168 | pci_dev_put(pdev); | ||
1169 | } | 1169 | } |
1170 | } | 1170 | } |
1171 | 1171 | ||
1172 | list_for_each (l, &slot->funcs) { | 1172 | list_for_each_entry(func, &slot->funcs, sibling) { |
1173 | func = list_entry(l, struct acpiphp_func, sibling); | ||
1174 | |||
1175 | acpiphp_unconfigure_ioapics(func->handle); | 1173 | acpiphp_unconfigure_ioapics(func->handle); |
1176 | acpiphp_bus_trim(func->handle); | 1174 | acpiphp_bus_trim(func->handle); |
1177 | /* try to remove anyway. | ||
1178 | * acpiphp_bus_add might have been failed */ | ||
1179 | |||
1180 | if (!func->pci_dev) | ||
1181 | continue; | ||
1182 | |||
1183 | pci_remove_bus_device(func->pci_dev); | ||
1184 | pci_dev_put(func->pci_dev); | ||
1185 | func->pci_dev = NULL; | ||
1186 | } | 1175 | } |
1187 | 1176 | ||
1188 | slot->flags &= (~SLOT_ENABLED); | 1177 | slot->flags &= (~SLOT_ENABLED); |
1189 | 1178 | ||
1190 | err_exit: | 1179 | err_exit: |
1191 | return retval; | 1180 | return 0; |
1192 | } | 1181 | } |
1193 | 1182 | ||
1194 | 1183 | ||
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; |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index e3c3e081b834..f1ae2475ffff 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -745,6 +745,8 @@ int pci_setup_device(struct pci_dev *dev) | |||
745 | 745 | ||
746 | /* Early fixups, before probing the BARs */ | 746 | /* Early fixups, before probing the BARs */ |
747 | pci_fixup_device(pci_fixup_early, dev); | 747 | pci_fixup_device(pci_fixup_early, dev); |
748 | /* device class may be changed after fixup */ | ||
749 | class = dev->class >> 8; | ||
748 | 750 | ||
749 | switch (dev->hdr_type) { /* header type */ | 751 | switch (dev->hdr_type) { /* header type */ |
750 | case PCI_HEADER_TYPE_NORMAL: /* standard header */ | 752 | case PCI_HEADER_TYPE_NORMAL: /* standard header */ |