aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap/mcbsp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-omap/mcbsp.c')
-rw-r--r--arch/arm/plat-omap/mcbsp.c431
1 files changed, 255 insertions, 176 deletions
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index 014d26574bb6..af33fc713e1a 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -27,43 +27,65 @@
27#include <mach/dma.h> 27#include <mach/dma.h>
28#include <mach/mcbsp.h> 28#include <mach/mcbsp.h>
29 29
30static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT]; 30struct omap_mcbsp **mcbsp_ptr;
31int omap_mcbsp_count;
31 32
32#define omap_mcbsp_check_valid_id(id) (mcbsp[id].pdata && \ 33void omap_mcbsp_write(void __iomem *io_base, u16 reg, u32 val)
33 mcbsp[id].pdata->ops && \ 34{
34 mcbsp[id].pdata->ops->check && \ 35 if (cpu_class_is_omap1() || cpu_is_omap2420())
35 (mcbsp[id].pdata->ops->check(id) == 0)) 36 __raw_writew((u16)val, io_base + reg);
37 else
38 __raw_writel(val, io_base + reg);
39}
40
41int omap_mcbsp_read(void __iomem *io_base, u16 reg)
42{
43 if (cpu_class_is_omap1() || cpu_is_omap2420())
44 return __raw_readw(io_base + reg);
45 else
46 return __raw_readl(io_base + reg);
47}
48
49#define OMAP_MCBSP_READ(base, reg) \
50 omap_mcbsp_read(base, OMAP_MCBSP_REG_##reg)
51#define OMAP_MCBSP_WRITE(base, reg, val) \
52 omap_mcbsp_write(base, OMAP_MCBSP_REG_##reg, val)
53
54#define omap_mcbsp_check_valid_id(id) (id < omap_mcbsp_count)
55#define id_to_mcbsp_ptr(id) mcbsp_ptr[id];
36 56
37static void omap_mcbsp_dump_reg(u8 id) 57static void omap_mcbsp_dump_reg(u8 id)
38{ 58{
39 dev_dbg(mcbsp[id].dev, "**** McBSP%d regs ****\n", mcbsp[id].id); 59 struct omap_mcbsp *mcbsp = id_to_mcbsp_ptr(id);
40 dev_dbg(mcbsp[id].dev, "DRR2: 0x%04x\n", 60
41 OMAP_MCBSP_READ(mcbsp[id].io_base, DRR2)); 61 dev_dbg(mcbsp->dev, "**** McBSP%d regs ****\n", mcbsp->id);
42 dev_dbg(mcbsp[id].dev, "DRR1: 0x%04x\n", 62 dev_dbg(mcbsp->dev, "DRR2: 0x%04x\n",
43 OMAP_MCBSP_READ(mcbsp[id].io_base, DRR1)); 63 OMAP_MCBSP_READ(mcbsp->io_base, DRR2));
44 dev_dbg(mcbsp[id].dev, "DXR2: 0x%04x\n", 64 dev_dbg(mcbsp->dev, "DRR1: 0x%04x\n",
45 OMAP_MCBSP_READ(mcbsp[id].io_base, DXR2)); 65 OMAP_MCBSP_READ(mcbsp->io_base, DRR1));
46 dev_dbg(mcbsp[id].dev, "DXR1: 0x%04x\n", 66 dev_dbg(mcbsp->dev, "DXR2: 0x%04x\n",
47 OMAP_MCBSP_READ(mcbsp[id].io_base, DXR1)); 67 OMAP_MCBSP_READ(mcbsp->io_base, DXR2));
48 dev_dbg(mcbsp[id].dev, "SPCR2: 0x%04x\n", 68 dev_dbg(mcbsp->dev, "DXR1: 0x%04x\n",
49 OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR2)); 69 OMAP_MCBSP_READ(mcbsp->io_base, DXR1));
50 dev_dbg(mcbsp[id].dev, "SPCR1: 0x%04x\n", 70 dev_dbg(mcbsp->dev, "SPCR2: 0x%04x\n",
51 OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR1)); 71 OMAP_MCBSP_READ(mcbsp->io_base, SPCR2));
52 dev_dbg(mcbsp[id].dev, "RCR2: 0x%04x\n", 72 dev_dbg(mcbsp->dev, "SPCR1: 0x%04x\n",
53 OMAP_MCBSP_READ(mcbsp[id].io_base, RCR2)); 73 OMAP_MCBSP_READ(mcbsp->io_base, SPCR1));
54 dev_dbg(mcbsp[id].dev, "RCR1: 0x%04x\n", 74 dev_dbg(mcbsp->dev, "RCR2: 0x%04x\n",
55 OMAP_MCBSP_READ(mcbsp[id].io_base, RCR1)); 75 OMAP_MCBSP_READ(mcbsp->io_base, RCR2));
56 dev_dbg(mcbsp[id].dev, "XCR2: 0x%04x\n", 76 dev_dbg(mcbsp->dev, "RCR1: 0x%04x\n",
57 OMAP_MCBSP_READ(mcbsp[id].io_base, XCR2)); 77 OMAP_MCBSP_READ(mcbsp->io_base, RCR1));
58 dev_dbg(mcbsp[id].dev, "XCR1: 0x%04x\n", 78 dev_dbg(mcbsp->dev, "XCR2: 0x%04x\n",
59 OMAP_MCBSP_READ(mcbsp[id].io_base, XCR1)); 79 OMAP_MCBSP_READ(mcbsp->io_base, XCR2));
60 dev_dbg(mcbsp[id].dev, "SRGR2: 0x%04x\n", 80 dev_dbg(mcbsp->dev, "XCR1: 0x%04x\n",
61 OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR2)); 81 OMAP_MCBSP_READ(mcbsp->io_base, XCR1));
62 dev_dbg(mcbsp[id].dev, "SRGR1: 0x%04x\n", 82 dev_dbg(mcbsp->dev, "SRGR2: 0x%04x\n",
63 OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR1)); 83 OMAP_MCBSP_READ(mcbsp->io_base, SRGR2));
64 dev_dbg(mcbsp[id].dev, "PCR0: 0x%04x\n", 84 dev_dbg(mcbsp->dev, "SRGR1: 0x%04x\n",
65 OMAP_MCBSP_READ(mcbsp[id].io_base, PCR0)); 85 OMAP_MCBSP_READ(mcbsp->io_base, SRGR1));
66 dev_dbg(mcbsp[id].dev, "***********************\n"); 86 dev_dbg(mcbsp->dev, "PCR0: 0x%04x\n",
87 OMAP_MCBSP_READ(mcbsp->io_base, PCR0));
88 dev_dbg(mcbsp->dev, "***********************\n");
67} 89}
68 90
69static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id) 91static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
@@ -126,16 +148,18 @@ static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)
126 */ 148 */
127void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config) 149void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config)
128{ 150{
129 u32 io_base; 151 struct omap_mcbsp *mcbsp;
152 void __iomem *io_base;
130 153
131 if (!omap_mcbsp_check_valid_id(id)) { 154 if (!omap_mcbsp_check_valid_id(id)) {
132 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); 155 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
133 return; 156 return;
134 } 157 }
158 mcbsp = id_to_mcbsp_ptr(id);
135 159
136 io_base = mcbsp[id].io_base; 160 io_base = mcbsp->io_base;
137 dev_dbg(mcbsp[id].dev, "Configuring McBSP%d io_base: 0x%8x\n", 161 dev_dbg(mcbsp->dev, "Configuring McBSP%d phys_base: 0x%08lx\n",
138 mcbsp[id].id, io_base); 162 mcbsp->id, mcbsp->phys_base);
139 163
140 /* We write the given config */ 164 /* We write the given config */
141 OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2); 165 OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2);
@@ -158,23 +182,26 @@ EXPORT_SYMBOL(omap_mcbsp_config);
158 */ 182 */
159int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type) 183int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type)
160{ 184{
185 struct omap_mcbsp *mcbsp;
186
161 if (!omap_mcbsp_check_valid_id(id)) { 187 if (!omap_mcbsp_check_valid_id(id)) {
162 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); 188 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
163 return -ENODEV; 189 return -ENODEV;
164 } 190 }
191 mcbsp = id_to_mcbsp_ptr(id);
165 192
166 spin_lock(&mcbsp[id].lock); 193 spin_lock(&mcbsp->lock);
167 194
168 if (!mcbsp[id].free) { 195 if (!mcbsp->free) {
169 dev_err(mcbsp[id].dev, "McBSP%d is currently in use\n", 196 dev_err(mcbsp->dev, "McBSP%d is currently in use\n",
170 mcbsp[id].id); 197 mcbsp->id);
171 spin_unlock(&mcbsp[id].lock); 198 spin_unlock(&mcbsp->lock);
172 return -EINVAL; 199 return -EINVAL;
173 } 200 }
174 201
175 mcbsp[id].io_type = io_type; 202 mcbsp->io_type = io_type;
176 203
177 spin_unlock(&mcbsp[id].lock); 204 spin_unlock(&mcbsp->lock);
178 205
179 return 0; 206 return 0;
180} 207}
@@ -182,53 +209,60 @@ EXPORT_SYMBOL(omap_mcbsp_set_io_type);
182 209
183int omap_mcbsp_request(unsigned int id) 210int omap_mcbsp_request(unsigned int id)
184{ 211{
212 struct omap_mcbsp *mcbsp;
185 int err; 213 int err;
186 214
187 if (!omap_mcbsp_check_valid_id(id)) { 215 if (!omap_mcbsp_check_valid_id(id)) {
188 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); 216 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
189 return -ENODEV; 217 return -ENODEV;
190 } 218 }
219 mcbsp = id_to_mcbsp_ptr(id);
191 220
192 if (mcbsp[id].pdata->ops->request) 221 if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request)
193 mcbsp[id].pdata->ops->request(id); 222 mcbsp->pdata->ops->request(id);
194 223
195 clk_enable(mcbsp[id].clk); 224 clk_enable(mcbsp->clk);
196 225
197 spin_lock(&mcbsp[id].lock); 226 spin_lock(&mcbsp->lock);
198 if (!mcbsp[id].free) { 227 if (!mcbsp->free) {
199 dev_err(mcbsp[id].dev, "McBSP%d is currently in use\n", 228 dev_err(mcbsp->dev, "McBSP%d is currently in use\n",
200 mcbsp[id].id); 229 mcbsp->id);
201 spin_unlock(&mcbsp[id].lock); 230 spin_unlock(&mcbsp->lock);
202 return -1; 231 return -1;
203 } 232 }
204 233
205 mcbsp[id].free = 0; 234 mcbsp->free = 0;
206 spin_unlock(&mcbsp[id].lock); 235 spin_unlock(&mcbsp->lock);
236
237 /*
238 * Make sure that transmitter, receiver and sample-rate generator are
239 * not running before activating IRQs.
240 */
241 OMAP_MCBSP_WRITE(mcbsp->io_base, SPCR1, 0);
242 OMAP_MCBSP_WRITE(mcbsp->io_base, SPCR2, 0);
207 243
208 if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) { 244 if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
209 /* We need to get IRQs here */ 245 /* We need to get IRQs here */
210 err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, 246 init_completion(&mcbsp->tx_irq_completion);
211 0, "McBSP", (void *) (&mcbsp[id])); 247 err = request_irq(mcbsp->tx_irq, omap_mcbsp_tx_irq_handler,
248 0, "McBSP", (void *)mcbsp);
212 if (err != 0) { 249 if (err != 0) {
213 dev_err(mcbsp[id].dev, "Unable to request TX IRQ %d " 250 dev_err(mcbsp->dev, "Unable to request TX IRQ %d "
214 "for McBSP%d\n", mcbsp[id].tx_irq, 251 "for McBSP%d\n", mcbsp->tx_irq,
215 mcbsp[id].id); 252 mcbsp->id);
216 return err; 253 return err;
217 } 254 }
218 255
219 init_completion(&(mcbsp[id].tx_irq_completion)); 256 init_completion(&mcbsp->rx_irq_completion);
220 257 err = request_irq(mcbsp->rx_irq, omap_mcbsp_rx_irq_handler,
221 err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, 258 0, "McBSP", (void *)mcbsp);
222 0, "McBSP", (void *) (&mcbsp[id]));
223 if (err != 0) { 259 if (err != 0) {
224 dev_err(mcbsp[id].dev, "Unable to request RX IRQ %d " 260 dev_err(mcbsp->dev, "Unable to request RX IRQ %d "
225 "for McBSP%d\n", mcbsp[id].rx_irq, 261 "for McBSP%d\n", mcbsp->rx_irq,
226 mcbsp[id].id); 262 mcbsp->id);
227 free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); 263 free_irq(mcbsp->tx_irq, (void *)mcbsp);
228 return err; 264 return err;
229 } 265 }
230
231 init_completion(&(mcbsp[id].rx_irq_completion));
232 } 266 }
233 267
234 return 0; 268 return 0;
@@ -237,31 +271,34 @@ EXPORT_SYMBOL(omap_mcbsp_request);
237 271
238void omap_mcbsp_free(unsigned int id) 272void omap_mcbsp_free(unsigned int id)
239{ 273{
274 struct omap_mcbsp *mcbsp;
275
240 if (!omap_mcbsp_check_valid_id(id)) { 276 if (!omap_mcbsp_check_valid_id(id)) {
241 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); 277 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
242 return; 278 return;
243 } 279 }
280 mcbsp = id_to_mcbsp_ptr(id);
244 281
245 if (mcbsp[id].pdata->ops->free) 282 if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
246 mcbsp[id].pdata->ops->free(id); 283 mcbsp->pdata->ops->free(id);
247 284
248 clk_disable(mcbsp[id].clk); 285 clk_disable(mcbsp->clk);
249 286
250 spin_lock(&mcbsp[id].lock); 287 spin_lock(&mcbsp->lock);
251 if (mcbsp[id].free) { 288 if (mcbsp->free) {
252 dev_err(mcbsp[id].dev, "McBSP%d was not reserved\n", 289 dev_err(mcbsp->dev, "McBSP%d was not reserved\n",
253 mcbsp[id].id); 290 mcbsp->id);
254 spin_unlock(&mcbsp[id].lock); 291 spin_unlock(&mcbsp->lock);
255 return; 292 return;
256 } 293 }
257 294
258 mcbsp[id].free = 1; 295 mcbsp->free = 1;
259 spin_unlock(&mcbsp[id].lock); 296 spin_unlock(&mcbsp->lock);
260 297
261 if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) { 298 if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
262 /* Free IRQs */ 299 /* Free IRQs */
263 free_irq(mcbsp[id].rx_irq, (void *) (&mcbsp[id])); 300 free_irq(mcbsp->rx_irq, (void *)mcbsp);
264 free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); 301 free_irq(mcbsp->tx_irq, (void *)mcbsp);
265 } 302 }
266} 303}
267EXPORT_SYMBOL(omap_mcbsp_free); 304EXPORT_SYMBOL(omap_mcbsp_free);
@@ -273,18 +310,19 @@ EXPORT_SYMBOL(omap_mcbsp_free);
273 */ 310 */
274void omap_mcbsp_start(unsigned int id) 311void omap_mcbsp_start(unsigned int id)
275{ 312{
276 u32 io_base; 313 struct omap_mcbsp *mcbsp;
314 void __iomem *io_base;
277 u16 w; 315 u16 w;
278 316
279 if (!omap_mcbsp_check_valid_id(id)) { 317 if (!omap_mcbsp_check_valid_id(id)) {
280 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); 318 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
281 return; 319 return;
282 } 320 }
321 mcbsp = id_to_mcbsp_ptr(id);
322 io_base = mcbsp->io_base;
283 323
284 io_base = mcbsp[id].io_base; 324 mcbsp->rx_word_length = (OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7;
285 325 mcbsp->tx_word_length = (OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7;
286 mcbsp[id].rx_word_length = (OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7;
287 mcbsp[id].tx_word_length = (OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7;
288 326
289 /* Start the sample generator */ 327 /* Start the sample generator */
290 w = OMAP_MCBSP_READ(io_base, SPCR2); 328 w = OMAP_MCBSP_READ(io_base, SPCR2);
@@ -310,7 +348,8 @@ EXPORT_SYMBOL(omap_mcbsp_start);
310 348
311void omap_mcbsp_stop(unsigned int id) 349void omap_mcbsp_stop(unsigned int id)
312{ 350{
313 u32 io_base; 351 struct omap_mcbsp *mcbsp;
352 void __iomem *io_base;
314 u16 w; 353 u16 w;
315 354
316 if (!omap_mcbsp_check_valid_id(id)) { 355 if (!omap_mcbsp_check_valid_id(id)) {
@@ -318,7 +357,8 @@ void omap_mcbsp_stop(unsigned int id)
318 return; 357 return;
319 } 358 }
320 359
321 io_base = mcbsp[id].io_base; 360 mcbsp = id_to_mcbsp_ptr(id);
361 io_base = mcbsp->io_base;
322 362
323 /* Reset transmitter */ 363 /* Reset transmitter */
324 w = OMAP_MCBSP_READ(io_base, SPCR2); 364 w = OMAP_MCBSP_READ(io_base, SPCR2);
@@ -337,14 +377,17 @@ EXPORT_SYMBOL(omap_mcbsp_stop);
337/* polled mcbsp i/o operations */ 377/* polled mcbsp i/o operations */
338int omap_mcbsp_pollwrite(unsigned int id, u16 buf) 378int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
339{ 379{
340 u32 base; 380 struct omap_mcbsp *mcbsp;
381 void __iomem *base;
341 382
342 if (!omap_mcbsp_check_valid_id(id)) { 383 if (!omap_mcbsp_check_valid_id(id)) {
343 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); 384 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
344 return -ENODEV; 385 return -ENODEV;
345 } 386 }
346 387
347 base = mcbsp[id].io_base; 388 mcbsp = id_to_mcbsp_ptr(id);
389 base = mcbsp->io_base;
390
348 writew(buf, base + OMAP_MCBSP_REG_DXR1); 391 writew(buf, base + OMAP_MCBSP_REG_DXR1);
349 /* if frame sync error - clear the error */ 392 /* if frame sync error - clear the error */
350 if (readw(base + OMAP_MCBSP_REG_SPCR2) & XSYNC_ERR) { 393 if (readw(base + OMAP_MCBSP_REG_SPCR2) & XSYNC_ERR) {
@@ -366,8 +409,8 @@ int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
366 (XRST), 409 (XRST),
367 base + OMAP_MCBSP_REG_SPCR2); 410 base + OMAP_MCBSP_REG_SPCR2);
368 udelay(10); 411 udelay(10);
369 dev_err(mcbsp[id].dev, "Could not write to" 412 dev_err(mcbsp->dev, "Could not write to"
370 " McBSP%d Register\n", mcbsp[id].id); 413 " McBSP%d Register\n", mcbsp->id);
371 return -2; 414 return -2;
372 } 415 }
373 } 416 }
@@ -379,14 +422,16 @@ EXPORT_SYMBOL(omap_mcbsp_pollwrite);
379 422
380int omap_mcbsp_pollread(unsigned int id, u16 *buf) 423int omap_mcbsp_pollread(unsigned int id, u16 *buf)
381{ 424{
382 u32 base; 425 struct omap_mcbsp *mcbsp;
426 void __iomem *base;
383 427
384 if (!omap_mcbsp_check_valid_id(id)) { 428 if (!omap_mcbsp_check_valid_id(id)) {
385 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); 429 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
386 return -ENODEV; 430 return -ENODEV;
387 } 431 }
432 mcbsp = id_to_mcbsp_ptr(id);
388 433
389 base = mcbsp[id].io_base; 434 base = mcbsp->io_base;
390 /* if frame sync error - clear the error */ 435 /* if frame sync error - clear the error */
391 if (readw(base + OMAP_MCBSP_REG_SPCR1) & RSYNC_ERR) { 436 if (readw(base + OMAP_MCBSP_REG_SPCR1) & RSYNC_ERR) {
392 /* clear error */ 437 /* clear error */
@@ -407,8 +452,8 @@ int omap_mcbsp_pollread(unsigned int id, u16 *buf)
407 (RRST), 452 (RRST),
408 base + OMAP_MCBSP_REG_SPCR1); 453 base + OMAP_MCBSP_REG_SPCR1);
409 udelay(10); 454 udelay(10);
410 dev_err(mcbsp[id].dev, "Could not read from" 455 dev_err(mcbsp->dev, "Could not read from"
411 " McBSP%d Register\n", mcbsp[id].id); 456 " McBSP%d Register\n", mcbsp->id);
412 return -2; 457 return -2;
413 } 458 }
414 } 459 }
@@ -424,7 +469,8 @@ EXPORT_SYMBOL(omap_mcbsp_pollread);
424 */ 469 */
425void omap_mcbsp_xmit_word(unsigned int id, u32 word) 470void omap_mcbsp_xmit_word(unsigned int id, u32 word)
426{ 471{
427 u32 io_base; 472 struct omap_mcbsp *mcbsp;
473 void __iomem *io_base;
428 omap_mcbsp_word_length word_length; 474 omap_mcbsp_word_length word_length;
429 475
430 if (!omap_mcbsp_check_valid_id(id)) { 476 if (!omap_mcbsp_check_valid_id(id)) {
@@ -432,10 +478,11 @@ void omap_mcbsp_xmit_word(unsigned int id, u32 word)
432 return; 478 return;
433 } 479 }
434 480
435 io_base = mcbsp[id].io_base; 481 mcbsp = id_to_mcbsp_ptr(id);
436 word_length = mcbsp[id].tx_word_length; 482 io_base = mcbsp->io_base;
483 word_length = mcbsp->tx_word_length;
437 484
438 wait_for_completion(&(mcbsp[id].tx_irq_completion)); 485 wait_for_completion(&mcbsp->tx_irq_completion);
439 486
440 if (word_length > OMAP_MCBSP_WORD_16) 487 if (word_length > OMAP_MCBSP_WORD_16)
441 OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16); 488 OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16);
@@ -445,7 +492,8 @@ EXPORT_SYMBOL(omap_mcbsp_xmit_word);
445 492
446u32 omap_mcbsp_recv_word(unsigned int id) 493u32 omap_mcbsp_recv_word(unsigned int id)
447{ 494{
448 u32 io_base; 495 struct omap_mcbsp *mcbsp;
496 void __iomem *io_base;
449 u16 word_lsb, word_msb = 0; 497 u16 word_lsb, word_msb = 0;
450 omap_mcbsp_word_length word_length; 498 omap_mcbsp_word_length word_length;
451 499
@@ -453,11 +501,12 @@ u32 omap_mcbsp_recv_word(unsigned int id)
453 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); 501 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
454 return -ENODEV; 502 return -ENODEV;
455 } 503 }
504 mcbsp = id_to_mcbsp_ptr(id);
456 505
457 word_length = mcbsp[id].rx_word_length; 506 word_length = mcbsp->rx_word_length;
458 io_base = mcbsp[id].io_base; 507 io_base = mcbsp->io_base;
459 508
460 wait_for_completion(&(mcbsp[id].rx_irq_completion)); 509 wait_for_completion(&mcbsp->rx_irq_completion);
461 510
462 if (word_length > OMAP_MCBSP_WORD_16) 511 if (word_length > OMAP_MCBSP_WORD_16)
463 word_msb = OMAP_MCBSP_READ(io_base, DRR2); 512 word_msb = OMAP_MCBSP_READ(io_base, DRR2);
@@ -469,7 +518,8 @@ EXPORT_SYMBOL(omap_mcbsp_recv_word);
469 518
470int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) 519int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
471{ 520{
472 u32 io_base; 521 struct omap_mcbsp *mcbsp;
522 void __iomem *io_base;
473 omap_mcbsp_word_length tx_word_length; 523 omap_mcbsp_word_length tx_word_length;
474 omap_mcbsp_word_length rx_word_length; 524 omap_mcbsp_word_length rx_word_length;
475 u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0; 525 u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
@@ -478,10 +528,10 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
478 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); 528 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
479 return -ENODEV; 529 return -ENODEV;
480 } 530 }
481 531 mcbsp = id_to_mcbsp_ptr(id);
482 io_base = mcbsp[id].io_base; 532 io_base = mcbsp->io_base;
483 tx_word_length = mcbsp[id].tx_word_length; 533 tx_word_length = mcbsp->tx_word_length;
484 rx_word_length = mcbsp[id].rx_word_length; 534 rx_word_length = mcbsp->rx_word_length;
485 535
486 if (tx_word_length != rx_word_length) 536 if (tx_word_length != rx_word_length)
487 return -EINVAL; 537 return -EINVAL;
@@ -496,8 +546,8 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
496 udelay(10); 546 udelay(10);
497 OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); 547 OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST);
498 udelay(10); 548 udelay(10);
499 dev_err(mcbsp[id].dev, "McBSP%d transmitter not " 549 dev_err(mcbsp->dev, "McBSP%d transmitter not "
500 "ready\n", mcbsp[id].id); 550 "ready\n", mcbsp->id);
501 return -EAGAIN; 551 return -EAGAIN;
502 } 552 }
503 } 553 }
@@ -517,8 +567,8 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
517 udelay(10); 567 udelay(10);
518 OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); 568 OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST);
519 udelay(10); 569 udelay(10);
520 dev_err(mcbsp[id].dev, "McBSP%d receiver not " 570 dev_err(mcbsp->dev, "McBSP%d receiver not "
521 "ready\n", mcbsp[id].id); 571 "ready\n", mcbsp->id);
522 return -EAGAIN; 572 return -EAGAIN;
523 } 573 }
524 } 574 }
@@ -534,7 +584,9 @@ EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll);
534 584
535int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word) 585int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
536{ 586{
537 u32 io_base, clock_word = 0; 587 struct omap_mcbsp *mcbsp;
588 u32 clock_word = 0;
589 void __iomem *io_base;
538 omap_mcbsp_word_length tx_word_length; 590 omap_mcbsp_word_length tx_word_length;
539 omap_mcbsp_word_length rx_word_length; 591 omap_mcbsp_word_length rx_word_length;
540 u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0; 592 u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
@@ -544,9 +596,11 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
544 return -ENODEV; 596 return -ENODEV;
545 } 597 }
546 598
547 io_base = mcbsp[id].io_base; 599 mcbsp = id_to_mcbsp_ptr(id);
548 tx_word_length = mcbsp[id].tx_word_length; 600 io_base = mcbsp->io_base;
549 rx_word_length = mcbsp[id].rx_word_length; 601
602 tx_word_length = mcbsp->tx_word_length;
603 rx_word_length = mcbsp->rx_word_length;
550 604
551 if (tx_word_length != rx_word_length) 605 if (tx_word_length != rx_word_length)
552 return -EINVAL; 606 return -EINVAL;
@@ -561,8 +615,8 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
561 udelay(10); 615 udelay(10);
562 OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); 616 OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST);
563 udelay(10); 617 udelay(10);
564 dev_err(mcbsp[id].dev, "McBSP%d transmitter not " 618 dev_err(mcbsp->dev, "McBSP%d transmitter not "
565 "ready\n", mcbsp[id].id); 619 "ready\n", mcbsp->id);
566 return -EAGAIN; 620 return -EAGAIN;
567 } 621 }
568 } 622 }
@@ -582,8 +636,8 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
582 udelay(10); 636 udelay(10);
583 OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); 637 OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST);
584 udelay(10); 638 udelay(10);
585 dev_err(mcbsp[id].dev, "McBSP%d receiver not " 639 dev_err(mcbsp->dev, "McBSP%d receiver not "
586 "ready\n", mcbsp[id].id); 640 "ready\n", mcbsp->id);
587 return -EAGAIN; 641 return -EAGAIN;
588 } 642 }
589 } 643 }
@@ -609,6 +663,7 @@ EXPORT_SYMBOL(omap_mcbsp_spi_master_recv_word_poll);
609int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, 663int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer,
610 unsigned int length) 664 unsigned int length)
611{ 665{
666 struct omap_mcbsp *mcbsp;
612 int dma_tx_ch; 667 int dma_tx_ch;
613 int src_port = 0; 668 int src_port = 0;
614 int dest_port = 0; 669 int dest_port = 0;
@@ -618,50 +673,51 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer,
618 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); 673 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
619 return -ENODEV; 674 return -ENODEV;
620 } 675 }
676 mcbsp = id_to_mcbsp_ptr(id);
621 677
622 if (omap_request_dma(mcbsp[id].dma_tx_sync, "McBSP TX", 678 if (omap_request_dma(mcbsp->dma_tx_sync, "McBSP TX",
623 omap_mcbsp_tx_dma_callback, 679 omap_mcbsp_tx_dma_callback,
624 &mcbsp[id], 680 mcbsp,
625 &dma_tx_ch)) { 681 &dma_tx_ch)) {
626 dev_err(mcbsp[id].dev, " Unable to request DMA channel for " 682 dev_err(mcbsp->dev, " Unable to request DMA channel for "
627 "McBSP%d TX. Trying IRQ based TX\n", 683 "McBSP%d TX. Trying IRQ based TX\n",
628 mcbsp[id].id); 684 mcbsp->id);
629 return -EAGAIN; 685 return -EAGAIN;
630 } 686 }
631 mcbsp[id].dma_tx_lch = dma_tx_ch; 687 mcbsp->dma_tx_lch = dma_tx_ch;
632 688
633 dev_err(mcbsp[id].dev, "McBSP%d TX DMA on channel %d\n", mcbsp[id].id, 689 dev_err(mcbsp->dev, "McBSP%d TX DMA on channel %d\n", mcbsp->id,
634 dma_tx_ch); 690 dma_tx_ch);
635 691
636 init_completion(&(mcbsp[id].tx_dma_completion)); 692 init_completion(&mcbsp->tx_dma_completion);
637 693
638 if (cpu_class_is_omap1()) { 694 if (cpu_class_is_omap1()) {
639 src_port = OMAP_DMA_PORT_TIPB; 695 src_port = OMAP_DMA_PORT_TIPB;
640 dest_port = OMAP_DMA_PORT_EMIFF; 696 dest_port = OMAP_DMA_PORT_EMIFF;
641 } 697 }
642 if (cpu_class_is_omap2()) 698 if (cpu_class_is_omap2())
643 sync_dev = mcbsp[id].dma_tx_sync; 699 sync_dev = mcbsp->dma_tx_sync;
644 700
645 omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch, 701 omap_set_dma_transfer_params(mcbsp->dma_tx_lch,
646 OMAP_DMA_DATA_TYPE_S16, 702 OMAP_DMA_DATA_TYPE_S16,
647 length >> 1, 1, 703 length >> 1, 1,
648 OMAP_DMA_SYNC_ELEMENT, 704 OMAP_DMA_SYNC_ELEMENT,
649 sync_dev, 0); 705 sync_dev, 0);
650 706
651 omap_set_dma_dest_params(mcbsp[id].dma_tx_lch, 707 omap_set_dma_dest_params(mcbsp->dma_tx_lch,
652 src_port, 708 src_port,
653 OMAP_DMA_AMODE_CONSTANT, 709 OMAP_DMA_AMODE_CONSTANT,
654 mcbsp[id].phys_base + OMAP_MCBSP_REG_DXR1, 710 mcbsp->phys_base + OMAP_MCBSP_REG_DXR1,
655 0, 0); 711 0, 0);
656 712
657 omap_set_dma_src_params(mcbsp[id].dma_tx_lch, 713 omap_set_dma_src_params(mcbsp->dma_tx_lch,
658 dest_port, 714 dest_port,
659 OMAP_DMA_AMODE_POST_INC, 715 OMAP_DMA_AMODE_POST_INC,
660 buffer, 716 buffer,
661 0, 0); 717 0, 0);
662 718
663 omap_start_dma(mcbsp[id].dma_tx_lch); 719 omap_start_dma(mcbsp->dma_tx_lch);
664 wait_for_completion(&(mcbsp[id].tx_dma_completion)); 720 wait_for_completion(&mcbsp->tx_dma_completion);
665 721
666 return 0; 722 return 0;
667} 723}
@@ -670,6 +726,7 @@ EXPORT_SYMBOL(omap_mcbsp_xmit_buffer);
670int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, 726int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer,
671 unsigned int length) 727 unsigned int length)
672{ 728{
729 struct omap_mcbsp *mcbsp;
673 int dma_rx_ch; 730 int dma_rx_ch;
674 int src_port = 0; 731 int src_port = 0;
675 int dest_port = 0; 732 int dest_port = 0;
@@ -679,50 +736,51 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer,
679 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); 736 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
680 return -ENODEV; 737 return -ENODEV;
681 } 738 }
739 mcbsp = id_to_mcbsp_ptr(id);
682 740
683 if (omap_request_dma(mcbsp[id].dma_rx_sync, "McBSP RX", 741 if (omap_request_dma(mcbsp->dma_rx_sync, "McBSP RX",
684 omap_mcbsp_rx_dma_callback, 742 omap_mcbsp_rx_dma_callback,
685 &mcbsp[id], 743 mcbsp,
686 &dma_rx_ch)) { 744 &dma_rx_ch)) {
687 dev_err(mcbsp[id].dev, "Unable to request DMA channel for " 745 dev_err(mcbsp->dev, "Unable to request DMA channel for "
688 "McBSP%d RX. Trying IRQ based RX\n", 746 "McBSP%d RX. Trying IRQ based RX\n",
689 mcbsp[id].id); 747 mcbsp->id);
690 return -EAGAIN; 748 return -EAGAIN;
691 } 749 }
692 mcbsp[id].dma_rx_lch = dma_rx_ch; 750 mcbsp->dma_rx_lch = dma_rx_ch;
693 751
694 dev_err(mcbsp[id].dev, "McBSP%d RX DMA on channel %d\n", mcbsp[id].id, 752 dev_err(mcbsp->dev, "McBSP%d RX DMA on channel %d\n", mcbsp->id,
695 dma_rx_ch); 753 dma_rx_ch);
696 754
697 init_completion(&(mcbsp[id].rx_dma_completion)); 755 init_completion(&mcbsp->rx_dma_completion);
698 756
699 if (cpu_class_is_omap1()) { 757 if (cpu_class_is_omap1()) {
700 src_port = OMAP_DMA_PORT_TIPB; 758 src_port = OMAP_DMA_PORT_TIPB;
701 dest_port = OMAP_DMA_PORT_EMIFF; 759 dest_port = OMAP_DMA_PORT_EMIFF;
702 } 760 }
703 if (cpu_class_is_omap2()) 761 if (cpu_class_is_omap2())
704 sync_dev = mcbsp[id].dma_rx_sync; 762 sync_dev = mcbsp->dma_rx_sync;
705 763
706 omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch, 764 omap_set_dma_transfer_params(mcbsp->dma_rx_lch,
707 OMAP_DMA_DATA_TYPE_S16, 765 OMAP_DMA_DATA_TYPE_S16,
708 length >> 1, 1, 766 length >> 1, 1,
709 OMAP_DMA_SYNC_ELEMENT, 767 OMAP_DMA_SYNC_ELEMENT,
710 sync_dev, 0); 768 sync_dev, 0);
711 769
712 omap_set_dma_src_params(mcbsp[id].dma_rx_lch, 770 omap_set_dma_src_params(mcbsp->dma_rx_lch,
713 src_port, 771 src_port,
714 OMAP_DMA_AMODE_CONSTANT, 772 OMAP_DMA_AMODE_CONSTANT,
715 mcbsp[id].phys_base + OMAP_MCBSP_REG_DRR1, 773 mcbsp->phys_base + OMAP_MCBSP_REG_DRR1,
716 0, 0); 774 0, 0);
717 775
718 omap_set_dma_dest_params(mcbsp[id].dma_rx_lch, 776 omap_set_dma_dest_params(mcbsp->dma_rx_lch,
719 dest_port, 777 dest_port,
720 OMAP_DMA_AMODE_POST_INC, 778 OMAP_DMA_AMODE_POST_INC,
721 buffer, 779 buffer,
722 0, 0); 780 0, 0);
723 781
724 omap_start_dma(mcbsp[id].dma_rx_lch); 782 omap_start_dma(mcbsp->dma_rx_lch);
725 wait_for_completion(&(mcbsp[id].rx_dma_completion)); 783 wait_for_completion(&mcbsp->rx_dma_completion);
726 784
727 return 0; 785 return 0;
728} 786}
@@ -737,12 +795,14 @@ EXPORT_SYMBOL(omap_mcbsp_recv_buffer);
737void omap_mcbsp_set_spi_mode(unsigned int id, 795void omap_mcbsp_set_spi_mode(unsigned int id,
738 const struct omap_mcbsp_spi_cfg *spi_cfg) 796 const struct omap_mcbsp_spi_cfg *spi_cfg)
739{ 797{
798 struct omap_mcbsp *mcbsp;
740 struct omap_mcbsp_reg_cfg mcbsp_cfg; 799 struct omap_mcbsp_reg_cfg mcbsp_cfg;
741 800
742 if (!omap_mcbsp_check_valid_id(id)) { 801 if (!omap_mcbsp_check_valid_id(id)) {
743 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); 802 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
744 return; 803 return;
745 } 804 }
805 mcbsp = id_to_mcbsp_ptr(id);
746 806
747 memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg)); 807 memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg));
748 808
@@ -803,9 +863,10 @@ EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);
803 * McBSP1 and McBSP3 are directly mapped on 1610 and 1510. 863 * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
804 * 730 has only 2 McBSP, and both of them are MPU peripherals. 864 * 730 has only 2 McBSP, and both of them are MPU peripherals.
805 */ 865 */
806static int __init omap_mcbsp_probe(struct platform_device *pdev) 866static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
807{ 867{
808 struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data; 868 struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data;
869 struct omap_mcbsp *mcbsp;
809 int id = pdev->id - 1; 870 int id = pdev->id - 1;
810 int ret = 0; 871 int ret = 0;
811 872
@@ -818,47 +879,63 @@ static int __init omap_mcbsp_probe(struct platform_device *pdev)
818 879
819 dev_dbg(&pdev->dev, "Initializing OMAP McBSP (%d).\n", pdev->id); 880 dev_dbg(&pdev->dev, "Initializing OMAP McBSP (%d).\n", pdev->id);
820 881
821 if (id >= OMAP_MAX_MCBSP_COUNT) { 882 if (id >= omap_mcbsp_count) {
822 dev_err(&pdev->dev, "Invalid McBSP device id (%d)\n", id); 883 dev_err(&pdev->dev, "Invalid McBSP device id (%d)\n", id);
823 ret = -EINVAL; 884 ret = -EINVAL;
824 goto exit; 885 goto exit;
825 } 886 }
826 887
827 spin_lock_init(&mcbsp[id].lock); 888 mcbsp = kzalloc(sizeof(struct omap_mcbsp), GFP_KERNEL);
828 mcbsp[id].id = id + 1; 889 if (!mcbsp) {
829 mcbsp[id].free = 1; 890 ret = -ENOMEM;
830 mcbsp[id].dma_tx_lch = -1; 891 goto exit;
831 mcbsp[id].dma_rx_lch = -1; 892 }
893 mcbsp_ptr[id] = mcbsp;
894
895 spin_lock_init(&mcbsp->lock);
896 mcbsp->id = id + 1;
897 mcbsp->free = 1;
898 mcbsp->dma_tx_lch = -1;
899 mcbsp->dma_rx_lch = -1;
900
901 mcbsp->phys_base = pdata->phys_base;
902 mcbsp->io_base = ioremap(pdata->phys_base, SZ_4K);
903 if (!mcbsp->io_base) {
904 ret = -ENOMEM;
905 goto err_ioremap;
906 }
832 907
833 mcbsp[id].phys_base = pdata->phys_base;
834 mcbsp[id].io_base = pdata->virt_base;
835 /* Default I/O is IRQ based */ 908 /* Default I/O is IRQ based */
836 mcbsp[id].io_type = OMAP_MCBSP_IRQ_IO; 909 mcbsp->io_type = OMAP_MCBSP_IRQ_IO;
837 mcbsp[id].tx_irq = pdata->tx_irq; 910 mcbsp->tx_irq = pdata->tx_irq;
838 mcbsp[id].rx_irq = pdata->rx_irq; 911 mcbsp->rx_irq = pdata->rx_irq;
839 mcbsp[id].dma_rx_sync = pdata->dma_rx_sync; 912 mcbsp->dma_rx_sync = pdata->dma_rx_sync;
840 mcbsp[id].dma_tx_sync = pdata->dma_tx_sync; 913 mcbsp->dma_tx_sync = pdata->dma_tx_sync;
841 914
842 if (pdata->clk_name) 915 if (pdata->clk_name)
843 mcbsp[id].clk = clk_get(&pdev->dev, pdata->clk_name); 916 mcbsp->clk = clk_get(&pdev->dev, pdata->clk_name);
844 if (IS_ERR(mcbsp[id].clk)) { 917 if (IS_ERR(mcbsp->clk)) {
845 mcbsp[id].free = 0;
846 dev_err(&pdev->dev, 918 dev_err(&pdev->dev,
847 "Invalid clock configuration for McBSP%d.\n", 919 "Invalid clock configuration for McBSP%d.\n",
848 mcbsp[id].id); 920 mcbsp->id);
849 ret = -EINVAL; 921 ret = PTR_ERR(mcbsp->clk);
850 goto exit; 922 goto err_clk;
851 } 923 }
852 924
853 mcbsp[id].pdata = pdata; 925 mcbsp->pdata = pdata;
854 mcbsp[id].dev = &pdev->dev; 926 mcbsp->dev = &pdev->dev;
855 platform_set_drvdata(pdev, &mcbsp[id]); 927 platform_set_drvdata(pdev, mcbsp);
928 return 0;
856 929
930err_clk:
931 iounmap(mcbsp->io_base);
932err_ioremap:
933 mcbsp->free = 0;
857exit: 934exit:
858 return ret; 935 return ret;
859} 936}
860 937
861static int omap_mcbsp_remove(struct platform_device *pdev) 938static int __devexit omap_mcbsp_remove(struct platform_device *pdev)
862{ 939{
863 struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev); 940 struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);
864 941
@@ -872,6 +949,8 @@ static int omap_mcbsp_remove(struct platform_device *pdev)
872 clk_disable(mcbsp->clk); 949 clk_disable(mcbsp->clk);
873 clk_put(mcbsp->clk); 950 clk_put(mcbsp->clk);
874 951
952 iounmap(mcbsp->io_base);
953
875 mcbsp->clk = NULL; 954 mcbsp->clk = NULL;
876 mcbsp->free = 0; 955 mcbsp->free = 0;
877 mcbsp->dev = NULL; 956 mcbsp->dev = NULL;
@@ -882,7 +961,7 @@ static int omap_mcbsp_remove(struct platform_device *pdev)
882 961
883static struct platform_driver omap_mcbsp_driver = { 962static struct platform_driver omap_mcbsp_driver = {
884 .probe = omap_mcbsp_probe, 963 .probe = omap_mcbsp_probe,
885 .remove = omap_mcbsp_remove, 964 .remove = __devexit_p(omap_mcbsp_remove),
886 .driver = { 965 .driver = {
887 .name = "omap-mcbsp", 966 .name = "omap-mcbsp",
888 }, 967 },