mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 21:21:41 +00:00
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:
parent
6d166fec12
commit
b4e518547d
@ -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.
|
||||
|
@ -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
|
@ -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__ */
|
||||
|
@ -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;
|
||||
line = intspec[0];
|
||||
|
||||
intspec++;
|
||||
type = *intspec;
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
id->controller = np;
|
||||
id->xlate = ioapic_xlate;
|
||||
id->priv = (void *)i;
|
||||
add_interrupt_host(id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -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 = {
|
||||
|
Loading…
Reference in New Issue
Block a user