aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYinghai Lu <yhlu.kernel@gmail.com>2008-08-19 23:50:05 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-16 10:52:29 -0400
commit08678b0841267c1d00d771fe01548d86043d065e (patch)
tree7debb21f9e9a768ced43077f7376797a0c46f8c0
parentbfea1238beac9d306eeac081c67de5ca6aec4c7a (diff)
generic: sparse irqs: use irq_desc() together with dyn_array, instead of irq_desc[]
add CONFIG_HAVE_SPARSE_IRQ to for use condensed array. Get rid of irq_desc[] array assumptions. Preallocate 32 irq_desc, and irq_desc() will try to get more. ( No change in functionality is expected anywhere, except the odd build failure where we missed a code site or where a crossing commit itroduces new irq_desc[] usage. ) v2: according to Eric, change get_irq_desc() to irq_desc() Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--arch/Kconfig4
-rw-r--r--arch/x86/Kconfig1
-rw-r--r--arch/x86/kernel/io_apic_32.c46
-rw-r--r--arch/x86/kernel/io_apic_64.c75
-rw-r--r--arch/x86/kernel/irq_32.c24
-rw-r--r--arch/x86/kernel/irq_64.c35
-rw-r--r--arch/x86/kernel/irqinit_64.c10
-rw-r--r--arch/x86/kernel/visws_quirks.c30
-rw-r--r--arch/x86/mach-voyager/voyager_smp.c4
-rw-r--r--drivers/gpio/gpiolib.c2
-rw-r--r--drivers/mfd/asic3.c4
-rw-r--r--drivers/mfd/htc-egpio.c2
-rw-r--r--drivers/parisc/dino.c6
-rw-r--r--drivers/parisc/eisa.c4
-rw-r--r--drivers/parisc/gsc.c12
-rw-r--r--drivers/parisc/iosapic.c4
-rw-r--r--drivers/parisc/superio.c4
-rw-r--r--drivers/pcmcia/hd64465_ss.c12
-rw-r--r--drivers/xen/events.c8
-rw-r--r--include/linux/irq.h32
-rw-r--r--kernel/irq/autoprobe.c10
-rw-r--r--kernel/irq/chip.c32
-rw-r--r--kernel/irq/handle.c138
-rw-r--r--kernel/irq/manage.c35
-rw-r--r--kernel/irq/migration.c14
-rw-r--r--kernel/irq/proc.c36
-rw-r--r--kernel/irq/resend.c2
-rw-r--r--kernel/irq/spurious.c5
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
106config HAVE_DYN_ARRAY 106config HAVE_DYN_ARRAY
107 def_bool n 107 def_bool n
108
109config 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
38config ARCH_DEFCONFIG 39config 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)
475static inline void rotate_irqs_among_cpus(unsigned long useful_load_threshold) 477static 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
1255static void ioapic_register_intr(int irq, int vector, unsigned long trigger) 1264static 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 = {
2027static inline void init_IO_APIC_traps(void) 2039static 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
2090static void lapic_register_intr(int irq, int vector) 2105static 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
934static void ioapic_register_intr(int irq, unsigned long trigger) 936static 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);
1596static void migrate_ioapic_irq(int irq, cpumask_t mask) 1601static 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
1643static int migrate_irq_remapped_level(int irq) 1650static 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
1667unmask: 1675unmask:
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 */
1699static void set_ir_ioapic_affinity_irq(unsigned int irq, cpumask_t mask) 1706static 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 = {
1868static inline void init_IO_APIC_traps(void) 1877static 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
1927static void lapic_register_intr(int irq) 1939static 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');
304skip: 305skip:
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');
113skip: 114skip:
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)
484static unsigned int startup_cobalt_irq(unsigned int irq) 484static 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)
506static void end_cobalt_irq(unsigned int irq) 507static 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 */
1484static void before_handle_vic_irq(unsigned int irq) 1484static 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 */
1519static void after_handle_vic_irq(unsigned int irq) 1519static 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
299static void dino_disable_irq(unsigned int irq) 299static 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
311static void dino_enable_irq(unsigned int irq) 312static 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
109static void gsc_asic_disable_irq(unsigned int irq) 109static 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
124static void gsc_asic_enable_irq(unsigned int irq) 125static 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 = {
159int gsc_assign_irq(struct hw_interrupt_type *type, void *data) 161int 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
620static struct vector_info *iosapic_get_vector(unsigned int irq) 620static 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
625static void iosapic_disable_irq(unsigned int irq) 627static 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 */
234static void hs_map_irq(hs_socket_t *sp, unsigned int irq) 234static 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 */
251static void hs_unmap_irq(hs_socket_t *sp, unsigned int irq) 254static 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 */
154struct irq_desc { 154struct 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 186extern struct irq_desc *irq_to_desc(unsigned int irq);
183extern 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 */
185extern struct irq_desc irq_desc[NR_IRQS]; 189extern struct irq_desc irq_desc[NR_IRQS];
186#endif 190#endif
187 191
@@ -249,7 +253,10 @@ extern int no_irq_affinity;
249 253
250static inline int irq_balancing_disabled(unsigned int irq) 254static 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 */
282static inline void generic_handle_irq(unsigned int irq) 289static 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,
325static inline void __set_irq_handler_unlocked(int irq, 332static 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 */
360static inline int irq_has_action(unsigned int irq) 370static 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);
374extern int set_irq_type(unsigned int irq, unsigned int type); 384extern int set_irq_type(unsigned int irq, unsigned int type);
375extern int set_irq_msi(unsigned int irq, struct msi_desc *entry); 385extern 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 */
199int set_irq_chip_data(unsigned int irq, void *data) 199int 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 */
220static void default_enable(unsigned int irq) 221static 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 */
238static unsigned int default_startup(unsigned int irq) 240static 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 */
248static void default_shutdown(unsigned int irq) 253static 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 */
26static 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;
51EXPORT_SYMBOL_GPL(nr_irqs); 59EXPORT_SYMBOL_GPL(nr_irqs);
52 60
53#ifdef CONFIG_HAVE_DYN_ARRAY 61#ifdef CONFIG_HAVE_DYN_ARRAY
54static struct irq_desc irq_desc_init __initdata = { 62static 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
75static 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
84static int nr_irq_desc = 32;
85
86static 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
93early_param("nr_irq_desc", parse_nr_irq_desc);
94
65static void __init init_work(void *data) 95static 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
77struct irq_desc *irq_desc; 110static struct irq_desc *sparse_irqs;
111DEFINE_DYN_ARRAY(sparse_irqs, sizeof(struct irq_desc), nr_irq_desc, PAGE_SIZE, init_work);
112
113extern int after_bootmem;
114extern void *__alloc_bootmem_nopanic(unsigned long size,
115 unsigned long align,
116 unsigned long goal);
117struct 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
164static 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}
176static struct irq_desc *irq_desc;
78DEFINE_DYN_ARRAY(irq_desc, sizeof(struct irq_desc), nr_irqs, PAGE_SIZE, init_work); 177DEFINE_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
82struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = { 183struct 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
199struct 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 */
100static void ack_bad(unsigned int irq) 212static 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 */
197unsigned int __do_IRQ(unsigned int irq) 312unsigned 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 */
295static struct lock_class_key irq_desc_lock_class;
296 405
406#ifdef CONFIG_TRACE_IRQFLAGS
297void early_init_irq_lock_class(void) 407void 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 */
32void synchronize_irq(unsigned int irq) 32void 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 */
65int irq_can_set_affinity(unsigned int irq) 65int 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 */
82int irq_set_affinity(unsigned int irq, cpumask_t cpumask) 82int 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)
111int irq_select_affinity(unsigned int irq) 111int 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 */
141void disable_irq_nosync(unsigned int irq) 143void 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 */
170void disable_irq(unsigned int irq) 172void 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 */
212void enable_irq(unsigned int irq) 214void 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
226static int set_irq_wake_real(unsigned int irq, unsigned int on) 228static 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 */
249int set_irq_wake(unsigned int irq, unsigned int on) 251int 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 */
289int can_request_irq(unsigned int irq, unsigned long irqflags) 291int 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 */
350int setup_irq(unsigned int irq, struct irqaction *new) 353int 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
4void set_pending_irq(unsigned int irq, cpumask_t mask) 4void 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
15void move_masked_irq(int irq) 15void 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
61void move_native_irq(int irq) 61void 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
20static int irq_affinity_proc_show(struct seq_file *m, void *v) 20static 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 = {
132static int irq_spurious_read(char *page, char **start, off_t off, 132static 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
146static int name_unique(unsigned int irq, struct irqaction *new_action) 146static 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)
165void register_handler_proc(unsigned int irq, struct irqaction *action) 165void 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
215void unregister_handler_proc(unsigned int irq, struct irqaction *action) 215void 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
221void register_default_affinity_proc(void) 223void 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 */