aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap/mcbsp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-omap/mcbsp.c')
-rw-r--r--arch/arm/plat-omap/mcbsp.c90
1 files changed, 37 insertions, 53 deletions
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index e5842e30e534..28b0a824b8cf 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -214,7 +214,6 @@ EXPORT_SYMBOL(omap_mcbsp_set_io_type);
214int omap_mcbsp_request(unsigned int id) 214int omap_mcbsp_request(unsigned int id)
215{ 215{
216 struct omap_mcbsp *mcbsp; 216 struct omap_mcbsp *mcbsp;
217 int i;
218 int err; 217 int err;
219 218
220 if (!omap_mcbsp_check_valid_id(id)) { 219 if (!omap_mcbsp_check_valid_id(id)) {
@@ -223,23 +222,23 @@ int omap_mcbsp_request(unsigned int id)
223 } 222 }
224 mcbsp = id_to_mcbsp_ptr(id); 223 mcbsp = id_to_mcbsp_ptr(id);
225 224
226 if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request)
227 mcbsp->pdata->ops->request(id);
228
229 for (i = 0; i < mcbsp->num_clks; i++)
230 clk_enable(mcbsp->clks[i]);
231
232 spin_lock(&mcbsp->lock); 225 spin_lock(&mcbsp->lock);
233 if (!mcbsp->free) { 226 if (!mcbsp->free) {
234 dev_err(mcbsp->dev, "McBSP%d is currently in use\n", 227 dev_err(mcbsp->dev, "McBSP%d is currently in use\n",
235 mcbsp->id); 228 mcbsp->id);
236 spin_unlock(&mcbsp->lock); 229 spin_unlock(&mcbsp->lock);
237 return -1; 230 return -EBUSY;
238 } 231 }
239 232
240 mcbsp->free = 0; 233 mcbsp->free = 0;
241 spin_unlock(&mcbsp->lock); 234 spin_unlock(&mcbsp->lock);
242 235
236 if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request)
237 mcbsp->pdata->ops->request(id);
238
239 clk_enable(mcbsp->iclk);
240 clk_enable(mcbsp->fclk);
241
243 /* 242 /*
244 * Make sure that transmitter, receiver and sample-rate generator are 243 * Make sure that transmitter, receiver and sample-rate generator are
245 * not running before activating IRQs. 244 * not running before activating IRQs.
@@ -278,7 +277,6 @@ EXPORT_SYMBOL(omap_mcbsp_request);
278void omap_mcbsp_free(unsigned int id) 277void omap_mcbsp_free(unsigned int id)
279{ 278{
280 struct omap_mcbsp *mcbsp; 279 struct omap_mcbsp *mcbsp;
281 int i;
282 280
283 if (!omap_mcbsp_check_valid_id(id)) { 281 if (!omap_mcbsp_check_valid_id(id)) {
284 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); 282 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
@@ -289,8 +287,14 @@ void omap_mcbsp_free(unsigned int id)
289 if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free) 287 if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
290 mcbsp->pdata->ops->free(id); 288 mcbsp->pdata->ops->free(id);
291 289
292 for (i = mcbsp->num_clks - 1; i >= 0; i--) 290 clk_disable(mcbsp->fclk);
293 clk_disable(mcbsp->clks[i]); 291 clk_disable(mcbsp->iclk);
292
293 if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
294 /* Free IRQs */
295 free_irq(mcbsp->rx_irq, (void *)mcbsp);
296 free_irq(mcbsp->tx_irq, (void *)mcbsp);
297 }
294 298
295 spin_lock(&mcbsp->lock); 299 spin_lock(&mcbsp->lock);
296 if (mcbsp->free) { 300 if (mcbsp->free) {
@@ -302,12 +306,6 @@ void omap_mcbsp_free(unsigned int id)
302 306
303 mcbsp->free = 1; 307 mcbsp->free = 1;
304 spin_unlock(&mcbsp->lock); 308 spin_unlock(&mcbsp->lock);
305
306 if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
307 /* Free IRQs */
308 free_irq(mcbsp->rx_irq, (void *)mcbsp);
309 free_irq(mcbsp->tx_irq, (void *)mcbsp);
310 }
311} 309}
312EXPORT_SYMBOL(omap_mcbsp_free); 310EXPORT_SYMBOL(omap_mcbsp_free);
313 311
@@ -876,7 +874,6 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
876 struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data; 874 struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data;
877 struct omap_mcbsp *mcbsp; 875 struct omap_mcbsp *mcbsp;
878 int id = pdev->id - 1; 876 int id = pdev->id - 1;
879 int i;
880 int ret = 0; 877 int ret = 0;
881 878
882 if (!pdata) { 879 if (!pdata) {
@@ -899,7 +896,6 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
899 ret = -ENOMEM; 896 ret = -ENOMEM;
900 goto exit; 897 goto exit;
901 } 898 }
902 mcbsp_ptr[id] = mcbsp;
903 899
904 spin_lock_init(&mcbsp->lock); 900 spin_lock_init(&mcbsp->lock);
905 mcbsp->id = id + 1; 901 mcbsp->id = id + 1;
@@ -921,39 +917,32 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
921 mcbsp->dma_rx_sync = pdata->dma_rx_sync; 917 mcbsp->dma_rx_sync = pdata->dma_rx_sync;
922 mcbsp->dma_tx_sync = pdata->dma_tx_sync; 918 mcbsp->dma_tx_sync = pdata->dma_tx_sync;
923 919
924 if (pdata->num_clks) { 920 mcbsp->iclk = clk_get(&pdev->dev, "ick");
925 mcbsp->num_clks = pdata->num_clks; 921 if (IS_ERR(mcbsp->iclk)) {
926 mcbsp->clks = kzalloc(mcbsp->num_clks * sizeof(struct clk *), 922 ret = PTR_ERR(mcbsp->iclk);
927 GFP_KERNEL); 923 dev_err(&pdev->dev, "unable to get ick: %d\n", ret);
928 if (!mcbsp->clks) { 924 goto err_iclk;
929 ret = -ENOMEM; 925 }
930 goto exit;
931 }
932 for (i = 0; i < mcbsp->num_clks; i++) {
933 mcbsp->clks[i] = clk_get(&pdev->dev, pdata->clk_names[i]);
934 if (IS_ERR(mcbsp->clks[i])) {
935 dev_err(&pdev->dev,
936 "Invalid %s configuration for McBSP%d.\n",
937 pdata->clk_names[i], mcbsp->id);
938 ret = PTR_ERR(mcbsp->clks[i]);
939 goto err_clk;
940 }
941 }
942 926
927 mcbsp->fclk = clk_get(&pdev->dev, "fck");
928 if (IS_ERR(mcbsp->fclk)) {
929 ret = PTR_ERR(mcbsp->fclk);
930 dev_err(&pdev->dev, "unable to get fck: %d\n", ret);
931 goto err_fclk;
943 } 932 }
944 933
945 mcbsp->pdata = pdata; 934 mcbsp->pdata = pdata;
946 mcbsp->dev = &pdev->dev; 935 mcbsp->dev = &pdev->dev;
936 mcbsp_ptr[id] = mcbsp;
947 platform_set_drvdata(pdev, mcbsp); 937 platform_set_drvdata(pdev, mcbsp);
948 return 0; 938 return 0;
949 939
950err_clk: 940err_fclk:
951 while (i--) 941 clk_put(mcbsp->iclk);
952 clk_put(mcbsp->clks[i]); 942err_iclk:
953 kfree(mcbsp->clks);
954 iounmap(mcbsp->io_base); 943 iounmap(mcbsp->io_base);
955err_ioremap: 944err_ioremap:
956 mcbsp->free = 0; 945 kfree(mcbsp);
957exit: 946exit:
958 return ret; 947 return ret;
959} 948}
@@ -961,7 +950,6 @@ exit:
961static int __devexit omap_mcbsp_remove(struct platform_device *pdev) 950static int __devexit omap_mcbsp_remove(struct platform_device *pdev)
962{ 951{
963 struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev); 952 struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);
964 int i;
965 953
966 platform_set_drvdata(pdev, NULL); 954 platform_set_drvdata(pdev, NULL);
967 if (mcbsp) { 955 if (mcbsp) {
@@ -970,18 +958,15 @@ static int __devexit omap_mcbsp_remove(struct platform_device *pdev)
970 mcbsp->pdata->ops->free) 958 mcbsp->pdata->ops->free)
971 mcbsp->pdata->ops->free(mcbsp->id); 959 mcbsp->pdata->ops->free(mcbsp->id);
972 960
973 for (i = mcbsp->num_clks - 1; i >= 0; i--) { 961 clk_disable(mcbsp->fclk);
974 clk_disable(mcbsp->clks[i]); 962 clk_disable(mcbsp->iclk);
975 clk_put(mcbsp->clks[i]); 963 clk_put(mcbsp->fclk);
976 } 964 clk_put(mcbsp->iclk);
977 965
978 iounmap(mcbsp->io_base); 966 iounmap(mcbsp->io_base);
979 967
980 if (mcbsp->num_clks) { 968 mcbsp->fclk = NULL;
981 kfree(mcbsp->clks); 969 mcbsp->iclk = NULL;
982 mcbsp->clks = NULL;
983 mcbsp->num_clks = 0;
984 }
985 mcbsp->free = 0; 970 mcbsp->free = 0;
986 mcbsp->dev = NULL; 971 mcbsp->dev = NULL;
987 } 972 }
@@ -1002,4 +987,3 @@ int __init omap_mcbsp_init(void)
1002 /* Register the McBSP driver */ 987 /* Register the McBSP driver */
1003 return platform_driver_register(&omap_mcbsp_driver); 988 return platform_driver_register(&omap_mcbsp_driver);
1004} 989}
1005