diff options
Diffstat (limited to 'arch/x86/kernel/devicetree.c')
| -rw-r--r-- | arch/x86/kernel/devicetree.c | 101 | 
1 files changed, 30 insertions, 71 deletions
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c index 52821799a70..3ae2ced4a87 100644 --- a/arch/x86/kernel/devicetree.c +++ b/arch/x86/kernel/devicetree.c @@ -4,6 +4,7 @@  #include <linux/bootmem.h>  #include <linux/export.h>  #include <linux/io.h> +#include <linux/irqdomain.h>  #include <linux/interrupt.h>  #include <linux/list.h>  #include <linux/of.h> @@ -17,64 +18,14 @@  #include <linux/initrd.h>  #include <asm/hpet.h> -#include <asm/irq_controller.h>  #include <asm/apic.h>  #include <asm/pci_x86.h>  __initdata u64 initial_dtb;  char __initdata cmd_line[COMMAND_LINE_SIZE]; -static LIST_HEAD(irq_domains); -static DEFINE_RAW_SPINLOCK(big_irq_lock);  int __initdata of_ioapic; -#ifdef CONFIG_X86_IO_APIC -static void add_interrupt_host(struct irq_domain *ih) -{ -	unsigned long flags; - -	raw_spin_lock_irqsave(&big_irq_lock, flags); -	list_add(&ih->l, &irq_domains); -	raw_spin_unlock_irqrestore(&big_irq_lock, flags); -} -#endif - -static struct irq_domain *get_ih_from_node(struct device_node *controller) -{ -	struct irq_domain *ih, *found = NULL; -	unsigned long flags; - -	raw_spin_lock_irqsave(&big_irq_lock, flags); -	list_for_each_entry(ih, &irq_domains, l) { -		if (ih->controller ==  controller) { -			found = ih; -			break; -		} -	} -	raw_spin_unlock_irqrestore(&big_irq_lock, flags); -	return found; -} - -unsigned int irq_create_of_mapping(struct device_node *controller, -				   const u32 *intspec, unsigned int intsize) -{ -	struct irq_domain *ih; -	u32 virq, type; -	int ret; - -	ih = get_ih_from_node(controller); -	if (!ih) -		return 0; -	ret = ih->xlate(ih, intspec, intsize, &virq, &type); -	if (ret) -		return 0; -	if (type == IRQ_TYPE_NONE) -		return virq; -	irq_set_irq_type(virq, type); -	return virq; -} -EXPORT_SYMBOL_GPL(irq_create_of_mapping); -  unsigned long pci_address_to_pio(phys_addr_t address)  {  	/* @@ -354,36 +305,43 @@ static struct of_ioapic_type of_ioapic_type[] =  	},  }; -static int ioapic_xlate(struct irq_domain *id, const u32 *intspec, u32 intsize, -			u32 *out_hwirq, u32 *out_type) +static int ioapic_xlate(struct irq_domain *domain, +			struct device_node *controller, +			const u32 *intspec, u32 intsize, +			irq_hw_number_t *out_hwirq, u32 *out_type)  { -	struct mp_ioapic_gsi *gsi_cfg;  	struct io_apic_irq_attr attr;  	struct of_ioapic_type *it; -	u32 line, idx, type; +	u32 line, idx; +	int rc; -	if (intsize < 2) +	if (WARN_ON(intsize < 2))  		return -EINVAL; -	line = *intspec; -	idx = (u32) id->priv; -	gsi_cfg = mp_ioapic_gsi_routing(idx); -	*out_hwirq = line + gsi_cfg->gsi_base; - -	intspec++; -	type = *intspec; +	line = intspec[0]; -	if (type >= ARRAY_SIZE(of_ioapic_type)) +	if (intspec[1] >= ARRAY_SIZE(of_ioapic_type))  		return -EINVAL; -	it = of_ioapic_type + type; -	*out_type = it->out_type; +	it = &of_ioapic_type[intspec[1]]; +	idx = (u32) domain->host_data;  	set_io_apic_irq_attr(&attr, idx, line, it->trigger, it->polarity); -	return io_apic_setup_irq_pin_once(*out_hwirq, cpu_to_node(0), &attr); +	rc = io_apic_setup_irq_pin_once(irq_find_mapping(domain, line), +					cpu_to_node(0), &attr); +	if (rc) +		return rc; + +	*out_hwirq = line; +	*out_type = it->out_type; +	return 0;  } +const struct irq_domain_ops ioapic_irq_domain_ops = { +	.xlate = ioapic_xlate, +}; +  static void __init ioapic_add_ofnode(struct device_node *np)  {  	struct resource r; @@ -399,13 +357,14 @@ static void __init ioapic_add_ofnode(struct device_node *np)  	for (i = 0; i < nr_ioapics; i++) {  		if (r.start == mpc_ioapic_addr(i)) {  			struct irq_domain *id; +			struct mp_ioapic_gsi *gsi_cfg; + +			gsi_cfg = mp_ioapic_gsi_routing(i); -			id = kzalloc(sizeof(*id), GFP_KERNEL); +			id = irq_domain_add_legacy(np, 32, gsi_cfg->gsi_base, 0, +						   &ioapic_irq_domain_ops, +						   (void*)i);  			BUG_ON(!id); -			id->controller = np; -			id->xlate = ioapic_xlate; -			id->priv = (void *)i; -			add_interrupt_host(id);  			return;  		}  	}  |