aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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--include/linux/irqdomain.h28
-rw-r--r--include/linux/of.h15
-rw-r--r--kernel/irq/irqdomain.c362
7 files changed, 248 insertions, 169 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/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 5abb533eb8eb..0d5b17bf5e51 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -112,6 +112,11 @@ struct irq_domain {
112}; 112};
113 113
114#ifdef CONFIG_IRQ_DOMAIN 114#ifdef CONFIG_IRQ_DOMAIN
115struct irq_domain *irq_domain_add_simple(struct device_node *of_node,
116 unsigned int size,
117 unsigned int first_irq,
118 const struct irq_domain_ops *ops,
119 void *host_data);
115struct irq_domain *irq_domain_add_legacy(struct device_node *of_node, 120struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
116 unsigned int size, 121 unsigned int size,
117 unsigned int first_irq, 122 unsigned int first_irq,
@@ -144,16 +149,31 @@ static inline struct irq_domain *irq_domain_add_legacy_isa(
144 149
145extern void irq_domain_remove(struct irq_domain *host); 150extern void irq_domain_remove(struct irq_domain *host);
146 151
152extern int irq_domain_associate_many(struct irq_domain *domain,
153 unsigned int irq_base,
154 irq_hw_number_t hwirq_base, int count);
155static inline int irq_domain_associate(struct irq_domain *domain, unsigned int irq,
156 irq_hw_number_t hwirq)
157{
158 return irq_domain_associate_many(domain, irq, hwirq, 1);
159}
160
147extern unsigned int irq_create_mapping(struct irq_domain *host, 161extern unsigned int irq_create_mapping(struct irq_domain *host,
148 irq_hw_number_t hwirq); 162 irq_hw_number_t hwirq);
149extern void irq_dispose_mapping(unsigned int virq); 163extern void irq_dispose_mapping(unsigned int virq);
150extern unsigned int irq_find_mapping(struct irq_domain *host, 164extern unsigned int irq_find_mapping(struct irq_domain *host,
151 irq_hw_number_t hwirq); 165 irq_hw_number_t hwirq);
152extern unsigned int irq_create_direct_mapping(struct irq_domain *host); 166extern unsigned int irq_create_direct_mapping(struct irq_domain *host);
153extern void irq_radix_revmap_insert(struct irq_domain *host, unsigned int virq, 167extern int irq_create_strict_mappings(struct irq_domain *domain,
154 irq_hw_number_t hwirq); 168 unsigned int irq_base,
155extern unsigned int irq_radix_revmap_lookup(struct irq_domain *host, 169 irq_hw_number_t hwirq_base, int count);
156 irq_hw_number_t hwirq); 170
171static inline int irq_create_identity_mapping(struct irq_domain *host,
172 irq_hw_number_t hwirq)
173{
174 return irq_create_strict_mappings(host, hwirq, hwirq, 1);
175}
176
157extern unsigned int irq_linear_revmap(struct irq_domain *host, 177extern unsigned int irq_linear_revmap(struct irq_domain *host,
158 irq_hw_number_t hwirq); 178 irq_hw_number_t hwirq);
159 179
diff --git a/include/linux/of.h b/include/linux/of.h
index 42c2a58328c1..5919ee33f2b7 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -21,6 +21,7 @@
21#include <linux/kref.h> 21#include <linux/kref.h>
22#include <linux/mod_devicetable.h> 22#include <linux/mod_devicetable.h>
23#include <linux/spinlock.h> 23#include <linux/spinlock.h>
24#include <linux/topology.h>
24 25
25#include <asm/byteorder.h> 26#include <asm/byteorder.h>
26#include <asm/errno.h> 27#include <asm/errno.h>
@@ -158,11 +159,6 @@ static inline unsigned long of_read_ulong(const __be32 *cell, int size)
158 159
159#define OF_BAD_ADDR ((u64)-1) 160#define OF_BAD_ADDR ((u64)-1)
160 161
161#ifndef of_node_to_nid
162static inline int of_node_to_nid(struct device_node *np) { return -1; }
163#define of_node_to_nid of_node_to_nid
164#endif
165
166static inline const char* of_node_full_name(struct device_node *np) 162static inline const char* of_node_full_name(struct device_node *np)
167{ 163{
168 return np ? np->full_name : "<no-node>"; 164 return np ? np->full_name : "<no-node>";
@@ -427,6 +423,15 @@ static inline int of_machine_is_compatible(const char *compat)
427 while (0) 423 while (0)
428#endif /* CONFIG_OF */ 424#endif /* CONFIG_OF */
429 425
426#ifndef of_node_to_nid
427static inline int of_node_to_nid(struct device_node *np)
428{
429 return numa_node_id();
430}
431
432#define of_node_to_nid of_node_to_nid
433#endif
434
430/** 435/**
431 * of_property_read_bool - Findfrom a property 436 * of_property_read_bool - Findfrom a property
432 * @np: device node from which the property value is to be read. 437 * @np: device node from which the property value is to be read.
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 38c5eb839c92..49a77727db42 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -10,6 +10,7 @@
10#include <linux/mutex.h> 10#include <linux/mutex.h>
11#include <linux/of.h> 11#include <linux/of.h>
12#include <linux/of_address.h> 12#include <linux/of_address.h>
13#include <linux/topology.h>
13#include <linux/seq_file.h> 14#include <linux/seq_file.h>
14#include <linux/slab.h> 15#include <linux/slab.h>
15#include <linux/smp.h> 16#include <linux/smp.h>
@@ -45,7 +46,8 @@ static struct irq_domain *irq_domain_alloc(struct device_node *of_node,
45{ 46{
46 struct irq_domain *domain; 47 struct irq_domain *domain;
47 48
48 domain = kzalloc(sizeof(*domain), GFP_KERNEL); 49 domain = kzalloc_node(sizeof(*domain), GFP_KERNEL,
50 of_node_to_nid(of_node));
49 if (WARN_ON(!domain)) 51 if (WARN_ON(!domain))
50 return NULL; 52