aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/io_apic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/io_apic.c')
-rw-r--r--arch/x86/kernel/io_apic.c80
1 files changed, 21 insertions, 59 deletions
diff --git a/arch/x86/kernel/io_apic.c b/arch/x86/kernel/io_apic.c
index 7e303e0967a4..099696109ca8 100644
--- a/arch/x86/kernel/io_apic.c
+++ b/arch/x86/kernel/io_apic.c
@@ -610,18 +610,7 @@ static void __init replace_pin_at_irq(unsigned int irq,
610 add_pin_to_irq(irq, newapic, newpin); 610 add_pin_to_irq(irq, newapic, newpin);
611} 611}
612 612
613#ifdef CONFIG_X86_64 613#define __DO_ACTION(R, ACTION_ENABLE, ACTION_DISABLE, FINAL) \
614/*
615 * Synchronize the IO-APIC and the CPU by doing
616 * a dummy read from the IO-APIC
617 */
618static inline void io_apic_sync(unsigned int apic)
619{
620 struct io_apic __iomem *io_apic = io_apic_base(apic);
621 readl(&io_apic->data);
622}
623
624#define __DO_ACTION(R, ACTION, FINAL) \
625 \ 614 \
626{ \ 615{ \
627 int pin; \ 616 int pin; \
@@ -636,7 +625,8 @@ static inline void io_apic_sync(unsigned int apic)
636 break; \ 625 break; \
637 pin = entry->pin; \ 626 pin = entry->pin; \
638 reg = io_apic_read(entry->apic, 0x10 + R + pin*2); \ 627 reg = io_apic_read(entry->apic, 0x10 + R + pin*2); \
639 reg ACTION; \ 628 reg ACTION_DISABLE; \
629 reg ACTION_ENABLE; \
640 io_apic_modify(entry->apic, 0x10 + R + pin*2, reg); \ 630 io_apic_modify(entry->apic, 0x10 + R + pin*2, reg); \
641 FINAL; \ 631 FINAL; \
642 if (!entry->next) \ 632 if (!entry->next) \
@@ -645,66 +635,38 @@ static inline void io_apic_sync(unsigned int apic)
645 } \ 635 } \
646} 636}
647 637
648#define DO_ACTION(name,R,ACTION, FINAL) \ 638#define DO_ACTION(name,R, ACTION_ENABLE, ACTION_DISABLE, FINAL) \
649 \ 639 \
650 static void name##_IO_APIC_irq (unsigned int irq) \ 640 static void name##_IO_APIC_irq (unsigned int irq) \
651 __DO_ACTION(R, ACTION, FINAL) 641 __DO_ACTION(R, ACTION_ENABLE, ACTION_DISABLE, FINAL)
652
653/* mask = 1 */
654DO_ACTION(__mask, 0, |= IO_APIC_REDIR_MASKED, io_apic_sync(entry->apic))
655 642
656/* mask = 0 */ 643/* mask = 0 */
657DO_ACTION(__unmask, 0, &= ~IO_APIC_REDIR_MASKED, ) 644DO_ACTION(__unmask, 0, |= 0, &= ~IO_APIC_REDIR_MASKED, )
658 645
659#else 646#ifdef CONFIG_X86_64
660 647/*
661static void __modify_IO_APIC_irq(unsigned int irq, unsigned long enable, unsigned long disable) 648 * Synchronize the IO-APIC and the CPU by doing
649 * a dummy read from the IO-APIC
650 */
651static inline void io_apic_sync(unsigned int apic)
662{ 652{
663 struct irq_cfg *cfg; 653 struct io_apic __iomem *io_apic = io_apic_base(apic);
664 struct irq_pin_list *entry; 654 readl(&io_apic->data);
665 unsigned int pin, reg;
666
667 cfg = irq_cfg(irq);
668 entry = cfg->irq_2_pin;
669 for (;;) {
670 if (!entry)
671 break;
672 pin = entry->pin;
673 reg = io_apic_read(entry->apic, 0x10 + pin*2);
674 reg &= ~disable;
675 reg |= enable;
676 io_apic_modify(entry->apic, 0x10 + pin*2, reg);
677 if (!entry->next)
678 break;
679 entry = entry->next;
680 }
681} 655}
682 656
683/* mask = 1 */ 657/* mask = 1 */
684static void __mask_IO_APIC_irq(unsigned int irq) 658DO_ACTION(__mask, 0, |= IO_APIC_REDIR_MASKED, &= ~0, io_apic_sync(entry->apic))
685{
686 __modify_IO_APIC_irq(irq, IO_APIC_REDIR_MASKED, 0);
687}
688 659
689/* mask = 0 */ 660#else
690static void __unmask_IO_APIC_irq(unsigned int irq) 661
691{ 662/* mask = 1 */
692 __modify_IO_APIC_irq(irq, 0, IO_APIC_REDIR_MASKED); 663DO_ACTION(__mask, 0, |= IO_APIC_REDIR_MASKED, &= ~0, )
693}
694 664
695/* mask = 1, trigger = 0 */ 665/* mask = 1, trigger = 0 */
696static void __mask_and_edge_IO_APIC_irq(unsigned int irq) 666DO_ACTION(__mask_and_edge, 0, |= IO_APIC_REDIR_MASKED, &= ~IO_APIC_REDIR_LEVEL_TRIGGER, )
697{
698 __modify_IO_APIC_irq(irq, IO_APIC_REDIR_MASKED,
699 IO_APIC_REDIR_LEVEL_TRIGGER);
700}
701 667
702/* mask = 0, trigger = 1 */ 668/* mask = 0, trigger = 1 */
703static void __unmask_and_level_IO_APIC_irq(unsigned int irq) 669DO_ACTION(__unmask_and_level, 0, |= IO_APIC_REDIR_LEVEL_TRIGGER, &= ~IO_APIC_REDIR_MASKED, )
704{
705 __modify_IO_APIC_irq(irq, IO_APIC_REDIR_LEVEL_TRIGGER,
706 IO_APIC_REDIR_MASKED);
707}
708 670
709#endif 671#endif
710 672