aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel/iosapic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64/kernel/iosapic.c')
-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;