Merge "USB: gadget: f_audio_source: Fix use after free in audio_unbind"
diff --git a/drivers/usb/gadget/f_audio_source.c b/drivers/usb/gadget/f_audio_source.c
index 0471f888..34faf6d 100644
--- a/drivers/usb/gadget/f_audio_source.c
+++ b/drivers/usb/gadget/f_audio_source.c
@@ -628,7 +628,10 @@
 		audio_request_free(req, audio->in_ep);
 
 	snd_card_free_when_closed(audio->card);
-	kfree(audio);
+	audio->card = NULL;
+	audio->pcm = NULL;
+	audio->substream = NULL;
+	audio->in_ep = NULL;
 }
 
 static void audio_pcm_playback_start(struct audio_dev *audio)
@@ -744,6 +747,21 @@
 	return ret;
 }
 
+static struct audio_dev _audio_dev = {
+	.func = {
+		.name = "audio_source",
+		.bind = audio_bind,
+		.unbind = audio_unbind,
+		.set_alt = audio_set_alt,
+		.setup = audio_setup,
+		.disable = audio_disable,
+		.descriptors = fs_audio_desc,
+		.hs_descriptors = hs_audio_desc,
+	},
+	.lock = __SPIN_LOCK_UNLOCKED(_audio_dev.lock),
+	.idle_reqs = LIST_HEAD_INIT(_audio_dev.idle_reqs),
+};
+
 static struct snd_pcm_ops audio_playback_ops = {
 	.open		= audio_pcm_open,
 	.close		= audio_pcm_close,
@@ -766,28 +784,12 @@
 	config->card = -1;
 	config->device = -1;
 
-	audio = kzalloc(sizeof *audio, GFP_KERNEL);
-	if (!audio)
-		return -ENOMEM;
-
-	audio->func.name = "audio_source";
-
-	spin_lock_init(&audio->lock);
-
-	audio->func.descriptors = fs_audio_desc;
-	audio->func.hs_descriptors = hs_audio_desc;
-	audio->func.bind = audio_bind;
-	audio->func.unbind = audio_unbind;
-	audio->func.set_alt = audio_set_alt;
-	audio->func.setup = audio_setup;
-	audio->func.disable = audio_disable;
-
-	INIT_LIST_HEAD(&audio->idle_reqs);
+	audio = &_audio_dev;
 
 	err = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
 			THIS_MODULE, 0, &card);
 	if (err)
-		goto snd_card_fail;
+		return err;
 
 	snd_card_set_dev(card, &c->cdev->gadget->dev);
 
@@ -826,7 +828,5 @@
 register_fail:
 pcm_fail:
 	snd_card_free(audio->card);
-snd_card_fail:
-	kfree(audio);
 	return err;
 }