diff options
| author | Thomas Gleixner <tglx@linutronix.de> | 2010-09-28 09:18:35 -0400 |
|---|---|---|
| committer | Thomas Gleixner <tglx@linutronix.de> | 2010-10-12 10:53:36 -0400 |
| commit | dd5f15e5cf104c9170b76ae3274f35b42a3e4161 (patch) | |
| tree | 31de134f5db3534dff174c2b72234243348677e4 /arch/x86/kernel | |
| parent | d4eba29770244e7cc5e60c0977d73d84148a3d6d (diff) | |
x86: Cleanup io_apic
Sanitize functions. Remove irq_desc pointer magic.
Preparatory patch for further cleanups.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel')
| -rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 109 |
1 files changed, 42 insertions, 67 deletions
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index fa0d92a6db59..3c4dee8a9ef7 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
| @@ -572,11 +572,6 @@ static void __unmask_and_level_IO_APIC_irq(struct irq_pin_list *entry) | |||
| 572 | IO_APIC_REDIR_LEVEL_TRIGGER, NULL); | 572 | IO_APIC_REDIR_LEVEL_TRIGGER, NULL); |
| 573 | } | 573 | } |
| 574 | 574 | ||
| 575 | static void __unmask_IO_APIC_irq(struct irq_cfg *cfg) | ||
| 576 | { | ||
| 577 | io_apic_modify_irq(cfg, ~IO_APIC_REDIR_MASKED, 0, NULL); | ||
| 578 | } | ||
| 579 | |||
| 580 | static void io_apic_sync(struct irq_pin_list *entry) | 575 | static void io_apic_sync(struct irq_pin_list *entry) |
| 581 | { | 576 | { |
| 582 | /* | 577 | /* |
| @@ -588,44 +583,41 @@ static void io_apic_sync(struct irq_pin_list *entry) | |||
| 588 | readl(&io_apic->data); | 583 | readl(&io_apic->data); |
| 589 | } | 584 | } |
| 590 | 585 | ||
| 591 | static void __mask_IO_APIC_irq(struct irq_cfg *cfg) | 586 | static void mask_ioapic(struct irq_cfg *cfg) |
| 592 | { | 587 | { |
| 588 | unsigned long flags; | ||
| 589 | |||
| 590 | raw_spin_lock_irqsave(&ioapic_lock, flags); | ||
| 593 | io_apic_modify_irq(cfg, ~0, IO_APIC_REDIR_MASKED, &io_apic_sync); | 591 | io_apic_modify_irq(cfg, ~0, IO_APIC_REDIR_MASKED, &io_apic_sync); |
| 592 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); | ||
| 594 | } | 593 | } |
| 595 | 594 | ||
| 596 | static void mask_IO_APIC_irq_desc(struct irq_desc *desc) | 595 | static void mask_ioapic_irq(unsigned int irq) |
| 597 | { | 596 | { |
| 598 | struct irq_cfg *cfg = get_irq_desc_chip_data(desc); | 597 | struct irq_cfg *cfg = get_irq_chip_data(irq); |
| 599 | unsigned long flags; | ||
| 600 | 598 | ||
| 601 | BUG_ON(!cfg); | 599 | mask_ioapic(cfg); |
| 600 | } | ||
| 602 | 601 | ||
| 603 | raw_spin_lock_irqsave(&ioapic_lock, flags); | 602 | static void __unmask_ioapic(struct irq_cfg *cfg) |
| 604 | __mask_IO_APIC_irq(cfg); | 603 | { |
| 605 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); | 604 | io_apic_modify_irq(cfg, ~IO_APIC_REDIR_MASKED, 0, NULL); |
| 606 | } | 605 | } |
| 607 | 606 | ||
| 608 | static void unmask_IO_APIC_irq_desc(struct irq_desc *desc) | 607 | static void unmask_ioapic(struct irq_cfg *cfg) |
| 609 | { | 608 | { |
| 610 | struct irq_cfg *cfg = get_irq_desc_chip_data(desc); | ||
| 611 | unsigned long flags; | 609 | unsigned long flags; |
| 612 | 610 | ||
| 613 | raw_spin_lock_irqsave(&ioapic_lock, flags); | 611 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
| 614 | __unmask_IO_APIC_irq(cfg); | 612 | __unmask_ioapic(cfg); |
| 615 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); | 613 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
| 616 | } | 614 | } |
| 617 | 615 | ||
| 618 | static void mask_IO_APIC_irq(unsigned int irq) | 616 | static void unmask_ioapic_irq(unsigned int irq) |
| 619 | { | 617 | { |
| 620 | struct irq_desc *desc = irq_to_desc(irq); | 618 | struct irq_cfg *cfg = get_irq_chip_data(irq); |
| 621 | 619 | ||
| 622 | mask_IO_APIC_irq_desc(desc); | 620 | unmask_ioapic(cfg); |
| 623 | } | ||
| 624 | static void unmask_IO_APIC_irq(unsigned int irq) | ||
| 625 | { | ||
| 626 | struct irq_desc *desc = irq_to_desc(irq); | ||
| 627 | |||
| 628 | unmask_IO_APIC_irq_desc(desc); | ||
| 629 | } | 621 | } |
| 630 | 622 | ||
| 631 | static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) | 623 | static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) |
| @@ -2239,7 +2231,7 @@ static unsigned int startup_ioapic_irq(unsigned int irq) | |||
| 2239 | was_pending = 1; | 2231 | was_pending = 1; |
| 2240 | } | 2232 | } |
| 2241 | cfg = irq_cfg(irq); | 2233 | cfg = irq_cfg(irq); |
| 2242 | __unmask_IO_APIC_irq(cfg); | 2234 | __unmask_ioapic(cfg); |
| 2243 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); | 2235 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
| 2244 | 2236 | ||
| 2245 | return was_pending; | 2237 | return was_pending; |
| @@ -2498,10 +2490,8 @@ unlock: | |||
| 2498 | irq_exit(); | 2490 | irq_exit(); |
| 2499 | } | 2491 | } |
| 2500 | 2492 | ||
| 2501 | static void __irq_complete_move(struct irq_desc **descp, unsigned vector) | 2493 | static void __irq_complete_move(struct irq_cfg *cfg, unsigned vector) |
| 2502 | { | 2494 | { |
| 2503 | struct irq_desc *desc = *descp; | ||
| 2504 | struct irq_cfg *cfg = get_irq_desc_chip_data(desc); | ||
| 2505 | unsigned me; | 2495 | unsigned me; |
| 2506 | 2496 | ||
| 2507 | if (likely(!cfg->move_in_progress)) | 2497 | if (likely(!cfg->move_in_progress)) |
| @@ -2513,30 +2503,29 @@ static void __irq_complete_move(struct irq_desc **descp, unsigned vector) | |||
| 2513 | send_cleanup_vector(cfg); | 2503 | send_cleanup_vector(cfg); |
| 2514 | } | 2504 | } |
| 2515 | 2505 | ||
| 2516 | static void irq_complete_move(struct irq_desc **descp) | 2506 | static void irq_complete_move(struct irq_cfg *cfg) |
| 2517 | { | 2507 | { |
| 2518 | __irq_complete_move(descp, ~get_irq_regs()->orig_ax); | 2508 | __irq_complete_move(cfg, ~get_irq_regs()->orig_ax); |
| 2519 | } | 2509 | } |
| 2520 | 2510 | ||
| 2521 | void irq_force_complete_move(int irq) | 2511 | void irq_force_complete_move(int irq) |
| 2522 | { | 2512 | { |
| 2523 | struct irq_desc *desc = irq_to_desc(irq); | 2513 | struct irq_cfg *cfg = get_irq_chip_data(irq); |
| 2524 | struct irq_cfg *cfg = get_irq_desc_chip_data(desc); | ||
| 2525 | 2514 | ||
| 2526 | if (!cfg) | 2515 | if (!cfg) |
| 2527 | return; | 2516 | return; |
| 2528 | 2517 | ||
| 2529 | __irq_complete_move(&desc, cfg->vector); | 2518 | __irq_complete_move(cfg, cfg->vector); |
| 2530 | } | 2519 | } |
| 2531 | #else | 2520 | #else |
| 2532 | static inline void irq_complete_move(struct irq_desc **descp) {} | 2521 | static inline void irq_complete_move(struct irq_cfg *cfg) { } |
| 2533 | #endif | 2522 | #endif |
| 2534 | 2523 | ||
| 2535 | static void ack_apic_edge(unsigned int irq) | 2524 | static void ack_apic_edge(unsigned int irq) |
| 2536 | { | 2525 | { |
| 2537 | struct irq_desc *desc = irq_to_desc(irq); | 2526 | struct irq_cfg *cfg = get_irq_chip_data(irq); |
| 2538 | 2527 | ||
| 2539 | irq_complete_move(&desc); | 2528 | irq_complete_move(cfg); |
| 2540 | move_native_irq(irq); | 2529 | move_native_irq(irq); |
| 2541 | ack_APIC_irq(); | 2530 | ack_APIC_irq(); |
| 2542 | } | 2531 | } |
| @@ -2559,10 +2548,12 @@ atomic_t irq_mis_count; | |||
| 2559 | * Otherwise, we simulate the EOI message manually by changing the trigger | 2548 | * Otherwise, we simulate the EOI message manually by changing the trigger |
| 2560 | * mode to edge and then back to level, with RTE being masked during this. | 2549 | * mode to edge and then back to level, with RTE being masked during this. |
| 2561 | */ | 2550 | */ |
| 2562 | static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg) | 2551 | static void eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg) |
| 2563 | { | 2552 | { |
| 2564 | struct irq_pin_list *entry; | 2553 | struct irq_pin_list *entry; |
| 2554 | unsigned long flags; | ||
| 2565 | 2555 | ||
| 2556 | raw_spin_lock_irqsave(&ioapic_lock, flags); | ||
| 2566 | for_each_irq_pin(entry, cfg->irq_2_pin) { | 2557 | for_each_irq_pin(entry, cfg->irq_2_pin) { |
| 2567 | if (mp_ioapics[entry->apic].apicver >= 0x20) { | 2558 | if (mp_ioapics[entry->apic].apicver >= 0x20) { |
| 2568 | /* | 2559 | /* |
| @@ -2580,36 +2571,22 @@ static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg) | |||
| 2580 | __unmask_and_level_IO_APIC_irq(entry); | 2571 | __unmask_and_level_IO_APIC_irq(entry); |
| 2581 | } | 2572 | } |
| 2582 | } | 2573 | } |
| 2583 | } | ||
| 2584 | |||
| 2585 | static void eoi_ioapic_irq(struct irq_desc *desc) | ||
| 2586 | { | ||
| 2587 | struct irq_cfg *cfg; | ||
| 2588 | unsigned long flags; | ||
| 2589 | unsigned int irq; | ||
| 2590 | |||
| 2591 | irq = desc->irq; | ||
| 2592 | cfg = get_irq_desc_chip_data(desc); | ||
| 2593 | |||
| 2594 | raw_spin_lock_irqsave(&ioapic_lock, flags); | ||
| 2595 | __eoi_ioapic_irq(irq, cfg); | ||
| 2596 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); | 2574 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
| 2597 | } | 2575 | } |
| 2598 | 2576 | ||
| 2599 | static void ack_apic_level(unsigned int irq) | 2577 | static void ack_apic_level(unsigned int irq) |
| 2600 | { | 2578 | { |
| 2601 | struct irq_desc *desc = irq_to_desc(irq); | 2579 | struct irq_desc *desc = irq_to_desc(irq); |
| 2580 | struct irq_cfg *cfg = get_irq_desc_chip_data(desc); | ||
| 2581 | int i, do_unmask_irq = 0; | ||
| 2602 | unsigned long v; | 2582 | unsigned long v; |
| 2603 | int i; | ||
| 2604 | struct irq_cfg *cfg; | ||
| 2605 | int do_unmask_irq = 0; | ||
| 2606 | 2583 | ||
| 2607 | irq_complete_move(&desc); | 2584 | irq_complete_move(cfg); |
| 2608 | #ifdef CONFIG_GENERIC_PENDING_IRQ | 2585 | #ifdef CONFIG_GENERIC_PENDING_IRQ |
| 2609 | /* If we are moving the irq we need to mask it */ | 2586 | /* If we are moving the irq we need to mask it */ |
| 2610 | if (unlikely(desc->status & IRQ_MOVE_PENDING)) { | 2587 | if (unlikely(desc->status & IRQ_MOVE_PENDING)) { |
| 2611 | do_unmask_irq = 1; | 2588 | do_unmask_irq = 1; |
| 2612 | mask_IO_APIC_irq_desc(desc); | 2589 | mask_ioapic(cfg); |
| 2613 | } | 2590 | } |
| 2614 | #endif | 2591 | #endif |
| 2615 | 2592 | ||
| @@ -2645,7 +2622,6 @@ static void ack_apic_level(unsigned int irq) | |||
| 2645 | * we use the above logic (mask+edge followed by unmask+level) from | 2622 | * we use the above logic (mask+edge followed by unmask+level) from |
| 2646 | * Manfred Spraul to clear the remote IRR. | 2623 | * Manfred Spraul to clear the remote IRR. |
| 2647 | */ | 2624 | */ |
| 2648 | cfg = get_irq_desc_chip_data(desc); | ||
| 2649 | i = cfg->vector; | 2625 | i = cfg->vector; |
| 2650 | v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1)); | 2626 | v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1)); |
| 2651 | 2627 | ||
| @@ -2665,7 +2641,7 @@ static void ack_apic_level(unsigned int irq) | |||
| 2665 | if (!(v & (1 << (i & 0x1f)))) { | 2641 | if (!(v & (1 << (i & 0x1f)))) { |
| 2666 | atomic_inc(&irq_mis_count); | 2642 | atomic_inc(&irq_mis_count); |
| 2667 | 2643 | ||
| 2668 | eoi_ioapic_irq(desc); | 2644 | eoi_ioapic_irq(irq, cfg); |
| 2669 | } | 2645 | } |
| 2670 | 2646 | ||
| 2671 | /* Now we can move and renable the irq */ | 2647 | /* Now we can move and renable the irq */ |
| @@ -2696,10 +2672,9 @@ static void ack_apic_level(unsigned int irq) | |||
| 2696 | * accurate and is causing problems then it is a hardware bug | 2672 | * accurate and is causing problems then it is a hardware bug |
| 2697 | * and you can go talk to the chipset vendor about it. | 2673 | * and you can go talk to the chipset vendor about it. |
| 2698 | */ | 2674 | */ |
| 2699 | cfg = get_irq_desc_chip_data(desc); | ||
| 2700 | if (!io_apic_level_ack_pending(cfg)) | 2675 | if (!io_apic_level_ack_pending(cfg)) |
| 2701 | move_masked_irq(irq); | 2676 | move_masked_irq(irq); |
| 2702 | unmask_IO_APIC_irq_desc(desc); | 2677 | unmask_ioapic(cfg); |
| 2703 | } | 2678 | } |
| 2704 | } | 2679 | } |
| 2705 | 2680 | ||
| @@ -2711,18 +2686,18 @@ static void ir_ack_apic_edge(unsigned int irq) | |||
| 2711 | 2686 | ||
| 2712 | static void ir_ack_apic_level(unsigned int irq) | 2687 | static void ir_ack_apic_level(unsigned int irq) |
| 2713 | { | 2688 | { |
| 2714 | struct irq_desc *desc = irq_to_desc(irq); | 2689 | struct irq_cfg *cfg = get_irq_chip_data(irq); |
| 2715 | 2690 | ||
| 2716 | ack_APIC_irq(); | 2691 | ack_APIC_irq(); |
| 2717 | eoi_ioapic_irq(desc); | 2692 | eoi_ioapic_irq(irq, cfg); |
| 2718 | } | 2693 | } |
| 2719 | #endif /* CONFIG_INTR_REMAP */ | 2694 | #endif /* CONFIG_INTR_REMAP */ |
| 2720 | 2695 | ||
| 2721 | static struct irq_chip ioapic_chip __read_mostly = { | 2696 | static struct irq_chip ioapic_chip __read_mostly = { |
| 2722 | .name = "IO-APIC", | 2697 | .name = "IO-APIC", |
| 2723 | .startup = startup_ioapic_irq, | 2698 | .startup = startup_ioapic_irq, |
| 2724 | .mask = mask_IO_APIC_irq, | 2699 | .mask = mask_ioapic_irq, |
| 2725 | .unmask = unmask_IO_APIC_irq, | 2700 | .unmask = unmask_ioapic_irq, |
| 2726 | .ack = ack_apic_edge, | 2701 | .ack = ack_apic_edge, |
| 2727 | .eoi = ack_apic_level, | 2702 | .eoi = ack_apic_level, |
| 2728 | #ifdef CONFIG_SMP | 2703 | #ifdef CONFIG_SMP |
| @@ -2734,8 +2709,8 @@ static struct irq_chip ioapic_chip __read_mostly = { | |||
| 2734 | static struct irq_chip ir_ioapic_chip __read_mostly = { | 2709 | static struct irq_chip ir_ioapic_chip __read_mostly = { |
| 2735 | .name = "IR-IO-APIC", | 2710 | .name = "IR-IO-APIC", |
| 2736 | .startup = startup_ioapic_irq, | 2711 | .startup = startup_ioapic_irq, |
| 2737 | .mask = mask_IO_APIC_irq, | 2712 | .mask = mask_ioapic_irq, |
| 2738 | .unmask = unmask_IO_APIC_irq, | 2713 | .unmask = unmask_ioapic_irq, |
| 2739 | #ifdef CONFIG_INTR_REMAP | 2714 | #ifdef CONFIG_INTR_REMAP |
| 2740 | .ack = ir_ack_apic_edge, | 2715 | .ack = ir_ack_apic_edge, |
| 2741 | .eoi = ir_ack_apic_level, | 2716 | .eoi = ir_ack_apic_level, |
| @@ -2996,7 +2971,7 @@ static inline void __init check_timer(void) | |||
| 2996 | int idx; | 2971 | int idx; |
| 2997 | idx = find_irq_entry(apic1, pin1, mp_INT); | 2972 | idx = find_irq_entry(apic1, pin1, mp_INT); |
| 2998 | if (idx != -1 && irq_trigger(idx)) | 2973 | if (idx != -1 && irq_trigger(idx)) |
| 2999 | unmask_IO_APIC_irq_desc(desc); | 2974 | unmask_ioapic(cfg); |
| 3000 | } | 2975 | } |
| 3001 | if (timer_irq_works()) { | 2976 | if (timer_irq_works()) { |
| 3002 | if (nmi_watchdog == NMI_IO_APIC) { | 2977 | if (nmi_watchdog == NMI_IO_APIC) { |
