aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Baryshkov <dbaryshkov@gmail.com>2009-01-05 04:58:06 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-01-05 12:47:17 -0500
commit796123368871e4a838dc0dfd5dbc3cd8981ef429 (patch)
tree281f0576a8a5af9002c00e154d99d5a19759bbae
parent05d5e991a7290807e7d62a7d272bb4f37c27c6ae (diff)
pxa2xx-ac97: switch AC unit to correct state before probing
If AC97 unit is in partially enabled state, early request_irq can trigger IRQ storm or even full hang up. Workaround this by forcibly switching ACLINK off at the start of the probe. Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--sound/arm/pxa2xx-ac97-lib.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/sound/arm/pxa2xx-ac97-lib.c b/sound/arm/pxa2xx-ac97-lib.c
index ef6539eea579..35afd0c33be5 100644
--- a/sound/arm/pxa2xx-ac97-lib.c
+++ b/sound/arm/pxa2xx-ac97-lib.c
@@ -321,10 +321,6 @@ int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
321{ 321{
322 int ret; 322 int ret;
323 323
324 ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, 0, "AC97", NULL);
325 if (ret < 0)
326 goto err;
327
328 if (cpu_is_pxa25x() || cpu_is_pxa27x()) { 324 if (cpu_is_pxa25x() || cpu_is_pxa27x()) {
329 pxa_gpio_mode(GPIO31_SYNC_AC97_MD); 325 pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
330 pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD); 326 pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
@@ -339,7 +335,7 @@ int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
339 if (IS_ERR(ac97conf_clk)) { 335 if (IS_ERR(ac97conf_clk)) {
340 ret = PTR_ERR(ac97conf_clk); 336 ret = PTR_ERR(ac97conf_clk);
341 ac97conf_clk = NULL; 337 ac97conf_clk = NULL;
342 goto err_irq; 338 goto err_conf;
343 } 339 }
344 } 340 }
345 341
@@ -347,19 +343,30 @@ int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
347 if (IS_ERR(ac97_clk)) { 343 if (IS_ERR(ac97_clk)) {
348 ret = PTR_ERR(ac97_clk); 344 ret = PTR_ERR(ac97_clk);
349 ac97_clk = NULL; 345 ac97_clk = NULL;
350 goto err_irq; 346 goto err_clk;
351 } 347 }
352 348
353 return clk_enable(ac97_clk); 349 ret = clk_enable(ac97_clk);
350 if (ret)
351 goto err_clk2;
352
353 ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, IRQF_DISABLED, "AC97", NULL);
354 if (ret < 0)
355 goto err_irq;
356
357 return 0;
354 358
355err_irq: 359err_irq:
356 GCR |= GCR_ACLINK_OFF; 360 GCR |= GCR_ACLINK_OFF;
361err_clk2:
362 clk_put(ac97_clk);
363 ac97_clk = NULL;
364err_clk:
357 if (ac97conf_clk) { 365 if (ac97conf_clk) {
358 clk_put(ac97conf_clk); 366 clk_put(ac97conf_clk);
359 ac97conf_clk = NULL; 367 ac97conf_clk = NULL;
360 } 368 }
361 free_irq(IRQ_AC97, NULL); 369err_conf:
362err:
363 return ret; 370 return ret;
364} 371}
365EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_probe); 372EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_probe);