diff options
-rw-r--r-- | arch/x86/include/asm/hw_irq.h | 21 | ||||
-rw-r--r-- | arch/x86/include/asm/io_apic.h | 5 | ||||
-rw-r--r-- | arch/x86/kernel/acpi/boot.c | 22 | ||||
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 43 | ||||
-rw-r--r-- | arch/x86/pci/irq.c | 16 | ||||
-rw-r--r-- | drivers/pci/hotplug/ibmphp_core.c | 6 |
6 files changed, 66 insertions, 47 deletions
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h index 26a40ab70131..a7d14bbae110 100644 --- a/arch/x86/include/asm/hw_irq.h +++ b/arch/x86/include/asm/hw_irq.h | |||
@@ -63,9 +63,26 @@ 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 | |||
67 | struct io_apic_irq_attr { | ||
68 | int ioapic; | ||
69 | int ioapic_pin; | ||
70 | int trigger; | ||
71 | int polarity; | ||
72 | }; | ||
73 | |||
74 | static inline void set_io_apic_irq_attr(struct io_apic_irq_attr *irq_attr, | ||
75 | int ioapic, int ioapic_pin, | ||
76 | int trigger, int polarity) | ||
77 | { | ||
78 | irq_attr->ioapic = ioapic; | ||
79 | irq_attr->ioapic_pin = ioapic_pin; | ||
80 | irq_attr->trigger = trigger; | ||
81 | irq_attr->polarity = polarity; | ||
82 | } | ||
83 | |||
66 | extern int IO_APIC_get_PCI_irq_vector(int bus, int devfn, int pin, | 84 | extern int IO_APIC_get_PCI_irq_vector(int bus, int devfn, int pin, |
67 | int *ioapic, int *ioapic_pin, | 85 | struct io_apic_irq_attr *irq_attr); |
68 | int *trigger, int *polarity); | ||
69 | extern void setup_ioapic_dest(void); | 86 | extern void setup_ioapic_dest(void); |
70 | 87 | ||
71 | extern void enable_IO_APIC(void); | 88 | extern void enable_IO_APIC(void); |
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h index 6fd99f96eb0a..daf866ed0612 100644 --- a/arch/x86/include/asm/io_apic.h +++ b/arch/x86/include/asm/io_apic.h | |||
@@ -156,8 +156,9 @@ extern int io_apic_get_version(int ioapic); | |||
156 | extern int io_apic_get_redir_entries(int ioapic); | 156 | extern int io_apic_get_redir_entries(int ioapic); |
157 | #endif /* CONFIG_ACPI */ | 157 | #endif /* CONFIG_ACPI */ |
158 | 158 | ||
159 | extern int io_apic_set_pci_routing(struct device *dev, int ioapic, int pin, | 159 | struct io_apic_irq_attr; |
160 | int irq, int edge_level, int active_high_low); | 160 | extern int io_apic_set_pci_routing(struct device *dev, int irq, |
161 | struct io_apic_irq_attr *irq_attr); | ||
161 | extern int (*ioapic_renumber_irq)(int ioapic, int irq); | 162 | extern int (*ioapic_renumber_irq)(int ioapic, int irq); |
162 | extern void ioapic_init_mappings(void); | 163 | extern void ioapic_init_mappings(void); |
163 | 164 | ||
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index dcfbc3ab9e46..4af63dfb0f06 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
@@ -523,7 +523,7 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) | |||
523 | * success: return IRQ number (>=0) | 523 | * success: return IRQ number (>=0) |
524 | * failure: return < 0 | 524 | * failure: return < 0 |
525 | */ | 525 | */ |
526 | int acpi_register_gsi(struct device *dev, u32 gsi, int triggering, int polarity) | 526 | int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) |
527 | { | 527 | { |
528 | unsigned int irq; | 528 | unsigned int irq; |
529 | unsigned int plat_gsi = gsi; | 529 | unsigned int plat_gsi = gsi; |
@@ -533,14 +533,14 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int triggering, int polarity) | |||
533 | * Make sure all (legacy) PCI IRQs are set as level-triggered. | 533 | * Make sure all (legacy) PCI IRQs are set as level-triggered. |
534 | */ | 534 | */ |
535 | if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) { | 535 | if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) { |
536 | if (triggering == ACPI_LEVEL_SENSITIVE) | 536 | if (trigger == ACPI_LEVEL_SENSITIVE) |
537 | eisa_set_level_irq(gsi); | 537 | eisa_set_level_irq(gsi); |
538 | } | 538 | } |
539 | #endif | 539 | #endif |
540 | 540 | ||
541 | #ifdef CONFIG_X86_IO_APIC | 541 | #ifdef CONFIG_X86_IO_APIC |
542 | if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) { | 542 | if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) { |
543 | plat_gsi = mp_register_gsi(dev, gsi, triggering, polarity); | 543 | plat_gsi = mp_register_gsi(dev, gsi, trigger, polarity); |
544 | } | 544 | } |
545 | #endif | 545 | #endif |
546 | acpi_gsi_to_irq(plat_gsi, &irq); | 546 | acpi_gsi_to_irq(plat_gsi, &irq); |
@@ -1156,7 +1156,7 @@ void __init mp_config_acpi_legacy_irqs(void) | |||
1156 | } | 1156 | } |
1157 | } | 1157 | } |
1158 | 1158 | ||
1159 | static int mp_config_acpi_gsi(struct device *dev, u32 gsi, int triggering, | 1159 | static int mp_config_acpi_gsi(struct device *dev, u32 gsi, int trigger, |
1160 | int polarity) | 1160 | int polarity) |
1161 | { | 1161 | { |
1162 | #ifdef CONFIG_X86_MPPARSE | 1162 | #ifdef CONFIG_X86_MPPARSE |
@@ -1181,7 +1181,7 @@ static int mp_config_acpi_gsi(struct device *dev, u32 gsi, int triggering, | |||
1181 | /* print the entry should happen on mptable identically */ | 1181 | /* print the entry should happen on mptable identically */ |
1182 | mp_irq.type = MP_INTSRC; | 1182 | mp_irq.type = MP_INTSRC; |
1183 | mp_irq.irqtype = mp_INT; | 1183 | mp_irq.irqtype = mp_INT; |
1184 | mp_irq.irqflag = (triggering == ACPI_EDGE_SENSITIVE ? 4 : 0x0c) | | 1184 | mp_irq.irqflag = (trigger == ACPI_EDGE_SENSITIVE ? 4 : 0x0c) | |
1185 | (polarity == ACPI_ACTIVE_HIGH ? 1 : 3); | 1185 | (polarity == ACPI_ACTIVE_HIGH ? 1 : 3); |
1186 | mp_irq.srcbus = number; | 1186 | mp_irq.srcbus = number; |
1187 | mp_irq.srcbusirq = (((devfn >> 3) & 0x1f) << 2) | ((pin - 1) & 3); | 1187 | mp_irq.srcbusirq = (((devfn >> 3) & 0x1f) << 2) | ((pin - 1) & 3); |
@@ -1194,10 +1194,11 @@ static int mp_config_acpi_gsi(struct device *dev, u32 gsi, int triggering, | |||
1194 | return 0; | 1194 | return 0; |
1195 | } | 1195 | } |
1196 | 1196 | ||
1197 | int mp_register_gsi(struct device *dev, u32 gsi, int triggering, int polarity) | 1197 | int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) |
1198 | { | 1198 | { |
1199 | int ioapic; | 1199 | int ioapic; |
1200 | int ioapic_pin; | 1200 | int ioapic_pin; |
1201 | struct io_apic_irq_attr irq_attr; | ||
1201 | 1202 | ||
1202 | if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC) | 1203 | if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC) |
1203 | return gsi; | 1204 | return gsi; |
@@ -1225,11 +1226,12 @@ int mp_register_gsi(struct device *dev, u32 gsi, int triggering, int polarity) | |||
1225 | ioapic_pin); | 1226 | ioapic_pin); |
1226 | return gsi; | 1227 | return gsi; |
1227 | } | 1228 | } |
1228 | mp_config_acpi_gsi(dev, gsi, triggering, polarity); | 1229 | mp_config_acpi_gsi(dev, gsi, trigger, polarity); |
1229 | 1230 | ||
1230 | io_apic_set_pci_routing(dev, ioapic, ioapic_pin, gsi, | 1231 | set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin, |
1231 | triggering == ACPI_EDGE_SENSITIVE ? 0 : 1, | 1232 | trigger == ACPI_EDGE_SENSITIVE ? 0 : 1, |
1232 | polarity == ACPI_ACTIVE_HIGH ? 0 : 1); | 1233 | polarity == ACPI_ACTIVE_HIGH ? 0 : 1); |
1234 | io_apic_set_pci_routing(dev, gsi, &irq_attr); | ||
1233 | 1235 | ||
1234 | return gsi; | 1236 | return gsi; |
1235 | } | 1237 | } |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 74d2b480a20b..ce1ac74baa73 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -1096,8 +1096,7 @@ static int pin_2_irq(int idx, int apic, int pin) | |||
1096 | * Not an __init, possibly needed by modules | 1096 | * Not an __init, possibly needed by modules |
1097 | */ | 1097 | */ |
1098 | int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin, | 1098 | int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin, |
1099 | int *ioapic, int *ioapic_pin, | 1099 | struct io_apic_irq_attr *irq_attr) |
1100 | int *trigger, int *polarity) | ||
1101 | { | 1100 | { |
1102 | int apic, i, best_guess = -1; | 1101 | int apic, i, best_guess = -1; |
1103 | 1102 | ||
@@ -1127,10 +1126,10 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin, | |||
1127 | continue; | 1126 | continue; |
1128 | 1127 | ||
1129 | if (pin == (mp_irqs[i].srcbusirq & 3)) { | 1128 | if (pin == (mp_irqs[i].srcbusirq & 3)) { |
1130 | *ioapic = apic; | 1129 | set_io_apic_irq_attr(irq_attr, apic, |
1131 | *ioapic_pin = mp_irqs[i].dstirq; | 1130 | mp_irqs[i].dstirq, |
1132 | *trigger = irq_trigger(i); | 1131 | irq_trigger(i), |
1133 | *polarity = irq_polarity(i); | 1132 | irq_polarity(i)); |
1134 | return irq; | 1133 | return irq; |
1135 | } | 1134 | } |
1136 | /* | 1135 | /* |
@@ -1138,10 +1137,10 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin, | |||
1138 | * best-guess fuzzy result for broken mptables. | 1137 | * best-guess fuzzy result for broken mptables. |
1139 | */ | 1138 | */ |
1140 | if (best_guess < 0) { | 1139 | if (best_guess < 0) { |
1141 | *ioapic = apic; | 1140 | set_io_apic_irq_attr(irq_attr, apic, |
1142 | *ioapic_pin = mp_irqs[i].dstirq; | 1141 | mp_irqs[i].dstirq, |
1143 | *trigger = irq_trigger(i); | 1142 | irq_trigger(i), |
1144 | *polarity = irq_polarity(i); | 1143 | irq_polarity(i)); |
1145 | best_guess = irq; | 1144 | best_guess = irq; |
1146 | } | 1145 | } |
1147 | } | 1146 | } |
@@ -3865,13 +3864,16 @@ int __init arch_probe_nr_irqs(void) | |||
3865 | } | 3864 | } |
3866 | #endif | 3865 | #endif |
3867 | 3866 | ||
3868 | static int __io_apic_set_pci_routing(struct device *dev, int ioapic, int pin, int irq, | 3867 | static int __io_apic_set_pci_routing(struct device *dev, int irq, |
3869 | int triggering, int polarity) | 3868 | struct io_apic_irq_attr *irq_attr) |
3870 | { | 3869 | { |
3871 | struct irq_desc *desc; | 3870 | struct irq_desc *desc; |
3872 | struct irq_cfg *cfg; | 3871 | struct irq_cfg *cfg; |
3873 | int node; | 3872 | int node; |
3873 | int ioapic, pin; | ||
3874 | int trigger, polarity; | ||
3874 | 3875 | ||
3876 | ioapic = irq_attr->ioapic; | ||
3875 | if (!IO_APIC_IRQ(irq)) { | 3877 | if (!IO_APIC_IRQ(irq)) { |
3876 | apic_printk(APIC_QUIET,KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n", | 3878 | apic_printk(APIC_QUIET,KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n", |
3877 | ioapic); | 3879 | ioapic); |
@@ -3889,6 +3891,10 @@ static int __io_apic_set_pci_routing(struct device *dev, int ioapic, int pin, in | |||
3889 | return 0; | 3891 | return 0; |
3890 | } | 3892 | } |
3891 | 3893 | ||
3894 | pin = irq_attr->ioapic_pin; | ||
3895 | trigger = irq_attr->trigger; | ||
3896 | polarity = irq_attr->polarity; | ||
3897 | |||
3892 | /* | 3898 | /* |
3893 | * IRQs < 16 are already in the irq_2_pin[] map | 3899 | * IRQs < 16 are already in the irq_2_pin[] map |
3894 | */ | 3900 | */ |
@@ -3897,20 +3903,22 @@ static int __io_apic_set_pci_routing(struct device *dev, int ioapic, int pin, in | |||
3897 | add_pin_to_irq_node(cfg, node, ioapic, pin); | 3903 | add_pin_to_irq_node(cfg, node, ioapic, pin); |
3898 | } | 3904 | } |
3899 | 3905 | ||
3900 | setup_IO_APIC_irq(ioapic, pin, irq, desc, triggering, polarity); | 3906 | setup_IO_APIC_irq(ioapic, pin, irq, desc, trigger, polarity); |
3901 | 3907 | ||
3902 | return 0; | 3908 | return 0; |
3903 | } | 3909 | } |
3904 | 3910 | ||
3905 | int io_apic_set_pci_routing(struct device *dev, int ioapic, int pin, int irq, | 3911 | int io_apic_set_pci_routing(struct device *dev, int irq, |
3906 | int triggering, int polarity) | 3912 | struct io_apic_irq_attr *irq_attr) |
3907 | { | 3913 | { |
3908 | 3914 | int ioapic, pin; | |
3909 | /* | 3915 | /* |
3910 | * Avoid pin reprogramming. PRTs typically include entries | 3916 | * Avoid pin reprogramming. PRTs typically include entries |
3911 | * with redundant pin->gsi mappings (but unique PCI devices); | 3917 | * with redundant pin->gsi mappings (but unique PCI devices); |
3912 | * we only program the IOAPIC on the first. | 3918 | * we only program the IOAPIC on the first. |
3913 | */ | 3919 | */ |
3920 | ioapic = irq_attr->ioapic; | ||
3921 | pin = irq_attr->ioapic_pin; | ||
3914 | if (test_bit(pin, mp_ioapic_routing[ioapic].pin_programmed)) { | 3922 | if (test_bit(pin, mp_ioapic_routing[ioapic].pin_programmed)) { |
3915 | pr_debug("Pin %d-%d already programmed\n", | 3923 | pr_debug("Pin %d-%d already programmed\n", |
3916 | mp_ioapics[ioapic].apicid, pin); | 3924 | mp_ioapics[ioapic].apicid, pin); |
@@ -3918,8 +3926,7 @@ int io_apic_set_pci_routing(struct device *dev, int ioapic, int pin, int irq, | |||
3918 | } | 3926 | } |
3919 | set_bit(pin, mp_ioapic_routing[ioapic].pin_programmed); | 3927 | set_bit(pin, mp_ioapic_routing[ioapic].pin_programmed); |
3920 | 3928 | ||
3921 | return __io_apic_set_pci_routing(dev, ioapic, pin, irq, | 3929 | return __io_apic_set_pci_routing(dev, irq, irq_attr); |
3922 | triggering, polarity); | ||
3923 | } | 3930 | } |
3924 | 3931 | ||
3925 | /* -------------------------------------------------------------------------- | 3932 | /* -------------------------------------------------------------------------- |
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c index 2f3e192615c0..0696d506c4ad 100644 --- a/arch/x86/pci/irq.c +++ b/arch/x86/pci/irq.c | |||
@@ -1200,14 +1200,11 @@ static int pirq_enable_irq(struct pci_dev *dev) | |||
1200 | #ifdef CONFIG_X86_IO_APIC | 1200 | #ifdef CONFIG_X86_IO_APIC |
1201 | struct pci_dev *temp_dev; | 1201 | struct pci_dev *temp_dev; |
1202 | int irq; | 1202 | int irq; |
1203 | int ioapic = -1, ioapic_pin = -1; | 1203 | struct io_apic_irq_attr irq_attr; |
1204 | int triggering, polarity; | ||
1205 | 1204 | ||
1206 | irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, | 1205 | irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, |
1207 | PCI_SLOT(dev->devfn), | 1206 | PCI_SLOT(dev->devfn), |
1208 | pin - 1, | 1207 | pin - 1, &irq_attr); |
1209 | &ioapic, &ioapic_pin, | ||
1210 | &triggering, &polarity); | ||
1211 | /* | 1208 | /* |
1212 | * Busses behind bridges are typically not listed in the MP-table. | 1209 | * Busses behind bridges are typically not listed in the MP-table. |
1213 | * In this case we have to look up the IRQ based on the parent bus, | 1210 | * In this case we have to look up the IRQ based on the parent bus, |
@@ -1221,9 +1218,7 @@ static int pirq_enable_irq(struct pci_dev *dev) | |||
1221 | pin = pci_swizzle_interrupt_pin(dev, pin); | 1218 | pin = pci_swizzle_interrupt_pin(dev, pin); |
1222 | irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, | 1219 | irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, |
1223 | PCI_SLOT(bridge->devfn), | 1220 | PCI_SLOT(bridge->devfn), |
1224 | pin - 1, | 1221 | pin - 1, &irq_attr); |
1225 | &ioapic, &ioapic_pin, | ||
1226 | &triggering, &polarity); | ||
1227 | if (irq >= 0) | 1222 | if (irq >= 0) |
1228 | dev_warn(&dev->dev, "using bridge %s " | 1223 | dev_warn(&dev->dev, "using bridge %s " |
1229 | "INT %c to get IRQ %d\n", | 1224 | "INT %c to get IRQ %d\n", |
@@ -1233,9 +1228,8 @@ static int pirq_enable_irq(struct pci_dev *dev) | |||
1233 | } | 1228 | } |
1234 | dev = temp_dev; | 1229 | dev = temp_dev; |
1235 | if (irq >= 0) { | 1230 | if (irq >= 0) { |
1236 | io_apic_set_pci_routing(&dev->dev, ioapic, | 1231 | io_apic_set_pci_routing(&dev->dev, irq, |
1237 | ioapic_pin, irq, | 1232 | &irq_attr); |
1238 | triggering, polarity); | ||
1239 | dev->irq = irq; | 1233 | dev->irq = irq; |
1240 | dev_info(&dev->dev, "PCI->APIC IRQ transform: " | 1234 | dev_info(&dev->dev, "PCI->APIC IRQ transform: " |
1241 | "INT %c -> IRQ %d\n", 'A' + pin - 1, irq); | 1235 | "INT %c -> IRQ %d\n", 'A' + pin - 1, irq); |
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index 79901a0db885..42e4260c3b12 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c | |||
@@ -155,15 +155,13 @@ int ibmphp_init_devno(struct slot **cur_slot) | |||
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 | (*cur_slot)->bus == rtable->slots[loop].bus) { | 157 | (*cur_slot)->bus == rtable->slots[loop].bus) { |
158 | int ioapic = -1, ioapic_pin = -1; | 158 | struct io_apic_irq_attr irq_attr; |
159 | int triggering, polarity; | ||
160 | 159 | ||
161 | (*cur_slot)->device = PCI_SLOT(rtable->slots[loop].devfn); | 160 | (*cur_slot)->device = PCI_SLOT(rtable->slots[loop].devfn); |
162 | for (i = 0; i < 4; i++) | 161 | for (i = 0; i < 4; i++) |
163 | (*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, |
164 | (int) (*cur_slot)->device, i, | 163 | (int) (*cur_slot)->device, i, |
165 | &ioapic, &ioapic_pin, | 164 | &irq_attr); |
166 | &triggering, &polarity); | ||
167 | 165 | ||
168 | debug("(*cur_slot)->irq[0] = %x\n", | 166 | debug("(*cur_slot)->irq[0] = %x\n", |
169 | (*cur_slot)->irq[0]); | 167 | (*cur_slot)->irq[0]); |