aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2012-07-11 12:24:31 -0400
committerGrant Likely <grant.likely@linaro.org>2013-06-10 06:52:09 -0400
commitcef5075c8c238ffd04c86a77a5a9bdbd18031137 (patch)
tree0163ec330ce81f90375ee1208c27d4e063a0e89f /include
parent0bb4afb45dd1add73ca643a865daa38716aeff0c (diff)
irqdomain: merge linear and tree reverse mappings.
Keeping them separate makes irq_domain more complex and adds a lot of code (as proven by the diffstat). Merging them simplifies the whole scheme. This change makes it so both the tree and linear methods can be used by the same irq_domain instance. If the hwirq is less than the ->linear_size, then the linear map is used to reverse map the hwirq. Otherwise the radix tree is used. The test for which map to use is no more expensive that the existing code, so the performance of fast path is preserved. It also means that complex interrupt controllers can use both the linear map and a tree in the same domain. This may be useful for an interrupt controller with a base set of core irqs and a large number of GPIOs which might be used as irqs. The linear map could cover the core irqs, and the tree used for thas irqs. The linear map could cover the core irqs, and the tree used for the gpios. v2: Drop reorganization of revmap data Signed-off-by: Grant Likely <grant.likely@secretlab.ca> Cc: Paul Mundt <lethal@linux-sh.org> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Rob Herring <rob.herring@calxeda.com>
Diffstat (limited to 'include')
-rw-r--r--include/linux/irqdomain.h18
1 files changed, 10 insertions, 8 deletions
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index e5e513c2d104..1cbb7413c121 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -75,7 +75,6 @@ struct irq_domain_chip_generic;
75 * @link: Element in global irq_domain list. 75 * @link: Element in global irq_domain list.
76 * @revmap_type: Method used for reverse mapping hwirq numbers to linux irq. This 76 * @revmap_type: Method used for reverse mapping hwirq numbers to linux irq. This
77 * will be one of the IRQ_DOMAIN_MAP_* values. 77 * will be one of the IRQ_DOMAIN_MAP_* values.
78 * @revmap_data: Revmap method specific data.
79 * @ops: pointer to irq_domain methods 78 * @ops: pointer to irq_domain methods
80 * @host_data: private data pointer for use by owner. Not touched by irq_domain 79 * @host_data: private data pointer for use by owner. Not touched by irq_domain
81 * core code. 80 * core code.
@@ -93,10 +92,9 @@ struct irq_domain {
93 92
94 /* type of reverse mapping_technique */ 93 /* type of reverse mapping_technique */
95 unsigned int revmap_type; 94 unsigned int revmap_type;
96 union { 95 struct {
97 struct { 96 struct {
98 unsigned int size; 97 unsigned int size;
99 unsigned int *revmap;
100 } linear; 98 } linear;
101 struct { 99 struct {
102 unsigned int max_irq; 100 unsigned int max_irq;
@@ -111,11 +109,13 @@ struct irq_domain {
111 struct device_node *of_node; 109 struct device_node *of_node;
112 /* Optional pointer to generic interrupt chips */ 110 /* Optional pointer to generic interrupt chips */
113 struct irq_domain_chip_generic *gc; 111 struct irq_domain_chip_generic *gc;
112
113 /* Linear reverse map */
114 unsigned int linear_revmap[];
114}; 115};
115 116
116#define IRQ_DOMAIN_MAP_NOMAP 1 /* no fast reverse mapping */ 117#define IRQ_DOMAIN_MAP_NOMAP 1 /* no fast reverse mapping */
117#define IRQ_DOMAIN_MAP_LINEAR 2 /* linear map of interrupts */ 118#define IRQ_DOMAIN_MAP_LINEAR 2 /* linear map of interrupts */
118#define IRQ_DOMAIN_MAP_TREE 3 /* radix tree */
119 119
120#ifdef CONFIG_IRQ_DOMAIN 120#ifdef CONFIG_IRQ_DOMAIN
121struct irq_domain *irq_domain_add_simple(struct device_node *of_node, 121struct irq_domain *irq_domain_add_simple(struct device_node *of_node,
@@ -137,10 +137,6 @@ struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
137 unsigned int max_irq, 137 unsigned int max_irq,
138 const struct irq_domain_ops *ops, 138 const struct irq_domain_ops *ops,
139 void *host_data); 139 void *host_data);
140struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
141 const struct irq_domain_ops *ops,
142 void *host_data);
143
144extern struct irq_domain *irq_find_host(struct device_node *node); 140extern struct irq_domain *irq_find_host(struct device_node *node);
145extern void irq_set_default_host(struct irq_domain *host); 141extern void irq_set_default_host(struct irq_domain *host);
146 142
@@ -152,6 +148,12 @@ static inline struct irq_domain *irq_domain_add_legacy_isa(
152 return irq_domain_add_legacy(of_node, NUM_ISA_INTERRUPTS, 0, 0, ops, 148 return irq_domain_add_legacy(of_node, NUM_ISA_INTERRUPTS, 0, 0, ops,
153 host_data); 149 host_data);
154} 150}
151static inline struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
152 const struct irq_domain_ops *ops,
153 void *host_data)
154{
155 return irq_domain_add_linear(of_node, 0, ops, host_data);
156}
155 157
156extern void irq_domain_remove(struct irq_domain *host); 158extern void irq_domain_remove(struct irq_domain *host);
157 159