Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86: Cleanup visws interrupt handling

Remove the open coded access to irq_desc and convert to the new irq
chip functions. Change the mask function of piix4_virtual_irq_type so
we can use the generic irq handling function for the virtual interrupt
instead of open coding it.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Ingo Molnar <mingo@elte.hu>

+42 -94
+42 -94
arch/x86/kernel/visws_quirks.c
··· 66 66 } 67 67 68 68 /* Replaces the default init_ISA_irqs in the generic setup */ 69 - static void __init visws_pre_intr_init(void) 70 - { 71 - init_VISWS_APIC_irqs(); 72 - } 69 + static void __init visws_pre_intr_init(void); 73 70 74 71 /* Quirk for machine specific memory setup. */ 75 72 ··· 426 429 /* 427 430 * This is the SGI Cobalt (IO-)APIC: 428 431 */ 429 - 430 - static void enable_cobalt_irq(unsigned int irq) 432 + static void enable_cobalt_irq(struct irq_data *data) 431 433 { 432 - co_apic_set(is_co_apic(irq), irq); 434 + co_apic_set(is_co_apic(data->irq), data->irq); 433 435 } 434 436 435 - static void disable_cobalt_irq(unsigned int irq) 437 + static void disable_cobalt_irq(struct irq_data *data) 436 438 { 437 - int entry = is_co_apic(irq); 439 + int entry = is_co_apic(data->irq); 438 440 439 441 co_apic_write(CO_APIC_LO(entry), CO_APIC_MASK); 440 442 co_apic_read(CO_APIC_LO(entry)); 441 443 } 442 444 443 - /* 444 - * "irq" really just serves to identify the device. Here is where we 445 - * map this to the Cobalt APIC entry where it's physically wired. 446 - * This is called via request_irq -> setup_irq -> irq_desc->startup() 447 - */ 448 - static unsigned int startup_cobalt_irq(unsigned int irq) 449 - { 450 - unsigned long flags; 451 - struct irq_desc *desc = irq_to_desc(irq); 452 - 453 - spin_lock_irqsave(&cobalt_lock, flags); 454 - if ((desc->status & (IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING))) 455 - desc->status &= ~(IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING); 456 - enable_cobalt_irq(irq); 457 - spin_unlock_irqrestore(&cobalt_lock, flags); 458 - return 0; 459 - } 460 - 461 - static void ack_cobalt_irq(unsigned int irq) 445 + static void ack_cobalt_irq(struct irq_data *data) 462 446 { 463 447 unsigned long flags; 464 448 465 449 spin_lock_irqsave(&cobalt_lock, flags); 466 - disable_cobalt_irq(irq); 450 + disable_cobalt_irq(data); 467 451 apic_write(APIC_EOI, APIC_EIO_ACK); 468 452 spin_unlock_irqrestore(&cobalt_lock, flags); 469 453 } 470 454 471 - static void end_cobalt_irq(unsigned int irq) 472 - { 473 - unsigned long flags; 474 - struct irq_desc *desc = irq_to_desc(irq); 475 - 476 - spin_lock_irqsave(&cobalt_lock, flags); 477 - if (!(desc->status & (IRQ_DISABLED | IRQ_INPROGRESS))) 478 - enable_cobalt_irq(irq); 479 - spin_unlock_irqrestore(&cobalt_lock, flags); 480 - } 481 - 482 455 static struct irq_chip cobalt_irq_type = { 483 - .name = "Cobalt-APIC", 484 - .startup = startup_cobalt_irq, 485 - .shutdown = disable_cobalt_irq, 486 - .enable = enable_cobalt_irq, 487 - .disable = disable_cobalt_irq, 488 - .ack = ack_cobalt_irq, 489 - .end = end_cobalt_irq, 456 + .name = "Cobalt-APIC", 457 + .irq_enable = enable_cobalt_irq, 458 + .irq_disable = disable_cobalt_irq, 459 + .irq_ack = ack_cobalt_irq, 490 460 }; 491 461 492 462 ··· 467 503 * interrupt controller type, and through a special virtual interrupt- 468 504 * controller. Device drivers only see the virtual interrupt sources. 469 505 */ 470 - static unsigned int startup_piix4_master_irq(unsigned int irq) 506 + static unsigned int startup_piix4_master_irq(struct irq_data *data) 471 507 { 472 508 legacy_pic->init(0); 473 - 474 - return startup_cobalt_irq(irq); 509 + enable_cobalt_irq(data); 475 510 } 476 511 477 - static void end_piix4_master_irq(unsigned int irq) 512 + static void end_piix4_master_irq(struct irq_data *data) 478 513 { 479 514 unsigned long flags; 480 515 481 516 spin_lock_irqsave(&cobalt_lock, flags); 482 - enable_cobalt_irq(irq); 517 + enable_cobalt_irq(data); 483 518 spin_unlock_irqrestore(&cobalt_lock, flags); 484 519 } 485 520 486 521 static struct irq_chip piix4_master_irq_type = { 487 - .name = "PIIX4-master", 488 - .startup = startup_piix4_master_irq, 489 - .ack = ack_cobalt_irq, 490 - .end = end_piix4_master_irq, 522 + .name = "PIIX4-master", 523 + .irq_startup = startup_piix4_master_irq, 524 + .irq_ack = ack_cobalt_irq, 491 525 }; 492 526 527 + static void pii4_mask(struct irq_data *data) { } 493 528 494 529 static struct irq_chip piix4_virtual_irq_type = { 495 - .name = "PIIX4-virtual", 530 + .name = "PIIX4-virtual", 531 + .mask = pii4_mask, 496 532 }; 497 - 498 533 499 534 /* 500 535 * PIIX4-8259 master/virtual functions to handle interrupt requests ··· 512 549 */ 513 550 static irqreturn_t piix4_master_intr(int irq, void *dev_id) 514 551 { 515 - int realirq; 516 - struct irq_desc *desc; 517 552 unsigned long flags; 553 + int realirq; 518 554 519 555 raw_spin_lock_irqsave(&i8259A_lock, flags); 520 556 ··· 554 592 555 593 raw_spin_unlock_irqrestore(&i8259A_lock, flags); 556 594 557 - desc = irq_to_desc(realirq); 558 - 559 595 /* 560 596 * handle this 'virtual interrupt' as a Cobalt one now. 561 597 */ 562 - kstat_incr_irqs_this_cpu(realirq, desc); 563 - 564 - if (likely(desc->action != NULL)) 565 - handle_IRQ_event(realirq, desc->action); 566 - 567 - if (!(desc->status & IRQ_DISABLED)) 568 - legacy_pic->chip->unmask(realirq); 598 + generic_handle_irq(realirq); 569 599 570 600 return IRQ_HANDLED; 571 601 ··· 578 624 579 625 static inline void set_piix4_virtual_irq_type(void) 580 626 { 581 - piix4_virtual_irq_type.shutdown = i8259A_chip.mask; 582 627 piix4_virtual_irq_type.enable = i8259A_chip.unmask; 583 628 piix4_virtual_irq_type.disable = i8259A_chip.mask; 629 + piix4_virtual_irq_type.unmask = i8259A_chip.unmask; 584 630 } 585 631 586 - void init_VISWS_APIC_irqs(void) 632 + static void __init visws_pre_intr_init(void) 587 633 { 588 634 int i; 589 635 636 + set_piix4_virtual_irq_type(); 637 + 590 638 for (i = 0; i < CO_IRQ_APIC0 + CO_APIC_LAST + 1; i++) { 591 - struct irq_desc *desc = irq_to_desc(i); 639 + struct irq_chip *chip = NULL; 592 640 593 - desc->status = IRQ_DISABLED; 594 - desc->action = 0; 595 - desc->depth = 1; 641 + if (i == 0) 642 + chip = &cobalt_irq_type; 643 + else if (i == CO_IRQ_IDE0) 644 + chip = &cobalt_irq_type; 645 + else if (i == CO_IRQ_IDE1) 646 + >chip = &cobalt_irq_type; 647 + else if (i == CO_IRQ_8259) 648 + chip = &piix4_master_irq_type; 649 + else if (i < CO_IRQ_APIC0) 650 + chip = &piix4_virtual_irq_type; 651 + else if (IS_CO_APIC(i)) 652 + chip = &cobalt_irq_type; 596 653 597 - if (i == 0) { 598 - desc->chip = &cobalt_irq_type; 599 - } 600 - else if (i == CO_IRQ_IDE0) { 601 - desc->chip = &cobalt_irq_type; 602 - } 603 - else if (i == CO_IRQ_IDE1) { 604 - desc->chip = &cobalt_irq_type; 605 - } 606 - else if (i == CO_IRQ_8259) { 607 - desc->chip = &piix4_master_irq_type; 608 - } 609 - else if (i < CO_IRQ_APIC0) { 610 - set_piix4_virtual_irq_type(); 611 - desc->chip = &piix4_virtual_irq_type; 612 - } 613 - else if (IS_CO_APIC(i)) { 614 - desc->chip = &cobalt_irq_type; 615 - } 654 + if (chip) 655 + set_irq_chip(i, chip); 616 656 } 617 657 618 658 setup_irq(CO_IRQ_8259, &master_action);