diff options
Diffstat (limited to 'arch/arm/plat-omap/mcbsp.c')
-rw-r--r-- | arch/arm/plat-omap/mcbsp.c | 90 |
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); | |||
214 | int omap_mcbsp_request(unsigned int id) | 214 | int 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); | |||
278 | void omap_mcbsp_free(unsigned int id) | 277 | void 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 | } |
312 | EXPORT_SYMBOL(omap_mcbsp_free); | 310 | EXPORT_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 | ||
950 | err_clk: | 940 | err_fclk: |
951 | while (i--) | 941 | clk_put(mcbsp->iclk); |
952 | clk_put(mcbsp->clks[i]); | 942 | err_iclk: |
953 | kfree(mcbsp->clks); | ||
954 | iounmap(mcbsp->io_base); | 943 | iounmap(mcbsp->io_base); |
955 | err_ioremap: | 944 | err_ioremap: |
956 | mcbsp->free = 0; | 945 | kfree(mcbsp); |
957 | exit: | 946 | exit: |
958 | return ret; | 947 | return ret; |
959 | } | 948 | } |
@@ -961,7 +950,6 @@ exit: | |||
961 | static int __devexit omap_mcbsp_remove(struct platform_device *pdev) | 950 | static 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 | |||