diff options
author | Max Filippov <jcmvbkbc@gmail.com> | 2013-10-16 18:42:28 -0400 |
---|---|---|
committer | Chris Zankel <chris@zankel.net> | 2014-01-14 13:19:59 -0500 |
commit | 49b424fedaf88d0fa9913082b8c1ccd012a8a972 (patch) | |
tree | 1a1fac57b578fe828b54b0367df4ed1fd94940b9 /arch/xtensa/kernel/irq.c | |
parent | f615136c06a791364f5afa8b8ba965315a6440f1 (diff) |
xtensa: implement CPU hotplug
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Chris Zankel <chris@zankel.net>
Diffstat (limited to 'arch/xtensa/kernel/irq.c')
-rw-r--r-- | arch/xtensa/kernel/irq.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c index fad9e0059765..482868a2de6e 100644 --- a/arch/xtensa/kernel/irq.c +++ b/arch/xtensa/kernel/irq.c | |||
@@ -153,3 +153,52 @@ void __init init_IRQ(void) | |||
153 | #endif | 153 | #endif |
154 | variant_init_irq(); | 154 | variant_init_irq(); |
155 | } | 155 | } |
156 | |||
157 | #ifdef CONFIG_HOTPLUG_CPU | ||
158 | static void route_irq(struct irq_data *data, unsigned int irq, unsigned int cpu) | ||
159 | { | ||
160 | struct irq_desc *desc = irq_to_desc(irq); | ||
161 | struct irq_chip *chip = irq_data_get_irq_chip(data); | ||
162 | unsigned long flags; | ||
163 | |||
164 | raw_spin_lock_irqsave(&desc->lock, flags); | ||
165 | if (chip->irq_set_affinity) | ||
166 | chip->irq_set_affinity(data, cpumask_of(cpu), false); | ||
167 | raw_spin_unlock_irqrestore(&desc->lock, flags); | ||
168 | } | ||
169 | |||
170 | /* | ||
171 | * The CPU has been marked offline. Migrate IRQs off this CPU. If | ||
172 | * the affinity settings do not allow other CPUs, force them onto any | ||
173 | * available CPU. | ||
174 | */ | ||
175 | void migrate_irqs(void) | ||
176 | { | ||
177 | unsigned int i, cpu = smp_processor_id(); | ||
178 | struct irq_desc *desc; | ||
179 | |||
180 | for_each_irq_desc(i, desc) { | ||
181 | struct irq_data *data = irq_desc_get_irq_data(desc); | ||
182 | unsigned int newcpu; | ||
183 | |||
184 | if (irqd_is_per_cpu(data)) | ||
185 | continue; | ||
186 | |||
187 | if (!cpumask_test_cpu(cpu, data->affinity)) | ||
188 | continue; | ||
189 | |||
190 | newcpu = cpumask_any_and(data->affinity, cpu_online_mask); | ||
191 | |||
192 | if (newcpu >= nr_cpu_ids) { | ||
193 | pr_info_ratelimited("IRQ%u no longer affine to CPU%u\n", | ||
194 | i, cpu); | ||
195 | |||
196 | cpumask_setall(data->affinity); | ||
197 | newcpu = cpumask_any_and(data->affinity, | ||
198 | cpu_online_mask); | ||
199 | } | ||
200 | |||
201 | route_irq(data, i, newcpu); | ||
202 | } | ||
203 | } | ||
204 | #endif /* CONFIG_HOTPLUG_CPU */ | ||