aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2012-08-01 04:14:52 -0400
committerPaul Mundt <lethal@linux-sh.org>2012-08-01 04:14:52 -0400
commitf38770477a30d03b6296570071ca2fcd6d3a5f11 (patch)
tree3dd11460c4115d97137a6ff82683e593a3813607
parent1ca8fe38a6c958babe6571e39cb0115a40b94603 (diff)
parent1d6a21b0a672fb29b01ccf397d478e0541e17716 (diff)
Merge branch 'common/irqdomain' into sh-latest
-rw-r--r--Documentation/IRQ-domain.txt5
-rw-r--r--arch/powerpc/sysdev/xics/icp-hv.c2
-rw-r--r--arch/powerpc/sysdev/xics/icp-native.c2
-rw-r--r--arch/powerpc/sysdev/xics/xics-common.c3
-rw-r--r--drivers/sh/intc/Kconfig4
-rw-r--r--drivers/sh/intc/Makefile2
-rw-r--r--drivers/sh/intc/core.c11
-rw-r--r--drivers/sh/intc/internals.h5
-rw-r--r--drivers/sh/intc/irqdomain.c68
-rw-r--r--include/linux/irqdomain.h28
-rw-r--r--include/linux/of.h15
-rw-r--r--kernel/irq/irqdomain.c362
12 files changed, 333 insertions, 174 deletions
diff --git a/Documentation/IRQ-domain.txt b/Documentation/IRQ-domain.txt
index 27dcaabfb4db..1401cece745a 100644
--- a/Documentation/IRQ-domain.txt
+++ b/Documentation/IRQ-domain.txt
@@ -93,6 +93,7 @@ Linux IRQ number into the hardware.
93Most drivers cannot use this mapping. 93Most drivers cannot use this mapping.
94 94
95==== Legacy ==== 95==== Legacy ====
96irq_domain_add_simple()
96irq_domain_add_legacy() 97irq_domain_add_legacy()
97irq_domain_add_legacy_isa() 98irq_domain_add_legacy_isa()
98 99
@@ -115,3 +116,7 @@ The legacy map should only be used if fixed IRQ mappings must be
115supported. For example, ISA controllers would use the legacy map for 116supported. For example, ISA controllers would use the legacy map for
116mapping Linux IRQs 0-15 so that existing ISA drivers get the correct IRQ 117mapping Linux IRQs 0-15 so that existing ISA drivers get the correct IRQ
117numbers. 118numbers.
119
120Most users of legacy mappings should use irq_domain_add_simple() which
121will use a legacy domain only if an IRQ range is supplied by the
122system and will otherwise use a linear domain mapping.
diff --git a/arch/powerpc/sysdev/xics/icp-hv.c b/arch/powerpc/sysdev/xics/icp-hv.c
index 253dce98c16e..14469cf9df68 100644
--- a/arch/powerpc/sysdev/xics/icp-hv.c
+++ b/arch/powerpc/sysdev/xics/icp-hv.c
@@ -111,7 +111,7 @@ static unsigned int icp_hv_get_irq(void)
111 if (vec == XICS_IRQ_SPURIOUS) 111 if (vec == XICS_IRQ_SPURIOUS)
112 return NO_IRQ; 112 return NO_IRQ;
113 113
114 irq = irq_radix_revmap_lookup(xics_host, vec); 114 irq = irq_find_mapping(xics_host, vec);
115 if (likely(irq != NO_IRQ)) { 115 if (likely(irq != NO_IRQ)) {
116 xics_push_cppr(vec); 116 xics_push_cppr(vec);
117 return irq; 117 return irq;
diff --git a/arch/powerpc/sysdev/xics/icp-native.c b/arch/powerpc/sysdev/xics/icp-native.c
index 4c79b6fbee1c..48861d3fcd07 100644
--- a/arch/powerpc/sysdev/xics/icp-native.c
+++ b/arch/powerpc/sysdev/xics/icp-native.c
@@ -119,7 +119,7 @@ static unsigned int icp_native_get_irq(void)
119 if (vec == XICS_IRQ_SPURIOUS) 119 if (vec == XICS_IRQ_SPURIOUS)
120 return NO_IRQ; 120 return NO_IRQ;
121 121
122 irq = irq_radix_revmap_lookup(xics_host, vec); 122 irq = irq_find_mapping(xics_host, vec);
123 if (likely(irq != NO_IRQ)) { 123 if (likely(irq != NO_IRQ)) {
124 xics_push_cppr(vec); 124 xics_push_cppr(vec);
125 return irq; 125 return irq;
diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c
index cd1d18db92c6..9049d9f44485 100644
--- a/arch/powerpc/sysdev/xics/xics-common.c
+++ b/arch/powerpc/sysdev/xics/xics-common.c
@@ -329,9 +329,6 @@ static int xics_host_map(struct irq_domain *h, unsigned int virq,
329 329
330 pr_devel("xics: map virq %d, hwirq 0x%lx\n", virq, hw); 330 pr_devel("xics: map virq %d, hwirq 0x%lx\n", virq, hw);
331 331
332 /* Insert the interrupt mapping into the radix tree for fast lookup */
333 irq_radix_revmap_insert(xics_host, virq, hw);
334
335 /* They aren't all level sensitive but we just don't really know */ 332 /* They aren't all level sensitive but we just don't really know */
336 irq_set_status_flags(virq, IRQ_LEVEL); 333 irq_set_status_flags(virq, IRQ_LEVEL);
337 334
diff --git a/drivers/sh/intc/Kconfig b/drivers/sh/intc/Kconfig
index c88cbccc62b0..a305731742a9 100644
--- a/drivers/sh/intc/Kconfig
+++ b/drivers/sh/intc/Kconfig
@@ -1,3 +1,7 @@
1config SH_INTC
2 def_bool y
3 select IRQ_DOMAIN
4
1comment "Interrupt controller options" 5comment "Interrupt controller options"
2 6
3config INTC_USERIMASK 7config INTC_USERIMASK
diff --git a/drivers/sh/intc/Makefile b/drivers/sh/intc/Makefile
index 44f006d09471..54ec2a0643df 100644
--- a/drivers/sh/intc/Makefile
+++ b/drivers/sh/intc/Makefile
@@ -1,4 +1,4 @@
1obj-y := access.o chip.o core.o handle.o virq.o 1obj-y := access.o chip.o core.o handle.o irqdomain.o virq.o
2 2
3obj-$(CONFIG_INTC_BALANCING) += balancing.o 3obj-$(CONFIG_INTC_BALANCING) += balancing.o
4obj-$(CONFIG_INTC_USERIMASK) += userimask.o 4obj-$(CONFIG_INTC_USERIMASK) += userimask.o
diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c
index 7e562ccb6997..2374468615ed 100644
--- a/drivers/sh/intc/core.c
+++ b/drivers/sh/intc/core.c
@@ -25,6 +25,7 @@
25#include <linux/stat.h> 25#include <linux/stat.h>
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <linux/sh_intc.h> 27#include <linux/sh_intc.h>
28#include <linux/irqdomain.h>
28#include <linux/device.h> 29#include <linux/device.h>
29#include <linux/syscore_ops.h> 30#include <linux/syscore_ops.h>
30#include <linux/list.h> 31#include <linux/list.h>
@@ -310,6 +311,8 @@ int __init register_intc_controller(struct intc_desc *desc)
310 311
311 BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */ 312 BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */
312 313
314 intc_irq_domain_init(d, hw);
315
313 /* register the vectors one by one */ 316 /* register the vectors one by one */
314 for (i = 0; i < hw->nr_vectors; i++) { 317 for (i = 0; i < hw->nr_vectors; i++) {
315 struct intc_vect *vect = hw->vectors + i; 318 struct intc_vect *vect = hw->vectors + i;
@@ -319,8 +322,8 @@ int __init register_intc_controller(struct intc_desc *desc)
319 if (!vect->enum_id) 322 if (!vect->enum_id)
320 continue; 323 continue;
321 324
322 res = irq_alloc_desc_at(irq, numa_node_id()); 325 res = irq_create_identity_mapping(d->domain, irq);
323 if (res != irq && res != -EEXIST) { 326 if (unlikely(res)) {
324 pr_err("can't get irq_desc for %d\n", irq); 327 pr_err("can't get irq_desc for %d\n", irq);
325 continue; 328 continue;
326 } 329 }
@@ -340,8 +343,8 @@ int __init register_intc_controller(struct intc_desc *desc)
340 * IRQ support, each vector still needs to have 343 * IRQ support, each vector still needs to have
341 * its own backing irq_desc. 344 * its own backing irq_desc.
342 */ 345 */
343 res = irq_alloc_desc_at(irq2, numa_node_id()); 346 res = irq_create_identity_mapping(d->domain, irq2);
344 if (res != irq2 && res != -EEXIST) { 347 if (unlikely(res)) {
345 pr_err("can't get irq_desc for %d\n", irq2); 348 pr_err("can't get irq_desc for %d\n", irq2);
346 continue; 349 continue;
347 } 350 }
diff --git a/drivers/sh/intc/internals.h b/drivers/sh/intc/internals.h
index f034a979a16f..7dff08e2a071 100644
--- a/drivers/sh/intc/internals.h
+++ b/drivers/sh/intc/internals.h
@@ -1,5 +1,6 @@
1#include <linux/sh_intc.h> 1#include <linux/sh_intc.h>
2#include <linux/irq.h> 2#include <linux/irq.h>
3#include <linux/irqdomain.h>
3#include <linux/list.h> 4#include <linux/list.h>
4#include <linux/kernel.h> 5#include <linux/kernel.h>
5#include <linux/types.h> 6#include <linux/types.h>
@@ -66,6 +67,7 @@ struct intc_desc_int {
66 unsigned int nr_sense; 67 unsigned int nr_sense;
67 struct intc_window *window; 68 struct intc_window *window;
68 unsigned int nr_windows; 69 unsigned int nr_windows;
70 struct irq_domain *domain;
69 struct irq_chip chip; 71 struct irq_chip chip;
70 bool skip_suspend; 72 bool skip_suspend;
71}; 73};
@@ -187,6 +189,9 @@ unsigned long intc_get_ack_handle(unsigned int irq);
187void intc_enable_disable_enum(struct intc_desc *desc, struct intc_desc_int *d, 189void intc_enable_disable_enum(struct intc_desc *desc, struct intc_desc_int *d,
188 intc_enum enum_id, int enable); 190 intc_enum enum_id, int enable);
189 191
192/* irqdomain.c */
193void intc_irq_domain_init(struct intc_desc_int *d, struct intc_hw_desc *hw);
194
190/* virq.c */ 195/* virq.c */
191void intc_subgroup_init(struct intc_desc *desc, struct intc_desc_int *d); 196void intc_subgroup_init(struct intc_desc *desc, struct intc_desc_int *d);
192void intc_irq_xlate_set(unsigned int irq, intc_enum id, struct intc_desc_int *d); 197void intc_irq_xlate_set(unsigned int irq, intc_enum id, struct intc_desc_int *d);
diff --git a/drivers/sh/intc/irqdomain.c b/drivers/sh/intc/irqdomain.c
new file mode 100644
index 000000000000..3968f1c3c5c3
--- /dev/null
+++ b/drivers/sh/intc/irqdomain.c
@@ -0,0 +1,68 @@