diff options
Diffstat (limited to 'arch/arm/plat-omap/mcbsp.c')
-rw-r--r-- | arch/arm/plat-omap/mcbsp.c | 56 |
1 files changed, 43 insertions, 13 deletions
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index af33fc713e1a..e5842e30e534 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c | |||
@@ -173,6 +173,10 @@ void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config) | |||
173 | OMAP_MCBSP_WRITE(io_base, MCR2, config->mcr2); | 173 | OMAP_MCBSP_WRITE(io_base, MCR2, config->mcr2); |
174 | OMAP_MCBSP_WRITE(io_base, MCR1, config->mcr1); | 174 | OMAP_MCBSP_WRITE(io_base, MCR1, config->mcr1); |
175 | OMAP_MCBSP_WRITE(io_base, PCR0, config->pcr0); | 175 | OMAP_MCBSP_WRITE(io_base, PCR0, config->pcr0); |
176 | if (cpu_is_omap2430() || cpu_is_omap34xx()) { | ||
177 | OMAP_MCBSP_WRITE(io_base, XCCR, config->xccr); | ||
178 | OMAP_MCBSP_WRITE(io_base, RCCR, config->rccr); | ||
179 | } | ||
176 | } | 180 | } |
177 | EXPORT_SYMBOL(omap_mcbsp_config); | 181 | EXPORT_SYMBOL(omap_mcbsp_config); |
178 | 182 | ||
@@ -210,6 +214,7 @@ EXPORT_SYMBOL(omap_mcbsp_set_io_type); | |||
210 | int omap_mcbsp_request(unsigned int id) | 214 | int omap_mcbsp_request(unsigned int id) |
211 | { | 215 | { |
212 | struct omap_mcbsp *mcbsp; | 216 | struct omap_mcbsp *mcbsp; |
217 | int i; | ||
213 | int err; | 218 | int err; |
214 | 219 | ||
215 | if (!omap_mcbsp_check_valid_id(id)) { | 220 | if (!omap_mcbsp_check_valid_id(id)) { |
@@ -221,7 +226,8 @@ int omap_mcbsp_request(unsigned int id) | |||
221 | if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request) | 226 | if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request) |
222 | mcbsp->pdata->ops->request(id); | 227 | mcbsp->pdata->ops->request(id); |
223 | 228 | ||
224 | clk_enable(mcbsp->clk); | 229 | for (i = 0; i < mcbsp->num_clks; i++) |
230 | clk_enable(mcbsp->clks[i]); | ||
225 | 231 | ||
226 | spin_lock(&mcbsp->lock); | 232 | spin_lock(&mcbsp->lock); |
227 | if (!mcbsp->free) { | 233 | if (!mcbsp->free) { |
@@ -272,6 +278,7 @@ EXPORT_SYMBOL(omap_mcbsp_request); | |||
272 | void omap_mcbsp_free(unsigned int id) | 278 | void omap_mcbsp_free(unsigned int id) |
273 | { | 279 | { |
274 | struct omap_mcbsp *mcbsp; | 280 | struct omap_mcbsp *mcbsp; |
281 | int i; | ||
275 | 282 | ||
276 | if (!omap_mcbsp_check_valid_id(id)) { | 283 | if (!omap_mcbsp_check_valid_id(id)) { |
277 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); | 284 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); |
@@ -282,7 +289,8 @@ void omap_mcbsp_free(unsigned int id) | |||
282 | if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free) | 289 | if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free) |
283 | mcbsp->pdata->ops->free(id); | 290 | mcbsp->pdata->ops->free(id); |
284 | 291 | ||
285 | clk_disable(mcbsp->clk); | 292 | for (i = mcbsp->num_clks - 1; i >= 0; i--) |
293 | clk_disable(mcbsp->clks[i]); | ||
286 | 294 | ||
287 | spin_lock(&mcbsp->lock); | 295 | spin_lock(&mcbsp->lock); |
288 | if (mcbsp->free) { | 296 | if (mcbsp->free) { |
@@ -868,6 +876,7 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev) | |||
868 | struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data; | 876 | struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data; |
869 | struct omap_mcbsp *mcbsp; | 877 | struct omap_mcbsp *mcbsp; |
870 | int id = pdev->id - 1; | 878 | int id = pdev->id - 1; |
879 | int i; | ||
871 | int ret = 0; | 880 | int ret = 0; |
872 | 881 | ||
873 | if (!pdata) { | 882 | if (!pdata) { |
@@ -912,14 +921,25 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev) | |||
912 | mcbsp->dma_rx_sync = pdata->dma_rx_sync; | 921 | mcbsp->dma_rx_sync = pdata->dma_rx_sync; |
913 | mcbsp->dma_tx_sync = pdata->dma_tx_sync; | 922 | mcbsp->dma_tx_sync = pdata->dma_tx_sync; |
914 | 923 | ||
915 | if (pdata->clk_name) | 924 | if (pdata->num_clks) { |
916 | mcbsp->clk = clk_get(&pdev->dev, pdata->clk_name); | 925 | mcbsp->num_clks = pdata->num_clks; |
917 | if (IS_ERR(mcbsp->clk)) { | 926 | mcbsp->clks = kzalloc(mcbsp->num_clks * sizeof(struct clk *), |
918 | dev_err(&pdev->dev, | 927 | GFP_KERNEL); |
919 | "Invalid clock configuration for McBSP%d.\n", | 928 | if (!mcbsp->clks) { |
920 | mcbsp->id); | 929 | ret = -ENOMEM; |
921 | ret = PTR_ERR(mcbsp->clk); | 930 | goto exit; |
922 | goto err_clk; | 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 | |||
923 | } | 943 | } |
924 | 944 | ||
925 | mcbsp->pdata = pdata; | 945 | mcbsp->pdata = pdata; |
@@ -928,6 +948,9 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev) | |||
928 | return 0; | 948 | return 0; |
929 | 949 | ||
930 | err_clk: | 950 | err_clk: |
951 | while (i--) | ||
952 | clk_put(mcbsp->clks[i]); | ||
953 | kfree(mcbsp->clks); | ||
931 | iounmap(mcbsp->io_base); | 954 | iounmap(mcbsp->io_base); |
932 | err_ioremap: | 955 | err_ioremap: |
933 | mcbsp->free = 0; | 956 | mcbsp->free = 0; |
@@ -938,6 +961,7 @@ exit: | |||
938 | static int __devexit omap_mcbsp_remove(struct platform_device *pdev) | 961 | static int __devexit omap_mcbsp_remove(struct platform_device *pdev) |
939 | { | 962 | { |
940 | struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev); | 963 | struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev); |
964 | int i; | ||
941 | 965 | ||
942 | platform_set_drvdata(pdev, NULL); | 966 | platform_set_drvdata(pdev, NULL); |
943 | if (mcbsp) { | 967 | if (mcbsp) { |
@@ -946,12 +970,18 @@ static int __devexit omap_mcbsp_remove(struct platform_device *pdev) | |||
946 | mcbsp->pdata->ops->free) | 970 | mcbsp->pdata->ops->free) |
947 | mcbsp->pdata->ops->free(mcbsp->id); | 971 | mcbsp->pdata->ops->free(mcbsp->id); |
948 | 972 | ||
949 | clk_disable(mcbsp->clk); | 973 | for (i = mcbsp->num_clks - 1; i >= 0; i--) { |
950 | clk_put(mcbsp->clk); | 974 | clk_disable(mcbsp->clks[i]); |
975 | clk_put(mcbsp->clks[i]); | ||
976 | } | ||
951 | 977 | ||
952 | iounmap(mcbsp->io_base); | 978 | iounmap(mcbsp->io_base); |
953 | 979 | ||
954 | mcbsp->clk = NULL; | 980 | if (mcbsp->num_clks) { |
981 | kfree(mcbsp->clks); | ||
982 | mcbsp->clks = NULL; | ||
983 | mcbsp->num_clks = 0; | ||
984 | } | ||
955 | mcbsp->free = 0; | 985 | mcbsp->free = 0; |
956 | mcbsp->dev = NULL; | 986 | mcbsp->dev = NULL; |
957 | } | 987 | } |