Commit 54bc0937 authored by Philippe Gerum's avatar Philippe Gerum Committed by Jan Kiszka
Browse files

cobalt: dovetail: fix SMP kernel boot on uniprocessor machine



We may be running a SMP kernel on a uniprocessor machine whose
interrupt controller supports no IPI. We should attempt to hook IPIs
only if the hardware can support multiple CPUs, otherwise it is
unneeded and poised to fail.
Signed-off-by: Philippe Gerum's avatarPhilippe Gerum <rpm@xenomai.org>
Signed-off-by: Jan Kiszka's avatarJan Kiszka <jan.kiszka@siemens.com>
parent 17fa132d
......@@ -6,6 +6,7 @@
#define _COBALT_KERNEL_DOVETAIL_PIPELINE_H
#include <linux/irq_pipeline.h>
#include <linux/cpumask.h>
#include <cobalt/kernel/assert.h>
#include <asm/xenomai/features.h>
#include <pipeline/machine.h>
......@@ -35,6 +36,9 @@ irqreturn_t pipeline_reschedule_ipi_handler(int irq, void *dev_id);
static inline int pipeline_request_resched_ipi(void (*handler)(void))
{
if (num_possible_cpus() == 1)
return 0;
/* Trap the out-of-band rescheduling interrupt. */
return __request_percpu_irq(RESCHEDULE_OOB_IPI,
pipeline_reschedule_ipi_handler,
......@@ -45,8 +49,9 @@ static inline int pipeline_request_resched_ipi(void (*handler)(void))
static inline void pipeline_free_resched_ipi(void)
{
/* Release the out-of-band rescheduling interrupt. */
free_percpu_irq(RESCHEDULE_OOB_IPI, &cobalt_machine_cpudata);
if (num_possible_cpus() > 1)
/* Release the out-of-band rescheduling interrupt. */
free_percpu_irq(RESCHEDULE_OOB_IPI, &cobalt_machine_cpudata);
}
static inline void pipeline_send_resched_ipi(const struct cpumask *dest)
......
......@@ -144,12 +144,20 @@ int pipeline_install_tick_proxy(void)
int ret;
#ifdef CONFIG_SMP
ret = __request_percpu_irq(TIMER_OOB_IPI,
tick_ipi_handler,
IRQF_OOB, "Xenomai timer IPI",
&cobalt_machine_cpudata);
if (ret)
return ret;
/*
* We may be running a SMP kernel on a uniprocessor machine
* whose interrupt controller provides no IPI: attempt to hook
* the timer IPI only if the hardware can support multiple
* CPUs.
*/
if (num_possible_cpus() > 1) {
ret = __request_percpu_irq(TIMER_OOB_IPI,
tick_ipi_handler,
IRQF_OOB, "Xenomai timer IPI",
&cobalt_machine_cpudata);
if (ret)
return ret;
}
#endif
/* Install the proxy tick device */
......@@ -161,7 +169,8 @@ int pipeline_install_tick_proxy(void)
fail_proxy:
#ifdef CONFIG_SMP
free_percpu_irq(TIMER_OOB_IPI, &cobalt_machine_cpudata);
if (num_possible_cpus() > 1)
free_percpu_irq(TIMER_OOB_IPI, &cobalt_machine_cpudata);
#endif
return ret;
......@@ -173,6 +182,7 @@ void pipeline_uninstall_tick_proxy(void)
tick_uninstall_proxy(&xnsched_realtime_cpus);
#ifdef CONFIG_SMP
free_percpu_irq(TIMER_OOB_IPI, &cobalt_machine_cpudata);
if (num_possible_cpus() > 1)
free_percpu_irq(TIMER_OOB_IPI, &cobalt_machine_cpudata);
#endif
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment