aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap/mcbsp.c
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2009-01-23 05:26:46 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-02-08 12:50:19 -0500
commitb820ce4e6736ddad7ccda528e10aaf37ad3f13f9 (patch)
tree173ca76cff521df77256564ee3905ccd0928f10f /arch/arm/plat-omap/mcbsp.c
parent1b5715ec471d1def9722e22b6cb1d24841b5e290 (diff)
[ARM] omap: mcbsp: convert to use fck/ick clocks directly
Rather than introducing a special 'mcbsp_clk' with code behind it in mach-omap*/mcbsp.c to handle the SoC specifics, arrange for the mcbsp driver to be like any other driver. mcbsp requests its fck and ick clocks directly, and the SoC specific code deals with selecting the correct clock. There is one oddity to deal with - OMAP1 fiddles with the DSP clocks and DSP reset, so we move this to the two callback functions. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
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