aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/hw_irq.h4
-rw-r--r--arch/x86/kernel/apic/io_apic.c107
-rw-r--r--arch/x86/pci/irq.c24
-rw-r--r--drivers/pci/hotplug/ibmphp_core.c56
4 files changed, 112 insertions, 79 deletions
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index b762ea49bd70..26a40ab70131 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -63,7 +63,9 @@ extern unsigned long io_apic_irqs;
63extern void init_VISWS_APIC_irqs(void); 63extern void init_VISWS_APIC_irqs(void);
64extern void setup_IO_APIC(void); 64extern void setup_IO_APIC(void);
65extern void disable_IO_APIC(void); 65extern void disable_IO_APIC(void);
66extern int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn); 66extern int IO_APIC_get_PCI_irq_vector(int bus, int devfn, int pin,
67 int *ioapic, int *ioapic_pin,
68 int *trigger, int *polarity);
67extern void setup_ioapic_dest(void); 69extern void setup_ioapic_dest(void);
68 70
69extern void enable_IO_APIC(void); 71extern void enable_IO_APIC(void);
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index e279ae339285..caf9dbdde050 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -873,54 +873,6 @@ static int __init find_isa_irq_apic(int irq, int type)
873 return -1; 873 return -1;
874} 874}
875 875
876/*
877 * Find a specific PCI IRQ entry.
878 * Not an __init, possibly needed by modules
879 */
880static int pin_2_irq(int idx, int apic, int pin);
881
882int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin)
883{
884 int apic, i, best_guess = -1;
885
886 apic_printk(APIC_DEBUG, "querying PCI -> IRQ mapping bus:%d, slot:%d, pin:%d.\n",
887 bus, slot, pin);
888 if (test_bit(bus, mp_bus_not_pci)) {
889 apic_printk(APIC_VERBOSE, "PCI BIOS passed nonexistent PCI bus %d!\n", bus);
890 return -1;
891 }
892 for (i = 0; i < mp_irq_entries; i++) {
893 int lbus = mp_irqs[i].srcbus;
894
895 for (apic = 0; apic < nr_ioapics; apic++)
896 if (mp_ioapics[apic].apicid == mp_irqs[i].dstapic ||
897 mp_irqs[i].dstapic == MP_APIC_ALL)
898 break;
899
900 if (!test_bit(lbus, mp_bus_not_pci) &&
901 !mp_irqs[i].irqtype &&
902 (bus == lbus) &&
903 (slot == ((mp_irqs[i].srcbusirq >> 2) & 0x1f))) {
904 int irq = pin_2_irq(i, apic, mp_irqs[i].dstirq);
905
906 if (!(apic || IO_APIC_IRQ(irq)))
907 continue;
908
909 if (pin == (mp_irqs[i].srcbusirq & 3))
910 return irq;
911 /*
912 * Use the first all-but-pin matching entry as a
913 * best-guess fuzzy result for broken mptables.
914 */
915 if (best_guess < 0)
916 best_guess = irq;
917 }
918 }
919 return best_guess;
920}
921
922EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
923
924#if defined(CONFIG_EISA) || defined(CONFIG_MCA) 876#if defined(CONFIG_EISA) || defined(CONFIG_MCA)
925/* 877/*
926 * EISA Edge/Level control register, ELCR 878 * EISA Edge/Level control register, ELCR
@@ -1139,6 +1091,65 @@ static int pin_2_irq(int idx, int apic, int pin)
1139 return irq; 1091 return irq;
1140} 1092}
1141 1093
1094/*
1095 * Find a specific PCI IRQ entry.
1096 * Not an __init, possibly needed by modules
1097 */
1098int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin,
1099 int *ioapic, int *ioapic_pin,
1100 int *trigger, int *polarity)
1101{
1102 int apic, i, best_guess = -1;
1103
1104 apic_printk(APIC_DEBUG,
1105 "querying PCI -> IRQ mapping bus:%d, slot:%d, pin:%d.\n",
1106 bus, slot, pin);
1107 if (test_bit(bus, mp_bus_not_pci)) {
1108 apic_printk(APIC_VERBOSE,
1109 "PCI BIOS passed nonexistent PCI bus %d!\n", bus);
1110 return -1;
1111 }
1112 for (i = 0; i < mp_irq_entries; i++) {
1113 int lbus = mp_irqs[i].srcbus;
1114
1115 for (apic = 0; apic < nr_ioapics; apic++)
1116 if (mp_ioapics[apic].apicid == mp_irqs[i].dstapic ||
1117 mp_irqs[i].dstapic == MP_APIC_ALL)
1118 break;
1119
1120 if (!test_bit(lbus, mp_bus_not_pci) &&
1121 !mp_irqs[i].irqtype &&
1122 (bus == lbus) &&
1123 (slot == ((mp_irqs[i].srcbusirq >> 2) & 0x1f))) {
1124 int irq = pin_2_irq(i, apic, mp_irqs[i].dstirq);
1125
1126 if (!(apic || IO_APIC_IRQ(irq)))
1127 continue;
1128
1129 if (pin == (mp_irqs[i].srcbusirq & 3)) {
1130 *ioapic = apic;
1131 *ioapic_pin = mp_irqs[i].dstirq;
1132 *trigger = irq_trigger(i);
1133 *polarity = irq_polarity(i);
1134 return irq;
1135 }
1136 /*
1137 * Use the first all-but-pin matching entry as a
1138 * best-guess fuzzy result for broken mptables.
1139 */
1140 if (best_guess < 0) {
1141 *ioapic = apic;
1142 *ioapic_pin = mp_irqs[i].dstirq;
1143 *trigger = irq_trigger(i);
1144 *polarity = irq_polarity(i);
1145 best_guess = irq;
1146 }
1147 }
1148 }
1149 return best_guess;
1150}
1151EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
1152
1142void lock_vector_lock(void) 1153void lock_vector_lock(void)
1143{ 1154{
1144 /* Used to the online set of cpus does not change 1155 /* Used to the online set of cpus does not change
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index fecbce6e7d7c..a2f6bde9c4eb 100644
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c
@@ -1051,12 +1051,16 @@ static void __init pcibios_fixup_irqs(void)
1051 */ 1051 */
1052 if (io_apic_assign_pci_irqs) { 1052 if (io_apic_assign_pci_irqs) {
1053 int irq; 1053 int irq;
1054 int ioapic = -1, ioapic_pin = -1;
1055 int triggering, polarity;
1054 1056
1055 /* 1057 /*
1056 * interrupt pins are numbered starting from 1 1058 * interrupt pins are numbered starting from 1
1057 */ 1059 */
1058 irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, 1060 irq = IO_APIC_get_PCI_irq_vector(dev->bus->number,
1059 PCI_SLOT(dev->devfn), pin - 1); 1061 PCI_SLOT(dev->devfn), pin - 1,
1062 &ioapic, &ioapic_pin,
1063 &triggering, &polarity);
1060 /* 1064 /*
1061 * Busses behind bridges are typically not listed in the 1065 * Busses behind bridges are typically not listed in the
1062 * MP-table. In this case we have to look up the IRQ 1066 * MP-table. In this case we have to look up the IRQ
@@ -1072,7 +1076,10 @@ static void __init pcibios_fixup_irqs(void)
1072 pin = pci_swizzle_interrupt_pin(dev, pin); 1076 pin = pci_swizzle_interrupt_pin(dev, pin);
1073 bus = bridge->bus->number; 1077 bus = bridge->bus->number;
1074 irq = IO_APIC_get_PCI_irq_vector(bus, 1078 irq = IO_APIC_get_PCI_irq_vector(bus,
1075 PCI_SLOT(bridge->devfn), pin - 1); 1079 PCI_SLOT(bridge->devfn),
1080 pin - 1,
1081 &ioapic, &ioapic_pin,
1082 &triggering, &polarity);
1076 if (irq >= 0) 1083 if (irq >= 0)
1077 dev_warn(&dev->dev, 1084 dev_warn(&dev->dev,
1078 "using bridge %s INT %c to " 1085 "using bridge %s INT %c to "
@@ -1221,8 +1228,14 @@ static int pirq_enable_irq(struct pci_dev *dev)
1221 1228
1222 if (io_apic_assign_pci_irqs) { 1229 if (io_apic_assign_pci_irqs) {
1223 int irq; 1230 int irq;
1231 int ioapic = -1, ioapic_pin = -1;
1232 int triggering, polarity;
1224 1233
1225 irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin - 1); 1234 irq = IO_APIC_get_PCI_irq_vector(dev->bus->number,
1235 PCI_SLOT(dev->devfn),
1236 pin - 1,
1237 &ioapic, &ioapic_pin,
1238 &triggering, &polarity);
1226 /* 1239 /*
1227 * Busses behind bridges are typically not listed in the MP-table. 1240 * Busses behind bridges are typically not listed in the MP-table.
1228 * In this case we have to look up the IRQ based on the parent bus, 1241 * In this case we have to look up the IRQ based on the parent bus,
@@ -1235,7 +1248,10 @@ static int pirq_enable_irq(struct pci_dev *dev)
1235 1248
1236 pin = pci_swizzle_interrupt_pin(dev, pin); 1249 pin = pci_swizzle_interrupt_pin(dev, pin);
1237 irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, 1250 irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number,
1238 PCI_SLOT(bridge->devfn), pin - 1); 1251 PCI_SLOT(bridge->devfn),
1252 pin - 1,
1253 &ioapic, &ioapic_pin,
1254 &triggering, &polarity);
1239 if (irq >= 0) 1255 if (irq >= 0)
1240 dev_warn(&dev->dev, "using bridge %s " 1256 dev_warn(&dev->dev, "using bridge %s "
1241 "INT %c to get IRQ %d\n", 1257 "INT %c to get IRQ %d\n",
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c
index dd18f857dfb0..ef53b05a411a 100644
--- a/drivers/pci/hotplug/ibmphp_core.c
+++ b/drivers/pci/hotplug/ibmphp_core.c
@@ -153,45 +153,49 @@ 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 int ioapic = -1, ioapic_pin = -1;
159 int triggering, polarity;
160
158 (*cur_slot)->device = PCI_SLOT(rtable->slots[loop].devfn); 161 (*cur_slot)->device = PCI_SLOT(rtable->slots[loop].devfn);
159 for (i = 0; i < 4; i++) 162 for (i = 0; i < 4; i++)
160 (*cur_slot)->irq[i] = IO_APIC_get_PCI_irq_vector((int) (*cur_slot)->bus, 163 (*cur_slot)->irq[i] = IO_APIC_get_PCI_irq_vector((int) (*cur_slot)->bus,
161 (int) (*cur_slot)->device, i); 164 (int) (*cur_slot)->device, i.
162 165 &ioapic, &ioapic_pin,
163 debug("(*cur_slot)->irq[0] = %x\n", 166 &triggering, &polarity);
164 (*cur_slot)->irq[0]); 167
165 debug("(*cur_slot)->irq[1] = %x\n", 168 debug("(*cur_slot)->irq[0] = %x\n",
166 (*cur_slot)->irq[1]); 169 (*cur_slot)->irq[0]);
167 debug("(*cur_slot)->irq[2] = %x\n", 170 debug("(*cur_slot)->irq[1] = %x\n",
168 (*cur_slot)->irq[2]); 171 (*cur_slot)->irq[1]);
169 debug("(*cur_slot)->irq[3] = %x\n", 172 debug("(*cur_slot)->irq[2] = %x\n",
170 (*cur_slot)->irq[3]); 173 (*cur_slot)->irq[2]);
171 174 debug("(*cur_slot)->irq[3] = %x\n",
172 debug("rtable->exlusive_irqs = %x\n", 175 (*cur_slot)->irq[3]);
176
177 debug("rtable->exlusive_irqs = %x\n",
173 rtable->exclusive_irqs); 178 rtable->exclusive_irqs);
174 debug("rtable->slots[loop].irq[0].bitmap = %x\n", 179 debug("rtable->slots[loop].irq[0].bitmap = %x\n",
175 rtable->slots[loop].irq[0].bitmap); 180 rtable->slots[loop].irq[0].bitmap);
176 debug("rtable->slots[loop].irq[1].bitmap = %x\n", 181 debug("rtable->slots[loop].irq[1].bitmap = %x\n",
177 rtable->slots[loop].irq[1].bitmap); 182 rtable->slots[loop].irq[1].bitmap);
178 debug("rtable->slots[loop].irq[2].bitmap = %x\n", 183 debug("rtable->slots[loop].irq[2].bitmap = %x\n",
179 rtable->slots[loop].irq[2].bitmap); 184 rtable->slots[loop].irq[2].bitmap);
180 debug("rtable->slots[loop].irq[3].bitmap = %x\n", 185 debug("rtable->slots[loop].irq[3].bitmap = %x\n",
181 rtable->slots[loop].irq[3].bitmap); 186 rtable->slots[loop].irq[3].bitmap);
182 187
183 debug("rtable->slots[loop].irq[0].link = %x\n", 188 debug("rtable->slots[loop].irq[0].link = %x\n",
184 rtable->slots[loop].irq[0].link); 189 rtable->slots[loop].irq[0].link);
185 debug("rtable->slots[loop].irq[1].link = %x\n", 190 debug("rtable->slots[loop].irq[1].link = %x\n",
186 rtable->slots[loop].irq[1].link); 191 rtable->slots[loop].irq[1].link);
187 debug("rtable->slots[loop].irq[2].link = %x\n", 192 debug("rtable->slots[loop].irq[2].link = %x\n",
188 rtable->slots[loop].irq[2].link); 193 rtable->slots[loop].irq[2].link);
189 debug("rtable->slots[loop].irq[3].link = %x\n", 194 debug("rtable->slots[loop].irq[3].link = %x\n",
190 rtable->slots[loop].irq[3].link); 195 rtable->slots[loop].irq[3].link);
191 debug("end of init_devno\n"); 196 debug("end of init_devno\n");
192 kfree(rtable); 197 kfree(rtable);
193 return 0; 198 return 0;
194 }
195 } 199 }
196 } 200 }
197 201