diff options
-rw-r--r-- | arch/Kconfig | 4 | ||||
-rw-r--r-- | arch/x86/Kconfig | 1 | ||||
-rw-r--r-- | arch/x86/kernel/io_apic_32.c | 46 | ||||
-rw-r--r-- | arch/x86/kernel/io_apic_64.c | 75 | ||||
-rw-r--r-- | arch/x86/kernel/irq_32.c | 24 | ||||
-rw-r--r-- | arch/x86/kernel/irq_64.c | 35 | ||||
-rw-r--r-- | arch/x86/kernel/irqinit_64.c | 10 | ||||
-rw-r--r-- | arch/x86/kernel/visws_quirks.c | 30 | ||||
-rw-r--r-- | arch/x86/mach-voyager/voyager_smp.c | 4 | ||||
-rw-r--r-- | drivers/gpio/gpiolib.c | 2 | ||||
-rw-r--r-- | drivers/mfd/asic3.c | 4 | ||||
-rw-r--r-- | drivers/mfd/htc-egpio.c | 2 | ||||
-rw-r--r-- | drivers/parisc/dino.c | 6 | ||||
-rw-r--r-- | drivers/parisc/eisa.c | 4 | ||||
-rw-r--r-- | drivers/parisc/gsc.c | 12 | ||||
-rw-r--r-- | drivers/parisc/iosapic.c | 4 | ||||
-rw-r--r-- | drivers/parisc/superio.c | 4 | ||||
-rw-r--r-- | drivers/pcmcia/hd64465_ss.c | 12 | ||||
-rw-r--r-- | drivers/xen/events.c | 8 | ||||
-rw-r--r-- | include/linux/irq.h | 32 | ||||
-rw-r--r-- | kernel/irq/autoprobe.c | 10 | ||||
-rw-r--r-- | kernel/irq/chip.c | 32 | ||||
-rw-r--r-- | kernel/irq/handle.c | 138 | ||||
-rw-r--r-- | kernel/irq/manage.c | 35 | ||||
-rw-r--r-- | kernel/irq/migration.c | 14 | ||||
-rw-r--r-- | kernel/irq/proc.c | 36 | ||||
-rw-r--r-- | kernel/irq/resend.c | 2 | ||||
-rw-r--r-- | kernel/irq/spurious.c | 5 |
28 files changed, 404 insertions, 187 deletions
diff --git a/arch/Kconfig b/arch/Kconfig index c1f9febb404f..b36762246265 100644 --- a/arch/Kconfig +++ b/arch/Kconfig | |||
@@ -105,3 +105,7 @@ config HAVE_CLK | |||
105 | 105 | ||
106 | config HAVE_DYN_ARRAY | 106 | config HAVE_DYN_ARRAY |
107 | def_bool n | 107 | def_bool n |
108 | |||
109 | config HAVE_SPARSE_IRQ | ||
110 | def_bool n | ||
111 | |||
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 42f98009d752..1004888e9b13 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -34,6 +34,7 @@ config X86 | |||
34 | select HAVE_GENERIC_DMA_COHERENT if X86_32 | 34 | select HAVE_GENERIC_DMA_COHERENT if X86_32 |
35 | select HAVE_EFFICIENT_UNALIGNED_ACCESS | 35 | select HAVE_EFFICIENT_UNALIGNED_ACCESS |
36 | select HAVE_DYN_ARRAY | 36 | select HAVE_DYN_ARRAY |
37 | select HAVE_SPARSE_IRQ if X86_64 | ||
37 | 38 | ||
38 | config ARCH_DEFCONFIG | 39 | config ARCH_DEFCONFIG |
39 | string | 40 | string |
diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c index 7f2bcc3dad82..c2160cfdec9b 100644 --- a/arch/x86/kernel/io_apic_32.c +++ b/arch/x86/kernel/io_apic_32.c | |||
@@ -345,6 +345,7 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask) | |||
345 | struct irq_pin_list *entry = irq_2_pin + irq; | 345 | struct irq_pin_list *entry = irq_2_pin + irq; |
346 | unsigned int apicid_value; | 346 | unsigned int apicid_value; |
347 | cpumask_t tmp; | 347 | cpumask_t tmp; |
348 | struct irq_desc *desc; | ||
348 | 349 | ||
349 | cpus_and(tmp, cpumask, cpu_online_map); | 350 | cpus_and(tmp, cpumask, cpu_online_map); |
350 | if (cpus_empty(tmp)) | 351 | if (cpus_empty(tmp)) |
@@ -365,7 +366,8 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask) | |||
365 | break; | 366 | break; |
366 | entry = irq_2_pin + entry->next; | 367 | entry = irq_2_pin + entry->next; |
367 | } | 368 | } |
368 | irq_desc[irq].affinity = cpumask; | 369 | desc = irq_to_desc(irq); |
370 | desc->affinity = cpumask; | ||
369 | spin_unlock_irqrestore(&ioapic_lock, flags); | 371 | spin_unlock_irqrestore(&ioapic_lock, flags); |
370 | } | 372 | } |
371 | 373 | ||
@@ -475,10 +477,12 @@ static inline void balance_irq(int cpu, int irq) | |||
475 | static inline void rotate_irqs_among_cpus(unsigned long useful_load_threshold) | 477 | static inline void rotate_irqs_among_cpus(unsigned long useful_load_threshold) |
476 | { | 478 | { |
477 | int i, j; | 479 | int i, j; |
480 | struct irq_desc *desc; | ||
478 | 481 | ||
479 | for_each_online_cpu(i) { | 482 | for_each_online_cpu(i) { |
480 | for (j = 0; j < nr_irqs; j++) { | 483 | for (j = 0; j < nr_irqs; j++) { |
481 | if (!irq_desc[j].action) | 484 | desc = irq_to_desc(j); |
485 | if (!desc->action) | ||
482 | continue; | 486 | continue; |
483 | /* Is it a significant load ? */ | 487 | /* Is it a significant load ? */ |
484 | if (IRQ_DELTA(CPU_TO_PACKAGEINDEX(i), j) < | 488 | if (IRQ_DELTA(CPU_TO_PACKAGEINDEX(i), j) < |
@@ -505,6 +509,7 @@ static void do_irq_balance(void) | |||
505 | unsigned long tmp_cpu_irq; | 509 | unsigned long tmp_cpu_irq; |
506 | unsigned long imbalance = 0; | 510 | unsigned long imbalance = 0; |
507 | cpumask_t allowed_mask, target_cpu_mask, tmp; | 511 | cpumask_t allowed_mask, target_cpu_mask, tmp; |
512 | struct irq_desc *desc; | ||
508 | 513 | ||
509 | for_each_possible_cpu(i) { | 514 | for_each_possible_cpu(i) { |
510 | int package_index; | 515 | int package_index; |
@@ -515,7 +520,8 @@ static void do_irq_balance(void) | |||
515 | for (j = 0; j < nr_irqs; j++) { | 520 | for (j = 0; j < nr_irqs; j++) { |
516 | unsigned long value_now, delta; | 521 | unsigned long value_now, delta; |
517 | /* Is this an active IRQ or balancing disabled ? */ | 522 | /* Is this an active IRQ or balancing disabled ? */ |
518 | if (!irq_desc[j].action || irq_balancing_disabled(j)) | 523 | desc = irq_to_desc(j); |
524 | if (!desc->action || irq_balancing_disabled(j)) | ||
519 | continue; | 525 | continue; |
520 | if (package_index == i) | 526 | if (package_index == i) |
521 | IRQ_DELTA(package_index, j) = 0; | 527 | IRQ_DELTA(package_index, j) = 0; |
@@ -609,7 +615,8 @@ tryanotherirq: | |||
609 | selected_irq = -1; | 615 | selected_irq = -1; |
610 | for (j = 0; j < nr_irqs; j++) { | 616 | for (j = 0; j < nr_irqs; j++) { |
611 | /* Is this an active IRQ? */ | 617 | /* Is this an active IRQ? */ |
612 | if (!irq_desc[j].action) | 618 | desc = irq_to_desc(j); |
619 | if (!desc->action) | ||
613 | continue; | 620 | continue; |
614 | if (imbalance <= IRQ_DELTA(max_loaded, j)) | 621 | if (imbalance <= IRQ_DELTA(max_loaded, j)) |
615 | continue; | 622 | continue; |
@@ -682,10 +689,12 @@ static int balanced_irq(void *unused) | |||
682 | int i; | 689 | int i; |
683 | unsigned long prev_balance_time = jiffies; | 690 | unsigned long prev_balance_time = jiffies; |
684 | long time_remaining = balanced_irq_interval; | 691 | long time_remaining = balanced_irq_interval; |
692 | struct irq_desc *desc; | ||
685 | 693 | ||
686 | /* push everything to CPU 0 to give us a starting point. */ | 694 | /* push everything to CPU 0 to give us a starting point. */ |
687 | for (i = 0 ; i < nr_irqs ; i++) { | 695 | for (i = 0 ; i < nr_irqs ; i++) { |
688 | irq_desc[i].pending_mask = cpumask_of_cpu(0); | 696 | desc = irq_to_desc(i); |
697 | desc->pending_mask = cpumask_of_cpu(0); | ||
689 | set_pending_irq(i, cpumask_of_cpu(0)); | 698 | set_pending_irq(i, cpumask_of_cpu(0)); |
690 | } | 699 | } |
691 | 700 | ||
@@ -1254,13 +1263,16 @@ static struct irq_chip ioapic_chip; | |||
1254 | 1263 | ||
1255 | static void ioapic_register_intr(int irq, int vector, unsigned long trigger) | 1264 | static void ioapic_register_intr(int irq, int vector, unsigned long trigger) |
1256 | { | 1265 | { |
1266 | struct irq_desc *desc; | ||
1267 | |||
1268 | desc = irq_to_desc(irq); | ||
1257 | if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || | 1269 | if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || |
1258 | trigger == IOAPIC_LEVEL) { | 1270 | trigger == IOAPIC_LEVEL) { |
1259 | irq_desc[irq].status |= IRQ_LEVEL; | 1271 | desc->status |= IRQ_LEVEL; |
1260 | set_irq_chip_and_handler_name(irq, &ioapic_chip, | 1272 | set_irq_chip_and_handler_name(irq, &ioapic_chip, |
1261 | handle_fasteoi_irq, "fasteoi"); | 1273 | handle_fasteoi_irq, "fasteoi"); |
1262 | } else { | 1274 | } else { |
1263 | irq_desc[irq].status &= ~IRQ_LEVEL; | 1275 | desc->status &= ~IRQ_LEVEL; |
1264 | set_irq_chip_and_handler_name(irq, &ioapic_chip, | 1276 | set_irq_chip_and_handler_name(irq, &ioapic_chip, |
1265 | handle_edge_irq, "edge"); | 1277 | handle_edge_irq, "edge"); |
1266 | } | 1278 | } |
@@ -2027,6 +2039,7 @@ static struct irq_chip ioapic_chip __read_mostly = { | |||
2027 | static inline void init_IO_APIC_traps(void) | 2039 | static inline void init_IO_APIC_traps(void) |
2028 | { | 2040 | { |
2029 | int irq; | 2041 | int irq; |
2042 | struct irq_desc *desc; | ||
2030 | 2043 | ||
2031 | /* | 2044 | /* |
2032 | * NOTE! The local APIC isn't very good at handling | 2045 | * NOTE! The local APIC isn't very good at handling |
@@ -2048,9 +2061,11 @@ static inline void init_IO_APIC_traps(void) | |||
2048 | */ | 2061 | */ |
2049 | if (irq < 16) | 2062 | if (irq < 16) |
2050 | make_8259A_irq(irq); | 2063 | make_8259A_irq(irq); |
2051 | else | 2064 | else { |
2065 | desc = irq_to_desc(irq); | ||
2052 | /* Strange. Oh, well.. */ | 2066 | /* Strange. Oh, well.. */ |
2053 | irq_desc[irq].chip = &no_irq_chip; | 2067 | desc->chip = &no_irq_chip; |
2068 | } | ||
2054 | } | 2069 | } |
2055 | } | 2070 | } |
2056 | } | 2071 | } |
@@ -2089,7 +2104,10 @@ static struct irq_chip lapic_chip __read_mostly = { | |||
2089 | 2104 | ||
2090 | static void lapic_register_intr(int irq, int vector) | 2105 | static void lapic_register_intr(int irq, int vector) |
2091 | { | 2106 | { |
2092 | irq_desc[irq].status &= ~IRQ_LEVEL; | 2107 | struct irq_desc *desc; |
2108 | |||
2109 | desc = irq_to_desc(irq); | ||
2110 | desc->status &= ~IRQ_LEVEL; | ||
2093 | set_irq_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq, | 2111 | set_irq_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq, |
2094 | "edge"); | 2112 | "edge"); |
2095 | set_intr_gate(vector, interrupt[irq]); | 2113 | set_intr_gate(vector, interrupt[irq]); |
@@ -2556,6 +2574,7 @@ static void set_msi_irq_affinity(unsigned int irq, cpumask_t mask) | |||
2556 | unsigned int dest; | 2574 | unsigned int dest; |
2557 | cpumask_t tmp; | 2575 | cpumask_t tmp; |
2558 | int vector; | 2576 | int vector; |
2577 | struct irq_desc *desc; | ||
2559 | 2578 | ||
2560 | cpus_and(tmp, mask, cpu_online_map); | 2579 | cpus_and(tmp, mask, cpu_online_map); |
2561 | if (cpus_empty(tmp)) | 2580 | if (cpus_empty(tmp)) |
@@ -2575,7 +2594,8 @@ static void set_msi_irq_affinity(unsigned int irq, cpumask_t mask) | |||
2575 | msg.address_lo |= MSI_ADDR_DEST_ID(dest); | 2594 | msg.address_lo |= MSI_ADDR_DEST_ID(dest); |
2576 | 2595 | ||
2577 | write_msi_msg(irq, &msg); | 2596 | write_msi_msg(irq, &msg); |
2578 | irq_desc[irq].affinity = mask; | 2597 | desc = irq_to_desc(irq); |
2598 | desc->affinity = mask; | ||
2579 | } | 2599 | } |
2580 | #endif /* CONFIG_SMP */ | 2600 | #endif /* CONFIG_SMP */ |
2581 | 2601 | ||
@@ -2649,6 +2669,7 @@ static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask) | |||
2649 | { | 2669 | { |
2650 | unsigned int dest; | 2670 | unsigned int dest; |
2651 | cpumask_t tmp; | 2671 | cpumask_t tmp; |
2672 | struct irq_desc *desc; | ||
2652 | 2673 | ||
2653 | cpus_and(tmp, mask, cpu_online_map); | 2674 | cpus_and(tmp, mask, cpu_online_map); |
2654 | if (cpus_empty(tmp)) | 2675 | if (cpus_empty(tmp)) |
@@ -2659,7 +2680,8 @@ static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask) | |||
2659 | dest = cpu_mask_to_apicid(mask); | 2680 | dest = cpu_mask_to_apicid(mask); |
2660 | 2681 | ||
2661 | target_ht_irq(irq, dest); | 2682 | target_ht_irq(irq, dest); |
2662 | irq_desc[irq].affinity = mask; | 2683 | desc = irq_to_desc(irq); |
2684 | desc->affinity = mask; | ||
2663 | } | 2685 | } |
2664 | #endif | 2686 | #endif |
2665 | 2687 | ||
diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c index 93a3ffabfe6a..cab5a25d81b1 100644 --- a/arch/x86/kernel/io_apic_64.c +++ b/arch/x86/kernel/io_apic_64.c | |||
@@ -345,6 +345,7 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask) | |||
345 | unsigned long flags; | 345 | unsigned long flags; |
346 | unsigned int dest; | 346 | unsigned int dest; |
347 | cpumask_t tmp; | 347 | cpumask_t tmp; |
348 | struct irq_desc *desc; | ||
348 | 349 | ||
349 | cpus_and(tmp, mask, cpu_online_map); | 350 | cpus_and(tmp, mask, cpu_online_map); |
350 | if (cpus_empty(tmp)) | 351 | if (cpus_empty(tmp)) |
@@ -361,9 +362,10 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask) | |||
361 | */ | 362 | */ |
362 | dest = SET_APIC_LOGICAL_ID(dest); | 363 | dest = SET_APIC_LOGICAL_ID(dest); |
363 | 364 | ||
365 | desc = irq_to_desc(irq); | ||
364 | spin_lock_irqsave(&ioapic_lock, flags); | 366 | spin_lock_irqsave(&ioapic_lock, flags); |
365 | __target_IO_APIC_irq(irq, dest, cfg->vector); | 367 | __target_IO_APIC_irq(irq, dest, cfg->vector); |
366 | irq_desc[irq].affinity = mask; | 368 | desc->affinity = mask; |
367 | spin_unlock_irqrestore(&ioapic_lock, flags); | 369 | spin_unlock_irqrestore(&ioapic_lock, flags); |
368 | } | 370 | } |
369 | #endif | 371 | #endif |
@@ -933,14 +935,17 @@ static struct irq_chip ir_ioapic_chip; | |||
933 | 935 | ||
934 | static void ioapic_register_intr(int irq, unsigned long trigger) | 936 | static void ioapic_register_intr(int irq, unsigned long trigger) |
935 | { | 937 | { |
938 | struct irq_desc *desc; | ||
939 | |||
940 | desc = irq_to_desc(irq); | ||
936 | if (trigger) | 941 | if (trigger) |
937 | irq_desc[irq].status |= IRQ_LEVEL; | 942 | desc->status |= IRQ_LEVEL; |
938 | else | 943 | else |
939 | irq_desc[irq].status &= ~IRQ_LEVEL; | 944 | desc->status &= ~IRQ_LEVEL; |
940 | 945 | ||
941 | #ifdef CONFIG_INTR_REMAP | 946 | #ifdef CONFIG_INTR_REMAP |
942 | if (irq_remapped(irq)) { | 947 | if (irq_remapped(irq)) { |
943 | irq_desc[irq].status |= IRQ_MOVE_PCNTXT; | 948 | desc->status |= IRQ_MOVE_PCNTXT; |
944 | if (trigger) | 949 | if (trigger) |
945 | set_irq_chip_and_handler_name(irq, &ir_ioapic_chip, | 950 | set_irq_chip_and_handler_name(irq, &ir_ioapic_chip, |
946 | handle_fasteoi_irq, | 951 | handle_fasteoi_irq, |
@@ -1596,10 +1601,10 @@ static DECLARE_DELAYED_WORK(ir_migration_work, ir_irq_migration); | |||
1596 | static void migrate_ioapic_irq(int irq, cpumask_t mask) | 1601 | static void migrate_ioapic_irq(int irq, cpumask_t mask) |
1597 | { | 1602 | { |
1598 | struct irq_cfg *cfg = irq_cfg + irq; | 1603 | struct irq_cfg *cfg = irq_cfg + irq; |
1599 | struct irq_desc *desc = irq_desc + irq; | 1604 | struct irq_desc *desc; |
1600 | cpumask_t tmp, cleanup_mask; | 1605 | cpumask_t tmp, cleanup_mask; |
1601 | struct irte irte; | 1606 | struct irte irte; |
1602 | int modify_ioapic_rte = desc->status & IRQ_LEVEL; | 1607 | int modify_ioapic_rte; |
1603 | unsigned int dest; | 1608 | unsigned int dest; |
1604 | unsigned long flags; | 1609 | unsigned long flags; |
1605 | 1610 | ||
@@ -1616,6 +1621,8 @@ static void migrate_ioapic_irq(int irq, cpumask_t mask) | |||
1616 | cpus_and(tmp, cfg->domain, mask); | 1621 | cpus_and(tmp, cfg->domain, mask); |
1617 | dest = cpu_mask_to_apicid(tmp); | 1622 | dest = cpu_mask_to_apicid(tmp); |
1618 | 1623 | ||
1624 | desc = irq_to_desc(irq); | ||
1625 | modify_ioapic_rte = desc->status & IRQ_LEVEL; | ||
1619 | if (modify_ioapic_rte) { | 1626 | if (modify_ioapic_rte) { |
1620 | spin_lock_irqsave(&ioapic_lock, flags); | 1627 | spin_lock_irqsave(&ioapic_lock, flags); |
1621 | __target_IO_APIC_irq(irq, dest, cfg->vector); | 1628 | __target_IO_APIC_irq(irq, dest, cfg->vector); |
@@ -1637,12 +1644,13 @@ static void migrate_ioapic_irq(int irq, cpumask_t mask) | |||
1637 | cfg->move_in_progress = 0; | 1644 | cfg->move_in_progress = 0; |
1638 | } | 1645 | } |
1639 | 1646 | ||
1640 | irq_desc[irq].affinity = mask; | 1647 | desc->affinity = mask; |
1641 | } | 1648 | } |
1642 | 1649 | ||
1643 | static int migrate_irq_remapped_level(int irq) | 1650 | static int migrate_irq_remapped_level(int irq) |
1644 | { | 1651 | { |
1645 | int ret = -1; | 1652 | int ret = -1; |
1653 | struct irq_desc *desc = irq_to_desc(irq); | ||
1646 | 1654 | ||
1647 | mask_IO_APIC_irq(irq); | 1655 | mask_IO_APIC_irq(irq); |
1648 | 1656 | ||
@@ -1658,11 +1666,11 @@ static int migrate_irq_remapped_level(int irq) | |||
1658 | } | 1666 | } |
1659 | 1667 | ||
1660 | /* everthing is clear. we have right of way */ | 1668 | /* everthing is clear. we have right of way */ |
1661 | migrate_ioapic_irq(irq, irq_desc[irq].pending_mask); | 1669 | migrate_ioapic_irq(irq, desc->pending_mask); |
1662 | 1670 | ||
1663 | ret = 0; | 1671 | ret = 0; |
1664 | irq_desc[irq].status &= ~IRQ_MOVE_PENDING; | 1672 | desc->status &= ~IRQ_MOVE_PENDING; |
1665 | cpus_clear(irq_desc[irq].pending_mask); | 1673 | cpus_clear(desc->pending_mask); |
1666 | 1674 | ||
1667 | unmask: | 1675 | unmask: |
1668 | unmask_IO_APIC_irq(irq); | 1676 | unmask_IO_APIC_irq(irq); |
@@ -1674,7 +1682,7 @@ static void ir_irq_migration(struct work_struct *work) | |||
1674 | int irq; | 1682 | int irq; |
1675 | 1683 | ||
1676 | for (irq = 0; irq < nr_irqs; irq++) { | 1684 | for (irq = 0; irq < nr_irqs; irq++) { |
1677 | struct irq_desc *desc = irq_desc + irq; | 1685 | struct irq_desc *desc = irq_to_desc(irq); |
1678 | if (desc->status & IRQ_MOVE_PENDING) { | 1686 | if (desc->status & IRQ_MOVE_PENDING) { |
1679 | unsigned long flags; | 1687 | unsigned long flags; |
1680 | 1688 | ||
@@ -1686,8 +1694,7 @@ static void ir_irq_migration(struct work_struct *work) | |||
1686 | continue; | 1694 | continue; |
1687 | } | 1695 | } |
1688 | 1696 | ||
1689 | desc->chip->set_affinity(irq, | 1697 | desc->chip->set_affinity(irq, desc->pending_mask); |
1690 | irq_desc[irq].pending_mask); | ||
1691 | spin_unlock_irqrestore(&desc->lock, flags); | 1698 | spin_unlock_irqrestore(&desc->lock, flags); |
1692 | } | 1699 | } |
1693 | } | 1700 | } |
@@ -1698,9 +1705,11 @@ static void ir_irq_migration(struct work_struct *work) | |||
1698 | */ | 1705 | */ |
1699 | static void set_ir_ioapic_affinity_irq(unsigned int irq, cpumask_t mask) | 1706 | static void set_ir_ioapic_affinity_irq(unsigned int irq, cpumask_t mask) |
1700 | { | 1707 | { |
1701 | if (irq_desc[irq].status & IRQ_LEVEL) { | 1708 | struct irq_desc *desc = irq_to_desc(irq); |
1702 | irq_desc[irq].status |= IRQ_MOVE_PENDING; | 1709 | |
1703 | irq_desc[irq].pending_mask = mask; | 1710 | if (desc->status & IRQ_LEVEL) { |
1711 | desc->status |= IRQ_MOVE_PENDING; | ||
1712 | desc->pending_mask = mask; | ||
1704 | migrate_irq_remapped_level(irq); | 1713 | migrate_irq_remapped_level(irq); |
1705 | return; | 1714 | return; |
1706 | } | 1715 | } |
@@ -1725,7 +1734,7 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void) | |||
1725 | if (irq >= nr_irqs) | 1734 | if (irq >= nr_irqs) |
1726 | continue; | 1735 | continue; |
1727 | 1736 | ||
1728 | desc = irq_desc + irq; | 1737 | desc = irq_to_desc(irq); |
1729 | cfg = irq_cfg + irq; | 1738 | cfg = irq_cfg + irq; |
1730 | spin_lock(&desc->lock); | 1739 | spin_lock(&desc->lock); |
1731 | if (!cfg->move_cleanup_count) | 1740 | if (!cfg->move_cleanup_count) |
@@ -1791,7 +1800,7 @@ static void ack_apic_level(unsigned int irq) | |||
1791 | irq_complete_move(irq); | 1800 | irq_complete_move(irq); |
1792 | #ifdef CONFIG_GENERIC_PENDING_IRQ | 1801 | #ifdef CONFIG_GENERIC_PENDING_IRQ |
1793 | /* If we are moving the irq we need to mask it */ | 1802 | /* If we are moving the irq we need to mask it */ |
1794 | if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING)) { | 1803 | if (unlikely(irq_to_desc(irq)->status & IRQ_MOVE_PENDING)) { |
1795 | do_unmask_irq = 1; | 1804 | do_unmask_irq = 1; |
1796 | mask_IO_APIC_irq(irq); | 1805 | mask_IO_APIC_irq(irq); |
1797 | } | 1806 | } |
@@ -1868,6 +1877,7 @@ static struct irq_chip ir_ioapic_chip __read_mostly = { | |||
1868 | static inline void init_IO_APIC_traps(void) | 1877 | static inline void init_IO_APIC_traps(void) |
1869 | { | 1878 | { |
1870 | int irq; | 1879 | int irq; |
1880 | struct irq_desc *desc; | ||
1871 | 1881 | ||
1872 | /* | 1882 | /* |
1873 | * NOTE! The local APIC isn't very good at handling | 1883 | * NOTE! The local APIC isn't very good at handling |
@@ -1889,9 +1899,11 @@ static inline void init_IO_APIC_traps(void) | |||
1889 | */ | 1899 | */ |
1890 | if (irq < 16) | 1900 | if (irq < 16) |
1891 | make_8259A_irq(irq); | 1901 | make_8259A_irq(irq); |
1892 | else | 1902 | else { |
1903 | desc = irq_to_desc(irq); | ||
1893 | /* Strange. Oh, well.. */ | 1904 | /* Strange. Oh, well.. */ |
1894 | irq_desc[irq].chip = &no_irq_chip; | 1905 | desc->chip = &no_irq_chip; |
1906 | } | ||
1895 | } | 1907 | } |
1896 | } | 1908 | } |
1897 | } | 1909 | } |
@@ -1926,7 +1938,10 @@ static struct irq_chip lapic_chip __read_mostly = { | |||
1926 | 1938 | ||
1927 | static void lapic_register_intr(int irq) | 1939 | static void lapic_register_intr(int irq) |
1928 | { | 1940 | { |
1929 | irq_desc[irq].status &= ~IRQ_LEVEL; | 1941 | struct irq_desc *desc; |
1942 | |||
1943 | desc = irq_to_desc(irq); | ||
1944 | desc->status &= ~IRQ_LEVEL; | ||
1930 | set_irq_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq, | 1945 | set_irq_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq, |
1931 | "edge"); | 1946 | "edge"); |
1932 | } | 1947 | } |
@@ -2402,6 +2417,7 @@ static void set_msi_irq_affinity(unsigned int irq, cpumask_t mask) | |||
2402 | struct msi_msg msg; | 2417 | struct msi_msg msg; |
2403 | unsigned int dest; | 2418 | unsigned int dest; |
2404 | cpumask_t tmp; | 2419 | cpumask_t tmp; |
2420 | struct irq_desc *desc; | ||
2405 | 2421 | ||
2406 | cpus_and(tmp, mask, cpu_online_map); | 2422 | cpus_and(tmp, mask, cpu_online_map); |
2407 | if (cpus_empty(tmp)) | 2423 | if (cpus_empty(tmp)) |
@@ -2421,7 +2437,8 @@ static void set_msi_irq_affinity(unsigned int irq, cpumask_t mask) | |||
2421 | msg.address_lo |= MSI_ADDR_DEST_ID(dest); | 2437 | msg.address_lo |= MSI_ADDR_DEST_ID(dest); |
2422 | 2438 | ||
2423 | write_msi_msg(irq, &msg); | 2439 | write_msi_msg(irq, &msg); |
2424 | irq_desc[irq].affinity = mask; | 2440 | desc = irq_to_desc(irq); |
2441 | desc->affinity = mask; | ||
2425 | } | 2442 | } |
2426 | 2443 | ||
2427 | #ifdef CONFIG_INTR_REMAP | 2444 | #ifdef CONFIG_INTR_REMAP |
@@ -2435,6 +2452,7 @@ static void ir_set_msi_irq_affinity(unsigned int irq, cpumask_t mask) | |||
2435 | unsigned int dest; | 2452 | unsigned int dest; |
2436 | cpumask_t tmp, cleanup_mask; | 2453 | cpumask_t tmp, cleanup_mask; |
2437 | struct irte irte; | 2454 | struct irte irte; |
2455 | struct irq_desc *desc; | ||
2438 | 2456 | ||
2439 | cpus_and(tmp, mask, cpu_online_map); | 2457 | cpus_and(tmp, mask, cpu_online_map); |
2440 | if (cpus_empty(tmp)) | 2458 | if (cpus_empty(tmp)) |
@@ -2469,7 +2487,8 @@ static void ir_set_msi_irq_affinity(unsigned int irq, cpumask_t mask) | |||
2469 | cfg->move_in_progress = 0; | 2487 | cfg->move_in_progress = 0; |
2470 | } | 2488 | } |
2471 | 2489 | ||
2472 | irq_desc[irq].affinity = mask; | 2490 | desc = irq_to_desc(irq); |
2491 | desc->affinity = mask; | ||
2473 | } | 2492 | } |
2474 | #endif | 2493 | #endif |
2475 | #endif /* CONFIG_SMP */ | 2494 | #endif /* CONFIG_SMP */ |
@@ -2543,7 +2562,7 @@ static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc, int irq) | |||
2543 | 2562 | ||
2544 | #ifdef CONFIG_INTR_REMAP | 2563 | #ifdef CONFIG_INTR_REMAP |
2545 | if (irq_remapped(irq)) { | 2564 | if (irq_remapped(irq)) { |
2546 | struct irq_desc *desc = irq_desc + irq; | 2565 | struct irq_desc *desc = irq_to_desc(irq); |
2547 | /* | 2566 | /* |
2548 | * irq migration in process context | 2567 | * irq migration in process context |
2549 | */ | 2568 | */ |
@@ -2655,6 +2674,7 @@ static void dmar_msi_set_affinity(unsigned int irq, cpumask_t mask) | |||
2655 | struct msi_msg msg; | 2674 | struct msi_msg msg; |
2656 | unsigned int dest; | 2675 | unsigned int dest; |
2657 | cpumask_t tmp; | 2676 | cpumask_t tmp; |
2677 | struct irq_desc *desc; | ||
2658 | 2678 | ||
2659 | cpus_and(tmp, mask, cpu_online_map); | 2679 | cpus_and(tmp, mask, cpu_online_map); |
2660 | if (cpus_empty(tmp)) | 2680 | if (cpus_empty(tmp)) |
@@ -2674,7 +2694,8 @@ static void dmar_msi_set_affinity(unsigned int irq, cpumask_t mask) | |||
2674 | msg.address_lo |= MSI_ADDR_DEST_ID(dest); | 2694 | msg.address_lo |= MSI_ADDR_DEST_ID(dest); |
2675 | 2695 | ||
2676 | dmar_msi_write(irq, &msg); | 2696 | dmar_msi_write(irq, &msg); |
2677 | irq_desc[irq].affinity = mask; | 2697 | desc = irq_to_desc(irq); |
2698 | desc->affinity = mask; | ||
2678 | } | 2699 | } |
2679 | #endif /* CONFIG_SMP */ | 2700 | #endif /* CONFIG_SMP */ |
2680 | 2701 | ||
@@ -2731,6 +2752,7 @@ static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask) | |||
2731 | struct irq_cfg *cfg = irq_cfg + irq; | 2752 | struct irq_cfg *cfg = irq_cfg + irq; |
2732 | unsigned int dest; | 2753 | unsigned int dest; |
2733 | cpumask_t tmp; | 2754 | cpumask_t tmp; |
2755 | struct irq_desc *desc; | ||
2734 | 2756 | ||
2735 | cpus_and(tmp, mask, cpu_online_map); | 2757 | cpus_and(tmp, mask, cpu_online_map); |
2736 | if (cpus_empty(tmp)) | 2758 | if (cpus_empty(tmp)) |
@@ -2743,7 +2765,8 @@ static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask) | |||
2743 | dest = cpu_mask_to_apicid(tmp); | 2765 | dest = cpu_mask_to_apicid(tmp); |
2744 | 2766 | ||
2745 | target_ht_irq(irq, dest, cfg->vector); | 2767 | target_ht_irq(irq, dest, cfg->vector); |
2746 | irq_desc[irq].affinity = mask; | 2768 | desc = irq_to_desc(irq); |
2769 | desc->affinity = mask; | ||
2747 | } | 2770 | } |
2748 | #endif | 2771 | #endif |
2749 | 2772 | ||
diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c index 4c7ffb32854c..ede513be517d 100644 --- a/arch/x86/kernel/irq_32.c +++ b/arch/x86/kernel/irq_32.c | |||
@@ -224,7 +224,7 @@ unsigned int do_IRQ(struct pt_regs *regs) | |||
224 | struct pt_regs *old_regs; | 224 | struct pt_regs *old_regs; |
225 | /* high bit used in ret_from_ code */ | 225 | /* high bit used in ret_from_ code */ |
226 | int overflow, irq = ~regs->orig_ax; | 226 | int overflow, irq = ~regs->orig_ax; |
227 | struct irq_desc *desc = irq_desc + irq; | 227 | struct irq_desc *desc = irq_to_desc(irq); |
228 | 228 | ||
229 | if (unlikely((unsigned)irq >= nr_irqs)) { | 229 | if (unlikely((unsigned)irq >= nr_irqs)) { |
230 | printk(KERN_EMERG "%s: cannot handle IRQ %d\n", | 230 | printk(KERN_EMERG "%s: cannot handle IRQ %d\n", |
@@ -273,15 +273,16 @@ int show_interrupts(struct seq_file *p, void *v) | |||
273 | 273 | ||
274 | if (i < nr_irqs) { | 274 | if (i < nr_irqs) { |
275 | unsigned any_count = 0; | 275 | unsigned any_count = 0; |
276 | struct irq_desc *desc = irq_to_desc(i); | ||
276 | 277 | ||
277 | spin_lock_irqsave(&irq_desc[i].lock, flags); | 278 | spin_lock_irqsave(&desc->lock, flags); |
278 | #ifndef CONFIG_SMP | 279 | #ifndef CONFIG_SMP |
279 | any_count = kstat_irqs(i); | 280 | any_count = kstat_irqs(i); |
280 | #else | 281 | #else |
281 | for_each_online_cpu(j) | 282 | for_each_online_cpu(j) |
282 | any_count |= kstat_cpu(j).irqs[i]; | 283 | any_count |= kstat_cpu(j).irqs[i]; |
283 | #endif | 284 | #endif |
284 | action = irq_desc[i].action; | 285 | action = desc->action; |
285 | if (!action && !any_count) | 286 | if (!action && !any_count) |
286 | goto skip; | 287 | goto skip; |
287 | seq_printf(p, "%3d: ",i); | 288 | seq_printf(p, "%3d: ",i); |
@@ -291,8 +292,8 @@ int show_interrupts(struct seq_file *p, void *v) | |||
291 | for_each_online_cpu(j) | 292 | for_each_online_cpu(j) |
292 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); | 293 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); |
293 | #endif | 294 | #endif |
294 | seq_printf(p, " %8s", irq_desc[i].chip->name); | 295 | seq_printf(p, " %8s", desc->chip->name); |
295 | seq_printf(p, "-%-8s", irq_desc[i].name); | 296 | seq_printf(p, "-%-8s", desc->name); |
296 | 297 | ||
297 | if (action) { | 298 | if (action) { |
298 | seq_printf(p, " %s", action->name); | 299 | seq_printf(p, " %s", action->name); |
@@ -302,7 +303,7 @@ int show_interrupts(struct seq_file *p, void *v) | |||
302 | 303 | ||
303 | seq_putc(p, '\n'); | 304 | seq_putc(p, '\n'); |
304 | skip: | 305 | skip: |
305 | spin_unlock_irqrestore(&irq_desc[i].lock, flags); | 306 | spin_unlock_irqrestore(&desc->lock, flags); |
306 | } else if (i == nr_irqs) { | 307 | } else if (i == nr_irqs) { |
307 | seq_printf(p, "NMI: "); | 308 | seq_printf(p, "NMI: "); |
308 | for_each_online_cpu(j) | 309 | for_each_online_cpu(j) |
@@ -398,17 +399,20 @@ void fixup_irqs(cpumask_t map) | |||
398 | 399 | ||
399 | for (irq = 0; irq < nr_irqs; irq++) { | 400 | for (irq = 0; irq < nr_irqs; irq++) { |
400 | cpumask_t mask; | 401 | cpumask_t mask; |
402 | struct irq_desc *desc; | ||
403 | |||
401 | if (irq == 2) | 404 | if (irq == 2) |
402 | continue; | 405 | continue; |
403 | 406 | ||
404 | cpus_and(mask, irq_desc[irq].affinity, map); | 407 | desc = irq_to_desc(irq); |
408 | cpus_and(mask, desc->affinity, map); | ||
405 | if (any_online_cpu(mask) == NR_CPUS) { | 409 | if (any_online_cpu(mask) == NR_CPUS) { |
406 | printk("Breaking affinity for irq %i\n", irq); | 410 | printk("Breaking affinity for irq %i\n", irq); |
407 | mask = map; | 411 | mask = map; |
408 | } | 412 | } |
409 | if (irq_desc[irq].chip->set_affinity) | 413 | if (desc->chip->set_affinity) |
410 | irq_desc[irq].chip->set_affinity(irq, mask); | 414 | desc->chip->set_affinity(irq, mask); |
411 | else if (irq_desc[irq].action && !(warned++)) | 415 | else if (desc->action && !(warned++)) |
412 | printk("Cannot set affinity for irq %i\n", irq); | 416 | printk("Cannot set affinity for irq %i\n", irq); |
413 | } | 417 | } |
414 | 418 | ||
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c index e1f0839430d2..738eb65a924e 100644 --- a/arch/x86/kernel/irq_64.c +++ b/arch/x86/kernel/irq_64.c | |||
@@ -83,15 +83,16 @@ int show_interrupts(struct seq_file *p, void *v) | |||
83 | 83 | ||
84 | if (i < nr_irqs) { | 84 | if (i < nr_irqs) { |
85 | unsigned any_count = 0; | 85 | unsigned any_count = 0; |
86 | struct irq_desc *desc = irq_to_desc(i); | ||
86 | 87 | ||
87 | spin_lock_irqsave(&irq_desc[i].lock, flags); | 88 | spin_lock_irqsave(&desc->lock, flags); |
88 | #ifndef CONFIG_SMP | 89 | #ifndef CONFIG_SMP |
89 | any_count = kstat_irqs(i); | 90 | any_count = kstat_irqs(i); |
90 | #else | 91 | #else |
91 | for_each_online_cpu(j) | 92 | for_each_online_cpu(j) |
92 | any_count |= kstat_cpu(j).irqs[i]; | 93 | any_count |= kstat_cpu(j).irqs[i]; |
93 | #endif | 94 | #endif |
94 | action = irq_desc[i].action; | 95 | action = desc->action; |
95 | if (!action && !any_count) | 96 | if (!action && !any_count) |
96 | goto skip; | 97 | goto skip; |
97 | seq_printf(p, "%3d: ",i); | 98 | seq_printf(p, "%3d: ",i); |
@@ -101,8 +102,8 @@ int show_interrupts(struct seq_file *p, void *v) | |||
101 | for_each_online_cpu(j) | 102 | for_each_online_cpu(j) |
102 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); | 103 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); |
103 | #endif | 104 | #endif |
104 | seq_printf(p, " %8s", irq_desc[i].chip->name); | 105 | seq_printf(p, " %8s", desc->chip->name); |
105 | seq_printf(p, "-%-8s", irq_desc[i].name); | 106 | seq_printf(p, "-%-8s", desc->name); |
106 | 107 | ||
107 | if (action) { | 108 | if (action) { |
108 | seq_printf(p, " %s", action->name); | 109 | seq_printf(p, " %s", action->name); |
@@ -111,7 +112,7 @@ int show_interrupts(struct seq_file *p, void *v) | |||
111 | } | 112 | } |
112 | seq_putc(p, '\n'); | 113 | seq_putc(p, '\n'); |
113 | skip: | 114 | skip: |
114 | spin_unlock_irqrestore(&irq_desc[i].lock, flags); | 115 | spin_unlock_irqrestore(&desc->lock, flags); |
115 | } else if (i == nr_irqs) { | 116 | } else if (i == nr_irqs) { |
116 | seq_printf(p, "NMI: "); | 117 | seq_printf(p, "NMI: "); |
117 | for_each_online_cpu(j) | 118 | for_each_online_cpu(j) |
@@ -228,37 +229,39 @@ void fixup_irqs(cpumask_t map) | |||
228 | cpumask_t mask; | 229 | cpumask_t mask; |
229 | int break_affinity = 0; | 230 | int break_affinity = 0; |
230 | int set_affinity = 1; | 231 | int set_affinity = 1; |
232 | struct irq_desc *desc; | ||
231 | 233 | ||
232 | if (irq == 2) | 234 | if (irq == 2) |
233 | continue; | 235 | continue; |
234 | 236 | ||
237 | desc = irq_to_desc(irq); | ||
235 | /* interrupt's are disabled at this point */ | 238 | /* interrupt's are disabled at this point */ |
236 | spin_lock(&irq_desc[irq].lock); | 239 | spin_lock(&desc->lock); |
237 | 240 | ||
238 | if (!irq_has_action(irq) || | 241 | if (!irq_has_action(irq) || |
239 | cpus_equal(irq_desc[irq].affinity, map)) { | 242 | cpus_equal(desc->affinity, map)) { |
240 | spin_unlock(&irq_desc[irq].lock); | 243 | spin_unlock(&desc->lock); |
241 | continue; | 244 | continue; |
242 | } | 245 | } |
243 | 246 | ||
244 | cpus_and(mask, irq_desc[irq].affinity, map); | 247 | cpus_and(mask, desc->affinity, map); |
245 | if (cpus_empty(mask)) { | 248 | if (cpus_empty(mask)) { |
246 | break_affinity = 1; | 249 | break_affinity = 1; |
247 | mask = map; | 250 | mask = map; |
248 | } | 251 | } |
249 | 252 | ||
250 | if (irq_desc[irq].chip->mask) | 253 | if (desc->chip->mask) |
251 | irq_desc[irq].chip->mask(irq); | 254 | desc->chip->mask(irq); |
252 | 255 | ||
253 | if (irq_desc[irq].chip->set_affinity) | 256 | if (desc->chip->set_affinity) |
254 | irq_desc[irq].chip->set_affinity(irq, mask); | 257 | desc->chip->set_affinity(irq, mask); |
255 | else if (!(warned++)) | 258 | else if (!(warned++)) |
256 | set_affinity = 0; | 259 | set_affinity = 0; |
257 | 260 | ||
258 | if (irq_desc[irq].chip->unmask) | 261 | if (desc->chip->unmask) |
259 | irq_desc[irq].chip->unmask(irq); | 262 | desc->chip->unmask(irq); |
260 | 263 | ||
261 | spin_unlock(&irq_desc[irq].lock); | 264 | spin_unlock(&desc->lock); |
262 | 265 | ||
263 | if (break_affinity && set_affinity) | 266 | if (break_affinity && set_affinity) |
264 | printk("Broke affinity for irq %i\n", irq); | 267 | printk("Broke affinity for irq %i\n", irq); |
diff --git a/arch/x86/kernel/irqinit_64.c b/arch/x86/kernel/irqinit_64.c index 165c5d9b0d1a..0744b49b4d12 100644 --- a/arch/x86/kernel/irqinit_64.c +++ b/arch/x86/kernel/irqinit_64.c | |||
@@ -143,9 +143,11 @@ void __init init_ISA_irqs(void) | |||
143 | init_8259A(0); | 143 | init_8259A(0); |
144 | 144 | ||
145 | for (i = 0; i < nr_irqs; i++) { | 145 | for (i = 0; i < nr_irqs; i++) { |
146 | irq_desc[i].status = IRQ_DISABLED; | 146 | struct irq_desc *desc = irq_to_desc(i); |
147 | irq_desc[i].action = NULL; | 147 | |
148 | irq_desc[i].depth = 1; | 148 | desc->status = IRQ_DISABLED; |
149 | desc->action = NULL; | ||
150 | desc->depth = 1; | ||
149 | 151 | ||
150 | if (i < 16) { | 152 | if (i < 16) { |
151 | /* | 153 | /* |
@@ -157,7 +159,7 @@ void __init init_ISA_irqs(void) | |||
157 | /* | 159 | /* |
158 | * 'high' PCI IRQs filled in on demand | 160 | * 'high' PCI IRQs filled in on demand |
159 | */ | 161 | */ |
160 | irq_desc[i].chip = &no_irq_chip; | 162 | desc->chip = &no_irq_chip; |
161 | } | 163 | } |
162 | } | 164 | } |
163 | } | 165 | } |
diff --git a/arch/x86/kernel/visws_quirks.c b/arch/x86/kernel/visws_quirks.c index 61a97e616f70..9d85ab384435 100644 --- a/arch/x86/kernel/visws_quirks.c +++ b/arch/x86/kernel/visws_quirks.c | |||
@@ -484,10 +484,11 @@ static void disable_cobalt_irq(unsigned int irq) | |||
484 | static unsigned int startup_cobalt_irq(unsigned int irq) | 484 | static unsigned int startup_cobalt_irq(unsigned int irq) |
485 | { | 485 | { |
486 | unsigned long flags; | 486 | unsigned long flags; |
487 | struct irq_desc *desc = irq_to_desc(irq); | ||
487 | 488 | ||
488 | spin_lock_irqsave(&cobalt_lock, flags); | 489 | spin_lock_irqsave(&cobalt_lock, flags); |
489 | if ((irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING))) | 490 | if ((desc->status & (IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING))) |
490 | irq_desc[irq].status &= ~(IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING); | 491 | desc->status &= ~(IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING); |
491 | enable_cobalt_irq(irq); | 492 | enable_cobalt_irq(irq); |
492 | spin_unlock_irqrestore(&cobalt_lock, flags); | 493 | spin_unlock_irqrestore(&cobalt_lock, flags); |
493 | return 0; | 494 | return 0; |
@@ -506,9 +507,10 @@ static void ack_cobalt_irq(unsigned int irq) | |||
506 | static void end_cobalt_irq(unsigned int irq) | 507 | static void end_cobalt_irq(unsigned int irq) |
507 | { | 508 | { |
508 | unsigned long flags; | 509 | unsigned long flags; |
510 | struct irq_desc *desc = irq_to_desc(irq); | ||
509 | 511 | ||
510 | spin_lock_irqsave(&cobalt_lock, flags); | 512 | spin_lock_irqsave(&cobalt_lock, flags); |
511 | if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) | 513 | if (!(desc->status & (IRQ_DISABLED | IRQ_INPROGRESS))) |
512 | enable_cobalt_irq(irq); | 514 | enable_cobalt_irq(irq); |
513 | spin_unlock_irqrestore(&cobalt_lock, flags); | 515 | spin_unlock_irqrestore(&cobalt_lock, flags); |
514 | } | 516 | } |
@@ -626,7 +628,7 @@ static irqreturn_t piix4_master_intr(int irq, void *dev_id) | |||
626 | 628 | ||
627 | spin_unlock_irqrestore(&i8259A_lock, flags); | 629 | spin_unlock_irqrestore(&i8259A_lock, flags); |
628 | 630 | ||
629 | desc = irq_desc + realirq; | 631 | desc = irq_to_desc(realirq); |
630 | 632 | ||
631 | /* | 633 | /* |
632 | * handle this 'virtual interrupt' as a Cobalt one now. | 634 | * handle this 'virtual interrupt' as a Cobalt one now. |
@@ -662,27 +664,29 @@ void init_VISWS_APIC_irqs(void) | |||
662 | int i; | 664 | int i; |
663 | 665 | ||
664 | for (i = 0; i < CO_IRQ_APIC0 + CO_APIC_LAST + 1; i++) { | 666 | for (i = 0; i < CO_IRQ_APIC0 + CO_APIC_LAST + 1; i++) { |
665 | irq_desc[i].status = IRQ_DISABLED; | 667 | struct irq_desc *desc = irq_to_desc(i); |
666 | irq_desc[i].action = 0; | 668 | |
667 | irq_desc[i].depth = 1; | 669 | desc->status = IRQ_DISABLED; |
670 | desc->action = 0; | ||
671 | desc->depth = 1; | ||
668 | 672 | ||
669 | if (i == 0) { | 673 | if (i == 0) { |
670 | irq_desc[i].chip = &cobalt_irq_type; | 674 | desc->chip = &cobalt_irq_type; |
671 | } | 675 | } |
672 | else if (i == CO_IRQ_IDE0) { | 676 | else if (i == CO_IRQ_IDE0) { |
673 | irq_desc[i].chip = &cobalt_irq_type; | 677 | desc->chip = &cobalt_irq_type; |
674 | } | 678 | } |
675 | else if (i == CO_IRQ_IDE1) { | 679 | else if (i == CO_IRQ_IDE1) { |
676 | irq_desc[i].chip = &cobalt_irq_type; | 680 | desc->chip = &cobalt_irq_type; |
677 | } | 681 | } |
678 | else if (i == CO_IRQ_8259) { | 682 | else if (i == CO_IRQ_8259) { |
679 | irq_desc[i].chip = &piix4_master_irq_type; | 683 | desc->chip = &piix4_master_irq_type; |
680 | } | 684 | } |
681 | else if (i < CO_IRQ_APIC0) { | 685 | else if (i < CO_IRQ_APIC0) { |
682 | irq_desc[i].chip = &piix4_virtual_irq_type; | 686 | desc->chip = &piix4_virtual_irq_type; |
683 | } | 687 | } |
684 | else if (IS_CO_APIC(i)) { | 688 | else if (IS_CO_APIC(i)) { |
685 | irq_desc[i].chip = &cobalt_irq_type; | 689 | desc->chip = &cobalt_irq_type; |
686 | } | 690 | } |
687 | } | 691 | } |
688 | 692 | ||
diff --git a/arch/x86/mach-voyager/voyager_smp.c b/arch/x86/mach-voyager/voyager_smp.c index 199a5f4a873c..0f6e8a6523ae 100644 --- a/arch/x86/mach-voyager/voyager_smp.c +++ b/arch/x86/mach-voyager/voyager_smp.c | |||
@@ -1483,7 +1483,7 @@ static void disable_local_vic_irq(unsigned int irq) | |||
1483 | * the interrupt off to another CPU */ | 1483 | * the interrupt off to another CPU */ |
1484 | static void before_handle_vic_irq(unsigned int irq) | 1484 | static void before_handle_vic_irq(unsigned int irq) |
1485 | { | 1485 | { |
1486 | irq_desc_t *desc = irq_desc + irq; | 1486 | irq_desc_t *desc = irq_to_desc(irq); |
1487 | __u8 cpu = smp_processor_id(); | 1487 | __u8 cpu = smp_processor_id(); |
1488 | 1488 | ||
1489 | _raw_spin_lock(&vic_irq_lock); | 1489 | _raw_spin_lock(&vic_irq_lock); |
@@ -1518,7 +1518,7 @@ static void before_handle_vic_irq(unsigned int irq) | |||
1518 | /* Finish the VIC interrupt: basically mask */ | 1518 | /* Finish the VIC interrupt: basically mask */ |
1519 | static void after_handle_vic_irq(unsigned int irq) | 1519 | static void after_handle_vic_irq(unsigned int irq) |
1520 | { | 1520 | { |
1521 | irq_desc_t *desc = irq_desc + irq; | 1521 | irq_desc_t *desc = irq_to_desc(irq); |
1522 | 1522 | ||
1523 | _raw_spin_lock(&vic_irq_lock); | 1523 | _raw_spin_lock(&vic_irq_lock); |
1524 | { | 1524 | { |
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 8d2940517c99..572d372899d3 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -1058,7 +1058,7 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) | |||
1058 | 1058 | ||
1059 | if (!is_out) { | 1059 | if (!is_out) { |
1060 | int irq = gpio_to_irq(gpio); | 1060 | int irq = gpio_to_irq(gpio); |
1061 | struct irq_desc *desc = irq_desc + irq; | 1061 | struct irq_desc *desc = irq_to_desc(irq); |
1062 | 1062 | ||
1063 | /* This races with request_irq(), set_irq_type(), | 1063 | /* This races with request_irq(), set_irq_type(), |
1064 | * and set_irq_wake() ... but those are "rare". | 1064 | * and set_irq_wake() ... but those are "rare". |
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index ba5aa2008273..e4c0db4dc7b1 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c | |||
@@ -123,7 +123,7 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc) | |||
123 | irqnr = asic->irq_base + | 123 | irqnr = asic->irq_base + |
124 | (ASIC3_GPIOS_PER_BANK * bank) | 124 | (ASIC3_GPIOS_PER_BANK * bank) |
125 | + i; | 125 | + i; |
126 | desc = irq_desc + irqnr; | 126 | desc = irq_to_desc(irqnr); |
127 | desc->handle_irq(irqnr, desc); | 127 | desc->handle_irq(irqnr, desc); |
128 | if (asic->irq_bothedge[bank] & bit) | 128 | if (asic->irq_bothedge[bank] & bit) |
129 | asic3_irq_flip_edge(asic, base, | 129 | asic3_irq_flip_edge(asic, base, |
@@ -136,7 +136,7 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc) | |||
136 | for (i = ASIC3_NUM_GPIOS; i < ASIC3_NR_IRQS; i++) { | 136 | for (i = ASIC3_NUM_GPIOS; i < ASIC3_NR_IRQS; i++) { |
137 | /* They start at bit 4 and go up */ | 137 | /* They start at bit 4 and go up */ |
138 | if (status & (1 << (i - ASIC3_NUM_GPIOS + 4))) { | 138 | if (status & (1 << (i - ASIC3_NUM_GPIOS + 4))) { |
139 | desc = irq_desc + asic->irq_base + i; | 139 | desc = irq_to_desc(asic->irq_base + i); |
140 | desc->handle_irq(asic->irq_base + i, | 140 | desc->handle_irq(asic->irq_base + i, |
141 | desc); | 141 | desc); |
142 | } | 142 | } |
diff --git a/drivers/mfd/htc-egpio.c b/drivers/mfd/htc-egpio.c index 6be43172dc65..ad3379fcd194 100644 --- a/drivers/mfd/htc-egpio.c +++ b/drivers/mfd/htc-egpio.c | |||
@@ -112,7 +112,7 @@ static void egpio_handler(unsigned int irq, struct irq_desc *desc) | |||
112 | /* Run irq handler */ | 112 | /* Run irq handler */ |
113 | pr_debug("got IRQ %d\n", irqpin); | 113 | pr_debug("got IRQ %d\n", irqpin); |
114 | irq = ei->irq_start + irqpin; | 114 | irq = ei->irq_start + irqpin; |
115 | desc = &irq_desc[irq]; | 115 | desc = irq_to_desc(irq); |
116 | desc->handle_irq(irq, desc); | 116 | desc->handle_irq(irq, desc); |
117 | } | 117 | } |
118 | } | 118 | } |
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index fd56128525d1..3bc54b30c3a1 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c | |||
@@ -298,7 +298,8 @@ struct pci_port_ops dino_port_ops = { | |||
298 | 298 | ||
299 | static void dino_disable_irq(unsigned int irq) | 299 | static void dino_disable_irq(unsigned int irq) |
300 | { | 300 | { |
301 | struct dino_device *dino_dev = irq_desc[irq].chip_data; | 301 | struct irq_desc *desc = irq_to_desc(irq); |
302 | struct dino_device *dino_dev = desc->chip_data; | ||
302 | int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); | 303 | int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); |
303 | 304 | ||
304 | DBG(KERN_WARNING "%s(0x%p, %d)\n", __func__, dino_dev, irq); | 305 | DBG(KERN_WARNING "%s(0x%p, %d)\n", __func__, dino_dev, irq); |
@@ -310,7 +311,8 @@ static void dino_disable_irq(unsigned int irq) | |||
310 | 311 | ||
311 | static void dino_enable_irq(unsigned int irq) | 312 | static void dino_enable_irq(unsigned int irq) |
312 | { | 313 | { |
313 | struct dino_device *dino_dev = irq_desc[irq].chip_data; | 314 | struct irq_desc *desc = irq_to_desc(irq); |
315 | struct dino_device *dino_dev = desc->chip_data; | ||
314 | int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); | 316 | int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); |
315 | u32 tmp; | 317 | u32 tmp; |
316 | 318 | ||
diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c index 771cef592542..7891db50c483 100644 --- a/drivers/parisc/eisa.c +++ b/drivers/parisc/eisa.c | |||
@@ -346,10 +346,10 @@ static int __init eisa_probe(struct parisc_device *dev) | |||
346 | } | 346 | } |
347 | 347 | ||
348 | /* Reserve IRQ2 */ | 348 | /* Reserve IRQ2 */ |
349 | irq_desc[2].action = &irq2_action; | 349 | irq_to_desc(2)->action = &irq2_action; |
350 | 350 | ||
351 | for (i = 0; i < 16; i++) { | 351 | for (i = 0; i < 16; i++) { |
352 | irq_desc[i].chip = &eisa_interrupt_type; | 352 | irq_to_desc(i)->chip = &eisa_interrupt_type; |
353 | } | 353 | } |
354 | 354 | ||
355 | EISA_bus = 1; | 355 | EISA_bus = 1; |
diff --git a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c index f7d088b897ee..e76db9e4d504 100644 --- a/drivers/parisc/gsc.c +++ b/drivers/parisc/gsc.c | |||
@@ -108,7 +108,8 @@ int gsc_find_local_irq(unsigned int irq, int *global_irqs, int limit) | |||
108 | 108 | ||
109 | static void gsc_asic_disable_irq(unsigned int irq) | 109 | static void gsc_asic_disable_irq(unsigned int irq) |
110 | { | 110 | { |
111 | struct gsc_asic *irq_dev = irq_desc[irq].chip_data; | 111 | struct irq_desc *desc = irq_to_desc(irq); |
112 | struct gsc_asic *irq_dev = desc->chip_data; | ||
112 | int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32); | 113 | int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32); |
113 | u32 imr; | 114 | u32 imr; |
114 | 115 | ||
@@ -123,7 +124,8 @@ static void gsc_asic_disable_irq(unsigned int irq) | |||
123 | 124 | ||
124 | static void gsc_asic_enable_irq(unsigned int irq) | 125 | static void gsc_asic_enable_irq(unsigned int irq) |
125 | { | 126 | { |
126 | struct gsc_asic *irq_dev = irq_desc[irq].chip_data; | 127 | struct irq_desc *desc = irq_to_desc(irq); |
128 | struct gsc_asic *irq_dev = desc->chip_data; | ||
127 | int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32); | 129 | int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32); |
128 | u32 imr; | 130 | u32 imr; |
129 | 131 | ||
@@ -159,12 +161,14 @@ static struct hw_interrupt_type gsc_asic_interrupt_type = { | |||
159 | int gsc_assign_irq(struct hw_interrupt_type *type, void *data) | 161 | int gsc_assign_irq(struct hw_interrupt_type *type, void *data) |
160 | { | 162 | { |
161 | static int irq = GSC_IRQ_BASE; | 163 | static int irq = GSC_IRQ_BASE; |
164 | struct irq_desc *desc; | ||
162 | 165 | ||
163 | if (irq > GSC_IRQ_MAX) | 166 | if (irq > GSC_IRQ_MAX) |
164 | return NO_IRQ; | 167 | return NO_IRQ; |
165 | 168 | ||
166 | irq_desc[irq].chip = type; | 169 | desc = irq_to_desc(irq); |
167 | irq_desc[irq].chip_data = data; | 170 | desc->chip = type; |
171 | desc->chip_data = data; | ||
168 | return irq++; | 172 | return irq++; |
169 | } | 173 | } |
170 | 174 | ||
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c index 6fb3f7979f21..7beffcab2745 100644 --- a/drivers/parisc/iosapic.c +++ b/drivers/parisc/iosapic.c | |||
@@ -619,7 +619,9 @@ iosapic_set_irt_data( struct vector_info *vi, u32 *dp0, u32 *dp1) | |||
619 | 619 | ||
620 | static struct vector_info *iosapic_get_vector(unsigned int irq) | 620 | static struct vector_info *iosapic_get_vector(unsigned int irq) |
621 | { | 621 | { |
622 | return irq_desc[irq].chip_data; | 622 | struct irq_desc *desc = irq_to_desc(irq); |
623 | |||
624 | return desc->chip_data; | ||
623 | } | 625 | } |
624 | 626 | ||
625 | static void iosapic_disable_irq(unsigned int irq) | 627 | static void iosapic_disable_irq(unsigned int irq) |
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c index 1e8d2d17f04c..1e93c837514f 100644 --- a/drivers/parisc/superio.c +++ b/drivers/parisc/superio.c | |||
@@ -363,7 +363,9 @@ int superio_fixup_irq(struct pci_dev *pcidev) | |||
363 | #endif | 363 | #endif |
364 | 364 | ||
365 | for (i = 0; i < 16; i++) { | 365 | for (i = 0; i < 16; i++) { |
366 | irq_desc[i].chip = &superio_interrupt_type; | 366 | struct irq_desc *desc = irq_to_desc(i); |
367 | |||
368 | desc->chip = &superio_interrupt_type; | ||
367 | } | 369 | } |
368 | 370 | ||
369 | /* | 371 | /* |
diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c index 117dc12ab438..9ef69cdb3183 100644 --- a/drivers/pcmcia/hd64465_ss.c +++ b/drivers/pcmcia/hd64465_ss.c | |||
@@ -233,15 +233,18 @@ static struct hw_interrupt_type hd64465_ss_irq_type = { | |||
233 | */ | 233 | */ |
234 | static void hs_map_irq(hs_socket_t *sp, unsigned int irq) | 234 | static void hs_map_irq(hs_socket_t *sp, unsigned int irq) |
235 | { | 235 | { |
236 | struct irq_desc *desc; | ||
237 | |||
236 | DPRINTK("hs_map_irq(sock=%d irq=%d)\n", sp->number, irq); | 238 | DPRINTK("hs_map_irq(sock=%d irq=%d)\n", sp->number, irq); |
237 | 239 | ||
238 | if (irq >= HS_NUM_MAPPED_IRQS) | 240 | if (irq >= HS_NUM_MAPPED_IRQS) |
239 | return; | 241 | return; |
240 | 242 | ||
243 | desc = irq_to_desc(irq); | ||
241 | hs_mapped_irq[irq].sock = sp; | 244 | hs_mapped_irq[irq].sock = sp; |
242 | /* insert ourselves as the irq controller */ | 245 | /* insert ourselves as the irq controller */ |
243 | hs_mapped_irq[irq].old_handler = irq_desc[irq].chip; | 246 | hs_mapped_irq[irq].old_handler = desc->chip; |
244 | irq_desc[irq].chip = &hd64465_ss_irq_type; | 247 | desc->chip = &hd64465_ss_irq_type; |
245 | } | 248 | } |
246 | 249 | ||
247 | 250 | ||
@@ -250,13 +253,16 @@ static void hs_map_irq(hs_socket_t *sp, unsigned int irq) | |||
250 | */ | 253 | */ |
251 | static void hs_unmap_irq(hs_socket_t *sp, unsigned int irq) | 254 | static void hs_unmap_irq(hs_socket_t *sp, unsigned int irq) |
252 | { | 255 | { |
256 | struct irq_desc *desc; | ||
257 | |||
253 | DPRINTK("hs_unmap_irq(sock=%d irq=%d)\n", sp->number, irq); | 258 | DPRINTK("hs_unmap_irq(sock=%d irq=%d)\n", sp->number, irq); |
254 | 259 | ||
255 | if (irq >= HS_NUM_MAPPED_IRQS) | 260 | if (irq >= HS_NUM_MAPPED_IRQS) |
256 | return; | 261 | return; |
257 | 262 | ||
263 | desc = irq_to_desc(irq); | ||
258 | /* restore the original irq controller */ | 264 | /* restore the original irq controller */ |
259 | irq_desc[irq].chip = hs_mapped_irq[irq].old_handler; | 265 | desc->chip = hs_mapped_irq[irq].old_handler; |
260 | } | 266 | } |
261 | 267 | ||
262 | /*============================================================*/ | 268 | /*============================================================*/ |
diff --git a/drivers/xen/events.c b/drivers/xen/events.c index ed8235187dc0..56ace47f24d6 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c | |||
@@ -125,7 +125,7 @@ static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu) | |||
125 | 125 | ||
126 | BUG_ON(irq == -1); | 126 | BUG_ON(irq == -1); |
127 | #ifdef CONFIG_SMP | 127 | #ifdef CONFIG_SMP |
128 | irq_desc[irq].affinity = cpumask_of_cpu(cpu); | 128 | irq_to_desc(irq)->affinity = cpumask_of_cpu(cpu); |
129 | #endif | 129 | #endif |
130 | 130 | ||
131 | __clear_bit(chn, cpu_evtchn_mask[cpu_evtchn[chn]]); | 131 | __clear_bit(chn, cpu_evtchn_mask[cpu_evtchn[chn]]); |
@@ -139,8 +139,10 @@ static void init_evtchn_cpu_bindings(void) | |||
139 | #ifdef CONFIG_SMP | 139 | #ifdef CONFIG_SMP |
140 | int i; | 140 | int i; |
141 | /* By default all event channels notify CPU#0. */ | 141 | /* By default all event channels notify CPU#0. */ |
142 | for (i = 0; i < nr_irqs; i++) | 142 | for (i = 0; i < nr_irqs; i++) { |
143 | irq_desc[i].affinity = cpumask_of_cpu(0); | 143 | struct irq_desc *desc = irq_to_desc(i); |
144 | desc->affinity = cpumask_of_cpu(0); | ||
145 | } | ||
144 | #endif | 146 | #endif |
145 | 147 | ||
146 | memset(cpu_evtchn, 0, sizeof(cpu_evtchn)); | 148 | memset(cpu_evtchn, 0, sizeof(cpu_evtchn)); |
diff --git a/include/linux/irq.h b/include/linux/irq.h index 5f4b013624dc..80b8200f2adb 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h | |||
@@ -152,6 +152,10 @@ struct irq_chip { | |||
152 | * @name: flow handler name for /proc/interrupts output | 152 | * @name: flow handler name for /proc/interrupts output |
153 | */ | 153 | */ |
154 | struct irq_desc { | 154 | struct irq_desc { |
155 | unsigned int irq; | ||
156 | #ifdef CONFIG_HAVE_SPARSE_IRQ | ||
157 | struct irq_desc *next; | ||
158 | #endif | ||
155 | irq_flow_handler_t handle_irq; | 159 | irq_flow_handler_t handle_irq; |
156 | struct irq_chip *chip; | 160 | struct irq_chip *chip; |
157 | struct msi_desc *msi_desc; | 161 | struct msi_desc *msi_desc; |
@@ -179,9 +183,9 @@ struct irq_desc { | |||
179 | const char *name; | 183 | const char *name; |
180 | } ____cacheline_internodealigned_in_smp; | 184 | } ____cacheline_internodealigned_in_smp; |
181 | 185 | ||
182 | #ifdef CONFIG_HAVE_DYN_ARRAY | 186 | extern struct irq_desc *irq_to_desc(unsigned int irq); |
183 | extern struct irq_desc *irq_desc; | 187 | #ifndef CONFIG_HAVE_DYN_ARRAY |
184 | #else | 188 | /* could be removed if we get rid of all irq_desc reference */ |
185 | extern struct irq_desc irq_desc[NR_IRQS]; | 189 | extern struct irq_desc irq_desc[NR_IRQS]; |
186 | #endif | 190 | #endif |
187 | 191 | ||
@@ -249,7 +253,10 @@ extern int no_irq_affinity; | |||
249 | 253 | ||
250 | static inline int irq_balancing_disabled(unsigned int irq) | 254 | static inline int irq_balancing_disabled(unsigned int irq) |
251 | { | 255 | { |
252 | return irq_desc[irq].status & IRQ_NO_BALANCING_MASK; | 256 | struct irq_desc *desc; |
257 | |||
258 | desc = irq_to_desc(irq); | ||
259 | return desc->status & IRQ_NO_BALANCING_MASK; | ||
253 | } | 260 | } |
254 | 261 | ||
255 | /* Handle irq action chains: */ | 262 | /* Handle irq action chains: */ |
@@ -281,7 +288,7 @@ extern unsigned int __do_IRQ(unsigned int irq); | |||
281 | */ | 288 | */ |
282 | static inline void generic_handle_irq(unsigned int irq) | 289 | static inline void generic_handle_irq(unsigned int irq) |
283 | { | 290 | { |
284 | struct irq_desc *desc = irq_desc + irq; | 291 | struct irq_desc *desc = irq_to_desc(irq); |
285 | 292 | ||
286 | #ifdef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ | 293 | #ifdef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ |
287 | desc->handle_irq(irq, desc); | 294 | desc->handle_irq(irq, desc); |
@@ -325,7 +332,10 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, | |||
325 | static inline void __set_irq_handler_unlocked(int irq, | 332 | static inline void __set_irq_handler_unlocked(int irq, |
326 | irq_flow_handler_t handler) | 333 | irq_flow_handler_t handler) |
327 | { | 334 | { |
328 | irq_desc[irq].handle_irq = handler; | 335 | struct irq_desc *desc; |
336 | |||
337 | desc = irq_to_desc(irq); | ||
338 | desc->handle_irq = handler; | ||
329 | } | 339 | } |
330 | 340 | ||
331 | /* | 341 | /* |
@@ -359,7 +369,7 @@ extern void destroy_irq(unsigned int irq); | |||
359 | /* Test to see if a driver has successfully requested an irq */ | 369 | /* Test to see if a driver has successfully requested an irq */ |
360 | static inline int irq_has_action(unsigned int irq) | 370 | static inline int irq_has_action(unsigned int irq) |
361 | { | 371 | { |
362 | struct irq_desc *desc = irq_desc + irq; | 372 | struct irq_desc *desc = irq_to_desc(irq); |
363 | return desc->action != NULL; | 373 | return desc->action != NULL; |
364 | } | 374 | } |
365 | 375 | ||
@@ -374,10 +384,10 @@ extern int set_irq_chip_data(unsigned int irq, void *data); | |||
374 | extern int set_irq_type(unsigned int irq, unsigned int type); | 384 | extern int set_irq_type(unsigned int irq, unsigned int type); |
375 | extern int set_irq_msi(unsigned int irq, struct msi_desc *entry); | 385 | extern int set_irq_msi(unsigned int irq, struct msi_desc *entry); |
376 | 386 | ||
377 | #define get_irq_chip(irq) (irq_desc[irq].chip) | 387 | #define get_irq_chip(irq) (irq_to_desc(irq)->chip) |
378 | #define get_irq_chip_data(irq) (irq_desc[irq].chip_data) | 388 | #define get_irq_chip_data(irq) (irq_to_desc(irq)->chip_data) |
379 | #define get_irq_data(irq) (irq_desc[irq].handler_data) | 389 | #define get_irq_data(irq) (irq_to_desc(irq)->handler_data) |
380 | #define get_irq_msi(irq) (irq_desc[irq].msi_desc) | 390 | #define get_irq_msi(irq) (irq_to_desc(irq)->msi_desc) |
381 | 391 | ||
382 | #endif /* CONFIG_GENERIC_HARDIRQS */ | 392 | #endif /* CONFIG_GENERIC_HARDIRQS */ |
383 | 393 | ||
diff --git a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c index c689e9851a80..c45ab718cf07 100644 --- a/kernel/irq/autoprobe.c +++ b/kernel/irq/autoprobe.c | |||
@@ -39,7 +39,7 @@ unsigned long probe_irq_on(void) | |||
39 | * flush such a longstanding irq before considering it as spurious. | 39 | * flush such a longstanding irq before considering it as spurious. |
40 | */ | 40 | */ |
41 | for (i = nr_irqs-1; i > 0; i--) { | 41 | for (i = nr_irqs-1; i > 0; i--) { |
42 | desc = irq_desc + i; | 42 | desc = irq_to_desc(i); |
43 | 43 | ||
44 | spin_lock_irq(&desc->lock); | 44 | spin_lock_irq(&desc->lock); |
45 | if (!desc->action && !(desc->status & IRQ_NOPROBE)) { | 45 | if (!desc->action && !(desc->status & IRQ_NOPROBE)) { |
@@ -69,7 +69,7 @@ unsigned long probe_irq_on(void) | |||
69 | * happened in the previous stage, it may have masked itself) | 69 | * happened in the previous stage, it may have masked itself) |
70 | */ | 70 | */ |
71 | for (i = nr_irqs-1; i > 0; i--) { | 71 | for (i = nr_irqs-1; i > 0; i--) { |
72 | desc = irq_desc + i; | 72 | desc = irq_to_desc(i); |
73 | 73 | ||
74 | spin_lock_irq(&desc->lock); | 74 | spin_lock_irq(&desc->lock); |
75 | if (!desc->action && !(desc->status & IRQ_NOPROBE)) { | 75 | if (!desc->action && !(desc->status & IRQ_NOPROBE)) { |
@@ -92,7 +92,7 @@ unsigned long probe_irq_on(void) | |||
92 | for (i = 0; i < nr_irqs; i++) { | 92 | for (i = 0; i < nr_irqs; i++) { |
93 | unsigned int status; | 93 | unsigned int status; |
94 | 94 | ||
95 | desc = irq_desc + i; | 95 | desc = irq_to_desc(i); |
96 | spin_lock_irq(&desc->lock); | 96 | spin_lock_irq(&desc->lock); |
97 | status = desc->status; | 97 | status = desc->status; |
98 | 98 | ||
@@ -131,7 +131,7 @@ unsigned int probe_irq_mask(unsigned long val) | |||
131 | 131 | ||
132 | mask = 0; | 132 | mask = 0; |
133 | for (i = 0; i < nr_irqs; i++) { | 133 | for (i = 0; i < nr_irqs; i++) { |
134 | struct irq_desc *desc = irq_desc + i; | 134 | struct irq_desc *desc = irq_to_desc(i); |
135 | unsigned int status; | 135 | unsigned int status; |
136 | 136 | ||
137 | spin_lock_irq(&desc->lock); | 137 | spin_lock_irq(&desc->lock); |
@@ -174,7 +174,7 @@ int probe_irq_off(unsigned long val) | |||
174 | int i, irq_found = 0, nr_irqs = 0; | 174 | int i, irq_found = 0, nr_irqs = 0; |
175 | 175 | ||
176 | for (i = 0; i < nr_irqs; i++) { | 176 | for (i = 0; i < nr_irqs; i++) { |
177 | struct irq_desc *desc = irq_desc + i; | 177 | struct irq_desc *desc = irq_to_desc(i); |
178 | unsigned int status; | 178 | unsigned int status; |
179 | 179 | ||
180 | spin_lock_irq(&desc->lock); | 180 | spin_lock_irq(&desc->lock); |
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index bba66e098703..76c225cf4b26 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c | |||
@@ -33,7 +33,7 @@ void dynamic_irq_init(unsigned int irq) | |||
33 | } | 33 | } |
34 | 34 | ||
35 | /* Ensure we don't have left over values from a previous use of this irq */ | 35 | /* Ensure we don't have left over values from a previous use of this irq */ |
36 | desc = irq_desc + irq; | 36 | desc = irq_to_desc(irq); |
37 | spin_lock_irqsave(&desc->lock, flags); | 37 | spin_lock_irqsave(&desc->lock, flags); |
38 | desc->status = IRQ_DISABLED; | 38 | desc->status = IRQ_DISABLED; |
39 | desc->chip = &no_irq_chip; | 39 | desc->chip = &no_irq_chip; |
@@ -65,7 +65,7 @@ void dynamic_irq_cleanup(unsigned int irq) | |||
65 | return; | 65 | return; |
66 | } | 66 | } |
67 | 67 | ||
68 | desc = irq_desc + irq; | 68 | desc = irq_to_desc(irq); |
69 | spin_lock_irqsave(&desc->lock, flags); | 69 | spin_lock_irqsave(&desc->lock, flags); |
70 | if (desc->action) { | 70 | if (desc->action) { |
71 | spin_unlock_irqrestore(&desc->lock, flags); | 71 | spin_unlock_irqrestore(&desc->lock, flags); |
@@ -100,7 +100,7 @@ int set_irq_chip(unsigned int irq, struct irq_chip *chip) | |||
100 | if (!chip) | 100 | if (!chip) |
101 | chip = &no_irq_chip; | 101 | chip = &no_irq_chip; |
102 | 102 | ||
103 | desc = irq_desc + irq; | 103 | desc = irq_to_desc(irq); |
104 | spin_lock_irqsave(&desc->lock, flags); | 104 | spin_lock_irqsave(&desc->lock, flags); |
105 | irq_chip_set_defaults(chip); | 105 | irq_chip_set_defaults(chip); |
106 | desc->chip = chip; | 106 | desc->chip = chip; |
@@ -126,7 +126,7 @@ int set_irq_type(unsigned int irq, unsigned int type) | |||
126 | return -ENODEV; | 126 | return -ENODEV; |
127 | } | 127 | } |
128 | 128 | ||
129 | desc = irq_desc + irq; | 129 | desc = irq_to_desc(irq); |
130 | if (type == IRQ_TYPE_NONE) | 130 | if (type == IRQ_TYPE_NONE) |
131 | return 0; | 131 | return 0; |
132 | 132 | ||
@@ -155,7 +155,7 @@ int set_irq_data(unsigned int irq, void *data) | |||
155 | return -EINVAL; | 155 | return -EINVAL; |
156 | } | 156 | } |
157 | 157 | ||
158 | desc = irq_desc + irq; | 158 | desc = irq_to_desc(irq); |
159 | spin_lock_irqsave(&desc->lock, flags); | 159 | spin_lock_irqsave(&desc->lock, flags); |
160 | desc->handler_data = data; | 160 | desc->handler_data = data; |
161 | spin_unlock_irqrestore(&desc->lock, flags); | 161 | spin_unlock_irqrestore(&desc->lock, flags); |
@@ -180,7 +180,7 @@ int set_irq_msi(unsigned int irq, struct msi_desc *entry) | |||
180 | "Trying to install msi data for IRQ%d\n", irq); | 180 | "Trying to install msi data for IRQ%d\n", irq); |
181 | return -EINVAL; | 181 | return -EINVAL; |
182 | } | 182 | } |
183 | desc = irq_desc + irq; | 183 | desc = irq_to_desc(irq); |
184 | spin_lock_irqsave(&desc->lock, flags); | 184 | spin_lock_irqsave(&desc->lock, flags); |
185 | desc->msi_desc = entry; | 185 | desc->msi_desc = entry; |
186 | if (entry) | 186 | if (entry) |
@@ -198,9 +198,10 @@ int set_irq_msi(unsigned int irq, struct msi_desc *entry) | |||
198 | */ | 198 | */ |
199 | int set_irq_chip_data(unsigned int irq, void *data) | 199 | int set_irq_chip_data(unsigned int irq, void *data) |
200 | { | 200 | { |
201 | struct irq_desc *desc = irq_desc + irq; | 201 | struct irq_desc *desc; |
202 | unsigned long flags; | 202 | unsigned long flags; |
203 | 203 | ||
204 | desc = irq_to_desc(irq); | ||
204 | if (irq >= nr_irqs || !desc->chip) { | 205 | if (irq >= nr_irqs || !desc->chip) { |
205 | printk(KERN_ERR "BUG: bad set_irq_chip_data(IRQ#%d)\n", irq); | 206 | printk(KERN_ERR "BUG: bad set_irq_chip_data(IRQ#%d)\n", irq); |
206 | return -EINVAL; | 207 | return -EINVAL; |
@@ -219,8 +220,9 @@ EXPORT_SYMBOL(set_irq_chip_data); | |||
219 | */ | 220 | */ |
220 | static void default_enable(unsigned int irq) | 221 | static void default_enable(unsigned int irq) |
221 | { | 222 | { |
222 | struct irq_desc *desc = irq_desc + irq; | 223 | struct irq_desc *desc; |
223 | 224 | ||
225 | desc = irq_to_desc(irq); | ||
224 | desc->chip->unmask(irq); | 226 | desc->chip->unmask(irq); |
225 | desc->status &= ~IRQ_MASKED; | 227 | desc->status &= ~IRQ_MASKED; |
226 | } | 228 | } |
@@ -237,7 +239,10 @@ static void default_disable(unsigned int irq) | |||
237 | */ | 239 | */ |
238 | static unsigned int default_startup(unsigned int irq) | 240 | static unsigned int default_startup(unsigned int irq) |
239 | { | 241 | { |
240 | irq_desc[irq].chip->enable(irq); | 242 | struct irq_desc *desc; |
243 | |||
244 | desc = irq_to_desc(irq); | ||
245 | desc->chip->enable(irq); | ||
241 | 246 | ||
242 | return 0; | 247 | return 0; |
243 | } | 248 | } |
@@ -247,8 +252,9 @@ static unsigned int default_startup(unsigned int irq) | |||
247 | */ | 252 | */ |
248 | static void default_shutdown(unsigned int irq) | 253 | static void default_shutdown(unsigned int irq) |
249 | { | 254 | { |
250 | struct irq_desc *desc = irq_desc + irq; | 255 | struct irq_desc *desc; |
251 | 256 | ||
257 | desc = irq_to_desc(irq); | ||
252 | desc->chip->mask(irq); | 258 | desc->chip->mask(irq); |
253 | desc->status |= IRQ_MASKED; | 259 | desc->status |= IRQ_MASKED; |
254 | } | 260 | } |
@@ -551,7 +557,7 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, | |||
551 | return; | 557 | return; |
552 | } | 558 | } |
553 | 559 | ||
554 | desc = irq_desc + irq; | 560 | desc = irq_to_desc(irq); |
555 | 561 | ||
556 | if (!handle) | 562 | if (!handle) |
557 | handle = handle_bad_irq; | 563 | handle = handle_bad_irq; |
@@ -616,7 +622,7 @@ void __init set_irq_noprobe(unsigned int irq) | |||
616 | return; | 622 | return; |
617 | } | 623 | } |
618 | 624 | ||
619 | desc = irq_desc + irq; | 625 | desc = irq_to_desc(irq); |
620 | 626 | ||
621 | spin_lock_irqsave(&desc->lock, flags); | 627 | spin_lock_irqsave(&desc->lock, flags); |
622 | desc->status |= IRQ_NOPROBE; | 628 | desc->status |= IRQ_NOPROBE; |
@@ -634,7 +640,7 @@ void __init set_irq_probe(unsigned int irq) | |||
634 | return; | 640 | return; |
635 | } | 641 | } |
636 | 642 | ||
637 | desc = irq_desc + irq; | 643 | desc = irq_to_desc(irq); |
638 | 644 | ||
639 | spin_lock_irqsave(&desc->lock, flags); | 645 | spin_lock_irqsave(&desc->lock, flags); |
640 | desc->status &= ~IRQ_NOPROBE; | 646 | desc->status &= ~IRQ_NOPROBE; |
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c index 6ce3bcc2b8f7..9fc33b3378e6 100644 --- a/kernel/irq/handle.c +++ b/kernel/irq/handle.c | |||
@@ -18,6 +18,14 @@ | |||
18 | 18 | ||
19 | #include "internals.h" | 19 | #include "internals.h" |
20 | 20 | ||
21 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
22 | |||
23 | /* | ||
24 | * lockdep: we want to handle all irq_desc locks as a single lock-class: | ||
25 | */ | ||
26 | static struct lock_class_key irq_desc_lock_class; | ||
27 | #endif | ||
28 | |||
21 | /** | 29 | /** |
22 | * handle_bad_irq - handle spurious and unhandled irqs | 30 | * handle_bad_irq - handle spurious and unhandled irqs |
23 | * @irq: the interrupt number | 31 | * @irq: the interrupt number |
@@ -51,7 +59,8 @@ int nr_irqs = NR_IRQS; | |||
51 | EXPORT_SYMBOL_GPL(nr_irqs); | 59 | EXPORT_SYMBOL_GPL(nr_irqs); |
52 | 60 | ||
53 | #ifdef CONFIG_HAVE_DYN_ARRAY | 61 | #ifdef CONFIG_HAVE_DYN_ARRAY |
54 | static struct irq_desc irq_desc_init __initdata = { | 62 | static struct irq_desc irq_desc_init = { |
63 | .irq = -1U, | ||
55 | .status = IRQ_DISABLED, | 64 | .status = IRQ_DISABLED, |
56 | .chip = &no_irq_chip, | 65 | .chip = &no_irq_chip, |
57 | .handle_irq = handle_bad_irq, | 66 | .handle_irq = handle_bad_irq, |
@@ -62,6 +71,27 @@ static struct irq_desc irq_desc_init __initdata = { | |||
62 | #endif | 71 | #endif |
63 | }; | 72 | }; |
64 | 73 | ||
74 | |||
75 | static void init_one_irq_desc(struct irq_desc *desc) | ||
76 | { | ||
77 | memcpy(desc, &irq_desc_init, sizeof(struct irq_desc)); | ||
78 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
79 | lockdep_set_class(&desc->lock, &irq_desc_lock_class); | ||
80 | #endif | ||
81 | } | ||
82 | |||
83 | #ifdef CONFIG_HAVE_SPARSE_IRQ | ||
84 | static int nr_irq_desc = 32; | ||
85 | |||
86 | static int __init parse_nr_irq_desc(char *arg) | ||
87 | { | ||
88 | if (arg) | ||
89 | nr_irq_desc = simple_strtoul(arg, NULL, 0); | ||
90 | return 0; | ||
91 | } | ||
92 | |||
93 | early_param("nr_irq_desc", parse_nr_irq_desc); | ||
94 | |||
65 | static void __init init_work(void *data) | 95 | static void __init init_work(void *data) |
66 | { | 96 | { |
67 | struct dyn_array *da = data; | 97 | struct dyn_array *da = data; |
@@ -71,12 +101,83 @@ static void __init init_work(void *data) | |||
71 | desc = *da->name; | 101 | desc = *da->name; |
72 | 102 | ||
73 | for (i = 0; i < *da->nr; i++) | 103 | for (i = 0; i < *da->nr; i++) |
74 | memcpy(&desc[i], &irq_desc_init, sizeof(struct irq_desc)); | 104 | init_one_irq_desc(&desc[i]); |
105 | |||
106 | for (i = 1; i < *da->nr; i++) | ||
107 | desc[i-1].next = &desc[i]; | ||
75 | } | 108 | } |
76 | 109 | ||
77 | struct irq_desc *irq_desc; | 110 | static struct irq_desc *sparse_irqs; |
111 | DEFINE_DYN_ARRAY(sparse_irqs, sizeof(struct irq_desc), nr_irq_desc, PAGE_SIZE, init_work); | ||
112 | |||
113 | extern int after_bootmem; | ||
114 | extern void *__alloc_bootmem_nopanic(unsigned long size, | ||
115 | unsigned long align, | ||
116 | unsigned long goal); | ||
117 | struct irq_desc *irq_to_desc(unsigned int irq) | ||
118 | { | ||
119 | struct irq_desc *desc, *desc_pri; | ||
120 | int i; | ||
121 | int count = 0; | ||
122 | |||
123 | BUG_ON(irq == -1U); | ||
124 | |||
125 | desc_pri = desc = &sparse_irqs[0]; | ||
126 | while (desc) { | ||
127 | if (desc->irq == irq) | ||
128 | return desc; | ||
129 | |||
130 | if (desc->irq == -1U) { | ||
131 | desc->irq = irq; | ||
132 | return desc; | ||
133 | } | ||
134 | desc_pri = desc; | ||
135 | desc = desc->next; | ||
136 | count++; | ||
137 | } | ||
138 | |||
139 | /* | ||
140 | * we run out of pre-allocate ones, allocate more | ||
141 | */ | ||
142 | printk(KERN_DEBUG "try to get more irq_desc %d\n", nr_irq_desc); | ||
143 | |||
144 | if (after_bootmem) | ||
145 | desc = kzalloc(sizeof(struct irq_desc)*nr_irq_desc, GFP_ATOMIC); | ||
146 | else | ||
147 | desc = __alloc_bootmem_nopanic(sizeof(struct irq_desc)*nr_irq_desc, PAGE_SIZE, 0); | ||
148 | |||
149 | if (!desc) | ||
150 | panic("please boot with nr_irq_desc= %d\n", count * 2); | ||
151 | |||
152 | for (i = 0; i < nr_irq_desc; i++) | ||
153 | init_one_irq_desc(&desc[i]); | ||
154 | |||
155 | for (i = 1; i < nr_irq_desc; i++) | ||
156 | desc[i-1].next = &desc[i]; | ||
157 | |||
158 | desc->irq = irq; | ||
159 | desc_pri->next = desc; | ||
160 | |||
161 | return desc; | ||
162 | } | ||
163 | #else | ||
164 | static void __init init_work(void *data) | ||
165 | { | ||
166 | struct dyn_array *da = data; | ||
167 | int i; | ||
168 | struct irq_desc *desc; | ||
169 | |||
170 | desc = *da->name; | ||
171 | |||
172 | for (i = 0; i < *da->nr; i++) | ||
173 | init_one_irq_desc(&desc[i]); | ||
174 | |||
175 | } | ||
176 | static struct irq_desc *irq_desc; | ||
78 | DEFINE_DYN_ARRAY(irq_desc, sizeof(struct irq_desc), nr_irqs, PAGE_SIZE, init_work); | 177 | DEFINE_DYN_ARRAY(irq_desc, sizeof(struct irq_desc), nr_irqs, PAGE_SIZE, init_work); |
79 | 178 | ||
179 | #endif | ||
180 | |||
80 | #else | 181 | #else |
81 | 182 | ||
82 | struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = { | 183 | struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = { |
@@ -85,12 +186,23 @@ struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = { | |||
85 | .chip = &no_irq_chip, | 186 | .chip = &no_irq_chip, |
86 | .handle_irq = handle_bad_irq, | 187 | .handle_irq = handle_bad_irq, |
87 | .depth = 1, | 188 | .depth = 1, |
88 | .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock), | 189 | .lock = __SPIN_LOCK_UNLOCKED(sparse_irqs->lock), |
89 | #ifdef CONFIG_SMP | 190 | #ifdef CONFIG_SMP |
90 | .affinity = CPU_MASK_ALL | 191 | .affinity = CPU_MASK_ALL |
91 | #endif | 192 | #endif |
92 | } | 193 | } |
93 | }; | 194 | }; |
195 | |||
196 | #endif | ||
197 | |||
198 | #ifndef CONFIG_HAVE_SPARSE_IRQ | ||
199 | struct irq_desc *irq_to_desc(unsigned int irq) | ||
200 | { | ||
201 | if (irq < nr_irqs) | ||
202 | return &irq_desc[irq]; | ||
203 | |||
204 | return NULL; | ||
205 | } | ||
94 | #endif | 206 | #endif |
95 | 207 | ||
96 | /* | 208 | /* |
@@ -99,7 +211,10 @@ struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = { | |||
99 | */ | 211 | */ |
100 | static void ack_bad(unsigned int irq) | 212 | static void ack_bad(unsigned int irq) |
101 | { | 213 | { |
102 | print_irq_desc(irq, irq_desc + irq); | 214 | struct irq_desc *desc; |
215 | |||
216 | desc = irq_to_desc(irq); | ||
217 | print_irq_desc(irq, desc); | ||
103 | ack_bad_irq(irq); | 218 | ack_bad_irq(irq); |
104 | } | 219 | } |
105 | 220 | ||
@@ -196,7 +311,7 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action) | |||
196 | */ | 311 | */ |
197 | unsigned int __do_IRQ(unsigned int irq) | 312 | unsigned int __do_IRQ(unsigned int irq) |
198 | { | 313 | { |
199 | struct irq_desc *desc = irq_desc + irq; | 314 | struct irq_desc *desc = irq_to_desc(irq); |
200 | struct irqaction *action; | 315 | struct irqaction *action; |
201 | unsigned int status; | 316 | unsigned int status; |
202 | 317 | ||
@@ -287,19 +402,16 @@ out: | |||
287 | } | 402 | } |
288 | #endif | 403 | #endif |
289 | 404 | ||
290 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
291 | |||
292 | /* | ||
293 | * lockdep: we want to handle all irq_desc locks as a single lock-class: | ||
294 | */ | ||
295 | static struct lock_class_key irq_desc_lock_class; | ||
296 | 405 | ||
406 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
297 | void early_init_irq_lock_class(void) | 407 | void early_init_irq_lock_class(void) |
298 | { | 408 | { |
409 | #ifndef CONFIG_HAVE_DYN_ARRAY | ||
299 | int i; | 410 | int i; |
300 | 411 | ||
301 | for (i = 0; i < nr_irqs; i++) | 412 | for (i = 0; i < nr_irqs; i++) |
302 | lockdep_set_class(&irq_desc[i].lock, &irq_desc_lock_class); | 413 | lockdep_set_class(&irq_desc[i].lock, &irq_desc_lock_class); |
414 | #endif | ||
303 | } | 415 | } |
304 | |||
305 | #endif | 416 | #endif |
417 | |||
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index d5a4333d8f1f..b5943e9f95aa 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
@@ -31,7 +31,7 @@ cpumask_t irq_default_affinity = CPU_MASK_ALL; | |||
31 | */ | 31 | */ |
32 | void synchronize_irq(unsigned int irq) | 32 | void synchronize_irq(unsigned int irq) |
33 | { | 33 | { |
34 | struct irq_desc *desc = irq_desc + irq; | 34 | struct irq_desc *desc = irq_to_desc(irq); |
35 | unsigned int status; | 35 | unsigned int status; |
36 | 36 | ||
37 | if (irq >= nr_irqs) | 37 | if (irq >= nr_irqs) |
@@ -64,7 +64,7 @@ EXPORT_SYMBOL(synchronize_irq); | |||
64 | */ | 64 | */ |
65 | int irq_can_set_affinity(unsigned int irq) | 65 | int irq_can_set_affinity(unsigned int irq) |
66 | { | 66 | { |
67 | struct irq_desc *desc = irq_desc + irq; | 67 | struct irq_desc *desc = irq_to_desc(irq); |
68 | 68 | ||
69 | if (CHECK_IRQ_PER_CPU(desc->status) || !desc->chip || | 69 | if (CHECK_IRQ_PER_CPU(desc->status) || !desc->chip || |
70 | !desc->chip->set_affinity) | 70 | !desc->chip->set_affinity) |
@@ -81,7 +81,7 @@ int irq_can_set_affinity(unsigned int irq) | |||
81 | */ | 81 | */ |
82 | int irq_set_affinity(unsigned int irq, cpumask_t cpumask) | 82 | int irq_set_affinity(unsigned int irq, cpumask_t cpumask) |
83 | { | 83 | { |
84 | struct irq_desc *desc = irq_desc + irq; | 84 | struct irq_desc *desc = irq_to_desc(irq); |
85 | 85 | ||
86 | if (!desc->chip->set_affinity) | 86 | if (!desc->chip->set_affinity) |
87 | return -EINVAL; | 87 | return -EINVAL; |
@@ -111,14 +111,16 @@ int irq_set_affinity(unsigned int irq, cpumask_t cpumask) | |||
111 | int irq_select_affinity(unsigned int irq) | 111 | int irq_select_affinity(unsigned int irq) |
112 | { | 112 | { |
113 | cpumask_t mask; | 113 | cpumask_t mask; |
114 | struct irq_desc *desc; | ||
114 | 115 | ||
115 | if (!irq_can_set_affinity(irq)) | 116 | if (!irq_can_set_affinity(irq)) |
116 | return 0; | 117 | return 0; |
117 | 118 | ||
118 | cpus_and(mask, cpu_online_map, irq_default_affinity); | 119 | cpus_and(mask, cpu_online_map, irq_default_affinity); |
119 | 120 | ||
120 | irq_desc[irq].affinity = mask; | 121 | desc = irq_to_desc(irq); |
121 | irq_desc[irq].chip->set_affinity(irq, mask); | 122 | desc->affinity = mask; |
123 | desc->chip->set_affinity(irq, mask); | ||
122 | 124 | ||
123 | set_balance_irq_affinity(irq, mask); | 125 | set_balance_irq_affinity(irq, mask); |
124 | return 0; | 126 | return 0; |
@@ -140,7 +142,7 @@ int irq_select_affinity(unsigned int irq) | |||
140 | */ | 142 | */ |
141 | void disable_irq_nosync(unsigned int irq) | 143 | void disable_irq_nosync(unsigned int irq) |
142 | { | 144 | { |
143 | struct irq_desc *desc = irq_desc + irq; | 145 | struct irq_desc *desc = irq_to_desc(irq); |
144 | unsigned long flags; | 146 | unsigned long flags; |
145 | 147 | ||
146 | if (irq >= nr_irqs) | 148 | if (irq >= nr_irqs) |
@@ -169,7 +171,7 @@ EXPORT_SYMBOL(disable_irq_nosync); | |||
169 | */ | 171 | */ |
170 | void disable_irq(unsigned int irq) | 172 | void disable_irq(unsigned int irq) |
171 | { | 173 | { |
172 | struct irq_desc *desc = irq_desc + irq; | 174 | struct irq_desc *desc = irq_to_desc(irq); |
173 | 175 | ||
174 | if (irq >= nr_irqs) | 176 | if (irq >= nr_irqs) |
175 | return; | 177 | return; |
@@ -211,7 +213,7 @@ static void __enable_irq(struct irq_desc *desc, unsigned int irq) | |||
211 | */ | 213 | */ |
212 | void enable_irq(unsigned int irq) | 214 | void enable_irq(unsigned int irq) |
213 | { | 215 | { |
214 | struct irq_desc *desc = irq_desc + irq; | 216 | struct irq_desc *desc = irq_to_desc(irq); |
215 | unsigned long flags; | 217 | unsigned long flags; |
216 | 218 | ||
217 | if (irq >= nr_irqs) | 219 | if (irq >= nr_irqs) |
@@ -225,7 +227,7 @@ EXPORT_SYMBOL(enable_irq); | |||
225 | 227 | ||
226 | static int set_irq_wake_real(unsigned int irq, unsigned int on) | 228 | static int set_irq_wake_real(unsigned int irq, unsigned int on) |
227 | { | 229 | { |
228 | struct irq_desc *desc = irq_desc + irq; | 230 | struct irq_desc *desc = irq_to_desc(irq); |
229 | int ret = -ENXIO; | 231 | int ret = -ENXIO; |
230 | 232 | ||
231 | if (desc->chip->set_wake) | 233 | if (desc->chip->set_wake) |
@@ -248,7 +250,7 @@ static int set_irq_wake_real(unsigned int irq, unsigned int on) | |||
248 | */ | 250 | */ |
249 | int set_irq_wake(unsigned int irq, unsigned int on) | 251 | int set_irq_wake(unsigned int irq, unsigned int on) |
250 | { | 252 | { |
251 | struct irq_desc *desc = irq_desc + irq; | 253 | struct irq_desc *desc = irq_to_desc(irq); |
252 | unsigned long flags; | 254 | unsigned long flags; |
253 | int ret = 0; | 255 | int ret = 0; |
254 | 256 | ||
@@ -288,12 +290,13 @@ EXPORT_SYMBOL(set_irq_wake); | |||
288 | */ | 290 | */ |
289 | int can_request_irq(unsigned int irq, unsigned long irqflags) | 291 | int can_request_irq(unsigned int irq, unsigned long irqflags) |
290 | { | 292 | { |
293 | struct irq_desc *desc = irq_to_desc(irq); | ||
291 | struct irqaction *action; | 294 | struct irqaction *action; |
292 | 295 | ||
293 | if (irq >= nr_irqs || irq_desc[irq].status & IRQ_NOREQUEST) | 296 | if (irq >= nr_irqs || desc->status & IRQ_NOREQUEST) |
294 | return 0; | 297 | return 0; |
295 | 298 | ||
296 | action = irq_desc[irq].action; | 299 | action = desc->action; |
297 | if (action) | 300 | if (action) |
298 | if (irqflags & action->flags & IRQF_SHARED) | 301 | if (irqflags & action->flags & IRQF_SHARED) |
299 | action = NULL; | 302 | action = NULL; |
@@ -349,7 +352,7 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned int irq, | |||
349 | */ | 352 | */ |
350 | int setup_irq(unsigned int irq, struct irqaction *new) | 353 | int setup_irq(unsigned int irq, struct irqaction *new) |
351 | { | 354 | { |
352 | struct irq_desc *desc = irq_desc + irq; | 355 | struct irq_desc *desc = irq_to_desc(irq); |
353 | struct irqaction *old, **p; | 356 | struct irqaction *old, **p; |
354 | const char *old_name = NULL; | 357 | const char *old_name = NULL; |
355 | unsigned long flags; | 358 | unsigned long flags; |
@@ -518,7 +521,7 @@ void free_irq(unsigned int irq, void *dev_id) | |||
518 | if (irq >= nr_irqs) | 521 | if (irq >= nr_irqs) |
519 | return; | 522 | return; |
520 | 523 | ||
521 | desc = irq_desc + irq; | 524 | desc = irq_to_desc(irq); |
522 | spin_lock_irqsave(&desc->lock, flags); | 525 | spin_lock_irqsave(&desc->lock, flags); |
523 | p = &desc->action; | 526 | p = &desc->action; |
524 | for (;;) { | 527 | for (;;) { |
@@ -615,6 +618,7 @@ int request_irq(unsigned int irq, irq_handler_t handler, | |||
615 | { | 618 | { |
616 | struct irqaction *action; | 619 | struct irqaction *action; |
617 | int retval; | 620 | int retval; |
621 | struct irq_desc *desc; | ||
618 | 622 | ||
619 | #ifdef CONFIG_LOCKDEP | 623 | #ifdef CONFIG_LOCKDEP |
620 | /* | 624 | /* |
@@ -632,7 +636,8 @@ int request_irq(unsigned int irq, irq_handler_t handler, | |||
632 | return -EINVAL; | 636 | return -EINVAL; |
633 | if (irq >= nr_irqs) | 637 | if (irq >= nr_irqs) |
634 | return -EINVAL; | 638 | return -EINVAL; |
635 | if (irq_desc[irq].status & IRQ_NOREQUEST) | 639 | desc = irq_to_desc(irq); |
640 | if (desc->status & IRQ_NOREQUEST) | ||
636 | return -EINVAL; | 641 | return -EINVAL; |
637 | if (!handler) | 642 | if (!handler) |
638 | return -EINVAL; | 643 | return -EINVAL; |
diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c index 77b7acc875c5..90b920d3f52b 100644 --- a/kernel/irq/migration.c +++ b/kernel/irq/migration.c | |||
@@ -3,18 +3,18 @@ | |||
3 | 3 | ||
4 | void set_pending_irq(unsigned int irq, cpumask_t mask) | 4 | void set_pending_irq(unsigned int irq, cpumask_t mask) |
5 | { | 5 | { |
6 | struct irq_desc *desc = irq_desc + irq; | 6 | struct irq_desc *desc = irq_to_desc(irq); |
7 | unsigned long flags; | 7 | unsigned long flags; |
8 | 8 | ||
9 | spin_lock_irqsave(&desc->lock, flags); | 9 | spin_lock_irqsave(&desc->lock, flags); |
10 | desc->status |= IRQ_MOVE_PENDING; | 10 | desc->status |= IRQ_MOVE_PENDING; |
11 | irq_desc[irq].pending_mask = mask; | 11 | desc->pending_mask = mask; |
12 | spin_unlock_irqrestore(&desc->lock, flags); | 12 | spin_unlock_irqrestore(&desc->lock, flags); |
13 | } | 13 | } |
14 | 14 | ||
15 | void move_masked_irq(int irq) | 15 | void move_masked_irq(int irq) |
16 | { | 16 | { |
17 | struct irq_desc *desc = irq_desc + irq; | 17 | struct irq_desc *desc = irq_to_desc(irq); |
18 | cpumask_t tmp; | 18 | cpumask_t tmp; |
19 | 19 | ||
20 | if (likely(!(desc->status & IRQ_MOVE_PENDING))) | 20 | if (likely(!(desc->status & IRQ_MOVE_PENDING))) |
@@ -30,7 +30,7 @@ void move_masked_irq(int irq) | |||
30 | 30 | ||
31 | desc->status &= ~IRQ_MOVE_PENDING; | 31 | desc->status &= ~IRQ_MOVE_PENDING; |
32 | 32 | ||
33 | if (unlikely(cpus_empty(irq_desc[irq].pending_mask))) | 33 | if (unlikely(cpus_empty(desc->pending_mask))) |
34 | return; | 34 | return; |
35 | 35 | ||
36 | if (!desc->chip->set_affinity) | 36 | if (!desc->chip->set_affinity) |
@@ -38,7 +38,7 @@ void move_masked_irq(int irq) | |||
38 | 38 | ||
39 | assert_spin_locked(&desc->lock); | 39 | assert_spin_locked(&desc->lock); |
40 | 40 | ||
41 | cpus_and(tmp, irq_desc[irq].pending_mask, cpu_online_map); | 41 | cpus_and(tmp, desc->pending_mask, cpu_online_map); |
42 | 42 | ||
43 | /* | 43 | /* |
44 | * If there was a valid mask to work with, please | 44 | * If there was a valid mask to work with, please |
@@ -55,12 +55,12 @@ void move_masked_irq(int irq) | |||
55 | if (likely(!cpus_empty(tmp))) { | 55 | if (likely(!cpus_empty(tmp))) { |
56 | desc->chip->set_affinity(irq,tmp); | 56 | desc->chip->set_affinity(irq,tmp); |
57 | } | 57 | } |
58 | cpus_clear(irq_desc[irq].pending_mask); | 58 | cpus_clear(desc->pending_mask); |
59 | } | 59 | } |
60 | 60 | ||
61 | void move_native_irq(int irq) | 61 | void move_native_irq(int irq) |
62 | { | 62 | { |
63 | struct irq_desc *desc = irq_desc + irq; | 63 | struct irq_desc *desc = irq_to_desc(irq); |
64 | 64 | ||
65 | if (likely(!(desc->status & IRQ_MOVE_PENDING))) | 65 | if (likely(!(desc->status & IRQ_MOVE_PENDING))) |
66 | return; | 66 | return; |
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c index e5225a65a4f9..c2f356c808f6 100644 --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c | |||
@@ -19,7 +19,7 @@ static struct proc_dir_entry *root_irq_dir; | |||
19 | 19 | ||
20 | static int irq_affinity_proc_show(struct seq_file *m, void *v) | 20 | static int irq_affinity_proc_show(struct seq_file *m, void *v) |
21 | { | 21 | { |
22 | struct irq_desc *desc = irq_desc + (long)m->private; | 22 | struct irq_desc *desc = irq_to_desc((long)m->private); |
23 | cpumask_t *mask = &desc->affinity; | 23 | cpumask_t *mask = &desc->affinity; |
24 | 24 | ||
25 | #ifdef CONFIG_GENERIC_PENDING_IRQ | 25 | #ifdef CONFIG_GENERIC_PENDING_IRQ |
@@ -43,7 +43,7 @@ static ssize_t irq_affinity_proc_write(struct file *file, | |||
43 | cpumask_t new_value; | 43 | cpumask_t new_value; |
44 | int err; | 44 | int err; |
45 | 45 | ||
46 | if (!irq_desc[irq].chip->set_affinity || no_irq_affinity || | 46 | if (!irq_to_desc(irq)->chip->set_affinity || no_irq_affinity || |
47 | irq_balancing_disabled(irq)) | 47 | irq_balancing_disabled(irq)) |
48 | return -EIO; | 48 | return -EIO; |
49 | 49 | ||
@@ -132,20 +132,20 @@ static const struct file_operations default_affinity_proc_fops = { | |||
132 | static int irq_spurious_read(char *page, char **start, off_t off, | 132 | static int irq_spurious_read(char *page, char **start, off_t off, |
133 | int count, int *eof, void *data) | 133 | int count, int *eof, void *data) |
134 | { | 134 | { |
135 | struct irq_desc *d = &irq_desc[(long) data]; | 135 | struct irq_desc *desc = irq_to_desc((long) data); |
136 | return sprintf(page, "count %u\n" | 136 | return sprintf(page, "count %u\n" |
137 | "unhandled %u\n" | 137 | "unhandled %u\n" |
138 | "last_unhandled %u ms\n", | 138 | "last_unhandled %u ms\n", |
139 | d->irq_count, | 139 | desc->irq_count, |
140 | d->irqs_unhandled, | 140 | desc->irqs_unhandled, |
141 | jiffies_to_msecs(d->last_unhandled)); | 141 | jiffies_to_msecs(desc->last_unhandled)); |
142 | } | 142 | } |
143 | 143 | ||
144 | #define MAX_NAMELEN 128 | 144 | #define MAX_NAMELEN 128 |
145 | 145 | ||
146 | static int name_unique(unsigned int irq, struct irqaction *new_action) | 146 | static int name_unique(unsigned int irq, struct irqaction *new_action) |
147 | { | 147 | { |
148 | struct irq_desc *desc = irq_desc + irq; | 148 | struct irq_desc *desc = irq_to_desc(irq); |
149 | struct irqaction *action; | 149 | struct irqaction *action; |
150 | unsigned long flags; | 150 | unsigned long flags; |
151 | int ret = 1; | 151 | int ret = 1; |
@@ -165,8 +165,9 @@ static int name_unique(unsigned int irq, struct irqaction *new_action) | |||
165 | void register_handler_proc(unsigned int irq, struct irqaction *action) | 165 | void register_handler_proc(unsigned int irq, struct irqaction *action) |
166 | { | 166 | { |
167 | char name [MAX_NAMELEN]; | 167 | char name [MAX_NAMELEN]; |
168 | struct irq_desc *desc = irq_to_desc(irq); | ||
168 | 169 | ||
169 | if (!irq_desc[irq].dir || action->dir || !action->name || | 170 | if (!desc->dir || action->dir || !action->name || |
170 | !name_unique(irq, action)) | 171 | !name_unique(irq, action)) |
171 | return; | 172 | return; |
172 | 173 | ||
@@ -174,7 +175,7 @@ void register_handler_proc(unsigned int irq, struct irqaction *action) | |||
174 | snprintf(name, MAX_NAMELEN, "%s", action->name); | 175 | snprintf(name, MAX_NAMELEN, "%s", action->name); |
175 | 176 | ||
176 | /* create /proc/irq/1234/handler/ */ | 177 | /* create /proc/irq/1234/handler/ */ |
177 | action->dir = proc_mkdir(name, irq_desc[irq].dir); | 178 | action->dir = proc_mkdir(name, desc->dir); |
178 | } | 179 | } |
179 | 180 | ||
180 | #undef MAX_NAMELEN | 181 | #undef MAX_NAMELEN |
@@ -185,25 +186,24 @@ void register_irq_proc(unsigned int irq) | |||
185 | { | 186 | { |
186 | char name [MAX_NAMELEN]; | 187 | char name [MAX_NAMELEN]; |
187 | struct proc_dir_entry *entry; | 188 | struct proc_dir_entry *entry; |
189 | struct irq_desc *desc = irq_to_desc(irq); | ||
188 | 190 | ||
189 | if (!root_irq_dir || | 191 | if (!root_irq_dir || (desc->chip == &no_irq_chip) || desc->dir) |
190 | (irq_desc[irq].chip == &no_irq_chip) || | ||
191 | irq_desc[irq].dir) | ||
192 | return; | 192 | return; |
193 | 193 | ||
194 | memset(name, 0, MAX_NAMELEN); | 194 | memset(name, 0, MAX_NAMELEN); |
195 | sprintf(name, "%d", irq); | 195 | sprintf(name, "%d", irq); |
196 | 196 | ||
197 | /* create /proc/irq/1234 */ | 197 | /* create /proc/irq/1234 */ |
198 | irq_desc[irq].dir = proc_mkdir(name, root_irq_dir); | 198 | desc->dir = proc_mkdir(name, root_irq_dir); |
199 | 199 | ||
200 | #ifdef CONFIG_SMP | 200 | #ifdef CONFIG_SMP |
201 | /* create /proc/irq/<irq>/smp_affinity */ | 201 | /* create /proc/irq/<irq>/smp_affinity */ |
202 | proc_create_data("smp_affinity", 0600, irq_desc[irq].dir, | 202 | proc_create_data("smp_affinity", 0600, desc->dir, |
203 | &irq_affinity_proc_fops, (void *)(long)irq); | 203 | &irq_affinity_proc_fops, (void *)(long)irq); |
204 | #endif | 204 | #endif |
205 | 205 | ||
206 | entry = create_proc_entry("spurious", 0444, irq_desc[irq].dir); | 206 | entry = create_proc_entry("spurious", 0444, desc->dir); |
207 | if (entry) { | 207 | if (entry) { |
208 | entry->data = (void *)(long)irq; | 208 | entry->data = (void *)(long)irq; |
209 | entry->read_proc = irq_spurious_read; | 209 | entry->read_proc = irq_spurious_read; |
@@ -214,8 +214,10 @@ void register_irq_proc(unsigned int irq) | |||
214 | 214 | ||
215 | void unregister_handler_proc(unsigned int irq, struct irqaction *action) | 215 | void unregister_handler_proc(unsigned int irq, struct irqaction *action) |
216 | { | 216 | { |
217 | if (action->dir) | 217 | if (action->dir) { |
218 | remove_proc_entry(action->dir->name, irq_desc[irq].dir); | 218 | struct irq_desc *desc = irq_to_desc(irq); |
219 | remove_proc_entry(action->dir->name, desc->dir); | ||
220 | } | ||
219 | } | 221 | } |
220 | 222 | ||
221 | void register_default_affinity_proc(void) | 223 | void register_default_affinity_proc(void) |
diff --git a/kernel/irq/resend.c b/kernel/irq/resend.c index cba8aa5bc7f4..89c7117acf2b 100644 --- a/kernel/irq/resend.c +++ b/kernel/irq/resend.c | |||
@@ -36,7 +36,7 @@ static void resend_irqs(unsigned long arg) | |||
36 | while (!bitmap_empty(irqs_resend, nr_irqs)) { | 36 | while (!bitmap_empty(irqs_resend, nr_irqs)) { |
37 | irq = find_first_bit(irqs_resend, nr_irqs); | 37 | irq = find_first_bit(irqs_resend, nr_irqs); |
38 | clear_bit(irq, irqs_resend); | 38 | clear_bit(irq, irqs_resend); |
39 | desc = irq_desc + irq; | 39 | desc = irq_to_desc(irq); |
40 | local_irq_disable(); | 40 | local_irq_disable(); |
41 | desc->handle_irq(irq, desc); | 41 | desc->handle_irq(irq, desc); |
42 | local_irq_enable(); | 42 | local_irq_enable(); |
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c index e26ca1e90c08..b5d906002e1d 100644 --- a/kernel/irq/spurious.c +++ b/kernel/irq/spurious.c | |||
@@ -92,11 +92,12 @@ static int misrouted_irq(int irq) | |||
92 | int ok = 0; | 92 | int ok = 0; |
93 | 93 | ||
94 | for (i = 1; i < nr_irqs; i++) { | 94 | for (i = 1; i < nr_irqs; i++) { |
95 | struct irq_desc *desc = irq_desc + i; | 95 | struct irq_desc *desc; |
96 | 96 | ||
97 | if (i == irq) /* Already tried */ | 97 | if (i == irq) /* Already tried */ |
98 | continue; | 98 | continue; |
99 | 99 | ||
100 | desc = irq_to_desc(i); | ||
100 | if (try_one_irq(i, desc)) | 101 | if (try_one_irq(i, desc)) |
101 | ok = 1; | 102 | ok = 1; |
102 | } | 103 | } |
@@ -108,7 +109,7 @@ static void poll_spurious_irqs(unsigned long dummy) | |||
108 | { | 109 | { |
109 | int i; | 110 | int i; |
110 | for (i = 1; i < nr_irqs; i++) { | 111 | for (i = 1; i < nr_irqs; i++) { |
111 | struct irq_desc *desc = irq_desc + i; | 112 | struct irq_desc *desc = irq_to_desc(i); |
112 | unsigned int status; | 113 | unsigned int status; |
113 | 114 | ||
114 | /* Racy but it doesn't matter */ | 115 | /* Racy but it doesn't matter */ |