Commit 5df718d8 authored by Tomasz Figa's avatar Tomasz Figa Committed by Daniel Lezcano

clocksource: exynos_mct: Set IRQ affinity when the CPU goes online

Some variants of Exynos MCT, namely exynos4210-mct at the moment, use
normal, shared interrupts for local timers. This means that each
interrupt must have correct affinity set to fire only on CPU
corresponding to given local timer.

However after recent conversion of clocksource drivers to not use the
local timer API for local timer initialization any more, the point of
time when local timers get initialized changed and irq_set_affinity()
fails because the CPU is not marked as online yet.

This patch fixes this by moving the call to irq_set_affinity() to
CPU_ONLINE notification, so the affinity is being set when the CPU goes
online.

This fixes a regression introduced by commit
	ee98d27d ARM: EXYNOS4: Divorce mct from local timer API
which rendered all Exynos4210 based boards unbootable due to
failing irq_set_affinity() making local timers inoperatible.
Signed-off-by: default avatarTomasz Figa <t.figa@samsung.com>
Signed-off-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
Acked-by: default avatarStephen Boyd <sboyd@codeaurora.org>
Signed-off-by: default avatarDaniel Lezcano <daniel.lezcano@linaro.org>
parent 7b0dd72a
...@@ -428,7 +428,6 @@ static int exynos4_local_timer_setup(struct clock_event_device *evt) ...@@ -428,7 +428,6 @@ static int exynos4_local_timer_setup(struct clock_event_device *evt)
evt->irq); evt->irq);
return -EIO; return -EIO;
} }
irq_set_affinity(evt->irq, cpumask_of(cpu));
} else { } else {
enable_percpu_irq(mct_irqs[MCT_L0_IRQ], 0); enable_percpu_irq(mct_irqs[MCT_L0_IRQ], 0);
} }
...@@ -449,6 +448,7 @@ static int exynos4_mct_cpu_notify(struct notifier_block *self, ...@@ -449,6 +448,7 @@ static int exynos4_mct_cpu_notify(struct notifier_block *self,
unsigned long action, void *hcpu) unsigned long action, void *hcpu)
{ {
struct mct_clock_event_device *mevt; struct mct_clock_event_device *mevt;
unsigned int cpu;
/* /*
* Grab cpu pointer in each case to avoid spurious * Grab cpu pointer in each case to avoid spurious
...@@ -459,6 +459,12 @@ static int exynos4_mct_cpu_notify(struct notifier_block *self, ...@@ -459,6 +459,12 @@ static int exynos4_mct_cpu_notify(struct notifier_block *self,
mevt = this_cpu_ptr(&percpu_mct_tick); mevt = this_cpu_ptr(&percpu_mct_tick);
exynos4_local_timer_setup(&mevt->evt); exynos4_local_timer_setup(&mevt->evt);
break; break;
case CPU_ONLINE:
cpu = (unsigned long)hcpu;
if (mct_int_type == MCT_INT_SPI)
irq_set_affinity(mct_irqs[MCT_L0_IRQ + cpu],
cpumask_of(cpu));
break;
case CPU_DYING: case CPU_DYING:
mevt = this_cpu_ptr(&percpu_mct_tick); mevt = this_cpu_ptr(&percpu_mct_tick);
exynos4_local_timer_stop(&mevt->evt); exynos4_local_timer_stop(&mevt->evt);
...@@ -500,6 +506,8 @@ static void __init exynos4_timer_resources(struct device_node *np, void __iomem ...@@ -500,6 +506,8 @@ static void __init exynos4_timer_resources(struct device_node *np, void __iomem
&percpu_mct_tick); &percpu_mct_tick);
WARN(err, "MCT: can't request IRQ %d (%d)\n", WARN(err, "MCT: can't request IRQ %d (%d)\n",
mct_irqs[MCT_L0_IRQ], err); mct_irqs[MCT_L0_IRQ], err);
} else {
irq_set_affinity(mct_irqs[MCT_L0_IRQ], cpumask_of(0));
} }
err = register_cpu_notifier(&exynos4_mct_cpu_nb); err = register_cpu_notifier(&exynos4_mct_cpu_nb);
......
Markdown is supported
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