diff options
-rw-r--r-- | arch/arm/mach-exynos/common.c | 15 | ||||
-rw-r--r-- | arch/arm/mach-exynos/common.h | 3 | ||||
-rw-r--r-- | drivers/irqchip/exynos-combiner.c | 46 |
3 files changed, 32 insertions, 32 deletions
diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c index a453991ce90b..368fa4b01e7c 100644 --- a/arch/arm/mach-exynos/common.c +++ b/arch/arm/mach-exynos/common.c | |||
@@ -420,6 +420,19 @@ void __init exynos_init_time(void) | |||
420 | } | 420 | } |
421 | } | 421 | } |
422 | 422 | ||
423 | static unsigned int max_combiner_nr(void) | ||
424 | { | ||
425 | if (soc_is_exynos5250()) | ||
426 | return EXYNOS5_MAX_COMBINER_NR; | ||
427 | else if (soc_is_exynos4412()) | ||
428 | return EXYNOS4412_MAX_COMBINER_NR; | ||
429 | else if (soc_is_exynos4212()) | ||
430 | return EXYNOS4212_MAX_COMBINER_NR; | ||
431 | else | ||
432 | return EXYNOS4210_MAX_COMBINER_NR; | ||
433 | } | ||
434 | |||
435 | |||
423 | void __init exynos4_init_irq(void) | 436 | void __init exynos4_init_irq(void) |
424 | { | 437 | { |
425 | unsigned int gic_bank_offset; | 438 | unsigned int gic_bank_offset; |
@@ -434,7 +447,7 @@ void __init exynos4_init_irq(void) | |||
434 | #endif | 447 | #endif |
435 | 448 | ||
436 | if (!of_have_populated_dt()) | 449 | if (!of_have_populated_dt()) |
437 | combiner_init(S5P_VA_COMBINER_BASE, NULL); | 450 | combiner_init(S5P_VA_COMBINER_BASE, NULL, max_combiner_nr()); |
438 | 451 | ||
439 | /* | 452 | /* |
440 | * The parameters of s5p_init_irq() are for VIC init. | 453 | * The parameters of s5p_init_irq() are for VIC init. |
diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h index 9717d0f6088f..4ba8cbecc144 100644 --- a/arch/arm/mach-exynos/common.h +++ b/arch/arm/mach-exynos/common.h | |||
@@ -69,7 +69,8 @@ void exynos4212_register_clocks(void); | |||
69 | #endif | 69 | #endif |
70 | 70 | ||
71 | struct device_node; | 71 | struct device_node; |
72 | void combiner_init(void __iomem *combiner_base, struct device_node *np); | 72 | void combiner_init(void __iomem *combiner_base, struct device_node *np, |
73 | unsigned int max_nr); | ||
73 | 74 | ||
74 | extern struct smp_operations exynos_smp_ops; | 75 | extern struct smp_operations exynos_smp_ops; |
75 | 76 | ||
diff --git a/drivers/irqchip/exynos-combiner.c b/drivers/irqchip/exynos-combiner.c index e8501dbaa0b7..d8683836ee1e 100644 --- a/drivers/irqchip/exynos-combiner.c +++ b/drivers/irqchip/exynos-combiner.c | |||
@@ -25,6 +25,8 @@ | |||
25 | #define COMBINER_ENABLE_CLEAR 0x4 | 25 | #define COMBINER_ENABLE_CLEAR 0x4 |
26 | #define COMBINER_INT_STATUS 0xC | 26 | #define COMBINER_INT_STATUS 0xC |
27 | 27 | ||
28 | #define IRQ_IN_COMBINER 8 | ||
29 | |||
28 | static DEFINE_SPINLOCK(irq_controller_lock); | 30 | static DEFINE_SPINLOCK(irq_controller_lock); |
29 | 31 | ||
30 | struct combiner_chip_data { | 32 | struct combiner_chip_data { |
@@ -112,23 +114,9 @@ static struct irq_chip combiner_chip = { | |||
112 | #endif | 114 | #endif |
113 | }; | 115 | }; |
114 | 116 | ||
115 | static unsigned int max_combiner_nr(void) | ||
116 | { | ||
117 | if (soc_is_exynos5250()) | ||
118 | return EXYNOS5_MAX_COMBINER_NR; | ||
119 | else if (soc_is_exynos4412()) | ||
120 | return EXYNOS4412_MAX_COMBINER_NR; | ||
121 | else if (soc_is_exynos4212()) | ||
122 | return EXYNOS4212_MAX_COMBINER_NR; | ||
123 | else | ||
124 | return EXYNOS4210_MAX_COMBINER_NR; | ||
125 | } | ||
126 | |||
127 | static void __init combiner_cascade_irq(unsigned int combiner_nr, | 117 | static void __init combiner_cascade_irq(unsigned int combiner_nr, |
128 | unsigned int irq) | 118 | unsigned int irq) |
129 | { | 119 | { |
130 | if (combiner_nr >= max_combiner_nr()) | ||
131 | BUG(); | ||
132 | if (irq_set_handler_data(irq, &combiner_data[combiner_nr]) != 0) | 120 | if (irq_set_handler_data(irq, &combiner_data[combiner_nr]) != 0) |
133 | BUG(); | 121 | BUG(); |
134 | irq_set_chained_handler(irq, combiner_handle_cascade_irq); | 122 | irq_set_chained_handler(irq, combiner_handle_cascade_irq); |
@@ -139,7 +127,7 @@ static void __init combiner_init_one(unsigned int combiner_nr, | |||
139 | { | 127 | { |
140 | combiner_data[combiner_nr].base = base; | 128 | combiner_data[combiner_nr].base = base; |
141 | combiner_data[combiner_nr].irq_offset = irq_find_mapping( | 129 | combiner_data[combiner_nr].irq_offset = irq_find_mapping( |
142 | combiner_irq_domain, combiner_nr * MAX_IRQ_IN_COMBINER); | 130 | combiner_irq_domain, combiner_nr * IRQ_IN_COMBINER); |
143 | combiner_data[combiner_nr].irq_mask = 0xff << ((combiner_nr % 4) << 3); | 131 | combiner_data[combiner_nr].irq_mask = 0xff << ((combiner_nr % 4) << 3); |
144 | combiner_data[combiner_nr].parent_irq = irq; | 132 | combiner_data[combiner_nr].parent_irq = irq; |
145 | 133 | ||
@@ -161,7 +149,7 @@ static int combiner_irq_domain_xlate(struct irq_domain *d, | |||
161 | if (intsize < 2) | 149 | if (intsize < 2) |
162 | return -EINVAL; | 150 | return -EINVAL; |
163 | 151 | ||
164 | *out_hwirq = intspec[0] * MAX_IRQ_IN_COMBINER + intspec[1]; | 152 | *out_hwirq = intspec[0] * IRQ_IN_COMBINER + intspec[1]; |
165 | *out_type = 0; | 153 | *out_type = 0; |
166 | 154 | ||
167 | return 0; | 155 | return 0; |
@@ -209,22 +197,13 @@ static unsigned int exynos4x12_combiner_extra_irq(int group) | |||
209 | } | 197 | } |
210 | 198 | ||
211 | void __init combiner_init(void __iomem *combiner_base, | 199 | void __init combiner_init(void __iomem *combiner_base, |
212 | struct device_node *np) | 200 | struct device_node *np, |
201 | unsigned int max_nr) | ||
213 | { | 202 | { |
214 | int i, irq, irq_base; | 203 | int i, irq, irq_base; |
215 | unsigned int max_nr, nr_irq; | 204 | unsigned int nr_irq; |
216 | 205 | ||
217 | max_nr = max_combiner_nr(); | 206 | nr_irq = max_nr * IRQ_IN_COMBINER; |
218 | |||
219 | if (np) { | ||
220 | if (of_property_read_u32(np, "samsung,combiner-nr", &max_nr)) { | ||
221 | pr_info("%s: number of combiners not specified, " | ||
222 | "setting default as %d.\n", | ||
223 | __func__, max_nr); | ||
224 | } | ||
225 | } | ||
226 | |||
227 | nr_irq = max_nr * MAX_IRQ_IN_COMBINER; | ||
228 | 207 | ||
229 | irq_base = irq_alloc_descs(COMBINER_IRQ(0, 0), 1, nr_irq, 0); | 208 | irq_base = irq_alloc_descs(COMBINER_IRQ(0, 0), 1, nr_irq, 0); |
230 | if (IS_ERR_VALUE(irq_base)) { | 209 | if (IS_ERR_VALUE(irq_base)) { |
@@ -258,6 +237,7 @@ static int __init combiner_of_init(struct device_node *np, | |||
258 | struct device_node *parent) | 237 | struct device_node *parent) |
259 | { | 238 | { |
260 | void __iomem *combiner_base; | 239 | void __iomem *combiner_base; |
240 | unsigned int max_nr = 20; | ||
261 | 241 | ||
262 | combiner_base = of_iomap(np, 0); | 242 | combiner_base = of_iomap(np, 0); |
263 | if (!combiner_base) { | 243 | if (!combiner_base) { |
@@ -265,7 +245,13 @@ static int __init combiner_of_init(struct device_node *np, | |||
265 | return -ENXIO; | 245 | return -ENXIO; |
266 | } | 246 | } |
267 | 247 | ||
268 | combiner_init(combiner_base, np); | 248 | if (of_property_read_u32(np, "samsung,combiner-nr", &max_nr)) { |
249 | pr_info("%s: number of combiners not specified, " | ||
250 | "setting default as %d.\n", | ||
251 | __func__, max_nr); | ||
252 | } | ||
253 | |||
254 | combiner_init(combiner_base, np, max_nr); | ||
269 | 255 | ||
270 | return 0; | 256 | return 0; |
271 | } | 257 | } |