aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/irqchip
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2013-04-10 09:31:11 -0400
committerArnd Bergmann <arnd@arndb.de>2013-04-19 17:00:41 -0400
commitd34f03d4a1e4e56f5944186c2e74cbed58b27090 (patch)
treed5301a4dae852687efcaf5f8c87e61e5085ada3a /drivers/irqchip
parent6761dcfe8c42b55076753bc8bea7b5dcbfb445c0 (diff)
irqchip: exynos: allocate combiner_data dynamically
The number of combiners on a given SoC is a platform specific constant, and we cannot encode this number on a multiplatform kernel since the header file defining it is not available. Allocating the structure dynamically ends up cleaner anyway since we keep all the data local. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Cc: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'drivers/irqchip')
-rw-r--r--drivers/irqchip/exynos-combiner.c36
1 files changed, 23 insertions, 13 deletions
diff --git a/drivers/irqchip/exynos-combiner.c b/drivers/irqchip/exynos-combiner.c
index d8683836ee1e..7fcdeee869ce 100644
--- a/drivers/irqchip/exynos-combiner.c
+++ b/drivers/irqchip/exynos-combiner.c
@@ -12,6 +12,7 @@
12#include <linux/export.h> 12#include <linux/export.h>
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/io.h> 14#include <linux/io.h>
15#include <linux/slab.h>
15#include <linux/irqdomain.h> 16#include <linux/irqdomain.h>
16#include <linux/of_address.h> 17#include <linux/of_address.h>
17#include <linux/of_irq.h> 18#include <linux/of_irq.h>
@@ -37,7 +38,6 @@ struct combiner_chip_data {
37}; 38};
38 39
39static struct irq_domain *combiner_irq_domain; 40static struct irq_domain *combiner_irq_domain;
40static struct combiner_chip_data combiner_data[MAX_COMBINER_NR];
41 41
42static inline void __iomem *combiner_base(struct irq_data *data) 42static inline void __iomem *combiner_base(struct irq_data *data)
43{ 43{
@@ -114,26 +114,26 @@ static struct irq_chip combiner_chip = {
114#endif 114#endif
115}; 115};
116 116
117static void __init combiner_cascade_irq(unsigned int combiner_nr, 117static void __init combiner_cascade_irq(struct combiner_chip_data *combiner_data,
118 unsigned int irq) 118 unsigned int irq)
119{ 119{
120 if (irq_set_handler_data(irq, &combiner_data[combiner_nr]) != 0) 120 if (irq_set_handler_data(irq, combiner_data) != 0)
121 BUG(); 121 BUG();
122 irq_set_chained_handler(irq, combiner_handle_cascade_irq); 122 irq_set_chained_handler(irq, combiner_handle_cascade_irq);
123} 123}
124 124
125static void __init combiner_init_one(unsigned int combiner_nr, 125static void __init combiner_init_one(struct combiner_chip_data *combiner_data,
126 unsigned int combiner_nr,
126 void __iomem *base, unsigned int irq) 127 void __iomem *base, unsigned int irq)
127{ 128{
128 combiner_data[combiner_nr].base = base; 129 combiner_data->base = base;
129 combiner_data[combiner_nr].irq_offset = irq_find_mapping( 130 combiner_data->irq_offset = irq_find_mapping(
130 combiner_irq_domain, combiner_nr * IRQ_IN_COMBINER); 131 combiner_irq_domain, combiner_nr * IRQ_IN_COMBINER);
131 combiner_data[combiner_nr].irq_mask = 0xff << ((combiner_nr % 4) << 3); 132 combiner_data->irq_mask = 0xff << ((combiner_nr % 4) << 3);
132 combiner_data[combiner_nr].parent_irq = irq; 133 combiner_data->parent_irq = irq;
133 134
134 /* Disable all interrupts */ 135 /* Disable all interrupts */
135 __raw_writel(combiner_data[combiner_nr].irq_mask, 136 __raw_writel(combiner_data->irq_mask, base + COMBINER_ENABLE_CLEAR);
136 base + COMBINER_ENABLE_CLEAR);
137} 137}
138 138
139#ifdef CONFIG_OF 139#ifdef CONFIG_OF
@@ -168,6 +168,8 @@ static int combiner_irq_domain_xlate(struct irq_domain *d,
168static int combiner_irq_domain_map(struct irq_domain *d, unsigned int irq, 168static int combiner_irq_domain_map(struct irq_domain *d, unsigned int irq,
169 irq_hw_number_t hw) 169 irq_hw_number_t hw)
170{ 170{
171 struct combiner_chip_data *combiner_data = d->host_data;
172
171 irq_set_chip_and_handler(irq, &combiner_chip, handle_level_irq); 173 irq_set_chip_and_handler(irq, &combiner_chip, handle_level_irq);
172 irq_set_chip_data(irq, &combiner_data[hw >> 3]); 174 irq_set_chip_data(irq, &combiner_data[hw >> 3]);
173 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); 175 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
@@ -202,6 +204,7 @@ void __init combiner_init(void __iomem *combiner_base,
202{ 204{
203 int i, irq, irq_base; 205 int i, irq, irq_base;
204 unsigned int nr_irq; 206 unsigned int nr_irq;
207 struct combiner_chip_data *combiner_data;
205 208
206 nr_irq = max_nr * IRQ_IN_COMBINER; 209 nr_irq = max_nr * IRQ_IN_COMBINER;
207 210
@@ -211,8 +214,14 @@ void __init combiner_init(void __iomem *combiner_base,
211 pr_warning("%s: irq desc alloc failed. Continuing with %d as linux irq base\n", __func__, irq_base); 214 pr_warning("%s: irq desc alloc failed. Continuing with %d as linux irq base\n", __func__, irq_base);
212 } 215 }
213 216
217 combiner_data = kcalloc(max_nr, sizeof (*combiner_data), GFP_KERNEL);
218 if (!combiner_data) {
219 pr_warning("%s: could not allocate combiner data\n", __func__);
220 return;
221 }
222
214 combiner_irq_domain = irq_domain_add_legacy(np, nr_irq, irq_base, 0, 223 combiner_irq_domain = irq_domain_add_legacy(np, nr_irq, irq_base, 0,
215 &combiner_irq_domain_ops, &combiner_data); 224 &combiner_irq_domain_ops, combiner_data);
216 if (WARN_ON(!combiner_irq_domain)) { 225 if (WARN_ON(!combiner_irq_domain)) {
217 pr_warning("%s: irq domain init failed\n", __func__); 226 pr_warning("%s: irq domain init failed\n", __func__);
218 return; 227 return;
@@ -227,8 +236,9 @@ void __init combiner_init(void __iomem *combiner_base,
227 if (np) 236 if (np)
228 irq = irq_of_parse_and_map(np, i); 237 irq = irq_of_parse_and_map(np, i);
229#endif 238#endif
230 combiner_init_one(i, combiner_base + (i >> 2) * 0x10, irq); 239 combiner_init_one(&combiner_data[i], i,
231 combiner_cascade_irq(i, irq); 240 combiner_base + (i >> 2) * 0x10, irq);
241 combiner_cascade_irq(&combiner_data[i], irq);
232 } 242 }
233} 243}
234 244