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: Grant Likely <grant.likely@secretlab.ca>
Acked-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
Grant Likely 2011-12-16 15:50:17 -07:00
parent 6d166fec12
commit b4e518547d
5 changed files with 34 additions and 95 deletions

View File

@ -398,6 +398,7 @@ config X86_INTEL_CE
select X86_REBOOTFIXUPS select X86_REBOOTFIXUPS
select OF select OF
select OF_EARLY_FLATTREE select OF_EARLY_FLATTREE
select IRQ_DOMAIN
---help--- ---help---
Select for the Intel CE media processor (CE4100) SOC. Select for the Intel CE media processor (CE4100) SOC.
This option compiles in support for the CE4100 SOC for settop This option compiles in support for the CE4100 SOC for settop
@ -2076,6 +2077,7 @@ config OLPC
select GPIOLIB select GPIOLIB
select OF select OF
select OF_PROMTREE select OF_PROMTREE
select IRQ_DOMAIN
---help--- ---help---
Add support for detecting the unique features of the OLPC Add support for detecting the unique features of the OLPC
XO hardware. XO hardware.

View File

@ -1,12 +0,0 @@
#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

View File

@ -21,7 +21,6 @@
#include <asm/irq.h> #include <asm/irq.h>
#include <linux/atomic.h> #include <linux/atomic.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/irq_controller.h>
#ifdef CONFIG_OF #ifdef CONFIG_OF
extern int of_ioapic; extern int of_ioapic;
@ -43,15 +42,6 @@ extern char cmd_line[COMMAND_LINE_SIZE];
#define pci_address_to_pio pci_address_to_pio #define pci_address_to_pio pci_address_to_pio
unsigned long pci_address_to_pio(phys_addr_t addr); 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 #define HAVE_ARCH_DEVTREE_FIXUPS
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */

View File

@ -4,6 +4,7 @@
#include <linux/bootmem.h> #include <linux/bootmem.h>
#include <linux/export.h> #include <linux/export.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/irqdomain.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/of.h> #include <linux/of.h>
@ -17,64 +18,14 @@
#include <linux/initrd.h> #include <linux/initrd.h>
#include <asm/hpet.h> #include <asm/hpet.h>
#include <asm/irq_controller.h>
#include <asm/apic.h> #include <asm/apic.h>
#include <asm/pci_x86.h> #include <asm/pci_x86.h>
__initdata u64 initial_dtb; __initdata u64 initial_dtb;
char __initdata cmd_line[COMMAND_LINE_SIZE]; char __initdata cmd_line[COMMAND_LINE_SIZE];
static LIST_HEAD(irq_domains);
static DEFINE_RAW_SPINLOCK(big_irq_lock);
int __initdata of_ioapic; 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) 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, static int ioapic_xlate(struct irq_domain *domain,
u32 *out_hwirq, u32 *out_type) 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 io_apic_irq_attr attr;
struct of_ioapic_type *it; struct of_ioapic_type *it;
u32 line, idx, type; u32 line, idx;
int rc;
if (intsize < 2) if (WARN_ON(intsize < 2))
return -EINVAL; return -EINVAL;
line = *intspec; line = intspec[0];
idx = (u32) id->priv;
gsi_cfg = mp_ioapic_gsi_routing(idx);
*out_hwirq = line + gsi_cfg->gsi_base;
intspec++; if (intspec[1] >= ARRAY_SIZE(of_ioapic_type))
type = *intspec;
if (type >= ARRAY_SIZE(of_ioapic_type))
return -EINVAL; return -EINVAL;
it = of_ioapic_type + type; it = &of_ioapic_type[intspec[1]];
*out_type = it->out_type;
idx = (u32) domain->host_data;
set_io_apic_irq_attr(&attr, idx, line, it->trigger, it->polarity); 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) static void __init ioapic_add_ofnode(struct device_node *np)
{ {
struct resource r; struct resource r;
@ -399,13 +357,14 @@ static void __init ioapic_add_ofnode(struct device_node *np)
for (i = 0; i < nr_ioapics; i++) { for (i = 0; i < nr_ioapics; i++) {
if (r.start == mpc_ioapic_addr(i)) { if (r.start == mpc_ioapic_addr(i)) {
struct irq_domain *id; struct irq_domain *id;
struct mp_ioapic_gsi *gsi_cfg;
id = kzalloc(sizeof(*id), GFP_KERNEL); gsi_cfg = mp_ioapic_gsi_routing(i);
id = irq_domain_add_legacy(np, 32, gsi_cfg->gsi_base, 0,
&ioapic_irq_domain_ops,
(void*)i);
BUG_ON(!id); BUG_ON(!id);
id->controller = np;
id->xlate = ioapic_xlate;
id->priv = (void *)i;
add_interrupt_host(id);
return; return;
} }
} }

View File

@ -255,13 +255,13 @@ static inline int __init mdio_ofgpio_init(void)
return platform_driver_register(&mdio_ofgpio_driver); 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); platform_driver_unregister(&mdio_ofgpio_driver);
} }
#else #else
static inline int __init mdio_ofgpio_init(void) { return 0; } 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 */ #endif /* CONFIG_OF_GPIO */
static struct platform_driver mdio_gpio_driver = { static struct platform_driver mdio_gpio_driver = {