diff options
| author | Janusz Krzysztofik <jkrzyszt@tis.icnet.pl> | 2010-01-08 13:29:04 -0500 |
|---|---|---|
| committer | Tony Lindgren <tony@atomide.com> | 2010-01-08 13:29:04 -0500 |
| commit | 1866b54525d13402b2d129b906c4d189377f89c5 (patch) | |
| tree | 700f10fb9e2369ffe818b824211fe54f23b9159d | |
| parent | 74d2e4f8d79ae0c4b6ec027958d5b18058662eea (diff) | |
omap: McBSP: Fix possible port lockout
In its current form, the omap_mcbsp_request() function can return after
irq_request() failure without any cleanups, effectively locking out the port
forever with clocks left running. Fix it.
Signed-off-by: Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>
Acked-by: Jarkko Nikula <jhnikula@gmail.com>
Acked-by: Peter Ujfalusi <peter.ujfalusi@nokia.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
| -rw-r--r-- | arch/arm/plat-omap/mcbsp.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index 2cc1cc328bac..f75767278fc3 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c | |||
| @@ -436,7 +436,7 @@ int omap_mcbsp_request(unsigned int id) | |||
| 436 | dev_err(mcbsp->dev, "Unable to request TX IRQ %d " | 436 | dev_err(mcbsp->dev, "Unable to request TX IRQ %d " |
| 437 | "for McBSP%d\n", mcbsp->tx_irq, | 437 | "for McBSP%d\n", mcbsp->tx_irq, |
| 438 | mcbsp->id); | 438 | mcbsp->id); |
| 439 | return err; | 439 | goto error; |
| 440 | } | 440 | } |
| 441 | 441 | ||
| 442 | init_completion(&mcbsp->rx_irq_completion); | 442 | init_completion(&mcbsp->rx_irq_completion); |
| @@ -446,12 +446,26 @@ int omap_mcbsp_request(unsigned int id) | |||
| 446 | dev_err(mcbsp->dev, "Unable to request RX IRQ %d " | 446 | dev_err(mcbsp->dev, "Unable to request RX IRQ %d " |
| 447 | "for McBSP%d\n", mcbsp->rx_irq, | 447 | "for McBSP%d\n", mcbsp->rx_irq, |
| 448 | mcbsp->id); | 448 | mcbsp->id); |
| 449 | free_irq(mcbsp->tx_irq, (void *)mcbsp); | 449 | goto tx_irq; |
| 450 | return err; | ||
| 451 | } | 450 | } |
| 452 | } | 451 | } |
| 453 | 452 | ||
| 454 | return 0; | 453 | return 0; |
| 454 | tx_irq: | ||
| 455 | free_irq(mcbsp->tx_irq, (void *)mcbsp); | ||
| 456 | error: | ||
| 457 | if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free) | ||
| 458 | mcbsp->pdata->ops->free(id); | ||
| 459 | |||
| 460 | /* Do procedure specific to omap34xx arch, if applicable */ | ||
| 461 | omap34xx_mcbsp_free(mcbsp); | ||
| 462 | |||
| 463 | clk_disable(mcbsp->fclk); | ||
| 464 | clk_disable(mcbsp->iclk); | ||
| 465 | |||
| 466 | mcbsp->free = 1; | ||
| 467 | |||
| 468 | return err; | ||
| 455 | } | 469 | } |
| 456 | EXPORT_SYMBOL(omap_mcbsp_request); | 470 | EXPORT_SYMBOL(omap_mcbsp_request); |
| 457 | 471 | ||
