aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2011-02-22 15:07:39 -0500
committerThomas Gleixner <tglx@linutronix.de>2011-02-23 16:27:53 -0500
commit19c4f5f7f7e9c5db89a91627af2a426cfb5568de (patch)
tree43bf09fbf1fb330dc324f7a302566dd24ba8e7aa
parentdf2634f43f5106947f3735a0b61a6527a4b278cd (diff)
x86: dtb: Add irq domain abstraction
The here introduced irq_domain abstraction represents a generic irq controller. It is a subset of powerpc's irq_host which is going to be renamed to irq_domain and then become generic. This implementation will be removed once it is generic. The xlate callback is resposible to parse irq informations like irq type and number and returns the hardware irq number which is reported by the hardware as active. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Tested-by: Dirk Brandewie <dirk.brandewie@gmail.com> Acked-by: Grant Likely <grant.likely@secretlab.ca> Cc: sodaville@linutronix.de Cc: devicetree-discuss@lists.ozlabs.org LKML-Reference: <1298405266-1624-5-git-send-email-bigeasy@linutronix.de> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--arch/x86/include/asm/irq_controller.h12
-rw-r--r--arch/x86/include/asm/prom.h2
-rw-r--r--arch/x86/kernel/devicetree.c46
3 files changed, 59 insertions, 1 deletions
diff --git a/arch/x86/include/asm/irq_controller.h b/arch/x86/include/asm/irq_controller.h
new file mode 100644
index 000000000000..423bbbddf36d
--- /dev/null
+++ b/arch/x86/include/asm/irq_controller.h
@@ -0,0 +1,12 @@
1#ifndef __IRQ_CONTROLLER__
2#define __IRQ_CONTROLLER__
3
4struct irq_domain {
5 int (*xlate)(struct irq_domain *h, const u32 *intspec, u32 intsize,
6 u32 *out_hwirq, u32 *out_type);
7 void *priv;
8 struct device_node *controller;
9 struct list_head l;
10};
11
12#endif
diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
index e46f2a2b57a1..83833ac33dd1 100644
--- a/arch/x86/include/asm/prom.h
+++ b/arch/x86/include/asm/prom.h
@@ -20,9 +20,11 @@
20#include <asm/irq.h> 20#include <asm/irq.h>
21#include <asm/atomic.h> 21#include <asm/atomic.h>
22#include <asm/setup.h> 22#include <asm/setup.h>
23#include <asm/irq_controller.h>
23 24
24#ifdef CONFIG_OF 25#ifdef CONFIG_OF
25extern void add_dtb(u64 data); 26extern void add_dtb(u64 data);
27void add_interrupt_host(struct irq_domain *ih);
26#else 28#else
27static inline void add_dtb(u64 data) { } 29static inline void add_dtb(u64 data) { }
28#endif 30#endif
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index 0b8f0daef933..ef98e4edada1 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -3,19 +3,63 @@
3 */ 3 */
4#include <linux/bootmem.h> 4#include <linux/bootmem.h>
5#include <linux/io.h> 5#include <linux/io.h>
6#include <linux/interrupt.h>
6#include <linux/list.h> 7#include <linux/list.h>
7#include <linux/of.h> 8#include <linux/of.h>
8#include <linux/of_fdt.h> 9#include <linux/of_fdt.h>
9#include <linux/of_platform.h> 10#include <linux/of_platform.h>
10#include <linux/slab.h> 11#include <linux/slab.h>
11 12
13#include <asm/irq_controller.h>
14
12char __initdata cmd_line[COMMAND_LINE_SIZE]; 15char __initdata cmd_line[COMMAND_LINE_SIZE];
16static LIST_HEAD(irq_domains);
17static DEFINE_RAW_SPINLOCK(big_irq_lock);
18
19void add_interrupt_host(struct irq_domain *ih)
20{
21 unsigned long flags;
22
23 raw_spin_lock_irqsave(&big_irq_lock, flags);
24 list_add(&ih->l, &irq_domains);
25 raw_spin_unlock_irqrestore(&big_irq_lock, flags);
26}
27
28static struct irq_domain *get_ih_from_node(struct device_node *controller)
29{
30 struct irq_domain *ih, *found = NULL;
31 unsigned long flags;
32
33 raw_spin_lock_irqsave(&big_irq_lock, flags);
34 list_for_each_entry(ih, &irq_domains, l) {
35 if (ih->controller == controller) {
36 found = ih;
37 break;
38 }
39 }
40 raw_spin_unlock_irqrestore(&big_irq_lock, flags);
41 return found;
42}
13 43
14unsigned int irq_create_of_mapping(struct device_node *controller, 44unsigned int irq_create_of_mapping(struct device_node *controller,
15 const u32 *intspec, unsigned int intsize) 45 const u32 *intspec, unsigned int intsize)
16{ 46{
17 return intspec[0]; 47 struct irq_domain *ih;
48 u32 virq, type;
49 int ret;
18 50
51 ih = get_ih_from_node(controller);
52 if (!ih)
53 return 0;
54 ret = ih->xlate(ih, intspec, intsize, &virq, &type);
55 if (ret)
56 return ret;
57 if (type == IRQ_TYPE_NONE)
58 return virq;
59 /* set the mask if it is different from current */
60 if (type == (irq_to_desc(virq)->status & IRQF_TRIGGER_MASK))
61 set_irq_type(virq, type);
62 return virq;
19} 63}
20EXPORT_SYMBOL_GPL(irq_create_of_mapping); 64EXPORT_SYMBOL_GPL(irq_create_of_mapping);
21 65