diff options
author | Janusz Krzysztofik <jkrzyszt@tis.icnet.pl> | 2010-01-08 10:29:04 -0800 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2010-01-08 10:29:04 -0800 |
commit | 1866b54525d13402b2d129b906c4d189377f89c5 (patch) | |
tree | 700f10fb9e2369ffe818b824211fe54f23b9159d /arch/arm/plat-omap | |
parent | 74d2e4f8d79ae0c4b6ec027958d5b18058662eea (diff) | |
download | linux-3.10-1866b54525d13402b2d129b906c4d189377f89c5.tar.gz linux-3.10-1866b54525d13402b2d129b906c4d189377f89c5.tar.bz2 linux-3.10-1866b54525d13402b2d129b906c4d189377f89c5.zip |
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>
Diffstat (limited to 'arch/arm/plat-omap')
-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 2cc1cc328ba..f75767278fc 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) dev_err(mcbsp->dev, "Unable to request TX IRQ %d " "for McBSP%d\n", mcbsp->tx_irq, mcbsp->id); - return err; + goto error; } init_completion(&mcbsp->rx_irq_completion); @@ -446,12 +446,26 @@ int omap_mcbsp_request(unsigned int id) dev_err(mcbsp->dev, "Unable to request RX IRQ %d " "for McBSP%d\n", mcbsp->rx_irq, mcbsp->id); - free_irq(mcbsp->tx_irq, (void *)mcbsp); - return err; + goto tx_irq; } } return 0; +tx_irq: + free_irq(mcbsp->tx_irq, (void *)mcbsp); +error: + if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free) + mcbsp->pdata->ops->free(id); + + /* Do procedure specific to omap34xx arch, if applicable */ + omap34xx_mcbsp_free(mcbsp); + + clk_disable(mcbsp->fclk); + clk_disable(mcbsp->iclk); + + mcbsp->free = 1; + + return err; } EXPORT_SYMBOL(omap_mcbsp_request); |