diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-03-28 17:03:14 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-03-28 17:03:14 -0400 |
| commit | 0fe41b8982001cd14ee2c77cd776735a5024e98b (patch) | |
| tree | 83e65d595c413d55259ea14fb97748ce5efe5707 /arch/arm/plat-omap/mcbsp.c | |
| parent | eedf2c5296a8dfaaf9aec1a938c1d3bd73159a30 (diff) | |
| parent | 9759d22c8348343b0da4e25d6150c41712686c14 (diff) | |
Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm: (422 commits)
[ARM] 5435/1: fix compile warning in sanity_check_meminfo()
[ARM] 5434/1: ARM: OMAP: Fix mailbox compile for 24xx
[ARM] pxa: fix the bad assumption that PCMCIA sockets always start with 0
[ARM] pxa: fix Colibri PXA300 and PXA320 LCD backlight pins
imxfb: Fix TFT mode
i.MX21/27: remove ifdef CONFIG_FB_IMX
imxfb: add clock support
mxc: add arch_reset() function
clkdev: add possibility to get a clock based on the device name
i.MX1: remove fb support from mach-imx
[ARM] pxa: build arch/arm/plat-pxa/mfp.c only when PXA3xx or ARCH_MMP defined
Gemini: Add support for Teltonika RUT100
Gemini: gpiolib based GPIO support v2
MAINTAINERS: add myself as Gemini architecture maintainer
ARM: Add Gemini architecture v3
[ARM] OMAP: Fix compile for omap2_init_common_hw()
MAINTAINERS: Add myself as Faraday ARM core variant maintainer
ARM: Add support for FA526 v2
[ARM] acorn,ebsa110,footbridge,integrator,sa1100: Convert asm/io.h to linux/io.h
[ARM] collie: fix two minor formatting nits
...
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 | |||
