Merge tag 'sound-4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound fixes from Takashi Iwai:
"Since we got a bonus week, let me try to screw a few pending fixes.

A slightly large fix is the locking fix in ASoC STI driver, but it's
pretty board-specific, and the risk is fairly low.

All the rest are small / trivial fixes, mostly marked as stable, for
ALSA sequencer core, ASoC topology, ASoC Intel bytcr and Firewire
drivers"

* tag 'sound-4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
ASoC: intel: Fix PM and non-atomic crash in bytcr drivers
ALSA: firewire-lib: fix inappropriate assignment between signed/unsigned type
ALSA: seq: Don't break snd_use_lock_sync() loop by timeout
ASoC: topology: Fix to store enum text values
ASoC: STI: Fix null ptr deference in IRQ handler
ALSA: oxfw: fix regression to handle Stanton SCS.1m/1d

+54 -28
+3 -6
sound/core/seq/seq_lock.c
··· 28 28 /* wait until all locks are released */ 29 29 void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line) 30 30 { 31 - int max_count = 5 * HZ; 31 + int warn_count = 5 * HZ; 32 32 33 33 if (atomic_read(lockp) < 0) { 34 34 pr_warn("ALSA: seq_lock: lock trouble [counter = %d] in %s:%d\n", atomic_read(lockp), file, line); 35 35 return; 36 36 } 37 37 while (atomic_read(lockp) > 0) { 38 - if (max_count == 0) { 39 - pr_warn("ALSA: seq_lock: timeout [%d left] in %s:%d\n", atomic_read(lockp), file, line); 40 - break; 41 - } 38 + if (warn_count-- == 0) 39 + pr_warn("ALSA: seq_lock: waiting [%d left] in %s:%d\n", atomic_read(lockp), file, line); 42 40 schedule_timeout_uninterruptible(1); 43 - max_count--; 44 41 } 45 42 } 46 43
+1 -1
sound/firewire/lib.h
··· 45 45 46 46 struct snd_rawmidi_substream *substream; 47 47 snd_fw_async_midi_port_fill fill; 48 - unsigned int consume_bytes; 48 + int consume_bytes; 49 49 }; 50 50 51 51 int snd_fw_async_midi_port_init(struct snd_fw_async_midi_port *port,
+2 -2
sound/firewire/oxfw/oxfw.c
··· 227 227 if (err < 0) 228 228 goto error; 229 229 230 - err = detect_quirks(oxfw); 230 + err = snd_oxfw_stream_discover(oxfw); 231 231 if (err < 0) 232 232 goto error; 233 233 234 - err = snd_oxfw_stream_discover(oxfw); 234 + err = detect_quirks(oxfw); 235 235 if (err < 0) 236 236 goto error; 237 237
+2 -2
sound/soc/intel/boards/bytcr_rt5640.c
··· 621 621 .codec_dai_name = "snd-soc-dummy-dai", 622 622 .codec_name = "snd-soc-dummy", 623 623 .platform_name = "sst-mfld-platform", 624 - .ignore_suspend = 1, 624 + .nonatomic = true, 625 625 .dynamic = 1, 626 626 .dpcm_playback = 1, 627 627 .dpcm_capture = 1, ··· 634 634 .codec_dai_name = "snd-soc-dummy-dai", 635 635 .codec_name = "snd-soc-dummy", 636 636 .platform_name = "sst-mfld-platform", 637 - .ignore_suspend = 1, 638 637 .nonatomic = true, 639 638 .dynamic = 1, 640 639 .dpcm_playback = 1, ··· 660 661 | SND_SOC_DAIFMT_CBS_CFS, 661 662 .be_hw_params_fixup = byt_rt5640_codec_fixup, 662 663 .ignore_suspend = 1, 664 + .nonatomic = true, 663 665 .dpcm_playback = 1, 664 666 .dpcm_capture = 1, 665 667 .init = byt_rt5640_init,
-2
sound/soc/intel/boards/bytcr_rt5651.c
··· 235 235 .codec_dai_name = "snd-soc-dummy-dai", 236 236 .codec_name = "snd-soc-dummy", 237 237 .platform_name = "sst-mfld-platform", 238 - .ignore_suspend = 1, 239 238 .nonatomic = true, 240 239 .dynamic = 1, 241 240 .dpcm_playback = 1, ··· 248 249 .codec_dai_name = "snd-soc-dummy-dai", 249 250 .codec_name = "snd-soc-dummy", 250 251 .platform_name = "sst-mfld-platform", 251 - .ignore_suspend = 1, 252 252 .nonatomic = true, 253 253 .dynamic = 1, 254 254 .dpcm_playback = 1,
+1
sound/soc/soc-topology.c
··· 933 933 } 934 934 } 935 935 936 + se->texts = (const char * const *)se->dobj.control.dtexts; 936 937 return 0; 937 938 938 939 err:
+1
sound/soc/sti/uniperif.h
··· 1299 1299 int ver; /* IP version, used by register access macros */ 1300 1300 struct regmap_field *clk_sel; 1301 1301 struct regmap_field *valid_sel; 1302 + spinlock_t irq_lock; /* use to prevent race condition with IRQ */ 1302 1303 1303 1304 /* capabilities */ 1304 1305 const struct snd_pcm_hardware *hw;
+24 -11
sound/soc/sti/uniperif_player.c
··· 65 65 unsigned int status; 66 66 unsigned int tmp; 67 67 68 - if (player->state == UNIPERIF_STATE_STOPPED) { 69 - /* Unexpected IRQ: do nothing */ 70 - return IRQ_NONE; 71 - } 68 + spin_lock(&player->irq_lock); 69 + if (!player->substream) 70 + goto irq_spin_unlock; 71 + 72 + snd_pcm_stream_lock(player->substream); 73 + if (player->state == UNIPERIF_STATE_STOPPED) 74 + goto stream_unlock; 72 75 73 76 /* Get interrupt status & clear them immediately */ 74 77 status = GET_UNIPERIF_ITS(player); ··· 91 88 SET_UNIPERIF_ITM_BCLR_FIFO_ERROR(player); 92 89 93 90 /* Stop the player */ 94 - snd_pcm_stream_lock(player->substream); 95 91 snd_pcm_stop(player->substream, SNDRV_PCM_STATE_XRUN); 96 - snd_pcm_stream_unlock(player->substream); 97 92 } 98 93 99 94 ret = IRQ_HANDLED; ··· 105 104 SET_UNIPERIF_ITM_BCLR_DMA_ERROR(player); 106 105 107 106 /* Stop the player */ 108 - snd_pcm_stream_lock(player->substream); 109 107 snd_pcm_stop(player->substream, SNDRV_PCM_STATE_XRUN); 110 - snd_pcm_stream_unlock(player->substream); 111 108 112 109 ret = IRQ_HANDLED; 113 110 } ··· 115 116 if (!player->underflow_enabled) { 116 117 dev_err(player->dev, 117 118 "unexpected Underflow recovering\n"); 118 - return -EPERM; 119 + ret = -EPERM; 120 + goto stream_unlock; 119 121 } 120 122 /* Read the underflow recovery duration */ 121 123 tmp = GET_UNIPERIF_STATUS_1_UNDERFLOW_DURATION(player); ··· 138 138 dev_err(player->dev, "Underflow recovery failed\n"); 139 139 140 140 /* Stop the player */ 141 - snd_pcm_stream_lock(player->substream); 142 141 snd_pcm_stop(player->substream, SNDRV_PCM_STATE_XRUN); 143 - snd_pcm_stream_unlock(player->substream); 144 142 145 143 ret = IRQ_HANDLED; 146 144 } 145 + 146 + stream_unlock: 147 + snd_pcm_stream_unlock(player->substream); 148 + irq_spin_unlock: 149 + spin_unlock(&player->irq_lock); 147 150 148 151 return ret; 149 152 } ··· 591 588 struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai); 592 589 struct uniperif *player = priv->dai_data.uni; 593 590 struct snd_aes_iec958 *iec958 = &player->stream_settings.iec958; 591 + unsigned long flags; 594 592 595 593 mutex_lock(&player->ctrl_lock); 596 594 iec958->status[0] = ucontrol->value.iec958.status[0]; ··· 600 596 iec958->status[3] = ucontrol->value.iec958.status[3]; 601 597 mutex_unlock(&player->ctrl_lock); 602 598 599 + spin_lock_irqsave(&player->irq_lock, flags); 603 600 if (player->substream && player->substream->runtime) 604 601 uni_player_set_channel_status(player, 605 602 player->substream->runtime); 606 603 else 607 604 uni_player_set_channel_status(player, NULL); 608 605 606 + spin_unlock_irqrestore(&player->irq_lock, flags); 609 607 return 0; 610 608 } 611 609 ··· 692 686 { 693 687 struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai); 694 688 struct uniperif *player = priv->dai_data.uni; 689 + unsigned long flags; 695 690 int ret; 696 691 692 + spin_lock_irqsave(&player->irq_lock, flags); 697 693 player->substream = substream; 694 + spin_unlock_irqrestore(&player->irq_lock, flags); 698 695 699 696 player->clk_adj = 0; 700 697 ··· 995 986 { 996 987 struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai); 997 988 struct uniperif *player = priv->dai_data.uni; 989 + unsigned long flags; 998 990 991 + spin_lock_irqsave(&player->irq_lock, flags); 999 992 if (player->state != UNIPERIF_STATE_STOPPED) 1000 993 /* Stop the player */ 1001 994 uni_player_stop(player); 1002 995 1003 996 player->substream = NULL; 997 + spin_unlock_irqrestore(&player->irq_lock, flags); 1004 998 } 1005 999 1006 1000 static int uni_player_parse_dt_audio_glue(struct platform_device *pdev, ··· 1108 1096 } 1109 1097 1110 1098 mutex_init(&player->ctrl_lock); 1099 + spin_lock_init(&player->irq_lock); 1111 1100 1112 1101 /* Ensure that disabled by default */ 1113 1102 SET_UNIPERIF_CONFIG_BACK_STALL_REQ_DISABLE(player);
+20 -4
sound/soc/sti/uniperif_reader.c
··· 46 46 struct uniperif *reader = dev_id; 47 47 unsigned int status; 48 48 49 + spin_lock(&reader->irq_lock); 50 + if (!reader->substream) 51 + goto irq_spin_unlock; 52 + 53 + snd_pcm_stream_lock(reader->substream); 49 54 if (reader->state == UNIPERIF_STATE_STOPPED) { 50 55 /* Unexpected IRQ: do nothing */ 51 56 dev_warn(reader->dev, "unexpected IRQ\n"); 52 - return IRQ_HANDLED; 57 + goto stream_unlock; 53 58 } 54 59 55 60 /* Get interrupt status & clear them immediately */ ··· 65 60 if (unlikely(status & UNIPERIF_ITS_FIFO_ERROR_MASK(reader))) { 66 61 dev_err(reader->dev, "FIFO error detected\n"); 67 62 68 - snd_pcm_stream_lock(reader->substream); 69 63 snd_pcm_stop(reader->substream, SNDRV_PCM_STATE_XRUN); 70 - snd_pcm_stream_unlock(reader->substream); 71 64 72 - return IRQ_HANDLED; 65 + ret = IRQ_HANDLED; 73 66 } 67 + 68 + stream_unlock: 69 + snd_pcm_stream_unlock(reader->substream); 70 + irq_spin_unlock: 71 + spin_unlock(&reader->irq_lock); 74 72 75 73 return ret; 76 74 } ··· 355 347 { 356 348 struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai); 357 349 struct uniperif *reader = priv->dai_data.uni; 350 + unsigned long flags; 358 351 int ret; 359 352 353 + spin_lock_irqsave(&reader->irq_lock, flags); 360 354 reader->substream = substream; 355 + spin_unlock_irqrestore(&reader->irq_lock, flags); 361 356 362 357 if (!UNIPERIF_TYPE_IS_TDM(reader)) 363 358 return 0; ··· 386 375 { 387 376 struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai); 388 377 struct uniperif *reader = priv->dai_data.uni; 378 + unsigned long flags; 389 379 380 + spin_lock_irqsave(&reader->irq_lock, flags); 390 381 if (reader->state != UNIPERIF_STATE_STOPPED) { 391 382 /* Stop the reader */ 392 383 uni_reader_stop(reader); 393 384 } 394 385 reader->substream = NULL; 386 + spin_unlock_irqrestore(&reader->irq_lock, flags); 395 387 } 396 388 397 389 static const struct snd_soc_dai_ops uni_reader_dai_ops = { ··· 428 414 dev_err(&pdev->dev, "Failed to request IRQ\n"); 429 415 return -EBUSY; 430 416 } 417 + 418 + spin_lock_init(&reader->irq_lock); 431 419 432 420 return 0; 433 421 }