Skip to content

Commit ea3a859

Browse files
committed
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
2 parents ea839b4 + d4a2fbc commit ea3a859

File tree

9 files changed

+54
-28
lines changed

9 files changed

+54
-28
lines changed

sound/core/seq/seq_lock.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,16 @@
2828
/* wait until all locks are released */
2929
void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line)
3030
{
31-
int max_count = 5 * HZ;
31+
int warn_count = 5 * HZ;
3232

3333
if (atomic_read(lockp) < 0) {
3434
pr_warn("ALSA: seq_lock: lock trouble [counter = %d] in %s:%d\n", atomic_read(lockp), file, line);
3535
return;
3636
}
3737
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);
4240
schedule_timeout_uninterruptible(1);
43-
max_count--;
4441
}
4542
}
4643

sound/firewire/lib.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ struct snd_fw_async_midi_port {
4545

4646
struct snd_rawmidi_substream *substream;
4747
snd_fw_async_midi_port_fill fill;
48-
unsigned int consume_bytes;
48+
int consume_bytes;
4949
};
5050

5151
int snd_fw_async_midi_port_init(struct snd_fw_async_midi_port *port,

sound/firewire/oxfw/oxfw.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,11 +227,11 @@ static void do_registration(struct work_struct *work)
227227
if (err < 0)
228228
goto error;
229229

230-
err = detect_quirks(oxfw);
230+
err = snd_oxfw_stream_discover(oxfw);
231231
if (err < 0)
232232
goto error;
233233

234-
err = snd_oxfw_stream_discover(oxfw);
234+
err = detect_quirks(oxfw);
235235
if (err < 0)
236236
goto error;
237237

sound/soc/intel/boards/bytcr_rt5640.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,7 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = {
621621
.codec_dai_name = "snd-soc-dummy-dai",
622622
.codec_name = "snd-soc-dummy",
623623
.platform_name = "sst-mfld-platform",
624-
.ignore_suspend = 1,
624+
.nonatomic = true,
625625
.dynamic = 1,
626626
.dpcm_playback = 1,
627627
.dpcm_capture = 1,
@@ -634,7 +634,6 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = {
634634
.codec_dai_name = "snd-soc-dummy-dai",
635635
.codec_name = "snd-soc-dummy",
636636
.platform_name = "sst-mfld-platform",
637-
.ignore_suspend = 1,
638637
.nonatomic = true,
639638
.dynamic = 1,
640639
.dpcm_playback = 1,
@@ -661,6 +660,7 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = {
661660
| SND_SOC_DAIFMT_CBS_CFS,
662661
.be_hw_params_fixup = byt_rt5640_codec_fixup,
663662
.ignore_suspend = 1,
663+
.nonatomic = true,
664664
.dpcm_playback = 1,
665665
.dpcm_capture = 1,
666666
.init = byt_rt5640_init,

sound/soc/intel/boards/bytcr_rt5651.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,6 @@ static struct snd_soc_dai_link byt_rt5651_dais[] = {
235235
.codec_dai_name = "snd-soc-dummy-dai",
236236
.codec_name = "snd-soc-dummy",
237237
.platform_name = "sst-mfld-platform",
238-
.ignore_suspend = 1,
239238
.nonatomic = true,
240239
.dynamic = 1,
241240
.dpcm_playback = 1,
@@ -249,7 +248,6 @@ static struct snd_soc_dai_link byt_rt5651_dais[] = {
249248
.codec_dai_name = "snd-soc-dummy-dai",
250249
.codec_name = "snd-soc-dummy",
251250
.platform_name = "sst-mfld-platform",
252-
.ignore_suspend = 1,
253251
.nonatomic = true,
254252
.dynamic = 1,
255253
.dpcm_playback = 1,

sound/soc/soc-topology.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,7 @@ static int soc_tplg_denum_create_texts(struct soc_enum *se,
933933
}
934934
}
935935

936+
se->texts = (const char * const *)se->dobj.control.dtexts;
936937
return 0;
937938

938939
err:

sound/soc/sti/uniperif.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1299,6 +1299,7 @@ struct uniperif {
12991299
int ver; /* IP version, used by register access macros */
13001300
struct regmap_field *clk_sel;
13011301
struct regmap_field *valid_sel;
1302+
spinlock_t irq_lock; /* use to prevent race condition with IRQ */
13021303

13031304
/* capabilities */
13041305
const struct snd_pcm_hardware *hw;

sound/soc/sti/uniperif_player.c

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,13 @@ static irqreturn_t uni_player_irq_handler(int irq, void *dev_id)
6565
unsigned int status;
6666
unsigned int tmp;
6767

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;
7275

7376
/* Get interrupt status & clear them immediately */
7477
status = GET_UNIPERIF_ITS(player);
@@ -88,9 +91,7 @@ static irqreturn_t uni_player_irq_handler(int irq, void *dev_id)
8891
SET_UNIPERIF_ITM_BCLR_FIFO_ERROR(player);
8992

9093
/* Stop the player */
91-
snd_pcm_stream_lock(player->substream);
9294
snd_pcm_stop(player->substream, SNDRV_PCM_STATE_XRUN);
93-
snd_pcm_stream_unlock(player->substream);
9495
}
9596

9697
ret = IRQ_HANDLED;
@@ -104,9 +105,7 @@ static irqreturn_t uni_player_irq_handler(int irq, void *dev_id)
104105
SET_UNIPERIF_ITM_BCLR_DMA_ERROR(player);
105106

106107
/* Stop the player */
107-
snd_pcm_stream_lock(player->substream);
108108
snd_pcm_stop(player->substream, SNDRV_PCM_STATE_XRUN);
109-
snd_pcm_stream_unlock(player->substream);
110109

111110
ret = IRQ_HANDLED;
112111
}
@@ -116,7 +115,8 @@ static irqreturn_t uni_player_irq_handler(int irq, void *dev_id)
116115
if (!player->underflow_enabled) {
117116
dev_err(player->dev,
118117
"unexpected Underflow recovering\n");
119-
return -EPERM;
118+
ret = -EPERM;
119+
goto stream_unlock;
120120
}
121121
/* Read the underflow recovery duration */
122122
tmp = GET_UNIPERIF_STATUS_1_UNDERFLOW_DURATION(player);
@@ -138,13 +138,16 @@ static irqreturn_t uni_player_irq_handler(int irq, void *dev_id)
138138
dev_err(player->dev, "Underflow recovery failed\n");
139139

140140
/* Stop the player */
141-
snd_pcm_stream_lock(player->substream);
142141
snd_pcm_stop(player->substream, SNDRV_PCM_STATE_XRUN);
143-
snd_pcm_stream_unlock(player->substream);
144142

145143
ret = IRQ_HANDLED;
146144
}
147145

146+
stream_unlock:
147+
snd_pcm_stream_unlock(player->substream);
148+
irq_spin_unlock:
149+
spin_unlock(&player->irq_lock);
150+
148151
return ret;
149152
}
150153

@@ -588,6 +591,7 @@ static int uni_player_ctl_iec958_put(struct snd_kcontrol *kcontrol,
588591
struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
589592
struct uniperif *player = priv->dai_data.uni;
590593
struct snd_aes_iec958 *iec958 = &player->stream_settings.iec958;
594+
unsigned long flags;
591595

592596
mutex_lock(&player->ctrl_lock);
593597
iec958->status[0] = ucontrol->value.iec958.status[0];
@@ -596,12 +600,14 @@ static int uni_player_ctl_iec958_put(struct snd_kcontrol *kcontrol,
596600
iec958->status[3] = ucontrol->value.iec958.status[3];
597601
mutex_unlock(&player->ctrl_lock);
598602

603+
spin_lock_irqsave(&player->irq_lock, flags);
599604
if (player->substream && player->substream->runtime)
600605
uni_player_set_channel_status(player,
601606
player->substream->runtime);
602607
else
603608
uni_player_set_channel_status(player, NULL);
604609

610+
spin_unlock_irqrestore(&player->irq_lock, flags);
605611
return 0;
606612
}
607613

@@ -686,9 +692,12 @@ static int uni_player_startup(struct snd_pcm_substream *substream,
686692
{
687693
struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
688694
struct uniperif *player = priv->dai_data.uni;
695+
unsigned long flags;
689696
int ret;
690697

698+
spin_lock_irqsave(&player->irq_lock, flags);
691699
player->substream = substream;
700+
spin_unlock_irqrestore(&player->irq_lock, flags);
692701

693702
player->clk_adj = 0;
694703

@@ -986,12 +995,15 @@ static void uni_player_shutdown(struct snd_pcm_substream *substream,
986995
{
987996
struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
988997
struct uniperif *player = priv->dai_data.uni;
998+
unsigned long flags;
989999

1000+
spin_lock_irqsave(&player->irq_lock, flags);
9901001
if (player->state != UNIPERIF_STATE_STOPPED)
9911002
/* Stop the player */
9921003
uni_player_stop(player);
9931004

9941005
player->substream = NULL;
1006+
spin_unlock_irqrestore(&player->irq_lock, flags);
9951007
}
9961008

9971009
static int uni_player_parse_dt_audio_glue(struct platform_device *pdev,
@@ -1096,6 +1108,7 @@ int uni_player_init(struct platform_device *pdev,
10961108
}
10971109

10981110
mutex_init(&player->ctrl_lock);
1111+
spin_lock_init(&player->irq_lock);
10991112

11001113
/* Ensure that disabled by default */
11011114
SET_UNIPERIF_CONFIG_BACK_STALL_REQ_DISABLE(player);

sound/soc/sti/uniperif_reader.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,15 @@ static irqreturn_t uni_reader_irq_handler(int irq, void *dev_id)
4646
struct uniperif *reader = dev_id;
4747
unsigned int status;
4848

49+
spin_lock(&reader->irq_lock);
50+
if (!reader->substream)
51+
goto irq_spin_unlock;
52+
53+
snd_pcm_stream_lock(reader->substream);
4954
if (reader->state == UNIPERIF_STATE_STOPPED) {
5055
/* Unexpected IRQ: do nothing */
5156
dev_warn(reader->dev, "unexpected IRQ\n");
52-
return IRQ_HANDLED;
57+
goto stream_unlock;
5358
}
5459

5560
/* Get interrupt status & clear them immediately */
@@ -60,13 +65,16 @@ static irqreturn_t uni_reader_irq_handler(int irq, void *dev_id)
6065
if (unlikely(status & UNIPERIF_ITS_FIFO_ERROR_MASK(reader))) {
6166
dev_err(reader->dev, "FIFO error detected\n");
6267

63-
snd_pcm_stream_lock(reader->substream);
6468
snd_pcm_stop(reader->substream, SNDRV_PCM_STATE_XRUN);
65-
snd_pcm_stream_unlock(reader->substream);
6669

67-
return IRQ_HANDLED;
70+
ret = IRQ_HANDLED;
6871
}
6972

73+
stream_unlock:
74+
snd_pcm_stream_unlock(reader->substream);
75+
irq_spin_unlock:
76+
spin_unlock(&reader->irq_lock);
77+
7078
return ret;
7179
}
7280

@@ -347,9 +355,12 @@ static int uni_reader_startup(struct snd_pcm_substream *substream,
347355
{
348356
struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
349357
struct uniperif *reader = priv->dai_data.uni;
358+
unsigned long flags;
350359
int ret;
351360

361+
spin_lock_irqsave(&reader->irq_lock, flags);
352362
reader->substream = substream;
363+
spin_unlock_irqrestore(&reader->irq_lock, flags);
353364

354365
if (!UNIPERIF_TYPE_IS_TDM(reader))
355366
return 0;
@@ -375,12 +386,15 @@ static void uni_reader_shutdown(struct snd_pcm_substream *substream,
375386
{
376387
struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
377388
struct uniperif *reader = priv->dai_data.uni;
389+
unsigned long flags;
378390

391+
spin_lock_irqsave(&reader->irq_lock, flags);
379392
if (reader->state != UNIPERIF_STATE_STOPPED) {
380393
/* Stop the reader */
381394
uni_reader_stop(reader);
382395
}
383396
reader->substream = NULL;
397+
spin_unlock_irqrestore(&reader->irq_lock, flags);
384398
}
385399

386400
static const struct snd_soc_dai_ops uni_reader_dai_ops = {
@@ -415,6 +429,8 @@ int uni_reader_init(struct platform_device *pdev,
415429
return -EBUSY;
416430
}
417431

432+
spin_lock_init(&reader->irq_lock);
433+
418434
return 0;
419435
}
420436
EXPORT_SYMBOL_GPL(uni_reader_init);

0 commit comments

Comments
 (0)