diff options
author | Arnd Bergmann <arnd@arndb.de> | 2013-04-10 09:31:11 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2013-04-19 17:00:41 -0400 |
commit | d34f03d4a1e4e56f5944186c2e74cbed58b27090 (patch) | |
tree | d5301a4dae852687efcaf5f8c87e61e5085ada3a /drivers/irqchip | |
parent | 6761dcfe8c42b55076753bc8bea7b5dcbfb445c0 (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.c | 36 |
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 | ||
39 | static struct irq_domain *combiner_irq_domain; | 40 | static struct irq_domain *combiner_irq_domain; |
40 | static struct combiner_chip_data combiner_data[MAX_COMBINER_NR]; | ||
41 | 41 | ||
42 | static inline void __iomem *combiner_base(struct irq_data *data) | 42 | static 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 | ||
117 | static void __init combiner_cascade_irq(unsigned int combiner_nr, | 117 | static 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 | ||
125 | static void __init combiner_init_one(unsigned int combiner_nr, | 125 | static 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, | |||
168 | static int combiner_irq_domain_map(struct irq_domain *d, unsigned int irq, | 168 | static 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 | ||