aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/irqchip/exynos-combiner.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/irqchip/exynos-combiner.c')
-rw-r--r--drivers/irqchip/exynos-combiner.c30
1 files changed, 25 insertions, 5 deletions
diff --git a/drivers/irqchip/exynos-combiner.c b/drivers/irqchip/exynos-combiner.c
index 04d86a9803f4..b5ff271bfd64 100644
--- a/drivers/irqchip/exynos-combiner.c
+++ b/drivers/irqchip/exynos-combiner.c
@@ -31,6 +31,7 @@ struct combiner_chip_data {
31 unsigned int irq_offset; 31 unsigned int irq_offset;
32 unsigned int irq_mask; 32 unsigned int irq_mask;
33 void __iomem *base; 33 void __iomem *base;
34 unsigned int parent_irq;
34}; 35};
35 36
36static struct irq_domain *combiner_irq_domain; 37static struct irq_domain *combiner_irq_domain;
@@ -87,10 +88,28 @@ static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
87 chained_irq_exit(chip, desc); 88 chained_irq_exit(chip, desc);
88} 89}
89 90
91#ifdef CONFIG_SMP
92static int combiner_set_affinity(struct irq_data *d,
93 const struct cpumask *mask_val, bool force)
94{
95 struct combiner_chip_data *chip_data = irq_data_get_irq_chip_data(d);
96 struct irq_chip *chip = irq_get_chip(chip_data->parent_irq);
97 struct irq_data *data = irq_get_irq_data(chip_data->parent_irq);
98
99 if (chip && chip->irq_set_affinity)
100 return chip->irq_set_affinity(data, mask_val, force);
101 else
102 return -EINVAL;
103}
104#endif
105
90static struct irq_chip combiner_chip = { 106static struct irq_chip combiner_chip = {
91 .name = "COMBINER", 107 .name = "COMBINER",
92 .irq_mask = combiner_mask_irq, 108 .irq_mask = combiner_mask_irq,
93 .irq_unmask = combiner_unmask_irq, 109 .irq_unmask = combiner_unmask_irq,
110#ifdef CONFIG_SMP
111 .irq_set_affinity = combiner_set_affinity,
112#endif
94}; 113};
95 114
96static void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq) 115static void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq)
@@ -110,12 +129,13 @@ static void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int i
110} 129}
111 130
112static void __init combiner_init_one(unsigned int combiner_nr, 131static void __init combiner_init_one(unsigned int combiner_nr,
113 void __iomem *base) 132 void __iomem *base, unsigned int irq)
114{ 133{
115 combiner_data[combiner_nr].base = base; 134 combiner_data[combiner_nr].base = base;
116 combiner_data[combiner_nr].irq_offset = irq_find_mapping( 135 combiner_data[combiner_nr].irq_offset = irq_find_mapping(
117 combiner_irq_domain, combiner_nr * MAX_IRQ_IN_COMBINER); 136 combiner_irq_domain, combiner_nr * MAX_IRQ_IN_COMBINER);
118 combiner_data[combiner_nr].irq_mask = 0xff << ((combiner_nr % 4) << 3); 137 combiner_data[combiner_nr].irq_mask = 0xff << ((combiner_nr % 4) << 3);
138 combiner_data[combiner_nr].parent_irq = irq;
119 139
120 /* Disable all interrupts */ 140 /* Disable all interrupts */
121 __raw_writel(combiner_data[combiner_nr].irq_mask, 141 __raw_writel(combiner_data[combiner_nr].irq_mask,
@@ -199,12 +219,12 @@ void __init combiner_init(void __iomem *combiner_base,
199 } 219 }
200 220
201 for (i = 0; i < max_nr; i++) { 221 for (i = 0; i < max_nr; i++) {
202 combiner_init_one(i, combiner_base + (i >> 2) * 0x10);
203 irq = IRQ_SPI(i); 222 irq = IRQ_SPI(i);
204#ifdef CONFIG_OF 223#ifdef CONFIG_OF
205 if (np) 224 if (np)
206 irq = irq_of_parse_and_map(np, i); 225 irq = irq_of_parse_and_map(np, i);
207#endif 226#endif
227 combiner_init_one(i, combiner_base + (i >> 2) * 0x10, irq);
208 combiner_cascade_irq(i, irq); 228 combiner_cascade_irq(i, irq);
209 } 229 }
210} 230}