diff options
author | Paul Mundt <lethal@linux-sh.org> | 2010-04-26 19:08:55 +0900 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-04-26 19:08:55 +0900 |
commit | 763142d1efb56effe614d71185781796c4b83c78 (patch) | |
tree | f886c239786fd4be028e3a45006c5cc5c1b3a3f2 /arch/sh/kernel/irq.c | |
parent | 8db2bc4559639680a94d4492ae4b7ce71298a74f (diff) | |
download | linux-stable-763142d1efb56effe614d71185781796c4b83c78.tar.gz linux-stable-763142d1efb56effe614d71185781796c4b83c78.tar.bz2 linux-stable-763142d1efb56effe614d71185781796c4b83c78.zip |
sh: CPU hotplug support.
This adds preliminary support for CPU hotplug for SH SMP systems.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/irq.c')
-rw-r--r-- | arch/sh/kernel/irq.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index f6a9319c28e2..257de1f0692b 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c @@ -12,6 +12,7 @@ #include <linux/kernel_stat.h> #include <linux/seq_file.h> #include <linux/ftrace.h> +#include <linux/delay.h> #include <asm/processor.h> #include <asm/machvec.h> #include <asm/uaccess.h> @@ -292,3 +293,44 @@ int __init arch_probe_nr_irqs(void) return 0; } #endif + +#ifdef CONFIG_HOTPLUG_CPU +static void route_irq(struct irq_desc *desc, unsigned int irq, unsigned int cpu) +{ + printk(KERN_INFO "IRQ%u: moving from cpu%u to cpu%u\n", + irq, desc->node, cpu); + + raw_spin_lock_irq(&desc->lock); + desc->chip->set_affinity(irq, cpumask_of(cpu)); + raw_spin_unlock_irq(&desc->lock); +} + +/* + * The CPU has been marked offline. Migrate IRQs off this CPU. If + * the affinity settings do not allow other CPUs, force them onto any + * available CPU. + */ +void migrate_irqs(void) +{ + struct irq_desc *desc; + unsigned int irq, cpu = smp_processor_id(); + + for_each_irq_desc(irq, desc) { + if (desc->node == cpu) { + unsigned int newcpu = cpumask_any_and(desc->affinity, + cpu_online_mask); + if (newcpu >= nr_cpu_ids) { + if (printk_ratelimit()) + printk(KERN_INFO "IRQ%u no longer affine to CPU%u\n", + irq, cpu); + + cpumask_setall(desc->affinity); + newcpu = cpumask_any_and(desc->affinity, + cpu_online_mask); + } + + route_irq(desc, irq, newcpu); + } + } +} +#endif |