Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b4e51854 authored by Grant Likely's avatar Grant Likely
Browse files

irq_domain/x86: Convert x86 (embedded) to use common irq_domain



This patch removes the x86-specific definition of irq_domain and replaces
it with the common implementation.

Signed-off-by: default avatarGrant Likely <grant.likely@secretlab.ca>
Acked-by: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
parent 6d166fec
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -398,6 +398,7 @@ config X86_INTEL_CE
	select X86_REBOOTFIXUPS
	select OF
	select OF_EARLY_FLATTREE
	select IRQ_DOMAIN
	---help---
	  Select for the Intel CE media processor (CE4100) SOC.
	  This option compiles in support for the CE4100 SOC for settop
@@ -2076,6 +2077,7 @@ config OLPC
	select GPIOLIB
	select OF
	select OF_PROMTREE
	select IRQ_DOMAIN
	---help---
	  Add support for detecting the unique features of the OLPC
	  XO hardware.
+0 −12
Original line number Diff line number Diff line
#ifndef __IRQ_CONTROLLER__
#define __IRQ_CONTROLLER__

struct irq_domain {
	int (*xlate)(struct irq_domain *h, const u32 *intspec, u32 intsize,
			u32 *out_hwirq, u32 *out_type);
	void *priv;
	struct device_node *controller;
	struct list_head l;
};

#endif
+0 −10
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@
#include <asm/irq.h>
#include <linux/atomic.h>
#include <asm/setup.h>
#include <asm/irq_controller.h>

#ifdef CONFIG_OF
extern int of_ioapic;
@@ -43,15 +42,6 @@ extern char cmd_line[COMMAND_LINE_SIZE];
#define pci_address_to_pio pci_address_to_pio
unsigned long pci_address_to_pio(phys_addr_t addr);

/**
 * irq_dispose_mapping - Unmap an interrupt
 * @virq: linux virq number of the interrupt to unmap
 *
 * FIXME: We really should implement proper virq handling like power,
 * but that's going to be major surgery.
 */
static inline void irq_dispose_mapping(unsigned int virq) { }

#define HAVE_ARCH_DEVTREE_FIXUPS

#endif /* __ASSEMBLY__ */
+30 −71
Original line number Diff line number Diff line
@@ -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;
		}
	}
+2 −2
Original line number Diff line number Diff line
@@ -255,13 +255,13 @@ static inline int __init mdio_ofgpio_init(void)
	return platform_driver_register(&mdio_ofgpio_driver);
}

static inline void __exit mdio_ofgpio_exit(void)
static inline void mdio_ofgpio_exit(void)
{
	platform_driver_unregister(&mdio_ofgpio_driver);
}
#else
static inline int __init mdio_ofgpio_init(void) { return 0; }
static inline void __exit mdio_ofgpio_exit(void) { }
static inline void mdio_ofgpio_exit(void) { }
#endif /* CONFIG_OF_GPIO */

static struct platform_driver mdio_gpio_driver = {