aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/sparc64/kernel/irq.c238
1 files changed, 92 insertions, 146 deletions
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index f8f704524ed9..2be6bcbe50ca 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -122,7 +122,6 @@ static void bucket_set_virt_irq(unsigned long bucket_pa,
122 "i" (ASI_PHYS_USE_EC)); 122 "i" (ASI_PHYS_USE_EC));
123} 123}
124 124
125#define __bucket(irq) ((struct ino_bucket *)(irq))
126#define __irq(bucket) ((unsigned long)(bucket)) 125#define __irq(bucket) ((unsigned long)(bucket))
127 126
128#define irq_work_pa(__cpu) &(trap_block[(__cpu)].irq_worklist_pa) 127#define irq_work_pa(__cpu) &(trap_block[(__cpu)].irq_worklist_pa)
@@ -179,11 +178,6 @@ void virt_irq_free(unsigned int virt_irq)
179} 178}
180#endif 179#endif
181 180
182static unsigned long virt_to_real_irq(unsigned char virt_irq)
183{
184 return virt_to_real_irq_table[virt_irq].irq;
185}
186
187/* 181/*
188 * /proc/interrupts printing: 182 * /proc/interrupts printing:
189 */ 183 */
@@ -270,17 +264,6 @@ struct irq_handler_data {
270 void *pre_handler_arg2; 264 void *pre_handler_arg2;
271}; 265};
272 266
273static inline struct ino_bucket *virt_irq_to_bucket(unsigned int virt_irq)
274{
275 unsigned long real_irq = virt_to_real_irq(virt_irq);
276 struct ino_bucket *bucket = NULL;
277
278 if (likely(real_irq))
279 bucket = __bucket(real_irq);
280
281 return bucket;
282}
283
284#ifdef CONFIG_SMP 267#ifdef CONFIG_SMP
285static int irq_choose_cpu(unsigned int virt_irq) 268static int irq_choose_cpu(unsigned int virt_irq)
286{ 269{
@@ -380,178 +363,142 @@ static void sun4u_irq_end(unsigned int virt_irq)
380 363
381static void sun4v_irq_enable(unsigned int virt_irq) 364static void sun4v_irq_enable(unsigned int virt_irq)
382{ 365{
383 struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); 366 unsigned int ino = virt_to_real_irq_table[virt_irq].dev_ino;
384 unsigned int ino = bucket - &ivector_table[0]; 367 unsigned long cpuid = irq_choose_cpu(virt_irq);
368 int err;
385 369
386 if (likely(bucket)) { 370 err = sun4v_intr_settarget(ino, cpuid);
387 unsigned long cpuid; 371 if (err != HV_EOK)
388 int err; 372 printk(KERN_ERR "sun4v_intr_settarget(%x,%lu): "
389 373 "err(%d)\n", ino, cpuid, err);
390 cpuid = irq_choose_cpu(virt_irq); 374 err = sun4v_intr_setstate(ino, HV_INTR_STATE_IDLE);
391 375 if (err != HV_EOK)
392 err = sun4v_intr_settarget(ino, cpuid); 376 printk(KERN_ERR "sun4v_intr_setstate(%x): "
393 if (err != HV_EOK) 377 "err(%d)\n", ino, err);
394 printk(KERN_ERR "sun4v_intr_settarget(%x,%lu): " 378 err = sun4v_intr_setenabled(ino, HV_INTR_ENABLED);
395 "err(%d)\n", ino, cpuid, err); 379 if (err != HV_EOK)
396 err = sun4v_intr_setstate(ino, HV_INTR_STATE_IDLE); 380 printk(KERN_ERR "sun4v_intr_setenabled(%x): err(%d)\n",
397 if (err != HV_EOK) 381 ino, err);
398 printk(KERN_ERR "sun4v_intr_setstate(%x): "
399 "err(%d)\n", ino, err);
400 err = sun4v_intr_setenabled(ino, HV_INTR_ENABLED);
401 if (err != HV_EOK)
402 printk(KERN_ERR "sun4v_intr_setenabled(%x): err(%d)\n",
403 ino, err);
404 }
405} 382}
406 383
407static void sun4v_set_affinity(unsigned int virt_irq, cpumask_t mask) 384static void sun4v_set_affinity(unsigned int virt_irq, cpumask_t mask)
408{ 385{
409 struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); 386 unsigned int ino = virt_to_real_irq_table[virt_irq].dev_ino;
410 unsigned int ino = bucket - &ivector_table[0]; 387 unsigned long cpuid = irq_choose_cpu(virt_irq);
388 int err;
411 389
412 if (likely(bucket)) { 390 err = sun4v_intr_settarget(ino, cpuid);
413 unsigned long cpuid; 391 if (err != HV_EOK)
414 int err; 392 printk(KERN_ERR "sun4v_intr_settarget(%x,%lu): "
415 393 "err(%d)\n", ino, cpuid, err);
416 cpuid = irq_choose_cpu(virt_irq);
417
418 err = sun4v_intr_settarget(ino, cpuid);
419 if (err != HV_EOK)
420 printk(KERN_ERR "sun4v_intr_settarget(%x,%lu): "
421 "err(%d)\n", ino, cpuid, err);
422 }
423} 394}
424 395
425static void sun4v_irq_disable(unsigned int virt_irq) 396static void sun4v_irq_disable(unsigned int virt_irq)
426{ 397{
427 struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); 398 unsigned int ino = virt_to_real_irq_table[virt_irq].dev_ino;
428 unsigned int ino = bucket - &ivector_table[0]; 399 int err;
429 400
430 if (likely(bucket)) { 401 err = sun4v_intr_setenabled(ino, HV_INTR_DISABLED);
431 int err; 402 if (err != HV_EOK)
432 403 printk(KERN_ERR "sun4v_intr_setenabled(%x): "
433 err = sun4v_intr_setenabled(ino, HV_INTR_DISABLED); 404 "err(%d)\n", ino, err);
434 if (err != HV_EOK)
435 printk(KERN_ERR "sun4v_intr_setenabled(%x): "
436 "err(%d)\n", ino, err);
437 }
438} 405}
439 406
440static void sun4v_irq_end(unsigned int virt_irq) 407static void sun4v_irq_end(unsigned int virt_irq)
441{ 408{
442 struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); 409 unsigned int ino = virt_to_real_irq_table[virt_irq].dev_ino;
443 unsigned int ino = bucket - &ivector_table[0];
444 struct irq_desc *desc = irq_desc + virt_irq; 410 struct irq_desc *desc = irq_desc + virt_irq;
411 int err;
445 412
446 if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS))) 413 if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
447 return; 414 return;
448 415
449 if (likely(bucket)) { 416 err = sun4v_intr_setstate(ino, HV_INTR_STATE_IDLE);
450 int err; 417 if (err != HV_EOK)
451 418 printk(KERN_ERR "sun4v_intr_setstate(%x): "
452 err = sun4v_intr_setstate(ino, HV_INTR_STATE_IDLE); 419 "err(%d)\n", ino, err);
453 if (err != HV_EOK)
454 printk(KERN_ERR "sun4v_intr_setstate(%x): "
455 "err(%d)\n", ino, err);
456 }
457} 420}
458 421
459static void sun4v_virq_enable(unsigned int virt_irq) 422static void sun4v_virq_enable(unsigned int virt_irq)
460{ 423{
461 struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); 424 unsigned long cpuid, dev_handle, dev_ino;
462 425 int err;
463 if (likely(bucket)) { 426
464 unsigned long cpuid, dev_handle, dev_ino; 427 cpuid = irq_choose_cpu(virt_irq);
465 int err; 428
466 429 dev_handle = virt_to_real_irq_table[virt_irq].dev_handle;
467 cpuid = irq_choose_cpu(virt_irq); 430 dev_ino = virt_to_real_irq_table[virt_irq].dev_ino;
468 431
469 dev_handle = virt_to_real_irq_table[virt_irq].dev_handle; 432 err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid);
470 dev_ino = virt_to_real_irq_table[virt_irq].dev_ino; 433 if (err != HV_EOK)
471 434 printk(KERN_ERR "sun4v_vintr_set_target(%lx,%lx,%lu): "
472 err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid); 435 "err(%d)\n",
473 if (err != HV_EOK) 436 dev_handle, dev_ino, cpuid, err);
474 printk(KERN_ERR "sun4v_vintr_set_target(%lx,%lx,%lu): " 437 err = sun4v_vintr_set_state(dev_handle, dev_ino,
475 "err(%d)\n", 438 HV_INTR_STATE_IDLE);
476 dev_handle, dev_ino, cpuid, err); 439 if (err != HV_EOK)
477 err = sun4v_vintr_set_state(dev_handle, dev_ino, 440 printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx,"
478 HV_INTR_STATE_IDLE); 441 "HV_INTR_STATE_IDLE): err(%d)\n",
479 if (err != HV_EOK) 442 dev_handle, dev_ino, err);
480 printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx," 443 err = sun4v_vintr_set_valid(dev_handle, dev_ino,
481 "HV_INTR_STATE_IDLE): err(%d)\n", 444 HV_INTR_ENABLED);
482 dev_handle, dev_ino, err); 445 if (err != HV_EOK)
483 err = sun4v_vintr_set_valid(dev_handle, dev_ino, 446 printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx,"
484 HV_INTR_ENABLED); 447 "HV_INTR_ENABLED): err(%d)\n",
485 if (err != HV_EOK) 448 dev_handle, dev_ino, err);
486 printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx,"
487 "HV_INTR_ENABLED): err(%d)\n",
488 dev_handle, dev_ino, err);
489 }
490} 449}
491 450
492static void sun4v_virt_set_affinity(unsigned int virt_irq, cpumask_t mask) 451static void sun4v_virt_set_affinity(unsigned int virt_irq, cpumask_t mask)
493{ 452{
494 struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); 453 unsigned long cpuid, dev_handle, dev_ino;
495 454 int err;
496 if (likely(bucket)) {
497 unsigned long cpuid, dev_handle, dev_ino;
498 int err;
499 455
500 cpuid = irq_choose_cpu(virt_irq); 456 cpuid = irq_choose_cpu(virt_irq);
501 457
502 dev_handle = virt_to_real_irq_table[virt_irq].dev_handle; 458 dev_handle = virt_to_real_irq_table[virt_irq].dev_handle;
503 dev_ino = virt_to_real_irq_table[virt_irq].dev_ino; 459 dev_ino = virt_to_real_irq_table[virt_irq].dev_ino;
504 460
505 err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid); 461 err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid);
506 if (err != HV_EOK) 462 if (err != HV_EOK)
507 printk(KERN_ERR "sun4v_vintr_set_target(%lx,%lx,%lu): " 463 printk(KERN_ERR "sun4v_vintr_set_target(%lx,%lx,%lu): "
508 "err(%d)\n", 464 "err(%d)\n",
509 dev_handle, dev_ino, cpuid, err); 465 dev_handle, dev_ino, cpuid, err);
510 }
511} 466}
512 467
513static void sun4v_virq_disable(unsigned int virt_irq) 468static void sun4v_virq_disable(unsigned int virt_irq)
514{ 469{
515 struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); 470 unsigned long dev_handle, dev_ino;
471 int err;
516 472
517 if (likely(bucket)) { 473 dev_handle = virt_to_real_irq_table[virt_irq].dev_handle;
518 unsigned long dev_handle, dev_ino; 474 dev_ino = virt_to_real_irq_table[virt_irq].dev_ino;
519 int err;
520 475
521 dev_handle = virt_to_real_irq_table[virt_irq].dev_handle; 476 err = sun4v_vintr_set_valid(dev_handle, dev_ino,
522 dev_ino = virt_to_real_irq_table[virt_irq].dev_ino; 477 HV_INTR_DISABLED);
523 478 if (err != HV_EOK)
524 err = sun4v_vintr_set_valid(dev_handle, dev_ino, 479 printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx,"
525 HV_INTR_DISABLED); 480 "HV_INTR_DISABLED): err(%d)\n",
526 if (err != HV_EOK) 481 dev_handle, dev_ino, err);
527 printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx,"
528 "HV_INTR_DISABLED): err(%d)\n",
529 dev_handle, dev_ino, err);
530 }
531} 482}
532 483
533static void sun4v_virq_end(unsigned int virt_irq) 484static void sun4v_virq_end(unsigned int virt_irq)
534{ 485{
535 struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
536 struct irq_desc *desc = irq_desc + virt_irq; 486 struct irq_desc *desc = irq_desc + virt_irq;
487 unsigned long dev_handle, dev_ino;
488 int err;
537 489
538 if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS))) 490 if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
539 return; 491 return;
540 492
541 if (likely(bucket)) { 493 dev_handle = virt_to_real_irq_table[virt_irq].dev_handle;
542 unsigned long dev_handle, dev_ino; 494 dev_ino = virt_to_real_irq_table[virt_irq].dev_ino;
543 int err;
544 495
545 dev_handle = virt_to_real_irq_table[virt_irq].dev_handle; 496 err = sun4v_vintr_set_state(dev_handle, dev_ino,
546 dev_ino = virt_to_real_irq_table[virt_irq].dev_ino; 497 HV_INTR_STATE_IDLE);
547 498 if (err != HV_EOK)
548 err = sun4v_vintr_set_state(dev_handle, dev_ino, 499 printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx,"
549 HV_INTR_STATE_IDLE); 500 "HV_INTR_STATE_IDLE): err(%d)\n",
550 if (err != HV_EOK) 501 dev_handle, dev_ino, err);
551 printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx,"
552 "HV_INTR_STATE_IDLE): err(%d)\n",
553 dev_handle, dev_ino, err);
554 }
555} 502}
556 503
557static void run_pre_handler(unsigned int virt_irq) 504static void run_pre_handler(unsigned int virt_irq)
@@ -749,11 +696,10 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino)
749 696
750void ack_bad_irq(unsigned int virt_irq) 697void ack_bad_irq(unsigned int virt_irq)
751{ 698{
752 struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); 699 unsigned int ino = virt_to_real_irq_table[virt_irq].dev_ino;
753 unsigned int ino = 0xdeadbeef;
754 700
755 if (bucket) 701 if (!ino)
756 ino = bucket - &ivector_table[0]; 702 ino = 0xdeadbeef;
757 703
758 printk(KERN_CRIT "Unexpected IRQ from ino[%x] virt_irq[%u]\n", 704 printk(KERN_CRIT "Unexpected IRQ from ino[%x] virt_irq[%u]\n",
759 ino, virt_irq); 705 ino, virt_irq);