diff options
| -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 | ||
