aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorYinghai Lu <yhlu.kernel@gmail.com>2008-08-19 23:50:19 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-16 10:52:51 -0400
commita2f9f43858db64cb8b45c4f6746d7a52b80d4dcb (patch)
treee7b17e452e9dfbeac7815282b3a202d9d428694c /arch
parent67fb283e148e9bd761f73691d3173b6eab9ba8db (diff)
x86_64: separate irq_cfgx from irq_cfgx_free
so later don't need to compare with -1U Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/io_apic_64.c92
1 files changed, 59 insertions, 33 deletions
diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c
index a054db9ef19..8ab7ae01773 100644
--- a/arch/x86/kernel/io_apic_64.c
+++ b/arch/x86/kernel/io_apic_64.c
@@ -111,44 +111,44 @@ static void init_one_irq_cfg(struct irq_cfg *cfg)
111 memcpy(cfg, &irq_cfg_init, sizeof(struct irq_cfg)); 111 memcpy(cfg, &irq_cfg_init, sizeof(struct irq_cfg));
112} 112}
113 113
114static struct irq_cfg *irq_cfgx;
115static struct irq_cfg *irq_cfgx_free;
114static void __init init_work(void *data) 116static void __init init_work(void *data)
115{ 117{
116 struct dyn_array *da = data; 118 struct dyn_array *da = data;
117 struct irq_cfg *cfg; 119 struct irq_cfg *cfg;
120 int legacy_count;
118 int i; 121 int i;
119 122
120 cfg = *da->name; 123 cfg = *da->name;
121 124
122 memcpy(cfg, irq_cfg_legacy, sizeof(irq_cfg_legacy)); 125 memcpy(cfg, irq_cfg_legacy, sizeof(irq_cfg_legacy));
123 126
124 i = sizeof(irq_cfg_legacy)/sizeof(irq_cfg_legacy[0]); 127 legacy_count = sizeof(irq_cfg_legacy)/sizeof(irq_cfg_legacy[0]);
125 for (; i < *da->nr; i++) 128 for (i = legacy_count; i < *da->nr; i++)
126 init_one_irq_cfg(&cfg[i]); 129 init_one_irq_cfg(&cfg[i]);
127 130
128 for (i = 1; i < *da->nr; i++) 131 for (i = 1; i < *da->nr; i++)
129 cfg[i-1].next = &cfg[i]; 132 cfg[i-1].next = &cfg[i];
133
134 irq_cfgx_free = &irq_cfgx[legacy_count];
135 irq_cfgx[legacy_count - 1].next = NULL;
130} 136}
131 137
132#define for_each_irq_cfg(cfg) \ 138#define for_each_irq_cfg(cfg) \
133 for (cfg = irq_cfgx; cfg && cfg->irq != -1U; cfg = cfg->next) 139 for (cfg = irq_cfgx; cfg; cfg = cfg->next)
134 140
135static struct irq_cfg *irq_cfgx;
136DEFINE_DYN_ARRAY(irq_cfgx, sizeof(struct irq_cfg), nr_irq_cfg, PAGE_SIZE, init_work); 141DEFINE_DYN_ARRAY(irq_cfgx, sizeof(struct irq_cfg), nr_irq_cfg, PAGE_SIZE, init_work);
137 142
138static struct irq_cfg *irq_cfg(unsigned int irq) 143static struct irq_cfg *irq_cfg(unsigned int irq)
139{ 144{
140 struct irq_cfg *cfg; 145 struct irq_cfg *cfg;
141 146
142 BUG_ON(irq == -1U); 147 cfg = irq_cfgx;
143
144 cfg = &irq_cfgx[0];
145 while (cfg) { 148 while (cfg) {
146 if (cfg->irq == irq) 149 if (cfg->irq == irq)
147 return cfg; 150 return cfg;
148 151
149 if (cfg->irq == -1U)
150 return NULL;
151
152 cfg = cfg->next; 152 cfg = cfg->next;
153 } 153 }
154 154
@@ -161,44 +161,70 @@ static struct irq_cfg *irq_cfg_alloc(unsigned int irq)
161 int i; 161 int i;
162 int count = 0; 162 int count = 0;
163 163
164 BUG_ON(irq == -1U); 164 cfg_pri = cfg = irq_cfgx;
165
166 cfg_pri = cfg = &irq_cfgx[0];
167 while (cfg) { 165 while (cfg) {
168 if (cfg->irq == irq) 166 if (cfg->irq == irq)
169 return cfg; 167 return cfg;
170 168
171 if (cfg->irq == -1U) {
172 cfg->irq = irq;
173 return cfg;
174 }
175 cfg_pri = cfg; 169 cfg_pri = cfg;
176 cfg = cfg->next; 170 cfg = cfg->next;
177 count++; 171 count++;
178 } 172 }
179 173
180 /* 174 if (!irq_cfgx_free) {
181 * we run out of pre-allocate ones, allocate more 175 unsigned long phys;
182 */ 176 unsigned long total_bytes;
183 printk(KERN_DEBUG "try to get more irq_cfg %d\n", nr_irq_cfg); 177 /*
178 * we run out of pre-allocate ones, allocate more
179 */
180 printk(KERN_DEBUG "try to get more irq_cfg %d\n", nr_irq_cfg);
184 181
185 if (after_bootmem) 182 total_bytes = sizeof(struct irq_cfg) * nr_irq_cfg;
186 cfg = kzalloc(sizeof(struct irq_cfg)*nr_irq_cfg, GFP_ATOMIC); 183 if (after_bootmem)
187 else 184 cfg = kzalloc(total_bytes, GFP_ATOMIC);
188 cfg = __alloc_bootmem_nopanic(sizeof(struct irq_cfg)*nr_irq_cfg, PAGE_SIZE, 0); 185 else
186 cfg = __alloc_bootmem_nopanic(total_bytes, PAGE_SIZE, 0);
189 187
190 if (!cfg) 188 if (!cfg)
191 panic("please boot with nr_irq_cfg= %d\n", count * 2); 189 panic("please boot with nr_irq_cfg= %d\n", count * 2);
192 190
193 for (i = 0; i < nr_irq_cfg; i++) 191 phys = __pa(cfg);
194 init_one_irq_cfg(&cfg[i]); 192 printk(KERN_DEBUG "irq_irq ==> [%#lx - %#lx]\n", phys, phys + total_bytes);
195 193
196 for (i = 1; i < nr_irq_cfg; i++) 194 for (i = 0; i < nr_irq_cfg; i++)
197 cfg[i-1].next = &cfg[i]; 195 init_one_irq_cfg(&cfg[i]);
198 196
199 cfg->irq = irq; 197 for (i = 1; i < nr_irq_cfg; i++)
200 cfg_pri->next = cfg; 198 cfg[i-1].next = &cfg[i];
199
200 irq_cfgx_free = cfg;
201 }
201 202
203 cfg = irq_cfgx_free;
204 irq_cfgx_free = irq_cfgx_free->next;
205 cfg->next = NULL;
206 if (cfg_pri)
207 cfg_pri->next = cfg;
208 else
209 irq_cfgx = cfg;
210 cfg->irq = irq;
211 printk(KERN_DEBUG "found new irq_cfg for irq %d\n", cfg->irq);
212#ifdef CONFIG_HAVE_SPARSE_IRQ_DEBUG
213 {
214 /* dump the results */
215 struct irq_cfg *cfg;
216 unsigned long phys;
217 unsigned long bytes = sizeof(struct irq_cfg);
218
219 printk(KERN_DEBUG "=========================== %d\n", irq);
220 printk(KERN_DEBUG "irq_cfg dump after get that for %d\n", irq);
221 for_each_irq_cfg(cfg) {
222 phys = __pa(cfg);
223 printk(KERN_DEBUG "irq_cfg %d ==> [%#lx - %#lx]\n", cfg->irq, phys, phys + bytes);
224 }
225 printk(KERN_DEBUG "===========================\n");
226 }
227#endif
202 return cfg; 228 return cfg;
203} 229}
204 230