diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-07 18:59:39 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-07 18:59:39 -0500 |
commit | 322aafa6645a48c3b7837ca7385f126ab78127fd (patch) | |
tree | 50f6665aedcf051cecd571183df81ba7f248014b /arch/x86/kernel/apic/io_apic.c | |
parent | dd04265b028c00c365a78f9ff78a05e217f98656 (diff) | |
parent | c7bbf52aa4fa332b84c4f2bb33e69561ee6870b4 (diff) |
Merge branch 'x86-mrst-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'x86-mrst-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (30 commits)
x86, mrst: Fix whitespace breakage in apb_timer.c
x86, mrst: Fix APB timer per cpu clockevent
x86, mrst: Remove X86_MRST dependency on PCI_IOAPIC
x86, olpc: Use pci subarch init for OLPC
x86, pci: Add arch_init to x86_init abstraction
x86, mrst: Add Kconfig dependencies for Moorestown
x86, pci: Exclude Moorestown PCI code if CONFIG_X86_MRST=n
x86, numaq: Make CONFIG_X86_NUMAQ depend on CONFIG_PCI
x86, pci: Add sanity check for PCI fixed bar probing
x86, legacy_irq: Remove duplicate vector assigment
x86, legacy_irq: Remove left over nr_legacy_irqs
x86, mrst: Platform clock setup code
x86, apbt: Moorestown APB system timer driver
x86, mrst: Add vrtc platform data setup code
x86, mrst: Add platform timer info parsing code
x86, mrst: Fill in PCI functions in x86_init layer
x86, mrst: Add dummy legacy pic to platform setup
x86/PCI: Moorestown PCI support
x86, ioapic: Add dummy ioapic functions
x86, ioapic: Early enable ioapic for timer irq
...
Fixed up semantic conflict of new clocksources due to commit
17622339af25 ("clocksource: add argument to resume callback").
Diffstat (limited to 'arch/x86/kernel/apic/io_apic.c')
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 86 |
1 files changed, 53 insertions, 33 deletions
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 14862f11cc4a..e4e0ddcb1546 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -143,12 +143,6 @@ static struct irq_cfg irq_cfgx[NR_IRQS_LEGACY]; | |||
143 | static struct irq_cfg irq_cfgx[NR_IRQS]; | 143 | static struct irq_cfg irq_cfgx[NR_IRQS]; |
144 | #endif | 144 | #endif |
145 | 145 | ||
146 | void __init io_apic_disable_legacy(void) | ||
147 | { | ||
148 | nr_legacy_irqs = 0; | ||
149 | nr_irqs_gsi = 0; | ||
150 | } | ||
151 | |||
152 | int __init arch_early_irq_init(void) | 146 | int __init arch_early_irq_init(void) |
153 | { | 147 | { |
154 | struct irq_cfg *cfg; | 148 | struct irq_cfg *cfg; |
@@ -157,6 +151,11 @@ int __init arch_early_irq_init(void) | |||
157 | int node; | 151 | int node; |
158 | int i; | 152 | int i; |
159 | 153 | ||
154 | if (!legacy_pic->nr_legacy_irqs) { | ||
155 | nr_irqs_gsi = 0; | ||
156 | io_apic_irqs = ~0UL; | ||
157 | } | ||
158 | |||
160 | cfg = irq_cfgx; | 159 | cfg = irq_cfgx; |
161 | count = ARRAY_SIZE(irq_cfgx); | 160 | count = ARRAY_SIZE(irq_cfgx); |
162 | node= cpu_to_node(boot_cpu_id); | 161 | node= cpu_to_node(boot_cpu_id); |
@@ -170,7 +169,7 @@ int __init arch_early_irq_init(void) | |||
170 | * For legacy IRQ's, start with assigning irq0 to irq15 to | 169 | * For legacy IRQ's, start with assigning irq0 to irq15 to |
171 | * IRQ0_VECTOR to IRQ15_VECTOR on cpu 0. | 170 | * IRQ0_VECTOR to IRQ15_VECTOR on cpu 0. |
172 | */ | 171 | */ |
173 | if (i < nr_legacy_irqs) { | 172 | if (i < legacy_pic->nr_legacy_irqs) { |
174 | cfg[i].vector = IRQ0_VECTOR + i; | 173 | cfg[i].vector = IRQ0_VECTOR + i; |
175 | cpumask_set_cpu(0, cfg[i].domain); | 174 | cpumask_set_cpu(0, cfg[i].domain); |
176 | } | 175 | } |
@@ -852,7 +851,7 @@ static int __init find_isa_irq_apic(int irq, int type) | |||
852 | */ | 851 | */ |
853 | static int EISA_ELCR(unsigned int irq) | 852 | static int EISA_ELCR(unsigned int irq) |
854 | { | 853 | { |
855 | if (irq < nr_legacy_irqs) { | 854 | if (irq < legacy_pic->nr_legacy_irqs) { |
856 | unsigned int port = 0x4d0 + (irq >> 3); | 855 | unsigned int port = 0x4d0 + (irq >> 3); |
857 | return (inb(port) >> (irq & 7)) & 1; | 856 | return (inb(port) >> (irq & 7)) & 1; |
858 | } | 857 | } |
@@ -1439,7 +1438,7 @@ static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq | |||
1439 | * controllers like 8259. Now that IO-APIC can handle this irq, update | 1438 | * controllers like 8259. Now that IO-APIC can handle this irq, update |
1440 | * the cfg->domain. | 1439 | * the cfg->domain. |
1441 | */ | 1440 | */ |
1442 | if (irq < nr_legacy_irqs && cpumask_test_cpu(0, cfg->domain)) | 1441 | if (irq < legacy_pic->nr_legacy_irqs && cpumask_test_cpu(0, cfg->domain)) |
1443 | apic->vector_allocation_domain(0, cfg->domain); | 1442 | apic->vector_allocation_domain(0, cfg->domain); |
1444 | 1443 | ||
1445 | if (assign_irq_vector(irq, cfg, apic->target_cpus())) | 1444 | if (assign_irq_vector(irq, cfg, apic->target_cpus())) |
@@ -1463,8 +1462,8 @@ static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq | |||
1463 | } | 1462 | } |
1464 | 1463 | ||
1465 | ioapic_register_intr(irq, desc, trigger); | 1464 | ioapic_register_intr(irq, desc, trigger); |
1466 | if (irq < nr_legacy_irqs) | 1465 | if (irq < legacy_pic->nr_legacy_irqs) |
1467 | disable_8259A_irq(irq); | 1466 | legacy_pic->chip->mask(irq); |
1468 | 1467 | ||
1469 | ioapic_write_entry(apic_id, pin, entry); | 1468 | ioapic_write_entry(apic_id, pin, entry); |
1470 | } | 1469 | } |
@@ -1873,7 +1872,7 @@ __apicdebuginit(void) print_PIC(void) | |||
1873 | unsigned int v; | 1872 | unsigned int v; |
1874 | unsigned long flags; | 1873 | unsigned long flags; |
1875 | 1874 | ||
1876 | if (!nr_legacy_irqs) | 1875 | if (!legacy_pic->nr_legacy_irqs) |
1877 | return; | 1876 | return; |
1878 | 1877 | ||
1879 | printk(KERN_DEBUG "\nprinting PIC contents\n"); | 1878 | printk(KERN_DEBUG "\nprinting PIC contents\n"); |
@@ -1957,7 +1956,7 @@ void __init enable_IO_APIC(void) | |||
1957 | nr_ioapic_registers[apic] = reg_01.bits.entries+1; | 1956 | nr_ioapic_registers[apic] = reg_01.bits.entries+1; |
1958 | } | 1957 | } |
1959 | 1958 | ||
1960 | if (!nr_legacy_irqs) | 1959 | if (!legacy_pic->nr_legacy_irqs) |
1961 | return; | 1960 | return; |
1962 | 1961 | ||
1963 | for(apic = 0; apic < nr_ioapics; apic++) { | 1962 | for(apic = 0; apic < nr_ioapics; apic++) { |
@@ -2014,7 +2013,7 @@ void disable_IO_APIC(void) | |||
2014 | */ | 2013 | */ |
2015 | clear_IO_APIC(); | 2014 | clear_IO_APIC(); |
2016 | 2015 | ||
2017 | if (!nr_legacy_irqs) | 2016 | if (!legacy_pic->nr_legacy_irqs) |
2018 | return; | 2017 | return; |
2019 | 2018 | ||
2020 | /* | 2019 | /* |
@@ -2247,9 +2246,9 @@ static unsigned int startup_ioapic_irq(unsigned int irq) | |||
2247 | struct irq_cfg *cfg; | 2246 | struct irq_cfg *cfg; |
2248 | 2247 | ||
2249 | raw_spin_lock_irqsave(&ioapic_lock, flags); | 2248 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
2250 | if (irq < nr_legacy_irqs) { | 2249 | if (irq < legacy_pic->nr_legacy_irqs) { |
2251 | disable_8259A_irq(irq); | 2250 | legacy_pic->chip->mask(irq); |
2252 | if (i8259A_irq_pending(irq)) | 2251 | if (legacy_pic->irq_pending(irq)) |
2253 | was_pending = 1; | 2252 | was_pending = 1; |
2254 | } | 2253 | } |
2255 | cfg = irq_cfg(irq); | 2254 | cfg = irq_cfg(irq); |
@@ -2782,8 +2781,8 @@ static inline void init_IO_APIC_traps(void) | |||
2782 | * so default to an old-fashioned 8259 | 2781 | * so default to an old-fashioned 8259 |
2783 | * interrupt if we can.. | 2782 | * interrupt if we can.. |
2784 | */ | 2783 | */ |
2785 | if (irq < nr_legacy_irqs) | 2784 | if (irq < legacy_pic->nr_legacy_irqs) |
2786 | make_8259A_irq(irq); | 2785 | legacy_pic->make_irq(irq); |
2787 | else | 2786 | else |
2788 | /* Strange. Oh, well.. */ | 2787 | /* Strange. Oh, well.. */ |
2789 | desc->chip = &no_irq_chip; | 2788 | desc->chip = &no_irq_chip; |
@@ -2940,7 +2939,7 @@ static inline void __init check_timer(void) | |||
2940 | /* | 2939 | /* |
2941 | * get/set the timer IRQ vector: | 2940 | * get/set the timer IRQ vector: |
2942 | */ | 2941 | */ |
2943 | disable_8259A_irq(0); | 2942 | legacy_pic->chip->mask(0); |
2944 | assign_irq_vector(0, cfg, apic->target_cpus()); | 2943 | assign_irq_vector(0, cfg, apic->target_cpus()); |
2945 | 2944 | ||
2946 | /* | 2945 | /* |
@@ -2953,7 +2952,7 @@ static inline void __init check_timer(void) | |||
2953 | * automatically. | 2952 | * automatically. |
2954 | */ | 2953 | */ |
2955 | apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); | 2954 | apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); |
2956 | init_8259A(1); | 2955 | legacy_pic->init(1); |
2957 | #ifdef CONFIG_X86_32 | 2956 | #ifdef CONFIG_X86_32 |
2958 | { | 2957 | { |
2959 | unsigned int ver; | 2958 | unsigned int ver; |
@@ -3012,7 +3011,7 @@ static inline void __init check_timer(void) | |||
3012 | if (timer_irq_works()) { | 3011 | if (timer_irq_works()) { |
3013 | if (nmi_watchdog == NMI_IO_APIC) { | 3012 | if (nmi_watchdog == NMI_IO_APIC) { |
3014 | setup_nmi(); | 3013 | setup_nmi(); |
3015 | enable_8259A_irq(0); | 3014 | legacy_pic->chip->unmask(0); |
3016 | } | 3015 | } |
3017 | if (disable_timer_pin_1 > 0) | 3016 | if (disable_timer_pin_1 > 0) |
3018 | clear_IO_APIC_pin(0, pin1); | 3017 | clear_IO_APIC_pin(0, pin1); |
@@ -3035,14 +3034,14 @@ static inline void __init check_timer(void) | |||
3035 | */ | 3034 | */ |
3036 | replace_pin_at_irq_node(cfg, node, apic1, pin1, apic2, pin2); | 3035 | replace_pin_at_irq_node(cfg, node, apic1, pin1, apic2, pin2); |
3037 | setup_timer_IRQ0_pin(apic2, pin2, cfg->vector); | 3036 | setup_timer_IRQ0_pin(apic2, pin2, cfg->vector); |
3038 | enable_8259A_irq(0); | 3037 | legacy_pic->chip->unmask(0); |
3039 | if (timer_irq_works()) { | 3038 | if (timer_irq_works()) { |
3040 | apic_printk(APIC_QUIET, KERN_INFO "....... works.\n"); | 3039 | apic_printk(APIC_QUIET, KERN_INFO "....... works.\n"); |
3041 | timer_through_8259 = 1; | 3040 | timer_through_8259 = 1; |
3042 | if (nmi_watchdog == NMI_IO_APIC) { | 3041 | if (nmi_watchdog == NMI_IO_APIC) { |
3043 | disable_8259A_irq(0); | 3042 | legacy_pic->chip->mask(0); |
3044 | setup_nmi(); | 3043 | setup_nmi(); |
3045 | enable_8259A_irq(0); | 3044 | legacy_pic->chip->unmask(0); |
3046 | } | 3045 | } |
3047 | goto out; | 3046 | goto out; |
3048 | } | 3047 | } |
@@ -3050,7 +3049,7 @@ static inline void __init check_timer(void) | |||
3050 | * Cleanup, just in case ... | 3049 | * Cleanup, just in case ... |
3051 | */ | 3050 | */ |
3052 | local_irq_disable(); | 3051 | local_irq_disable(); |
3053 | disable_8259A_irq(0); | 3052 | legacy_pic->chip->mask(0); |
3054 | clear_IO_APIC_pin(apic2, pin2); | 3053 | clear_IO_APIC_pin(apic2, pin2); |
3055 | apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n"); | 3054 | apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n"); |
3056 | } | 3055 | } |
@@ -3069,22 +3068,22 @@ static inline void __init check_timer(void) | |||
3069 | 3068 | ||
3070 | lapic_register_intr(0, desc); | 3069 | lapic_register_intr(0, desc); |
3071 | apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector); /* Fixed mode */ | 3070 | apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector); /* Fixed mode */ |
3072 | enable_8259A_irq(0); | 3071 | legacy_pic->chip->unmask(0); |
3073 | 3072 | ||
3074 | if (timer_irq_works()) { | 3073 | if (timer_irq_works()) { |
3075 | apic_printk(APIC_QUIET, KERN_INFO "..... works.\n"); | 3074 | apic_printk(APIC_QUIET, KERN_INFO "..... works.\n"); |
3076 | goto out; | 3075 | goto out; |
3077 | } | 3076 | } |
3078 | local_irq_disable(); | 3077 | local_irq_disable(); |
3079 | disable_8259A_irq(0); | 3078 | legacy_pic->chip->mask(0); |
3080 | apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector); | 3079 | apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector); |
3081 | apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n"); | 3080 | apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n"); |
3082 | 3081 | ||
3083 | apic_printk(APIC_QUIET, KERN_INFO | 3082 | apic_printk(APIC_QUIET, KERN_INFO |
3084 | "...trying to set up timer as ExtINT IRQ...\n"); | 3083 | "...trying to set up timer as ExtINT IRQ...\n"); |
3085 | 3084 | ||
3086 | init_8259A(0); | 3085 | legacy_pic->init(0); |
3087 | make_8259A_irq(0); | 3086 | legacy_pic->make_irq(0); |
3088 | apic_write(APIC_LVT0, APIC_DM_EXTINT); | 3087 | apic_write(APIC_LVT0, APIC_DM_EXTINT); |
3089 | 3088 | ||
3090 | unlock_ExtINT_logic(); | 3089 | unlock_ExtINT_logic(); |
@@ -3126,7 +3125,7 @@ void __init setup_IO_APIC(void) | |||
3126 | /* | 3125 | /* |
3127 | * calling enable_IO_APIC() is moved to setup_local_APIC for BP | 3126 | * calling enable_IO_APIC() is moved to setup_local_APIC for BP |
3128 | */ | 3127 | */ |
3129 | io_apic_irqs = nr_legacy_irqs ? ~PIC_IRQS : ~0UL; | 3128 | io_apic_irqs = legacy_pic->nr_legacy_irqs ? ~PIC_IRQS : ~0UL; |
3130 | 3129 | ||
3131 | apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n"); | 3130 | apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n"); |
3132 | /* | 3131 | /* |
@@ -3137,7 +3136,7 @@ void __init setup_IO_APIC(void) | |||
3137 | sync_Arb_IDs(); | 3136 | sync_Arb_IDs(); |
3138 | setup_IO_APIC_irqs(); | 3137 | setup_IO_APIC_irqs(); |
3139 | init_IO_APIC_traps(); | 3138 | init_IO_APIC_traps(); |
3140 | if (nr_legacy_irqs) | 3139 | if (legacy_pic->nr_legacy_irqs) |
3141 | check_timer(); | 3140 | check_timer(); |
3142 | } | 3141 | } |
3143 | 3142 | ||
@@ -3928,7 +3927,7 @@ static int __io_apic_set_pci_routing(struct device *dev, int irq, | |||
3928 | /* | 3927 | /* |
3929 | * IRQs < 16 are already in the irq_2_pin[] map | 3928 | * IRQs < 16 are already in the irq_2_pin[] map |
3930 | */ | 3929 | */ |
3931 | if (irq >= nr_legacy_irqs) { | 3930 | if (irq >= legacy_pic->nr_legacy_irqs) { |
3932 | cfg = desc->chip_data; | 3931 | cfg = desc->chip_data; |
3933 | if (add_pin_to_irq_node_nopanic(cfg, node, ioapic, pin)) { | 3932 | if (add_pin_to_irq_node_nopanic(cfg, node, ioapic, pin)) { |
3934 | printk(KERN_INFO "can not add pin %d for irq %d\n", | 3933 | printk(KERN_INFO "can not add pin %d for irq %d\n", |
@@ -4302,3 +4301,24 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base) | |||
4302 | 4301 | ||
4303 | nr_ioapics++; | 4302 | nr_ioapics++; |
4304 | } | 4303 | } |
4304 | |||
4305 | /* Enable IOAPIC early just for system timer */ | ||
4306 | void __init pre_init_apic_IRQ0(void) | ||
4307 | { | ||
4308 | struct irq_cfg *cfg; | ||
4309 | struct irq_desc *desc; | ||
4310 | |||
4311 | printk(KERN_INFO "Early APIC setup for system timer0\n"); | ||
4312 | #ifndef CONFIG_SMP | ||
4313 | phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid); | ||
4314 | #endif | ||
4315 | desc = irq_to_desc_alloc_node(0, 0); | ||
4316 | |||
4317 | setup_local_APIC(); | ||
4318 | |||
4319 | cfg = irq_cfg(0); | ||
4320 | add_pin_to_irq_node(cfg, 0, 0, 0); | ||
4321 | set_irq_chip_and_handler_name(0, &ioapic_chip, handle_edge_irq, "edge"); | ||
4322 | |||
4323 | setup_IO_APIC_irq(0, 0, 0, desc, 0, 0); | ||
4324 | } | ||