diff options
-rw-r--r-- | arch/x86/include/asm/hw_irq.h | 4 | ||||
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 107 | ||||
-rw-r--r-- | arch/x86/pci/irq.c | 24 | ||||
-rw-r--r-- | drivers/pci/hotplug/ibmphp_core.c | 56 |
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; | |||
63 | extern void init_VISWS_APIC_irqs(void); | 63 | extern void init_VISWS_APIC_irqs(void); |
64 | extern void setup_IO_APIC(void); | 64 | extern void setup_IO_APIC(void); |
65 | extern void disable_IO_APIC(void); | 65 | extern void disable_IO_APIC(void); |
66 | extern int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn); | 66 | extern int IO_APIC_get_PCI_irq_vector(int bus, int devfn, int pin, |
67 | int *ioapic, int *ioapic_pin, | ||
68 | int *trigger, int *polarity); | ||
67 | extern void setup_ioapic_dest(void); | 69 | extern void setup_ioapic_dest(void); |
68 | 70 | ||
69 | extern void enable_IO_APIC(void); | 71 | extern 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 | */ | ||
880 | static int pin_2_irq(int idx, int apic, int pin); | ||
881 | |||
882 | int 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 | |||
922 | EXPORT_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 | */ | ||
1098 | int 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 | } | ||
1151 | EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector); | ||
1152 | |||
1142 | void lock_vector_lock(void) | 1153 | void 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 | ||