diff options
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/apic/apic.c | 5 | ||||
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 265 | ||||
-rw-r--r-- | arch/x86/kernel/smpboot.c | 11 |
3 files changed, 122 insertions, 159 deletions
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 76b96d74978a..f0e079823c43 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <asm/i8259.h> | 43 | #include <asm/i8259.h> |
44 | #include <asm/proto.h> | 44 | #include <asm/proto.h> |
45 | #include <asm/apic.h> | 45 | #include <asm/apic.h> |
46 | #include <asm/io_apic.h> | ||
46 | #include <asm/desc.h> | 47 | #include <asm/desc.h> |
47 | #include <asm/hpet.h> | 48 | #include <asm/hpet.h> |
48 | #include <asm/idle.h> | 49 | #include <asm/idle.h> |
@@ -1209,7 +1210,7 @@ void __cpuinit setup_local_APIC(void) | |||
1209 | rdtscll(tsc); | 1210 | rdtscll(tsc); |
1210 | 1211 | ||
1211 | if (disable_apic) { | 1212 | if (disable_apic) { |
1212 | arch_disable_smp_support(); | 1213 | disable_ioapic_support(); |
1213 | return; | 1214 | return; |
1214 | } | 1215 | } |
1215 | 1216 | ||
@@ -1448,7 +1449,7 @@ int __init enable_IR(void) | |||
1448 | void __init enable_IR_x2apic(void) | 1449 | void __init enable_IR_x2apic(void) |
1449 | { | 1450 | { |
1450 | unsigned long flags; | 1451 | unsigned long flags; |
1451 | struct IO_APIC_route_entry **ioapic_entries = NULL; | 1452 | struct IO_APIC_route_entry **ioapic_entries; |
1452 | int ret, x2apic_enabled = 0; | 1453 | int ret, x2apic_enabled = 0; |
1453 | int dmar_table_init_ret; | 1454 | int dmar_table_init_ret; |
1454 | 1455 | ||
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index ca9e2a3545a9..8d23e831a45e 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 | { |
@@ -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; |
@@ -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 | { |
@@ -1385,33 +1377,26 @@ static struct { | |||
1385 | DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1); | 1377 | DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1); |
1386 | } mp_ioapic_routing[MAX_IO_APICS]; | 1378 | } mp_ioapic_routing[MAX_IO_APICS]; |
1387 | 1379 | ||
1388 | static void __init setup_IO_APIC_irqs(void) | 1380 | static bool __init io_apic_pin_not_connected(int idx, int apic_id, int pin) |
1389 | { | 1381 | { |
1390 | int apic_id, pin, idx, irq, notcon = 0; | 1382 | if (idx != -1) |
1391 | int node = cpu_to_node(0); | 1383 | return false; |
1392 | struct irq_cfg *cfg; | ||
1393 | 1384 | ||
1394 | apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n"); | 1385 | apic_printk(APIC_VERBOSE, KERN_DEBUG " apic %d pin %d not connected\n", |
1386 | mp_ioapics[apic_id].apicid, pin); | ||
1387 | return true; | ||
1388 | } | ||
1389 | |||
1390 | static void __init __io_apic_setup_irqs(unsigned int apic_id) | ||
1391 | { | ||
1392 | int idx, node = cpu_to_node(0); | ||
1393 | struct io_apic_irq_attr attr; | ||
1394 | unsigned int pin, irq; | ||
1395 | 1395 | ||
1396 | for (apic_id = 0; apic_id < nr_ioapics; apic_id++) | ||
1397 | for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) { | 1396 | for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) { |
1398 | idx = find_irq_entry(apic_id, pin, mp_INT); | 1397 | idx = find_irq_entry(apic_id, pin, mp_INT); |
1399 | if (idx == -1) { | 1398 | 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; | 1399 | continue; |
1409 | } | ||
1410 | if (notcon) { | ||
1411 | apic_printk(APIC_VERBOSE, | ||
1412 | " (apicid-pin) not connected\n"); | ||
1413 | notcon = 0; | ||
1414 | } | ||
1415 | 1400 | ||
1416 | irq = pin_2_irq(idx, apic_id, pin); | 1401 | irq = pin_2_irq(idx, apic_id, pin); |
1417 | 1402 | ||
@@ -1423,25 +1408,24 @@ static void __init setup_IO_APIC_irqs(void) | |||
1423 | * installed and if it returns 1: | 1408 | * installed and if it returns 1: |
1424 | */ | 1409 | */ |
1425 | if (apic->multi_timer_check && | 1410 | if (apic->multi_timer_check && |
1426 | apic->multi_timer_check(apic_id, irq)) | 1411 | apic->multi_timer_check(apic_id, irq)) |
1427 | continue; | 1412 | continue; |
1428 | 1413 | ||
1429 | cfg = alloc_irq_and_cfg_at(irq, node); | 1414 | set_io_apic_irq_attr(&attr, apic_id, pin, irq_trigger(idx), |
1430 | if (!cfg) | 1415 | irq_polarity(idx)); |
1431 | continue; | ||
1432 | 1416 | ||
1433 | add_pin_to_irq_node(cfg, node, apic_id, pin); | 1417 | 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 | } | 1418 | } |
1419 | } | ||
1441 | 1420 | ||
1442 | if (notcon) | 1421 | static void __init setup_IO_APIC_irqs(void) |
1443 | apic_printk(APIC_VERBOSE, | 1422 | { |
1444 | " (apicid-pin) not connected\n"); | 1423 | unsigned int apic_id; |
1424 | |||
1425 | apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n"); | ||
1426 | |||
1427 | for (apic_id = 0; apic_id < nr_ioapics; apic_id++) | ||
1428 | __io_apic_setup_irqs(apic_id); | ||
1445 | } | 1429 | } |
1446 | 1430 | ||
1447 | /* | 1431 | /* |
@@ -1452,7 +1436,7 @@ static void __init setup_IO_APIC_irqs(void) | |||
1452 | void setup_IO_APIC_irq_extra(u32 gsi) | 1436 | void setup_IO_APIC_irq_extra(u32 gsi) |
1453 | { | 1437 | { |
1454 | int apic_id = 0, pin, idx, irq, node = cpu_to_node(0); | 1438 | int apic_id = 0, pin, idx, irq, node = cpu_to_node(0); |
1455 | struct irq_cfg *cfg; | 1439 | struct io_apic_irq_attr attr; |
1456 | 1440 | ||
1457 | /* | 1441 | /* |
1458 | * Convert 'gsi' to 'ioapic.pin'. | 1442 | * Convert 'gsi' to 'ioapic.pin'. |
@@ -1472,21 +1456,10 @@ void setup_IO_APIC_irq_extra(u32 gsi) | |||
1472 | if (apic_id == 0 || irq < NR_IRQS_LEGACY) | 1456 | if (apic_id == 0 || irq < NR_IRQS_LEGACY) |
1473 | return; | 1457 | return; |
1474 | 1458 | ||
1475 | cfg = alloc_irq_and_cfg_at(irq, node); | 1459 | set_io_apic_irq_attr(&attr, apic_id, pin, irq_trigger(idx), |
1476 | if (!cfg) | 1460 | 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 | 1461 | ||
1488 | setup_ioapic_irq(apic_id, pin, irq, cfg, | 1462 | io_apic_setup_irq_pin_once(irq, node, &attr); |
1489 | irq_trigger(idx), irq_polarity(idx)); | ||
1490 | } | 1463 | } |
1491 | 1464 | ||
1492 | /* | 1465 | /* |
@@ -3605,7 +3578,40 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) | |||
3605 | } | 3578 | } |
3606 | #endif /* CONFIG_HT_IRQ */ | 3579 | #endif /* CONFIG_HT_IRQ */ |
3607 | 3580 | ||
3608 | int __init io_apic_get_redir_entries (int ioapic) | 3581 | int |
3582 | io_apic_setup_irq_pin(unsigned int irq, int node, struct io_apic_irq_attr *attr) | ||
3583 | { | ||
3584 | struct irq_cfg *cfg = alloc_irq_and_cfg_at(irq, node); | ||
3585 | int ret; | ||
3586 | |||
3587 | if (!cfg) | ||
3588 | return -EINVAL; | ||
3589 | ret = __add_pin_to_irq_node(cfg, node, attr->ioapic, attr->ioapic_pin); | ||
3590 | if (!ret) | ||
3591 | setup_ioapic_irq(attr->ioapic, attr->ioapic_pin, irq, cfg, | ||
3592 | attr->trigger, attr->polarity); | ||
3593 | return ret; | ||
3594 | } | ||
3595 | |||
3596 | static int io_apic_setup_irq_pin_once(unsigned int irq, int node, | ||
3597 | struct io_apic_irq_attr *attr) | ||
3598 | { | ||
3599 | unsigned int id = attr->ioapic, pin = attr->ioapic_pin; | ||
3600 | int ret; | ||
3601 | |||
3602 | /* Avoid redundant programming */ | ||
3603 | if (test_bit(pin, mp_ioapic_routing[id].pin_programmed)) { | ||
3604 | pr_debug("Pin %d-%d already programmed\n", | ||
3605 | mp_ioapics[id].apicid, pin); | ||
3606 | return 0; | ||
3607 | } | ||
3608 | ret = io_apic_setup_irq_pin(irq, node, attr); | ||
3609 | if (!ret) | ||
3610 | set_bit(pin, mp_ioapic_routing[id].pin_programmed); | ||
3611 | return ret; | ||
3612 | } | ||
3613 | |||
3614 | static int __init io_apic_get_redir_entries(int ioapic) | ||
3609 | { | 3615 | { |
3610 | union IO_APIC_reg_01 reg_01; | 3616 | union IO_APIC_reg_01 reg_01; |
3611 | unsigned long flags; | 3617 | unsigned long flags; |
@@ -3659,96 +3665,24 @@ int __init arch_probe_nr_irqs(void) | |||
3659 | } | 3665 | } |
3660 | #endif | 3666 | #endif |
3661 | 3667 | ||
3662 | static int __io_apic_set_pci_routing(struct device *dev, int irq, | 3668 | int io_apic_set_pci_routing(struct device *dev, int irq, |
3663 | struct io_apic_irq_attr *irq_attr) | 3669 | struct io_apic_irq_attr *irq_attr) |
3664 | { | 3670 | { |
3665 | struct irq_cfg *cfg; | ||
3666 | int node; | 3671 | int node; |
3667 | int ioapic, pin; | ||
3668 | int trigger, polarity; | ||
3669 | 3672 | ||
3670 | ioapic = irq_attr->ioapic; | ||
3671 | if (!IO_APIC_IRQ(irq)) { | 3673 | if (!IO_APIC_IRQ(irq)) { |
3672 | apic_printk(APIC_QUIET,KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n", | 3674 | apic_printk(APIC_QUIET,KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n", |
3673 | ioapic); | 3675 | irq_attr->ioapic); |
3674 | return -EINVAL; | 3676 | return -EINVAL; |
3675 | } | 3677 | } |
3676 | 3678 | ||
3677 | if (dev) | 3679 | 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 | |||
3690 | /* | ||
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 | 3680 | ||
3703 | return 0; | 3681 | return io_apic_setup_irq_pin_once(irq, node, irq_attr); |
3704 | } | 3682 | } |
3705 | 3683 | ||
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 | 3684 | #ifdef CONFIG_X86_32 |
3730 | if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && | 3685 | 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 | { | 3686 | { |
3753 | union IO_APIC_reg_00 reg_00; | 3687 | union IO_APIC_reg_00 reg_00; |
3754 | static physid_mask_t apic_id_map = PHYSID_MASK_NONE; | 3688 | static physid_mask_t apic_id_map = PHYSID_MASK_NONE; |
@@ -3821,9 +3755,33 @@ int __init io_apic_get_unique_id(int ioapic, int apic_id) | |||
3821 | 3755 | ||
3822 | return apic_id; | 3756 | return apic_id; |
3823 | } | 3757 | } |
3758 | |||
3759 | static u8 __init io_apic_unique_id(u8 id) | ||
3760 | { | ||
3761 | if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && | ||
3762 | !APIC_XAPIC(apic_version[boot_cpu_physical_apicid])) | ||
3763 | return io_apic_get_unique_id(nr_ioapics, id); | ||
3764 | else | ||
3765 | return id; | ||
3766 | } | ||
3767 | #else | ||
3768 | static u8 __init io_apic_unique_id(u8 id) | ||
3769 | { | ||
3770 | int i; | ||
3771 | DECLARE_BITMAP(used, 256); | ||
3772 | |||
3773 | bitmap_zero(used, 256); | ||
3774 | for (i = 0; i < nr_ioapics; i++) { | ||
3775 | struct mpc_ioapic *ia = &mp_ioapics[i]; | ||
3776 | __set_bit(ia->apicid, used); | ||
3777 | } | ||
3778 | if (!test_bit(id, used)) | ||
3779 | return id; | ||
3780 | return find_first_zero_bit(used, 256); | ||
3781 | } | ||
3824 | #endif | 3782 | #endif |
3825 | 3783 | ||
3826 | int __init io_apic_get_version(int ioapic) | 3784 | static int __init io_apic_get_version(int ioapic) |
3827 | { | 3785 | { |
3828 | union IO_APIC_reg_01 reg_01; | 3786 | union IO_APIC_reg_01 reg_01; |
3829 | unsigned long flags; | 3787 | unsigned long flags; |
@@ -4026,7 +3984,7 @@ int mp_find_ioapic_pin(int ioapic, u32 gsi) | |||
4026 | return gsi - mp_gsi_routing[ioapic].gsi_base; | 3984 | return gsi - mp_gsi_routing[ioapic].gsi_base; |
4027 | } | 3985 | } |
4028 | 3986 | ||
4029 | static int bad_ioapic(unsigned long address) | 3987 | static __init int bad_ioapic(unsigned long address) |
4030 | { | 3988 | { |
4031 | if (nr_ioapics >= MAX_IO_APICS) { | 3989 | if (nr_ioapics >= MAX_IO_APICS) { |
4032 | printk(KERN_WARNING "WARING: Max # of I/O APICs (%d) exceeded " | 3990 | printk(KERN_WARNING "WARING: Max # of I/O APICs (%d) exceeded " |
@@ -4086,20 +4044,15 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base) | |||
4086 | /* Enable IOAPIC early just for system timer */ | 4044 | /* Enable IOAPIC early just for system timer */ |
4087 | void __init pre_init_apic_IRQ0(void) | 4045 | void __init pre_init_apic_IRQ0(void) |
4088 | { | 4046 | { |
4089 | struct irq_cfg *cfg; | 4047 | struct io_apic_irq_attr attr = { 0, 0, 0, 0 }; |
4090 | 4048 | ||
4091 | printk(KERN_INFO "Early APIC setup for system timer0\n"); | 4049 | printk(KERN_INFO "Early APIC setup for system timer0\n"); |
4092 | #ifndef CONFIG_SMP | 4050 | #ifndef CONFIG_SMP |
4093 | physid_set_mask_of_physid(boot_cpu_physical_apicid, | 4051 | physid_set_mask_of_physid(boot_cpu_physical_apicid, |
4094 | &phys_cpu_present_map); | 4052 | &phys_cpu_present_map); |
4095 | #endif | 4053 | #endif |
4096 | /* Make sure the irq descriptor is set up */ | ||
4097 | cfg = alloc_irq_and_cfg_at(0, 0); | ||
4098 | |||
4099 | setup_local_APIC(); | 4054 | setup_local_APIC(); |
4100 | 4055 | ||
4101 | add_pin_to_irq_node(cfg, 0, 0, 0); | 4056 | io_apic_setup_irq_pin(0, 0, &attr); |
4102 | set_irq_chip_and_handler_name(0, &ioapic_chip, handle_edge_irq, "edge"); | 4057 | set_irq_chip_and_handler_name(0, &ioapic_chip, handle_edge_irq, "edge"); |
4103 | |||
4104 | setup_ioapic_irq(0, 0, 0, cfg, 0, 0); | ||
4105 | } | 4058 | } |
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 08776a953487..09d0172a0059 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -64,6 +64,7 @@ | |||
64 | #include <asm/mtrr.h> | 64 | #include <asm/mtrr.h> |
65 | #include <asm/mwait.h> | 65 | #include <asm/mwait.h> |
66 | #include <asm/apic.h> | 66 | #include <asm/apic.h> |
67 | #include <asm/io_apic.h> | ||
67 | #include <asm/setup.h> | 68 | #include <asm/setup.h> |
68 | #include <asm/uv/uv.h> | 69 | #include <asm/uv/uv.h> |
69 | #include <linux/mc146818rtc.h> | 70 | #include <linux/mc146818rtc.h> |
@@ -945,6 +946,14 @@ int __cpuinit native_cpu_up(unsigned int cpu) | |||
945 | return 0; | 946 | return 0; |
946 | } | 947 | } |
947 | 948 | ||
949 | /** | ||
950 | * arch_disable_smp_support() - disables SMP support for x86 at runtime | ||
951 | */ | ||
952 | void arch_disable_smp_support(void) | ||
953 | { | ||
954 | disable_ioapic_support(); | ||
955 | } | ||
956 | |||
948 | /* | 957 | /* |
949 | * Fall back to non SMP mode after errors. | 958 | * Fall back to non SMP mode after errors. |
950 | * | 959 | * |
@@ -1045,7 +1054,7 @@ static int __init smp_sanity_check(unsigned max_cpus) | |||
1045 | "(tell your hw vendor)\n"); | 1054 | "(tell your hw vendor)\n"); |
1046 | } | 1055 | } |
1047 | smpboot_clear_io_apic(); | 1056 | smpboot_clear_io_apic(); |
1048 | arch_disable_smp_support(); | 1057 | disable_ioapic_support(); |
1049 | return -1; | 1058 | return -1; |
1050 | } | 1059 | } |
1051 | 1060 | ||