diff options
author | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2011-01-06 12:04:50 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2011-01-06 21:03:26 -0500 |
commit | 661382fe190475c17d0b3a6b5f0350b4f82f5939 (patch) | |
tree | 3609fdecc5b29a6875cbe92cca747096819db7b4 | |
parent | 3c0cb7c31c206aaedb967e44b98442bbeb17a6c4 (diff) |
dma: shdma: don't register the global die notifier multiple times
A recent patch has added a die notifier to the shdma driver, however,
it registers a static die-notifier object in the probe routine, i.e.,
for each device instance. This is wrong and leads to a system lockup.
This patch moves the die notifier registration to module init and
exit routines respectively.
Reported-by: Magnus Damm <damm@opensource.se>
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r-- | drivers/dma/shdma.c | 16 |
1 files changed, 7 insertions, 9 deletions
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index a0069c171518..28720d3103c4 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c | |||
@@ -1110,11 +1110,6 @@ static int __init sh_dmae_probe(struct platform_device *pdev) | |||
1110 | list_add_tail_rcu(&shdev->node, &sh_dmae_devices); | 1110 | list_add_tail_rcu(&shdev->node, &sh_dmae_devices); |
1111 | spin_unlock_irqrestore(&sh_dmae_lock, flags); | 1111 | spin_unlock_irqrestore(&sh_dmae_lock, flags); |
1112 | 1112 | ||
1113 | /* Wire up NMI handling before bringing the controller online */ | ||
1114 | err = register_die_notifier(&sh_dmae_nmi_notifier); | ||
1115 | if (err) | ||
1116 | goto notifier_err; | ||
1117 | |||
1118 | /* reset dma controller */ | 1113 | /* reset dma controller */ |
1119 | err = sh_dmae_rst(shdev); | 1114 | err = sh_dmae_rst(shdev); |
1120 | if (err) | 1115 | if (err) |
@@ -1218,8 +1213,6 @@ eirqres: | |||
1218 | eirq_err: | 1213 | eirq_err: |
1219 | #endif | 1214 | #endif |
1220 | rst_err: | 1215 | rst_err: |
1221 | unregister_die_notifier(&sh_dmae_nmi_notifier); | ||
1222 | notifier_err: | ||
1223 | spin_lock_irqsave(&sh_dmae_lock, flags); | 1216 | spin_lock_irqsave(&sh_dmae_lock, flags); |
1224 | list_del_rcu(&shdev->node); | 1217 | list_del_rcu(&shdev->node); |
1225 | spin_unlock_irqrestore(&sh_dmae_lock, flags); | 1218 | spin_unlock_irqrestore(&sh_dmae_lock, flags); |
@@ -1252,8 +1245,6 @@ static int __exit sh_dmae_remove(struct platform_device *pdev) | |||
1252 | if (errirq > 0) | 1245 | if (errirq > 0) |
1253 | free_irq(errirq, shdev); | 1246 | free_irq(errirq, shdev); |
1254 | 1247 | ||
1255 | unregister_die_notifier(&sh_dmae_nmi_notifier); | ||
1256 | |||
1257 | spin_lock_irqsave(&sh_dmae_lock, flags); | 1248 | spin_lock_irqsave(&sh_dmae_lock, flags); |
1258 | list_del_rcu(&shdev->node); | 1249 | list_del_rcu(&shdev->node); |
1259 | spin_unlock_irqrestore(&sh_dmae_lock, flags); | 1250 | spin_unlock_irqrestore(&sh_dmae_lock, flags); |
@@ -1296,6 +1287,11 @@ static struct platform_driver sh_dmae_driver = { | |||
1296 | 1287 | ||
1297 | static int __init sh_dmae_init(void) | 1288 | static int __init sh_dmae_init(void) |
1298 | { | 1289 | { |
1290 | /* Wire up NMI handling */ | ||
1291 | int err = register_die_notifier(&sh_dmae_nmi_notifier); | ||
1292 | if (err) | ||
1293 | return err; | ||
1294 | |||
1299 | return platform_driver_probe(&sh_dmae_driver, sh_dmae_probe); | 1295 | return platform_driver_probe(&sh_dmae_driver, sh_dmae_probe); |
1300 | } | 1296 | } |
1301 | module_init(sh_dmae_init); | 1297 | module_init(sh_dmae_init); |
@@ -1303,6 +1299,8 @@ module_init(sh_dmae_init); | |||
1303 | static void __exit sh_dmae_exit(void) | 1299 | static void __exit sh_dmae_exit(void) |
1304 | { | 1300 | { |
1305 | platform_driver_unregister(&sh_dmae_driver); | 1301 | platform_driver_unregister(&sh_dmae_driver); |
1302 | |||
1303 | unregister_die_notifier(&sh_dmae_nmi_notifier); | ||
1306 | } | 1304 | } |
1307 | module_exit(sh_dmae_exit); | 1305 | module_exit(sh_dmae_exit); |
1308 | 1306 | ||