diff options
Diffstat (limited to 'arch/x86/kernel/io_apic_32.c')
-rw-r--r-- | arch/x86/kernel/io_apic_32.c | 676 |
1 files changed, 369 insertions, 307 deletions
diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c index 4dc8600d9d20..603261a5885c 100644 --- a/arch/x86/kernel/io_apic_32.c +++ b/arch/x86/kernel/io_apic_32.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
27 | #include <linux/sched.h> | 27 | #include <linux/sched.h> |
28 | #include <linux/bootmem.h> | ||
28 | #include <linux/mc146818rtc.h> | 29 | #include <linux/mc146818rtc.h> |
29 | #include <linux/compiler.h> | 30 | #include <linux/compiler.h> |
30 | #include <linux/acpi.h> | 31 | #include <linux/acpi.h> |
@@ -58,7 +59,7 @@ static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; | |||
58 | static DEFINE_SPINLOCK(ioapic_lock); | 59 | static DEFINE_SPINLOCK(ioapic_lock); |
59 | static DEFINE_SPINLOCK(vector_lock); | 60 | static DEFINE_SPINLOCK(vector_lock); |
60 | 61 | ||
61 | int timer_over_8254 __initdata = 1; | 62 | int timer_through_8259 __initdata; |
62 | 63 | ||
63 | /* | 64 | /* |
64 | * Is the SiS APIC rmw bug present ? | 65 | * Is the SiS APIC rmw bug present ? |
@@ -72,15 +73,21 @@ int sis_apic_bug = -1; | |||
72 | int nr_ioapic_registers[MAX_IO_APICS]; | 73 | int nr_ioapic_registers[MAX_IO_APICS]; |
73 | 74 | ||
74 | /* I/O APIC entries */ | 75 | /* I/O APIC entries */ |
75 | struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS]; | 76 | struct mp_config_ioapic mp_ioapics[MAX_IO_APICS]; |
76 | int nr_ioapics; | 77 | int nr_ioapics; |
77 | 78 | ||
78 | /* MP IRQ source entries */ | 79 | /* MP IRQ source entries */ |
79 | struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES]; | 80 | struct mp_config_intsrc mp_irqs[MAX_IRQ_SOURCES]; |
80 | 81 | ||
81 | /* # of MP IRQ source entries */ | 82 | /* # of MP IRQ source entries */ |
82 | int mp_irq_entries; | 83 | int mp_irq_entries; |
83 | 84 | ||
85 | #if defined (CONFIG_MCA) || defined (CONFIG_EISA) | ||
86 | int mp_bus_id_to_type[MAX_MP_BUSSES]; | ||
87 | #endif | ||
88 | |||
89 | DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES); | ||
90 | |||
84 | static int disable_timer_pin_1 __initdata; | 91 | static int disable_timer_pin_1 __initdata; |
85 | 92 | ||
86 | /* | 93 | /* |
@@ -110,7 +117,7 @@ struct io_apic { | |||
110 | static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx) | 117 | static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx) |
111 | { | 118 | { |
112 | return (void __iomem *) __fix_to_virt(FIX_IO_APIC_BASE_0 + idx) | 119 | return (void __iomem *) __fix_to_virt(FIX_IO_APIC_BASE_0 + idx) |
113 | + (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK); | 120 | + (mp_ioapics[idx].mp_apicaddr & ~PAGE_MASK); |
114 | } | 121 | } |
115 | 122 | ||
116 | static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg) | 123 | static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg) |
@@ -239,7 +246,7 @@ static void __init replace_pin_at_irq(unsigned int irq, | |||
239 | } | 246 | } |
240 | } | 247 | } |
241 | 248 | ||
242 | static void __modify_IO_APIC_irq (unsigned int irq, unsigned long enable, unsigned long disable) | 249 | static void __modify_IO_APIC_irq(unsigned int irq, unsigned long enable, unsigned long disable) |
243 | { | 250 | { |
244 | struct irq_pin_list *entry = irq_2_pin + irq; | 251 | struct irq_pin_list *entry = irq_2_pin + irq; |
245 | unsigned int pin, reg; | 252 | unsigned int pin, reg; |
@@ -259,30 +266,32 @@ static void __modify_IO_APIC_irq (unsigned int irq, unsigned long enable, unsign | |||
259 | } | 266 | } |
260 | 267 | ||
261 | /* mask = 1 */ | 268 | /* mask = 1 */ |
262 | static void __mask_IO_APIC_irq (unsigned int irq) | 269 | static void __mask_IO_APIC_irq(unsigned int irq) |
263 | { | 270 | { |
264 | __modify_IO_APIC_irq(irq, 0x00010000, 0); | 271 | __modify_IO_APIC_irq(irq, IO_APIC_REDIR_MASKED, 0); |
265 | } | 272 | } |
266 | 273 | ||
267 | /* mask = 0 */ | 274 | /* mask = 0 */ |
268 | static void __unmask_IO_APIC_irq (unsigned int irq) | 275 | static void __unmask_IO_APIC_irq(unsigned int irq) |
269 | { | 276 | { |
270 | __modify_IO_APIC_irq(irq, 0, 0x00010000); | 277 | __modify_IO_APIC_irq(irq, 0, IO_APIC_REDIR_MASKED); |
271 | } | 278 | } |
272 | 279 | ||
273 | /* mask = 1, trigger = 0 */ | 280 | /* mask = 1, trigger = 0 */ |
274 | static void __mask_and_edge_IO_APIC_irq (unsigned int irq) | 281 | static void __mask_and_edge_IO_APIC_irq(unsigned int irq) |
275 | { | 282 | { |
276 | __modify_IO_APIC_irq(irq, 0x00010000, 0x00008000); | 283 | __modify_IO_APIC_irq(irq, IO_APIC_REDIR_MASKED, |
284 | IO_APIC_REDIR_LEVEL_TRIGGER); | ||
277 | } | 285 | } |
278 | 286 | ||
279 | /* mask = 0, trigger = 1 */ | 287 | /* mask = 0, trigger = 1 */ |
280 | static void __unmask_and_level_IO_APIC_irq (unsigned int irq) | 288 | static void __unmask_and_level_IO_APIC_irq(unsigned int irq) |
281 | { | 289 | { |
282 | __modify_IO_APIC_irq(irq, 0x00008000, 0x00010000); | 290 | __modify_IO_APIC_irq(irq, IO_APIC_REDIR_LEVEL_TRIGGER, |
291 | IO_APIC_REDIR_MASKED); | ||
283 | } | 292 | } |
284 | 293 | ||
285 | static void mask_IO_APIC_irq (unsigned int irq) | 294 | static void mask_IO_APIC_irq(unsigned int irq) |
286 | { | 295 | { |
287 | unsigned long flags; | 296 | unsigned long flags; |
288 | 297 | ||
@@ -291,7 +300,7 @@ static void mask_IO_APIC_irq (unsigned int irq) | |||
291 | spin_unlock_irqrestore(&ioapic_lock, flags); | 300 | spin_unlock_irqrestore(&ioapic_lock, flags); |
292 | } | 301 | } |
293 | 302 | ||
294 | static void unmask_IO_APIC_irq (unsigned int irq) | 303 | static void unmask_IO_APIC_irq(unsigned int irq) |
295 | { | 304 | { |
296 | unsigned long flags; | 305 | unsigned long flags; |
297 | 306 | ||
@@ -303,7 +312,7 @@ static void unmask_IO_APIC_irq (unsigned int irq) | |||
303 | static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) | 312 | static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) |
304 | { | 313 | { |
305 | struct IO_APIC_route_entry entry; | 314 | struct IO_APIC_route_entry entry; |
306 | 315 | ||
307 | /* Check delivery_mode to be sure we're not clearing an SMI pin */ | 316 | /* Check delivery_mode to be sure we're not clearing an SMI pin */ |
308 | entry = ioapic_read_entry(apic, pin); | 317 | entry = ioapic_read_entry(apic, pin); |
309 | if (entry.delivery_mode == dest_SMI) | 318 | if (entry.delivery_mode == dest_SMI) |
@@ -315,7 +324,7 @@ static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) | |||
315 | ioapic_mask_entry(apic, pin); | 324 | ioapic_mask_entry(apic, pin); |
316 | } | 325 | } |
317 | 326 | ||
318 | static void clear_IO_APIC (void) | 327 | static void clear_IO_APIC(void) |
319 | { | 328 | { |
320 | int apic, pin; | 329 | int apic, pin; |
321 | 330 | ||
@@ -332,7 +341,7 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask) | |||
332 | struct irq_pin_list *entry = irq_2_pin + irq; | 341 | struct irq_pin_list *entry = irq_2_pin + irq; |
333 | unsigned int apicid_value; | 342 | unsigned int apicid_value; |
334 | cpumask_t tmp; | 343 | cpumask_t tmp; |
335 | 344 | ||
336 | cpus_and(tmp, cpumask, cpu_online_map); | 345 | cpus_and(tmp, cpumask, cpu_online_map); |
337 | if (cpus_empty(tmp)) | 346 | if (cpus_empty(tmp)) |
338 | tmp = TARGET_CPUS; | 347 | tmp = TARGET_CPUS; |
@@ -361,7 +370,7 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask) | |||
361 | # include <linux/kernel_stat.h> /* kstat */ | 370 | # include <linux/kernel_stat.h> /* kstat */ |
362 | # include <linux/slab.h> /* kmalloc() */ | 371 | # include <linux/slab.h> /* kmalloc() */ |
363 | # include <linux/timer.h> | 372 | # include <linux/timer.h> |
364 | 373 | ||
365 | #define IRQBALANCE_CHECK_ARCH -999 | 374 | #define IRQBALANCE_CHECK_ARCH -999 |
366 | #define MAX_BALANCED_IRQ_INTERVAL (5*HZ) | 375 | #define MAX_BALANCED_IRQ_INTERVAL (5*HZ) |
367 | #define MIN_BALANCED_IRQ_INTERVAL (HZ/2) | 376 | #define MIN_BALANCED_IRQ_INTERVAL (HZ/2) |
@@ -373,14 +382,14 @@ static int physical_balance __read_mostly; | |||
373 | static long balanced_irq_interval __read_mostly = MAX_BALANCED_IRQ_INTERVAL; | 382 | static long balanced_irq_interval __read_mostly = MAX_BALANCED_IRQ_INTERVAL; |
374 | 383 | ||
375 | static struct irq_cpu_info { | 384 | static struct irq_cpu_info { |
376 | unsigned long * last_irq; | 385 | unsigned long *last_irq; |
377 | unsigned long * irq_delta; | 386 | unsigned long *irq_delta; |
378 | unsigned long irq; | 387 | unsigned long irq; |
379 | } irq_cpu_data[NR_CPUS]; | 388 | } irq_cpu_data[NR_CPUS]; |
380 | 389 | ||
381 | #define CPU_IRQ(cpu) (irq_cpu_data[cpu].irq) | 390 | #define CPU_IRQ(cpu) (irq_cpu_data[cpu].irq) |
382 | #define LAST_CPU_IRQ(cpu,irq) (irq_cpu_data[cpu].last_irq[irq]) | 391 | #define LAST_CPU_IRQ(cpu, irq) (irq_cpu_data[cpu].last_irq[irq]) |
383 | #define IRQ_DELTA(cpu,irq) (irq_cpu_data[cpu].irq_delta[irq]) | 392 | #define IRQ_DELTA(cpu, irq) (irq_cpu_data[cpu].irq_delta[irq]) |
384 | 393 | ||
385 | #define IDLE_ENOUGH(cpu,now) \ | 394 | #define IDLE_ENOUGH(cpu,now) \ |
386 | (idle_cpu(cpu) && ((now) - per_cpu(irq_stat, (cpu)).idle_timestamp > 1)) | 395 | (idle_cpu(cpu) && ((now) - per_cpu(irq_stat, (cpu)).idle_timestamp > 1)) |
@@ -419,8 +428,8 @@ inside: | |||
419 | if (cpu == -1) | 428 | if (cpu == -1) |
420 | cpu = NR_CPUS-1; | 429 | cpu = NR_CPUS-1; |
421 | } | 430 | } |
422 | } while (!cpu_online(cpu) || !IRQ_ALLOWED(cpu,allowed_mask) || | 431 | } while (!cpu_online(cpu) || !IRQ_ALLOWED(cpu, allowed_mask) || |
423 | (search_idle && !IDLE_ENOUGH(cpu,now))); | 432 | (search_idle && !IDLE_ENOUGH(cpu, now))); |
424 | 433 | ||
425 | return cpu; | 434 | return cpu; |
426 | } | 435 | } |
@@ -430,15 +439,14 @@ static inline void balance_irq(int cpu, int irq) | |||
430 | unsigned long now = jiffies; | 439 | unsigned long now = jiffies; |
431 | cpumask_t allowed_mask; | 440 | cpumask_t allowed_mask; |
432 | unsigned int new_cpu; | 441 | unsigned int new_cpu; |
433 | 442 | ||
434 | if (irqbalance_disabled) | 443 | if (irqbalance_disabled) |
435 | return; | 444 | return; |
436 | 445 | ||
437 | cpus_and(allowed_mask, cpu_online_map, balance_irq_affinity[irq]); | 446 | cpus_and(allowed_mask, cpu_online_map, balance_irq_affinity[irq]); |
438 | new_cpu = move(cpu, allowed_mask, now, 1); | 447 | new_cpu = move(cpu, allowed_mask, now, 1); |
439 | if (cpu != new_cpu) { | 448 | if (cpu != new_cpu) |
440 | set_pending_irq(irq, cpumask_of_cpu(new_cpu)); | 449 | set_pending_irq(irq, cpumask_of_cpu(new_cpu)); |
441 | } | ||
442 | } | 450 | } |
443 | 451 | ||
444 | static inline void rotate_irqs_among_cpus(unsigned long useful_load_threshold) | 452 | static inline void rotate_irqs_among_cpus(unsigned long useful_load_threshold) |
@@ -450,14 +458,14 @@ static inline void rotate_irqs_among_cpus(unsigned long useful_load_threshold) | |||
450 | if (!irq_desc[j].action) | 458 | if (!irq_desc[j].action) |
451 | continue; | 459 | continue; |
452 | /* Is it a significant load ? */ | 460 | /* Is it a significant load ? */ |
453 | if (IRQ_DELTA(CPU_TO_PACKAGEINDEX(i),j) < | 461 | if (IRQ_DELTA(CPU_TO_PACKAGEINDEX(i), j) < |
454 | useful_load_threshold) | 462 | useful_load_threshold) |
455 | continue; | 463 | continue; |
456 | balance_irq(i, j); | 464 | balance_irq(i, j); |
457 | } | 465 | } |
458 | } | 466 | } |
459 | balanced_irq_interval = max((long)MIN_BALANCED_IRQ_INTERVAL, | 467 | balanced_irq_interval = max((long)MIN_BALANCED_IRQ_INTERVAL, |
460 | balanced_irq_interval - BALANCED_IRQ_LESS_DELTA); | 468 | balanced_irq_interval - BALANCED_IRQ_LESS_DELTA); |
461 | return; | 469 | return; |
462 | } | 470 | } |
463 | 471 | ||
@@ -486,22 +494,22 @@ static void do_irq_balance(void) | |||
486 | /* Is this an active IRQ or balancing disabled ? */ | 494 | /* Is this an active IRQ or balancing disabled ? */ |
487 | if (!irq_desc[j].action || irq_balancing_disabled(j)) | 495 | if (!irq_desc[j].action || irq_balancing_disabled(j)) |
488 | continue; | 496 | continue; |
489 | if ( package_index == i ) | 497 | if (package_index == i) |
490 | IRQ_DELTA(package_index,j) = 0; | 498 | IRQ_DELTA(package_index, j) = 0; |
491 | /* Determine the total count per processor per IRQ */ | 499 | /* Determine the total count per processor per IRQ */ |
492 | value_now = (unsigned long) kstat_cpu(i).irqs[j]; | 500 | value_now = (unsigned long) kstat_cpu(i).irqs[j]; |
493 | 501 | ||
494 | /* Determine the activity per processor per IRQ */ | 502 | /* Determine the activity per processor per IRQ */ |
495 | delta = value_now - LAST_CPU_IRQ(i,j); | 503 | delta = value_now - LAST_CPU_IRQ(i, j); |
496 | 504 | ||
497 | /* Update last_cpu_irq[][] for the next time */ | 505 | /* Update last_cpu_irq[][] for the next time */ |
498 | LAST_CPU_IRQ(i,j) = value_now; | 506 | LAST_CPU_IRQ(i, j) = value_now; |
499 | 507 | ||
500 | /* Ignore IRQs whose rate is less than the clock */ | 508 | /* Ignore IRQs whose rate is less than the clock */ |
501 | if (delta < useful_load_threshold) | 509 | if (delta < useful_load_threshold) |
502 | continue; | 510 | continue; |
503 | /* update the load for the processor or package total */ | 511 | /* update the load for the processor or package total */ |
504 | IRQ_DELTA(package_index,j) += delta; | 512 | IRQ_DELTA(package_index, j) += delta; |
505 | 513 | ||
506 | /* Keep track of the higher numbered sibling as well */ | 514 | /* Keep track of the higher numbered sibling as well */ |
507 | if (i != package_index) | 515 | if (i != package_index) |
@@ -527,7 +535,8 @@ static void do_irq_balance(void) | |||
527 | max_cpu_irq = ULONG_MAX; | 535 | max_cpu_irq = ULONG_MAX; |
528 | 536 | ||
529 | tryanothercpu: | 537 | tryanothercpu: |
530 | /* Look for heaviest loaded processor. | 538 | /* |
539 | * Look for heaviest loaded processor. | ||
531 | * We may come back to get the next heaviest loaded processor. | 540 | * We may come back to get the next heaviest loaded processor. |
532 | * Skip processors with trivial loads. | 541 | * Skip processors with trivial loads. |
533 | */ | 542 | */ |
@@ -536,7 +545,7 @@ tryanothercpu: | |||
536 | for_each_online_cpu(i) { | 545 | for_each_online_cpu(i) { |
537 | if (i != CPU_TO_PACKAGEINDEX(i)) | 546 | if (i != CPU_TO_PACKAGEINDEX(i)) |
538 | continue; | 547 | continue; |
539 | if (max_cpu_irq <= CPU_IRQ(i)) | 548 | if (max_cpu_irq <= CPU_IRQ(i)) |
540 | continue; | 549 | continue; |
541 | if (tmp_cpu_irq < CPU_IRQ(i)) { | 550 | if (tmp_cpu_irq < CPU_IRQ(i)) { |
542 | tmp_cpu_irq = CPU_IRQ(i); | 551 | tmp_cpu_irq = CPU_IRQ(i); |
@@ -545,8 +554,9 @@ tryanothercpu: | |||
545 | } | 554 | } |
546 | 555 | ||
547 | if (tmp_loaded == -1) { | 556 | if (tmp_loaded == -1) { |
548 | /* In the case of small number of heavy interrupt sources, | 557 | /* |
549 | * loading some of the cpus too much. We use Ingo's original | 558 | * In the case of small number of heavy interrupt sources, |
559 | * loading some of the cpus too much. We use Ingo's original | ||
550 | * approach to rotate them around. | 560 | * approach to rotate them around. |
551 | */ | 561 | */ |
552 | if (!first_attempt && imbalance >= useful_load_threshold) { | 562 | if (!first_attempt && imbalance >= useful_load_threshold) { |
@@ -555,13 +565,14 @@ tryanothercpu: | |||
555 | } | 565 | } |
556 | goto not_worth_the_effort; | 566 | goto not_worth_the_effort; |
557 | } | 567 | } |
558 | 568 | ||
559 | first_attempt = 0; /* heaviest search */ | 569 | first_attempt = 0; /* heaviest search */ |
560 | max_cpu_irq = tmp_cpu_irq; /* load */ | 570 | max_cpu_irq = tmp_cpu_irq; /* load */ |
561 | max_loaded = tmp_loaded; /* processor */ | 571 | max_loaded = tmp_loaded; /* processor */ |
562 | imbalance = (max_cpu_irq - min_cpu_irq) / 2; | 572 | imbalance = (max_cpu_irq - min_cpu_irq) / 2; |
563 | 573 | ||
564 | /* if imbalance is less than approx 10% of max load, then | 574 | /* |
575 | * if imbalance is less than approx 10% of max load, then | ||
565 | * observe diminishing returns action. - quit | 576 | * observe diminishing returns action. - quit |
566 | */ | 577 | */ |
567 | if (imbalance < (max_cpu_irq >> 3)) | 578 | if (imbalance < (max_cpu_irq >> 3)) |
@@ -577,26 +588,25 @@ tryanotherirq: | |||
577 | /* Is this an active IRQ? */ | 588 | /* Is this an active IRQ? */ |
578 | if (!irq_desc[j].action) | 589 | if (!irq_desc[j].action) |
579 | continue; | 590 | continue; |
580 | if (imbalance <= IRQ_DELTA(max_loaded,j)) | 591 | if (imbalance <= IRQ_DELTA(max_loaded, j)) |
581 | continue; | 592 | continue; |
582 | /* Try to find the IRQ that is closest to the imbalance | 593 | /* Try to find the IRQ that is closest to the imbalance |
583 | * without going over. | 594 | * without going over. |
584 | */ | 595 | */ |
585 | if (move_this_load < IRQ_DELTA(max_loaded,j)) { | 596 | if (move_this_load < IRQ_DELTA(max_loaded, j)) { |
586 | move_this_load = IRQ_DELTA(max_loaded,j); | 597 | move_this_load = IRQ_DELTA(max_loaded, j); |
587 | selected_irq = j; | 598 | selected_irq = j; |
588 | } | 599 | } |
589 | } | 600 | } |
590 | if (selected_irq == -1) { | 601 | if (selected_irq == -1) |
591 | goto tryanothercpu; | 602 | goto tryanothercpu; |
592 | } | ||
593 | 603 | ||
594 | imbalance = move_this_load; | 604 | imbalance = move_this_load; |
595 | 605 | ||
596 | /* For physical_balance case, we accumulated both load | 606 | /* For physical_balance case, we accumulated both load |
597 | * values in the one of the siblings cpu_irq[], | 607 | * values in the one of the siblings cpu_irq[], |
598 | * to use the same code for physical and logical processors | 608 | * to use the same code for physical and logical processors |
599 | * as much as possible. | 609 | * as much as possible. |
600 | * | 610 | * |
601 | * NOTE: the cpu_irq[] array holds the sum of the load for | 611 | * NOTE: the cpu_irq[] array holds the sum of the load for |
602 | * sibling A and sibling B in the slot for the lowest numbered | 612 | * sibling A and sibling B in the slot for the lowest numbered |
@@ -625,11 +635,11 @@ tryanotherirq: | |||
625 | /* mark for change destination */ | 635 | /* mark for change destination */ |
626 | set_pending_irq(selected_irq, cpumask_of_cpu(min_loaded)); | 636 | set_pending_irq(selected_irq, cpumask_of_cpu(min_loaded)); |
627 | 637 | ||
628 | /* Since we made a change, come back sooner to | 638 | /* Since we made a change, come back sooner to |
629 | * check for more variation. | 639 | * check for more variation. |
630 | */ | 640 | */ |
631 | balanced_irq_interval = max((long)MIN_BALANCED_IRQ_INTERVAL, | 641 | balanced_irq_interval = max((long)MIN_BALANCED_IRQ_INTERVAL, |
632 | balanced_irq_interval - BALANCED_IRQ_LESS_DELTA); | 642 | balanced_irq_interval - BALANCED_IRQ_LESS_DELTA); |
633 | return; | 643 | return; |
634 | } | 644 | } |
635 | goto tryanotherirq; | 645 | goto tryanotherirq; |
@@ -640,7 +650,7 @@ not_worth_the_effort: | |||
640 | * upward | 650 | * upward |
641 | */ | 651 | */ |
642 | balanced_irq_interval = min((long)MAX_BALANCED_IRQ_INTERVAL, | 652 | balanced_irq_interval = min((long)MAX_BALANCED_IRQ_INTERVAL, |
643 | balanced_irq_interval + BALANCED_IRQ_MORE_DELTA); | 653 | balanced_irq_interval + BALANCED_IRQ_MORE_DELTA); |
644 | return; | 654 | return; |
645 | } | 655 | } |
646 | 656 | ||
@@ -679,13 +689,13 @@ static int __init balanced_irq_init(void) | |||
679 | cpumask_t tmp; | 689 | cpumask_t tmp; |
680 | 690 | ||
681 | cpus_shift_right(tmp, cpu_online_map, 2); | 691 | cpus_shift_right(tmp, cpu_online_map, 2); |
682 | c = &boot_cpu_data; | 692 | c = &boot_cpu_data; |
683 | /* When not overwritten by the command line ask subarchitecture. */ | 693 | /* When not overwritten by the command line ask subarchitecture. */ |
684 | if (irqbalance_disabled == IRQBALANCE_CHECK_ARCH) | 694 | if (irqbalance_disabled == IRQBALANCE_CHECK_ARCH) |
685 | irqbalance_disabled = NO_BALANCE_IRQ; | 695 | irqbalance_disabled = NO_BALANCE_IRQ; |
686 | if (irqbalance_disabled) | 696 | if (irqbalance_disabled) |
687 | return 0; | 697 | return 0; |
688 | 698 | ||
689 | /* disable irqbalance completely if there is only one processor online */ | 699 | /* disable irqbalance completely if there is only one processor online */ |
690 | if (num_online_cpus() < 2) { | 700 | if (num_online_cpus() < 2) { |
691 | irqbalance_disabled = 1; | 701 | irqbalance_disabled = 1; |
@@ -699,16 +709,14 @@ static int __init balanced_irq_init(void) | |||
699 | physical_balance = 1; | 709 | physical_balance = 1; |
700 | 710 | ||
701 | for_each_online_cpu(i) { | 711 | for_each_online_cpu(i) { |
702 | irq_cpu_data[i].irq_delta = kmalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL); | 712 | irq_cpu_data[i].irq_delta = kzalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL); |
703 | irq_cpu_data[i].last_irq = kmalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL); | 713 | irq_cpu_data[i].last_irq = kzalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL); |
704 | if (irq_cpu_data[i].irq_delta == NULL || irq_cpu_data[i].last_irq == NULL) { | 714 | if (irq_cpu_data[i].irq_delta == NULL || irq_cpu_data[i].last_irq == NULL) { |
705 | printk(KERN_ERR "balanced_irq_init: out of memory"); | 715 | printk(KERN_ERR "balanced_irq_init: out of memory"); |
706 | goto failed; | 716 | goto failed; |
707 | } | 717 | } |
708 | memset(irq_cpu_data[i].irq_delta,0,sizeof(unsigned long) * NR_IRQS); | ||
709 | memset(irq_cpu_data[i].last_irq,0,sizeof(unsigned long) * NR_IRQS); | ||
710 | } | 718 | } |
711 | 719 | ||
712 | printk(KERN_INFO "Starting balanced_irq\n"); | 720 | printk(KERN_INFO "Starting balanced_irq\n"); |
713 | if (!IS_ERR(kthread_run(balanced_irq, NULL, "kirqd"))) | 721 | if (!IS_ERR(kthread_run(balanced_irq, NULL, "kirqd"))) |
714 | return 0; | 722 | return 0; |
@@ -801,10 +809,10 @@ static int find_irq_entry(int apic, int pin, int type) | |||
801 | int i; | 809 | int i; |
802 | 810 | ||
803 | for (i = 0; i < mp_irq_entries; i++) | 811 | for (i = 0; i < mp_irq_entries; i++) |
804 | if (mp_irqs[i].mpc_irqtype == type && | 812 | if (mp_irqs[i].mp_irqtype == type && |
805 | (mp_irqs[i].mpc_dstapic == mp_ioapics[apic].mpc_apicid || | 813 | (mp_irqs[i].mp_dstapic == mp_ioapics[apic].mp_apicid || |
806 | mp_irqs[i].mpc_dstapic == MP_APIC_ALL) && | 814 | mp_irqs[i].mp_dstapic == MP_APIC_ALL) && |
807 | mp_irqs[i].mpc_dstirq == pin) | 815 | mp_irqs[i].mp_dstirq == pin) |
808 | return i; | 816 | return i; |
809 | 817 | ||
810 | return -1; | 818 | return -1; |
@@ -818,13 +826,13 @@ static int __init find_isa_irq_pin(int irq, int type) | |||
818 | int i; | 826 | int i; |
819 | 827 | ||
820 | for (i = 0; i < mp_irq_entries; i++) { | 828 | for (i = 0; i < mp_irq_entries; i++) { |
821 | int lbus = mp_irqs[i].mpc_srcbus; | 829 | int lbus = mp_irqs[i].mp_srcbus; |
822 | 830 | ||
823 | if (test_bit(lbus, mp_bus_not_pci) && | 831 | if (test_bit(lbus, mp_bus_not_pci) && |
824 | (mp_irqs[i].mpc_irqtype == type) && | 832 | (mp_irqs[i].mp_irqtype == type) && |
825 | (mp_irqs[i].mpc_srcbusirq == irq)) | 833 | (mp_irqs[i].mp_srcbusirq == irq)) |
826 | 834 | ||
827 | return mp_irqs[i].mpc_dstirq; | 835 | return mp_irqs[i].mp_dstirq; |
828 | } | 836 | } |
829 | return -1; | 837 | return -1; |
830 | } | 838 | } |
@@ -834,17 +842,17 @@ static int __init find_isa_irq_apic(int irq, int type) | |||
834 | int i; | 842 | int i; |
835 | 843 | ||
836 | for (i = 0; i < mp_irq_entries; i++) { | 844 | for (i = 0; i < mp_irq_entries; i++) { |
837 | int lbus = mp_irqs[i].mpc_srcbus; | 845 | int lbus = mp_irqs[i].mp_srcbus; |
838 | 846 | ||
839 | if (test_bit(lbus, mp_bus_not_pci) && | 847 | if (test_bit(lbus, mp_bus_not_pci) && |
840 | (mp_irqs[i].mpc_irqtype == type) && | 848 | (mp_irqs[i].mp_irqtype == type) && |
841 | (mp_irqs[i].mpc_srcbusirq == irq)) | 849 | (mp_irqs[i].mp_srcbusirq == irq)) |
842 | break; | 850 | break; |
843 | } | 851 | } |
844 | if (i < mp_irq_entries) { | 852 | if (i < mp_irq_entries) { |
845 | int apic; | 853 | int apic; |
846 | for(apic = 0; apic < nr_ioapics; apic++) { | 854 | for (apic = 0; apic < nr_ioapics; apic++) { |
847 | if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic) | 855 | if (mp_ioapics[apic].mp_apicid == mp_irqs[i].mp_dstapic) |
848 | return apic; | 856 | return apic; |
849 | } | 857 | } |
850 | } | 858 | } |
@@ -864,28 +872,28 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin) | |||
864 | 872 | ||
865 | apic_printk(APIC_DEBUG, "querying PCI -> IRQ mapping bus:%d, " | 873 | apic_printk(APIC_DEBUG, "querying PCI -> IRQ mapping bus:%d, " |
866 | "slot:%d, pin:%d.\n", bus, slot, pin); | 874 | "slot:%d, pin:%d.\n", bus, slot, pin); |
867 | if (mp_bus_id_to_pci_bus[bus] == -1) { | 875 | if (test_bit(bus, mp_bus_not_pci)) { |
868 | printk(KERN_WARNING "PCI BIOS passed nonexistent PCI bus %d!\n", bus); | 876 | printk(KERN_WARNING "PCI BIOS passed nonexistent PCI bus %d!\n", bus); |
869 | return -1; | 877 | return -1; |
870 | } | 878 | } |
871 | for (i = 0; i < mp_irq_entries; i++) { | 879 | for (i = 0; i < mp_irq_entries; i++) { |
872 | int lbus = mp_irqs[i].mpc_srcbus; | 880 | int lbus = mp_irqs[i].mp_srcbus; |
873 | 881 | ||
874 | for (apic = 0; apic < nr_ioapics; apic++) | 882 | for (apic = 0; apic < nr_ioapics; apic++) |
875 | if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic || | 883 | if (mp_ioapics[apic].mp_apicid == mp_irqs[i].mp_dstapic || |
876 | mp_irqs[i].mpc_dstapic == MP_APIC_ALL) | 884 | mp_irqs[i].mp_dstapic == MP_APIC_ALL) |
877 | break; | 885 | break; |
878 | 886 | ||
879 | if (!test_bit(lbus, mp_bus_not_pci) && | 887 | if (!test_bit(lbus, mp_bus_not_pci) && |
880 | !mp_irqs[i].mpc_irqtype && | 888 | !mp_irqs[i].mp_irqtype && |
881 | (bus == lbus) && | 889 | (bus == lbus) && |
882 | (slot == ((mp_irqs[i].mpc_srcbusirq >> 2) & 0x1f))) { | 890 | (slot == ((mp_irqs[i].mp_srcbusirq >> 2) & 0x1f))) { |
883 | int irq = pin_2_irq(i,apic,mp_irqs[i].mpc_dstirq); | 891 | int irq = pin_2_irq(i, apic, mp_irqs[i].mp_dstirq); |
884 | 892 | ||
885 | if (!(apic || IO_APIC_IRQ(irq))) | 893 | if (!(apic || IO_APIC_IRQ(irq))) |
886 | continue; | 894 | continue; |
887 | 895 | ||
888 | if (pin == (mp_irqs[i].mpc_srcbusirq & 3)) | 896 | if (pin == (mp_irqs[i].mp_srcbusirq & 3)) |
889 | return irq; | 897 | return irq; |
890 | /* | 898 | /* |
891 | * Use the first all-but-pin matching entry as a | 899 | * Use the first all-but-pin matching entry as a |
@@ -900,7 +908,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin) | |||
900 | EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector); | 908 | EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector); |
901 | 909 | ||
902 | /* | 910 | /* |
903 | * This function currently is only a helper for the i386 smp boot process where | 911 | * This function currently is only a helper for the i386 smp boot process where |
904 | * we need to reprogram the ioredtbls to cater for the cpus which have come online | 912 | * we need to reprogram the ioredtbls to cater for the cpus which have come online |
905 | * so mask in all cases should simply be TARGET_CPUS | 913 | * so mask in all cases should simply be TARGET_CPUS |
906 | */ | 914 | */ |
@@ -952,7 +960,7 @@ static int EISA_ELCR(unsigned int irq) | |||
952 | * EISA conforming in the MP table, that means its trigger type must | 960 | * EISA conforming in the MP table, that means its trigger type must |
953 | * be read in from the ELCR */ | 961 | * be read in from the ELCR */ |
954 | 962 | ||
955 | #define default_EISA_trigger(idx) (EISA_ELCR(mp_irqs[idx].mpc_srcbusirq)) | 963 | #define default_EISA_trigger(idx) (EISA_ELCR(mp_irqs[idx].mp_srcbusirq)) |
956 | #define default_EISA_polarity(idx) default_ISA_polarity(idx) | 964 | #define default_EISA_polarity(idx) default_ISA_polarity(idx) |
957 | 965 | ||
958 | /* PCI interrupts are always polarity one level triggered, | 966 | /* PCI interrupts are always polarity one level triggered, |
@@ -969,118 +977,115 @@ static int EISA_ELCR(unsigned int irq) | |||
969 | 977 | ||
970 | static int MPBIOS_polarity(int idx) | 978 | static int MPBIOS_polarity(int idx) |
971 | { | 979 | { |
972 | int bus = mp_irqs[idx].mpc_srcbus; | 980 | int bus = mp_irqs[idx].mp_srcbus; |
973 | int polarity; | 981 | int polarity; |
974 | 982 | ||
975 | /* | 983 | /* |
976 | * Determine IRQ line polarity (high active or low active): | 984 | * Determine IRQ line polarity (high active or low active): |
977 | */ | 985 | */ |
978 | switch (mp_irqs[idx].mpc_irqflag & 3) | 986 | switch (mp_irqs[idx].mp_irqflag & 3) { |
987 | case 0: /* conforms, ie. bus-type dependent polarity */ | ||
979 | { | 988 | { |
980 | case 0: /* conforms, ie. bus-type dependent polarity */ | 989 | polarity = test_bit(bus, mp_bus_not_pci)? |
981 | { | 990 | default_ISA_polarity(idx): |
982 | polarity = test_bit(bus, mp_bus_not_pci)? | 991 | default_PCI_polarity(idx); |
983 | default_ISA_polarity(idx): | 992 | break; |
984 | default_PCI_polarity(idx); | 993 | } |
985 | break; | 994 | case 1: /* high active */ |
986 | } | 995 | { |
987 | case 1: /* high active */ | 996 | polarity = 0; |
988 | { | 997 | break; |
989 | polarity = 0; | 998 | } |
990 | break; | 999 | case 2: /* reserved */ |
991 | } | 1000 | { |
992 | case 2: /* reserved */ | 1001 | printk(KERN_WARNING "broken BIOS!!\n"); |
993 | { | 1002 | polarity = 1; |
994 | printk(KERN_WARNING "broken BIOS!!\n"); | 1003 | break; |
995 | polarity = 1; | 1004 | } |
996 | break; | 1005 | case 3: /* low active */ |
997 | } | 1006 | { |
998 | case 3: /* low active */ | 1007 | polarity = 1; |
999 | { | 1008 | break; |
1000 | polarity = 1; | 1009 | } |
1001 | break; | 1010 | default: /* invalid */ |
1002 | } | 1011 | { |
1003 | default: /* invalid */ | 1012 | printk(KERN_WARNING "broken BIOS!!\n"); |
1004 | { | 1013 | polarity = 1; |
1005 | printk(KERN_WARNING "broken BIOS!!\n"); | 1014 | break; |
1006 | polarity = 1; | 1015 | } |
1007 | break; | ||
1008 | } | ||
1009 | } | 1016 | } |
1010 | return polarity; | 1017 | return polarity; |
1011 | } | 1018 | } |
1012 | 1019 | ||
1013 | static int MPBIOS_trigger(int idx) | 1020 | static int MPBIOS_trigger(int idx) |
1014 | { | 1021 | { |
1015 | int bus = mp_irqs[idx].mpc_srcbus; | 1022 | int bus = mp_irqs[idx].mp_srcbus; |
1016 | int trigger; | 1023 | int trigger; |
1017 | 1024 | ||
1018 | /* | 1025 | /* |
1019 | * Determine IRQ trigger mode (edge or level sensitive): | 1026 | * Determine IRQ trigger mode (edge or level sensitive): |
1020 | */ | 1027 | */ |
1021 | switch ((mp_irqs[idx].mpc_irqflag>>2) & 3) | 1028 | switch ((mp_irqs[idx].mp_irqflag>>2) & 3) { |
1029 | case 0: /* conforms, ie. bus-type dependent */ | ||
1022 | { | 1030 | { |
1023 | case 0: /* conforms, ie. bus-type dependent */ | 1031 | trigger = test_bit(bus, mp_bus_not_pci)? |
1024 | { | 1032 | default_ISA_trigger(idx): |
1025 | trigger = test_bit(bus, mp_bus_not_pci)? | 1033 | default_PCI_trigger(idx); |
1026 | default_ISA_trigger(idx): | ||
1027 | default_PCI_trigger(idx); | ||
1028 | #if defined(CONFIG_EISA) || defined(CONFIG_MCA) | 1034 | #if defined(CONFIG_EISA) || defined(CONFIG_MCA) |
1029 | switch (mp_bus_id_to_type[bus]) | 1035 | switch (mp_bus_id_to_type[bus]) { |
1030 | { | 1036 | case MP_BUS_ISA: /* ISA pin */ |
1031 | case MP_BUS_ISA: /* ISA pin */ | 1037 | { |
1032 | { | 1038 | /* set before the switch */ |
1033 | /* set before the switch */ | ||
1034 | break; | ||
1035 | } | ||
1036 | case MP_BUS_EISA: /* EISA pin */ | ||
1037 | { | ||
1038 | trigger = default_EISA_trigger(idx); | ||
1039 | break; | ||
1040 | } | ||
1041 | case MP_BUS_PCI: /* PCI pin */ | ||
1042 | { | ||
1043 | /* set before the switch */ | ||
1044 | break; | ||
1045 | } | ||
1046 | case MP_BUS_MCA: /* MCA pin */ | ||
1047 | { | ||
1048 | trigger = default_MCA_trigger(idx); | ||
1049 | break; | ||
1050 | } | ||
1051 | default: | ||
1052 | { | ||
1053 | printk(KERN_WARNING "broken BIOS!!\n"); | ||
1054 | trigger = 1; | ||
1055 | break; | ||
1056 | } | ||
1057 | } | ||
1058 | #endif | ||
1059 | break; | 1039 | break; |
1060 | } | 1040 | } |
1061 | case 1: /* edge */ | 1041 | case MP_BUS_EISA: /* EISA pin */ |
1062 | { | 1042 | { |
1063 | trigger = 0; | 1043 | trigger = default_EISA_trigger(idx); |
1064 | break; | 1044 | break; |
1065 | } | 1045 | } |
1066 | case 2: /* reserved */ | 1046 | case MP_BUS_PCI: /* PCI pin */ |
1067 | { | 1047 | { |
1068 | printk(KERN_WARNING "broken BIOS!!\n"); | 1048 | /* set before the switch */ |
1069 | trigger = 1; | ||
1070 | break; | 1049 | break; |
1071 | } | 1050 | } |
1072 | case 3: /* level */ | 1051 | case MP_BUS_MCA: /* MCA pin */ |
1073 | { | 1052 | { |
1074 | trigger = 1; | 1053 | trigger = default_MCA_trigger(idx); |
1075 | break; | 1054 | break; |
1076 | } | 1055 | } |
1077 | default: /* invalid */ | 1056 | default: |
1078 | { | 1057 | { |
1079 | printk(KERN_WARNING "broken BIOS!!\n"); | 1058 | printk(KERN_WARNING "broken BIOS!!\n"); |
1080 | trigger = 0; | 1059 | trigger = 1; |
1081 | break; | 1060 | break; |
1082 | } | 1061 | } |
1083 | } | 1062 | } |
1063 | #endif | ||
1064 | break; | ||
1065 | } | ||
1066 | case 1: /* edge */ | ||
1067 | { | ||
1068 | trigger = 0; | ||
1069 | break; | ||
1070 | } | ||
1071 | case 2: /* reserved */ | ||
1072 | { | ||
1073 | printk(KERN_WARNING "broken BIOS!!\n"); | ||
1074 | trigger = 1; | ||
1075 | break; | ||
1076 | } | ||
1077 | case 3: /* level */ | ||
1078 | { | ||
1079 | trigger = 1; | ||
1080 | break; | ||
1081 | } | ||
1082 | default: /* invalid */ | ||
1083 | { | ||
1084 | printk(KERN_WARNING "broken BIOS!!\n"); | ||
1085 | trigger = 0; | ||
1086 | break; | ||
1087 | } | ||
1088 | } | ||
1084 | return trigger; | 1089 | return trigger; |
1085 | } | 1090 | } |
1086 | 1091 | ||
@@ -1097,16 +1102,16 @@ static inline int irq_trigger(int idx) | |||
1097 | static int pin_2_irq(int idx, int apic, int pin) | 1102 | static int pin_2_irq(int idx, int apic, int pin) |
1098 | { | 1103 | { |
1099 | int irq, i; | 1104 | int irq, i; |
1100 | int bus = mp_irqs[idx].mpc_srcbus; | 1105 | int bus = mp_irqs[idx].mp_srcbus; |
1101 | 1106 | ||
1102 | /* | 1107 | /* |
1103 | * Debugging check, we are in big trouble if this message pops up! | 1108 | * Debugging check, we are in big trouble if this message pops up! |
1104 | */ | 1109 | */ |
1105 | if (mp_irqs[idx].mpc_dstirq != pin) | 1110 | if (mp_irqs[idx].mp_dstirq != pin) |
1106 | printk(KERN_ERR "broken BIOS or MPTABLE parser, ayiee!!\n"); | 1111 | printk(KERN_ERR "broken BIOS or MPTABLE parser, ayiee!!\n"); |
1107 | 1112 | ||
1108 | if (test_bit(bus, mp_bus_not_pci)) | 1113 | if (test_bit(bus, mp_bus_not_pci)) |
1109 | irq = mp_irqs[idx].mpc_srcbusirq; | 1114 | irq = mp_irqs[idx].mp_srcbusirq; |
1110 | else { | 1115 | else { |
1111 | /* | 1116 | /* |
1112 | * PCI IRQs are mapped in order | 1117 | * PCI IRQs are mapped in order |
@@ -1148,8 +1153,8 @@ static inline int IO_APIC_irq_trigger(int irq) | |||
1148 | 1153 | ||
1149 | for (apic = 0; apic < nr_ioapics; apic++) { | 1154 | for (apic = 0; apic < nr_ioapics; apic++) { |
1150 | for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { | 1155 | for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { |
1151 | idx = find_irq_entry(apic,pin,mp_INT); | 1156 | idx = find_irq_entry(apic, pin, mp_INT); |
1152 | if ((idx != -1) && (irq == pin_2_irq(idx,apic,pin))) | 1157 | if ((idx != -1) && (irq == pin_2_irq(idx, apic, pin))) |
1153 | return irq_trigger(idx); | 1158 | return irq_trigger(idx); |
1154 | } | 1159 | } |
1155 | } | 1160 | } |
@@ -1164,7 +1169,7 @@ static u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 } | |||
1164 | 1169 | ||
1165 | static int __assign_irq_vector(int irq) | 1170 | static int __assign_irq_vector(int irq) |
1166 | { | 1171 | { |
1167 | static int current_vector = FIRST_DEVICE_VECTOR, current_offset = 0; | 1172 | static int current_vector = FIRST_DEVICE_VECTOR, current_offset; |
1168 | int vector, offset; | 1173 | int vector, offset; |
1169 | 1174 | ||
1170 | BUG_ON((unsigned)irq >= NR_IRQ_VECTORS); | 1175 | BUG_ON((unsigned)irq >= NR_IRQ_VECTORS); |
@@ -1176,7 +1181,7 @@ static int __assign_irq_vector(int irq) | |||
1176 | offset = current_offset; | 1181 | offset = current_offset; |
1177 | next: | 1182 | next: |
1178 | vector += 8; | 1183 | vector += 8; |
1179 | if (vector >= FIRST_SYSTEM_VECTOR) { | 1184 | if (vector >= first_system_vector) { |
1180 | offset = (offset + 1) % 8; | 1185 | offset = (offset + 1) % 8; |
1181 | vector = FIRST_DEVICE_VECTOR + offset; | 1186 | vector = FIRST_DEVICE_VECTOR + offset; |
1182 | } | 1187 | } |
@@ -1203,6 +1208,11 @@ static int assign_irq_vector(int irq) | |||
1203 | 1208 | ||
1204 | return vector; | 1209 | return vector; |
1205 | } | 1210 | } |
1211 | |||
1212 | void setup_vector_irq(int cpu) | ||
1213 | { | ||
1214 | } | ||
1215 | |||
1206 | static struct irq_chip ioapic_chip; | 1216 | static struct irq_chip ioapic_chip; |
1207 | 1217 | ||
1208 | #define IOAPIC_AUTO -1 | 1218 | #define IOAPIC_AUTO -1 |
@@ -1237,25 +1247,25 @@ static void __init setup_IO_APIC_irqs(void) | |||
1237 | /* | 1247 | /* |
1238 | * add it to the IO-APIC irq-routing table: | 1248 | * add it to the IO-APIC irq-routing table: |
1239 | */ | 1249 | */ |
1240 | memset(&entry,0,sizeof(entry)); | 1250 | memset(&entry, 0, sizeof(entry)); |
1241 | 1251 | ||
1242 | entry.delivery_mode = INT_DELIVERY_MODE; | 1252 | entry.delivery_mode = INT_DELIVERY_MODE; |
1243 | entry.dest_mode = INT_DEST_MODE; | 1253 | entry.dest_mode = INT_DEST_MODE; |
1244 | entry.mask = 0; /* enable IRQ */ | 1254 | entry.mask = 0; /* enable IRQ */ |
1245 | entry.dest.logical.logical_dest = | 1255 | entry.dest.logical.logical_dest = |
1246 | cpu_mask_to_apicid(TARGET_CPUS); | 1256 | cpu_mask_to_apicid(TARGET_CPUS); |
1247 | 1257 | ||
1248 | idx = find_irq_entry(apic,pin,mp_INT); | 1258 | idx = find_irq_entry(apic, pin, mp_INT); |
1249 | if (idx == -1) { | 1259 | if (idx == -1) { |
1250 | if (first_notcon) { | 1260 | if (first_notcon) { |
1251 | apic_printk(APIC_VERBOSE, KERN_DEBUG | 1261 | apic_printk(APIC_VERBOSE, KERN_DEBUG |
1252 | " IO-APIC (apicid-pin) %d-%d", | 1262 | " IO-APIC (apicid-pin) %d-%d", |
1253 | mp_ioapics[apic].mpc_apicid, | 1263 | mp_ioapics[apic].mp_apicid, |
1254 | pin); | 1264 | pin); |
1255 | first_notcon = 0; | 1265 | first_notcon = 0; |
1256 | } else | 1266 | } else |
1257 | apic_printk(APIC_VERBOSE, ", %d-%d", | 1267 | apic_printk(APIC_VERBOSE, ", %d-%d", |
1258 | mp_ioapics[apic].mpc_apicid, pin); | 1268 | mp_ioapics[apic].mp_apicid, pin); |
1259 | continue; | 1269 | continue; |
1260 | } | 1270 | } |
1261 | 1271 | ||
@@ -1289,7 +1299,7 @@ static void __init setup_IO_APIC_irqs(void) | |||
1289 | vector = assign_irq_vector(irq); | 1299 | vector = assign_irq_vector(irq); |
1290 | entry.vector = vector; | 1300 | entry.vector = vector; |
1291 | ioapic_register_intr(irq, vector, IOAPIC_AUTO); | 1301 | ioapic_register_intr(irq, vector, IOAPIC_AUTO); |
1292 | 1302 | ||
1293 | if (!apic && (irq < 16)) | 1303 | if (!apic && (irq < 16)) |
1294 | disable_8259A_irq(irq); | 1304 | disable_8259A_irq(irq); |
1295 | } | 1305 | } |
@@ -1302,25 +1312,21 @@ static void __init setup_IO_APIC_irqs(void) | |||
1302 | } | 1312 | } |
1303 | 1313 | ||
1304 | /* | 1314 | /* |
1305 | * Set up the 8259A-master output pin: | 1315 | * Set up the timer pin, possibly with the 8259A-master behind. |
1306 | */ | 1316 | */ |
1307 | static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, int vector) | 1317 | static void __init setup_timer_IRQ0_pin(unsigned int apic, unsigned int pin, |
1318 | int vector) | ||
1308 | { | 1319 | { |
1309 | struct IO_APIC_route_entry entry; | 1320 | struct IO_APIC_route_entry entry; |
1310 | 1321 | ||
1311 | memset(&entry,0,sizeof(entry)); | 1322 | memset(&entry, 0, sizeof(entry)); |
1312 | |||
1313 | disable_8259A_irq(0); | ||
1314 | |||
1315 | /* mask LVT0 */ | ||
1316 | apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); | ||
1317 | 1323 | ||
1318 | /* | 1324 | /* |
1319 | * We use logical delivery to get the timer IRQ | 1325 | * We use logical delivery to get the timer IRQ |
1320 | * to the first CPU. | 1326 | * to the first CPU. |
1321 | */ | 1327 | */ |
1322 | entry.dest_mode = INT_DEST_MODE; | 1328 | entry.dest_mode = INT_DEST_MODE; |
1323 | entry.mask = 0; /* unmask IRQ now */ | 1329 | entry.mask = 1; /* mask IRQ now */ |
1324 | entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS); | 1330 | entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS); |
1325 | entry.delivery_mode = INT_DELIVERY_MODE; | 1331 | entry.delivery_mode = INT_DELIVERY_MODE; |
1326 | entry.polarity = 0; | 1332 | entry.polarity = 0; |
@@ -1329,17 +1335,14 @@ static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, in | |||
1329 | 1335 | ||
1330 | /* | 1336 | /* |
1331 | * The timer IRQ doesn't have to know that behind the | 1337 | * The timer IRQ doesn't have to know that behind the |
1332 | * scene we have a 8259A-master in AEOI mode ... | 1338 | * scene we may have a 8259A-master in AEOI mode ... |
1333 | */ | 1339 | */ |
1334 | irq_desc[0].chip = &ioapic_chip; | 1340 | ioapic_register_intr(0, vector, IOAPIC_EDGE); |
1335 | set_irq_handler(0, handle_edge_irq); | ||
1336 | 1341 | ||
1337 | /* | 1342 | /* |
1338 | * Add it to the IO-APIC irq-routing table: | 1343 | * Add it to the IO-APIC irq-routing table: |
1339 | */ | 1344 | */ |
1340 | ioapic_write_entry(apic, pin, entry); | 1345 | ioapic_write_entry(apic, pin, entry); |
1341 | |||
1342 | enable_8259A_irq(0); | ||
1343 | } | 1346 | } |
1344 | 1347 | ||
1345 | void __init print_IO_APIC(void) | 1348 | void __init print_IO_APIC(void) |
@@ -1354,10 +1357,10 @@ void __init print_IO_APIC(void) | |||
1354 | if (apic_verbosity == APIC_QUIET) | 1357 | if (apic_verbosity == APIC_QUIET) |
1355 | return; | 1358 | return; |
1356 | 1359 | ||
1357 | printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries); | 1360 | printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries); |
1358 | for (i = 0; i < nr_ioapics; i++) | 1361 | for (i = 0; i < nr_ioapics; i++) |
1359 | printk(KERN_DEBUG "number of IO-APIC #%d registers: %d.\n", | 1362 | printk(KERN_DEBUG "number of IO-APIC #%d registers: %d.\n", |
1360 | mp_ioapics[i].mpc_apicid, nr_ioapic_registers[i]); | 1363 | mp_ioapics[i].mp_apicid, nr_ioapic_registers[i]); |
1361 | 1364 | ||
1362 | /* | 1365 | /* |
1363 | * We are a bit conservative about what we expect. We have to | 1366 | * We are a bit conservative about what we expect. We have to |
@@ -1376,7 +1379,7 @@ void __init print_IO_APIC(void) | |||
1376 | reg_03.raw = io_apic_read(apic, 3); | 1379 | reg_03.raw = io_apic_read(apic, 3); |
1377 | spin_unlock_irqrestore(&ioapic_lock, flags); | 1380 | spin_unlock_irqrestore(&ioapic_lock, flags); |
1378 | 1381 | ||
1379 | printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].mpc_apicid); | 1382 | printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].mp_apicid); |
1380 | printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw); | 1383 | printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw); |
1381 | printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.bits.ID); | 1384 | printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.bits.ID); |
1382 | printk(KERN_DEBUG "....... : Delivery Type: %X\n", reg_00.bits.delivery_type); | 1385 | printk(KERN_DEBUG "....... : Delivery Type: %X\n", reg_00.bits.delivery_type); |
@@ -1459,7 +1462,7 @@ void __init print_IO_APIC(void) | |||
1459 | 1462 | ||
1460 | #if 0 | 1463 | #if 0 |
1461 | 1464 | ||
1462 | static void print_APIC_bitfield (int base) | 1465 | static void print_APIC_bitfield(int base) |
1463 | { | 1466 | { |
1464 | unsigned int v; | 1467 | unsigned int v; |
1465 | int i, j; | 1468 | int i, j; |
@@ -1480,7 +1483,7 @@ static void print_APIC_bitfield (int base) | |||
1480 | } | 1483 | } |
1481 | } | 1484 | } |
1482 | 1485 | ||
1483 | void /*__init*/ print_local_APIC(void * dummy) | 1486 | void /*__init*/ print_local_APIC(void *dummy) |
1484 | { | 1487 | { |
1485 | unsigned int v, ver, maxlvt; | 1488 | unsigned int v, ver, maxlvt; |
1486 | 1489 | ||
@@ -1489,6 +1492,7 @@ void /*__init*/ print_local_APIC(void * dummy) | |||
1489 | 1492 | ||
1490 | printk("\n" KERN_DEBUG "printing local APIC contents on CPU#%d/%d:\n", | 1493 | printk("\n" KERN_DEBUG "printing local APIC contents on CPU#%d/%d:\n", |
1491 | smp_processor_id(), hard_smp_processor_id()); | 1494 | smp_processor_id(), hard_smp_processor_id()); |
1495 | v = apic_read(APIC_ID); | ||
1492 | printk(KERN_INFO "... APIC ID: %08x (%01x)\n", v, | 1496 | printk(KERN_INFO "... APIC ID: %08x (%01x)\n", v, |
1493 | GET_APIC_ID(read_apic_id())); | 1497 | GET_APIC_ID(read_apic_id())); |
1494 | v = apic_read(APIC_LVR); | 1498 | v = apic_read(APIC_LVR); |
@@ -1563,7 +1567,7 @@ void /*__init*/ print_local_APIC(void * dummy) | |||
1563 | printk("\n"); | 1567 | printk("\n"); |
1564 | } | 1568 | } |
1565 | 1569 | ||
1566 | void print_all_local_APICs (void) | 1570 | void print_all_local_APICs(void) |
1567 | { | 1571 | { |
1568 | on_each_cpu(print_local_APIC, NULL, 1, 1); | 1572 | on_each_cpu(print_local_APIC, NULL, 1, 1); |
1569 | } | 1573 | } |
@@ -1586,11 +1590,11 @@ void /*__init*/ print_PIC(void) | |||
1586 | v = inb(0xa0) << 8 | inb(0x20); | 1590 | v = inb(0xa0) << 8 | inb(0x20); |
1587 | printk(KERN_DEBUG "... PIC IRR: %04x\n", v); | 1591 | printk(KERN_DEBUG "... PIC IRR: %04x\n", v); |
1588 | 1592 | ||
1589 | outb(0x0b,0xa0); | 1593 | outb(0x0b, 0xa0); |
1590 | outb(0x0b,0x20); | 1594 | outb(0x0b, 0x20); |
1591 | v = inb(0xa0) << 8 | inb(0x20); | 1595 | v = inb(0xa0) << 8 | inb(0x20); |
1592 | outb(0x0a,0xa0); | 1596 | outb(0x0a, 0xa0); |
1593 | outb(0x0a,0x20); | 1597 | outb(0x0a, 0x20); |
1594 | 1598 | ||
1595 | spin_unlock_irqrestore(&i8259A_lock, flags); | 1599 | spin_unlock_irqrestore(&i8259A_lock, flags); |
1596 | 1600 | ||
@@ -1626,7 +1630,7 @@ static void __init enable_IO_APIC(void) | |||
1626 | spin_unlock_irqrestore(&ioapic_lock, flags); | 1630 | spin_unlock_irqrestore(&ioapic_lock, flags); |
1627 | nr_ioapic_registers[apic] = reg_01.bits.entries+1; | 1631 | nr_ioapic_registers[apic] = reg_01.bits.entries+1; |
1628 | } | 1632 | } |
1629 | for(apic = 0; apic < nr_ioapics; apic++) { | 1633 | for (apic = 0; apic < nr_ioapics; apic++) { |
1630 | int pin; | 1634 | int pin; |
1631 | /* See if any of the pins is in ExtINT mode */ | 1635 | /* See if any of the pins is in ExtINT mode */ |
1632 | for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { | 1636 | for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { |
@@ -1716,7 +1720,6 @@ void disable_IO_APIC(void) | |||
1716 | * by Matt Domsch <Matt_Domsch@dell.com> Tue Dec 21 12:25:05 CST 1999 | 1720 | * by Matt Domsch <Matt_Domsch@dell.com> Tue Dec 21 12:25:05 CST 1999 |
1717 | */ | 1721 | */ |
1718 | 1722 | ||
1719 | #ifndef CONFIG_X86_NUMAQ | ||
1720 | static void __init setup_ioapic_ids_from_mpc(void) | 1723 | static void __init setup_ioapic_ids_from_mpc(void) |
1721 | { | 1724 | { |
1722 | union IO_APIC_reg_00 reg_00; | 1725 | union IO_APIC_reg_00 reg_00; |
@@ -1726,6 +1729,11 @@ static void __init setup_ioapic_ids_from_mpc(void) | |||
1726 | unsigned char old_id; | 1729 | unsigned char old_id; |
1727 | unsigned long flags; | 1730 | unsigned long flags; |
1728 | 1731 | ||
1732 | #ifdef CONFIG_X86_NUMAQ | ||
1733 | if (found_numaq) | ||
1734 | return; | ||
1735 | #endif | ||
1736 | |||
1729 | /* | 1737 | /* |
1730 | * Don't check I/O APIC IDs for xAPIC systems. They have | 1738 | * Don't check I/O APIC IDs for xAPIC systems. They have |
1731 | * no meaning without the serial APIC bus. | 1739 | * no meaning without the serial APIC bus. |
@@ -1748,15 +1756,15 @@ static void __init setup_ioapic_ids_from_mpc(void) | |||
1748 | spin_lock_irqsave(&ioapic_lock, flags); | 1756 | spin_lock_irqsave(&ioapic_lock, flags); |
1749 | reg_00.raw = io_apic_read(apic, 0); | 1757 | reg_00.raw = io_apic_read(apic, 0); |
1750 | spin_unlock_irqrestore(&ioapic_lock, flags); | 1758 | spin_unlock_irqrestore(&ioapic_lock, flags); |
1751 | |||
1752 | old_id = mp_ioapics[apic].mpc_apicid; | ||
1753 | 1759 | ||
1754 | if (mp_ioapics[apic].mpc_apicid >= get_physical_broadcast()) { | 1760 | old_id = mp_ioapics[apic].mp_apicid; |
1761 | |||
1762 | if (mp_ioapics[apic].mp_apicid >= get_physical_broadcast()) { | ||
1755 | printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n", | 1763 | printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n", |
1756 | apic, mp_ioapics[apic].mpc_apicid); | 1764 | apic, mp_ioapics[apic].mp_apicid); |
1757 | printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n", | 1765 | printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n", |
1758 | reg_00.bits.ID); | 1766 | reg_00.bits.ID); |
1759 | mp_ioapics[apic].mpc_apicid = reg_00.bits.ID; | 1767 | mp_ioapics[apic].mp_apicid = reg_00.bits.ID; |
1760 | } | 1768 | } |
1761 | 1769 | ||
1762 | /* | 1770 | /* |
@@ -1765,9 +1773,9 @@ static void __init setup_ioapic_ids_from_mpc(void) | |||
1765 | * 'stuck on smp_invalidate_needed IPI wait' messages. | 1773 | * 'stuck on smp_invalidate_needed IPI wait' messages. |
1766 | */ | 1774 | */ |
1767 | if (check_apicid_used(phys_id_present_map, | 1775 | if (check_apicid_used(phys_id_present_map, |
1768 | mp_ioapics[apic].mpc_apicid)) { | 1776 | mp_ioapics[apic].mp_apicid)) { |
1769 | printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n", | 1777 | printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n", |
1770 | apic, mp_ioapics[apic].mpc_apicid); | 1778 | apic, mp_ioapics[apic].mp_apicid); |
1771 | for (i = 0; i < get_physical_broadcast(); i++) | 1779 | for (i = 0; i < get_physical_broadcast(); i++) |
1772 | if (!physid_isset(i, phys_id_present_map)) | 1780 | if (!physid_isset(i, phys_id_present_map)) |
1773 | break; | 1781 | break; |
@@ -1776,13 +1784,13 @@ static void __init setup_ioapic_ids_from_mpc(void) | |||
1776 | printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n", | 1784 | printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n", |
1777 | i); | 1785 | i); |
1778 | physid_set(i, phys_id_present_map); | 1786 | physid_set(i, phys_id_present_map); |
1779 | mp_ioapics[apic].mpc_apicid = i; | 1787 | mp_ioapics[apic].mp_apicid = i; |
1780 | } else { | 1788 | } else { |
1781 | physid_mask_t tmp; | 1789 | physid_mask_t tmp; |
1782 | tmp = apicid_to_cpu_present(mp_ioapics[apic].mpc_apicid); | 1790 | tmp = apicid_to_cpu_present(mp_ioapics[apic].mp_apicid); |
1783 | apic_printk(APIC_VERBOSE, "Setting %d in the " | 1791 | apic_printk(APIC_VERBOSE, "Setting %d in the " |
1784 | "phys_id_present_map\n", | 1792 | "phys_id_present_map\n", |
1785 | mp_ioapics[apic].mpc_apicid); | 1793 | mp_ioapics[apic].mp_apicid); |
1786 | physids_or(phys_id_present_map, phys_id_present_map, tmp); | 1794 | physids_or(phys_id_present_map, phys_id_present_map, tmp); |
1787 | } | 1795 | } |
1788 | 1796 | ||
@@ -1791,21 +1799,21 @@ static void __init setup_ioapic_ids_from_mpc(void) | |||
1791 | * We need to adjust the IRQ routing table | 1799 | * We need to adjust the IRQ routing table |
1792 | * if the ID changed. | 1800 | * if the ID changed. |
1793 | */ | 1801 | */ |
1794 | if (old_id != mp_ioapics[apic].mpc_apicid) | 1802 | if (old_id != mp_ioapics[apic].mp_apicid) |
1795 | for (i = 0; i < mp_irq_entries; i++) | 1803 | for (i = 0; i < mp_irq_entries; i++) |
1796 | if (mp_irqs[i].mpc_dstapic == old_id) | 1804 | if (mp_irqs[i].mp_dstapic == old_id) |
1797 | mp_irqs[i].mpc_dstapic | 1805 | mp_irqs[i].mp_dstapic |
1798 | = mp_ioapics[apic].mpc_apicid; | 1806 | = mp_ioapics[apic].mp_apicid; |
1799 | 1807 | ||
1800 | /* | 1808 | /* |
1801 | * Read the right value from the MPC table and | 1809 | * Read the right value from the MPC table and |
1802 | * write it into the ID register. | 1810 | * write it into the ID register. |
1803 | */ | 1811 | */ |
1804 | apic_printk(APIC_VERBOSE, KERN_INFO | 1812 | apic_printk(APIC_VERBOSE, KERN_INFO |
1805 | "...changing IO-APIC physical APIC ID to %d ...", | 1813 | "...changing IO-APIC physical APIC ID to %d ...", |
1806 | mp_ioapics[apic].mpc_apicid); | 1814 | mp_ioapics[apic].mp_apicid); |
1807 | 1815 | ||
1808 | reg_00.bits.ID = mp_ioapics[apic].mpc_apicid; | 1816 | reg_00.bits.ID = mp_ioapics[apic].mp_apicid; |
1809 | spin_lock_irqsave(&ioapic_lock, flags); | 1817 | spin_lock_irqsave(&ioapic_lock, flags); |
1810 | io_apic_write(apic, 0, reg_00.raw); | 1818 | io_apic_write(apic, 0, reg_00.raw); |
1811 | spin_unlock_irqrestore(&ioapic_lock, flags); | 1819 | spin_unlock_irqrestore(&ioapic_lock, flags); |
@@ -1816,15 +1824,12 @@ static void __init setup_ioapic_ids_from_mpc(void) | |||
1816 | spin_lock_irqsave(&ioapic_lock, flags); | 1824 | spin_lock_irqsave(&ioapic_lock, flags); |
1817 | reg_00.raw = io_apic_read(apic, 0); | 1825 | reg_00.raw = io_apic_read(apic, 0); |
1818 | spin_unlock_irqrestore(&ioapic_lock, flags); | 1826 | spin_unlock_irqrestore(&ioapic_lock, flags); |
1819 | if (reg_00.bits.ID != mp_ioapics[apic].mpc_apicid) | 1827 | if (reg_00.bits.ID != mp_ioapics[apic].mp_apicid) |
1820 | printk("could not set ID!\n"); | 1828 | printk("could not set ID!\n"); |
1821 | else | 1829 | else |
1822 | apic_printk(APIC_VERBOSE, " ok.\n"); | 1830 | apic_printk(APIC_VERBOSE, " ok.\n"); |
1823 | } | 1831 | } |
1824 | } | 1832 | } |
1825 | #else | ||
1826 | static void __init setup_ioapic_ids_from_mpc(void) { } | ||
1827 | #endif | ||
1828 | 1833 | ||
1829 | int no_timer_check __initdata; | 1834 | int no_timer_check __initdata; |
1830 | 1835 | ||
@@ -2015,12 +2020,12 @@ static inline void init_IO_APIC_traps(void) | |||
2015 | * The local APIC irq-chip implementation: | 2020 | * The local APIC irq-chip implementation: |
2016 | */ | 2021 | */ |
2017 | 2022 | ||
2018 | static void ack_apic(unsigned int irq) | 2023 | static void ack_lapic_irq(unsigned int irq) |
2019 | { | 2024 | { |
2020 | ack_APIC_irq(); | 2025 | ack_APIC_irq(); |
2021 | } | 2026 | } |
2022 | 2027 | ||
2023 | static void mask_lapic_irq (unsigned int irq) | 2028 | static void mask_lapic_irq(unsigned int irq) |
2024 | { | 2029 | { |
2025 | unsigned long v; | 2030 | unsigned long v; |
2026 | 2031 | ||
@@ -2028,7 +2033,7 @@ static void mask_lapic_irq (unsigned int irq) | |||
2028 | apic_write_around(APIC_LVT0, v | APIC_LVT_MASKED); | 2033 | apic_write_around(APIC_LVT0, v | APIC_LVT_MASKED); |
2029 | } | 2034 | } |
2030 | 2035 | ||
2031 | static void unmask_lapic_irq (unsigned int irq) | 2036 | static void unmask_lapic_irq(unsigned int irq) |
2032 | { | 2037 | { |
2033 | unsigned long v; | 2038 | unsigned long v; |
2034 | 2039 | ||
@@ -2037,23 +2042,31 @@ static void unmask_lapic_irq (unsigned int irq) | |||
2037 | } | 2042 | } |
2038 | 2043 | ||
2039 | static struct irq_chip lapic_chip __read_mostly = { | 2044 | static struct irq_chip lapic_chip __read_mostly = { |
2040 | .name = "local-APIC-edge", | 2045 | .name = "local-APIC", |
2041 | .mask = mask_lapic_irq, | 2046 | .mask = mask_lapic_irq, |
2042 | .unmask = unmask_lapic_irq, | 2047 | .unmask = unmask_lapic_irq, |
2043 | .eoi = ack_apic, | 2048 | .ack = ack_lapic_irq, |
2044 | }; | 2049 | }; |
2045 | 2050 | ||
2051 | static void lapic_register_intr(int irq, int vector) | ||
2052 | { | ||
2053 | irq_desc[irq].status &= ~IRQ_LEVEL; | ||
2054 | set_irq_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq, | ||
2055 | "edge"); | ||
2056 | set_intr_gate(vector, interrupt[irq]); | ||
2057 | } | ||
2058 | |||
2046 | static void __init setup_nmi(void) | 2059 | static void __init setup_nmi(void) |
2047 | { | 2060 | { |
2048 | /* | 2061 | /* |
2049 | * Dirty trick to enable the NMI watchdog ... | 2062 | * Dirty trick to enable the NMI watchdog ... |
2050 | * We put the 8259A master into AEOI mode and | 2063 | * We put the 8259A master into AEOI mode and |
2051 | * unmask on all local APICs LVT0 as NMI. | 2064 | * unmask on all local APICs LVT0 as NMI. |
2052 | * | 2065 | * |
2053 | * The idea to use the 8259A in AEOI mode ('8259A Virtual Wire') | 2066 | * The idea to use the 8259A in AEOI mode ('8259A Virtual Wire') |
2054 | * is from Maciej W. Rozycki - so we do not have to EOI from | 2067 | * is from Maciej W. Rozycki - so we do not have to EOI from |
2055 | * the NMI handler or the timer interrupt. | 2068 | * the NMI handler or the timer interrupt. |
2056 | */ | 2069 | */ |
2057 | apic_printk(APIC_VERBOSE, KERN_INFO "activating NMI Watchdog ..."); | 2070 | apic_printk(APIC_VERBOSE, KERN_INFO "activating NMI Watchdog ..."); |
2058 | 2071 | ||
2059 | enable_NMI_through_LVT0(); | 2072 | enable_NMI_through_LVT0(); |
@@ -2129,11 +2142,16 @@ static inline void __init unlock_ExtINT_logic(void) | |||
2129 | static inline void __init check_timer(void) | 2142 | static inline void __init check_timer(void) |
2130 | { | 2143 | { |
2131 | int apic1, pin1, apic2, pin2; | 2144 | int apic1, pin1, apic2, pin2; |
2145 | int no_pin1 = 0; | ||
2132 | int vector; | 2146 | int vector; |
2147 | unsigned int ver; | ||
2133 | unsigned long flags; | 2148 | unsigned long flags; |
2134 | 2149 | ||
2135 | local_irq_save(flags); | 2150 | local_irq_save(flags); |
2136 | 2151 | ||
2152 | ver = apic_read(APIC_LVR); | ||
2153 | ver = GET_APIC_VERSION(ver); | ||
2154 | |||
2137 | /* | 2155 | /* |
2138 | * get/set the timer IRQ vector: | 2156 | * get/set the timer IRQ vector: |
2139 | */ | 2157 | */ |
@@ -2142,17 +2160,17 @@ static inline void __init check_timer(void) | |||
2142 | set_intr_gate(vector, interrupt[0]); | 2160 | set_intr_gate(vector, interrupt[0]); |
2143 | 2161 | ||
2144 | /* | 2162 | /* |
2145 | * Subtle, code in do_timer_interrupt() expects an AEOI | 2163 | * As IRQ0 is to be enabled in the 8259A, the virtual |
2146 | * mode for the 8259A whenever interrupts are routed | 2164 | * wire has to be disabled in the local APIC. Also |
2147 | * through I/O APICs. Also IRQ0 has to be enabled in | 2165 | * timer interrupts need to be acknowledged manually in |
2148 | * the 8259A which implies the virtual wire has to be | 2166 | * the 8259A for the i82489DX when using the NMI |
2149 | * disabled in the local APIC. | 2167 | * watchdog as that APIC treats NMIs as level-triggered. |
2168 | * The AEOI mode will finish them in the 8259A | ||
2169 | * automatically. | ||
2150 | */ | 2170 | */ |
2151 | apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); | 2171 | apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); |
2152 | init_8259A(1); | 2172 | init_8259A(1); |
2153 | timer_ack = 1; | 2173 | timer_ack = (nmi_watchdog == NMI_IO_APIC && !APIC_INTEGRATED(ver)); |
2154 | if (timer_over_8254 > 0) | ||
2155 | enable_8259A_irq(0); | ||
2156 | 2174 | ||
2157 | pin1 = find_isa_irq_pin(0, mp_INT); | 2175 | pin1 = find_isa_irq_pin(0, mp_INT); |
2158 | apic1 = find_isa_irq_apic(0, mp_INT); | 2176 | apic1 = find_isa_irq_apic(0, mp_INT); |
@@ -2162,14 +2180,33 @@ static inline void __init check_timer(void) | |||
2162 | printk(KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n", | 2180 | printk(KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n", |
2163 | vector, apic1, pin1, apic2, pin2); | 2181 | vector, apic1, pin1, apic2, pin2); |
2164 | 2182 | ||
2183 | /* | ||
2184 | * Some BIOS writers are clueless and report the ExtINTA | ||
2185 | * I/O APIC input from the cascaded 8259A as the timer | ||
2186 | * interrupt input. So just in case, if only one pin | ||
2187 | * was found above, try it both directly and through the | ||
2188 | * 8259A. | ||
2189 | */ | ||
2190 | if (pin1 == -1) { | ||
2191 | pin1 = pin2; | ||
2192 | apic1 = apic2; | ||
2193 | no_pin1 = 1; | ||
2194 | } else if (pin2 == -1) { | ||
2195 | pin2 = pin1; | ||
2196 | apic2 = apic1; | ||
2197 | } | ||
2198 | |||
2165 | if (pin1 != -1) { | 2199 | if (pin1 != -1) { |
2166 | /* | 2200 | /* |
2167 | * Ok, does IRQ0 through the IOAPIC work? | 2201 | * Ok, does IRQ0 through the IOAPIC work? |
2168 | */ | 2202 | */ |
2203 | if (no_pin1) { | ||
2204 | add_pin_to_irq(0, apic1, pin1); | ||
2205 | setup_timer_IRQ0_pin(apic1, pin1, vector); | ||
2206 | } | ||
2169 | unmask_IO_APIC_irq(0); | 2207 | unmask_IO_APIC_irq(0); |
2170 | if (timer_irq_works()) { | 2208 | if (timer_irq_works()) { |
2171 | if (nmi_watchdog == NMI_IO_APIC) { | 2209 | if (nmi_watchdog == NMI_IO_APIC) { |
2172 | disable_8259A_irq(0); | ||
2173 | setup_nmi(); | 2210 | setup_nmi(); |
2174 | enable_8259A_irq(0); | 2211 | enable_8259A_irq(0); |
2175 | } | 2212 | } |
@@ -2178,45 +2215,47 @@ static inline void __init check_timer(void) | |||
2178 | goto out; | 2215 | goto out; |
2179 | } | 2216 | } |
2180 | clear_IO_APIC_pin(apic1, pin1); | 2217 | clear_IO_APIC_pin(apic1, pin1); |
2181 | printk(KERN_ERR "..MP-BIOS bug: 8254 timer not connected to " | 2218 | if (!no_pin1) |
2182 | "IO-APIC\n"); | 2219 | printk(KERN_ERR "..MP-BIOS bug: " |
2183 | } | 2220 | "8254 timer not connected to IO-APIC\n"); |
2184 | 2221 | ||
2185 | printk(KERN_INFO "...trying to set up timer (IRQ0) through the 8259A ... "); | 2222 | printk(KERN_INFO "...trying to set up timer (IRQ0) " |
2186 | if (pin2 != -1) { | 2223 | "through the 8259A ... "); |
2187 | printk("\n..... (found pin %d) ...", pin2); | 2224 | printk("\n..... (found pin %d) ...", pin2); |
2188 | /* | 2225 | /* |
2189 | * legacy devices should be connected to IO APIC #0 | 2226 | * legacy devices should be connected to IO APIC #0 |
2190 | */ | 2227 | */ |
2191 | setup_ExtINT_IRQ0_pin(apic2, pin2, vector); | 2228 | replace_pin_at_irq(0, apic1, pin1, apic2, pin2); |
2229 | setup_timer_IRQ0_pin(apic2, pin2, vector); | ||
2230 | unmask_IO_APIC_irq(0); | ||
2231 | enable_8259A_irq(0); | ||
2192 | if (timer_irq_works()) { | 2232 | if (timer_irq_works()) { |
2193 | printk("works.\n"); | 2233 | printk("works.\n"); |
2194 | if (pin1 != -1) | 2234 | timer_through_8259 = 1; |
2195 | replace_pin_at_irq(0, apic1, pin1, apic2, pin2); | ||
2196 | else | ||
2197 | add_pin_to_irq(0, apic2, pin2); | ||
2198 | if (nmi_watchdog == NMI_IO_APIC) { | 2235 | if (nmi_watchdog == NMI_IO_APIC) { |
2236 | disable_8259A_irq(0); | ||
2199 | setup_nmi(); | 2237 | setup_nmi(); |
2238 | enable_8259A_irq(0); | ||
2200 | } | 2239 | } |
2201 | goto out; | 2240 | goto out; |
2202 | } | 2241 | } |
2203 | /* | 2242 | /* |
2204 | * Cleanup, just in case ... | 2243 | * Cleanup, just in case ... |
2205 | */ | 2244 | */ |
2245 | disable_8259A_irq(0); | ||
2206 | clear_IO_APIC_pin(apic2, pin2); | 2246 | clear_IO_APIC_pin(apic2, pin2); |
2247 | printk(" failed.\n"); | ||
2207 | } | 2248 | } |
2208 | printk(" failed.\n"); | ||
2209 | 2249 | ||
2210 | if (nmi_watchdog == NMI_IO_APIC) { | 2250 | if (nmi_watchdog == NMI_IO_APIC) { |
2211 | printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n"); | 2251 | printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n"); |
2212 | nmi_watchdog = 0; | 2252 | nmi_watchdog = NMI_NONE; |
2213 | } | 2253 | } |
2254 | timer_ack = 0; | ||
2214 | 2255 | ||
2215 | printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); | 2256 | printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); |
2216 | 2257 | ||
2217 | disable_8259A_irq(0); | 2258 | lapic_register_intr(0, vector); |
2218 | set_irq_chip_and_handler_name(0, &lapic_chip, handle_fasteoi_irq, | ||
2219 | "fasteoi"); | ||
2220 | apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */ | 2259 | apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */ |
2221 | enable_8259A_irq(0); | 2260 | enable_8259A_irq(0); |
2222 | 2261 | ||
@@ -2224,12 +2263,12 @@ static inline void __init check_timer(void) | |||
2224 | printk(" works.\n"); | 2263 | printk(" works.\n"); |
2225 | goto out; | 2264 | goto out; |
2226 | } | 2265 | } |
2266 | disable_8259A_irq(0); | ||
2227 | apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | vector); | 2267 | apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | vector); |
2228 | printk(" failed.\n"); | 2268 | printk(" failed.\n"); |
2229 | 2269 | ||
2230 | printk(KERN_INFO "...trying to set up timer as ExtINT IRQ..."); | 2270 | printk(KERN_INFO "...trying to set up timer as ExtINT IRQ..."); |
2231 | 2271 | ||
2232 | timer_ack = 0; | ||
2233 | init_8259A(0); | 2272 | init_8259A(0); |
2234 | make_8259A_irq(0); | 2273 | make_8259A_irq(0); |
2235 | apic_write_around(APIC_LVT0, APIC_DM_EXTINT); | 2274 | apic_write_around(APIC_LVT0, APIC_DM_EXTINT); |
@@ -2248,11 +2287,21 @@ out: | |||
2248 | } | 2287 | } |
2249 | 2288 | ||
2250 | /* | 2289 | /* |
2251 | * | 2290 | * Traditionally ISA IRQ2 is the cascade IRQ, and is not available |
2252 | * IRQ's that are handled by the PIC in the MPS IOAPIC case. | 2291 | * to devices. However there may be an I/O APIC pin available for |
2253 | * - IRQ2 is the cascade IRQ, and cannot be a io-apic IRQ. | 2292 | * this interrupt regardless. The pin may be left unconnected, but |
2254 | * Linux doesn't really care, as it's not actually used | 2293 | * typically it will be reused as an ExtINT cascade interrupt for |
2255 | * for any interrupt handling anyway. | 2294 | * the master 8259A. In the MPS case such a pin will normally be |
2295 | * reported as an ExtINT interrupt in the MP table. With ACPI | ||
2296 | * there is no provision for ExtINT interrupts, and in the absence | ||
2297 | * of an override it would be treated as an ordinary ISA I/O APIC | ||
2298 | * interrupt, that is edge-triggered and unmasked by default. We | ||
2299 | * used to do this, but it caused problems on some systems because | ||
2300 | * of the NMI watchdog and sometimes IRQ0 of the 8254 timer using | ||
2301 | * the same ExtINT cascade interrupt to drive the local APIC of the | ||
2302 | * bootstrap processor. Therefore we refrain from routing IRQ2 to | ||
2303 | * the I/O APIC in all cases now. No actual device should request | ||
2304 | * it anyway. --macro | ||
2256 | */ | 2305 | */ |
2257 | #define PIC_IRQS (1 << PIC_CASCADE_IR) | 2306 | #define PIC_IRQS (1 << PIC_CASCADE_IR) |
2258 | 2307 | ||
@@ -2261,15 +2310,12 @@ void __init setup_IO_APIC(void) | |||
2261 | int i; | 2310 | int i; |
2262 | 2311 | ||
2263 | /* Reserve all the system vectors. */ | 2312 | /* Reserve all the system vectors. */ |
2264 | for (i = FIRST_SYSTEM_VECTOR; i < NR_VECTORS; i++) | 2313 | for (i = first_system_vector; i < NR_VECTORS; i++) |
2265 | set_bit(i, used_vectors); | 2314 | set_bit(i, used_vectors); |
2266 | 2315 | ||
2267 | enable_IO_APIC(); | 2316 | enable_IO_APIC(); |
2268 | 2317 | ||
2269 | if (acpi_ioapic) | 2318 | io_apic_irqs = ~PIC_IRQS; |
2270 | io_apic_irqs = ~0; /* all IRQs go through IOAPIC */ | ||
2271 | else | ||
2272 | io_apic_irqs = ~PIC_IRQS; | ||
2273 | 2319 | ||
2274 | printk("ENABLING IO-APIC IRQs\n"); | 2320 | printk("ENABLING IO-APIC IRQs\n"); |
2275 | 2321 | ||
@@ -2286,28 +2332,14 @@ void __init setup_IO_APIC(void) | |||
2286 | print_IO_APIC(); | 2332 | print_IO_APIC(); |
2287 | } | 2333 | } |
2288 | 2334 | ||
2289 | static int __init setup_disable_8254_timer(char *s) | ||
2290 | { | ||
2291 | timer_over_8254 = -1; | ||
2292 | return 1; | ||
2293 | } | ||
2294 | static int __init setup_enable_8254_timer(char *s) | ||
2295 | { | ||
2296 | timer_over_8254 = 2; | ||
2297 | return 1; | ||
2298 | } | ||
2299 | |||
2300 | __setup("disable_8254_timer", setup_disable_8254_timer); | ||
2301 | __setup("enable_8254_timer", setup_enable_8254_timer); | ||
2302 | |||
2303 | /* | 2335 | /* |
2304 | * Called after all the initialization is done. If we didnt find any | 2336 | * Called after all the initialization is done. If we didnt find any |
2305 | * APIC bugs then we can allow the modify fast path | 2337 | * APIC bugs then we can allow the modify fast path |
2306 | */ | 2338 | */ |
2307 | 2339 | ||
2308 | static int __init io_apic_bug_finalize(void) | 2340 | static int __init io_apic_bug_finalize(void) |
2309 | { | 2341 | { |
2310 | if(sis_apic_bug == -1) | 2342 | if (sis_apic_bug == -1) |
2311 | sis_apic_bug = 0; | 2343 | sis_apic_bug = 0; |
2312 | return 0; | 2344 | return 0; |
2313 | } | 2345 | } |
@@ -2318,17 +2350,17 @@ struct sysfs_ioapic_data { | |||
2318 | struct sys_device dev; | 2350 | struct sys_device dev; |
2319 | struct IO_APIC_route_entry entry[0]; | 2351 | struct IO_APIC_route_entry entry[0]; |
2320 | }; | 2352 | }; |
2321 | static struct sysfs_ioapic_data * mp_ioapic_data[MAX_IO_APICS]; | 2353 | static struct sysfs_ioapic_data *mp_ioapic_data[MAX_IO_APICS]; |
2322 | 2354 | ||
2323 | static int ioapic_suspend(struct sys_device *dev, pm_message_t state) | 2355 | static int ioapic_suspend(struct sys_device *dev, pm_message_t state) |
2324 | { | 2356 | { |
2325 | struct IO_APIC_route_entry *entry; | 2357 | struct IO_APIC_route_entry *entry; |
2326 | struct sysfs_ioapic_data *data; | 2358 | struct sysfs_ioapic_data *data; |
2327 | int i; | 2359 | int i; |
2328 | 2360 | ||
2329 | data = container_of(dev, struct sysfs_ioapic_data, dev); | 2361 | data = container_of(dev, struct sysfs_ioapic_data, dev); |
2330 | entry = data->entry; | 2362 | entry = data->entry; |
2331 | for (i = 0; i < nr_ioapic_registers[dev->id]; i ++) | 2363 | for (i = 0; i < nr_ioapic_registers[dev->id]; i++) |
2332 | entry[i] = ioapic_read_entry(dev->id, i); | 2364 | entry[i] = ioapic_read_entry(dev->id, i); |
2333 | 2365 | ||
2334 | return 0; | 2366 | return 0; |
@@ -2341,18 +2373,18 @@ static int ioapic_resume(struct sys_device *dev) | |||
2341 | unsigned long flags; | 2373 | unsigned long flags; |
2342 | union IO_APIC_reg_00 reg_00; | 2374 | union IO_APIC_reg_00 reg_00; |
2343 | int i; | 2375 | int i; |
2344 | 2376 | ||
2345 | data = container_of(dev, struct sysfs_ioapic_data, dev); | 2377 | data = container_of(dev, struct sysfs_ioapic_data, dev); |
2346 | entry = data->entry; | 2378 | entry = data->entry; |
2347 | 2379 | ||
2348 | spin_lock_irqsave(&ioapic_lock, flags); | 2380 | spin_lock_irqsave(&ioapic_lock, flags); |
2349 | reg_00.raw = io_apic_read(dev->id, 0); | 2381 | reg_00.raw = io_apic_read(dev->id, 0); |
2350 | if (reg_00.bits.ID != mp_ioapics[dev->id].mpc_apicid) { | 2382 | if (reg_00.bits.ID != mp_ioapics[dev->id].mp_apicid) { |
2351 | reg_00.bits.ID = mp_ioapics[dev->id].mpc_apicid; | 2383 | reg_00.bits.ID = mp_ioapics[dev->id].mp_apicid; |
2352 | io_apic_write(dev->id, 0, reg_00.raw); | 2384 | io_apic_write(dev->id, 0, reg_00.raw); |
2353 | } | 2385 | } |
2354 | spin_unlock_irqrestore(&ioapic_lock, flags); | 2386 | spin_unlock_irqrestore(&ioapic_lock, flags); |
2355 | for (i = 0; i < nr_ioapic_registers[dev->id]; i ++) | 2387 | for (i = 0; i < nr_ioapic_registers[dev->id]; i++) |
2356 | ioapic_write_entry(dev->id, i, entry[i]); | 2388 | ioapic_write_entry(dev->id, i, entry[i]); |
2357 | 2389 | ||
2358 | return 0; | 2390 | return 0; |
@@ -2366,24 +2398,23 @@ static struct sysdev_class ioapic_sysdev_class = { | |||
2366 | 2398 | ||
2367 | static int __init ioapic_init_sysfs(void) | 2399 | static int __init ioapic_init_sysfs(void) |
2368 | { | 2400 | { |
2369 | struct sys_device * dev; | 2401 | struct sys_device *dev; |
2370 | int i, size, error = 0; | 2402 | int i, size, error = 0; |
2371 | 2403 | ||
2372 | error = sysdev_class_register(&ioapic_sysdev_class); | 2404 | error = sysdev_class_register(&ioapic_sysdev_class); |
2373 | if (error) | 2405 | if (error) |
2374 | return error; | 2406 | return error; |
2375 | 2407 | ||
2376 | for (i = 0; i < nr_ioapics; i++ ) { | 2408 | for (i = 0; i < nr_ioapics; i++) { |
2377 | size = sizeof(struct sys_device) + nr_ioapic_registers[i] | 2409 | size = sizeof(struct sys_device) + nr_ioapic_registers[i] |
2378 | * sizeof(struct IO_APIC_route_entry); | 2410 | * sizeof(struct IO_APIC_route_entry); |
2379 | mp_ioapic_data[i] = kmalloc(size, GFP_KERNEL); | 2411 | mp_ioapic_data[i] = kzalloc(size, GFP_KERNEL); |
2380 | if (!mp_ioapic_data[i]) { | 2412 | if (!mp_ioapic_data[i]) { |
2381 | printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i); | 2413 | printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i); |
2382 | continue; | 2414 | continue; |
2383 | } | 2415 | } |
2384 | memset(mp_ioapic_data[i], 0, size); | ||
2385 | dev = &mp_ioapic_data[i]->dev; | 2416 | dev = &mp_ioapic_data[i]->dev; |
2386 | dev->id = i; | 2417 | dev->id = i; |
2387 | dev->cls = &ioapic_sysdev_class; | 2418 | dev->cls = &ioapic_sysdev_class; |
2388 | error = sysdev_register(dev); | 2419 | error = sysdev_register(dev); |
2389 | if (error) { | 2420 | if (error) { |
@@ -2458,7 +2489,7 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_ms | |||
2458 | msg->address_lo = | 2489 | msg->address_lo = |
2459 | MSI_ADDR_BASE_LO | | 2490 | MSI_ADDR_BASE_LO | |
2460 | ((INT_DEST_MODE == 0) ? | 2491 | ((INT_DEST_MODE == 0) ? |
2461 | MSI_ADDR_DEST_MODE_PHYSICAL: | 2492 | MSI_ADDR_DEST_MODE_PHYSICAL: |
2462 | MSI_ADDR_DEST_MODE_LOGICAL) | | 2493 | MSI_ADDR_DEST_MODE_LOGICAL) | |
2463 | ((INT_DELIVERY_MODE != dest_LowestPrio) ? | 2494 | ((INT_DELIVERY_MODE != dest_LowestPrio) ? |
2464 | MSI_ADDR_REDIRECTION_CPU: | 2495 | MSI_ADDR_REDIRECTION_CPU: |
@@ -2469,7 +2500,7 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_ms | |||
2469 | MSI_DATA_TRIGGER_EDGE | | 2500 | MSI_DATA_TRIGGER_EDGE | |
2470 | MSI_DATA_LEVEL_ASSERT | | 2501 | MSI_DATA_LEVEL_ASSERT | |
2471 | ((INT_DELIVERY_MODE != dest_LowestPrio) ? | 2502 | ((INT_DELIVERY_MODE != dest_LowestPrio) ? |
2472 | MSI_DATA_DELIVERY_FIXED: | 2503 | MSI_DATA_DELIVERY_FIXED: |
2473 | MSI_DATA_DELIVERY_LOWPRI) | | 2504 | MSI_DATA_DELIVERY_LOWPRI) | |
2474 | MSI_DATA_VECTOR(vector); | 2505 | MSI_DATA_VECTOR(vector); |
2475 | } | 2506 | } |
@@ -2640,12 +2671,12 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) | |||
2640 | #endif /* CONFIG_HT_IRQ */ | 2671 | #endif /* CONFIG_HT_IRQ */ |
2641 | 2672 | ||
2642 | /* -------------------------------------------------------------------------- | 2673 | /* -------------------------------------------------------------------------- |
2643 | ACPI-based IOAPIC Configuration | 2674 | ACPI-based IOAPIC Configuration |
2644 | -------------------------------------------------------------------------- */ | 2675 | -------------------------------------------------------------------------- */ |
2645 | 2676 | ||
2646 | #ifdef CONFIG_ACPI | 2677 | #ifdef CONFIG_ACPI |
2647 | 2678 | ||
2648 | int __init io_apic_get_unique_id (int ioapic, int apic_id) | 2679 | int __init io_apic_get_unique_id(int ioapic, int apic_id) |
2649 | { | 2680 | { |
2650 | union IO_APIC_reg_00 reg_00; | 2681 | union IO_APIC_reg_00 reg_00; |
2651 | static physid_mask_t apic_id_map = PHYSID_MASK_NONE; | 2682 | static physid_mask_t apic_id_map = PHYSID_MASK_NONE; |
@@ -2654,10 +2685,10 @@ int __init io_apic_get_unique_id (int ioapic, int apic_id) | |||
2654 | int i = 0; | 2685 | int i = 0; |
2655 | 2686 | ||
2656 | /* | 2687 | /* |
2657 | * The P4 platform supports up to 256 APIC IDs on two separate APIC | 2688 | * The P4 platform supports up to 256 APIC IDs on two separate APIC |
2658 | * buses (one for LAPICs, one for IOAPICs), where predecessors only | 2689 | * buses (one for LAPICs, one for IOAPICs), where predecessors only |
2659 | * supports up to 16 on one shared APIC bus. | 2690 | * supports up to 16 on one shared APIC bus. |
2660 | * | 2691 | * |
2661 | * TBD: Expand LAPIC/IOAPIC support on P4-class systems to take full | 2692 | * TBD: Expand LAPIC/IOAPIC support on P4-class systems to take full |
2662 | * advantage of new APIC bus architecture. | 2693 | * advantage of new APIC bus architecture. |
2663 | */ | 2694 | */ |
@@ -2676,7 +2707,7 @@ int __init io_apic_get_unique_id (int ioapic, int apic_id) | |||
2676 | } | 2707 | } |
2677 | 2708 | ||
2678 | /* | 2709 | /* |
2679 | * Every APIC in a system must have a unique ID or we get lots of nice | 2710 | * Every APIC in a system must have a unique ID or we get lots of nice |
2680 | * 'stuck on smp_invalidate_needed IPI wait' messages. | 2711 | * 'stuck on smp_invalidate_needed IPI wait' messages. |
2681 | */ | 2712 | */ |
2682 | if (check_apicid_used(apic_id_map, apic_id)) { | 2713 | if (check_apicid_used(apic_id_map, apic_id)) { |
@@ -2693,7 +2724,7 @@ int __init io_apic_get_unique_id (int ioapic, int apic_id) | |||
2693 | "trying %d\n", ioapic, apic_id, i); | 2724 | "trying %d\n", ioapic, apic_id, i); |
2694 | 2725 | ||
2695 | apic_id = i; | 2726 | apic_id = i; |
2696 | } | 2727 | } |
2697 | 2728 | ||
2698 | tmp = apicid_to_cpu_present(apic_id); | 2729 | tmp = apicid_to_cpu_present(apic_id); |
2699 | physids_or(apic_id_map, apic_id_map, tmp); | 2730 | physids_or(apic_id_map, apic_id_map, tmp); |
@@ -2720,7 +2751,7 @@ int __init io_apic_get_unique_id (int ioapic, int apic_id) | |||
2720 | } | 2751 | } |
2721 | 2752 | ||
2722 | 2753 | ||
2723 | int __init io_apic_get_version (int ioapic) | 2754 | int __init io_apic_get_version(int ioapic) |
2724 | { | 2755 | { |
2725 | union IO_APIC_reg_01 reg_01; | 2756 | union IO_APIC_reg_01 reg_01; |
2726 | unsigned long flags; | 2757 | unsigned long flags; |
@@ -2733,7 +2764,7 @@ int __init io_apic_get_version (int ioapic) | |||
2733 | } | 2764 | } |
2734 | 2765 | ||
2735 | 2766 | ||
2736 | int __init io_apic_get_redir_entries (int ioapic) | 2767 | int __init io_apic_get_redir_entries(int ioapic) |
2737 | { | 2768 | { |
2738 | union IO_APIC_reg_01 reg_01; | 2769 | union IO_APIC_reg_01 reg_01; |
2739 | unsigned long flags; | 2770 | unsigned long flags; |
@@ -2746,7 +2777,7 @@ int __init io_apic_get_redir_entries (int ioapic) | |||
2746 | } | 2777 | } |
2747 | 2778 | ||
2748 | 2779 | ||
2749 | int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int active_high_low) | 2780 | int io_apic_set_pci_routing(int ioapic, int pin, int irq, int edge_level, int active_high_low) |
2750 | { | 2781 | { |
2751 | struct IO_APIC_route_entry entry; | 2782 | struct IO_APIC_route_entry entry; |
2752 | 2783 | ||
@@ -2762,7 +2793,7 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a | |||
2762 | * corresponding device driver registers for this IRQ. | 2793 | * corresponding device driver registers for this IRQ. |
2763 | */ | 2794 | */ |
2764 | 2795 | ||
2765 | memset(&entry,0,sizeof(entry)); | 2796 | memset(&entry, 0, sizeof(entry)); |
2766 | 2797 | ||
2767 | entry.delivery_mode = INT_DELIVERY_MODE; | 2798 | entry.delivery_mode = INT_DELIVERY_MODE; |
2768 | entry.dest_mode = INT_DEST_MODE; | 2799 | entry.dest_mode = INT_DEST_MODE; |
@@ -2781,7 +2812,7 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a | |||
2781 | 2812 | ||
2782 | apic_printk(APIC_DEBUG, KERN_DEBUG "IOAPIC[%d]: Set PCI routing entry " | 2813 | apic_printk(APIC_DEBUG, KERN_DEBUG "IOAPIC[%d]: Set PCI routing entry " |
2783 | "(%d-%d -> 0x%x -> IRQ %d Mode:%i Active:%i)\n", ioapic, | 2814 | "(%d-%d -> 0x%x -> IRQ %d Mode:%i Active:%i)\n", ioapic, |
2784 | mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq, | 2815 | mp_ioapics[ioapic].mp_apicid, pin, entry.vector, irq, |
2785 | edge_level, active_high_low); | 2816 | edge_level, active_high_low); |
2786 | 2817 | ||
2787 | ioapic_register_intr(irq, entry.vector, edge_level); | 2818 | ioapic_register_intr(irq, entry.vector, edge_level); |
@@ -2802,8 +2833,8 @@ int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity) | |||
2802 | return -1; | 2833 | return -1; |
2803 | 2834 | ||
2804 | for (i = 0; i < mp_irq_entries; i++) | 2835 | for (i = 0; i < mp_irq_entries; i++) |
2805 | if (mp_irqs[i].mpc_irqtype == mp_INT && | 2836 | if (mp_irqs[i].mp_irqtype == mp_INT && |
2806 | mp_irqs[i].mpc_srcbusirq == bus_irq) | 2837 | mp_irqs[i].mp_srcbusirq == bus_irq) |
2807 | break; | 2838 | break; |
2808 | if (i >= mp_irq_entries) | 2839 | if (i >= mp_irq_entries) |
2809 | return -1; | 2840 | return -1; |
@@ -2836,3 +2867,34 @@ static int __init parse_noapic(char *arg) | |||
2836 | return 0; | 2867 | return 0; |
2837 | } | 2868 | } |
2838 | early_param("noapic", parse_noapic); | 2869 | early_param("noapic", parse_noapic); |
2870 | |||
2871 | void __init ioapic_init_mappings(void) | ||
2872 | { | ||
2873 | unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0; | ||
2874 | int i; | ||
2875 | |||
2876 | for (i = 0; i < nr_ioapics; i++) { | ||
2877 | if (smp_found_config) { | ||
2878 | ioapic_phys = mp_ioapics[i].mp_apicaddr; | ||
2879 | if (!ioapic_phys) { | ||
2880 | printk(KERN_ERR | ||
2881 | "WARNING: bogus zero IO-APIC " | ||
2882 | "address found in MPTABLE, " | ||
2883 | "disabling IO/APIC support!\n"); | ||
2884 | smp_found_config = 0; | ||
2885 | skip_ioapic_setup = 1; | ||
2886 | goto fake_ioapic_page; | ||
2887 | } | ||
2888 | } else { | ||
2889 | fake_ioapic_page: | ||
2890 | ioapic_phys = (unsigned long) | ||
2891 | alloc_bootmem_pages(PAGE_SIZE); | ||
2892 | ioapic_phys = __pa(ioapic_phys); | ||
2893 | } | ||
2894 | set_fixmap_nocache(idx, ioapic_phys); | ||
2895 | printk(KERN_DEBUG "mapped IOAPIC to %08lx (%08lx)\n", | ||
2896 | __fix_to_virt(idx), ioapic_phys); | ||
2897 | idx++; | ||
2898 | } | ||
2899 | } | ||
2900 | |||