aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/irq/handle.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/irq/handle.c')
-rw-r--r--kernel/irq/handle.c57
1 files changed, 35 insertions, 22 deletions
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index c20db0be9173..375d68cd5bf0 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -17,6 +17,7 @@
17#include <linux/kernel_stat.h> 17#include <linux/kernel_stat.h>
18#include <linux/rculist.h> 18#include <linux/rculist.h>
19#include <linux/hash.h> 19#include <linux/hash.h>
20#include <linux/bootmem.h>
20 21
21#include "internals.h" 22#include "internals.h"
22 23
@@ -57,6 +58,7 @@ int nr_irqs = NR_IRQS;
57EXPORT_SYMBOL_GPL(nr_irqs); 58EXPORT_SYMBOL_GPL(nr_irqs);
58 59
59#ifdef CONFIG_SPARSE_IRQ 60#ifdef CONFIG_SPARSE_IRQ
61
60static struct irq_desc irq_desc_init = { 62static struct irq_desc irq_desc_init = {
61 .irq = -1, 63 .irq = -1,
62 .status = IRQ_DISABLED, 64 .status = IRQ_DISABLED,
@@ -64,9 +66,6 @@ static struct irq_desc irq_desc_init = {
64 .handle_irq = handle_bad_irq, 66 .handle_irq = handle_bad_irq,
65 .depth = 1, 67 .depth = 1,
66 .lock = __SPIN_LOCK_UNLOCKED(irq_desc_init.lock), 68 .lock = __SPIN_LOCK_UNLOCKED(irq_desc_init.lock),
67#ifdef CONFIG_SMP
68 .affinity = CPU_MASK_ALL
69#endif
70}; 69};
71 70
72void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr) 71void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr)
@@ -101,6 +100,10 @@ static void init_one_irq_desc(int irq, struct irq_desc *desc, int cpu)
101 printk(KERN_ERR "can not alloc kstat_irqs\n"); 100 printk(KERN_ERR "can not alloc kstat_irqs\n");
102 BUG_ON(1); 101 BUG_ON(1);
103 } 102 }
103 if (!init_alloc_desc_masks(desc, cpu, false)) {
104 printk(KERN_ERR "can not alloc irq_desc cpumasks\n");
105 BUG_ON(1);
106 }
104 arch_init_chip_data(desc, cpu); 107 arch_init_chip_data(desc, cpu);
105} 108}
106 109
@@ -109,7 +112,7 @@ static void init_one_irq_desc(int irq, struct irq_desc *desc, int cpu)
109 */ 112 */
110DEFINE_SPINLOCK(sparse_irq_lock); 113DEFINE_SPINLOCK(sparse_irq_lock);
111 114
112struct irq_desc *irq_desc_ptrs[NR_IRQS] __read_mostly; 115struct irq_desc **irq_desc_ptrs __read_mostly;
113 116
114static struct irq_desc irq_desc_legacy[NR_IRQS_LEGACY] __cacheline_aligned_in_smp = { 117static struct irq_desc irq_desc_legacy[NR_IRQS_LEGACY] __cacheline_aligned_in_smp = {
115 [0 ... NR_IRQS_LEGACY-1] = { 118 [0 ... NR_IRQS_LEGACY-1] = {
@@ -119,14 +122,10 @@ static struct irq_desc irq_desc_legacy[NR_IRQS_LEGACY] __cacheline_aligned_in_sm
119 .handle_irq = handle_bad_irq, 122 .handle_irq = handle_bad_irq,
120 .depth = 1, 123 .depth = 1,
121 .lock = __SPIN_LOCK_UNLOCKED(irq_desc_init.lock), 124 .lock = __SPIN_LOCK_UNLOCKED(irq_desc_init.lock),
122#ifdef CONFIG_SMP
123 .affinity = CPU_MASK_ALL
124#endif
125 } 125 }
126}; 126};
127 127
128/* FIXME: use bootmem alloc ...*/ 128static unsigned int *kstat_irqs_legacy;
129static unsigned int kstat_irqs_legacy[NR_IRQS_LEGACY][NR_CPUS];
130 129
131int __init early_irq_init(void) 130int __init early_irq_init(void)
132{ 131{
@@ -134,18 +133,30 @@ int __init early_irq_init(void)
134 int legacy_count; 133 int legacy_count;
135 int i; 134 int i;
136 135
136 /* initialize nr_irqs based on nr_cpu_ids */
137 arch_probe_nr_irqs();
138 printk(KERN_INFO "NR_IRQS:%d nr_irqs:%d\n", NR_IRQS, nr_irqs);
139
137 desc = irq_desc_legacy; 140 desc = irq_desc_legacy;
138 legacy_count = ARRAY_SIZE(irq_desc_legacy); 141 legacy_count = ARRAY_SIZE(irq_desc_legacy);
139 142
143 /* allocate irq_desc_ptrs array based on nr_irqs */
144 irq_desc_ptrs = alloc_bootmem(nr_irqs * sizeof(void *));
145
146 /* allocate based on nr_cpu_ids */
147 /* FIXME: invert kstat_irgs, and it'd be a per_cpu_alloc'd thing */
148 kstat_irqs_legacy = alloc_bootmem(NR_IRQS_LEGACY * nr_cpu_ids *
149 sizeof(int));
150
140 for (i = 0; i < legacy_count; i++) { 151 for (i = 0; i < legacy_count; i++) {
141 desc[i].irq = i; 152 desc[i].irq = i;
142 desc[i].kstat_irqs = kstat_irqs_legacy[i]; 153 desc[i].kstat_irqs = kstat_irqs_legacy + i * nr_cpu_ids;
143 lockdep_set_class(&desc[i].lock, &irq_desc_lock_class); 154 lockdep_set_class(&desc[i].lock, &irq_desc_lock_class);
144 155 init_alloc_desc_masks(&desc[i], 0, true);
145 irq_desc_ptrs[i] = desc + i; 156 irq_desc_ptrs[i] = desc + i;
146 } 157 }
147 158
148 for (i = legacy_count; i < NR_IRQS; i++) 159 for (i = legacy_count; i < nr_irqs; i++)
149 irq_desc_ptrs[i] = NULL; 160 irq_desc_ptrs[i] = NULL;
150 161
151 return arch_early_irq_init(); 162 return arch_early_irq_init();
@@ -153,7 +164,10 @@ int __init early_irq_init(void)
153 164
154struct irq_desc *irq_to_desc(unsigned int irq) 165struct irq_desc *irq_to_desc(unsigned int irq)
155{ 166{
156 return (irq < NR_IRQS) ? irq_desc_ptrs[irq] : NULL; 167 if (irq_desc_ptrs && irq < nr_irqs)
168 return irq_desc_ptrs[irq];
169
170 return NULL;
157} 171}
158 172
159struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu) 173struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu)
@@ -162,10 +176,9 @@ struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu)
162 unsigned long flags; 176 unsigned long flags;
163 int node; 177 int node;
164 178
165 if (irq >= NR_IRQS) { 179 if (irq >= nr_irqs) {
166 printk(KERN_WARNING "irq >= NR_IRQS in irq_to_desc_alloc: %d %d\n", 180 WARN(1, "irq (%d) >= nr_irqs (%d) in irq_to_desc_alloc\n",
167 irq, NR_IRQS); 181 irq, nr_irqs);
168 WARN_ON(1);
169 return NULL; 182 return NULL;
170 } 183 }
171 184
@@ -207,9 +220,6 @@ struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
207 .handle_irq = handle_bad_irq, 220 .handle_irq = handle_bad_irq,
208 .depth = 1, 221 .depth = 1,
209 .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock), 222 .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
210#ifdef CONFIG_SMP
211 .affinity = CPU_MASK_ALL
212#endif
213 } 223 }
214}; 224};
215 225
@@ -219,12 +229,15 @@ int __init early_irq_init(void)
219 int count; 229 int count;
220 int i; 230 int i;
221 231
232 printk(KERN_INFO "NR_IRQS:%d\n", NR_IRQS);
233
222 desc = irq_desc; 234 desc = irq_desc;
223 count = ARRAY_SIZE(irq_desc); 235 count = ARRAY_SIZE(irq_desc);
224 236
225 for (i = 0; i < count; i++) 237 for (i = 0; i < count; i++) {
226 desc[i].irq = i; 238 desc[i].irq = i;
227 239 init_alloc_desc_masks(&desc[i], 0, true);
240 }
228 return arch_early_irq_init(); 241 return arch_early_irq_init();
229} 242}
230 243