Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[pandora-kernel.git] / arch / arm / plat-omap / mcbsp.c
index f2401a8..28b0a82 100644 (file)
@@ -222,22 +222,23 @@ int omap_mcbsp_request(unsigned int id)
        }
        mcbsp = id_to_mcbsp_ptr(id);
 
-       if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request)
-               mcbsp->pdata->ops->request(id);
-
-       clk_enable(mcbsp->clk);
-
        spin_lock(&mcbsp->lock);
        if (!mcbsp->free) {
                dev_err(mcbsp->dev, "McBSP%d is currently in use\n",
                        mcbsp->id);
                spin_unlock(&mcbsp->lock);
-               return -1;
+               return -EBUSY;
        }
 
        mcbsp->free = 0;
        spin_unlock(&mcbsp->lock);
 
+       if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request)
+               mcbsp->pdata->ops->request(id);
+
+       clk_enable(mcbsp->iclk);
+       clk_enable(mcbsp->fclk);
+
        /*
         * Make sure that transmitter, receiver and sample-rate generator are
         * not running before activating IRQs.
@@ -286,7 +287,14 @@ void omap_mcbsp_free(unsigned int id)
        if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
                mcbsp->pdata->ops->free(id);
 
-       clk_disable(mcbsp->clk);
+       clk_disable(mcbsp->fclk);
+       clk_disable(mcbsp->iclk);
+
+       if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
+               /* Free IRQs */
+               free_irq(mcbsp->rx_irq, (void *)mcbsp);
+               free_irq(mcbsp->tx_irq, (void *)mcbsp);
+       }
 
        spin_lock(&mcbsp->lock);
        if (mcbsp->free) {
@@ -298,12 +306,6 @@ void omap_mcbsp_free(unsigned int id)
 
        mcbsp->free = 1;
        spin_unlock(&mcbsp->lock);
-
-       if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
-               /* Free IRQs */
-               free_irq(mcbsp->rx_irq, (void *)mcbsp);
-               free_irq(mcbsp->tx_irq, (void *)mcbsp);
-       }
 }
 EXPORT_SYMBOL(omap_mcbsp_free);
 
@@ -894,7 +896,6 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
                ret = -ENOMEM;
                goto exit;
        }
-       mcbsp_ptr[id] = mcbsp;
 
        spin_lock_init(&mcbsp->lock);
        mcbsp->id = id + 1;
@@ -916,25 +917,32 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
        mcbsp->dma_rx_sync = pdata->dma_rx_sync;
        mcbsp->dma_tx_sync = pdata->dma_tx_sync;
 
-       if (pdata->clk_name)
-               mcbsp->clk = clk_get(&pdev->dev, pdata->clk_name);
-       if (IS_ERR(mcbsp->clk)) {
-               dev_err(&pdev->dev,
-                       "Invalid clock configuration for McBSP%d.\n",
-                       mcbsp->id);
-               ret = PTR_ERR(mcbsp->clk);
-               goto err_clk;
+       mcbsp->iclk = clk_get(&pdev->dev, "ick");
+       if (IS_ERR(mcbsp->iclk)) {
+               ret = PTR_ERR(mcbsp->iclk);
+               dev_err(&pdev->dev, "unable to get ick: %d\n", ret);
+               goto err_iclk;
+       }
+
+       mcbsp->fclk = clk_get(&pdev->dev, "fck");
+       if (IS_ERR(mcbsp->fclk)) {
+               ret = PTR_ERR(mcbsp->fclk);
+               dev_err(&pdev->dev, "unable to get fck: %d\n", ret);
+               goto err_fclk;
        }
 
        mcbsp->pdata = pdata;
        mcbsp->dev = &pdev->dev;
+       mcbsp_ptr[id] = mcbsp;
        platform_set_drvdata(pdev, mcbsp);
        return 0;
 
-err_clk:
+err_fclk:
+       clk_put(mcbsp->iclk);
+err_iclk:
        iounmap(mcbsp->io_base);
 err_ioremap:
-       mcbsp->free = 0;
+       kfree(mcbsp);
 exit:
        return ret;
 }
@@ -950,12 +958,15 @@ static int __devexit omap_mcbsp_remove(struct platform_device *pdev)
                                mcbsp->pdata->ops->free)
                        mcbsp->pdata->ops->free(mcbsp->id);
 
-               clk_disable(mcbsp->clk);
-               clk_put(mcbsp->clk);
+               clk_disable(mcbsp->fclk);
+               clk_disable(mcbsp->iclk);
+               clk_put(mcbsp->fclk);
+               clk_put(mcbsp->iclk);
 
                iounmap(mcbsp->io_base);
 
-               mcbsp->clk = NULL;
+               mcbsp->fclk = NULL;
+               mcbsp->iclk = NULL;
                mcbsp->free = 0;
                mcbsp->dev = NULL;
        }
@@ -976,4 +987,3 @@ int __init omap_mcbsp_init(void)
        /* Register the McBSP driver */
        return platform_driver_register(&omap_mcbsp_driver);
 }
-