]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/arm/mach-omap1/mcbsp.c
OMAP: Fix McBSP spin_lock deadlock
[linux-2.6-omap-h63xx.git] / arch / arm / mach-omap1 / mcbsp.c
1 /*
2  * linux/arch/arm/mach-omap1/mcbsp.c
3  *
4  * Copyright (C) 2008 Instituto Nokia de Tecnologia
5  * Contact: Eduardo Valentin <eduardo.valentin@indt.org.br>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  *
11  * Multichannel mode not supported.
12  */
13 #include <linux/module.h>
14 #include <linux/init.h>
15 #include <linux/clk.h>
16 #include <linux/err.h>
17 #include <linux/io.h>
18 #include <linux/platform_device.h>
19
20 #include <mach/dma.h>
21 #include <mach/mux.h>
22 #include <mach/cpu.h>
23 #include <mach/mcbsp.h>
24 #include <mach/dsp_common.h>
25
26 #define DPS_RSTCT2_PER_EN       (1 << 0)
27 #define DSP_RSTCT2_WD_PER_EN    (1 << 1)
28
29 #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
30 const char *clk_names[] = { "dsp_ck", "api_ck", "dspxor_ck" };
31 #endif
32
33 static void omap1_mcbsp_request(unsigned int id)
34 {
35         /*
36          * On 1510, 1610 and 1710, McBSP1 and McBSP3
37          * are DSP public peripherals.
38          */
39         if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) {
40                 omap_dsp_request_mem();
41                 /*
42                  * DSP external peripheral reset
43                  * FIXME: This should be moved to dsp code
44                  */
45                 __raw_writew(__raw_readw(DSP_RSTCT2) | DPS_RSTCT2_PER_EN |
46                                 DSP_RSTCT2_WD_PER_EN, DSP_RSTCT2);
47         }
48 }
49
50 static void omap1_mcbsp_free(unsigned int id)
51 {
52         if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
53                 omap_dsp_release_mem();
54 }
55
56 static struct omap_mcbsp_ops omap1_mcbsp_ops = {
57         .request        = omap1_mcbsp_request,
58         .free           = omap1_mcbsp_free,
59 };
60
61 #ifdef CONFIG_ARCH_OMAP730
62 static struct omap_mcbsp_platform_data omap730_mcbsp_pdata[] = {
63         {
64                 .phys_base      = OMAP730_MCBSP1_BASE,
65                 .dma_rx_sync    = OMAP_DMA_MCBSP1_RX,
66                 .dma_tx_sync    = OMAP_DMA_MCBSP1_TX,
67                 .rx_irq         = INT_730_McBSP1RX,
68                 .tx_irq         = INT_730_McBSP1TX,
69                 .ops            = &omap1_mcbsp_ops,
70         },
71         {
72                 .phys_base      = OMAP730_MCBSP2_BASE,
73                 .dma_rx_sync    = OMAP_DMA_MCBSP3_RX,
74                 .dma_tx_sync    = OMAP_DMA_MCBSP3_TX,
75                 .rx_irq         = INT_730_McBSP2RX,
76                 .tx_irq         = INT_730_McBSP2TX,
77                 .ops            = &omap1_mcbsp_ops,
78         },
79 };
80 #define OMAP730_MCBSP_PDATA_SZ          ARRAY_SIZE(omap730_mcbsp_pdata)
81 #else
82 #define omap730_mcbsp_pdata             NULL
83 #define OMAP730_MCBSP_PDATA_SZ          0
84 #endif
85
86 #ifdef CONFIG_ARCH_OMAP15XX
87 static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = {
88         {
89                 .phys_base      = OMAP1510_MCBSP1_BASE,
90                 .dma_rx_sync    = OMAP_DMA_MCBSP1_RX,
91                 .dma_tx_sync    = OMAP_DMA_MCBSP1_TX,
92                 .rx_irq         = INT_McBSP1RX,
93                 .tx_irq         = INT_McBSP1TX,
94                 .ops            = &omap1_mcbsp_ops,
95                 .clk_names      = clk_names,
96                 .num_clks       = 3,
97         },
98         {
99                 .phys_base      = OMAP1510_MCBSP2_BASE,
100                 .dma_rx_sync    = OMAP_DMA_MCBSP2_RX,
101                 .dma_tx_sync    = OMAP_DMA_MCBSP2_TX,
102                 .rx_irq         = INT_1510_SPI_RX,
103                 .tx_irq         = INT_1510_SPI_TX,
104                 .ops            = &omap1_mcbsp_ops,
105         },
106         {
107                 .phys_base      = OMAP1510_MCBSP3_BASE,
108                 .dma_rx_sync    = OMAP_DMA_MCBSP3_RX,
109                 .dma_tx_sync    = OMAP_DMA_MCBSP3_TX,
110                 .rx_irq         = INT_McBSP3RX,
111                 .tx_irq         = INT_McBSP3TX,
112                 .ops            = &omap1_mcbsp_ops,
113                 .clk_names      = clk_names,
114                 .num_clks       = 3,
115         },
116 };
117 #define OMAP15XX_MCBSP_PDATA_SZ         ARRAY_SIZE(omap15xx_mcbsp_pdata)
118 #else
119 #define omap15xx_mcbsp_pdata            NULL
120 #define OMAP15XX_MCBSP_PDATA_SZ         0
121 #endif
122
123 #ifdef CONFIG_ARCH_OMAP16XX
124 static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = {
125         {
126                 .phys_base      = OMAP1610_MCBSP1_BASE,
127                 .dma_rx_sync    = OMAP_DMA_MCBSP1_RX,
128                 .dma_tx_sync    = OMAP_DMA_MCBSP1_TX,
129                 .rx_irq         = INT_McBSP1RX,
130                 .tx_irq         = INT_McBSP1TX,
131                 .ops            = &omap1_mcbsp_ops,
132                 .clk_names      = clk_names,
133                 .num_clks       = 3,
134         },
135         {
136                 .phys_base      = OMAP1610_MCBSP2_BASE,
137                 .dma_rx_sync    = OMAP_DMA_MCBSP2_RX,
138                 .dma_tx_sync    = OMAP_DMA_MCBSP2_TX,
139                 .rx_irq         = INT_1610_McBSP2_RX,
140                 .tx_irq         = INT_1610_McBSP2_TX,
141                 .ops            = &omap1_mcbsp_ops,
142         },
143         {
144                 .phys_base      = OMAP1610_MCBSP3_BASE,
145                 .dma_rx_sync    = OMAP_DMA_MCBSP3_RX,
146                 .dma_tx_sync    = OMAP_DMA_MCBSP3_TX,
147                 .rx_irq         = INT_McBSP3RX,
148                 .tx_irq         = INT_McBSP3TX,
149                 .ops            = &omap1_mcbsp_ops,
150                 .clk_names      = clk_names,
151                 .num_clks       = 3,
152         },
153 };
154 #define OMAP16XX_MCBSP_PDATA_SZ         ARRAY_SIZE(omap16xx_mcbsp_pdata)
155 #else
156 #define omap16xx_mcbsp_pdata            NULL
157 #define OMAP16XX_MCBSP_PDATA_SZ         0
158 #endif
159
160 int __init omap1_mcbsp_init(void)
161 {
162         if (cpu_is_omap730())
163                 omap_mcbsp_count = OMAP730_MCBSP_PDATA_SZ;
164         if (cpu_is_omap15xx())
165                 omap_mcbsp_count = OMAP15XX_MCBSP_PDATA_SZ;
166         if (cpu_is_omap16xx())
167                 omap_mcbsp_count = OMAP16XX_MCBSP_PDATA_SZ;
168
169         mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *),
170                                                                 GFP_KERNEL);
171         if (!mcbsp_ptr)
172                 return -ENOMEM;
173
174         if (cpu_is_omap730())
175                 omap_mcbsp_register_board_cfg(omap730_mcbsp_pdata,
176                                                 OMAP730_MCBSP_PDATA_SZ);
177
178         if (cpu_is_omap15xx())
179                 omap_mcbsp_register_board_cfg(omap15xx_mcbsp_pdata,
180                                                 OMAP15XX_MCBSP_PDATA_SZ);
181
182         if (cpu_is_omap16xx())
183                 omap_mcbsp_register_board_cfg(omap16xx_mcbsp_pdata,
184                                                 OMAP16XX_MCBSP_PDATA_SZ);
185
186         return omap_mcbsp_init();
187 }
188
189 arch_initcall(omap1_mcbsp_init);