Commit 6452ea2a authored by David Woodhouse's avatar David Woodhouse Committed by Thomas Gleixner
Browse files

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: default avatarDavid Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20201024213535.443185-24-dwmw2@infradead.org
parent 2cbd5a45
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -12,6 +12,9 @@ enum {
	X86_IRQ_ALLOC_LEGACY				= 0x2,
};

extern int x86_fwspec_is_ioapic(struct irq_fwspec *fwspec);
extern int x86_fwspec_is_hpet(struct irq_fwspec *fwspec);

extern struct irq_domain *x86_vector_domain;

extern void init_irq_alloc_info(struct irq_alloc_info *info,
+43 −0
Original line number Diff line number Diff line
@@ -636,7 +636,50 @@ static void x86_vector_debug_show(struct seq_file *m, struct irq_domain *d,
}
#endif

int x86_fwspec_is_ioapic(struct irq_fwspec *fwspec)
{
	if (fwspec->param_count != 1)
		return 0;

	if (is_fwnode_irqchip(fwspec->fwnode)) {
		const char *fwname = fwnode_get_name(fwspec->fwnode);
		return fwname && !strncmp(fwname, "IO-APIC-", 8) &&
			simple_strtol(fwname+8, NULL, 10) == fwspec->param[0];
	}
	return to_of_node(fwspec->fwnode) &&
		of_device_is_compatible(to_of_node(fwspec->fwnode),
					"intel,ce4100-ioapic");
}

int x86_fwspec_is_hpet(struct irq_fwspec *fwspec)
{
	if (fwspec->param_count != 1)
		return 0;

	if (is_fwnode_irqchip(fwspec->fwnode)) {
		const char *fwname = fwnode_get_name(fwspec->fwnode);
		return fwname && !strncmp(fwname, "HPET-MSI-", 9) &&
			simple_strtol(fwname+9, NULL, 10) == fwspec->param[0];
	}
	return 0;
}

static int x86_vector_select(struct irq_domain *d, struct irq_fwspec *fwspec,
			     enum irq_domain_bus_token bus_token)
{
	/*
	 * HPET and I/OAPIC cannot be parented in the vector domain
	 * if IRQ remapping is enabled. APIC IDs above 15 bits are
	 * only permitted if IRQ remapping is enabled, so check that.
	 */
	if (apic->apic_id_valid(32768))
		return 0;

	return x86_fwspec_is_ioapic(fwspec) || x86_fwspec_is_hpet(fwspec);
}

static const struct irq_domain_ops x86_vector_domain_ops = {
	.select		= x86_vector_select,
	.alloc		= x86_vector_alloc_irqs,
	.free		= x86_vector_free_irqs,
	.activate	= x86_vector_activate,