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

x86/apic: Add select() method on vector irqdomain

This will be used to select the irqdomain for I/O-APIC and HPET.

Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20201024213535.443185-24-dwmw2@infradead.org

authored by

David Woodhouse and committed by
Thomas Gleixner
6452ea2a 2cbd5a45

+46
+3
arch/x86/include/asm/irqdomain.h
··· 12 12 X86_IRQ_ALLOC_LEGACY = 0x2, 13 13 }; 14 14 15 + extern int x86_fwspec_is_ioapic(struct irq_fwspec *fwspec); 16 + extern int x86_fwspec_is_hpet(struct irq_fwspec *fwspec); 17 + 15 18 extern struct irq_domain *x86_vector_domain; 16 19 17 20 extern void init_irq_alloc_info(struct irq_alloc_info *info,
+43
arch/x86/kernel/apic/vector.c
··· 636 636 } 637 637 #endif 638 638 639 + int x86_fwspec_is_ioapic(struct irq_fwspec *fwspec) 640 + { 641 + if (fwspec->param_count != 1) 642 + return 0; 643 + 644 + if (is_fwnode_irqchip(fwspec->fwnode)) { 645 + const char *fwname = fwnode_get_name(fwspec->fwnode); 646 + return fwname && !strncmp(fwname, "IO-APIC-", 8) && 647 + simple_strtol(fwname+8, NULL, 10) == fwspec->param[0]; 648 + } 649 + return to_of_node(fwspec->fwnode) && 650 + of_device_is_compatible(to_of_node(fwspec->fwnode), 651 + "intel,ce4100-ioapic"); 652 + } 653 + 654 + int x86_fwspec_is_hpet(struct irq_fwspec *fwspec) 655 + { 656 + if (fwspec->param_count != 1) 657 + return 0; 658 + 659 + if (is_fwnode_irqchip(fwspec->fwnode)) { 660 + const char *fwname = fwnode_get_name(fwspec->fwnode); 661 + return fwname && !strncmp(fwname, "HPET-MSI-", 9) && 662 + simple_strtol(fwname+9, NULL, 10) == fwspec->param[0]; 663 + } 664 + return 0; 665 + } 666 + 667 + static int x86_vector_select(struct irq_domain *d, struct irq_fwspec *fwspec, 668 + enum irq_domain_bus_token bus_token) 669 + { 670 + /* 671 + * HPET and I/OAPIC cannot be parented in the vector domain 672 + * if IRQ remapping is enabled. APIC IDs above 15 bits are 673 + * only permitted if IRQ remapping is enabled, so check that. 674 + */ 675 + if (apic->apic_id_valid(32768)) 676 + return 0; 677 + 678 + return x86_fwspec_is_ioapic(fwspec) || x86_fwspec_is_hpet(fwspec); 679 + } 680 + 639 681 static const struct irq_domain_ops x86_vector_domain_ops = { 682 + .select = x86_vector_select, 640 683 .alloc = x86_vector_alloc_irqs, 641 684 .free = x86_vector_free_irqs, 642 685 .activate = x86_vector_activate,