aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/io_apic_32.c
diff options
context:
space:
mode:
authorYinghai Lu <yhlu.kernel@gmail.com>2008-08-19 23:50:41 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-16 10:52:55 -0400
commit047c8fdb8718890e3340073b178d0859d0c7f91f (patch)
tree12386f7d380da5212d720d7a2d7e9ca1c64473bb /arch/x86/kernel/io_apic_32.c
parentaa45f97b1bb40adae1288669e73350907ffae85e (diff)
x86: make io_apic_64.c and io_apic_32.c the same
all the same except INTR_REMAPPING related and ioapic io resource. Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/io_apic_32.c')
-rw-r--r--arch/x86/kernel/io_apic_32.c213
1 files changed, 199 insertions, 14 deletions
diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c
index 48184e126f2..3ed36041c81 100644
--- a/arch/x86/kernel/io_apic_32.c
+++ b/arch/x86/kernel/io_apic_32.c
@@ -123,7 +123,6 @@ struct irq_cfg {
123 u8 move_in_progress : 1; 123 u8 move_in_progress : 1;
124}; 124};
125 125
126
127/* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */ 126/* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */
128static struct irq_cfg irq_cfg_legacy[] __initdata = { 127static struct irq_cfg irq_cfg_legacy[] __initdata = {
129 [0] = { .irq = 0, .domain = CPU_MASK_ALL, .vector = IRQ0_VECTOR, }, 128 [0] = { .irq = 0, .domain = CPU_MASK_ALL, .vector = IRQ0_VECTOR, },
@@ -391,6 +390,38 @@ static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned
391 writel(value, &io_apic->data); 390 writel(value, &io_apic->data);
392} 391}
393 392
393#ifdef CONFIG_X86_64
394static bool io_apic_level_ack_pending(unsigned int irq)
395{
396 struct irq_pin_list *entry;
397 unsigned long flags;
398 struct irq_cfg *cfg = irq_cfg(irq);
399
400 spin_lock_irqsave(&ioapic_lock, flags);
401 entry = cfg->irq_2_pin;
402 for (;;) {
403 unsigned int reg;
404 int pin;
405
406 if (!entry)
407 break;
408 pin = entry->pin;
409 reg = io_apic_read(entry->apic, 0x10 + pin*2);
410 /* Is the remote IRR bit set? */
411 if (reg & IO_APIC_REDIR_REMOTE_IRR) {
412 spin_unlock_irqrestore(&ioapic_lock, flags);
413 return true;
414 }
415 if (!entry->next)
416 break;
417 entry = entry->next;
418 }
419 spin_unlock_irqrestore(&ioapic_lock, flags);
420
421 return false;
422}
423#endif
424
394union entry_union { 425union entry_union {
395 struct { u32 w1, w2; }; 426 struct { u32 w1, w2; };
396 struct IO_APIC_route_entry entry; 427 struct IO_APIC_route_entry entry;
@@ -483,17 +514,15 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask)
483 unsigned int dest; 514 unsigned int dest;
484 cpumask_t tmp; 515 cpumask_t tmp;
485 516
486 cfg = irq_cfg(irq);
487
488 cpus_and(tmp, mask, cpu_online_map); 517 cpus_and(tmp, mask, cpu_online_map);
489 if (cpus_empty(tmp)) 518 if (cpus_empty(tmp))
490 return; 519 return;
491 520
521 cfg = irq_cfg(irq);
492 if (assign_irq_vector(irq, mask)) 522 if (assign_irq_vector(irq, mask))
493 return; 523 return;
494 524
495 cpus_and(tmp, cfg->domain, mask); 525 cpus_and(tmp, cfg->domain, mask);
496
497 dest = cpu_mask_to_apicid(tmp); 526 dest = cpu_mask_to_apicid(tmp);
498 /* 527 /*
499 * Only the high 8 bits are valid. 528 * Only the high 8 bits are valid.
@@ -572,6 +601,54 @@ static void __init replace_pin_at_irq(unsigned int irq,
572 add_pin_to_irq(irq, newapic, newpin); 601 add_pin_to_irq(irq, newapic, newpin);
573} 602}
574 603
604#ifdef CONFIG_X86_64
605/*
606 * Synchronize the IO-APIC and the CPU by doing
607 * a dummy read from the IO-APIC
608 */
609static inline void io_apic_sync(unsigned int apic)
610{
611 struct io_apic __iomem *io_apic = io_apic_base(apic);
612 readl(&io_apic->data);
613}
614
615#define __DO_ACTION(R, ACTION, FINAL) \
616 \
617{ \
618 int pin; \
619 struct irq_cfg *cfg; \
620 struct irq_pin_list *entry; \
621 \
622 cfg = irq_cfg(irq); \
623 entry = cfg->irq_2_pin; \
624 for (;;) { \
625 unsigned int reg; \
626 if (!entry) \
627 break; \
628 pin = entry->pin; \
629 reg = io_apic_read(entry->apic, 0x10 + R + pin*2); \
630 reg ACTION; \
631 io_apic_modify(entry->apic, 0x10 + R + pin*2, reg); \
632 FINAL; \
633 if (!entry->next) \
634 break; \
635 entry = entry->next; \
636 } \
637}
638
639#define DO_ACTION(name,R,ACTION, FINAL) \
640 \
641 static void name##_IO_APIC_irq (unsigned int irq) \
642 __DO_ACTION(R, ACTION, FINAL)
643
644/* mask = 1 */
645DO_ACTION(__mask, 0, |= IO_APIC_REDIR_MASKED, io_apic_sync(entry->apic))
646
647/* mask = 0 */
648DO_ACTION(__unmask, 0, &= ~IO_APIC_REDIR_MASKED, )
649
650#else
651
575static void __modify_IO_APIC_irq(unsigned int irq, unsigned long enable, unsigned long disable) 652static void __modify_IO_APIC_irq(unsigned int irq, unsigned long enable, unsigned long disable)
576{ 653{
577 struct irq_cfg *cfg; 654 struct irq_cfg *cfg;
@@ -620,6 +697,8 @@ static void __unmask_and_level_IO_APIC_irq(unsigned int irq)
620 IO_APIC_REDIR_MASKED); 697 IO_APIC_REDIR_MASKED);
621} 698}
622 699
700#endif
701
623static void mask_IO_APIC_irq(unsigned int irq) 702static void mask_IO_APIC_irq(unsigned int irq)
624{ 703{
625 unsigned long flags; 704 unsigned long flags;
@@ -1055,6 +1134,17 @@ void unlock_vector_lock(void)
1055 1134
1056static int __assign_irq_vector(int irq, cpumask_t mask) 1135static int __assign_irq_vector(int irq, cpumask_t mask)
1057{ 1136{
1137 /*
1138 * NOTE! The local APIC isn't very good at handling
1139 * multiple interrupts at the same interrupt level.
1140 * As the interrupt level is determined by taking the
1141 * vector number and shifting that right by 4, we
1142 * want to spread these out a bit so that they don't
1143 * all fall in the same interrupt level.
1144 *
1145 * Also, we've got to be careful not to trash gate
1146 * 0x80, because int 0x80 is hm, kind of importantish. ;)
1147 */
1058 static int current_vector = FIRST_DEVICE_VECTOR, current_offset = 0; 1148 static int current_vector = FIRST_DEVICE_VECTOR, current_offset = 0;
1059 unsigned int old_vector; 1149 unsigned int old_vector;
1060 int cpu; 1150 int cpu;
@@ -1095,9 +1185,13 @@ next:
1095 } 1185 }
1096 if (unlikely(current_vector == vector)) 1186 if (unlikely(current_vector == vector))
1097 continue; 1187 continue;
1098 if (vector == SYSCALL_VECTOR) 1188#ifdef CONFIG_X86_64
1189 if (vector == IA32_SYSCALL_VECTOR)
1099 goto next; 1190 goto next;
1100 1191#else
1192 if (vector == SYSCALL_VECTOR)
1193 goto next;
1194#endif
1101 for_each_cpu_mask_nr(new_cpu, new_mask) 1195 for_each_cpu_mask_nr(new_cpu, new_mask)
1102 if (per_cpu(vector_irq, new_cpu)[vector] != -1) 1196 if (per_cpu(vector_irq, new_cpu)[vector] != -1)
1103 goto next; 1197 goto next;
@@ -1184,6 +1278,7 @@ static struct irq_chip ioapic_chip;
1184#define IOAPIC_EDGE 0 1278#define IOAPIC_EDGE 0
1185#define IOAPIC_LEVEL 1 1279#define IOAPIC_LEVEL 1
1186 1280
1281#ifdef CONFIG_X86_32
1187static inline int IO_APIC_irq_trigger(int irq) 1282static inline int IO_APIC_irq_trigger(int irq)
1188{ 1283{
1189 int apic, idx, pin; 1284 int apic, idx, pin;
@@ -1200,6 +1295,12 @@ static inline int IO_APIC_irq_trigger(int irq)
1200 */ 1295 */
1201 return 0; 1296 return 0;
1202} 1297}
1298#else
1299static inline int IO_APIC_irq_trigger(int irq)
1300{
1301 return 1;
1302}
1303#endif
1203 1304
1204static void ioapic_register_intr(int irq, unsigned long trigger) 1305static void ioapic_register_intr(int irq, unsigned long trigger)
1205{ 1306{
@@ -1212,15 +1313,18 @@ static void ioapic_register_intr(int irq, unsigned long trigger)
1212 desc = irq_to_desc_alloc(irq); 1313 desc = irq_to_desc_alloc(irq);
1213 1314
1214 if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || 1315 if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
1215 trigger == IOAPIC_LEVEL) { 1316 trigger == IOAPIC_LEVEL)
1216 desc->status |= IRQ_LEVEL; 1317 desc->status |= IRQ_LEVEL;
1318 else
1319 desc->status &= ~IRQ_LEVEL;
1320
1321 if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
1322 trigger == IOAPIC_LEVEL)
1217 set_irq_chip_and_handler_name(irq, &ioapic_chip, 1323 set_irq_chip_and_handler_name(irq, &ioapic_chip,
1218 handle_fasteoi_irq, "fasteoi"); 1324 handle_fasteoi_irq, "fasteoi");
1219 } else { 1325 else
1220 desc->status &= ~IRQ_LEVEL;
1221 set_irq_chip_and_handler_name(irq, &ioapic_chip, 1326 set_irq_chip_and_handler_name(irq, &ioapic_chip,
1222 handle_edge_irq, "edge"); 1327 handle_edge_irq, "edge");
1223 }
1224} 1328}
1225 1329
1226static int setup_ioapic_entry(int apic, int irq, 1330static int setup_ioapic_entry(int apic, int irq,
@@ -1662,7 +1766,6 @@ static void __init enable_IO_APIC(void)
1662 struct IO_APIC_route_entry entry; 1766 struct IO_APIC_route_entry entry;
1663 entry = ioapic_read_entry(apic, pin); 1767 entry = ioapic_read_entry(apic, pin);
1664 1768
1665
1666 /* If the interrupt line is enabled and in ExtInt mode 1769 /* If the interrupt line is enabled and in ExtInt mode
1667 * I have found the pin where the i8259 is connected. 1770 * I have found the pin where the i8259 is connected.
1668 */ 1771 */
@@ -2012,6 +2115,60 @@ static void ack_apic_edge(unsigned int irq)
2012 ack_APIC_irq(); 2115 ack_APIC_irq();
2013} 2116}
2014 2117
2118#ifdef CONFIG_X86_64
2119static void ack_apic_level(unsigned int irq)
2120{
2121 int do_unmask_irq = 0;
2122
2123 irq_complete_move(irq);
2124#ifdef CONFIG_GENERIC_PENDING_IRQ
2125 /* If we are moving the irq we need to mask it */
2126 if (unlikely(desc->status & IRQ_MOVE_PENDING)) {
2127 do_unmask_irq = 1;
2128 mask_IO_APIC_irq(irq);
2129 }
2130#endif
2131
2132 /*
2133 * We must acknowledge the irq before we move it or the acknowledge will
2134 * not propagate properly.
2135 */
2136 ack_APIC_irq();
2137
2138 /* Now we can move and renable the irq */
2139 if (unlikely(do_unmask_irq)) {
2140 /* Only migrate the irq if the ack has been received.
2141 *
2142 * On rare occasions the broadcast level triggered ack gets
2143 * delayed going to ioapics, and if we reprogram the
2144 * vector while Remote IRR is still set the irq will never
2145 * fire again.
2146 *
2147 * To prevent this scenario we read the Remote IRR bit
2148 * of the ioapic. This has two effects.
2149 * - On any sane system the read of the ioapic will
2150 * flush writes (and acks) going to the ioapic from
2151 * this cpu.
2152 * - We get to see if the ACK has actually been delivered.
2153 *
2154 * Based on failed experiments of reprogramming the
2155 * ioapic entry from outside of irq context starting
2156 * with masking the ioapic entry and then polling until
2157 * Remote IRR was clear before reprogramming the
2158 * ioapic I don't trust the Remote IRR bit to be
2159 * completey accurate.
2160 *
2161 * However there appears to be no other way to plug
2162 * this race, so if the Remote IRR bit is not
2163 * accurate and is causing problems then it is a hardware bug
2164 * and you can go talk to the chipset vendor about it.
2165 */
2166 if (!io_apic_level_ack_pending(irq))
2167 move_masked_irq(irq, desc);
2168 unmask_IO_APIC_irq(irq);
2169 }
2170}
2171#else
2015atomic_t irq_mis_count; 2172atomic_t irq_mis_count;
2016static void ack_apic_level(unsigned int irq) 2173static void ack_apic_level(unsigned int irq)
2017{ 2174{
@@ -2053,6 +2210,7 @@ static void ack_apic_level(unsigned int irq)
2053 spin_unlock(&ioapic_lock); 2210 spin_unlock(&ioapic_lock);
2054 } 2211 }
2055} 2212}
2213#endif
2056 2214
2057static struct irq_chip ioapic_chip __read_mostly = { 2215static struct irq_chip ioapic_chip __read_mostly = {
2058 .name = "IO-APIC", 2216 .name = "IO-APIC",
@@ -2224,7 +2382,7 @@ static inline void __init unlock_ExtINT_logic(void)
2224} 2382}
2225 2383
2226static int disable_timer_pin_1 __initdata; 2384static int disable_timer_pin_1 __initdata;
2227 2385/* Actually the next is obsolete, but keep it for paranoid reasons -AK */
2228static int __init parse_disable_timer_pin_1(char *arg) 2386static int __init parse_disable_timer_pin_1(char *arg)
2229{ 2387{
2230 disable_timer_pin_1 = 1; 2388 disable_timer_pin_1 = 1;
@@ -2244,9 +2402,9 @@ static inline void __init check_timer(void)
2244{ 2402{
2245 struct irq_cfg *cfg = irq_cfg(0); 2403 struct irq_cfg *cfg = irq_cfg(0);
2246 int apic1, pin1, apic2, pin2; 2404 int apic1, pin1, apic2, pin2;
2247 int no_pin1 = 0;
2248 unsigned int ver;
2249 unsigned long flags; 2405 unsigned long flags;
2406 unsigned int ver;
2407 int no_pin1 = 0;
2250 2408
2251 local_irq_save(flags); 2409 local_irq_save(flags);
2252 2410
@@ -2550,6 +2708,7 @@ unsigned int create_irq_nr(unsigned int irq_want)
2550 cfg_new = irq_cfg(new); 2708 cfg_new = irq_cfg(new);
2551 if (cfg_new && cfg_new->vector != 0) 2709 if (cfg_new && cfg_new->vector != 0)
2552 continue; 2710 continue;
2711 /* check if need to create one */
2553 if (!cfg_new) 2712 if (!cfg_new)
2554 cfg_new = irq_cfg_alloc(new); 2713 cfg_new = irq_cfg_alloc(new);
2555 if (__assign_irq_vector(new, TARGET_CPUS) == 0) 2714 if (__assign_irq_vector(new, TARGET_CPUS) == 0)
@@ -2720,6 +2879,32 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
2720 return 0; 2879 return 0;
2721} 2880}
2722 2881
2882int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
2883{
2884 unsigned int irq;
2885 int ret, sub_handle;
2886 struct msi_desc *desc;
2887 unsigned int irq_want;
2888
2889 irq_want = build_irq_for_pci_dev(dev) + 0x100;
2890 sub_handle = 0;
2891 list_for_each_entry(desc, &dev->msi_list, list) {
2892 irq = create_irq_nr(irq_want--);
2893 if (irq == 0)
2894 return -1;
2895 ret = setup_msi_irq(dev, desc, irq);
2896 if (ret < 0)
2897 goto error;
2898 sub_handle++;
2899 }
2900 return 0;
2901
2902error:
2903 destroy_irq(irq);
2904 return ret;
2905}
2906
2907
2723void arch_teardown_msi_irq(unsigned int irq) 2908void arch_teardown_msi_irq(unsigned int irq)
2724{ 2909{
2725 destroy_irq(irq); 2910 destroy_irq(irq);