diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2007-02-23 06:19:08 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-26 13:34:07 -0500 |
commit | a8c8a36736c00b261fd5dd01400c41726f2f19eb (patch) | |
tree | 8b84efce27ce09fe5c9bc9d0613ace3ed9d90c5a /arch | |
parent | a27bc06dd8ee6ad6394e8a76345660b93621b51b (diff) |
[PATCH] x86_64 irq: Refactor setup_IO_APIC_irq
Currently we have two routines that do practically the same thing
setup_IO_APIC_irq and io_apic_set_pci_routing. This patch makes
setup_IO_APIC_irq the common factor of these two previous routines.
For setup_IO_APIC_irq all that was needed was to pass the trigger
and polarity to make the code a proper subset of io_apic_set_pci_routing.
Hopefully consolidating these two routines will improve maintenance
there were several differences that simply appear to be one routine
or the other getting it wrong.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86_64/kernel/io_apic.c | 126 |
1 files changed, 34 insertions, 92 deletions
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index a69c38b62629..e0648380fdde 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c | |||
@@ -615,22 +615,6 @@ static int pin_2_irq(int idx, int apic, int pin) | |||
615 | return irq; | 615 | return irq; |
616 | } | 616 | } |
617 | 617 | ||
618 | static inline int IO_APIC_irq_trigger(int irq) | ||
619 | { | ||
620 | int apic, idx, pin; | ||
621 | |||
622 | for (apic = 0; apic < nr_ioapics; apic++) { | ||
623 | for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { | ||
624 | idx = find_irq_entry(apic,pin,mp_INT); | ||
625 | if ((idx != -1) && (irq == pin_2_irq(idx,apic,pin))) | ||
626 | return irq_trigger(idx); | ||
627 | } | ||
628 | } | ||
629 | /* | ||
630 | * nonexistent IRQs are edge default | ||
631 | */ | ||
632 | return 0; | ||
633 | } | ||
634 | 618 | ||
635 | /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */ | 619 | /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */ |
636 | static u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { | 620 | static u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { |
@@ -795,26 +779,36 @@ void __setup_vector_irq(int cpu) | |||
795 | 779 | ||
796 | static struct irq_chip ioapic_chip; | 780 | static struct irq_chip ioapic_chip; |
797 | 781 | ||
798 | #define IOAPIC_AUTO -1 | ||
799 | #define IOAPIC_EDGE 0 | ||
800 | #define IOAPIC_LEVEL 1 | ||
801 | |||
802 | static void ioapic_register_intr(int irq, unsigned long trigger) | 782 | static void ioapic_register_intr(int irq, unsigned long trigger) |
803 | { | 783 | { |
804 | if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || | 784 | if (trigger) |
805 | trigger == IOAPIC_LEVEL) | ||
806 | set_irq_chip_and_handler_name(irq, &ioapic_chip, | 785 | set_irq_chip_and_handler_name(irq, &ioapic_chip, |
807 | handle_fasteoi_irq, "fasteoi"); | 786 | handle_fasteoi_irq, "fasteoi"); |
808 | else | 787 | else |
809 | set_irq_chip_and_handler_name(irq, &ioapic_chip, | 788 | set_irq_chip_and_handler_name(irq, &ioapic_chip, |
810 | handle_edge_irq, "edge"); | 789 | handle_edge_irq, "edge"); |
811 | } | 790 | } |
812 | static void __init setup_IO_APIC_irq(int apic, int pin, int idx, int irq) | 791 | |
792 | static void setup_IO_APIC_irq(int apic, int pin, unsigned int irq, | ||
793 | int trigger, int polarity) | ||
813 | { | 794 | { |
814 | struct IO_APIC_route_entry entry; | 795 | struct IO_APIC_route_entry entry; |
796 | cpumask_t mask; | ||
815 | int vector; | 797 | int vector; |
816 | unsigned long flags; | 798 | unsigned long flags; |
817 | 799 | ||
800 | if (!IO_APIC_IRQ(irq)) | ||
801 | return; | ||
802 | |||
803 | vector = assign_irq_vector(irq, TARGET_CPUS, &mask); | ||
804 | if (vector < 0) | ||
805 | return; | ||
806 | |||
807 | apic_printk(APIC_VERBOSE,KERN_DEBUG | ||
808 | "IOAPIC[%d]: Set routing entry (%d-%d -> 0x%x -> " | ||
809 | "IRQ %d Mode:%i Active:%i)\n", | ||
810 | apic, mp_ioapics[apic].mpc_apicid, pin, vector, | ||
811 | irq, trigger, polarity); | ||
818 | 812 | ||
819 | /* | 813 | /* |
820 | * add it to the IO-APIC irq-routing table: | 814 | * add it to the IO-APIC irq-routing table: |
@@ -823,41 +817,27 @@ static void __init setup_IO_APIC_irq(int apic, int pin, int idx, int irq) | |||
823 | 817 | ||
824 | entry.delivery_mode = INT_DELIVERY_MODE; | 818 | entry.delivery_mode = INT_DELIVERY_MODE; |
825 | entry.dest_mode = INT_DEST_MODE; | 819 | entry.dest_mode = INT_DEST_MODE; |
820 | entry.dest = cpu_mask_to_apicid(mask); | ||
826 | entry.mask = 0; /* enable IRQ */ | 821 | entry.mask = 0; /* enable IRQ */ |
827 | entry.dest = cpu_mask_to_apicid(TARGET_CPUS); | 822 | entry.trigger = trigger; |
828 | 823 | entry.polarity = polarity; | |
829 | entry.trigger = irq_trigger(idx); | 824 | entry.vector = vector; |
830 | entry.polarity = irq_polarity(idx); | ||
831 | 825 | ||
832 | if (irq_trigger(idx)) { | 826 | /* Mask level triggered irqs. |
833 | entry.trigger = 1; | 827 | * Use IRQ_DELAYED_DISABLE for edge triggered irqs. |
828 | */ | ||
829 | if (trigger) | ||
834 | entry.mask = 1; | 830 | entry.mask = 1; |
835 | entry.dest = cpu_mask_to_apicid(TARGET_CPUS); | ||
836 | } | ||
837 | |||
838 | if (!apic && !IO_APIC_IRQ(irq)) | ||
839 | return; | ||
840 | 831 | ||
841 | if (IO_APIC_IRQ(irq)) { | 832 | ioapic_register_intr(irq, trigger); |
842 | cpumask_t mask; | 833 | if (irq < 16) |
843 | vector = assign_irq_vector(irq, TARGET_CPUS, &mask); | 834 | disable_8259A_irq(irq); |
844 | if (vector < 0) | ||
845 | return; | ||
846 | |||
847 | entry.dest = cpu_mask_to_apicid(mask); | ||
848 | entry.vector = vector; | ||
849 | |||
850 | ioapic_register_intr(irq, IOAPIC_AUTO); | ||
851 | if (!apic && (irq < 16)) | ||
852 | disable_8259A_irq(irq); | ||
853 | } | ||
854 | 835 | ||
855 | ioapic_write_entry(apic, pin, entry); | 836 | ioapic_write_entry(apic, pin, entry); |
856 | 837 | ||
857 | spin_lock_irqsave(&ioapic_lock, flags); | 838 | spin_lock_irqsave(&ioapic_lock, flags); |
858 | irq_desc[irq].affinity = TARGET_CPUS; | 839 | irq_desc[irq].affinity = TARGET_CPUS; |
859 | spin_unlock_irqrestore(&ioapic_lock, flags); | 840 | spin_unlock_irqrestore(&ioapic_lock, flags); |
860 | |||
861 | } | 841 | } |
862 | 842 | ||
863 | static void __init setup_IO_APIC_irqs(void) | 843 | static void __init setup_IO_APIC_irqs(void) |
@@ -882,8 +862,8 @@ static void __init setup_IO_APIC_irqs(void) | |||
882 | irq = pin_2_irq(idx, apic, pin); | 862 | irq = pin_2_irq(idx, apic, pin); |
883 | add_pin_to_irq(irq, apic, pin); | 863 | add_pin_to_irq(irq, apic, pin); |
884 | 864 | ||
885 | setup_IO_APIC_irq(apic, pin, idx, irq); | 865 | setup_IO_APIC_irq(apic, pin, irq, |
886 | 866 | irq_trigger(idx), irq_polarity(idx)); | |
887 | } | 867 | } |
888 | } | 868 | } |
889 | 869 | ||
@@ -2090,11 +2070,6 @@ int __init io_apic_get_redir_entries (int ioapic) | |||
2090 | 2070 | ||
2091 | int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int polarity) | 2071 | int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int polarity) |
2092 | { | 2072 | { |
2093 | struct IO_APIC_route_entry entry; | ||
2094 | unsigned long flags; | ||
2095 | int vector; | ||
2096 | cpumask_t mask; | ||
2097 | |||
2098 | if (!IO_APIC_IRQ(irq)) { | 2073 | if (!IO_APIC_IRQ(irq)) { |
2099 | apic_printk(APIC_QUIET,KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n", | 2074 | apic_printk(APIC_QUIET,KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n", |
2100 | ioapic); | 2075 | ioapic); |
@@ -2107,42 +2082,7 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int p | |||
2107 | if (irq >= 16) | 2082 | if (irq >= 16) |
2108 | add_pin_to_irq(irq, ioapic, pin); | 2083 | add_pin_to_irq(irq, ioapic, pin); |
2109 | 2084 | ||
2110 | 2085 | setup_IO_APIC_irq(ioapic, pin, irq, triggering, polarity); | |
2111 | vector = assign_irq_vector(irq, TARGET_CPUS, &mask); | ||
2112 | if (vector < 0) | ||
2113 | return vector; | ||
2114 | |||
2115 | /* | ||
2116 | * Generate a PCI IRQ routing entry and program the IOAPIC accordingly. | ||
2117 | * Note that we mask (disable) IRQs now -- these get enabled when the | ||
2118 | * corresponding device driver registers for this IRQ. | ||
2119 | */ | ||
2120 | |||
2121 | memset(&entry,0,sizeof(entry)); | ||
2122 | |||
2123 | entry.delivery_mode = INT_DELIVERY_MODE; | ||
2124 | entry.dest_mode = INT_DEST_MODE; | ||
2125 | entry.dest = cpu_mask_to_apicid(mask); | ||
2126 | entry.trigger = triggering; | ||
2127 | entry.polarity = polarity; | ||
2128 | entry.mask = 1; /* Disabled (masked) */ | ||
2129 | entry.vector = vector & 0xff; | ||
2130 | |||
2131 | apic_printk(APIC_VERBOSE,KERN_DEBUG "IOAPIC[%d]: Set PCI routing entry (%d-%d -> 0x%x -> " | ||
2132 | "IRQ %d Mode:%i Active:%i)\n", ioapic, | ||
2133 | mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq, | ||
2134 | triggering, polarity); | ||
2135 | |||
2136 | ioapic_register_intr(irq, triggering); | ||
2137 | |||
2138 | if (!ioapic && (irq < 16)) | ||
2139 | disable_8259A_irq(irq); | ||
2140 | |||
2141 | ioapic_write_entry(ioapic, pin, entry); | ||
2142 | |||
2143 | spin_lock_irqsave(&ioapic_lock, flags); | ||
2144 | irq_desc[irq].affinity = TARGET_CPUS; | ||
2145 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
2146 | 2086 | ||
2147 | return 0; | 2087 | return 0; |
2148 | } | 2088 | } |
@@ -2175,7 +2115,9 @@ void __init setup_ioapic_dest(void) | |||
2175 | * cpu is online. | 2115 | * cpu is online. |
2176 | */ | 2116 | */ |
2177 | if(!irq_vector[irq]) | 2117 | if(!irq_vector[irq]) |
2178 | setup_IO_APIC_irq(ioapic, pin, irq_entry, irq); | 2118 | setup_IO_APIC_irq(ioapic, pin, irq, |
2119 | irq_trigger(irq_entry), | ||
2120 | irq_polarity(irq_entry)); | ||
2179 | else | 2121 | else |
2180 | set_ioapic_affinity_irq(irq, TARGET_CPUS); | 2122 | set_ioapic_affinity_irq(irq, TARGET_CPUS); |
2181 | } | 2123 | } |