From a9c2989ee37e0360ce5cf9f6d53cb3bf691da035 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 22 Feb 2011 21:07:39 +0100 Subject: [PATCH] --- yaml --- r: 234923 b: refs/heads/master c: 19c4f5f7f7e9c5db89a91627af2a426cfb5568de h: refs/heads/master i: 234921: c03b2cc23446d163aea9ad9978d773aba23b0211 234919: 9d0d4d38f9d5ff8e1b1074769fd8f27ada7048cb v: v3 --- [refs] | 2 +- trunk/arch/x86/include/asm/irq_controller.h | 12 ++++++ trunk/arch/x86/include/asm/prom.h | 2 + trunk/arch/x86/kernel/devicetree.c | 46 ++++++++++++++++++++- 4 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 trunk/arch/x86/include/asm/irq_controller.h diff --git a/[refs] b/[refs] index d1e49cc3ed9a..81ff1807b8b8 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: df2634f43f5106947f3735a0b61a6527a4b278cd +refs/heads/master: 19c4f5f7f7e9c5db89a91627af2a426cfb5568de diff --git a/trunk/arch/x86/include/asm/irq_controller.h b/trunk/arch/x86/include/asm/irq_controller.h new file mode 100644 index 000000000000..423bbbddf36d --- /dev/null +++ b/trunk/arch/x86/include/asm/irq_controller.h @@ -0,0 +1,12 @@ +#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 diff --git a/trunk/arch/x86/include/asm/prom.h b/trunk/arch/x86/include/asm/prom.h index e46f2a2b57a1..83833ac33dd1 100644 --- a/trunk/arch/x86/include/asm/prom.h +++ b/trunk/arch/x86/include/asm/prom.h @@ -20,9 +20,11 @@ #include #include #include +#include #ifdef CONFIG_OF extern void add_dtb(u64 data); +void add_interrupt_host(struct irq_domain *ih); #else static inline void add_dtb(u64 data) { } #endif diff --git a/trunk/arch/x86/kernel/devicetree.c b/trunk/arch/x86/kernel/devicetree.c index 0b8f0daef933..ef98e4edada1 100644 --- a/trunk/arch/x86/kernel/devicetree.c +++ b/trunk/arch/x86/kernel/devicetree.c @@ -3,19 +3,63 @@ */ #include #include +#include #include #include #include #include #include +#include + char __initdata cmd_line[COMMAND_LINE_SIZE]; +static LIST_HEAD(irq_domains); +static DEFINE_RAW_SPINLOCK(big_irq_lock); + +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); +} + +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) { - return intspec[0]; + 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 ret; + if (type == IRQ_TYPE_NONE) + return virq; + /* set the mask if it is different from current */ + if (type == (irq_to_desc(virq)->status & IRQF_TRIGGER_MASK)) + set_irq_type(virq, type); + return virq; } EXPORT_SYMBOL_GPL(irq_create_of_mapping);