aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Pitre <nicolas.pitre@linaro.org>2012-11-27 21:54:41 -0500
committerNicolas Pitre <nicolas.pitre@linaro.org>2013-09-23 18:47:26 -0400
commit5135d875e1457ef946a055003d8f80713e862135 (patch)
tree6cd37d9a8fd486ac2af3205b9baf2dce20ac0040
parent108a9640abfada2599b6cb08c7cc00a4eebf8f8f (diff)
ARM: SMP: basic IPI triggered completion support
We need a mechanism to let an inbound CPU signal that it is alive before even getting into the kernel environment i.e. from early assembly code. Using an IPI is the simplest way to achieve that. This adds some basic infrastructure to register a struct completion pointer to be "completed" when the dedicated IPI for this task is received. Signed-off-by: Nicolas Pitre <nico@linaro.org>
-rw-r--r--arch/arm/include/asm/hardirq.h2
-rw-r--r--arch/arm/include/asm/smp.h2
-rw-r--r--arch/arm/kernel/smp.c21
3 files changed, 24 insertions, 1 deletions
diff --git a/arch/arm/include/asm/hardirq.h b/arch/arm/include/asm/hardirq.h
index 2740c2a2df63..3d7351c844aa 100644
--- a/arch/arm/include/asm/hardirq.h
+++ b/arch/arm/include/asm/hardirq.h
@@ -5,7 +5,7 @@
5#include <linux/threads.h> 5#include <linux/threads.h>
6#include <asm/irq.h> 6#include <asm/irq.h>
7 7
8#define NR_IPI 6 8#define NR_IPI 7
9 9
10typedef struct { 10typedef struct {
11 unsigned int __softirq_pending; 11 unsigned int __softirq_pending;
diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
index a8cae71caceb..22a3b9b5d4a1 100644
--- a/arch/arm/include/asm/smp.h
+++ b/arch/arm/include/asm/smp.h
@@ -84,6 +84,8 @@ extern void arch_send_call_function_single_ipi(int cpu);
84extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); 84extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
85extern void arch_send_wakeup_ipi_mask(const struct cpumask *mask); 85extern void arch_send_wakeup_ipi_mask(const struct cpumask *mask);
86 86
87extern int register_ipi_completion(struct completion *completion, int cpu);
88
87struct smp_operations { 89struct smp_operations {
88#ifdef CONFIG_SMP 90#ifdef CONFIG_SMP
89 /* 91 /*
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 72024ea8a3a6..7d80a549cae5 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -66,6 +66,7 @@ enum ipi_msg_type {
66 IPI_CALL_FUNC, 66 IPI_CALL_FUNC,
67 IPI_CALL_FUNC_SINGLE, 67 IPI_CALL_FUNC_SINGLE,
68 IPI_CPU_STOP, 68 IPI_CPU_STOP,
69 IPI_COMPLETION,
69}; 70};
70 71
71static DECLARE_COMPLETION(cpu_running); 72static DECLARE_COMPLETION(cpu_running);
@@ -456,6 +457,7 @@ static const char *ipi_types[NR_IPI] = {
456 S(IPI_CALL_FUNC, "Function call interrupts"), 457 S(IPI_CALL_FUNC, "Function call interrupts"),
457 S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"), 458 S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"),
458 S(IPI_CPU_STOP, "CPU stop interrupts"), 459 S(IPI_CPU_STOP, "CPU stop interrupts"),
460 S(IPI_COMPLETION, "completion interrupts"),
459}; 461};
460 462
461void show_ipi_list(struct seq_file *p, int prec) 463void show_ipi_list(struct seq_file *p, int prec)
@@ -515,6 +517,19 @@ static void ipi_cpu_stop(unsigned int cpu)
515 cpu_relax(); 517 cpu_relax();
516} 518}
517 519
520static DEFINE_PER_CPU(struct completion *, cpu_completion);
521
522int register_ipi_completion(struct completion *completion, int cpu)
523{
524 per_cpu(cpu_completion, cpu) = completion;
525 return IPI_COMPLETION;
526}
527
528static void ipi_complete(unsigned int cpu)
529{
530 complete(per_cpu(cpu_completion, cpu));
531}
532
518/* 533/*
519 * Main handler for inter-processor interrupts 534 * Main handler for inter-processor interrupts
520 */ 535 */
@@ -565,6 +580,12 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
565 irq_exit(); 580 irq_exit();
566 break; 581 break;
567 582
583 case IPI_COMPLETION:
584 irq_enter();
585 ipi_complete(cpu);
586 irq_exit();
587 break;
588
568 default: 589 default:
569 printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%x\n", 590 printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%x\n",
570 cpu, ipinr); 591 cpu, ipinr);