aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64
diff options
context:
space:
mode:
authorYasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>2007-07-17 08:22:03 -0400
committerTony Luck <tony.luck@intel.com>2007-07-17 12:51:00 -0400
commit4bbdec7a84ca8ce786c44bc338a37d97a13cbf20 (patch)
treef259b119cad33e54e6f924108e9bb86b5268dfab /arch/ia64
parenteb21ab24955ee025434ad09cd8e5e1a74c798777 (diff)
[IA64] Fix invalid irq vector assumption for iosapic
Many of IOSAPIC codes depends on the flollowing assumptions, but these would become invalid when multiple vector domain will be supported in the future. - 1:1 mapping between IRQ and vector - IRQ == vector To fix those invalid assumptions, this patch changes iosapic_intr_info[] to be indexed by irq number instead of vector. Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> Signed-off-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64')
-rw-r--r--arch/ia64/kernel/iosapic.c258
1 files changed, 122 insertions, 136 deletions
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index 4c531953e2e1..bcf91dceaf5d 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -147,7 +147,7 @@ static struct iosapic_intr_info {
147 unsigned char polarity: 1; /* interrupt polarity 147 unsigned char polarity: 1; /* interrupt polarity
148 * (see iosapic.h) */ 148 * (see iosapic.h) */
149 unsigned char trigger : 1; /* trigger mode (see iosapic.h) */ 149 unsigned char trigger : 1; /* trigger mode (see iosapic.h) */
150} iosapic_intr_info[IA64_NUM_VECTORS]; 150} iosapic_intr_info[NR_IRQS];
151 151
152static unsigned char pcat_compat __devinitdata; /* 8259 compatibility flag */ 152static unsigned char pcat_compat __devinitdata; /* 8259 compatibility flag */
153 153
@@ -181,17 +181,18 @@ find_iosapic (unsigned int gsi)
181 return -1; 181 return -1;
182} 182}
183 183
184static inline int 184static inline int __gsi_to_irq(unsigned int gsi)
185_gsi_to_vector (unsigned int gsi)
186{ 185{
186 int irq;
187 struct iosapic_intr_info *info; 187 struct iosapic_intr_info *info;
188 struct iosapic_rte_info *rte; 188 struct iosapic_rte_info *rte;
189 189
190 for (info = iosapic_intr_info; info < 190 for (irq = 0; irq < NR_IRQS; irq++) {
191 iosapic_intr_info + IA64_NUM_VECTORS; ++info) 191 info = &iosapic_intr_info[irq];
192 list_for_each_entry(rte, &info->rtes, rte_list) 192 list_for_each_entry(rte, &info->rtes, rte_list)
193 if (rte->iosapic->gsi_base + rte->rte_index == gsi) 193 if (rte->iosapic->gsi_base + rte->rte_index == gsi)
194 return info - iosapic_intr_info; 194 return irq;
195 }
195 return -1; 196 return -1;
196} 197}
197 198
@@ -202,7 +203,10 @@ _gsi_to_vector (unsigned int gsi)
202inline int 203inline int
203gsi_to_vector (unsigned int gsi) 204gsi_to_vector (unsigned int gsi)
204{ 205{
205 return _gsi_to_vector(gsi); 206 int irq = __gsi_to_irq(gsi);
207 if (irq < 0)
208 return -1;
209 return irq_to_vector(irq);
206} 210}
207 211
208int 212int
@@ -210,62 +214,48 @@ gsi_to_irq (unsigned int gsi)
210{ 214{
211 unsigned long flags; 215 unsigned long flags;
212 int irq; 216 int irq;
213 /* 217
214 * XXX fix me: this assumes an identity mapping between IA-64 vector
215 * and Linux irq numbers...
216 */
217 spin_lock_irqsave(&iosapic_lock, flags); 218 spin_lock_irqsave(&iosapic_lock, flags);
218 irq = _gsi_to_vector(gsi); 219 irq = __gsi_to_irq(gsi);
219 spin_unlock_irqrestore(&iosapic_lock, flags); 220 spin_unlock_irqrestore(&iosapic_lock, flags);
220
221 return irq; 221 return irq;
222} 222}
223 223
224static struct iosapic_rte_info *gsi_vector_to_rte(unsigned int gsi, 224static struct iosapic_rte_info *find_rte(unsigned int irq, unsigned int gsi)
225 unsigned int vec)
226{ 225{
227 struct iosapic_rte_info *rte; 226 struct iosapic_rte_info *rte;
228 227
229 list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) 228 list_for_each_entry(rte, &iosapic_intr_info[irq].rtes, rte_list)
230 if (rte->iosapic->gsi_base + rte->rte_index == gsi) 229 if (rte->iosapic->gsi_base + rte->rte_index == gsi)
231 return rte; 230 return rte;
232 return NULL; 231 return NULL;
233} 232}
234 233
235static void 234static void
236set_rte (unsigned int gsi, unsigned int vector, unsigned int dest, int mask) 235set_rte (unsigned int gsi, unsigned int irq, unsigned int dest, int mask)
237{ 236{
238 unsigned long pol, trigger, dmode; 237 unsigned long pol, trigger, dmode;
239 u32 low32, high32; 238 u32 low32, high32;
240 int rte_index; 239 int rte_index;
241 char redir; 240 char redir;
242 struct iosapic_rte_info *rte; 241 struct iosapic_rte_info *rte;
242 ia64_vector vector = irq_to_vector(irq);
243 243
244 DBG(KERN_DEBUG"IOSAPIC: routing vector %d to 0x%x\n", vector, dest); 244 DBG(KERN_DEBUG"IOSAPIC: routing vector %d to 0x%x\n", vector, dest);
245 245
246 rte = gsi_vector_to_rte(gsi, vector); 246 rte = find_rte(irq, gsi);
247 if (!rte) 247 if (!rte)
248 return; /* not an IOSAPIC interrupt */ 248 return; /* not an IOSAPIC interrupt */
249 249
250 rte_index = rte->rte_index; 250 rte_index = rte->rte_index;
251 pol = iosapic_intr_info[vector].polarity; 251 pol = iosapic_intr_info[irq].polarity;
252 trigger = iosapic_intr_info[vector].trigger; 252 trigger = iosapic_intr_info[irq].trigger;
253 dmode = iosapic_intr_info[vector].dmode; 253 dmode = iosapic_intr_info[irq].dmode;
254 254
255 redir = (dmode == IOSAPIC_LOWEST_PRIORITY) ? 1 : 0; 255 redir = (dmode == IOSAPIC_LOWEST_PRIORITY) ? 1 : 0;
256 256
257#ifdef CONFIG_SMP 257#ifdef CONFIG_SMP
258 { 258 set_irq_affinity_info(irq, (int)(dest & 0xffff), redir);
259 unsigned int irq;
260
261 for (irq = 0; irq < NR_IRQS; ++irq)
262 if (irq_to_vector(irq) == vector) {
263 set_irq_affinity_info(irq,
264 (int)(dest & 0xffff),
265 redir);
266 break;
267 }
268 }
269#endif 259#endif
270 260
271 low32 = ((pol << IOSAPIC_POLARITY_SHIFT) | 261 low32 = ((pol << IOSAPIC_POLARITY_SHIFT) |
@@ -279,8 +269,8 @@ set_rte (unsigned int gsi, unsigned int vector, unsigned int dest, int mask)
279 269
280 iosapic_write(rte->iosapic, IOSAPIC_RTE_HIGH(rte_index), high32); 270 iosapic_write(rte->iosapic, IOSAPIC_RTE_HIGH(rte_index), high32);
281 iosapic_write(rte->iosapic, IOSAPIC_RTE_LOW(rte_index), low32); 271 iosapic_write(rte->iosapic, IOSAPIC_RTE_LOW(rte_index), low32);
282 iosapic_intr_info[vector].low32 = low32; 272 iosapic_intr_info[irq].low32 = low32;
283 iosapic_intr_info[vector].dest = dest; 273 iosapic_intr_info[irq].dest = dest;
284} 274}
285 275
286static void 276static void
@@ -296,9 +286,12 @@ kexec_disable_iosapic(void)
296{ 286{
297 struct iosapic_intr_info *info; 287 struct iosapic_intr_info *info;
298 struct iosapic_rte_info *rte; 288 struct iosapic_rte_info *rte;
299 u8 vec = 0; 289 ia64_vector vec;
300 for (info = iosapic_intr_info; info < 290 int irq;
301 iosapic_intr_info + IA64_NUM_VECTORS; ++info, ++vec) { 291
292 for (irq = 0; irq < NR_IRQS; irq++) {
293 info = &iosapic_intr_info[irq];
294 vec = irq_to_vector(irq);
302 list_for_each_entry(rte, &info->rtes, 295 list_for_each_entry(rte, &info->rtes,
303 rte_list) { 296 rte_list) {
304 iosapic_write(rte->iosapic, 297 iosapic_write(rte->iosapic,
@@ -315,15 +308,14 @@ mask_irq (unsigned int irq)
315{ 308{
316 u32 low32; 309 u32 low32;
317 int rte_index; 310 int rte_index;
318 ia64_vector vec = irq_to_vector(irq);
319 struct iosapic_rte_info *rte; 311 struct iosapic_rte_info *rte;
320 312
321 if (list_empty(&iosapic_intr_info[vec].rtes)) 313 if (list_empty(&iosapic_intr_info[irq].rtes))
322 return; /* not an IOSAPIC interrupt! */ 314 return; /* not an IOSAPIC interrupt! */
323 315
324 /* set only the mask bit */ 316 /* set only the mask bit */
325 low32 = iosapic_intr_info[vec].low32 |= IOSAPIC_MASK; 317 low32 = iosapic_intr_info[irq].low32 |= IOSAPIC_MASK;
326 list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) { 318 list_for_each_entry(rte, &iosapic_intr_info[irq].rtes, rte_list) {
327 rte_index = rte->rte_index; 319 rte_index = rte->rte_index;
328 iosapic_write(rte->iosapic, IOSAPIC_RTE_LOW(rte_index), low32); 320 iosapic_write(rte->iosapic, IOSAPIC_RTE_LOW(rte_index), low32);
329 } 321 }
@@ -334,14 +326,13 @@ unmask_irq (unsigned int irq)
334{ 326{
335 u32 low32; 327 u32 low32;
336 int rte_index; 328 int rte_index;
337 ia64_vector vec = irq_to_vector(irq);
338 struct iosapic_rte_info *rte; 329 struct iosapic_rte_info *rte;
339 330
340 if (list_empty(&iosapic_intr_info[vec].rtes)) 331 if (list_empty(&iosapic_intr_info[irq].rtes))
341 return; /* not an IOSAPIC interrupt! */ 332 return; /* not an IOSAPIC interrupt! */
342 333
343 low32 = iosapic_intr_info[vec].low32 &= ~IOSAPIC_MASK; 334 low32 = iosapic_intr_info[irq].low32 &= ~IOSAPIC_MASK;
344 list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) { 335 list_for_each_entry(rte, &iosapic_intr_info[irq].rtes, rte_list) {
345 rte_index = rte->rte_index; 336 rte_index = rte->rte_index;
346 iosapic_write(rte->iosapic, IOSAPIC_RTE_LOW(rte_index), low32); 337 iosapic_write(rte->iosapic, IOSAPIC_RTE_LOW(rte_index), low32);
347 } 338 }
@@ -355,19 +346,17 @@ iosapic_set_affinity (unsigned int irq, cpumask_t mask)
355 u32 high32, low32; 346 u32 high32, low32;
356 int dest, rte_index; 347 int dest, rte_index;
357 int redir = (irq & IA64_IRQ_REDIRECTED) ? 1 : 0; 348 int redir = (irq & IA64_IRQ_REDIRECTED) ? 1 : 0;
358 ia64_vector vec;
359 struct iosapic_rte_info *rte; 349 struct iosapic_rte_info *rte;
360 struct iosapic *iosapic; 350 struct iosapic *iosapic;
361 351
362 irq &= (~IA64_IRQ_REDIRECTED); 352 irq &= (~IA64_IRQ_REDIRECTED);
363 vec = irq_to_vector(irq);
364 353
365 if (cpus_empty(mask)) 354 if (cpus_empty(mask))
366 return; 355 return;
367 356
368 dest = cpu_physical_id(first_cpu(mask)); 357 dest = cpu_physical_id(first_cpu(mask));
369 358
370 if (list_empty(&iosapic_intr_info[vec].rtes)) 359 if (list_empty(&iosapic_intr_info[irq].rtes))
371 return; /* not an IOSAPIC interrupt */ 360 return; /* not an IOSAPIC interrupt */
372 361
373 set_irq_affinity_info(irq, dest, redir); 362 set_irq_affinity_info(irq, dest, redir);
@@ -375,7 +364,7 @@ iosapic_set_affinity (unsigned int irq, cpumask_t mask)
375 /* dest contains both id and eid */ 364 /* dest contains both id and eid */
376 high32 = dest << IOSAPIC_DEST_SHIFT; 365 high32 = dest << IOSAPIC_DEST_SHIFT;
377 366
378 low32 = iosapic_intr_info[vec].low32 & ~(7 << IOSAPIC_DELIVERY_SHIFT); 367 low32 = iosapic_intr_info[irq].low32 & ~(7 << IOSAPIC_DELIVERY_SHIFT);
379 if (redir) 368 if (redir)
380 /* change delivery mode to lowest priority */ 369 /* change delivery mode to lowest priority */
381 low32 |= (IOSAPIC_LOWEST_PRIORITY << IOSAPIC_DELIVERY_SHIFT); 370 low32 |= (IOSAPIC_LOWEST_PRIORITY << IOSAPIC_DELIVERY_SHIFT);
@@ -383,9 +372,9 @@ iosapic_set_affinity (unsigned int irq, cpumask_t mask)
383 /* change delivery mode to fixed */ 372 /* change delivery mode to fixed */
384 low32 |= (IOSAPIC_FIXED << IOSAPIC_DELIVERY_SHIFT); 373 low32 |= (IOSAPIC_FIXED << IOSAPIC_DELIVERY_SHIFT);
385 374
386 iosapic_intr_info[vec].low32 = low32; 375 iosapic_intr_info[irq].low32 = low32;
387 iosapic_intr_info[vec].dest = dest; 376 iosapic_intr_info[irq].dest = dest;
388 list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) { 377 list_for_each_entry(rte, &iosapic_intr_info[irq].rtes, rte_list) {
389 iosapic = rte->iosapic; 378 iosapic = rte->iosapic;
390 rte_index = rte->rte_index; 379 rte_index = rte->rte_index;
391 iosapic_write(iosapic, IOSAPIC_RTE_HIGH(rte_index), high32); 380 iosapic_write(iosapic, IOSAPIC_RTE_HIGH(rte_index), high32);
@@ -412,7 +401,7 @@ iosapic_end_level_irq (unsigned int irq)
412 struct iosapic_rte_info *rte; 401 struct iosapic_rte_info *rte;
413 402
414 move_native_irq(irq); 403 move_native_irq(irq);
415 list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) 404 list_for_each_entry(rte, &iosapic_intr_info[irq].rtes, rte_list)
416 iosapic_eoi(rte->iosapic->addr, vec); 405 iosapic_eoi(rte->iosapic->addr, vec);
417} 406}
418 407
@@ -498,10 +487,9 @@ iosapic_version (char __iomem *addr)
498 return __iosapic_read(addr, IOSAPIC_VERSION); 487 return __iosapic_read(addr, IOSAPIC_VERSION);
499} 488}
500 489
501static int iosapic_find_sharable_vector (unsigned long trigger, 490static int iosapic_find_sharable_irq(unsigned long trigger, unsigned long pol)
502 unsigned long pol)
503{ 491{
504 int i, vector = -ENOSPC, min_count = -1; 492 int i, irq = -ENOSPC, min_count = -1;
505 struct iosapic_intr_info *info; 493 struct iosapic_intr_info *info;
506 494
507 /* 495 /*
@@ -511,19 +499,18 @@ static int iosapic_find_sharable_vector (unsigned long trigger,
511 if (trigger == IOSAPIC_EDGE) 499 if (trigger == IOSAPIC_EDGE)
512 return -EINVAL; 500 return -EINVAL;
513 501
514 for (i = IA64_FIRST_DEVICE_VECTOR; i <= IA64_LAST_DEVICE_VECTOR; i++) { 502 for (i = 0; i <= NR_IRQS; i++) {
515 info = &iosapic_intr_info[i]; 503 info = &iosapic_intr_info[i];
516 if (info->trigger == trigger && info->polarity == pol && 504 if (info->trigger == trigger && info->polarity == pol &&
517 (info->dmode == IOSAPIC_FIXED || info->dmode == 505 (info->dmode == IOSAPIC_FIXED || info->dmode ==
518 IOSAPIC_LOWEST_PRIORITY)) { 506 IOSAPIC_LOWEST_PRIORITY)) {
519 if (min_count == -1 || info->count < min_count) { 507 if (min_count == -1 || info->count < min_count) {
520 vector = i; 508 irq = i;
521 min_count = info->count; 509 min_count = info->count;
522 } 510 }
523 } 511 }
524 } 512 }
525 513 return irq;
526 return vector;
527} 514}
528 515
529/* 516/*
@@ -531,26 +518,25 @@ static int iosapic_find_sharable_vector (unsigned long trigger,
531 * assign a new vector for the other and make the vector available 518 * assign a new vector for the other and make the vector available
532 */ 519 */
533static void __init 520static void __init
534iosapic_reassign_vector (int vector) 521iosapic_reassign_vector (int irq)
535{ 522{
536 int irq, new_vector; 523 int new_irq;
537 524
538 if (!list_empty(&iosapic_intr_info[vector].rtes)) { 525 if (!list_empty(&iosapic_intr_info[irq].rtes)) {
539 irq = create_irq(); 526 new_irq = create_irq();
540 if (irq < 0) 527 if (new_irq < 0)
541 panic("%s: out of interrupt vectors!\n", __FUNCTION__); 528 panic("%s: out of interrupt vectors!\n", __FUNCTION__);
542 new_vector = irq_to_vector(irq);
543 printk(KERN_INFO "Reassigning vector %d to %d\n", 529 printk(KERN_INFO "Reassigning vector %d to %d\n",
544 vector, new_vector); 530 irq_to_vector(irq), irq_to_vector(new_irq));
545 memcpy(&iosapic_intr_info[new_vector], &iosapic_intr_info[vector], 531 memcpy(&iosapic_intr_info[new_irq], &iosapic_intr_info[irq],
546 sizeof(struct iosapic_intr_info)); 532 sizeof(struct iosapic_intr_info));
547 INIT_LIST_HEAD(&iosapic_intr_info[new_vector].rtes); 533 INIT_LIST_HEAD(&iosapic_intr_info[new_irq].rtes);
548 list_move(iosapic_intr_info[vector].rtes.next, 534 list_move(iosapic_intr_info[irq].rtes.next,
549 &iosapic_intr_info[new_vector].rtes); 535 &iosapic_intr_info[new_irq].rtes);
550 memset(&iosapic_intr_info[vector], 0, 536 memset(&iosapic_intr_info[irq], 0,
551 sizeof(struct iosapic_intr_info)); 537 sizeof(struct iosapic_intr_info));
552 iosapic_intr_info[vector].low32 = IOSAPIC_MASK; 538 iosapic_intr_info[irq].low32 = IOSAPIC_MASK;
553 INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes); 539 INIT_LIST_HEAD(&iosapic_intr_info[irq].rtes);
554 } 540 }
555} 541}
556 542
@@ -595,13 +581,13 @@ static void iosapic_free_rte (struct iosapic_rte_info *rte)
595 kfree(rte); 581 kfree(rte);
596} 582}
597 583
598static inline int vector_is_shared (int vector) 584static inline int irq_is_shared (int irq)
599{ 585{
600 return (iosapic_intr_info[vector].count > 1); 586 return (iosapic_intr_info[irq].count > 1);
601} 587}
602 588
603static int 589static int
604register_intr (unsigned int gsi, int vector, unsigned char delivery, 590register_intr (unsigned int gsi, int irq, unsigned char delivery,
605 unsigned long polarity, unsigned long trigger) 591 unsigned long polarity, unsigned long trigger)
606{ 592{
607 irq_desc_t *idesc; 593 irq_desc_t *idesc;
@@ -616,7 +602,7 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
616 return -ENODEV; 602 return -ENODEV;
617 } 603 }
618 604
619 rte = gsi_vector_to_rte(gsi, vector); 605 rte = find_rte(irq, gsi);
620 if (!rte) { 606 if (!rte) {
621 rte = iosapic_alloc_rte(); 607 rte = iosapic_alloc_rte();
622 if (!rte) { 608 if (!rte) {
@@ -628,12 +614,12 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
628 rte->iosapic = &iosapic_lists[index]; 614 rte->iosapic = &iosapic_lists[index];
629 rte->rte_index = gsi - rte->iosapic->gsi_base; 615 rte->rte_index = gsi - rte->iosapic->gsi_base;
630 rte->refcnt++; 616 rte->refcnt++;
631 list_add_tail(&rte->rte_list, &iosapic_intr_info[vector].rtes); 617 list_add_tail(&rte->rte_list, &iosapic_intr_info[irq].rtes);
632 iosapic_intr_info[vector].count++; 618 iosapic_intr_info[irq].count++;
633 iosapic_lists[index].rtes_inuse++; 619 iosapic_lists[index].rtes_inuse++;
634 } 620 }
635 else if (vector_is_shared(vector)) { 621 else if (irq_is_shared(irq)) {
636 struct iosapic_intr_info *info = &iosapic_intr_info[vector]; 622 struct iosapic_intr_info *info = &iosapic_intr_info[irq];
637 if (info->trigger != trigger || info->polarity != polarity) { 623 if (info->trigger != trigger || info->polarity != polarity) {
638 printk (KERN_WARNING 624 printk (KERN_WARNING
639 "%s: cannot override the interrupt\n", 625 "%s: cannot override the interrupt\n",
@@ -642,21 +628,21 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
642 } 628 }
643 } 629 }
644 630
645 iosapic_intr_info[vector].polarity = polarity; 631 iosapic_intr_info[irq].polarity = polarity;
646 iosapic_intr_info[vector].dmode = delivery; 632 iosapic_intr_info[irq].dmode = delivery;
647 iosapic_intr_info[vector].trigger = trigger; 633 iosapic_intr_info[irq].trigger = trigger;
648 634
649 if (trigger == IOSAPIC_EDGE) 635 if (trigger == IOSAPIC_EDGE)
650 irq_type = &irq_type_iosapic_edge; 636 irq_type = &irq_type_iosapic_edge;
651 else 637 else
652 irq_type = &irq_type_iosapic_level; 638 irq_type = &irq_type_iosapic_level;
653 639
654 idesc = irq_desc + vector; 640 idesc = irq_desc + irq;
655 if (idesc->chip != irq_type) { 641 if (idesc->chip != irq_type) {
656 if (idesc->chip != &no_irq_type) 642 if (idesc->chip != &no_irq_type)
657 printk(KERN_WARNING 643 printk(KERN_WARNING
658 "%s: changing vector %d from %s to %s\n", 644 "%s: changing vector %d from %s to %s\n",
659 __FUNCTION__, vector, 645 __FUNCTION__, irq_to_vector(irq),
660 idesc->chip->name, irq_type->name); 646 idesc->chip->name, irq_type->name);
661 idesc->chip = irq_type; 647 idesc->chip = irq_type;
662 } 648 }
@@ -664,7 +650,7 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
664} 650}
665 651
666static unsigned int 652static unsigned int
667get_target_cpu (unsigned int gsi, int vector) 653get_target_cpu (unsigned int gsi, int irq)
668{ 654{
669#ifdef CONFIG_SMP 655#ifdef CONFIG_SMP
670 static int cpu = -1; 656 static int cpu = -1;
@@ -674,8 +660,8 @@ get_target_cpu (unsigned int gsi, int vector)
674 * In case of vector shared by multiple RTEs, all RTEs that 660 * In case of vector shared by multiple RTEs, all RTEs that
675 * share the vector need to use the same destination CPU. 661 * share the vector need to use the same destination CPU.
676 */ 662 */
677 if (!list_empty(&iosapic_intr_info[vector].rtes)) 663 if (!list_empty(&iosapic_intr_info[irq].rtes))
678 return iosapic_intr_info[vector].dest; 664 return iosapic_intr_info[irq].dest;
679 665
680 /* 666 /*
681 * If the platform supports redirection via XTP, let it 667 * If the platform supports redirection via XTP, let it
@@ -692,7 +678,7 @@ get_target_cpu (unsigned int gsi, int vector)
692 return cpu_physical_id(smp_processor_id()); 678 return cpu_physical_id(smp_processor_id());
693 679
694#ifdef CONFIG_ACPI 680#ifdef CONFIG_ACPI
695 if (cpe_vector > 0 && vector == IA64_CPEP_VECTOR) 681 if (cpe_vector > 0 && irq_to_vector(irq) == IA64_CPEP_VECTOR)
696 return get_cpei_target_cpu(); 682 return get_cpei_target_cpu();
697#endif 683#endif
698 684
@@ -718,8 +704,8 @@ get_target_cpu (unsigned int gsi, int vector)
718 if (!num_cpus) 704 if (!num_cpus)
719 goto skip_numa_setup; 705 goto skip_numa_setup;
720 706
721 /* Use vector assignment to distribute across cpus in node */ 707 /* Use irq assignment to distribute across cpus in node */
722 cpu_index = vector % num_cpus; 708 cpu_index = irq % num_cpus;
723 709
724 for (numa_cpu = first_cpu(cpu_mask) ; i < cpu_index ; i++) 710 for (numa_cpu = first_cpu(cpu_mask) ; i < cpu_index ; i++)
725 numa_cpu = next_cpu(numa_cpu, cpu_mask); 711 numa_cpu = next_cpu(numa_cpu, cpu_mask);
@@ -754,7 +740,7 @@ int
754iosapic_register_intr (unsigned int gsi, 740iosapic_register_intr (unsigned int gsi,
755 unsigned long polarity, unsigned long trigger) 741 unsigned long polarity, unsigned long trigger)
756{ 742{
757 int irq, vector, mask = 1, err; 743 int irq, mask = 1, err;
758 unsigned int dest; 744 unsigned int dest;
759 unsigned long flags; 745 unsigned long flags;
760 struct iosapic_rte_info *rte; 746 struct iosapic_rte_info *rte;
@@ -766,9 +752,9 @@ iosapic_register_intr (unsigned int gsi,
766 * don't touch the RTE. 752 * don't touch the RTE.
767 */ 753 */
768 spin_lock_irqsave(&iosapic_lock, flags); 754 spin_lock_irqsave(&iosapic_lock, flags);
769 vector = gsi_to_vector(gsi); 755 irq = __gsi_to_irq(gsi);
770 if (vector > 0) { 756 if (irq > 0) {
771 rte = gsi_vector_to_rte(gsi, vector); 757 rte = find_rte(irq, gsi);
772 rte->refcnt++; 758 rte->refcnt++;
773 goto unlock_iosapic_lock; 759 goto unlock_iosapic_lock;
774 } 760 }
@@ -776,18 +762,17 @@ iosapic_register_intr (unsigned int gsi,
776 /* If vector is running out, we try to find a sharable vector */ 762 /* If vector is running out, we try to find a sharable vector */
777 irq = create_irq(); 763 irq = create_irq();
778 if (irq < 0) { 764 if (irq < 0) {
779 vector = iosapic_find_sharable_vector(trigger, polarity); 765 irq = iosapic_find_sharable_irq(trigger, polarity);
780 if (vector < 0) 766 if (irq < 0)
781 goto unlock_iosapic_lock; 767 goto unlock_iosapic_lock;
782 } else 768 }
783 vector = irq_to_vector(irq);
784 769
785 spin_lock(&irq_desc[vector].lock); 770 spin_lock(&irq_desc[irq].lock);
786 dest = get_target_cpu(gsi, vector); 771 dest = get_target_cpu(gsi, irq);
787 err = register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, 772 err = register_intr(gsi, irq, IOSAPIC_LOWEST_PRIORITY,
788 polarity, trigger); 773 polarity, trigger);
789 if (err < 0) { 774 if (err < 0) {
790 vector = err; 775 irq = err;
791 goto unlock_all; 776 goto unlock_all;
792 } 777 }
793 778
@@ -795,27 +780,27 @@ iosapic_register_intr (unsigned int gsi,
795 * If the vector is shared and already unmasked for other 780 * If the vector is shared and already unmasked for other
796 * interrupt sources, don't mask it. 781 * interrupt sources, don't mask it.
797 */ 782 */
798 low32 = iosapic_intr_info[vector].low32; 783 low32 = iosapic_intr_info[irq].low32;
799 if (vector_is_shared(vector) && !(low32 & IOSAPIC_MASK)) 784 if (irq_is_shared(irq) && !(low32 & IOSAPIC_MASK))
800 mask = 0; 785 mask = 0;
801 set_rte(gsi, vector, dest, mask); 786 set_rte(gsi, irq, dest, mask);
802 787
803 printk(KERN_INFO "GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d\n", 788 printk(KERN_INFO "GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d\n",
804 gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"), 789 gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"),
805 (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), 790 (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
806 cpu_logical_id(dest), dest, vector); 791 cpu_logical_id(dest), dest, irq_to_vector(irq));
807 unlock_all: 792 unlock_all:
808 spin_unlock(&irq_desc[vector].lock); 793 spin_unlock(&irq_desc[irq].lock);
809 unlock_iosapic_lock: 794 unlock_iosapic_lock:
810 spin_unlock_irqrestore(&iosapic_lock, flags); 795 spin_unlock_irqrestore(&iosapic_lock, flags);
811 return vector; 796 return irq;
812} 797}
813 798
814void 799void
815iosapic_unregister_intr (unsigned int gsi) 800iosapic_unregister_intr (unsigned int gsi)
816{ 801{
817 unsigned long flags; 802 unsigned long flags;
818 int irq, vector, index; 803 int irq, index;
819 irq_desc_t *idesc; 804 irq_desc_t *idesc;
820 u32 low32; 805 u32 low32;
821 unsigned long trigger, polarity; 806 unsigned long trigger, polarity;
@@ -834,10 +819,9 @@ iosapic_unregister_intr (unsigned int gsi)
834 WARN_ON(1); 819 WARN_ON(1);
835 return; 820 return;
836 } 821 }
837 vector = irq_to_vector(irq);
838 822
839 spin_lock_irqsave(&iosapic_lock, flags); 823 spin_lock_irqsave(&iosapic_lock, flags);
840 if ((rte = gsi_vector_to_rte(gsi, vector)) == NULL) { 824 if ((rte = find_rte(irq, gsi)) == NULL) {
841 printk(KERN_ERR "iosapic_unregister_intr(%u) unbalanced\n", 825 printk(KERN_ERR "iosapic_unregister_intr(%u) unbalanced\n",
842 gsi); 826 gsi);
843 WARN_ON(1); 827 WARN_ON(1);
@@ -854,36 +838,36 @@ iosapic_unregister_intr (unsigned int gsi)
854 spin_unlock(&idesc->lock); 838 spin_unlock(&idesc->lock);
855 839
856 /* Mask the interrupt */ 840 /* Mask the interrupt */
857 low32 = iosapic_intr_info[vector].low32 | IOSAPIC_MASK; 841 low32 = iosapic_intr_info[irq].low32 | IOSAPIC_MASK;
858 iosapic_write(rte->iosapic, IOSAPIC_RTE_LOW(rte->rte_index), low32); 842 iosapic_write(rte->iosapic, IOSAPIC_RTE_LOW(rte->rte_index), low32);
859 843
860 iosapic_intr_info[vector].count--; 844 iosapic_intr_info[irq].count--;
861 iosapic_free_rte(rte); 845 iosapic_free_rte(rte);
862 index = find_iosapic(gsi); 846 index = find_iosapic(gsi);
863 iosapic_lists[index].rtes_inuse--; 847 iosapic_lists[index].rtes_inuse--;
864 WARN_ON(iosapic_lists[index].rtes_inuse < 0); 848 WARN_ON(iosapic_lists[index].rtes_inuse < 0);
865 849
866 trigger = iosapic_intr_info[vector].trigger; 850 trigger = iosapic_intr_info[irq].trigger;
867 polarity = iosapic_intr_info[vector].polarity; 851 polarity = iosapic_intr_info[irq].polarity;
868 dest = iosapic_intr_info[vector].dest; 852 dest = iosapic_intr_info[irq].dest;
869 printk(KERN_INFO 853 printk(KERN_INFO
870 "GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d unregistered\n", 854 "GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d unregistered\n",
871 gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"), 855 gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"),
872 (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), 856 (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
873 cpu_logical_id(dest), dest, vector); 857 cpu_logical_id(dest), dest, irq_to_vector(irq));
874 858
875 if (list_empty(&iosapic_intr_info[vector].rtes)) { 859 if (list_empty(&iosapic_intr_info[irq].rtes)) {
876 /* Sanity check */ 860 /* Sanity check */
877 BUG_ON(iosapic_intr_info[vector].count); 861 BUG_ON(iosapic_intr_info[irq].count);
878#ifdef CONFIG_SMP 862#ifdef CONFIG_SMP
879 /* Clear affinity */ 863 /* Clear affinity */
880 cpus_setall(idesc->affinity); 864 cpus_setall(idesc->affinity);
881#endif 865#endif
882 /* Clear the interrupt information */ 866 /* Clear the interrupt information */
883 memset(&iosapic_intr_info[vector], 0, 867 memset(&iosapic_intr_info[irq], 0,
884 sizeof(struct iosapic_intr_info)); 868 sizeof(struct iosapic_intr_info));
885 iosapic_intr_info[vector].low32 |= IOSAPIC_MASK; 869 iosapic_intr_info[irq].low32 |= IOSAPIC_MASK;
886 INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes); 870 INIT_LIST_HEAD(&iosapic_intr_info[irq].rtes);
887 871
888 /* Destroy IRQ */ 872 /* Destroy IRQ */
889 destroy_irq(irq); 873 destroy_irq(irq);
@@ -908,11 +892,12 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
908 switch (int_type) { 892 switch (int_type) {
909 case ACPI_INTERRUPT_PMI: 893 case ACPI_INTERRUPT_PMI:
910 vector = iosapic_vector; 894 vector = iosapic_vector;
895 irq = vector; /* FIXME */
911 /* 896 /*
912 * since PMI vector is alloc'd by FW(ACPI) not by kernel, 897 * since PMI vector is alloc'd by FW(ACPI) not by kernel,
913 * we need to make sure the vector is available 898 * we need to make sure the vector is available
914 */ 899 */
915 iosapic_reassign_vector(vector); 900 iosapic_reassign_vector(irq);
916 delivery = IOSAPIC_PMI; 901 delivery = IOSAPIC_PMI;
917 break; 902 break;
918 case ACPI_INTERRUPT_INIT: 903 case ACPI_INTERRUPT_INIT:
@@ -924,6 +909,7 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
924 break; 909 break;
925 case ACPI_INTERRUPT_CPEI: 910 case ACPI_INTERRUPT_CPEI:
926 vector = IA64_CPE_VECTOR; 911 vector = IA64_CPE_VECTOR;
912 irq = vector; /* FIXME */
927 delivery = IOSAPIC_LOWEST_PRIORITY; 913 delivery = IOSAPIC_LOWEST_PRIORITY;
928 mask = 1; 914 mask = 1;
929 break; 915 break;
@@ -933,7 +919,7 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
933 return -1; 919 return -1;
934 } 920 }
935 921
936 register_intr(gsi, vector, delivery, polarity, trigger); 922 register_intr(gsi, irq, delivery, polarity, trigger);
937 923
938 printk(KERN_INFO 924 printk(KERN_INFO
939 "PLATFORM int %s (0x%x): GSI %u (%s, %s) -> CPU %d (0x%04x)" 925 "PLATFORM int %s (0x%x): GSI %u (%s, %s) -> CPU %d (0x%04x)"
@@ -943,7 +929,7 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
943 (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), 929 (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
944 cpu_logical_id(dest), dest, vector); 930 cpu_logical_id(dest), dest, vector);
945 931
946 set_rte(gsi, vector, dest, mask); 932 set_rte(gsi, irq, dest, mask);
947 return vector; 933 return vector;
948} 934}
949 935
@@ -955,30 +941,30 @@ iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
955 unsigned long polarity, 941 unsigned long polarity,
956 unsigned long trigger) 942 unsigned long trigger)
957{ 943{
958 int vector; 944 int vector, irq;
959 unsigned int dest = cpu_physical_id(smp_processor_id()); 945 unsigned int dest = cpu_physical_id(smp_processor_id());
960 946
961 vector = isa_irq_to_vector(isa_irq); 947 vector = isa_irq_to_vector(isa_irq);
962 948 irq = vector; /* FIXME */
963 register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, polarity, trigger); 949 register_intr(gsi, irq, IOSAPIC_LOWEST_PRIORITY, polarity, trigger);
964 950
965 DBG("ISA: IRQ %u -> GSI %u (%s,%s) -> CPU %d (0x%04x) vector %d\n", 951 DBG("ISA: IRQ %u -> GSI %u (%s,%s) -> CPU %d (0x%04x) vector %d\n",
966 isa_irq, gsi, trigger == IOSAPIC_EDGE ? "edge" : "level", 952 isa_irq, gsi, trigger == IOSAPIC_EDGE ? "edge" : "level",
967 polarity == IOSAPIC_POL_HIGH ? "high" : "low", 953 polarity == IOSAPIC_POL_HIGH ? "high" : "low",
968 cpu_logical_id(dest), dest, vector); 954 cpu_logical_id(dest), dest, vector);
969 955
970 set_rte(gsi, vector, dest, 1); 956 set_rte(gsi, irq, dest, 1);
971} 957}
972 958
973void __init 959void __init
974iosapic_system_init (int system_pcat_compat) 960iosapic_system_init (int system_pcat_compat)
975{ 961{
976 int vector; 962 int irq;
977 963
978 for (vector = 0; vector < IA64_NUM_VECTORS; ++vector) { 964 for (irq = 0; irq < NR_IRQS; ++irq) {
979 iosapic_intr_info[vector].low32 = IOSAPIC_MASK; 965 iosapic_intr_info[irq].low32 = IOSAPIC_MASK;
980 /* mark as unused */ 966 /* mark as unused */
981 INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes); 967 INIT_LIST_HEAD(&iosapic_intr_info[irq].rtes);
982 } 968 }
983 969
984 pcat_compat = system_pcat_compat; 970 pcat_compat = system_pcat_compat;