aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@linaro.org>2013-06-09 20:06:02 -0400
committerGrant Likely <grant.likely@linaro.org>2013-06-24 09:01:42 -0400
commitddaf144c61da45ae5c49ae38556c3ac4524f9318 (patch)
tree6992bedc5f2a620f7b4e4dadfce76658e7667d35 /include/linux
parent1400ea86025a22862f97e7fe544433751b43ecec (diff)
irqdomain: Refactor irq_domain_associate_many()
Originally, irq_domain_associate_many() was designed to unwind the mapped irqs on a failure of any individual association. However, that proved to be a problem with certain IRQ controllers. Some of them only support a subset of irqs, and will fail when attempting to map a reserved IRQ. In those cases we want to map as many IRQs as possible, so instead it is better for irq_domain_associate_many() to make a best-effort attempt to map irqs, but not fail if any or all of them don't succeed. If a caller really cares about how many irqs got associated, then it should instead go back and check that all of the irqs is cares about were mapped. The original design open-coded the individual association code into the body of irq_domain_associate_many(), but with no longer needing to unwind associations, the code becomes simpler to split out irq_domain_associate() to contain the bulk of the logic, and irq_domain_associate_many() to be a simple loop wrapper. This patch also adds a new error check to the associate path to make sure it isn't called for an irq larger than the controller can handle, and adds locking so that the irq_domain_mutex is held while setting up a new association. v3: Fixup missing change to irq_domain_add_tree() v2: Fixup x86 warning. irq_domain_associate_many() no longer returns an error code, but reports errors to the printk log directly. In the majority of cases we don't actually want to fail if there is a problem, but rather log it and still try to boot the system. Signed-off-by: Grant Likely <grant.likely@linaro.org> irqdomain: Fix flubbed irq_domain_associate_many refactoring commit d39046ec72, "irqdomain: Refactor irq_domain_associate_many()" was missing the following hunk which causes a boot failure on anything using irq_domain_add_tree() to allocate an irq domain. Signed-off-by: Grant Likely <grant.likely@linaro.org> Cc: Michael Neuling <mikey@neuling.org> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>, Cc: Thomas Gleixner <tglx@linutronix.de>, Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/irqdomain.h24
1 files changed, 11 insertions, 13 deletions
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index fd4b26f8f44c..208d1352c40a 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -103,6 +103,7 @@ struct irq_domain {
103 struct irq_domain_chip_generic *gc; 103 struct irq_domain_chip_generic *gc;
104 104
105 /* reverse map data. The linear map gets appended to the irq_domain */ 105 /* reverse map data. The linear map gets appended to the irq_domain */
106 irq_hw_number_t hwirq_max;
106 unsigned int revmap_direct_max_irq; 107 unsigned int revmap_direct_max_irq;
107 unsigned int revmap_size; 108 unsigned int revmap_size;
108 struct radix_tree_root revmap_tree; 109 struct radix_tree_root revmap_tree;
@@ -110,8 +111,8 @@ struct irq_domain {
110}; 111};
111 112
112#ifdef CONFIG_IRQ_DOMAIN 113#ifdef CONFIG_IRQ_DOMAIN
113struct irq_domain *__irq_domain_add(struct device_node *of_node, 114struct irq_domain *__irq_domain_add(struct device_node *of_node, int size,
114 int size, int direct_max, 115 irq_hw_number_t hwirq_max, int direct_max,
115 const struct irq_domain_ops *ops, 116 const struct irq_domain_ops *ops,
116 void *host_data); 117 void *host_data);
117struct irq_domain *irq_domain_add_simple(struct device_node *of_node, 118struct irq_domain *irq_domain_add_simple(struct device_node *of_node,
@@ -140,14 +141,14 @@ static inline struct irq_domain *irq_domain_add_linear(struct device_node *of_no
140 const struct irq_domain_ops *ops, 141 const struct irq_domain_ops *ops,
141 void *host_data) 142 void *host_data)
142{ 143{
143 return __irq_domain_add(of_node, size, 0, ops, host_data); 144 return __irq_domain_add(of_node, size, size, 0, ops, host_data);
144} 145}
145static inline struct irq_domain *irq_domain_add_nomap(struct device_node *of_node, 146static inline struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
146 unsigned int max_irq, 147 unsigned int max_irq,
147 const struct irq_domain_ops *ops, 148 const struct irq_domain_ops *ops,
148 void *host_data) 149 void *host_data)
149{ 150{
150 return __irq_domain_add(of_node, 0, max_irq, ops, host_data); 151 return __irq_domain_add(of_node, 0, max_irq, max_irq, ops, host_data);
151} 152}
152static inline struct irq_domain *irq_domain_add_legacy_isa( 153static inline struct irq_domain *irq_domain_add_legacy_isa(
153 struct device_node *of_node, 154 struct device_node *of_node,
@@ -161,19 +162,16 @@ static inline struct irq_domain *irq_domain_add_tree(struct device_node *of_node
161 const struct irq_domain_ops *ops, 162 const struct irq_domain_ops *ops,
162 void *host_data) 163 void *host_data)
163{ 164{
164 return irq_domain_add_linear(of_node, 0, ops, host_data); 165 return __irq_domain_add(of_node, 0, ~0, 0, ops, host_data);
165} 166}
166 167
167extern void irq_domain_remove(struct irq_domain *host); 168extern void irq_domain_remove(struct irq_domain *host);
168 169
169extern int irq_domain_associate_many(struct irq_domain *domain, 170extern int irq_domain_associate(struct irq_domain *domain, unsigned int irq,
170 unsigned int irq_base, 171 irq_hw_number_t hwirq);
171 irq_hw_number_t hwirq_base, int count); 172extern void irq_domain_associate_many(struct irq_domain *domain,
172static inline int irq_domain_associate(struct irq_domain *domain, unsigned int irq, 173 unsigned int irq_base,
173 irq_hw_number_t hwirq) 174 irq_hw_number_t hwirq_base, int count);
174{
175 return irq_domain_associate_many(domain, irq, hwirq, 1);
176}
177 175
178extern unsigned int irq_create_mapping(struct irq_domain *host, 176extern unsigned int irq_create_mapping(struct irq_domain *host,
179 irq_hw_number_t hwirq); 177 irq_hw_number_t hwirq);