aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/sh/fsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/sh/fsi.c')
-rw-r--r--sound/soc/sh/fsi.c227
1 files changed, 144 insertions, 83 deletions
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 42813b808389..993abb730dfa 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -67,6 +67,7 @@
67/* DOFF_ST */ 67/* DOFF_ST */
68#define ERR_OVER 0x00000010 68#define ERR_OVER 0x00000010
69#define ERR_UNDER 0x00000001 69#define ERR_UNDER 0x00000001
70#define ST_ERR (ERR_OVER | ERR_UNDER)
70 71
71/* CLK_RST */ 72/* CLK_RST */
72#define B_CLK 0x00000010 73#define B_CLK 0x00000010
@@ -92,6 +93,7 @@
92struct fsi_priv { 93struct fsi_priv {
93 void __iomem *base; 94 void __iomem *base;
94 struct snd_pcm_substream *substream; 95 struct snd_pcm_substream *substream;
96 struct fsi_master *master;
95 97
96 int fifo_max; 98 int fifo_max;
97 int chan; 99 int chan;
@@ -108,10 +110,9 @@ struct fsi_master {
108 struct fsi_priv fsia; 110 struct fsi_priv fsia;
109 struct fsi_priv fsib; 111 struct fsi_priv fsib;
110 struct sh_fsi_platform_info *info; 112 struct sh_fsi_platform_info *info;
113 spinlock_t lock;
111}; 114};
112 115
113static struct fsi_master *master;
114
115/************************************************************************ 116/************************************************************************
116 117
117 118
@@ -119,35 +120,35 @@ static struct fsi_master *master;
119 120
120 121
121************************************************************************/ 122************************************************************************/
122static int __fsi_reg_write(u32 reg, u32 data) 123static void __fsi_reg_write(u32 reg, u32 data)
123{ 124{
124 /* valid data area is 24bit */ 125 /* valid data area is 24bit */
125 data &= 0x00ffffff; 126 data &= 0x00ffffff;
126 127
127 return ctrl_outl(data, reg); 128 __raw_writel(data, reg);
128} 129}
129 130
130static u32 __fsi_reg_read(u32 reg) 131static u32 __fsi_reg_read(u32 reg)
131{ 132{
132 return ctrl_inl(reg); 133 return __raw_readl(reg);
133} 134}
134 135
135static int __fsi_reg_mask_set(u32 reg, u32 mask, u32 data) 136static void __fsi_reg_mask_set(u32 reg, u32 mask, u32 data)
136{ 137{
137 u32 val = __fsi_reg_read(reg); 138 u32 val = __fsi_reg_read(reg);
138 139
139 val &= ~mask; 140 val &= ~mask;
140 val |= data & mask; 141 val |= data & mask;
141 142
142 return __fsi_reg_write(reg, val); 143 __fsi_reg_write(reg, val);
143} 144}
144 145
145static int fsi_reg_write(struct fsi_priv *fsi, u32 reg, u32 data) 146static void fsi_reg_write(struct fsi_priv *fsi, u32 reg, u32 data)
146{ 147{
147 if (reg > REG_END) 148 if (reg > REG_END)
148 return -1; 149 return;
149 150
150 return __fsi_reg_write((u32)(fsi->base + reg), data); 151 __fsi_reg_write((u32)(fsi->base + reg), data);
151} 152}
152 153
153static u32 fsi_reg_read(struct fsi_priv *fsi, u32 reg) 154static u32 fsi_reg_read(struct fsi_priv *fsi, u32 reg)
@@ -158,39 +159,55 @@ static u32 fsi_reg_read(struct fsi_priv *fsi, u32 reg)
158 return __fsi_reg_read((u32)(fsi->base + reg)); 159 return __fsi_reg_read((u32)(fsi->base + reg));
159} 160}
160 161
161static int fsi_reg_mask_set(struct fsi_priv *fsi, u32 reg, u32 mask, u32 data) 162static void fsi_reg_mask_set(struct fsi_priv *fsi, u32 reg, u32 mask, u32 data)
162{ 163{
163 if (reg > REG_END) 164 if (reg > REG_END)
164 return -1; 165 return;
165 166
166 return __fsi_reg_mask_set((u32)(fsi->base + reg), mask, data); 167 __fsi_reg_mask_set((u32)(fsi->base + reg), mask, data);
167} 168}
168 169
169static int fsi_master_write(u32 reg, u32 data) 170static void fsi_master_write(struct fsi_master *master, u32 reg, u32 data)
170{ 171{
172 unsigned long flags;
173
171 if ((reg < MREG_START) || 174 if ((reg < MREG_START) ||
172 (reg > MREG_END)) 175 (reg > MREG_END))
173 return -1; 176 return;
174 177
175 return __fsi_reg_write((u32)(master->base + reg), data); 178 spin_lock_irqsave(&master->lock, flags);
179 __fsi_reg_write((u32)(master->base + reg), data);
180 spin_unlock_irqrestore(&master->lock, flags);
176} 181}
177 182
178static u32 fsi_master_read(u32 reg) 183static u32 fsi_master_read(struct fsi_master *master, u32 reg)
179{ 184{
185 u32 ret;
186 unsigned long flags;
187
180 if ((reg < MREG_START) || 188 if ((reg < MREG_START) ||
181 (reg > MREG_END)) 189 (reg > MREG_END))
182 return 0; 190 return 0;
183 191
184 return __fsi_reg_read((u32)(master->base + reg)); 192 spin_lock_irqsave(&master->lock, flags);
193 ret = __fsi_reg_read((u32)(master->base + reg));
194 spin_unlock_irqrestore(&master->lock, flags);
195
196 return ret;
185} 197}
186 198
187static int fsi_master_mask_set(u32 reg, u32 mask, u32 data) 199static void fsi_master_mask_set(struct fsi_master *master,
200 u32 reg, u32 mask, u32 data)
188{ 201{
202 unsigned long flags;
203
189 if ((reg < MREG_START) || 204 if ((reg < MREG_START) ||
190 (reg > MREG_END)) 205 (reg > MREG_END))
191 return -1; 206 return;
192 207
193 return __fsi_reg_mask_set((u32)(master->base + reg), mask, data); 208 spin_lock_irqsave(&master->lock, flags);
209 __fsi_reg_mask_set((u32)(master->base + reg), mask, data);
210 spin_unlock_irqrestore(&master->lock, flags);
194} 211}
195 212
196/************************************************************************ 213/************************************************************************
@@ -200,43 +217,35 @@ static int fsi_master_mask_set(u32 reg, u32 mask, u32 data)
200 217
201 218
202************************************************************************/ 219************************************************************************/
203static struct fsi_priv *fsi_get(struct snd_pcm_substream *substream) 220static struct fsi_master *fsi_get_master(struct fsi_priv *fsi)
204{ 221{
205 struct snd_soc_pcm_runtime *rtd; 222 return fsi->master;
206 struct fsi_priv *fsi = NULL; 223}
207 224
208 if (!substream || !master) 225static int fsi_is_port_a(struct fsi_priv *fsi)
209 return NULL; 226{
227 return fsi->master->base == fsi->base;
228}
210 229
211 rtd = substream->private_data; 230static struct snd_soc_dai *fsi_get_dai(struct snd_pcm_substream *substream)
212 switch (rtd->dai->cpu_dai->id) { 231{
213 case 0: 232 struct snd_soc_pcm_runtime *rtd = substream->private_data;
214 fsi = &master->fsia; 233 struct snd_soc_dai_link *machine = rtd->dai;
215 break;
216 case 1:
217 fsi = &master->fsib;
218 break;
219 }
220 234
221 return fsi; 235 return machine->cpu_dai;
222} 236}
223 237
224static int fsi_is_port_a(struct fsi_priv *fsi) 238static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream)
225{ 239{
226 /* return 240 struct snd_soc_dai *dai = fsi_get_dai(substream);
227 * 1 : port a
228 * 0 : port b
229 */
230 241
231 if (fsi == &master->fsia) 242 return dai->private_data;
232 return 1;
233
234 return 0;
235} 243}
236 244
237static u32 fsi_get_info_flags(struct fsi_priv *fsi) 245static u32 fsi_get_info_flags(struct fsi_priv *fsi)
238{ 246{
239 int is_porta = fsi_is_port_a(fsi); 247 int is_porta = fsi_is_port_a(fsi);
248 struct fsi_master *master = fsi_get_master(fsi);
240 249
241 return is_porta ? master->info->porta_flags : 250 return is_porta ? master->info->porta_flags :
242 master->info->portb_flags; 251 master->info->portb_flags;
@@ -314,27 +323,30 @@ static int fsi_get_fifo_residue(struct fsi_priv *fsi, int is_play)
314static void fsi_irq_enable(struct fsi_priv *fsi, int is_play) 323static void fsi_irq_enable(struct fsi_priv *fsi, int is_play)
315{ 324{
316 u32 data = fsi_port_ab_io_bit(fsi, is_play); 325 u32 data = fsi_port_ab_io_bit(fsi, is_play);
326 struct fsi_master *master = fsi_get_master(fsi);
317 327
318 fsi_master_mask_set(IMSK, data, data); 328 fsi_master_mask_set(master, IMSK, data, data);
319 fsi_master_mask_set(IEMSK, data, data); 329 fsi_master_mask_set(master, IEMSK, data, data);
320} 330}
321 331
322static void fsi_irq_disable(struct fsi_priv *fsi, int is_play) 332static void fsi_irq_disable(struct fsi_priv *fsi, int is_play)
323{ 333{
324 u32 data = fsi_port_ab_io_bit(fsi, is_play); 334 u32 data = fsi_port_ab_io_bit(fsi, is_play);
335 struct fsi_master *master = fsi_get_master(fsi);
325 336
326 fsi_master_mask_set(IMSK, data, 0); 337 fsi_master_mask_set(master, IMSK, data, 0);
327 fsi_master_mask_set(IEMSK, data, 0); 338 fsi_master_mask_set(master, IEMSK, data, 0);
328} 339}
329 340
330static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable) 341static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable)
331{ 342{
332 u32 val = fsi_is_port_a(fsi) ? (1 << 0) : (1 << 4); 343 u32 val = fsi_is_port_a(fsi) ? (1 << 0) : (1 << 4);
344 struct fsi_master *master = fsi_get_master(fsi);
333 345
334 if (enable) 346 if (enable)
335 fsi_master_mask_set(CLK_RST, val, val); 347 fsi_master_mask_set(master, CLK_RST, val, val);
336 else 348 else
337 fsi_master_mask_set(CLK_RST, val, 0); 349 fsi_master_mask_set(master, CLK_RST, val, 0);
338} 350}
339 351
340static void fsi_irq_init(struct fsi_priv *fsi, int is_play) 352static void fsi_irq_init(struct fsi_priv *fsi, int is_play)
@@ -355,43 +367,46 @@ static void fsi_irq_init(struct fsi_priv *fsi, int is_play)
355 fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR); 367 fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR);
356 368
357 /* clear interrupt factor */ 369 /* clear interrupt factor */
358 fsi_master_mask_set(INT_ST, data, 0); 370 fsi_master_mask_set(fsi_get_master(fsi), INT_ST, data, 0);
359} 371}
360 372
361static void fsi_soft_all_reset(void) 373static void fsi_soft_all_reset(struct fsi_master *master)
362{ 374{
363 u32 status = fsi_master_read(SOFT_RST); 375 u32 status = fsi_master_read(master, SOFT_RST);
364 376
365 /* port AB reset */ 377 /* port AB reset */
366 status &= 0x000000ff; 378 status &= 0x000000ff;
367 fsi_master_write(SOFT_RST, status); 379 fsi_master_write(master, SOFT_RST, status);
368 mdelay(10); 380 mdelay(10);
369 381
370 /* soft reset */ 382 /* soft reset */
371 status &= 0x000000f0; 383 status &= 0x000000f0;
372 fsi_master_write(SOFT_RST, status); 384 fsi_master_write(master, SOFT_RST, status);
373 status |= 0x00000001; 385 status |= 0x00000001;
374 fsi_master_write(SOFT_RST, status); 386 fsi_master_write(master, SOFT_RST, status);
375 mdelay(10); 387 mdelay(10);
376} 388}
377 389
378/* playback interrupt */ 390/* playback interrupt */
379static int fsi_data_push(struct fsi_priv *fsi) 391static int fsi_data_push(struct fsi_priv *fsi, int startup)
380{ 392{
381 struct snd_pcm_runtime *runtime; 393 struct snd_pcm_runtime *runtime;
382 struct snd_pcm_substream *substream = NULL; 394 struct snd_pcm_substream *substream = NULL;
395 u32 status;
383 int send; 396 int send;
384 int fifo_free; 397 int fifo_free;
385 int width; 398 int width;
386 u8 *start; 399 u8 *start;
387 int i; 400 int i, over_period;
388 401
389 if (!fsi || 402 if (!fsi ||
390 !fsi->substream || 403 !fsi->substream ||
391 !fsi->substream->runtime) 404 !fsi->substream->runtime)
392 return -EINVAL; 405 return -EINVAL;
393 406
394 runtime = fsi->substream->runtime; 407 over_period = 0;
408 substream = fsi->substream;
409 runtime = substream->runtime;
395 410
396 /* FSI FIFO has limit. 411 /* FSI FIFO has limit.
397 * So, this driver can not send periods data at a time 412 * So, this driver can not send periods data at a time
@@ -399,7 +414,7 @@ static int fsi_data_push(struct fsi_priv *fsi)
399 if (fsi->byte_offset >= 414 if (fsi->byte_offset >=
400 fsi->period_len * (fsi->periods + 1)) { 415 fsi->period_len * (fsi->periods + 1)) {
401 416
402 substream = fsi->substream; 417 over_period = 1;
403 fsi->periods = (fsi->periods + 1) % runtime->periods; 418 fsi->periods = (fsi->periods + 1) % runtime->periods;
404 419
405 if (0 == fsi->periods) 420 if (0 == fsi->periods)
@@ -438,30 +453,44 @@ static int fsi_data_push(struct fsi_priv *fsi)
438 453
439 fsi->byte_offset += send * width; 454 fsi->byte_offset += send * width;
440 455
456 status = fsi_reg_read(fsi, DOFF_ST);
457 if (!startup) {
458 struct snd_soc_dai *dai = fsi_get_dai(substream);
459
460 if (status & ERR_OVER)
461 dev_err(dai->dev, "over run\n");
462 if (status & ERR_UNDER)
463 dev_err(dai->dev, "under run\n");
464 }
465 fsi_reg_write(fsi, DOFF_ST, 0);
466
441 fsi_irq_enable(fsi, 1); 467 fsi_irq_enable(fsi, 1);
442 468
443 if (substream) 469 if (over_period)
444 snd_pcm_period_elapsed(substream); 470 snd_pcm_period_elapsed(substream);
445 471
446 return 0; 472 return 0;
447} 473}
448 474
449static int fsi_data_pop(struct fsi_priv *fsi) 475static int fsi_data_pop(struct fsi_priv *fsi, int startup)
450{ 476{
451 struct snd_pcm_runtime *runtime; 477 struct snd_pcm_runtime *runtime;
452 struct snd_pcm_substream *substream = NULL; 478 struct snd_pcm_substream *substream = NULL;
479 u32 status;
453 int free; 480 int free;
454 int fifo_fill; 481 int fifo_fill;
455 int width; 482 int width;
456 u8 *start; 483 u8 *start;
457 int i; 484 int i, over_period;
458 485
459 if (!fsi || 486 if (!fsi ||
460 !fsi->substream || 487 !fsi->substream ||
461 !fsi->substream->runtime) 488 !fsi->substream->runtime)
462 return -EINVAL; 489 return -EINVAL;
463 490
464 runtime = fsi->substream->runtime; 491 over_period = 0;
492 substream = fsi->substream;
493 runtime = substream->runtime;
465 494
466 /* FSI FIFO has limit. 495 /* FSI FIFO has limit.
467 * So, this driver can not send periods data at a time 496 * So, this driver can not send periods data at a time
@@ -469,7 +498,7 @@ static int fsi_data_pop(struct fsi_priv *fsi)
469 if (fsi->byte_offset >= 498 if (fsi->byte_offset >=
470 fsi->period_len * (fsi->periods + 1)) { 499 fsi->period_len * (fsi->periods + 1)) {
471 500
472 substream = fsi->substream; 501 over_period = 1;
473 fsi->periods = (fsi->periods + 1) % runtime->periods; 502 fsi->periods = (fsi->periods + 1) % runtime->periods;
474 503
475 if (0 == fsi->periods) 504 if (0 == fsi->periods)
@@ -507,9 +536,20 @@ static int fsi_data_pop(struct fsi_priv *fsi)
507 536
508 fsi->byte_offset += fifo_fill * width; 537 fsi->byte_offset += fifo_fill * width;
509 538
539 status = fsi_reg_read(fsi, DIFF_ST);
540 if (!startup) {
541 struct snd_soc_dai *dai = fsi_get_dai(substream);
542
543 if (status & ERR_OVER)
544 dev_err(dai->dev, "over run\n");
545 if (status & ERR_UNDER)
546 dev_err(dai->dev, "under run\n");
547 }
548 fsi_reg_write(fsi, DIFF_ST, 0);
549
510 fsi_irq_enable(fsi, 0); 550 fsi_irq_enable(fsi, 0);
511 551
512 if (substream) 552 if (over_period)
513 snd_pcm_period_elapsed(substream); 553 snd_pcm_period_elapsed(substream);
514 554
515 return 0; 555 return 0;
@@ -517,23 +557,24 @@ static int fsi_data_pop(struct fsi_priv *fsi)
517 557
518static irqreturn_t fsi_interrupt(int irq, void *data) 558static irqreturn_t fsi_interrupt(int irq, void *data)
519{ 559{
520 u32 status = fsi_master_read(SOFT_RST) & ~0x00000010; 560 struct fsi_master *master = data;
521 u32 int_st = fsi_master_read(INT_ST); 561 u32 status = fsi_master_read(master, SOFT_RST) & ~0x00000010;
562 u32 int_st = fsi_master_read(master, INT_ST);
522 563
523 /* clear irq status */ 564 /* clear irq status */
524 fsi_master_write(SOFT_RST, status); 565 fsi_master_write(master, SOFT_RST, status);
525 fsi_master_write(SOFT_RST, status | 0x00000010); 566 fsi_master_write(master, SOFT_RST, status | 0x00000010);
526 567
527 if (int_st & INT_A_OUT) 568 if (int_st & INT_A_OUT)
528 fsi_data_push(&master->fsia); 569 fsi_data_push(&master->fsia, 0);
529 if (int_st & INT_B_OUT) 570 if (int_st & INT_B_OUT)
530 fsi_data_push(&master->fsib); 571 fsi_data_push(&master->fsib, 0);
531 if (int_st & INT_A_IN) 572 if (int_st & INT_A_IN)
532 fsi_data_pop(&master->fsia); 573 fsi_data_pop(&master->fsia, 0);
533 if (int_st & INT_B_IN) 574 if (int_st & INT_B_IN)
534 fsi_data_pop(&master->fsib); 575 fsi_data_pop(&master->fsib, 0);
535 576
536 fsi_master_write(INT_ST, 0x0000000); 577 fsi_master_write(master, INT_ST, 0x0000000);
537 578
538 return IRQ_HANDLED; 579 return IRQ_HANDLED;
539} 580}
@@ -548,7 +589,7 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
548static int fsi_dai_startup(struct snd_pcm_substream *substream, 589static int fsi_dai_startup(struct snd_pcm_substream *substream,
549 struct snd_soc_dai *dai) 590 struct snd_soc_dai *dai)
550{ 591{
551 struct fsi_priv *fsi = fsi_get(substream); 592 struct fsi_priv *fsi = fsi_get_priv(substream);
552 const char *msg; 593 const char *msg;
553 u32 flags = fsi_get_info_flags(fsi); 594 u32 flags = fsi_get_info_flags(fsi);
554 u32 fmt; 595 u32 fmt;
@@ -667,7 +708,7 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
667static void fsi_dai_shutdown(struct snd_pcm_substream *substream, 708static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
668 struct snd_soc_dai *dai) 709 struct snd_soc_dai *dai)
669{ 710{
670 struct fsi_priv *fsi = fsi_get(substream); 711 struct fsi_priv *fsi = fsi_get_priv(substream);
671 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 712 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
672 713
673 fsi_irq_disable(fsi, is_play); 714 fsi_irq_disable(fsi, is_play);
@@ -679,7 +720,7 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
679static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, 720static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
680 struct snd_soc_dai *dai) 721 struct snd_soc_dai *dai)
681{ 722{
682 struct fsi_priv *fsi = fsi_get(substream); 723 struct fsi_priv *fsi = fsi_get_priv(substream);
683 struct snd_pcm_runtime *runtime = substream->runtime; 724 struct snd_pcm_runtime *runtime = substream->runtime;
684 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 725 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
685 int ret = 0; 726 int ret = 0;
@@ -689,7 +730,7 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
689 fsi_stream_push(fsi, substream, 730 fsi_stream_push(fsi, substream,
690 frames_to_bytes(runtime, runtime->buffer_size), 731 frames_to_bytes(runtime, runtime->buffer_size),
691 frames_to_bytes(runtime, runtime->period_size)); 732 frames_to_bytes(runtime, runtime->period_size));
692 ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi); 733 ret = is_play ? fsi_data_push(fsi, 1) : fsi_data_pop(fsi, 1);
693 break; 734 break;
694 case SNDRV_PCM_TRIGGER_STOP: 735 case SNDRV_PCM_TRIGGER_STOP:
695 fsi_irq_disable(fsi, is_play); 736 fsi_irq_disable(fsi, is_play);
@@ -760,7 +801,7 @@ static int fsi_hw_free(struct snd_pcm_substream *substream)
760static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream) 801static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream)
761{ 802{
762 struct snd_pcm_runtime *runtime = substream->runtime; 803 struct snd_pcm_runtime *runtime = substream->runtime;
763 struct fsi_priv *fsi = fsi_get(substream); 804 struct fsi_priv *fsi = fsi_get_priv(substream);
764 long location; 805 long location;
765 806
766 location = (fsi->byte_offset - 1); 807 location = (fsi->byte_offset - 1);
@@ -870,10 +911,16 @@ EXPORT_SYMBOL_GPL(fsi_soc_platform);
870************************************************************************/ 911************************************************************************/
871static int fsi_probe(struct platform_device *pdev) 912static int fsi_probe(struct platform_device *pdev)
872{ 913{
914 struct fsi_master *master;
873 struct resource *res; 915 struct resource *res;
874 unsigned int irq; 916 unsigned int irq;
875 int ret; 917 int ret;
876 918
919 if (0 != pdev->id) {
920 dev_err(&pdev->dev, "current fsi support id 0 only now\n");
921 return -ENODEV;
922 }
923
877 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 924 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
878 irq = platform_get_irq(pdev, 0); 925 irq = platform_get_irq(pdev, 0);
879 if (!res || (int)irq <= 0) { 926 if (!res || (int)irq <= 0) {
@@ -899,15 +946,20 @@ static int fsi_probe(struct platform_device *pdev)
899 master->irq = irq; 946 master->irq = irq;
900 master->info = pdev->dev.platform_data; 947 master->info = pdev->dev.platform_data;
901 master->fsia.base = master->base; 948 master->fsia.base = master->base;
949 master->fsia.master = master;
902 master->fsib.base = master->base + 0x40; 950 master->fsib.base = master->base + 0x40;
951 master->fsib.master = master;
952 spin_lock_init(&master->lock);
903 953
904 pm_runtime_enable(&pdev->dev); 954 pm_runtime_enable(&pdev->dev);
905 pm_runtime_resume(&pdev->dev); 955 pm_runtime_resume(&pdev->dev);
906 956
907 fsi_soc_dai[0].dev = &pdev->dev; 957 fsi_soc_dai[0].dev = &pdev->dev;
958 fsi_soc_dai[0].private_data = &master->fsia;
908 fsi_soc_dai[1].dev = &pdev->dev; 959 fsi_soc_dai[1].dev = &pdev->dev;
960 fsi_soc_dai[1].private_data = &master->fsib;
909 961
910 fsi_soft_all_reset(); 962 fsi_soft_all_reset(master);
911 963
912 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, "fsi", master); 964 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, "fsi", master);
913 if (ret) { 965 if (ret) {
@@ -937,6 +989,10 @@ exit:
937 989
938static int fsi_remove(struct platform_device *pdev) 990static int fsi_remove(struct platform_device *pdev)
939{ 991{
992 struct fsi_master *master;
993
994 master = fsi_get_master(fsi_soc_dai[0].private_data);
995
940 snd_soc_unregister_dais(fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai)); 996 snd_soc_unregister_dais(fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai));
941 snd_soc_unregister_platform(&fsi_soc_platform); 997 snd_soc_unregister_platform(&fsi_soc_platform);
942 998
@@ -946,7 +1002,12 @@ static int fsi_remove(struct platform_device *pdev)
946 1002
947 iounmap(master->base); 1003 iounmap(master->base);
948 kfree(master); 1004 kfree(master);
949 master = NULL; 1005
1006 fsi_soc_dai[0].dev = NULL;
1007 fsi_soc_dai[0].private_data = NULL;
1008 fsi_soc_dai[1].dev = NULL;
1009 fsi_soc_dai[1].private_data = NULL;
1010
950 return 0; 1011 return 0;
951} 1012}
952 1013