Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bb160b85 authored by Sergei Shtylyov's avatar Sergei Shtylyov Committed by Jaroslav Kysela
Browse files

[ALSA] AMD Au1x00: fix DMA init/cleanup



Modules: MIPS AU1x00 driver

AMD Au1x00 ALSA driver causes kernel oops in au1000_init() by trying
to set DMA channel to -1 in yet unallocated audio streams. Here's the
patch that staightens up DMA init/cleanup code.

Signed-off-by: default avatarSergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 97ec558a
Loading
Loading
Loading
Loading
+20 −13
Original line number Original line Diff line number Diff line
@@ -612,15 +612,18 @@ snd_au1000_free(struct snd_card *card)
		release_and_free_resource(au1000->ac97_res_port);
		release_and_free_resource(au1000->ac97_res_port);
	}
	}


	if (au1000->stream[PLAYBACK]) {
	  	if (au1000->stream[PLAYBACK]->dma >= 0)
	  	if (au1000->stream[PLAYBACK]->dma >= 0)
			free_au1000_dma(au1000->stream[PLAYBACK]->dma);
			free_au1000_dma(au1000->stream[PLAYBACK]->dma);
		kfree(au1000->stream[PLAYBACK]);
	}


	if (au1000->stream[CAPTURE]) {
		if (au1000->stream[CAPTURE]->dma >= 0)
		if (au1000->stream[CAPTURE]->dma >= 0)
			free_au1000_dma(au1000->stream[CAPTURE]->dma);
			free_au1000_dma(au1000->stream[CAPTURE]->dma);

	kfree(au1000->stream[PLAYBACK]);
		kfree(au1000->stream[CAPTURE]);
		kfree(au1000->stream[CAPTURE]);
	}
	}
}




static struct snd_card *au1000_card;
static struct snd_card *au1000_card;
@@ -638,13 +641,17 @@ au1000_init(void)


	card->private_free = snd_au1000_free;
	card->private_free = snd_au1000_free;
	au1000 = card->private_data;
	au1000 = card->private_data;
	/* so that snd_au1000_free will work as intended */
	au1000->card = card;
	au1000->card = card;
	au1000->stream[PLAYBACK]->dma = -1;

	au1000->stream[CAPTURE]->dma = -1;
 	au1000->ac97_res_port = NULL;
	au1000->stream[PLAYBACK] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL);
	au1000->stream[PLAYBACK] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL);
	au1000->stream[CAPTURE ] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL);
	au1000->stream[CAPTURE ] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL);
	/* so that snd_au1000_free will work as intended */
 	au1000->ac97_res_port = NULL;
	if (au1000->stream[PLAYBACK])
		au1000->stream[PLAYBACK]->dma = -1;
	if (au1000->stream[CAPTURE ])
		au1000->stream[CAPTURE ]->dma = -1;

	if (au1000->stream[PLAYBACK] == NULL ||
	if (au1000->stream[PLAYBACK] == NULL ||
	    au1000->stream[CAPTURE ] == NULL) {
	    au1000->stream[CAPTURE ] == NULL) {
		snd_card_free(card);
		snd_card_free(card);