diff options
Diffstat (limited to 'arch/x86/kernel/devicetree.c')
-rw-r--r-- | arch/x86/kernel/devicetree.c | 46 |
1 files changed, 45 insertions, 1 deletions
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 | |||
12 | char __initdata cmd_line[COMMAND_LINE_SIZE]; | 15 | char __initdata cmd_line[COMMAND_LINE_SIZE]; |
16 | static LIST_HEAD(irq_domains); | ||
17 | static DEFINE_RAW_SPINLOCK(big_irq_lock); | ||
18 | |||
19 | void 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 | |||
28 | static 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 | ||
14 | unsigned int irq_create_of_mapping(struct device_node *controller, | 44 | unsigned 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 | } |
20 | EXPORT_SYMBOL_GPL(irq_create_of_mapping); | 64 | EXPORT_SYMBOL_GPL(irq_create_of_mapping); |
21 | 65 | ||