Commit b4e51854 authored by Grant Likely's avatar Grant Likely

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
...@@ -398,6 +398,7 @@ config X86_INTEL_CE ...@@ -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 ...@@ -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.
......
#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
...@@ -21,7 +21,6 @@ ...@@ -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]; ...@@ -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__ */
......
...@@ -4,6 +4,7 @@ ...@@ -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 @@ ...@@ -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[] = ...@@ -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++;
type = *intspec;
if (type >= ARRAY_SIZE(of_ioapic_type)) if (intspec[1] >= 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) ...@@ -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;
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); BUG_ON(!id);
id->controller = np;
id->xlate = ioapic_xlate;
id->priv = (void *)i;
add_interrupt_host(id);
return; return;
} }
} }
......
...@@ -255,13 +255,13 @@ static inline int __init mdio_ofgpio_init(void) ...@@ -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 = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment