diff options
Diffstat (limited to 'arch/x86/kernel/apic/io_apic.c')
| -rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 388 |
1 files changed, 169 insertions, 219 deletions
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index ca9e2a3545a..4b5ebd26f56 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
| @@ -108,7 +108,10 @@ DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES); | |||
| 108 | 108 | ||
| 109 | int skip_ioapic_setup; | 109 | int skip_ioapic_setup; |
| 110 | 110 | ||
| 111 | void arch_disable_smp_support(void) | 111 | /** |
| 112 | * disable_ioapic_support() - disables ioapic support at runtime | ||
| 113 | */ | ||
| 114 | void disable_ioapic_support(void) | ||
| 112 | { | 115 | { |
| 113 | #ifdef CONFIG_PCI | 116 | #ifdef CONFIG_PCI |
| 114 | noioapicquirk = 1; | 117 | noioapicquirk = 1; |
| @@ -120,11 +123,14 @@ void arch_disable_smp_support(void) | |||
| 120 | static int __init parse_noapic(char *str) | 123 | static int __init parse_noapic(char *str) |
| 121 | { | 124 | { |
| 122 | /* disable IO-APIC */ | 125 | /* disable IO-APIC */ |
| 123 | arch_disable_smp_support(); | 126 | disable_ioapic_support(); |
| 124 | return 0; | 127 | return 0; |
| 125 | } | 128 | } |
| 126 | early_param("noapic", parse_noapic); | 129 | early_param("noapic", parse_noapic); |
| 127 | 130 | ||
| 131 | static int io_apic_setup_irq_pin_once(unsigned int irq, int node, | ||
| 132 | struct io_apic_irq_attr *attr); | ||
| 133 | |||
| 128 | /* Will be called in mpparse/acpi/sfi codes for saving IRQ info */ | 134 | /* Will be called in mpparse/acpi/sfi codes for saving IRQ info */ |
| 129 | void mp_save_irq(struct mpc_intsrc *m) | 135 | void mp_save_irq(struct mpc_intsrc *m) |
| 130 | { | 136 | { |
| @@ -181,7 +187,7 @@ int __init arch_early_irq_init(void) | |||
| 181 | irq_reserve_irqs(0, legacy_pic->nr_legacy_irqs); | 187 | irq_reserve_irqs(0, legacy_pic->nr_legacy_irqs); |
| 182 | 188 | ||
| 183 | for (i = 0; i < count; i++) { | 189 | for (i = 0; i < count; i++) { |
| 184 | set_irq_chip_data(i, &cfg[i]); | 190 | irq_set_chip_data(i, &cfg[i]); |
| 185 | zalloc_cpumask_var_node(&cfg[i].domain, GFP_KERNEL, node); | 191 | zalloc_cpumask_var_node(&cfg[i].domain, GFP_KERNEL, node); |
| 186 | zalloc_cpumask_var_node(&cfg[i].old_domain, GFP_KERNEL, node); | 192 | zalloc_cpumask_var_node(&cfg[i].old_domain, GFP_KERNEL, node); |
| 187 | /* | 193 | /* |
| @@ -200,7 +206,7 @@ int __init arch_early_irq_init(void) | |||
| 200 | #ifdef CONFIG_SPARSE_IRQ | 206 | #ifdef CONFIG_SPARSE_IRQ |
| 201 | static struct irq_cfg *irq_cfg(unsigned int irq) | 207 | static struct irq_cfg *irq_cfg(unsigned int irq) |
| 202 | { | 208 | { |
| 203 | return get_irq_chip_data(irq); | 209 | return irq_get_chip_data(irq); |
| 204 | } | 210 | } |
| 205 | 211 | ||
| 206 | static struct irq_cfg *alloc_irq_cfg(unsigned int irq, int node) | 212 | static struct irq_cfg *alloc_irq_cfg(unsigned int irq, int node) |
| @@ -226,7 +232,7 @@ static void free_irq_cfg(unsigned int at, struct irq_cfg *cfg) | |||
| 226 | { | 232 | { |
| 227 | if (!cfg) | 233 | if (!cfg) |
| 228 | return; | 234 | return; |
| 229 | set_irq_chip_data(at, NULL); | 235 | irq_set_chip_data(at, NULL); |
| 230 | free_cpumask_var(cfg->domain); | 236 | free_cpumask_var(cfg->domain); |
| 231 | free_cpumask_var(cfg->old_domain); | 237 | free_cpumask_var(cfg->old_domain); |
| 232 | kfree(cfg); | 238 | kfree(cfg); |
| @@ -256,14 +262,14 @@ static struct irq_cfg *alloc_irq_and_cfg_at(unsigned int at, int node) | |||
| 256 | if (res < 0) { | 262 | if (res < 0) { |
| 257 | if (res != -EEXIST) | 263 | if (res != -EEXIST) |
| 258 | return NULL; | 264 | return NULL; |
| 259 | cfg = get_irq_chip_data(at); | 265 | cfg = irq_get_chip_data(at); |
| 260 | if (cfg) | 266 | if (cfg) |
| 261 | return cfg; | 267 | return cfg; |
| 262 | } | 268 | } |
| 263 | 269 | ||
| 264 | cfg = alloc_irq_cfg(at, node); | 270 | cfg = alloc_irq_cfg(at, node); |
| 265 | if (cfg) | 271 | if (cfg) |
| 266 | set_irq_chip_data(at, cfg); | 272 | irq_set_chip_data(at, cfg); |
| 267 | else | 273 | else |
| 268 | irq_free_desc(at); | 274 | irq_free_desc(at); |
| 269 | return cfg; | 275 | return cfg; |
| @@ -818,7 +824,7 @@ static int EISA_ELCR(unsigned int irq) | |||
| 818 | #define default_MCA_trigger(idx) (1) | 824 | #define default_MCA_trigger(idx) (1) |
| 819 | #define default_MCA_polarity(idx) default_ISA_polarity(idx) | 825 | #define default_MCA_polarity(idx) default_ISA_polarity(idx) |
| 820 | 826 | ||
| 821 | static int MPBIOS_polarity(int idx) | 827 | static int irq_polarity(int idx) |
| 822 | { | 828 | { |
| 823 | int bus = mp_irqs[idx].srcbus; | 829 | int bus = mp_irqs[idx].srcbus; |
| 824 | int polarity; | 830 | int polarity; |
| @@ -860,7 +866,7 @@ static int MPBIOS_polarity(int idx) | |||
| 860 | return polarity; | 866 | return polarity; |
| 861 | } | 867 | } |
| 862 | 868 | ||
| 863 | static int MPBIOS_trigger(int idx) | 869 | static int irq_trigger(int idx) |
| 864 | { | 870 | { |
| 865 | int bus = mp_irqs[idx].srcbus; | 871 | int bus = mp_irqs[idx].srcbus; |
| 866 | int trigger; | 872 | int trigger; |
| @@ -932,16 +938,6 @@ static int MPBIOS_trigger(int idx) | |||
| 932 | return trigger; | 938 | return trigger; |
| 933 | } | 939 | } |
| 934 | 940 | ||
| 935 | static inline int irq_polarity(int idx) | ||
| 936 | { | ||
| 937 | return MPBIOS_polarity(idx); | ||
| 938 | } | ||
| 939 | |||
| 940 | static inline int irq_trigger(int idx) | ||
| 941 | { | ||
| 942 | return MPBIOS_trigger(idx); | ||
| 943 | } | ||
| 944 | |||
| 945 | static int pin_2_irq(int idx, int apic, int pin) | 941 | static int pin_2_irq(int idx, int apic, int pin) |
| 946 | { | 942 | { |
| 947 | int irq; | 943 | int irq; |
| @@ -1189,7 +1185,7 @@ void __setup_vector_irq(int cpu) | |||
| 1189 | raw_spin_lock(&vector_lock); | 1185 | raw_spin_lock(&vector_lock); |
| 1190 | /* Mark the inuse vectors */ | 1186 | /* Mark the inuse vectors */ |
| 1191 | for_each_active_irq(irq) { | 1187 | for_each_active_irq(irq) { |
| 1192 | cfg = get_irq_chip_data(irq); | 1188 | cfg = irq_get_chip_data(irq); |
| 1193 | if (!cfg) | 1189 | if (!cfg) |
| 1194 | continue; | 1190 | continue; |
| 1195 | /* | 1191 | /* |
| @@ -1220,10 +1216,6 @@ void __setup_vector_irq(int cpu) | |||
| 1220 | static struct irq_chip ioapic_chip; | 1216 | static struct irq_chip ioapic_chip; |
| 1221 | static struct irq_chip ir_ioapic_chip; | 1217 | static struct irq_chip ir_ioapic_chip; |
| 1222 | 1218 | ||
| 1223 | #define IOAPIC_AUTO -1 | ||
| 1224 | #define IOAPIC_EDGE 0 | ||
| 1225 | #define IOAPIC_LEVEL 1 | ||
| 1226 | |||
| 1227 | #ifdef CONFIG_X86_32 | 1219 | #ifdef CONFIG_X86_32 |
| 1228 | static inline int IO_APIC_irq_trigger(int irq) | 1220 | static inline int IO_APIC_irq_trigger(int irq) |
| 1229 | { | 1221 | { |
| @@ -1248,35 +1240,31 @@ static inline int IO_APIC_irq_trigger(int irq) | |||
| 1248 | } | 1240 | } |
| 1249 | #endif | 1241 | #endif |
| 1250 | 1242 | ||
| 1251 | static void ioapic_register_intr(unsigned int irq, unsigned long trigger) | 1243 | static void ioapic_register_intr(unsigned int irq, struct irq_cfg *cfg, |
| 1244 | unsigned long trigger) | ||
| 1252 | { | 1245 | { |
| 1246 | struct irq_chip *chip = &ioapic_chip; | ||
| 1247 | irq_flow_handler_t hdl; | ||
| 1248 | bool fasteoi; | ||
| 1253 | 1249 | ||
| 1254 | if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || | 1250 | if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || |
| 1255 | trigger == IOAPIC_LEVEL) | 1251 | trigger == IOAPIC_LEVEL) { |
| 1256 | irq_set_status_flags(irq, IRQ_LEVEL); | 1252 | irq_set_status_flags(irq, IRQ_LEVEL); |
| 1257 | else | 1253 | fasteoi = true; |
| 1254 | } else { | ||
| 1258 | irq_clear_status_flags(irq, IRQ_LEVEL); | 1255 | irq_clear_status_flags(irq, IRQ_LEVEL); |
| 1256 | fasteoi = false; | ||
| 1257 | } | ||
| 1259 | 1258 | ||
| 1260 | if (irq_remapped(get_irq_chip_data(irq))) { | 1259 | if (irq_remapped(cfg)) { |
| 1261 | irq_set_status_flags(irq, IRQ_MOVE_PCNTXT); | 1260 | irq_set_status_flags(irq, IRQ_MOVE_PCNTXT); |
| 1262 | if (trigger) | 1261 | chip = &ir_ioapic_chip; |
| 1263 | set_irq_chip_and_handler_name(irq, &ir_ioapic_chip, | 1262 | fasteoi = trigger != 0; |
| 1264 | handle_fasteoi_irq, | ||
| 1265 | "fasteoi"); | ||
| 1266 | else | ||
| 1267 | set_irq_chip_and_handler_name(irq, &ir_ioapic_chip, | ||
| 1268 | handle_edge_irq, "edge"); | ||
| 1269 | return; | ||
| 1270 | } | 1263 | } |
| 1271 | 1264 | ||
| 1272 | if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || | 1265 | hdl = fasteoi ? handle_fasteoi_irq : handle_edge_irq; |
| 1273 | trigger == IOAPIC_LEVEL) | 1266 | irq_set_chip_and_handler_name(irq, chip, hdl, |
| 1274 | set_irq_chip_and_handler_name(irq, &ioapic_chip, | 1267 | fasteoi ? "fasteoi" : "edge"); |
| 1275 | handle_fasteoi_irq, | ||
| 1276 | "fasteoi"); | ||
| 1277 | else | ||
| 1278 | set_irq_chip_and_handler_name(irq, &ioapic_chip, | ||
| 1279 | handle_edge_irq, "edge"); | ||
| 1280 | } | 1268 | } |
| 1281 | 1269 | ||
| 1282 | static int setup_ioapic_entry(int apic_id, int irq, | 1270 | static int setup_ioapic_entry(int apic_id, int irq, |
| @@ -1374,7 +1362,7 @@ static void setup_ioapic_irq(int apic_id, int pin, unsigned int irq, | |||
| 1374 | return; | 1362 | return; |
| 1375 | } | 1363 | } |
| 1376 | 1364 | ||
| 1377 | ioapic_register_intr(irq, trigger); | 1365 | ioapic_register_intr(irq, cfg, trigger); |
| 1378 | if (irq < legacy_pic->nr_legacy_irqs) | 1366 | if (irq < legacy_pic->nr_legacy_irqs) |
| 1379 | legacy_pic->mask(irq); | 1367 | legacy_pic->mask(irq); |
| 1380 | 1368 | ||
| @@ -1385,33 +1373,26 @@ static struct { | |||
| 1385 | DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1); | 1373 | DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1); |
| 1386 | } mp_ioapic_routing[MAX_IO_APICS]; | 1374 | } mp_ioapic_routing[MAX_IO_APICS]; |
| 1387 | 1375 | ||
| 1388 | static void __init setup_IO_APIC_irqs(void) | 1376 | static bool __init io_apic_pin_not_connected(int idx, int apic_id, int pin) |
| 1389 | { | 1377 | { |
| 1390 | int apic_id, pin, idx, irq, notcon = 0; | 1378 | if (idx != -1) |
| 1391 | int node = cpu_to_node(0); | 1379 | return false; |
| 1392 | struct irq_cfg *cfg; | ||
| 1393 | 1380 | ||
| 1394 | apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n"); | 1381 | apic_printk(APIC_VERBOSE, KERN_DEBUG " apic %d pin %d not connected\n", |
| 1382 | mp_ioapics[apic_id].apicid, pin); | ||
| 1383 | return true; | ||
| 1384 | } | ||
| 1385 | |||
| 1386 | static void __init __io_apic_setup_irqs(unsigned int apic_id) | ||
| 1387 | { | ||
| 1388 | int idx, node = cpu_to_node(0); | ||
| 1389 | struct io_apic_irq_attr attr; | ||
| 1390 | unsigned int pin, irq; | ||
| 1395 | 1391 | ||
| 1396 | for (apic_id = 0; apic_id < nr_ioapics; apic_id++) | ||
| 1397 | for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) { | 1392 | for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) { |
| 1398 | idx = find_irq_entry(apic_id, pin, mp_INT); | 1393 | idx = find_irq_entry(apic_id, pin, mp_INT); |
| 1399 | if (idx == -1) { | 1394 | if (io_apic_pin_not_connected(idx, apic_id, pin)) |
| 1400 | if (!notcon) { | ||
| 1401 | notcon = 1; | ||
| 1402 | apic_printk(APIC_VERBOSE, | ||
| 1403 | KERN_DEBUG " %d-%d", | ||
| 1404 | mp_ioapics[apic_id].apicid, pin); | ||
| 1405 | } else | ||
| 1406 | apic_printk(APIC_VERBOSE, " %d-%d", | ||
| 1407 | mp_ioapics[apic_id].apicid, pin); | ||
| 1408 | continue; | 1395 | continue; |
| 1409 | } | ||
| 1410 | if (notcon) { | ||
| 1411 | apic_printk(APIC_VERBOSE, | ||
| 1412 | " (apicid-pin) not connected\n"); | ||
| 1413 | notcon = 0; | ||
| 1414 | } | ||
| 1415 | 1396 | ||
| 1416 | irq = pin_2_irq(idx, apic_id, pin); | 1397 | irq = pin_2_irq(idx, apic_id, pin); |
| 1417 | 1398 | ||
| @@ -1423,25 +1404,24 @@ static void __init setup_IO_APIC_irqs(void) | |||
| 1423 | * installed and if it returns 1: | 1404 | * installed and if it returns 1: |
| 1424 | */ | 1405 | */ |
| 1425 | if (apic->multi_timer_check && | 1406 | if (apic->multi_timer_check && |
| 1426 | apic->multi_timer_check(apic_id, irq)) | 1407 | apic->multi_timer_check(apic_id, irq)) |
| 1427 | continue; | 1408 | continue; |
| 1428 | 1409 | ||
| 1429 | cfg = alloc_irq_and_cfg_at(irq, node); | 1410 | set_io_apic_irq_attr(&attr, apic_id, pin, irq_trigger(idx), |
| 1430 | if (!cfg) | 1411 | irq_polarity(idx)); |
| 1431 | continue; | ||
| 1432 | 1412 | ||
| 1433 | add_pin_to_irq_node(cfg, node, apic_id, pin); | 1413 | io_apic_setup_irq_pin(irq, node, &attr); |
| 1434 | /* | ||
| 1435 | * don't mark it in pin_programmed, so later acpi could | ||
| 1436 | * set it correctly when irq < 16 | ||
| 1437 | */ | ||
| 1438 | setup_ioapic_irq(apic_id, pin, irq, cfg, irq_trigger(idx), | ||
| 1439 | irq_polarity(idx)); | ||
| 1440 | } | 1414 | } |
| 1415 | } | ||
| 1441 | 1416 | ||
| 1442 | if (notcon) | 1417 | static void __init setup_IO_APIC_irqs(void) |
| 1443 | apic_printk(APIC_VERBOSE, | 1418 | { |
| 1444 | " (apicid-pin) not connected\n"); | 1419 | unsigned int apic_id; |
| 1420 | |||
| 1421 | apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n"); | ||
| 1422 | |||
| 1423 | for (apic_id = 0; apic_id < nr_ioapics; apic_id++) | ||
| 1424 | __io_apic_setup_irqs(apic_id); | ||
| 1445 | } | 1425 | } |
| 1446 | 1426 | ||
| 1447 | /* | 1427 | /* |
| @@ -1452,7 +1432,7 @@ static void __init setup_IO_APIC_irqs(void) | |||
| 1452 | void setup_IO_APIC_irq_extra(u32 gsi) | 1432 | void setup_IO_APIC_irq_extra(u32 gsi) |
| 1453 | { | 1433 | { |
| 1454 | int apic_id = 0, pin, idx, irq, node = cpu_to_node(0); | 1434 | int apic_id = 0, pin, idx, irq, node = cpu_to_node(0); |
| 1455 | struct irq_cfg *cfg; | 1435 | struct io_apic_irq_attr attr; |
| 1456 | 1436 | ||
| 1457 | /* | 1437 | /* |
| 1458 | * Convert 'gsi' to 'ioapic.pin'. | 1438 | * Convert 'gsi' to 'ioapic.pin'. |
| @@ -1472,21 +1452,10 @@ void setup_IO_APIC_irq_extra(u32 gsi) | |||
| 1472 | if (apic_id == 0 || irq < NR_IRQS_LEGACY) | 1452 | if (apic_id == 0 || irq < NR_IRQS_LEGACY) |
| 1473 | return; | 1453 | return; |
| 1474 | 1454 | ||
| 1475 | cfg = alloc_irq_and_cfg_at(irq, node); | 1455 | set_io_apic_irq_attr(&attr, apic_id, pin, irq_trigger(idx), |
| 1476 | if (!cfg) | 1456 | irq_polarity(idx)); |
| 1477 | return; | ||
| 1478 | |||
| 1479 | add_pin_to_irq_node(cfg, node, apic_id, pin); | ||
| 1480 | |||
| 1481 | if (test_bit(pin, mp_ioapic_routing[apic_id].pin_programmed)) { | ||
| 1482 | pr_debug("Pin %d-%d already programmed\n", | ||
| 1483 | mp_ioapics[apic_id].apicid, pin); | ||
| 1484 | return; | ||
| 1485 | } | ||
| 1486 | set_bit(pin, mp_ioapic_routing[apic_id].pin_programmed); | ||
| 1487 | 1457 | ||
| 1488 | setup_ioapic_irq(apic_id, pin, irq, cfg, | 1458 | io_apic_setup_irq_pin_once(irq, node, &attr); |
| 1489 | irq_trigger(idx), irq_polarity(idx)); | ||
| 1490 | } | 1459 | } |
| 1491 | 1460 | ||
| 1492 | /* | 1461 | /* |
| @@ -1518,7 +1487,8 @@ static void __init setup_timer_IRQ0_pin(unsigned int apic_id, unsigned int pin, | |||
| 1518 | * The timer IRQ doesn't have to know that behind the | 1487 | * The timer IRQ doesn't have to know that behind the |
| 1519 | * scene we may have a 8259A-master in AEOI mode ... | 1488 | * scene we may have a 8259A-master in AEOI mode ... |
| 1520 | */ | 1489 | */ |
| 1521 | set_irq_chip_and_handler_name(0, &ioapic_chip, handle_edge_irq, "edge"); | 1490 | irq_set_chip_and_handler_name(0, &ioapic_chip, handle_edge_irq, |
| 1491 | "edge"); | ||
| 1522 | 1492 | ||
| 1523 | /* | 1493 | /* |
| 1524 | * Add it to the IO-APIC irq-routing table: | 1494 | * Add it to the IO-APIC irq-routing table: |
| @@ -1625,7 +1595,7 @@ __apicdebuginit(void) print_IO_APIC(void) | |||
| 1625 | for_each_active_irq(irq) { | 1595 | for_each_active_irq(irq) { |
| 1626 | struct irq_pin_list *entry; | 1596 | struct irq_pin_list *entry; |
| 1627 | 1597 | ||
| 1628 | cfg = get_irq_chip_data(irq); | 1598 | cfg = irq_get_chip_data(irq); |
| 1629 | if (!cfg) | 1599 | if (!cfg) |
| 1630 | continue; | 1600 | continue; |
| 1631 | entry = cfg->irq_2_pin; | 1601 | entry = cfg->irq_2_pin; |
| @@ -2391,7 +2361,7 @@ static void irq_complete_move(struct irq_cfg *cfg) | |||
| 2391 | 2361 | ||
| 2392 | void irq_force_complete_move(int irq) | 2362 | void irq_force_complete_move(int irq) |
| 2393 | { | 2363 | { |
| 2394 | struct irq_cfg *cfg = get_irq_chip_data(irq); | 2364 | struct irq_cfg *cfg = irq_get_chip_data(irq); |
| 2395 | 2365 | ||
| 2396 | if (!cfg) | 2366 | if (!cfg) |
| 2397 | return; | 2367 | return; |
| @@ -2405,7 +2375,7 @@ static inline void irq_complete_move(struct irq_cfg *cfg) { } | |||
| 2405 | static void ack_apic_edge(struct irq_data *data) | 2375 | static void ack_apic_edge(struct irq_data *data) |
| 2406 | { | 2376 | { |
| 2407 | irq_complete_move(data->chip_data); | 2377 | irq_complete_move(data->chip_data); |
| 2408 | move_native_irq(data->irq); | 2378 | irq_move_irq(data); |
| 2409 | ack_APIC_irq(); | 2379 | ack_APIC_irq(); |
| 2410 | } | 2380 | } |
| 2411 | 2381 | ||
| @@ -2462,7 +2432,7 @@ static void ack_apic_level(struct irq_data *data) | |||
| 2462 | irq_complete_move(cfg); | 2432 | irq_complete_move(cfg); |
| 2463 | #ifdef CONFIG_GENERIC_PENDING_IRQ | 2433 | #ifdef CONFIG_GENERIC_PENDING_IRQ |
| 2464 | /* If we are moving the irq we need to mask it */ | 2434 | /* If we are moving the irq we need to mask it */ |
| 2465 | if (unlikely(irq_to_desc(irq)->status & IRQ_MOVE_PENDING)) { | 2435 | if (unlikely(irqd_is_setaffinity_pending(data))) { |
| 2466 | do_unmask_irq = 1; | 2436 | do_unmask_irq = 1; |
| 2467 | mask_ioapic(cfg); | 2437 | mask_ioapic(cfg); |
| 2468 | } | 2438 | } |
| @@ -2551,7 +2521,7 @@ static void ack_apic_level(struct irq_data *data) | |||
| 2551 | * and you can go talk to the chipset vendor about it. | 2521 | * and you can go talk to the chipset vendor about it. |
| 2552 | */ | 2522 | */ |
| 2553 | if (!io_apic_level_ack_pending(cfg)) | 2523 | if (!io_apic_level_ack_pending(cfg)) |
| 2554 | move_masked_irq(irq); | 2524 | irq_move_masked_irq(data); |
| 2555 | unmask_ioapic(cfg); | 2525 | unmask_ioapic(cfg); |
| 2556 | } | 2526 | } |
| 2557 | } | 2527 | } |
| @@ -2614,7 +2584,7 @@ static inline void init_IO_APIC_traps(void) | |||
| 2614 | * 0x80, because int 0x80 is hm, kind of importantish. ;) | 2584 | * 0x80, because int 0x80 is hm, kind of importantish. ;) |
| 2615 | */ | 2585 | */ |
| 2616 | for_each_active_irq(irq) { | 2586 | for_each_active_irq(irq) { |
| 2617 | cfg = get_irq_chip_data(irq); | 2587 | cfg = irq_get_chip_data(irq); |
| 2618 | if (IO_APIC_IRQ(irq) && cfg && !cfg->vector) { | 2588 | if (IO_APIC_IRQ(irq) && cfg && !cfg->vector) { |
| 2619 | /* | 2589 | /* |
| 2620 | * Hmm.. We don't have an entry for this, | 2590 | * Hmm.. We don't have an entry for this, |
| @@ -2625,7 +2595,7 @@ static inline void init_IO_APIC_traps(void) | |||
| 2625 | legacy_pic->make_irq(irq); | 2595 | legacy_pic->make_irq(irq); |
| 2626 | else | 2596 | else |
| 2627 | /* Strange. Oh, well.. */ | 2597 | /* Strange. Oh, well.. */ |
| 2628 | set_irq_chip(irq, &no_irq_chip); | 2598 | irq_set_chip(irq, &no_irq_chip); |
| 2629 | } | 2599 | } |
| 2630 | } | 2600 | } |
| 2631 | } | 2601 | } |
| @@ -2665,7 +2635,7 @@ static struct irq_chip lapic_chip __read_mostly = { | |||
| 2665 | static void lapic_register_intr(int irq) | 2635 | static void lapic_register_intr(int irq) |
| 2666 | { | 2636 | { |
| 2667 | irq_clear_status_flags(irq, IRQ_LEVEL); | 2637 | irq_clear_status_flags(irq, IRQ_LEVEL); |
| 2668 | set_irq_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq, | 2638 | irq_set_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq, |
| 2669 | "edge"); | 2639 | "edge"); |
| 2670 | } | 2640 | } |
| 2671 | 2641 | ||
| @@ -2749,7 +2719,7 @@ int timer_through_8259 __initdata; | |||
| 2749 | */ | 2719 | */ |
| 2750 | static inline void __init check_timer(void) | 2720 | static inline void __init check_timer(void) |
| 2751 | { | 2721 | { |
| 2752 | struct irq_cfg *cfg = get_irq_chip_data(0); | 2722 | struct irq_cfg *cfg = irq_get_chip_data(0); |
| 2753 | int node = cpu_to_node(0); | 2723 | int node = cpu_to_node(0); |
| 2754 | int apic1, pin1, apic2, pin2; | 2724 | int apic1, pin1, apic2, pin2; |
| 2755 | unsigned long flags; | 2725 | unsigned long flags; |
| @@ -3060,7 +3030,7 @@ unsigned int create_irq_nr(unsigned int from, int node) | |||
| 3060 | raw_spin_unlock_irqrestore(&vector_lock, flags); | 3030 | raw_spin_unlock_irqrestore(&vector_lock, flags); |
| 3061 | 3031 | ||
| 3062 | if (ret) { | 3032 | if (ret) { |
| 3063 | set_irq_chip_data(irq, cfg); | 3033 | irq_set_chip_data(irq, cfg); |
| 3064 | irq_clear_status_flags(irq, IRQ_NOREQUEST); | 3034 | irq_clear_status_flags(irq, IRQ_NOREQUEST); |
| 3065 | } else { | 3035 | } else { |
| 3066 | free_irq_at(irq, cfg); | 3036 | free_irq_at(irq, cfg); |
| @@ -3085,7 +3055,7 @@ int create_irq(void) | |||
| 3085 | 3055 | ||
| 3086 | void destroy_irq(unsigned int irq) | 3056 | void destroy_irq(unsigned int irq) |
| 3087 | { | 3057 | { |
| 3088 | struct irq_cfg *cfg = get_irq_chip_data(irq); | 3058 | struct irq_cfg *cfg = irq_get_chip_data(irq); |
| 3089 | unsigned long flags; | 3059 | unsigned long flags; |
| 3090 | 3060 | ||
| 3091 | irq_set_status_flags(irq, IRQ_NOREQUEST|IRQ_NOPROBE); | 3061 | irq_set_status_flags(irq, IRQ_NOREQUEST|IRQ_NOPROBE); |
| @@ -3119,7 +3089,7 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, | |||
| 3119 | 3089 | ||
| 3120 | dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus()); | 3090 | dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus()); |
| 3121 | 3091 | ||
| 3122 | if (irq_remapped(get_irq_chip_data(irq))) { | 3092 | if (irq_remapped(cfg)) { |
| 3123 | struct irte irte; | 3093 | struct irte irte; |
| 3124 | int ir_index; | 3094 | int ir_index; |
| 3125 | u16 sub_handle; | 3095 | u16 sub_handle; |
| @@ -3291,6 +3261,7 @@ static int msi_alloc_irte(struct pci_dev *dev, int irq, int nvec) | |||
| 3291 | 3261 | ||
| 3292 | static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq) | 3262 | static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq) |
| 3293 | { | 3263 | { |
| 3264 | struct irq_chip *chip = &msi_chip; | ||
| 3294 | struct msi_msg msg; | 3265 | struct msi_msg msg; |
| 3295 | int ret; | 3266 | int ret; |
| 3296 | 3267 | ||
| @@ -3298,14 +3269,15 @@ static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq) | |||
| 3298 | if (ret < 0) | 3269 | if (ret < 0) |
| 3299 | return ret; | 3270 | return ret; |
| 3300 | 3271 | ||
| 3301 | set_irq_msi(irq, msidesc); | 3272 | irq_set_msi_desc(irq, msidesc); |
| 3302 | write_msi_msg(irq, &msg); | 3273 | write_msi_msg(irq, &msg); |
| 3303 | 3274 | ||
| 3304 | if (irq_remapped(get_irq_chip_data(irq))) { | 3275 | if (irq_remapped(irq_get_chip_data(irq))) { |
| 3305 | irq_set_status_flags(irq, IRQ_MOVE_PCNTXT); | 3276 | irq_set_status_flags(irq, IRQ_MOVE_PCNTXT); |
| 3306 | set_irq_chip_and_handler_name(irq, &msi_ir_chip, handle_edge_irq, "edge"); | 3277 | chip = &msi_ir_chip; |
| 3307 | } else | 3278 | } |
| 3308 | set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge"); | 3279 | |
| 3280 | irq_set_chip_and_handler_name(irq, chip, handle_edge_irq, "edge"); | ||
| 3309 | 3281 | ||
| 3310 | dev_printk(KERN_DEBUG, &dev->dev, "irq %d for MSI/MSI-X\n", irq); | 3282 | dev_printk(KERN_DEBUG, &dev->dev, "irq %d for MSI/MSI-X\n", irq); |
| 3311 | 3283 | ||
| @@ -3423,8 +3395,8 @@ int arch_setup_dmar_msi(unsigned int irq) | |||
| 3423 | if (ret < 0) | 3395 | if (ret < 0) |
| 3424 | return ret; | 3396 | return ret; |
| 3425 | dmar_msi_write(irq, &msg); | 3397 | dmar_msi_write(irq, &msg); |
| 3426 | set_irq_chip_and_handler_name(irq, &dmar_msi_type, handle_edge_irq, | 3398 | irq_set_chip_and_handler_name(irq, &dmar_msi_type, handle_edge_irq, |
| 3427 | "edge"); | 3399 | "edge"); |
| 3428 | return 0; | 3400 | return 0; |
| 3429 | } | 3401 | } |
| 3430 | #endif | 3402 | #endif |
| @@ -3482,6 +3454,7 @@ static struct irq_chip hpet_msi_type = { | |||
| 3482 | 3454 | ||
| 3483 | int arch_setup_hpet_msi(unsigned int irq, unsigned int id) | 3455 | int arch_setup_hpet_msi(unsigned int irq, unsigned int id) |
| 3484 | { | 3456 | { |
| 3457 | struct irq_chip *chip = &hpet_msi_type; | ||
| 3485 | struct msi_msg msg; | 3458 | struct msi_msg msg; |
| 3486 | int ret; | 3459 | int ret; |
| 3487 | 3460 | ||
| @@ -3501,15 +3474,12 @@ int arch_setup_hpet_msi(unsigned int irq, unsigned int id) | |||
| 3501 | if (ret < 0) | 3474 | if (ret < 0) |
| 3502 | return ret; | 3475 | return ret; |
| 3503 | 3476 | ||
| 3504 | hpet_msi_write(get_irq_data(irq), &msg); | 3477 | hpet_msi_write(irq_get_handler_data(irq), &msg); |
| 3505 | irq_set_status_flags(irq, IRQ_MOVE_PCNTXT); | 3478 | irq_set_status_flags(irq, IRQ_MOVE_PCNTXT); |
| 3506 | if (irq_remapped(get_irq_chip_data(irq))) | 3479 | if (irq_remapped(irq_get_chip_data(irq))) |
| 3507 | set_irq_chip_and_handler_name(irq, &ir_hpet_msi_type, | 3480 | chip = &ir_hpet_msi_type; |
| 3508 | handle_edge_irq, "edge"); | ||
| 3509 | else | ||
| 3510 | set_irq_chip_and_handler_name(irq, &hpet_msi_type, | ||
| 3511 | handle_edge_irq, "edge"); | ||
| 3512 | 3481 | ||
| 3482 | irq_set_chip_and_handler_name(irq, chip, handle_edge_irq, "edge"); | ||
| 3513 | return 0; | 3483 | return 0; |
| 3514 | } | 3484 | } |
| 3515 | #endif | 3485 | #endif |
| @@ -3596,7 +3566,7 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) | |||
| 3596 | 3566 | ||
| 3597 | write_ht_irq_msg(irq, &msg); | 3567 | write_ht_irq_msg(irq, &msg); |
| 3598 | 3568 | ||
| 3599 | set_irq_chip_and_handler_name(irq, &ht_irq_chip, | 3569 | irq_set_chip_and_handler_name(irq, &ht_irq_chip, |
| 3600 | handle_edge_irq, "edge"); | 3570 | handle_edge_irq, "edge"); |
| 3601 | 3571 | ||
| 3602 | dev_printk(KERN_DEBUG, &dev->dev, "irq %d for HT\n", irq); | 3572 | dev_printk(KERN_DEBUG, &dev->dev, "irq %d for HT\n", irq); |
| @@ -3605,7 +3575,40 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) | |||
| 3605 | } | 3575 | } |
| 3606 | #endif /* CONFIG_HT_IRQ */ | 3576 | #endif /* CONFIG_HT_IRQ */ |
| 3607 | 3577 | ||
| 3608 | int __init io_apic_get_redir_entries (int ioapic) | 3578 | int |
| 3579 | io_apic_setup_irq_pin(unsigned int irq, int node, struct io_apic_irq_attr *attr) | ||
| 3580 | { | ||
| 3581 | struct irq_cfg *cfg = alloc_irq_and_cfg_at(irq, node); | ||
| 3582 | int ret; | ||
| 3583 | |||
| 3584 | if (!cfg) | ||
| 3585 | return -EINVAL; | ||
| 3586 | ret = __add_pin_to_irq_node(cfg, node, attr->ioapic, attr->ioapic_pin); | ||
| 3587 | if (!ret) | ||
| 3588 | setup_ioapic_irq(attr->ioapic, attr->ioapic_pin, irq, cfg, | ||
| 3589 | attr->trigger, attr->polarity); | ||
| 3590 | return ret; | ||
| 3591 | } | ||
| 3592 | |||
| 3593 | static int io_apic_setup_irq_pin_once(unsigned int irq, int node, | ||
| 3594 | struct io_apic_irq_attr *attr) | ||
| 3595 | { | ||
| 3596 | unsigned int id = attr->ioapic, pin = attr->ioapic_pin; | ||
| 3597 | int ret; | ||
| 3598 | |||
| 3599 | /* Avoid redundant programming */ | ||
| 3600 | if (test_bit(pin, mp_ioapic_routing[id].pin_programmed)) { | ||
| 3601 | pr_debug("Pin %d-%d already programmed\n", | ||
| 3602 | mp_ioapics[id].apicid, pin); | ||
| 3603 | return 0; | ||
| 3604 | } | ||
| 3605 | ret = io_apic_setup_irq_pin(irq, node, attr); | ||
| 3606 | if (!ret) | ||
| 3607 | set_bit(pin, mp_ioapic_routing[id].pin_programmed); | ||
| 3608 | return ret; | ||
| 3609 | } | ||
| 3610 | |||
| 3611 | static int __init io_apic_get_redir_entries(int ioapic) | ||
| 3609 | { | 3612 | { |
| 3610 | union IO_APIC_reg_01 reg_01; | 3613 | union IO_APIC_reg_01 reg_01; |
| 3611 | unsigned long flags; | 3614 | unsigned long flags; |
| @@ -3659,96 +3662,24 @@ int __init arch_probe_nr_irqs(void) | |||
| 3659 | } | 3662 | } |
| 3660 | #endif | 3663 | #endif |
| 3661 | 3664 | ||
| 3662 | static int __io_apic_set_pci_routing(struct device *dev, int irq, | 3665 | int io_apic_set_pci_routing(struct device *dev, int irq, |
| 3663 | struct io_apic_irq_attr *irq_attr) | 3666 | struct io_apic_irq_attr *irq_attr) |
| 3664 | { | 3667 | { |
| 3665 | struct irq_cfg *cfg; | ||
| 3666 | int node; | 3668 | int node; |
| 3667 | int ioapic, pin; | ||
| 3668 | int trigger, polarity; | ||
| 3669 | 3669 | ||
| 3670 | ioapic = irq_attr->ioapic; | ||
| 3671 | if (!IO_APIC_IRQ(irq)) { | 3670 | if (!IO_APIC_IRQ(irq)) { |
| 3672 | apic_printk(APIC_QUIET,KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n", | 3671 | apic_printk(APIC_QUIET,KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n", |
| 3673 | ioapic); | 3672 | irq_attr->ioapic); |
| 3674 | return -EINVAL; | 3673 | return -EINVAL; |
| 3675 | } | 3674 | } |
| 3676 | 3675 | ||
| 3677 | if (dev) | 3676 | node = dev ? dev_to_node(dev) : cpu_to_node(0); |
| 3678 | node = dev_to_node(dev); | ||
| 3679 | else | ||
| 3680 | node = cpu_to_node(0); | ||
| 3681 | |||
| 3682 | cfg = alloc_irq_and_cfg_at(irq, node); | ||
| 3683 | if (!cfg) | ||
| 3684 | return 0; | ||
| 3685 | |||
| 3686 | pin = irq_attr->ioapic_pin; | ||
| 3687 | trigger = irq_attr->trigger; | ||
| 3688 | polarity = irq_attr->polarity; | ||
| 3689 | 3677 | ||
| 3690 | /* | 3678 | return io_apic_setup_irq_pin_once(irq, node, irq_attr); |
| 3691 | * IRQs < 16 are already in the irq_2_pin[] map | ||
| 3692 | */ | ||
| 3693 | if (irq >= legacy_pic->nr_legacy_irqs) { | ||
| 3694 | if (__add_pin_to_irq_node(cfg, node, ioapic, pin)) { | ||
| 3695 | printk(KERN_INFO "can not add pin %d for irq %d\n", | ||
| 3696 | pin, irq); | ||
| 3697 | return 0; | ||
| 3698 | } | ||
| 3699 | } | ||
| 3700 | |||
| 3701 | setup_ioapic_irq(ioapic, pin, irq, cfg, trigger, polarity); | ||
| 3702 | |||
| 3703 | return 0; | ||
| 3704 | } | 3679 | } |
| 3705 | 3680 | ||
| 3706 | int io_apic_set_pci_routing(struct device *dev, int irq, | ||
| 3707 | struct io_apic_irq_attr *irq_attr) | ||
| 3708 | { | ||
| 3709 | int ioapic, pin; | ||
| 3710 | /* | ||
| 3711 | * Avoid pin reprogramming. PRTs typically include entries | ||
| 3712 | * with redundant pin->gsi mappings (but unique PCI devices); | ||
| 3713 | * we only program the IOAPIC on the first. | ||
| 3714 | */ | ||
| 3715 | ioapic = irq_attr->ioapic; | ||
| 3716 | pin = irq_attr->ioapic_pin; | ||
| 3717 | if (test_bit(pin, mp_ioapic_routing[ioapic].pin_programmed)) { | ||
| 3718 | pr_debug("Pin %d-%d already programmed\n", | ||
| 3719 | mp_ioapics[ioapic].apicid, pin); | ||
| 3720 | return 0; | ||
| 3721 | } | ||
| 3722 | set_bit(pin, mp_ioapic_routing[ioapic].pin_programmed); | ||
| 3723 | |||
| 3724 | return __io_apic_set_pci_routing(dev, irq, irq_attr); | ||
| 3725 | } | ||
| 3726 | |||
| 3727 | u8 __init io_apic_unique_id(u8 id) | ||
| 3728 | { | ||
| 3729 | #ifdef CONFIG_X86_32 | 3681 | #ifdef CONFIG_X86_32 |
| 3730 | if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && | 3682 | static int __init io_apic_get_unique_id(int ioapic, int apic_id) |
| 3731 | !APIC_XAPIC(apic_version[boot_cpu_physical_apicid])) | ||
| 3732 | return io_apic_get_unique_id(nr_ioapics, id); | ||
| 3733 | else | ||
| 3734 | return id; | ||
| 3735 | #else | ||
| 3736 | int i; | ||
| 3737 | DECLARE_BITMAP(used, 256); | ||
| 3738 | |||
| 3739 | bitmap_zero(used, 256); | ||
| 3740 | for (i = 0; i < nr_ioapics; i++) { | ||
| 3741 | struct mpc_ioapic *ia = &mp_ioapics[i]; | ||
| 3742 | __set_bit(ia->apicid, used); | ||
| 3743 | } | ||
| 3744 | if (!test_bit(id, used)) | ||
| 3745 | return id; | ||
| 3746 | return find_first_zero_bit(used, 256); | ||
| 3747 | #endif | ||
| 3748 | } | ||
| 3749 | |||
| 3750 | #ifdef CONFIG_X86_32 | ||
| 3751 | int __init io_apic_get_unique_id(int ioapic, int apic_id) | ||
| 3752 | { | 3683 | { |
| 3753 | union IO_APIC_reg_00 reg_00; | 3684 | union IO_APIC_reg_00 reg_00; |
| 3754 | static physid_mask_t apic_id_map = PHYSID_MASK_NONE; | 3685 | static physid_mask_t apic_id_map = PHYSID_MASK_NONE; |
| @@ -3821,9 +3752,33 @@ int __init io_apic_get_unique_id(int ioapic, int apic_id) | |||
| 3821 | 3752 | ||
| 3822 | return apic_id; | 3753 | return apic_id; |
| 3823 | } | 3754 | } |
| 3755 | |||
| 3756 | static u8 __init io_apic_unique_id(u8 id) | ||
| 3757 | { | ||
| 3758 | if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && | ||
| 3759 | !APIC_XAPIC(apic_version[boot_cpu_physical_apicid])) | ||
| 3760 | return io_apic_get_unique_id(nr_ioapics, id); | ||
| 3761 | else | ||
| 3762 | return id; | ||
| 3763 | } | ||
| 3764 | #else | ||
| 3765 | static u8 __init io_apic_unique_id(u8 id) | ||
| 3766 | { | ||
| 3767 | int i; | ||
| 3768 | DECLARE_BITMAP(used, 256); | ||
| 3769 | |||
| 3770 | bitmap_zero(used, 256); | ||
| 3771 | for (i = 0; i < nr_ioapics; i++) { | ||
| 3772 | struct mpc_ioapic *ia = &mp_ioapics[i]; | ||
| 3773 | __set_bit(ia->apicid, used); | ||
| 3774 | } | ||
| 3775 | if (!test_bit(id, used)) | ||
| 3776 | return id; | ||
| 3777 | return find_first_zero_bit(used, 256); | ||
| 3778 | } | ||
| 3824 | #endif | 3779 | #endif |
| 3825 | 3780 | ||
| 3826 | int __init io_apic_get_version(int ioapic) | 3781 | static int __init io_apic_get_version(int ioapic) |
| 3827 | { | 3782 | { |
| 3828 | union IO_APIC_reg_01 reg_01; | 3783 | union IO_APIC_reg_01 reg_01; |
| 3829 | unsigned long flags; | 3784 | unsigned long flags; |
| @@ -3868,8 +3823,8 @@ int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity) | |||
| 3868 | void __init setup_ioapic_dest(void) | 3823 | void __init setup_ioapic_dest(void) |
| 3869 | { | 3824 | { |
| 3870 | int pin, ioapic, irq, irq_entry; | 3825 | int pin, ioapic, irq, irq_entry; |
| 3871 | struct irq_desc *desc; | ||
| 3872 | const struct cpumask *mask; | 3826 | const struct cpumask *mask; |
| 3827 | struct irq_data *idata; | ||
| 3873 | 3828 | ||
| 3874 | if (skip_ioapic_setup == 1) | 3829 | if (skip_ioapic_setup == 1) |
| 3875 | return; | 3830 | return; |
| @@ -3884,21 +3839,20 @@ void __init setup_ioapic_dest(void) | |||
| 3884 | if ((ioapic > 0) && (irq > 16)) | 3839 | if ((ioapic > 0) && (irq > 16)) |
| 3885 | continue; | 3840 | continue; |
| 3886 | 3841 | ||
| 3887 | desc = irq_to_desc(irq); | 3842 | idata = irq_get_irq_data(irq); |
| 3888 | 3843 | ||
| 3889 | /* | 3844 | /* |
| 3890 | * Honour affinities which have been set in early boot | 3845 | * Honour affinities which have been set in early boot |
| 3891 | */ | 3846 | */ |
| 3892 | if (desc->status & | 3847 | if (!irqd_can_balance(idata) || irqd_affinity_was_set(idata)) |
| 3893 | (IRQ_NO_BALANCING | IRQ_AFFINITY_SET)) | 3848 | mask = idata->affinity; |
| 3894 | mask = desc->irq_data.affinity; | ||
| 3895 | else | 3849 | else |
| 3896 | mask = apic->target_cpus(); | 3850 | mask = apic->target_cpus(); |
| 3897 | 3851 | ||
| 3898 | if (intr_remapping_enabled) | 3852 | if (intr_remapping_enabled) |
| 3899 | ir_ioapic_set_affinity(&desc->irq_data, mask, false); | 3853 | ir_ioapic_set_affinity(idata, mask, false); |
| 3900 | else | 3854 | else |
| 3901 | ioapic_set_affinity(&desc->irq_data, mask, false); | 3855 | ioapic_set_affinity(idata, mask, false); |
| 3902 | } | 3856 | } |
| 3903 | 3857 | ||
| 3904 | } | 3858 | } |
| @@ -4026,7 +3980,7 @@ int mp_find_ioapic_pin(int ioapic, u32 gsi) | |||
| 4026 | return gsi - mp_gsi_routing[ioapic].gsi_base; | 3980 | return gsi - mp_gsi_routing[ioapic].gsi_base; |
| 4027 | } | 3981 | } |
| 4028 | 3982 | ||
| 4029 | static int bad_ioapic(unsigned long address) | 3983 | static __init int bad_ioapic(unsigned long address) |
| 4030 | { | 3984 | { |
| 4031 | if (nr_ioapics >= MAX_IO_APICS) { | 3985 | if (nr_ioapics >= MAX_IO_APICS) { |
| 4032 | printk(KERN_WARNING "WARING: Max # of I/O APICs (%d) exceeded " | 3986 | printk(KERN_WARNING "WARING: Max # of I/O APICs (%d) exceeded " |
| @@ -4086,20 +4040,16 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base) | |||
| 4086 | /* Enable IOAPIC early just for system timer */ | 4040 | /* Enable IOAPIC early just for system timer */ |
| 4087 | void __init pre_init_apic_IRQ0(void) | 4041 | void __init pre_init_apic_IRQ0(void) |
| 4088 | { | 4042 | { |
| 4089 | struct irq_cfg *cfg; | 4043 | struct io_apic_irq_attr attr = { 0, 0, 0, 0 }; |
| 4090 | 4044 | ||
| 4091 | printk(KERN_INFO "Early APIC setup for system timer0\n"); | 4045 | printk(KERN_INFO "Early APIC setup for system timer0\n"); |
| 4092 | #ifndef CONFIG_SMP | 4046 | #ifndef CONFIG_SMP |
| 4093 | physid_set_mask_of_physid(boot_cpu_physical_apicid, | 4047 | physid_set_mask_of_physid(boot_cpu_physical_apicid, |
| 4094 | &phys_cpu_present_map); | 4048 | &phys_cpu_present_map); |
| 4095 | #endif | 4049 | #endif |
| 4096 | /* Make sure the irq descriptor is set up */ | ||
| 4097 | cfg = alloc_irq_and_cfg_at(0, 0); | ||
| 4098 | |||
| 4099 | setup_local_APIC(); | 4050 | setup_local_APIC(); |
| 4100 | 4051 | ||
| 4101 | add_pin_to_irq_node(cfg, 0, 0, 0); | 4052 | io_apic_setup_irq_pin(0, 0, &attr); |
| 4102 | set_irq_chip_and_handler_name(0, &ioapic_chip, handle_edge_irq, "edge"); | 4053 | irq_set_chip_and_handler_name(0, &ioapic_chip, handle_edge_irq, |
| 4103 | 4054 | "edge"); | |
| 4104 | setup_ioapic_irq(0, 0, 0, cfg, 0, 0); | ||
| 4105 | } | 4055 | } |
