.. | .. |
---|
70 | 70 | siu_stream->rw_flg = RWF_STM_WT; |
---|
71 | 71 | |
---|
72 | 72 | /* DMA transfer start */ |
---|
73 | | - tasklet_schedule(&siu_stream->tasklet); |
---|
| 73 | + queue_work(system_highpri_wq, &siu_stream->work); |
---|
74 | 74 | |
---|
75 | 75 | return 0; |
---|
76 | 76 | } |
---|
.. | .. |
---|
93 | 93 | siu_stream->cur_period * siu_stream->period_bytes, |
---|
94 | 94 | siu_stream->buf_bytes, siu_stream->cookie); |
---|
95 | 95 | |
---|
96 | | - tasklet_schedule(&siu_stream->tasklet); |
---|
| 96 | + queue_work(system_highpri_wq, &siu_stream->work); |
---|
97 | 97 | |
---|
98 | 98 | /* Notify alsa: a period is done */ |
---|
99 | 99 | snd_pcm_period_elapsed(siu_stream->substream); |
---|
.. | .. |
---|
198 | 198 | return 0; |
---|
199 | 199 | } |
---|
200 | 200 | |
---|
201 | | -static void siu_io_tasklet(unsigned long data) |
---|
| 201 | +static void siu_io_work(struct work_struct *work) |
---|
202 | 202 | { |
---|
203 | | - struct siu_stream *siu_stream = (struct siu_stream *)data; |
---|
| 203 | + struct siu_stream *siu_stream = container_of(work, struct siu_stream, |
---|
| 204 | + work); |
---|
204 | 205 | struct snd_pcm_substream *substream = siu_stream->substream; |
---|
205 | 206 | struct device *dev = substream->pcm->card->dev; |
---|
206 | 207 | struct snd_pcm_runtime *rt = substream->runtime; |
---|
.. | .. |
---|
253 | 254 | /* during stmread flag set */ |
---|
254 | 255 | siu_stream->rw_flg = RWF_STM_RD; |
---|
255 | 256 | |
---|
256 | | - tasklet_schedule(&siu_stream->tasklet); |
---|
| 257 | + queue_work(system_highpri_wq, &siu_stream->work); |
---|
257 | 258 | |
---|
258 | 259 | return 0; |
---|
259 | 260 | } |
---|
.. | .. |
---|
281 | 282 | return 0; |
---|
282 | 283 | } |
---|
283 | 284 | |
---|
284 | | -static int siu_pcm_hw_params(struct snd_pcm_substream *ss, |
---|
285 | | - struct snd_pcm_hw_params *hw_params) |
---|
| 285 | +static bool filter(struct dma_chan *chan, void *secondary) |
---|
286 | 286 | { |
---|
287 | | - struct siu_info *info = siu_i2s_data; |
---|
288 | | - struct device *dev = ss->pcm->card->dev; |
---|
289 | | - int ret; |
---|
| 287 | + struct sh_dmae_slave *param = secondary; |
---|
290 | 288 | |
---|
291 | | - dev_dbg(dev, "%s: port=%d\n", __func__, info->port_id); |
---|
292 | | - |
---|
293 | | - ret = snd_pcm_lib_malloc_pages(ss, params_buffer_bytes(hw_params)); |
---|
294 | | - if (ret < 0) |
---|
295 | | - dev_err(dev, "snd_pcm_lib_malloc_pages() failed\n"); |
---|
296 | | - |
---|
297 | | - return ret; |
---|
298 | | -} |
---|
299 | | - |
---|
300 | | -static int siu_pcm_hw_free(struct snd_pcm_substream *ss) |
---|
301 | | -{ |
---|
302 | | - struct siu_info *info = siu_i2s_data; |
---|
303 | | - struct siu_port *port_info = siu_port_info(ss); |
---|
304 | | - struct device *dev = ss->pcm->card->dev; |
---|
305 | | - struct siu_stream *siu_stream; |
---|
306 | | - |
---|
307 | | - if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) |
---|
308 | | - siu_stream = &port_info->playback; |
---|
309 | | - else |
---|
310 | | - siu_stream = &port_info->capture; |
---|
311 | | - |
---|
312 | | - dev_dbg(dev, "%s: port=%d\n", __func__, info->port_id); |
---|
313 | | - |
---|
314 | | - return snd_pcm_lib_free_pages(ss); |
---|
315 | | -} |
---|
316 | | - |
---|
317 | | -static bool filter(struct dma_chan *chan, void *slave) |
---|
318 | | -{ |
---|
319 | | - struct sh_dmae_slave *param = slave; |
---|
320 | | - |
---|
321 | | - pr_debug("%s: slave ID %d\n", __func__, param->shdma_slave.slave_id); |
---|
| 289 | + pr_debug("%s: secondary ID %d\n", __func__, param->shdma_slave.slave_id); |
---|
322 | 290 | |
---|
323 | 291 | chan->private = ¶m->shdma_slave; |
---|
324 | 292 | return true; |
---|
325 | 293 | } |
---|
326 | 294 | |
---|
327 | | -static int siu_pcm_open(struct snd_pcm_substream *ss) |
---|
| 295 | +static int siu_pcm_open(struct snd_soc_component *component, |
---|
| 296 | + struct snd_pcm_substream *ss) |
---|
328 | 297 | { |
---|
329 | 298 | /* Playback / Capture */ |
---|
330 | | - struct snd_soc_pcm_runtime *rtd = ss->private_data; |
---|
331 | | - struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); |
---|
332 | 299 | struct siu_platform *pdata = component->dev->platform_data; |
---|
333 | 300 | struct siu_info *info = siu_i2s_data; |
---|
334 | 301 | struct siu_port *port_info = siu_port_info(ss); |
---|
.. | .. |
---|
367 | 334 | return 0; |
---|
368 | 335 | } |
---|
369 | 336 | |
---|
370 | | -static int siu_pcm_close(struct snd_pcm_substream *ss) |
---|
| 337 | +static int siu_pcm_close(struct snd_soc_component *component, |
---|
| 338 | + struct snd_pcm_substream *ss) |
---|
371 | 339 | { |
---|
372 | 340 | struct siu_info *info = siu_i2s_data; |
---|
373 | 341 | struct device *dev = ss->pcm->card->dev; |
---|
.. | .. |
---|
389 | 357 | return 0; |
---|
390 | 358 | } |
---|
391 | 359 | |
---|
392 | | -static int siu_pcm_prepare(struct snd_pcm_substream *ss) |
---|
| 360 | +static int siu_pcm_prepare(struct snd_soc_component *component, |
---|
| 361 | + struct snd_pcm_substream *ss) |
---|
393 | 362 | { |
---|
394 | 363 | struct siu_info *info = siu_i2s_data; |
---|
395 | 364 | struct siu_port *port_info = siu_port_info(ss); |
---|
.. | .. |
---|
435 | 404 | return 0; |
---|
436 | 405 | } |
---|
437 | 406 | |
---|
438 | | -static int siu_pcm_trigger(struct snd_pcm_substream *ss, int cmd) |
---|
| 407 | +static int siu_pcm_trigger(struct snd_soc_component *component, |
---|
| 408 | + struct snd_pcm_substream *ss, int cmd) |
---|
439 | 409 | { |
---|
440 | 410 | struct siu_info *info = siu_i2s_data; |
---|
441 | 411 | struct device *dev = ss->pcm->card->dev; |
---|
.. | .. |
---|
477 | 447 | * So far only resolution of one period is supported, subject to extending the |
---|
478 | 448 | * dmangine API |
---|
479 | 449 | */ |
---|
480 | | -static snd_pcm_uframes_t siu_pcm_pointer_dma(struct snd_pcm_substream *ss) |
---|
| 450 | +static snd_pcm_uframes_t |
---|
| 451 | +siu_pcm_pointer_dma(struct snd_soc_component *component, |
---|
| 452 | + struct snd_pcm_substream *ss) |
---|
481 | 453 | { |
---|
482 | 454 | struct device *dev = ss->pcm->card->dev; |
---|
483 | 455 | struct siu_info *info = siu_i2s_data; |
---|
.. | .. |
---|
512 | 484 | return bytes_to_frames(ss->runtime, ptr); |
---|
513 | 485 | } |
---|
514 | 486 | |
---|
515 | | -static int siu_pcm_new(struct snd_soc_pcm_runtime *rtd) |
---|
| 487 | +static int siu_pcm_new(struct snd_soc_component *component, |
---|
| 488 | + struct snd_soc_pcm_runtime *rtd) |
---|
516 | 489 | { |
---|
517 | 490 | /* card->dev == socdev->dev, see snd_soc_new_pcms() */ |
---|
518 | 491 | struct snd_card *card = rtd->card->snd_card; |
---|
.. | .. |
---|
541 | 514 | if (ret < 0) |
---|
542 | 515 | return ret; |
---|
543 | 516 | |
---|
544 | | - ret = snd_pcm_lib_preallocate_pages_for_all(pcm, |
---|
545 | | - SNDRV_DMA_TYPE_DEV, NULL, |
---|
| 517 | + snd_pcm_set_managed_buffer_all(pcm, |
---|
| 518 | + SNDRV_DMA_TYPE_DEV, card->dev, |
---|
546 | 519 | SIU_BUFFER_BYTES_MAX, SIU_BUFFER_BYTES_MAX); |
---|
547 | | - if (ret < 0) { |
---|
548 | | - dev_err(card->dev, |
---|
549 | | - "snd_pcm_lib_preallocate_pages_for_all() err=%d", |
---|
550 | | - ret); |
---|
551 | | - goto fail; |
---|
552 | | - } |
---|
553 | 520 | |
---|
554 | 521 | (*port_info)->pcm = pcm; |
---|
555 | 522 | |
---|
556 | | - /* IO tasklets */ |
---|
557 | | - tasklet_init(&(*port_info)->playback.tasklet, siu_io_tasklet, |
---|
558 | | - (unsigned long)&(*port_info)->playback); |
---|
559 | | - tasklet_init(&(*port_info)->capture.tasklet, siu_io_tasklet, |
---|
560 | | - (unsigned long)&(*port_info)->capture); |
---|
| 523 | + /* IO works */ |
---|
| 524 | + INIT_WORK(&(*port_info)->playback.work, siu_io_work); |
---|
| 525 | + INIT_WORK(&(*port_info)->capture.work, siu_io_work); |
---|
561 | 526 | } |
---|
562 | 527 | |
---|
563 | 528 | dev_info(card->dev, "SuperH SIU driver initialized.\n"); |
---|
564 | 529 | return 0; |
---|
565 | | - |
---|
566 | | -fail: |
---|
567 | | - siu_free_port(siu_ports[pdev->id]); |
---|
568 | | - dev_err(card->dev, "SIU: failed to initialize.\n"); |
---|
569 | | - return ret; |
---|
570 | 530 | } |
---|
571 | 531 | |
---|
572 | | -static void siu_pcm_free(struct snd_pcm *pcm) |
---|
| 532 | +static void siu_pcm_free(struct snd_soc_component *component, |
---|
| 533 | + struct snd_pcm *pcm) |
---|
573 | 534 | { |
---|
574 | 535 | struct platform_device *pdev = to_platform_device(pcm->card->dev); |
---|
575 | 536 | struct siu_port *port_info = siu_ports[pdev->id]; |
---|
576 | 537 | |
---|
577 | | - tasklet_kill(&port_info->capture.tasklet); |
---|
578 | | - tasklet_kill(&port_info->playback.tasklet); |
---|
| 538 | + cancel_work_sync(&port_info->capture.work); |
---|
| 539 | + cancel_work_sync(&port_info->playback.work); |
---|
579 | 540 | |
---|
580 | 541 | siu_free_port(port_info); |
---|
581 | 542 | |
---|
582 | 543 | dev_dbg(pcm->card->dev, "%s\n", __func__); |
---|
583 | 544 | } |
---|
584 | 545 | |
---|
585 | | -static const struct snd_pcm_ops siu_pcm_ops = { |
---|
| 546 | +const struct snd_soc_component_driver siu_component = { |
---|
| 547 | + .name = DRV_NAME, |
---|
586 | 548 | .open = siu_pcm_open, |
---|
587 | 549 | .close = siu_pcm_close, |
---|
588 | | - .ioctl = snd_pcm_lib_ioctl, |
---|
589 | | - .hw_params = siu_pcm_hw_params, |
---|
590 | | - .hw_free = siu_pcm_hw_free, |
---|
591 | 550 | .prepare = siu_pcm_prepare, |
---|
592 | 551 | .trigger = siu_pcm_trigger, |
---|
593 | 552 | .pointer = siu_pcm_pointer_dma, |
---|
594 | | -}; |
---|
595 | | - |
---|
596 | | -struct snd_soc_component_driver siu_component = { |
---|
597 | | - .name = DRV_NAME, |
---|
598 | | - .ops = &siu_pcm_ops, |
---|
599 | | - .pcm_new = siu_pcm_new, |
---|
600 | | - .pcm_free = siu_pcm_free, |
---|
| 553 | + .pcm_construct = siu_pcm_new, |
---|
| 554 | + .pcm_destruct = siu_pcm_free, |
---|
601 | 555 | }; |
---|
602 | 556 | EXPORT_SYMBOL_GPL(siu_component); |
---|