diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kernel/acpi/boot.c | 57 | ||||
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 8 |
2 files changed, 59 insertions, 6 deletions
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 07a63ce5811a..325fbbab7f89 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
@@ -94,6 +94,53 @@ enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC; | |||
94 | 94 | ||
95 | 95 | ||
96 | /* | 96 | /* |
97 | * ISA irqs by default are the first 16 gsis but can be | ||
98 | * any gsi as specified by an interrupt source override. | ||
99 | */ | ||
100 | static u32 isa_irq_to_gsi[NR_IRQS_LEGACY] __read_mostly = { | ||
101 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 | ||
102 | }; | ||
103 | |||
104 | static unsigned int gsi_to_irq(unsigned int gsi) | ||
105 | { | ||
106 | unsigned int irq = gsi + NR_IRQS_LEGACY; | ||
107 | unsigned int i; | ||
108 | |||
109 | for (i = 0; i < NR_IRQS_LEGACY; i++) { | ||
110 | if (isa_irq_to_gsi[i] == gsi) { | ||
111 | return i; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | /* Provide an identity mapping of gsi == irq | ||
116 | * except on truly weird platforms that have | ||
117 | * non isa irqs in the first 16 gsis. | ||
118 | */ | ||
119 | if (gsi >= NR_IRQS_LEGACY) | ||
120 | irq = gsi; | ||
121 | else | ||
122 | irq = gsi_end + 1 + gsi; | ||
123 | |||
124 | return irq; | ||
125 | } | ||
126 | |||
127 | static u32 irq_to_gsi(int irq) | ||
128 | { | ||
129 | unsigned int gsi; | ||
130 | |||
131 | if (irq < NR_IRQS_LEGACY) | ||
132 | gsi = isa_irq_to_gsi[irq]; | ||
133 | else if (irq <= gsi_end) | ||
134 | gsi = irq; | ||
135 | else if (irq <= (gsi_end + NR_IRQS_LEGACY)) | ||
136 | gsi = irq - gsi_end; | ||
137 | else | ||
138 | gsi = 0xffffffff; | ||
139 | |||
140 | return gsi; | ||
141 | } | ||
142 | |||
143 | /* | ||
97 | * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END, | 144 | * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END, |
98 | * to map the target physical address. The problem is that set_fixmap() | 145 | * to map the target physical address. The problem is that set_fixmap() |
99 | * provides a single page, and it is possible that the page is not | 146 | * provides a single page, and it is possible that the page is not |
@@ -449,7 +496,7 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger) | |||
449 | 496 | ||
450 | int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) | 497 | int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) |
451 | { | 498 | { |
452 | *irq = gsi; | 499 | *irq = gsi_to_irq(gsi); |
453 | 500 | ||
454 | #ifdef CONFIG_X86_IO_APIC | 501 | #ifdef CONFIG_X86_IO_APIC |
455 | if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) | 502 | if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) |
@@ -463,7 +510,7 @@ int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi) | |||
463 | { | 510 | { |
464 | if (isa_irq >= 16) | 511 | if (isa_irq >= 16) |
465 | return -1; | 512 | return -1; |
466 | *gsi = isa_irq; | 513 | *gsi = irq_to_gsi(isa_irq); |
467 | return 0; | 514 | return 0; |
468 | } | 515 | } |
469 | 516 | ||
@@ -491,7 +538,7 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) | |||
491 | plat_gsi = mp_register_gsi(dev, gsi, trigger, polarity); | 538 | plat_gsi = mp_register_gsi(dev, gsi, trigger, polarity); |
492 | } | 539 | } |
493 | #endif | 540 | #endif |
494 | irq = plat_gsi; | 541 | irq = gsi_to_irq(plat_gsi); |
495 | 542 | ||
496 | return irq; | 543 | return irq; |
497 | } | 544 | } |
@@ -933,6 +980,8 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi) | |||
933 | mp_irq.dstirq = pin; /* INTIN# */ | 980 | mp_irq.dstirq = pin; /* INTIN# */ |
934 | 981 | ||
935 | save_mp_irq(&mp_irq); | 982 | save_mp_irq(&mp_irq); |
983 | |||
984 | isa_irq_to_gsi[bus_irq] = gsi; | ||
936 | } | 985 | } |
937 | 986 | ||
938 | void __init mp_config_acpi_legacy_irqs(void) | 987 | void __init mp_config_acpi_legacy_irqs(void) |
@@ -1086,7 +1135,7 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) | |||
1086 | set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin, | 1135 | set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin, |
1087 | trigger == ACPI_EDGE_SENSITIVE ? 0 : 1, | 1136 | trigger == ACPI_EDGE_SENSITIVE ? 0 : 1, |
1088 | polarity == ACPI_ACTIVE_HIGH ? 0 : 1); | 1137 | polarity == ACPI_ACTIVE_HIGH ? 0 : 1); |
1089 | io_apic_set_pci_routing(dev, gsi, &irq_attr); | 1138 | io_apic_set_pci_routing(dev, gsi_to_irq(gsi), &irq_attr); |
1090 | 1139 | ||
1091 | return gsi; | 1140 | return gsi; |
1092 | } | 1141 | } |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 9f3f6ca86dac..594827c3c615 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -1037,7 +1037,11 @@ static int pin_2_irq(int idx, int apic, int pin) | |||
1037 | */ | 1037 | */ |
1038 | if (ioapic_renumber_irq) | 1038 | if (ioapic_renumber_irq) |
1039 | gsi = ioapic_renumber_irq(apic, gsi); | 1039 | gsi = ioapic_renumber_irq(apic, gsi); |
1040 | irq = gsi; | 1040 | |
1041 | if (gsi >= NR_IRQS_LEGACY) | ||
1042 | irq = gsi; | ||
1043 | else | ||
1044 | irq = gsi_end + 1 + gsi; | ||
1041 | } | 1045 | } |
1042 | 1046 | ||
1043 | #ifdef CONFIG_X86_32 | 1047 | #ifdef CONFIG_X86_32 |
@@ -3852,7 +3856,7 @@ void __init probe_nr_irqs_gsi(void) | |||
3852 | { | 3856 | { |
3853 | int nr; | 3857 | int nr; |
3854 | 3858 | ||
3855 | nr = gsi_end + 1; | 3859 | nr = gsi_end + 1 + NR_IRQS_LEGACY; |
3856 | if (nr > nr_irqs_gsi) | 3860 | if (nr > nr_irqs_gsi) |
3857 | nr_irqs_gsi = nr; | 3861 | nr_irqs_gsi = nr; |
3858 | 3862 | ||