diff options
author | Takashi Iwai <tiwai@suse.de> | 2014-09-10 08:01:05 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2014-09-15 09:52:10 -0400 |
commit | 6336c20cdaee1dd13d01dfa8c07ce3b18bbc846f (patch) | |
tree | c974b279979eadaa0ace3768d7e231a59f62f3bd | |
parent | 9bef72bdb26e291d6dffb04768741a0e49582666 (diff) |
ALSA: lx6464es: Use nonatomic PCM ops
Like the other previous changes, this patch for lx6464es takes the
same strategy for converting to nonatomic PCM ops: replacing spinlock
with mutex, converting the irq tasklet to the threaded irq, and
merging the trigger tasklets back to the trigger callback.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | sound/pci/lx6464es/lx6464es.c | 43 | ||||
-rw-r--r-- | sound/pci/lx6464es/lx6464es.h | 9 | ||||
-rw-r--r-- | sound/pci/lx6464es/lx_core.c | 252 | ||||
-rw-r--r-- | sound/pci/lx6464es/lx_core.h | 4 |
4 files changed, 108 insertions, 200 deletions
diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c index a671f0865f71..601315a1f58f 100644 --- a/sound/pci/lx6464es/lx6464es.c +++ b/sound/pci/lx6464es/lx6464es.c | |||
@@ -279,7 +279,6 @@ static snd_pcm_uframes_t lx_pcm_stream_pointer(struct snd_pcm_substream | |||
279 | { | 279 | { |
280 | struct lx6464es *chip = snd_pcm_substream_chip(substream); | 280 | struct lx6464es *chip = snd_pcm_substream_chip(substream); |
281 | snd_pcm_uframes_t pos; | 281 | snd_pcm_uframes_t pos; |
282 | unsigned long flags; | ||
283 | int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); | 282 | int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); |
284 | 283 | ||
285 | struct lx_stream *lx_stream = is_capture ? &chip->capture_stream : | 284 | struct lx_stream *lx_stream = is_capture ? &chip->capture_stream : |
@@ -287,9 +286,9 @@ static snd_pcm_uframes_t lx_pcm_stream_pointer(struct snd_pcm_substream | |||
287 | 286 | ||
288 | dev_dbg(chip->card->dev, "->lx_pcm_stream_pointer\n"); | 287 | dev_dbg(chip->card->dev, "->lx_pcm_stream_pointer\n"); |
289 | 288 | ||
290 | spin_lock_irqsave(&chip->lock, flags); | 289 | mutex_lock(&chip->lock); |
291 | pos = lx_stream->frame_pos * substream->runtime->period_size; | 290 | pos = lx_stream->frame_pos * substream->runtime->period_size; |
292 | spin_unlock_irqrestore(&chip->lock, flags); | 291 | mutex_unlock(&chip->lock); |
293 | 292 | ||
294 | dev_dbg(chip->card->dev, "stream_pointer at %ld\n", pos); | 293 | dev_dbg(chip->card->dev, "stream_pointer at %ld\n", pos); |
295 | return pos; | 294 | return pos; |
@@ -485,8 +484,8 @@ static void lx_trigger_stop(struct lx6464es *chip, struct lx_stream *lx_stream) | |||
485 | 484 | ||
486 | } | 485 | } |
487 | 486 | ||
488 | static void lx_trigger_tasklet_dispatch_stream(struct lx6464es *chip, | 487 | static void lx_trigger_dispatch_stream(struct lx6464es *chip, |
489 | struct lx_stream *lx_stream) | 488 | struct lx_stream *lx_stream) |
490 | { | 489 | { |
491 | switch (lx_stream->status) { | 490 | switch (lx_stream->status) { |
492 | case LX_STREAM_STATUS_SCHEDULE_RUN: | 491 | case LX_STREAM_STATUS_SCHEDULE_RUN: |
@@ -502,24 +501,12 @@ static void lx_trigger_tasklet_dispatch_stream(struct lx6464es *chip, | |||
502 | } | 501 | } |
503 | } | 502 | } |
504 | 503 | ||
505 | static void lx_trigger_tasklet(unsigned long data) | ||
506 | { | ||
507 | struct lx6464es *chip = (struct lx6464es *)data; | ||
508 | unsigned long flags; | ||
509 | |||
510 | dev_dbg(chip->card->dev, "->lx_trigger_tasklet\n"); | ||
511 | |||
512 | spin_lock_irqsave(&chip->lock, flags); | ||
513 | lx_trigger_tasklet_dispatch_stream(chip, &chip->capture_stream); | ||
514 | lx_trigger_tasklet_dispatch_stream(chip, &chip->playback_stream); | ||
515 | spin_unlock_irqrestore(&chip->lock, flags); | ||
516 | } | ||
517 | |||
518 | static int lx_pcm_trigger_dispatch(struct lx6464es *chip, | 504 | static int lx_pcm_trigger_dispatch(struct lx6464es *chip, |
519 | struct lx_stream *lx_stream, int cmd) | 505 | struct lx_stream *lx_stream, int cmd) |
520 | { | 506 | { |
521 | int err = 0; | 507 | int err = 0; |
522 | 508 | ||
509 | mutex_lock(&chip->lock); | ||
523 | switch (cmd) { | 510 | switch (cmd) { |
524 | case SNDRV_PCM_TRIGGER_START: | 511 | case SNDRV_PCM_TRIGGER_START: |
525 | lx_stream->status = LX_STREAM_STATUS_SCHEDULE_RUN; | 512 | lx_stream->status = LX_STREAM_STATUS_SCHEDULE_RUN; |
@@ -533,9 +520,12 @@ static int lx_pcm_trigger_dispatch(struct lx6464es *chip, | |||
533 | err = -EINVAL; | 520 | err = -EINVAL; |
534 | goto exit; | 521 | goto exit; |
535 | } | 522 | } |
536 | tasklet_schedule(&chip->trigger_tasklet); | 523 | |
524 | lx_trigger_dispatch_stream(chip, &chip->capture_stream); | ||
525 | lx_trigger_dispatch_stream(chip, &chip->playback_stream); | ||
537 | 526 | ||
538 | exit: | 527 | exit: |
528 | mutex_unlock(&chip->lock); | ||
539 | return err; | 529 | return err; |
540 | } | 530 | } |
541 | 531 | ||
@@ -861,6 +851,7 @@ static int lx_pcm_create(struct lx6464es *chip) | |||
861 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &lx_ops_capture); | 851 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &lx_ops_capture); |
862 | 852 | ||
863 | pcm->info_flags = 0; | 853 | pcm->info_flags = 0; |
854 | pcm->nonatomic = true; | ||
864 | strcpy(pcm->name, card_name); | 855 | strcpy(pcm->name, card_name); |
865 | 856 | ||
866 | err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | 857 | err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
@@ -1009,15 +1000,9 @@ static int snd_lx6464es_create(struct snd_card *card, | |||
1009 | chip->irq = -1; | 1000 | chip->irq = -1; |
1010 | 1001 | ||
1011 | /* initialize synchronization structs */ | 1002 | /* initialize synchronization structs */ |
1012 | spin_lock_init(&chip->lock); | 1003 | mutex_init(&chip->lock); |
1013 | spin_lock_init(&chip->msg_lock); | 1004 | mutex_init(&chip->msg_lock); |
1014 | mutex_init(&chip->setup_mutex); | 1005 | mutex_init(&chip->setup_mutex); |
1015 | tasklet_init(&chip->trigger_tasklet, lx_trigger_tasklet, | ||
1016 | (unsigned long)chip); | ||
1017 | tasklet_init(&chip->tasklet_capture, lx_tasklet_capture, | ||
1018 | (unsigned long)chip); | ||
1019 | tasklet_init(&chip->tasklet_playback, lx_tasklet_playback, | ||
1020 | (unsigned long)chip); | ||
1021 | 1006 | ||
1022 | /* request resources */ | 1007 | /* request resources */ |
1023 | err = pci_request_regions(pci, card_name); | 1008 | err = pci_request_regions(pci, card_name); |
@@ -1032,8 +1017,8 @@ static int snd_lx6464es_create(struct snd_card *card, | |||
1032 | /* dsp port */ | 1017 | /* dsp port */ |
1033 | chip->port_dsp_bar = pci_ioremap_bar(pci, 2); | 1018 | chip->port_dsp_bar = pci_ioremap_bar(pci, 2); |
1034 | 1019 | ||
1035 | err = request_irq(pci->irq, lx_interrupt, IRQF_SHARED, | 1020 | err = request_threaded_irq(pci->irq, lx_interrupt, lx_threaded_irq, |
1036 | KBUILD_MODNAME, chip); | 1021 | IRQF_SHARED, KBUILD_MODNAME, chip); |
1037 | if (err) { | 1022 | if (err) { |
1038 | dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq); | 1023 | dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq); |
1039 | goto request_irq_failed; | 1024 | goto request_irq_failed; |
diff --git a/sound/pci/lx6464es/lx6464es.h b/sound/pci/lx6464es/lx6464es.h index 6792eda9c9a5..1bec187d772f 100644 --- a/sound/pci/lx6464es/lx6464es.h +++ b/sound/pci/lx6464es/lx6464es.h | |||
@@ -71,14 +71,10 @@ struct lx6464es { | |||
71 | 71 | ||
72 | u8 mac_address[6]; | 72 | u8 mac_address[6]; |
73 | 73 | ||
74 | spinlock_t lock; /* interrupt spinlock */ | 74 | struct mutex lock; /* interrupt lock */ |
75 | struct mutex setup_mutex; /* mutex used in hw_params, open | 75 | struct mutex setup_mutex; /* mutex used in hw_params, open |
76 | * and close */ | 76 | * and close */ |
77 | 77 | ||
78 | struct tasklet_struct trigger_tasklet; /* trigger tasklet */ | ||
79 | struct tasklet_struct tasklet_capture; | ||
80 | struct tasklet_struct tasklet_playback; | ||
81 | |||
82 | /* ports */ | 78 | /* ports */ |
83 | unsigned long port_plx; /* io port (size=256) */ | 79 | unsigned long port_plx; /* io port (size=256) */ |
84 | void __iomem *port_plx_remapped; /* remapped plx port */ | 80 | void __iomem *port_plx_remapped; /* remapped plx port */ |
@@ -87,8 +83,9 @@ struct lx6464es { | |||
87 | * size=8K) */ | 83 | * size=8K) */ |
88 | 84 | ||
89 | /* messaging */ | 85 | /* messaging */ |
90 | spinlock_t msg_lock; /* message spinlock */ | 86 | struct mutex msg_lock; /* message lock */ |
91 | struct lx_rmh rmh; | 87 | struct lx_rmh rmh; |
88 | u32 irqsrc; | ||
92 | 89 | ||
93 | /* configuration */ | 90 | /* configuration */ |
94 | uint freq_ratio : 2; | 91 | uint freq_ratio : 2; |
diff --git a/sound/pci/lx6464es/lx_core.c b/sound/pci/lx6464es/lx_core.c index e8f38e5df10a..f3d62020ef66 100644 --- a/sound/pci/lx6464es/lx_core.c +++ b/sound/pci/lx6464es/lx_core.c | |||
@@ -332,27 +332,25 @@ polling_successful: | |||
332 | int lx_dsp_get_version(struct lx6464es *chip, u32 *rdsp_version) | 332 | int lx_dsp_get_version(struct lx6464es *chip, u32 *rdsp_version) |
333 | { | 333 | { |
334 | u16 ret; | 334 | u16 ret; |
335 | unsigned long flags; | ||
336 | 335 | ||
337 | spin_lock_irqsave(&chip->msg_lock, flags); | 336 | mutex_lock(&chip->msg_lock); |
338 | 337 | ||
339 | lx_message_init(&chip->rmh, CMD_01_GET_SYS_CFG); | 338 | lx_message_init(&chip->rmh, CMD_01_GET_SYS_CFG); |
340 | ret = lx_message_send_atomic(chip, &chip->rmh); | 339 | ret = lx_message_send_atomic(chip, &chip->rmh); |
341 | 340 | ||
342 | *rdsp_version = chip->rmh.stat[1]; | 341 | *rdsp_version = chip->rmh.stat[1]; |
343 | spin_unlock_irqrestore(&chip->msg_lock, flags); | 342 | mutex_unlock(&chip->msg_lock); |
344 | return ret; | 343 | return ret; |
345 | } | 344 | } |
346 | 345 | ||
347 | int lx_dsp_get_clock_frequency(struct lx6464es *chip, u32 *rfreq) | 346 | int lx_dsp_get_clock_frequency(struct lx6464es *chip, u32 *rfreq) |
348 | { | 347 | { |
349 | u16 ret = 0; | 348 | u16 ret = 0; |
350 | unsigned long flags; | ||
351 | u32 freq_raw = 0; | 349 | u32 freq_raw = 0; |
352 | u32 freq = 0; | 350 | u32 freq = 0; |
353 | u32 frequency = 0; | 351 | u32 frequency = 0; |
354 | 352 | ||
355 | spin_lock_irqsave(&chip->msg_lock, flags); | 353 | mutex_lock(&chip->msg_lock); |
356 | 354 | ||
357 | lx_message_init(&chip->rmh, CMD_01_GET_SYS_CFG); | 355 | lx_message_init(&chip->rmh, CMD_01_GET_SYS_CFG); |
358 | ret = lx_message_send_atomic(chip, &chip->rmh); | 356 | ret = lx_message_send_atomic(chip, &chip->rmh); |
@@ -370,7 +368,7 @@ int lx_dsp_get_clock_frequency(struct lx6464es *chip, u32 *rfreq) | |||
370 | frequency = 48000; | 368 | frequency = 48000; |
371 | } | 369 | } |
372 | 370 | ||
373 | spin_unlock_irqrestore(&chip->msg_lock, flags); | 371 | mutex_unlock(&chip->msg_lock); |
374 | 372 | ||
375 | *rfreq = frequency * chip->freq_ratio; | 373 | *rfreq = frequency * chip->freq_ratio; |
376 | 374 | ||
@@ -398,25 +396,23 @@ int lx_dsp_get_mac(struct lx6464es *chip) | |||
398 | 396 | ||
399 | int lx_dsp_set_granularity(struct lx6464es *chip, u32 gran) | 397 | int lx_dsp_set_granularity(struct lx6464es *chip, u32 gran) |
400 | { | 398 | { |
401 | unsigned long flags; | ||
402 | int ret; | 399 | int ret; |
403 | 400 | ||
404 | spin_lock_irqsave(&chip->msg_lock, flags); | 401 | mutex_lock(&chip->msg_lock); |
405 | 402 | ||
406 | lx_message_init(&chip->rmh, CMD_02_SET_GRANULARITY); | 403 | lx_message_init(&chip->rmh, CMD_02_SET_GRANULARITY); |
407 | chip->rmh.cmd[0] |= gran; | 404 | chip->rmh.cmd[0] |= gran; |
408 | 405 | ||
409 | ret = lx_message_send_atomic(chip, &chip->rmh); | 406 | ret = lx_message_send_atomic(chip, &chip->rmh); |
410 | spin_unlock_irqrestore(&chip->msg_lock, flags); | 407 | mutex_unlock(&chip->msg_lock); |
411 | return ret; | 408 | return ret; |
412 | } | 409 | } |
413 | 410 | ||
414 | int lx_dsp_read_async_events(struct lx6464es *chip, u32 *data) | 411 | int lx_dsp_read_async_events(struct lx6464es *chip, u32 *data) |
415 | { | 412 | { |
416 | unsigned long flags; | ||
417 | int ret; | 413 | int ret; |
418 | 414 | ||
419 | spin_lock_irqsave(&chip->msg_lock, flags); | 415 | mutex_lock(&chip->msg_lock); |
420 | 416 | ||
421 | lx_message_init(&chip->rmh, CMD_04_GET_EVENT); | 417 | lx_message_init(&chip->rmh, CMD_04_GET_EVENT); |
422 | chip->rmh.stat_len = 9; /* we don't necessarily need the full length */ | 418 | chip->rmh.stat_len = 9; /* we don't necessarily need the full length */ |
@@ -426,7 +422,7 @@ int lx_dsp_read_async_events(struct lx6464es *chip, u32 *data) | |||
426 | if (!ret) | 422 | if (!ret) |
427 | memcpy(data, chip->rmh.stat, chip->rmh.stat_len * sizeof(u32)); | 423 | memcpy(data, chip->rmh.stat, chip->rmh.stat_len * sizeof(u32)); |
428 | 424 | ||
429 | spin_unlock_irqrestore(&chip->msg_lock, flags); | 425 | mutex_unlock(&chip->msg_lock); |
430 | return ret; | 426 | return ret; |
431 | } | 427 | } |
432 | 428 | ||
@@ -440,18 +436,16 @@ int lx_pipe_allocate(struct lx6464es *chip, u32 pipe, int is_capture, | |||
440 | int channels) | 436 | int channels) |
441 | { | 437 | { |
442 | int err; | 438 | int err; |
443 | unsigned long flags; | ||
444 | |||
445 | u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); | 439 | u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); |
446 | 440 | ||
447 | spin_lock_irqsave(&chip->msg_lock, flags); | 441 | mutex_lock(&chip->msg_lock); |
448 | lx_message_init(&chip->rmh, CMD_06_ALLOCATE_PIPE); | 442 | lx_message_init(&chip->rmh, CMD_06_ALLOCATE_PIPE); |
449 | 443 | ||
450 | chip->rmh.cmd[0] |= pipe_cmd; | 444 | chip->rmh.cmd[0] |= pipe_cmd; |
451 | chip->rmh.cmd[0] |= channels; | 445 | chip->rmh.cmd[0] |= channels; |
452 | 446 | ||
453 | err = lx_message_send_atomic(chip, &chip->rmh); | 447 | err = lx_message_send_atomic(chip, &chip->rmh); |
454 | spin_unlock_irqrestore(&chip->msg_lock, flags); | 448 | mutex_unlock(&chip->msg_lock); |
455 | 449 | ||
456 | if (err != 0) | 450 | if (err != 0) |
457 | dev_err(chip->card->dev, "could not allocate pipe\n"); | 451 | dev_err(chip->card->dev, "could not allocate pipe\n"); |
@@ -462,17 +456,15 @@ int lx_pipe_allocate(struct lx6464es *chip, u32 pipe, int is_capture, | |||
462 | int lx_pipe_release(struct lx6464es *chip, u32 pipe, int is_capture) | 456 | int lx_pipe_release(struct lx6464es *chip, u32 pipe, int is_capture) |
463 | { | 457 | { |
464 | int err; | 458 | int err; |
465 | unsigned long flags; | ||
466 | |||
467 | u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); | 459 | u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); |
468 | 460 | ||
469 | spin_lock_irqsave(&chip->msg_lock, flags); | 461 | mutex_lock(&chip->msg_lock); |
470 | lx_message_init(&chip->rmh, CMD_07_RELEASE_PIPE); | 462 | lx_message_init(&chip->rmh, CMD_07_RELEASE_PIPE); |
471 | 463 | ||
472 | chip->rmh.cmd[0] |= pipe_cmd; | 464 | chip->rmh.cmd[0] |= pipe_cmd; |
473 | 465 | ||
474 | err = lx_message_send_atomic(chip, &chip->rmh); | 466 | err = lx_message_send_atomic(chip, &chip->rmh); |
475 | spin_unlock_irqrestore(&chip->msg_lock, flags); | 467 | mutex_unlock(&chip->msg_lock); |
476 | 468 | ||
477 | return err; | 469 | return err; |
478 | } | 470 | } |
@@ -481,8 +473,6 @@ int lx_buffer_ask(struct lx6464es *chip, u32 pipe, int is_capture, | |||
481 | u32 *r_needed, u32 *r_freed, u32 *size_array) | 473 | u32 *r_needed, u32 *r_freed, u32 *size_array) |
482 | { | 474 | { |
483 | int err; | 475 | int err; |
484 | unsigned long flags; | ||
485 | |||
486 | u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); | 476 | u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); |
487 | 477 | ||
488 | #ifdef CONFIG_SND_DEBUG | 478 | #ifdef CONFIG_SND_DEBUG |
@@ -493,7 +483,7 @@ int lx_buffer_ask(struct lx6464es *chip, u32 pipe, int is_capture, | |||
493 | *r_needed = 0; | 483 | *r_needed = 0; |
494 | *r_freed = 0; | 484 | *r_freed = 0; |
495 | 485 | ||
496 | spin_lock_irqsave(&chip->msg_lock, flags); | 486 | mutex_lock(&chip->msg_lock); |
497 | lx_message_init(&chip->rmh, CMD_08_ASK_BUFFERS); | 487 | lx_message_init(&chip->rmh, CMD_08_ASK_BUFFERS); |
498 | 488 | ||
499 | chip->rmh.cmd[0] |= pipe_cmd; | 489 | chip->rmh.cmd[0] |= pipe_cmd; |
@@ -527,7 +517,7 @@ int lx_buffer_ask(struct lx6464es *chip, u32 pipe, int is_capture, | |||
527 | } | 517 | } |
528 | } | 518 | } |
529 | 519 | ||
530 | spin_unlock_irqrestore(&chip->msg_lock, flags); | 520 | mutex_unlock(&chip->msg_lock); |
531 | return err; | 521 | return err; |
532 | } | 522 | } |
533 | 523 | ||
@@ -535,36 +525,32 @@ int lx_buffer_ask(struct lx6464es *chip, u32 pipe, int is_capture, | |||
535 | int lx_pipe_stop(struct lx6464es *chip, u32 pipe, int is_capture) | 525 | int lx_pipe_stop(struct lx6464es *chip, u32 pipe, int is_capture) |
536 | { | 526 | { |
537 | int err; | 527 | int err; |
538 | unsigned long flags; | ||
539 | |||
540 | u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); | 528 | u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); |
541 | 529 | ||
542 | spin_lock_irqsave(&chip->msg_lock, flags); | 530 | mutex_lock(&chip->msg_lock); |
543 | lx_message_init(&chip->rmh, CMD_09_STOP_PIPE); | 531 | lx_message_init(&chip->rmh, CMD_09_STOP_PIPE); |
544 | 532 | ||
545 | chip->rmh.cmd[0] |= pipe_cmd; | 533 | chip->rmh.cmd[0] |= pipe_cmd; |
546 | 534 | ||
547 | err = lx_message_send_atomic(chip, &chip->rmh); | 535 | err = lx_message_send_atomic(chip, &chip->rmh); |
548 | 536 | ||
549 | spin_unlock_irqrestore(&chip->msg_lock, flags); | 537 | mutex_unlock(&chip->msg_lock); |
550 | return err; | 538 | return err; |
551 | } | 539 | } |
552 | 540 | ||
553 | static int lx_pipe_toggle_state(struct lx6464es *chip, u32 pipe, int is_capture) | 541 | static int lx_pipe_toggle_state(struct lx6464es *chip, u32 pipe, int is_capture) |
554 | { | 542 | { |
555 | int err; | 543 | int err; |
556 | unsigned long flags; | ||
557 | |||
558 | u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); | 544 | u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); |
559 | 545 | ||
560 | spin_lock_irqsave(&chip->msg_lock, flags); | 546 | mutex_lock(&chip->msg_lock); |
561 | lx_message_init(&chip->rmh, CMD_0B_TOGGLE_PIPE_STATE); | 547 | lx_message_init(&chip->rmh, CMD_0B_TOGGLE_PIPE_STATE); |
562 | 548 | ||
563 | chip->rmh.cmd[0] |= pipe_cmd; | 549 | chip->rmh.cmd[0] |= pipe_cmd; |
564 | 550 | ||
565 | err = lx_message_send_atomic(chip, &chip->rmh); | 551 | err = lx_message_send_atomic(chip, &chip->rmh); |
566 | 552 | ||
567 | spin_unlock_irqrestore(&chip->msg_lock, flags); | 553 | mutex_unlock(&chip->msg_lock); |
568 | return err; | 554 | return err; |
569 | } | 555 | } |
570 | 556 | ||
@@ -600,11 +586,9 @@ int lx_pipe_sample_count(struct lx6464es *chip, u32 pipe, int is_capture, | |||
600 | u64 *rsample_count) | 586 | u64 *rsample_count) |
601 | { | 587 | { |
602 | int err; | 588 | int err; |
603 | unsigned long flags; | ||
604 | |||
605 | u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); | 589 | u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); |
606 | 590 | ||
607 | spin_lock_irqsave(&chip->msg_lock, flags); | 591 | mutex_lock(&chip->msg_lock); |
608 | lx_message_init(&chip->rmh, CMD_0A_GET_PIPE_SPL_COUNT); | 592 | lx_message_init(&chip->rmh, CMD_0A_GET_PIPE_SPL_COUNT); |
609 | 593 | ||
610 | chip->rmh.cmd[0] |= pipe_cmd; | 594 | chip->rmh.cmd[0] |= pipe_cmd; |
@@ -621,18 +605,16 @@ int lx_pipe_sample_count(struct lx6464es *chip, u32 pipe, int is_capture, | |||
621 | + chip->rmh.stat[1]; /* lo part */ | 605 | + chip->rmh.stat[1]; /* lo part */ |
622 | } | 606 | } |
623 | 607 | ||
624 | spin_unlock_irqrestore(&chip->msg_lock, flags); | 608 | mutex_unlock(&chip->msg_lock); |
625 | return err; | 609 | return err; |
626 | } | 610 | } |
627 | 611 | ||
628 | int lx_pipe_state(struct lx6464es *chip, u32 pipe, int is_capture, u16 *rstate) | 612 | int lx_pipe_state(struct lx6464es *chip, u32 pipe, int is_capture, u16 *rstate) |
629 | { | 613 | { |
630 | int err; | 614 | int err; |
631 | unsigned long flags; | ||
632 | |||
633 | u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); | 615 | u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); |
634 | 616 | ||
635 | spin_lock_irqsave(&chip->msg_lock, flags); | 617 | mutex_lock(&chip->msg_lock); |
636 | lx_message_init(&chip->rmh, CMD_0A_GET_PIPE_SPL_COUNT); | 618 | lx_message_init(&chip->rmh, CMD_0A_GET_PIPE_SPL_COUNT); |
637 | 619 | ||
638 | chip->rmh.cmd[0] |= pipe_cmd; | 620 | chip->rmh.cmd[0] |= pipe_cmd; |
@@ -644,7 +626,7 @@ int lx_pipe_state(struct lx6464es *chip, u32 pipe, int is_capture, u16 *rstate) | |||
644 | else | 626 | else |
645 | *rstate = (chip->rmh.stat[0] >> PSTATE_OFFSET) & 0x0F; | 627 | *rstate = (chip->rmh.stat[0] >> PSTATE_OFFSET) & 0x0F; |
646 | 628 | ||
647 | spin_unlock_irqrestore(&chip->msg_lock, flags); | 629 | mutex_unlock(&chip->msg_lock); |
648 | return err; | 630 | return err; |
649 | } | 631 | } |
650 | 632 | ||
@@ -686,18 +668,16 @@ int lx_stream_set_state(struct lx6464es *chip, u32 pipe, | |||
686 | int is_capture, enum stream_state_t state) | 668 | int is_capture, enum stream_state_t state) |
687 | { | 669 | { |
688 | int err; | 670 | int err; |
689 | unsigned long flags; | ||
690 | |||
691 | u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); | 671 | u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); |
692 | 672 | ||
693 | spin_lock_irqsave(&chip->msg_lock, flags); | 673 | mutex_lock(&chip->msg_lock); |
694 | lx_message_init(&chip->rmh, CMD_13_SET_STREAM_STATE); | 674 | lx_message_init(&chip->rmh, CMD_13_SET_STREAM_STATE); |
695 | 675 | ||
696 | chip->rmh.cmd[0] |= pipe_cmd; | 676 | chip->rmh.cmd[0] |= pipe_cmd; |
697 | chip->rmh.cmd[0] |= state; | 677 | chip->rmh.cmd[0] |= state; |
698 | 678 | ||
699 | err = lx_message_send_atomic(chip, &chip->rmh); | 679 | err = lx_message_send_atomic(chip, &chip->rmh); |
700 | spin_unlock_irqrestore(&chip->msg_lock, flags); | 680 | mutex_unlock(&chip->msg_lock); |
701 | 681 | ||
702 | return err; | 682 | return err; |
703 | } | 683 | } |
@@ -706,17 +686,14 @@ int lx_stream_set_format(struct lx6464es *chip, struct snd_pcm_runtime *runtime, | |||
706 | u32 pipe, int is_capture) | 686 | u32 pipe, int is_capture) |
707 | { | 687 | { |
708 | int err; | 688 | int err; |
709 | unsigned long flags; | ||
710 | |||
711 | u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); | 689 | u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); |
712 | |||
713 | u32 channels = runtime->channels; | 690 | u32 channels = runtime->channels; |
714 | 691 | ||
715 | if (runtime->channels != channels) | 692 | if (runtime->channels != channels) |
716 | dev_err(chip->card->dev, "channel count mismatch: %d vs %d", | 693 | dev_err(chip->card->dev, "channel count mismatch: %d vs %d", |
717 | runtime->channels, channels); | 694 | runtime->channels, channels); |
718 | 695 | ||
719 | spin_lock_irqsave(&chip->msg_lock, flags); | 696 | mutex_lock(&chip->msg_lock); |
720 | lx_message_init(&chip->rmh, CMD_0C_DEF_STREAM); | 697 | lx_message_init(&chip->rmh, CMD_0C_DEF_STREAM); |
721 | 698 | ||
722 | chip->rmh.cmd[0] |= pipe_cmd; | 699 | chip->rmh.cmd[0] |= pipe_cmd; |
@@ -732,7 +709,7 @@ int lx_stream_set_format(struct lx6464es *chip, struct snd_pcm_runtime *runtime, | |||
732 | chip->rmh.cmd[0] |= channels-1; | 709 | chip->rmh.cmd[0] |= channels-1; |
733 | 710 | ||
734 | err = lx_message_send_atomic(chip, &chip->rmh); | 711 | err = lx_message_send_atomic(chip, &chip->rmh); |
735 | spin_unlock_irqrestore(&chip->msg_lock, flags); | 712 | mutex_unlock(&chip->msg_lock); |
736 | 713 | ||
737 | return err; | 714 | return err; |
738 | } | 715 | } |
@@ -741,11 +718,9 @@ int lx_stream_state(struct lx6464es *chip, u32 pipe, int is_capture, | |||
741 | int *rstate) | 718 | int *rstate) |
742 | { | 719 | { |
743 | int err; | 720 | int err; |
744 | unsigned long flags; | ||
745 | |||
746 | u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); | 721 | u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); |
747 | 722 | ||
748 | spin_lock_irqsave(&chip->msg_lock, flags); | 723 | mutex_lock(&chip->msg_lock); |
749 | lx_message_init(&chip->rmh, CMD_0E_GET_STREAM_SPL_COUNT); | 724 | lx_message_init(&chip->rmh, CMD_0E_GET_STREAM_SPL_COUNT); |
750 | 725 | ||
751 | chip->rmh.cmd[0] |= pipe_cmd; | 726 | chip->rmh.cmd[0] |= pipe_cmd; |
@@ -754,7 +729,7 @@ int lx_stream_state(struct lx6464es *chip, u32 pipe, int is_capture, | |||
754 | 729 | ||
755 | *rstate = (chip->rmh.stat[0] & SF_START) ? START_STATE : PAUSE_STATE; | 730 | *rstate = (chip->rmh.stat[0] & SF_START) ? START_STATE : PAUSE_STATE; |
756 | 731 | ||
757 | spin_unlock_irqrestore(&chip->msg_lock, flags); | 732 | mutex_unlock(&chip->msg_lock); |
758 | return err; | 733 | return err; |
759 | } | 734 | } |
760 | 735 | ||
@@ -762,11 +737,9 @@ int lx_stream_sample_position(struct lx6464es *chip, u32 pipe, int is_capture, | |||
762 | u64 *r_bytepos) | 737 | u64 *r_bytepos) |
763 | { | 738 | { |
764 | int err; | 739 | int err; |
765 | unsigned long flags; | ||
766 | |||
767 | u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); | 740 | u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); |
768 | 741 | ||
769 | spin_lock_irqsave(&chip->msg_lock, flags); | 742 | mutex_lock(&chip->msg_lock); |
770 | lx_message_init(&chip->rmh, CMD_0E_GET_STREAM_SPL_COUNT); | 743 | lx_message_init(&chip->rmh, CMD_0E_GET_STREAM_SPL_COUNT); |
771 | 744 | ||
772 | chip->rmh.cmd[0] |= pipe_cmd; | 745 | chip->rmh.cmd[0] |= pipe_cmd; |
@@ -777,7 +750,7 @@ int lx_stream_sample_position(struct lx6464es *chip, u32 pipe, int is_capture, | |||
777 | << 32) /* hi part */ | 750 | << 32) /* hi part */ |
778 | + chip->rmh.stat[1]; /* lo part */ | 751 | + chip->rmh.stat[1]; /* lo part */ |
779 | 752 | ||
780 | spin_unlock_irqrestore(&chip->msg_lock, flags); | 753 | mutex_unlock(&chip->msg_lock); |
781 | return err; | 754 | return err; |
782 | } | 755 | } |
783 | 756 | ||
@@ -787,11 +760,9 @@ int lx_buffer_give(struct lx6464es *chip, u32 pipe, int is_capture, | |||
787 | u32 *r_buffer_index) | 760 | u32 *r_buffer_index) |
788 | { | 761 | { |
789 | int err; | 762 | int err; |
790 | unsigned long flags; | ||
791 | |||
792 | u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); | 763 | u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); |
793 | 764 | ||
794 | spin_lock_irqsave(&chip->msg_lock, flags); | 765 | mutex_lock(&chip->msg_lock); |
795 | lx_message_init(&chip->rmh, CMD_0F_UPDATE_BUFFER); | 766 | lx_message_init(&chip->rmh, CMD_0F_UPDATE_BUFFER); |
796 | 767 | ||
797 | chip->rmh.cmd[0] |= pipe_cmd; | 768 | chip->rmh.cmd[0] |= pipe_cmd; |
@@ -828,7 +799,7 @@ int lx_buffer_give(struct lx6464es *chip, u32 pipe, int is_capture, | |||
828 | "lx_buffer_give EB_CMD_REFUSED\n"); | 799 | "lx_buffer_give EB_CMD_REFUSED\n"); |
829 | 800 | ||
830 | done: | 801 | done: |
831 | spin_unlock_irqrestore(&chip->msg_lock, flags); | 802 | mutex_unlock(&chip->msg_lock); |
832 | return err; | 803 | return err; |
833 | } | 804 | } |
834 | 805 | ||
@@ -836,11 +807,9 @@ int lx_buffer_free(struct lx6464es *chip, u32 pipe, int is_capture, | |||
836 | u32 *r_buffer_size) | 807 | u32 *r_buffer_size) |
837 | { | 808 | { |
838 | int err; | 809 | int err; |
839 | unsigned long flags; | ||
840 | |||
841 | u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); | 810 | u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); |
842 | 811 | ||
843 | spin_lock_irqsave(&chip->msg_lock, flags); | 812 | mutex_lock(&chip->msg_lock); |
844 | lx_message_init(&chip->rmh, CMD_11_CANCEL_BUFFER); | 813 | lx_message_init(&chip->rmh, CMD_11_CANCEL_BUFFER); |
845 | 814 | ||
846 | chip->rmh.cmd[0] |= pipe_cmd; | 815 | chip->rmh.cmd[0] |= pipe_cmd; |
@@ -852,7 +821,7 @@ int lx_buffer_free(struct lx6464es *chip, u32 pipe, int is_capture, | |||
852 | if (err == 0) | 821 | if (err == 0) |
853 | *r_buffer_size = chip->rmh.stat[0] & MASK_DATA_SIZE; | 822 | *r_buffer_size = chip->rmh.stat[0] & MASK_DATA_SIZE; |
854 | 823 | ||
855 | spin_unlock_irqrestore(&chip->msg_lock, flags); | 824 | mutex_unlock(&chip->msg_lock); |
856 | return err; | 825 | return err; |
857 | } | 826 | } |
858 | 827 | ||
@@ -860,11 +829,9 @@ int lx_buffer_cancel(struct lx6464es *chip, u32 pipe, int is_capture, | |||
860 | u32 buffer_index) | 829 | u32 buffer_index) |
861 | { | 830 | { |
862 | int err; | 831 | int err; |
863 | unsigned long flags; | ||
864 | |||
865 | u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); | 832 | u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); |
866 | 833 | ||
867 | spin_lock_irqsave(&chip->msg_lock, flags); | 834 | mutex_lock(&chip->msg_lock); |
868 | lx_message_init(&chip->rmh, CMD_11_CANCEL_BUFFER); | 835 | lx_message_init(&chip->rmh, CMD_11_CANCEL_BUFFER); |
869 | 836 | ||
870 | chip->rmh.cmd[0] |= pipe_cmd; | 837 | chip->rmh.cmd[0] |= pipe_cmd; |
@@ -872,7 +839,7 @@ int lx_buffer_cancel(struct lx6464es *chip, u32 pipe, int is_capture, | |||
872 | 839 | ||
873 | err = lx_message_send_atomic(chip, &chip->rmh); | 840 | err = lx_message_send_atomic(chip, &chip->rmh); |
874 | 841 | ||
875 | spin_unlock_irqrestore(&chip->msg_lock, flags); | 842 | mutex_unlock(&chip->msg_lock); |
876 | return err; | 843 | return err; |
877 | } | 844 | } |
878 | 845 | ||
@@ -885,12 +852,10 @@ int lx_buffer_cancel(struct lx6464es *chip, u32 pipe, int is_capture, | |||
885 | int lx_level_unmute(struct lx6464es *chip, int is_capture, int unmute) | 852 | int lx_level_unmute(struct lx6464es *chip, int is_capture, int unmute) |
886 | { | 853 | { |
887 | int err; | 854 | int err; |
888 | unsigned long flags; | ||
889 | |||
890 | /* bit set to 1: channel muted */ | 855 | /* bit set to 1: channel muted */ |
891 | u64 mute_mask = unmute ? 0 : 0xFFFFFFFFFFFFFFFFLLU; | 856 | u64 mute_mask = unmute ? 0 : 0xFFFFFFFFFFFFFFFFLLU; |
892 | 857 | ||
893 | spin_lock_irqsave(&chip->msg_lock, flags); | 858 | mutex_lock(&chip->msg_lock); |
894 | lx_message_init(&chip->rmh, CMD_0D_SET_MUTE); | 859 | lx_message_init(&chip->rmh, CMD_0D_SET_MUTE); |
895 | 860 | ||
896 | chip->rmh.cmd[0] |= PIPE_INFO_TO_CMD(is_capture, 0); | 861 | chip->rmh.cmd[0] |= PIPE_INFO_TO_CMD(is_capture, 0); |
@@ -904,7 +869,7 @@ int lx_level_unmute(struct lx6464es *chip, int is_capture, int unmute) | |||
904 | 869 | ||
905 | err = lx_message_send_atomic(chip, &chip->rmh); | 870 | err = lx_message_send_atomic(chip, &chip->rmh); |
906 | 871 | ||
907 | spin_unlock_irqrestore(&chip->msg_lock, flags); | 872 | mutex_unlock(&chip->msg_lock); |
908 | return err; | 873 | return err; |
909 | } | 874 | } |
910 | 875 | ||
@@ -931,10 +896,9 @@ int lx_level_peaks(struct lx6464es *chip, int is_capture, int channels, | |||
931 | u32 *r_levels) | 896 | u32 *r_levels) |
932 | { | 897 | { |
933 | int err = 0; | 898 | int err = 0; |
934 | unsigned long flags; | ||
935 | int i; | 899 | int i; |
936 | spin_lock_irqsave(&chip->msg_lock, flags); | ||
937 | 900 | ||
901 | mutex_lock(&chip->msg_lock); | ||
938 | for (i = 0; i < channels; i += 4) { | 902 | for (i = 0; i < channels; i += 4) { |
939 | u32 s0, s1, s2, s3; | 903 | u32 s0, s1, s2, s3; |
940 | 904 | ||
@@ -959,7 +923,7 @@ int lx_level_peaks(struct lx6464es *chip, int is_capture, int channels, | |||
959 | r_levels += 4; | 923 | r_levels += 4; |
960 | } | 924 | } |
961 | 925 | ||
962 | spin_unlock_irqrestore(&chip->msg_lock, flags); | 926 | mutex_unlock(&chip->msg_lock); |
963 | return err; | 927 | return err; |
964 | } | 928 | } |
965 | 929 | ||
@@ -1075,7 +1039,6 @@ static int lx_interrupt_request_new_buffer(struct lx6464es *chip, | |||
1075 | struct snd_pcm_substream *substream = lx_stream->stream; | 1039 | struct snd_pcm_substream *substream = lx_stream->stream; |
1076 | const unsigned int is_capture = lx_stream->is_capture; | 1040 | const unsigned int is_capture = lx_stream->is_capture; |
1077 | int err; | 1041 | int err; |
1078 | unsigned long flags; | ||
1079 | 1042 | ||
1080 | const u32 channels = substream->runtime->channels; | 1043 | const u32 channels = substream->runtime->channels; |
1081 | const u32 bytes_per_frame = channels * 3; | 1044 | const u32 bytes_per_frame = channels * 3; |
@@ -1095,7 +1058,7 @@ static int lx_interrupt_request_new_buffer(struct lx6464es *chip, | |||
1095 | 1058 | ||
1096 | dev_dbg(chip->card->dev, "->lx_interrupt_request_new_buffer\n"); | 1059 | dev_dbg(chip->card->dev, "->lx_interrupt_request_new_buffer\n"); |
1097 | 1060 | ||
1098 | spin_lock_irqsave(&chip->lock, flags); | 1061 | mutex_lock(&chip->lock); |
1099 | 1062 | ||
1100 | err = lx_buffer_ask(chip, 0, is_capture, &needed, &freed, size_array); | 1063 | err = lx_buffer_ask(chip, 0, is_capture, &needed, &freed, size_array); |
1101 | dev_dbg(chip->card->dev, | 1064 | dev_dbg(chip->card->dev, |
@@ -1109,85 +1072,28 @@ static int lx_interrupt_request_new_buffer(struct lx6464es *chip, | |||
1109 | buffer_index, (unsigned long)buf, period_bytes); | 1072 | buffer_index, (unsigned long)buf, period_bytes); |
1110 | 1073 | ||
1111 | lx_stream->frame_pos = next_pos; | 1074 | lx_stream->frame_pos = next_pos; |
1112 | spin_unlock_irqrestore(&chip->lock, flags); | 1075 | mutex_unlock(&chip->lock); |
1113 | 1076 | ||
1114 | return err; | 1077 | return err; |
1115 | } | 1078 | } |
1116 | 1079 | ||
1117 | void lx_tasklet_playback(unsigned long data) | ||
1118 | { | ||
1119 | struct lx6464es *chip = (struct lx6464es *)data; | ||
1120 | struct lx_stream *lx_stream = &chip->playback_stream; | ||
1121 | int err; | ||
1122 | |||
1123 | dev_dbg(chip->card->dev, "->lx_tasklet_playback\n"); | ||
1124 | |||
1125 | err = lx_interrupt_request_new_buffer(chip, lx_stream); | ||
1126 | if (err < 0) | ||
1127 | dev_err(chip->card->dev, | ||
1128 | "cannot request new buffer for playback\n"); | ||
1129 | |||
1130 | snd_pcm_period_elapsed(lx_stream->stream); | ||
1131 | } | ||
1132 | |||
1133 | void lx_tasklet_capture(unsigned long data) | ||
1134 | { | ||
1135 | struct lx6464es *chip = (struct lx6464es *)data; | ||
1136 | struct lx_stream *lx_stream = &chip->capture_stream; | ||
1137 | int err; | ||
1138 | |||
1139 | dev_dbg(chip->card->dev, "->lx_tasklet_capture\n"); | ||
1140 | err = lx_interrupt_request_new_buffer(chip, lx_stream); | ||
1141 | if (err < 0) | ||
1142 | dev_err(chip->card->dev, | ||
1143 | "cannot request new buffer for capture\n"); | ||
1144 | |||
1145 | snd_pcm_period_elapsed(lx_stream->stream); | ||
1146 | } | ||
1147 | |||
1148 | |||
1149 | |||
1150 | static int lx_interrupt_handle_audio_transfer(struct lx6464es *chip, | ||
1151 | u64 notified_in_pipe_mask, | ||
1152 | u64 notified_out_pipe_mask) | ||
1153 | { | ||
1154 | int err = 0; | ||
1155 | |||
1156 | if (notified_in_pipe_mask) { | ||
1157 | dev_dbg(chip->card->dev, | ||
1158 | "requesting audio transfer for capture\n"); | ||
1159 | tasklet_hi_schedule(&chip->tasklet_capture); | ||
1160 | } | ||
1161 | |||
1162 | if (notified_out_pipe_mask) { | ||
1163 | dev_dbg(chip->card->dev, | ||
1164 | "requesting audio transfer for playback\n"); | ||
1165 | tasklet_hi_schedule(&chip->tasklet_playback); | ||
1166 | } | ||
1167 | |||
1168 | return err; | ||
1169 | } | ||
1170 | |||
1171 | |||
1172 | irqreturn_t lx_interrupt(int irq, void *dev_id) | 1080 | irqreturn_t lx_interrupt(int irq, void *dev_id) |
1173 | { | 1081 | { |
1174 | struct lx6464es *chip = dev_id; | 1082 | struct lx6464es *chip = dev_id; |
1175 | int async_pending, async_escmd; | 1083 | int async_pending, async_escmd; |
1176 | u32 irqsrc; | 1084 | u32 irqsrc; |
1177 | 1085 | bool wake_thread = false; | |
1178 | spin_lock(&chip->lock); | ||
1179 | 1086 | ||
1180 | dev_dbg(chip->card->dev, | 1087 | dev_dbg(chip->card->dev, |
1181 | "**************************************************\n"); | 1088 | "**************************************************\n"); |
1182 | 1089 | ||
1183 | if (!lx_interrupt_ack(chip, &irqsrc, &async_pending, &async_escmd)) { | 1090 | if (!lx_interrupt_ack(chip, &irqsrc, &async_pending, &async_escmd)) { |
1184 | spin_unlock(&chip->lock); | ||
1185 | dev_dbg(chip->card->dev, "IRQ_NONE\n"); | 1091 | dev_dbg(chip->card->dev, "IRQ_NONE\n"); |
1186 | return IRQ_NONE; /* this device did not cause the interrupt */ | 1092 | return IRQ_NONE; /* this device did not cause the interrupt */ |
1187 | } | 1093 | } |
1188 | 1094 | ||
1189 | if (irqsrc & MASK_SYS_STATUS_CMD_DONE) | 1095 | if (irqsrc & MASK_SYS_STATUS_CMD_DONE) |
1190 | goto exit; | 1096 | return IRQ_HANDLED; |
1191 | 1097 | ||
1192 | if (irqsrc & MASK_SYS_STATUS_EOBI) | 1098 | if (irqsrc & MASK_SYS_STATUS_EOBI) |
1193 | dev_dbg(chip->card->dev, "interrupt: EOBI\n"); | 1099 | dev_dbg(chip->card->dev, "interrupt: EOBI\n"); |
@@ -1202,27 +1108,8 @@ irqreturn_t lx_interrupt(int irq, void *dev_id) | |||
1202 | dev_dbg(chip->card->dev, "interrupt: ORUN\n"); | 1108 | dev_dbg(chip->card->dev, "interrupt: ORUN\n"); |
1203 | 1109 | ||
1204 | if (async_pending) { | 1110 | if (async_pending) { |
1205 | u64 notified_in_pipe_mask = 0; | 1111 | wake_thread = true; |
1206 | u64 notified_out_pipe_mask = 0; | 1112 | chip->irqsrc = irqsrc; |
1207 | int freq_changed; | ||
1208 | int err; | ||
1209 | |||
1210 | /* handle async events */ | ||
1211 | err = lx_interrupt_handle_async_events(chip, irqsrc, | ||
1212 | &freq_changed, | ||
1213 | ¬ified_in_pipe_mask, | ||
1214 | ¬ified_out_pipe_mask); | ||
1215 | if (err) | ||
1216 | dev_err(chip->card->dev, | ||
1217 | "error handling async events\n"); | ||
1218 | |||
1219 | err = lx_interrupt_handle_audio_transfer(chip, | ||
1220 | notified_in_pipe_mask, | ||
1221 | notified_out_pipe_mask | ||
1222 | ); | ||
1223 | if (err) | ||
1224 | dev_err(chip->card->dev, | ||
1225 | "error during audio transfer\n"); | ||
1226 | } | 1113 | } |
1227 | 1114 | ||
1228 | if (async_escmd) { | 1115 | if (async_escmd) { |
@@ -1235,9 +1122,50 @@ irqreturn_t lx_interrupt(int irq, void *dev_id) | |||
1235 | dev_dbg(chip->card->dev, "interrupt requests escmd handling\n"); | 1122 | dev_dbg(chip->card->dev, "interrupt requests escmd handling\n"); |
1236 | } | 1123 | } |
1237 | 1124 | ||
1238 | exit: | 1125 | return wake_thread ? IRQ_WAKE_THREAD : IRQ_HANDLED; |
1239 | spin_unlock(&chip->lock); | 1126 | } |
1240 | return IRQ_HANDLED; /* this device caused the interrupt */ | 1127 | |
1128 | irqreturn_t lx_threaded_irq(int irq, void *dev_id) | ||
1129 | { | ||
1130 | struct lx6464es *chip = dev_id; | ||
1131 | u64 notified_in_pipe_mask = 0; | ||
1132 | u64 notified_out_pipe_mask = 0; | ||
1133 | int freq_changed; | ||
1134 | int err; | ||
1135 | |||
1136 | /* handle async events */ | ||
1137 | err = lx_interrupt_handle_async_events(chip, chip->irqsrc, | ||
1138 | &freq_changed, | ||
1139 | ¬ified_in_pipe_mask, | ||
1140 | ¬ified_out_pipe_mask); | ||
1141 | if (err) | ||
1142 | dev_err(chip->card->dev, "error handling async events\n"); | ||
1143 | |||
1144 | if (notified_in_pipe_mask) { | ||
1145 | struct lx_stream *lx_stream = &chip->capture_stream; | ||
1146 | |||
1147 | dev_dbg(chip->card->dev, | ||
1148 | "requesting audio transfer for capture\n"); | ||
1149 | err = lx_interrupt_request_new_buffer(chip, lx_stream); | ||
1150 | if (err < 0) | ||
1151 | dev_err(chip->card->dev, | ||
1152 | "cannot request new buffer for capture\n"); | ||
1153 | snd_pcm_period_elapsed(lx_stream->stream); | ||
1154 | } | ||
1155 | |||
1156 | if (notified_out_pipe_mask) { | ||
1157 | struct lx_stream *lx_stream = &chip->playback_stream; | ||
1158 | |||
1159 | dev_dbg(chip->card->dev, | ||
1160 | "requesting audio transfer for playback\n"); | ||
1161 | err = lx_interrupt_request_new_buffer(chip, lx_stream); | ||
1162 | if (err < 0) | ||
1163 | dev_err(chip->card->dev, | ||
1164 | "cannot request new buffer for playback\n"); | ||
1165 | snd_pcm_period_elapsed(lx_stream->stream); | ||
1166 | } | ||
1167 | |||
1168 | return IRQ_HANDLED; | ||
1241 | } | 1169 | } |
1242 | 1170 | ||
1243 | 1171 | ||
diff --git a/sound/pci/lx6464es/lx_core.h b/sound/pci/lx6464es/lx_core.h index 5ec5e04da1a5..0cc140ca98e3 100644 --- a/sound/pci/lx6464es/lx_core.h +++ b/sound/pci/lx6464es/lx_core.h | |||
@@ -181,12 +181,10 @@ int lx_level_peaks(struct lx6464es *chip, int is_capture, int channels, | |||
181 | 181 | ||
182 | /* interrupt handling */ | 182 | /* interrupt handling */ |
183 | irqreturn_t lx_interrupt(int irq, void *dev_id); | 183 | irqreturn_t lx_interrupt(int irq, void *dev_id); |
184 | irqreturn_t lx_threaded_irq(int irq, void *dev_id); | ||
184 | void lx_irq_enable(struct lx6464es *chip); | 185 | void lx_irq_enable(struct lx6464es *chip); |
185 | void lx_irq_disable(struct lx6464es *chip); | 186 | void lx_irq_disable(struct lx6464es *chip); |
186 | 187 | ||
187 | void lx_tasklet_capture(unsigned long data); | ||
188 | void lx_tasklet_playback(unsigned long data); | ||
189 | |||
190 | 188 | ||
191 | /* Stream Format Header Defines (for LIN and IEEE754) */ | 189 | /* Stream Format Header Defines (for LIN and IEEE754) */ |
192 | #define HEADER_FMT_BASE HEADER_FMT_BASE_LIN | 190 | #define HEADER_FMT_BASE HEADER_FMT_BASE_LIN |