diff options
| -rw-r--r-- | arch/x86/include/asm/i8259.h | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 20 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/nmi.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/i8259.c | 63 | ||||
| -rw-r--r-- | arch/x86/kernel/smpboot.c | 4 |
5 files changed, 47 insertions, 44 deletions
diff --git a/arch/x86/include/asm/i8259.h b/arch/x86/include/asm/i8259.h index 1655147646aa..a20365953bf8 100644 --- a/arch/x86/include/asm/i8259.h +++ b/arch/x86/include/asm/i8259.h | |||
| @@ -55,6 +55,8 @@ extern struct irq_chip i8259A_chip; | |||
| 55 | struct legacy_pic { | 55 | struct legacy_pic { |
| 56 | int nr_legacy_irqs; | 56 | int nr_legacy_irqs; |
| 57 | struct irq_chip *chip; | 57 | struct irq_chip *chip; |
| 58 | void (*mask)(unsigned int irq); | ||
| 59 | void (*unmask)(unsigned int irq); | ||
| 58 | void (*mask_all)(void); | 60 | void (*mask_all)(void); |
| 59 | void (*restore_mask)(void); | 61 | void (*restore_mask)(void); |
| 60 | void (*init)(int auto_eoi); | 62 | void (*init)(int auto_eoi); |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 74bb027b517e..e5ae2a222620 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
| @@ -1459,7 +1459,7 @@ static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq | |||
| 1459 | 1459 | ||
| 1460 | ioapic_register_intr(irq, desc, trigger); | 1460 | ioapic_register_intr(irq, desc, trigger); |
| 1461 | if (irq < legacy_pic->nr_legacy_irqs) | 1461 | if (irq < legacy_pic->nr_legacy_irqs) |
| 1462 | legacy_pic->chip->mask(irq); | 1462 | legacy_pic->mask(irq); |
| 1463 | 1463 | ||
| 1464 | ioapic_write_entry(apic_id, pin, entry); | 1464 | ioapic_write_entry(apic_id, pin, entry); |
| 1465 | } | 1465 | } |
| @@ -2233,7 +2233,7 @@ static unsigned int startup_ioapic_irq(unsigned int irq) | |||
| 2233 | 2233 | ||
| 2234 | raw_spin_lock_irqsave(&ioapic_lock, flags); | 2234 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
| 2235 | if (irq < legacy_pic->nr_legacy_irqs) { | 2235 | if (irq < legacy_pic->nr_legacy_irqs) { |
| 2236 | legacy_pic->chip->mask(irq); | 2236 | legacy_pic->mask(irq); |
| 2237 | if (legacy_pic->irq_pending(irq)) | 2237 | if (legacy_pic->irq_pending(irq)) |
| 2238 | was_pending = 1; | 2238 | was_pending = 1; |
| 2239 | } | 2239 | } |
| @@ -2928,7 +2928,7 @@ static inline void __init check_timer(void) | |||
| 2928 | /* | 2928 | /* |
| 2929 | * get/set the timer IRQ vector: | 2929 | * get/set the timer IRQ vector: |
| 2930 | */ | 2930 | */ |
| 2931 | legacy_pic->chip->mask(0); | 2931 | legacy_pic->mask(0); |
| 2932 | assign_irq_vector(0, cfg, apic->target_cpus()); | 2932 | assign_irq_vector(0, cfg, apic->target_cpus()); |
| 2933 | 2933 | ||
| 2934 | /* | 2934 | /* |
| @@ -3000,7 +3000,7 @@ static inline void __init check_timer(void) | |||
| 3000 | if (timer_irq_works()) { | 3000 | if (timer_irq_works()) { |
| 3001 | if (nmi_watchdog == NMI_IO_APIC) { | 3001 | if (nmi_watchdog == NMI_IO_APIC) { |
| 3002 | setup_nmi(); | 3002 | setup_nmi(); |
| 3003 | legacy_pic->chip->unmask(0); | 3003 | legacy_pic->unmask(0); |
| 3004 | } | 3004 | } |
| 3005 | if (disable_timer_pin_1 > 0) | 3005 | if (disable_timer_pin_1 > 0) |
| 3006 | clear_IO_APIC_pin(0, pin1); | 3006 | clear_IO_APIC_pin(0, pin1); |
| @@ -3023,14 +3023,14 @@ static inline void __init check_timer(void) | |||
| 3023 | */ | 3023 | */ |
| 3024 | replace_pin_at_irq_node(cfg, node, apic1, pin1, apic2, pin2); | 3024 | replace_pin_at_irq_node(cfg, node, apic1, pin1, apic2, pin2); |
| 3025 | setup_timer_IRQ0_pin(apic2, pin2, cfg->vector); | 3025 | setup_timer_IRQ0_pin(apic2, pin2, cfg->vector); |
| 3026 | legacy_pic->chip->unmask(0); | 3026 | legacy_pic->unmask(0); |
| 3027 | if (timer_irq_works()) { | 3027 | if (timer_irq_works()) { |
| 3028 | apic_printk(APIC_QUIET, KERN_INFO "....... works.\n"); | 3028 | apic_printk(APIC_QUIET, KERN_INFO "....... works.\n"); |
| 3029 | timer_through_8259 = 1; | 3029 | timer_through_8259 = 1; |
| 3030 | if (nmi_watchdog == NMI_IO_APIC) { | 3030 | if (nmi_watchdog == NMI_IO_APIC) { |
| 3031 | legacy_pic->chip->mask(0); | 3031 | legacy_pic->mask(0); |
| 3032 | setup_nmi(); | 3032 | setup_nmi(); |
| 3033 | legacy_pic->chip->unmask(0); | 3033 | legacy_pic->unmask(0); |
| 3034 | } | 3034 | } |
| 3035 | goto out; | 3035 | goto out; |
| 3036 | } | 3036 | } |
| @@ -3038,7 +3038,7 @@ static inline void __init check_timer(void) | |||
| 3038 | * Cleanup, just in case ... | 3038 | * Cleanup, just in case ... |
| 3039 | */ | 3039 | */ |
| 3040 | local_irq_disable(); | 3040 | local_irq_disable(); |
| 3041 | legacy_pic->chip->mask(0); | 3041 | legacy_pic->mask(0); |
| 3042 | clear_IO_APIC_pin(apic2, pin2); | 3042 | clear_IO_APIC_pin(apic2, pin2); |
| 3043 | apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n"); | 3043 | apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n"); |
| 3044 | } | 3044 | } |
| @@ -3057,14 +3057,14 @@ static inline void __init check_timer(void) | |||
| 3057 | 3057 | ||
| 3058 | lapic_register_intr(0, desc); | 3058 | lapic_register_intr(0, desc); |
| 3059 | apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector); /* Fixed mode */ | 3059 | apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector); /* Fixed mode */ |
| 3060 | legacy_pic->chip->unmask(0); | 3060 | legacy_pic->unmask(0); |
| 3061 | 3061 | ||
| 3062 | if (timer_irq_works()) { | 3062 | if (timer_irq_works()) { |
| 3063 | apic_printk(APIC_QUIET, KERN_INFO "..... works.\n"); | 3063 | apic_printk(APIC_QUIET, KERN_INFO "..... works.\n"); |
| 3064 | goto out; | 3064 | goto out; |
| 3065 | } | 3065 | } |
| 3066 | local_irq_disable(); | 3066 | local_irq_disable(); |
| 3067 | legacy_pic->chip->mask(0); | 3067 | legacy_pic->mask(0); |
| 3068 | apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector); | 3068 | apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector); |
| 3069 | apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n"); | 3069 | apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n"); |
| 3070 | 3070 | ||
diff --git a/arch/x86/kernel/apic/nmi.c b/arch/x86/kernel/apic/nmi.c index a43f71cb30f8..c90041ccb742 100644 --- a/arch/x86/kernel/apic/nmi.c +++ b/arch/x86/kernel/apic/nmi.c | |||
| @@ -178,7 +178,7 @@ int __init check_nmi_watchdog(void) | |||
| 178 | error: | 178 | error: |
| 179 | if (nmi_watchdog == NMI_IO_APIC) { | 179 | if (nmi_watchdog == NMI_IO_APIC) { |
| 180 | if (!timer_through_8259) | 180 | if (!timer_through_8259) |
| 181 | legacy_pic->chip->mask(0); | 181 | legacy_pic->mask(0); |
| 182 | on_each_cpu(__acpi_nmi_disable, NULL, 1); | 182 | on_each_cpu(__acpi_nmi_disable, NULL, 1); |
| 183 | } | 183 | } |
| 184 | 184 | ||
diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c index cafa7c80ac95..20757cb2efa3 100644 --- a/arch/x86/kernel/i8259.c +++ b/arch/x86/kernel/i8259.c | |||
| @@ -29,24 +29,10 @@ | |||
| 29 | * plus some generic x86 specific things if generic specifics makes | 29 | * plus some generic x86 specific things if generic specifics makes |
| 30 | * any sense at all. | 30 | * any sense at all. |
| 31 | */ | 31 | */ |
| 32 | static void init_8259A(int auto_eoi); | ||
| 32 | 33 | ||
| 33 | static int i8259A_auto_eoi; | 34 | static int i8259A_auto_eoi; |
| 34 | DEFINE_RAW_SPINLOCK(i8259A_lock); | 35 | DEFINE_RAW_SPINLOCK(i8259A_lock); |
| 35 | static void mask_and_ack_8259A(unsigned int); | ||
| 36 | static void mask_8259A(void); | ||
| 37 | static void unmask_8259A(void); | ||
| 38 | static void disable_8259A_irq(unsigned int irq); | ||
| 39 | static void enable_8259A_irq(unsigned int irq); | ||
| 40 | static void init_8259A(int auto_eoi); | ||
| 41 | static int i8259A_irq_pending(unsigned int irq); | ||
| 42 | |||
| 43 | struct irq_chip i8259A_chip = { | ||
| 44 | .name = "XT-PIC", | ||
| 45 | .mask = disable_8259A_irq, | ||
| 46 | .disable = disable_8259A_irq, | ||
| 47 | .unmask = enable_8259A_irq, | ||
| 48 | .mask_ack = mask_and_ack_8259A, | ||
| 49 | }; | ||
| 50 | 36 | ||
| 51 | /* | 37 | /* |
| 52 | * 8259A PIC functions to handle ISA devices: | 38 | * 8259A PIC functions to handle ISA devices: |
| @@ -68,7 +54,7 @@ unsigned int cached_irq_mask = 0xffff; | |||
| 68 | */ | 54 | */ |
| 69 | unsigned long io_apic_irqs; | 55 | unsigned long io_apic_irqs; |
| 70 | 56 | ||
| 71 | static void disable_8259A_irq(unsigned int irq) | 57 | static void mask_8259A_irq(unsigned int irq) |
| 72 | { | 58 | { |
| 73 | unsigned int mask = 1 << irq; | 59 | unsigned int mask = 1 << irq; |
| 74 | unsigned long flags; | 60 | unsigned long flags; |
| @@ -82,7 +68,12 @@ static void disable_8259A_irq(unsigned int irq) | |||
| 82 | raw_spin_unlock_irqrestore(&i8259A_lock, flags); | 68 | raw_spin_unlock_irqrestore(&i8259A_lock, flags); |
| 83 | } | 69 | } |
| 84 | 70 | ||
| 85 | static void enable_8259A_irq(unsigned int irq) | 71 | static void disable_8259A_irq(struct irq_data *data) |
| 72 | { | ||
| 73 | mask_8259A_irq(data->irq); | ||
| 74 | } | ||
| 75 | |||
| 76 | static void unmask_8259A_irq(unsigned int irq) | ||
| 86 | { | 77 | { |
| 87 | unsigned int mask = ~(1 << irq); | 78 | unsigned int mask = ~(1 << irq); |
| 88 | unsigned long flags; | 79 | unsigned long flags; |
| @@ -96,6 +87,11 @@ static void enable_8259A_irq(unsigned int irq) | |||
| 96 | raw_spin_unlock_irqrestore(&i8259A_lock, flags); | 87 | raw_spin_unlock_irqrestore(&i8259A_lock, flags); |
| 97 | } | 88 | } |
| 98 | 89 | ||
| 90 | static void enable_8259A_irq(struct irq_data *data) | ||
| 91 | { | ||
| 92 | unmask_8259A_irq(data->irq); | ||
| 93 | } | ||
| 94 | |||
| 99 | static int i8259A_irq_pending(unsigned int irq) | 95 | static int i8259A_irq_pending(unsigned int irq) |
| 100 | { | 96 | { |
| 101 | unsigned int mask = 1<<irq; | 97 | unsigned int mask = 1<<irq; |
| @@ -117,7 +113,7 @@ static void make_8259A_irq(unsigned int irq) | |||
| 117 | disable_irq_nosync(irq); | 113 | disable_irq_nosync(irq); |
| 118 | io_apic_irqs &= ~(1<<irq); | 114 | io_apic_irqs &= ~(1<<irq); |
| 119 | set_irq_chip_and_handler_name(irq, &i8259A_chip, handle_level_irq, | 115 | set_irq_chip_and_handler_name(irq, &i8259A_chip, handle_level_irq, |
| 120 | "XT"); | 116 | i8259A_chip.name); |
| 121 | enable_irq(irq); | 117 | enable_irq(irq); |
| 122 | } | 118 | } |
| 123 | 119 | ||
| @@ -150,8 +146,9 @@ static inline int i8259A_irq_real(unsigned int irq) | |||
| 150 | * first, _then_ send the EOI, and the order of EOI | 146 | * first, _then_ send the EOI, and the order of EOI |
| 151 | * to the two 8259s is important! | 147 | * to the two 8259s is important! |
| 152 | */ | 148 | */ |
| 153 | static void mask_and_ack_8259A(unsigned int irq) | 149 | static void mask_and_ack_8259A(struct irq_data *data) |
| 154 | { | 150 | { |
| 151 | unsigned int irq = data->irq; | ||
| 155 | unsigned int irqmask = 1 << irq; | 152 | unsigned int irqmask = 1 << irq; |
| 156 | unsigned long flags; | 153 | unsigned long flags; |
| 157 | 154 | ||
| @@ -223,6 +220,14 @@ spurious_8259A_irq: | |||
| 223 | } | 220 | } |
| 224 | } | 221 | } |
| 225 | 222 | ||
| 223 | struct irq_chip i8259A_chip = { | ||
| 224 | .name = "XT-PIC", | ||
| 225 | .irq_mask = disable_8259A_irq, | ||
| 226 | .irq_disable = disable_8259A_irq, | ||
| 227 | .irq_unmask = enable_8259A_irq, | ||
| 228 | .irq_mask_ack = mask_and_ack_8259A, | ||
| 229 | }; | ||
| 230 | |||
| 226 | static char irq_trigger[2]; | 231 | static char irq_trigger[2]; |
| 227 | /** | 232 | /** |
| 228 | * ELCR registers (0x4d0, 0x4d1) control edge/level of IRQ | 233 | * ELCR registers (0x4d0, 0x4d1) control edge/level of IRQ |
| @@ -342,9 +347,9 @@ static void init_8259A(int auto_eoi) | |||
| 342 | * In AEOI mode we just have to mask the interrupt | 347 | * In AEOI mode we just have to mask the interrupt |
| 343 | * when acking. | 348 | * when acking. |
| 344 | */ | 349 | */ |
| 345 | i8259A_chip.mask_ack = disable_8259A_irq; | 350 | i8259A_chip.irq_mask_ack = disable_8259A_irq; |
| 346 | else | 351 | else |
| 347 | i8259A_chip.mask_ack = mask_and_ack_8259A; | 352 | i8259A_chip.irq_mask_ack = mask_and_ack_8259A; |
| 348 | 353 | ||
| 349 | udelay(100); /* wait for 8259A to initialize */ | 354 | udelay(100); /* wait for 8259A to initialize */ |
| 350 | 355 | ||
| @@ -363,14 +368,6 @@ static void init_8259A(int auto_eoi) | |||
| 363 | static void legacy_pic_noop(void) { }; | 368 | static void legacy_pic_noop(void) { }; |
| 364 | static void legacy_pic_uint_noop(unsigned int unused) { }; | 369 | static void legacy_pic_uint_noop(unsigned int unused) { }; |
| 365 | static void legacy_pic_int_noop(int unused) { }; | 370 | static void legacy_pic_int_noop(int unused) { }; |
| 366 | |||
| 367 | static struct irq_chip dummy_pic_chip = { | ||
| 368 | .name = "dummy pic", | ||
| 369 | .mask = legacy_pic_uint_noop, | ||
| 370 | .unmask = legacy_pic_uint_noop, | ||
| 371 | .disable = legacy_pic_uint_noop, | ||
| 372 | .mask_ack = legacy_pic_uint_noop, | ||
| 373 | }; | ||
| 374 | static int legacy_pic_irq_pending_noop(unsigned int irq) | 371 | static int legacy_pic_irq_pending_noop(unsigned int irq) |
| 375 | { | 372 | { |
| 376 | return 0; | 373 | return 0; |
| @@ -378,7 +375,9 @@ static int legacy_pic_irq_pending_noop(unsigned int irq) | |||
| 378 | 375 | ||
| 379 | struct legacy_pic null_legacy_pic = { | 376 | struct legacy_pic null_legacy_pic = { |
| 380 | .nr_legacy_irqs = 0, | 377 | .nr_legacy_irqs = 0, |
| 381 | .chip = &dummy_pic_chip, | 378 | .chip = &dummy_irq_chip, |
| 379 | .mask = legacy_pic_uint_noop, | ||
| 380 | .unmask = legacy_pic_uint_noop, | ||
| 382 | .mask_all = legacy_pic_noop, | 381 | .mask_all = legacy_pic_noop, |
| 383 | .restore_mask = legacy_pic_noop, | 382 | .restore_mask = legacy_pic_noop, |
| 384 | .init = legacy_pic_int_noop, | 383 | .init = legacy_pic_int_noop, |
| @@ -389,7 +388,9 @@ struct legacy_pic null_legacy_pic = { | |||
| 389 | struct legacy_pic default_legacy_pic = { | 388 | struct legacy_pic default_legacy_pic = { |
| 390 | .nr_legacy_irqs = NR_IRQS_LEGACY, | 389 | .nr_legacy_irqs = NR_IRQS_LEGACY, |
| 391 | .chip = &i8259A_chip, | 390 | .chip = &i8259A_chip, |
| 392 | .mask_all = mask_8259A, | 391 | .mask = mask_8259A_irq, |
| 392 | .unmask = unmask_8259A_irq, | ||
| 393 | .mask_all = mask_8259A, | ||
| 393 | .restore_mask = unmask_8259A, | 394 | .restore_mask = unmask_8259A, |
| 394 | .init = init_8259A, | 395 | .init = init_8259A, |
| 395 | .irq_pending = i8259A_irq_pending, | 396 | .irq_pending = i8259A_irq_pending, |
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 87a8c6b00f8d..864b386f6c0e 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
| @@ -324,9 +324,9 @@ notrace static void __cpuinit start_secondary(void *unused) | |||
| 324 | check_tsc_sync_target(); | 324 | check_tsc_sync_target(); |
| 325 | 325 | ||
| 326 | if (nmi_watchdog == NMI_IO_APIC) { | 326 | if (nmi_watchdog == NMI_IO_APIC) { |
| 327 | legacy_pic->chip->mask(0); | 327 | legacy_pic->mask(0); |
| 328 | enable_NMI_through_LVT0(); | 328 | enable_NMI_through_LVT0(); |
| 329 | legacy_pic->chip->unmask(0); | 329 | legacy_pic->unmask(0); |
| 330 | } | 330 | } |
| 331 | 331 | ||
| 332 | /* This must be done before setting cpu_online_mask */ | 332 | /* This must be done before setting cpu_online_mask */ |
