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