aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clocksource/sh_tmu.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-02-25 02:37:46 -0500
committerPaul Mundt <lethal@linux-sh.org>2010-02-25 02:37:46 -0500
commitda64c2a8dee66ca03f4f3e15d84be7bedf73db3d (patch)
tree8de9d4de358447a80f731a49a689c84bca42abf5 /drivers/clocksource/sh_tmu.c
parent29463c28a553e1959ec45cc8ad9d2eb434663cdf (diff)
clocksource: Fix up a registration/IRQ race in the sh drivers.
All of the SH clocksource drivers follow the scheme that the IRQ is setup prior to registering the clockevent. The interrupt handler in the clockevent cases looks to the event handler function pointer being filled in by the registration code, permitting us to get in to situations where asserted IRQs step in to the handler before registration has had a chance to complete and hitting a NULL pointer deref. In practice this is not an issue for most platforms, but some of them with fairly special loaders (or that are chain-loading from another kernel) may enter in to this situation. This fixes up the oops reported by Rafael on hp6xx. Reported-and-tested-by: Rafael Ignacio Zurita <rafaelignacio.zurita@gmail.com> Cc: stable@kernel.org Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/clocksource/sh_tmu.c')
-rw-r--r--drivers/clocksource/sh_tmu.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c
index 93c2322feab7..961f5b5ef6a3 100644
--- a/drivers/clocksource/sh_tmu.c
+++ b/drivers/clocksource/sh_tmu.c
@@ -323,15 +323,15 @@ static void sh_tmu_register_clockevent(struct sh_tmu_priv *p,
323 ced->set_next_event = sh_tmu_clock_event_next; 323 ced->set_next_event = sh_tmu_clock_event_next;
324 ced->set_mode = sh_tmu_clock_event_mode; 324 ced->set_mode = sh_tmu_clock_event_mode;
325 325
326 pr_info("sh_tmu: %s used for clock events\n", ced->name);
327 clockevents_register_device(ced);
328
326 ret = setup_irq(p->irqaction.irq, &p->irqaction); 329 ret = setup_irq(p->irqaction.irq, &p->irqaction);
327 if (ret) { 330 if (ret) {
328 pr_err("sh_tmu: failed to request irq %d\n", 331 pr_err("sh_tmu: failed to request irq %d\n",
329 p->irqaction.irq); 332 p->irqaction.irq);
330 return; 333 return;
331 } 334 }
332
333 pr_info("sh_tmu: %s used for clock events\n", ced->name);
334 clockevents_register_device(ced);
335} 335}
336 336
337static int sh_tmu_register(struct sh_tmu_priv *p, char *name, 337static int sh_tmu_register(struct sh_tmu_priv *p, char *name,