Merge tag 'asoc-fix-v4.11-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus

ASoC: Fixes for v4.11

A few last minute fixes for v4.11, the STI fix is relatively large but
driver specific and has been cooking in -next for a little while now:

- A fix from Takashi for some suspend/resume related crashes in the
Intel drivers.
- A fix from Mousumi Jana for issues with incorrectly created
enumeration controls generated from topology files which could cause
problems for userspace.
- Fixes from Arnaud Pouliquen for some crashes due to races with the
interrupt handler in the STI driver.

+48 -19
+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 }