diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kernel/acpi/boot.c | 15 | ||||
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 98 |
2 files changed, 40 insertions, 73 deletions
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 9add76f15cb0..fd4b6d2e436c 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
@@ -101,17 +101,6 @@ static u32 isa_irq_to_gsi[NR_IRQS_LEGACY] __read_mostly = { | |||
101 | 101 | ||
102 | #define ACPI_INVALID_GSI INT_MIN | 102 | #define ACPI_INVALID_GSI INT_MIN |
103 | 103 | ||
104 | static int map_gsi_to_irq(unsigned int gsi, unsigned int flags) | ||
105 | { | ||
106 | int i; | ||
107 | |||
108 | for (i = 0; i < nr_legacy_irqs(); i++) | ||
109 | if (isa_irq_to_gsi[i] == gsi) | ||
110 | return i; | ||
111 | |||
112 | return mp_map_gsi_to_irq(gsi, flags); | ||
113 | } | ||
114 | |||
115 | /* | 104 | /* |
116 | * This is just a simple wrapper around early_ioremap(), | 105 | * This is just a simple wrapper around early_ioremap(), |
117 | * with sanity checks for phys == 0 and size == 0. | 106 | * with sanity checks for phys == 0 and size == 0. |
@@ -422,7 +411,7 @@ static int mp_register_gsi(struct device *dev, u32 gsi, int trigger, | |||
422 | return -1; | 411 | return -1; |
423 | } | 412 | } |
424 | 413 | ||
425 | irq = map_gsi_to_irq(gsi, IOAPIC_MAP_ALLOC); | 414 | irq = mp_map_gsi_to_irq(gsi, IOAPIC_MAP_ALLOC); |
426 | if (irq < 0) | 415 | if (irq < 0) |
427 | return irq; | 416 | return irq; |
428 | 417 | ||
@@ -603,7 +592,7 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger) | |||
603 | 592 | ||
604 | int acpi_gsi_to_irq(u32 gsi, unsigned int *irqp) | 593 | int acpi_gsi_to_irq(u32 gsi, unsigned int *irqp) |
605 | { | 594 | { |
606 | int irq = map_gsi_to_irq(gsi, IOAPIC_MAP_ALLOC | IOAPIC_MAP_CHECK); | 595 | int irq = mp_map_gsi_to_irq(gsi, IOAPIC_MAP_ALLOC | IOAPIC_MAP_CHECK); |
607 | 596 | ||
608 | if (irq >= 0) { | 597 | if (irq >= 0) { |
609 | *irqp = irq; | 598 | *irqp = irq; |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 6e3d4c771832..8485d904b653 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -204,8 +204,6 @@ static int __init parse_noapic(char *str) | |||
204 | } | 204 | } |
205 | early_param("noapic", parse_noapic); | 205 | early_param("noapic", parse_noapic); |
206 | 206 | ||
207 | static int io_apic_setup_irq_pin(unsigned int irq, int node, | ||
208 | struct io_apic_irq_attr *attr); | ||
209 | static struct irq_cfg *alloc_irq_and_cfg_at(unsigned int at, int node); | 207 | static struct irq_cfg *alloc_irq_and_cfg_at(unsigned int at, int node); |
210 | 208 | ||
211 | /* Will be called in mpparse/acpi/sfi codes for saving IRQ info */ | 209 | /* Will be called in mpparse/acpi/sfi codes for saving IRQ info */ |
@@ -1021,6 +1019,16 @@ static int mp_map_pin_to_irq(u32 gsi, int idx, int ioapic, int pin, | |||
1021 | struct irq_domain *domain = mp_ioapic_irqdomain(ioapic); | 1019 | struct irq_domain *domain = mp_ioapic_irqdomain(ioapic); |
1022 | struct mp_pin_info *info = mp_pin_info(ioapic, pin); | 1020 | struct mp_pin_info *info = mp_pin_info(ioapic, pin); |
1023 | 1021 | ||
1022 | if (!domain) { | ||
1023 | /* | ||
1024 | * Provide an identity mapping of gsi == irq except on truly | ||
1025 | * weird platforms that have non isa irqs in the first 16 gsis. | ||
1026 | */ | ||
1027 | return gsi >= nr_legacy_irqs() ? gsi : gsi_top + gsi; | ||
1028 | } | ||
1029 | |||
1030 | mutex_lock(&ioapic_mutex); | ||
1031 | |||
1024 | /* | 1032 | /* |
1025 | * Don't use irqdomain to manage ISA IRQs because there may be | 1033 | * Don't use irqdomain to manage ISA IRQs because there may be |
1026 | * multiple IOAPIC pins sharing the same ISA IRQ number and | 1034 | * multiple IOAPIC pins sharing the same ISA IRQ number and |
@@ -1033,28 +1041,30 @@ static int mp_map_pin_to_irq(u32 gsi, int idx, int ioapic, int pin, | |||
1033 | * the interrupt routing logic. Thus there may be multiple pins | 1041 | * the interrupt routing logic. Thus there may be multiple pins |
1034 | * sharing the same legacy IRQ number when ACPI is disabled. | 1042 | * sharing the same legacy IRQ number when ACPI is disabled. |
1035 | */ | 1043 | */ |
1036 | if (idx >= 0 && test_bit(mp_irqs[idx].srcbus, mp_bus_not_pci)) | 1044 | if (idx >= 0 && test_bit(mp_irqs[idx].srcbus, mp_bus_not_pci)) { |
1037 | return mp_irqs[idx].srcbusirq; | 1045 | irq = mp_irqs[idx].srcbusirq; |
1038 | 1046 | if (flags & IOAPIC_MAP_ALLOC) { | |
1039 | if (!domain) { | 1047 | if (info->count == 0 && |
1040 | /* | 1048 | mp_irqdomain_map(domain, irq, pin) != 0) |
1041 | * Provide an identity mapping of gsi == irq except on truly | 1049 | irq = -1; |
1042 | * weird platforms that have non isa irqs in the first 16 gsis. | 1050 | |
1043 | */ | 1051 | /* special handling for timer IRQ0 */ |
1044 | return gsi >= nr_legacy_irqs() ? gsi : gsi_top + gsi; | 1052 | if (irq == 0) |
1053 | info->count++; | ||
1054 | } | ||
1055 | } else { | ||
1056 | irq = irq_find_mapping(domain, pin); | ||
1057 | if (irq <= 0 && (flags & IOAPIC_MAP_ALLOC)) | ||
1058 | irq = alloc_irq_from_domain(domain, gsi, pin); | ||
1045 | } | 1059 | } |
1046 | 1060 | ||
1047 | mutex_lock(&ioapic_mutex); | ||
1048 | irq = irq_find_mapping(domain, pin); | ||
1049 | if (irq <= 0 && (flags & IOAPIC_MAP_ALLOC)) | ||
1050 | irq = alloc_irq_from_domain(domain, gsi, pin); | ||
1051 | |||
1052 | if (flags & IOAPIC_MAP_ALLOC) { | 1061 | if (flags & IOAPIC_MAP_ALLOC) { |
1053 | if (irq > 0) | 1062 | if (irq > 0) |
1054 | info->count++; | 1063 | info->count++; |
1055 | else if (info->count == 0) | 1064 | else if (info->count == 0) |
1056 | info->set = 0; | 1065 | info->set = 0; |
1057 | } | 1066 | } |
1067 | |||
1058 | mutex_unlock(&ioapic_mutex); | 1068 | mutex_unlock(&ioapic_mutex); |
1059 | 1069 | ||
1060 | return irq > 0 ? irq : -1; | 1070 | return irq > 0 ? irq : -1; |
@@ -1471,55 +1481,23 @@ static void setup_ioapic_irq(unsigned int irq, struct irq_cfg *cfg, | |||
1471 | ioapic_write_entry(attr->ioapic, attr->ioapic_pin, entry); | 1481 | ioapic_write_entry(attr->ioapic, attr->ioapic_pin, entry); |
1472 | } | 1482 | } |
1473 | 1483 | ||
1474 | static bool __init io_apic_pin_not_connected(int idx, int ioapic_idx, int pin) | ||
1475 | { | ||
1476 | if (idx != -1) | ||
1477 | return false; | ||
1478 | |||
1479 | apic_printk(APIC_VERBOSE, KERN_DEBUG " apic %d pin %d not connected\n", | ||
1480 | mpc_ioapic_id(ioapic_idx), pin); | ||
1481 | return true; | ||
1482 | } | ||
1483 | |||
1484 | static void __init __io_apic_setup_irqs(unsigned int ioapic_idx) | ||
1485 | { | ||
1486 | int idx, node = cpu_to_node(0); | ||
1487 | struct io_apic_irq_attr attr; | ||
1488 | unsigned int pin, irq; | ||
1489 | |||
1490 | for_each_pin(ioapic_idx, pin) { | ||
1491 | idx = find_irq_entry(ioapic_idx, pin, mp_INT); | ||
1492 | if (io_apic_pin_not_connected(idx, ioapic_idx, pin)) | ||
1493 | continue; | ||
1494 | |||
1495 | irq = pin_2_irq(idx, ioapic_idx, pin, | ||
1496 | ioapic_idx ? 0 : IOAPIC_MAP_ALLOC); | ||
1497 | if (irq < 0 || !mp_init_irq_at_boot(ioapic_idx, irq)) | ||
1498 | continue; | ||
1499 | |||
1500 | /* | ||
1501 | * Skip the timer IRQ if there's a quirk handler | ||
1502 | * installed and if it returns 1: | ||
1503 | */ | ||
1504 | if (apic->multi_timer_check && | ||
1505 | apic->multi_timer_check(ioapic_idx, irq)) | ||
1506 | continue; | ||
1507 | |||
1508 | set_io_apic_irq_attr(&attr, ioapic_idx, pin, irq_trigger(idx), | ||
1509 | irq_polarity(idx)); | ||
1510 | |||
1511 | io_apic_setup_irq_pin(irq, node, &attr); | ||
1512 | } | ||
1513 | } | ||
1514 | |||
1515 | static void __init setup_IO_APIC_irqs(void) | 1484 | static void __init setup_IO_APIC_irqs(void) |
1516 | { | 1485 | { |
1517 | unsigned int ioapic_idx; | 1486 | unsigned int ioapic, pin; |
1487 | int idx; | ||
1518 | 1488 | ||
1519 | apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n"); | 1489 | apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n"); |
1520 | 1490 | ||
1521 | for_each_ioapic(ioapic_idx) | 1491 | for_each_ioapic_pin(ioapic, pin) { |
1522 | __io_apic_setup_irqs(ioapic_idx); | 1492 | idx = find_irq_entry(ioapic, pin, mp_INT); |
1493 | if (idx < 0) | ||
1494 | apic_printk(APIC_VERBOSE, | ||
1495 | KERN_DEBUG " apic %d pin %d not connected\n", | ||
1496 | mpc_ioapic_id(ioapic), pin); | ||
1497 | else | ||
1498 | pin_2_irq(idx, ioapic, pin, | ||
1499 | ioapic ? 0 : IOAPIC_MAP_ALLOC); | ||
1500 | } | ||
1523 | } | 1501 | } |
1524 | 1502 | ||
1525 | /* | 1503 | /* |