Re: [alsa-devel] PROBLEM: snd-au8830: dead after software suspend

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



At Sat, 04 Aug 2007 02:51:44 +0200,
Gert Robben wrote:
> 
> >>> Have you reported this to the ALSA people?
> >> No, I thought this might as well be something for PCI or PM people, and 
> >> I expected some ALSA people are also reading this list.
> >> If not, where else should I report this exactly?
> > alsa-devel [...] the author of the driver
> Done (original message below). Thanks again :)
> 
> Gert Robben wrote:
> > After a suspend-resume cycle (using Suspend2), my sound card doesn't 
> > work anymore. It works again after reloading the module.
> > 
> > dmesg, initial boot:
> >> Linux version 2.6.22-ck1
> > ----8<----
> >> PCI driver au8830 lacks driver specific resume support.
> > 
> > dmesg, after resume, trying to use the card:
> >> vortex: ac97 codec stuck busy
> > 
> > Thanks for any help!
> > 
> > Gert Robben

The below is an untested fix.  Give it a try.


Takashi

diff -r 23fc708178e1 pci/au88x0/au88x0.c
--- a/pci/au88x0/au88x0.c	Mon Aug 06 14:05:27 2007 +0200
+++ b/pci/au88x0/au88x0.c	Mon Aug 06 15:19:16 2007 +0200
@@ -78,7 +78,7 @@ static void vortex_fix_agp_bridge(struct
 	}
 }
 
-static void __devinit snd_vortex_workaround(struct pci_dev *vortex, int fix)
+static void snd_vortex_workaround(struct pci_dev *vortex, int fix)
 {
 	struct pci_dev *via = NULL;
 
@@ -117,6 +117,50 @@ static void __devinit snd_vortex_workaro
 	pci_dev_put(via);
 }
 
+/*
+ * Power management code
+ */
+#ifdef CONFIG_PM
+static int snd_vortex_suspend(struct pci_dev *pci, pm_message_t state)
+{
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct snd_vortex *chip = card->private_data;
+	int i;
+
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+	for (i = 0; i < VORTEX_PCM_LAST; i++)
+		snd_pcm_suspend_all(chip->pcm[i]);
+	snd_ac97_suspend(chip->codec);
+	vortex_core_shutdown(chip);
+	pci_disable_device(pci);
+	pci_save_state(pci);
+	return 0;
+}
+
+static int snd_vortex_resume(struct pci_dev *pci)
+{
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct snd_vortex *chip = card->private_data;
+
+	pci_set_power_state(pci, PCI_D0);
+	pci_restore_state(pci);
+	if (pci_enable_device(pci) < 0) {
+		printk(KERN_ERR "au88x0: pci_enable_device failed, "
+		       "disabling device\n");
+		snd_card_disconnect(card);
+		return -EIO;
+	}
+	pci_set_master(pci);
+	vortex_core_init(chip, 1);
+	snd_vortex_workaround(pci, chip->pcifix);
+	snd_ac97_resume(chip->codec);
+	vortex_connect_default(chip, 1);
+	vortex_enable_int(chip);
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+	return 0;
+}
+#endif /* CONFIG_PM */
+
 // component-destructor
 // (see "Management of Cards and Components")
 static int snd_vortex_dev_free(struct snd_device *device)
@@ -192,7 +236,7 @@ snd_vortex_create(struct snd_card *card,
 	/* Init audio core.
 	 * This must be done before we do request_irq otherwise we can get spurious
 	 * interupts that we do not handle properly and make a mess of things */
-	if ((err = vortex_core_init(chip)) != 0) {
+	if ((err = vortex_core_init(chip, 0)) != 0) {
 		printk(KERN_ERR "hw core init failed\n");
 		goto core_out;
 	}
@@ -262,7 +306,9 @@ snd_vortex_probe(struct pci_dev *pci, co
 		snd_card_free(card);
 		return err;
 	}
-	snd_vortex_workaround(pci, pcifix[dev]);
+	card->private_data = chip;
+	chip->pcifix = pcifix[dev];
+	snd_vortex_workaround(pci, chip->pcifix);
 
 	// Card details needed in snd_vortex_midi
 	strcpy(card->driver, CARD_NAME_SHORT);
@@ -382,6 +428,10 @@ static struct pci_driver driver = {
 	.id_table = snd_vortex_ids,
 	.probe = snd_vortex_probe,
 	.remove = __devexit_p(snd_vortex_remove),
+#ifdef CONFIG_PM
+	.suspend = snd_vortex_suspend,
+	.resume = snd_vortex_resume,
+#endif
 };
 
 // initialization of the module
diff -r 23fc708178e1 pci/au88x0/au88x0.h
--- a/pci/au88x0/au88x0.h	Mon Aug 06 14:05:27 2007 +0200
+++ b/pci/au88x0/au88x0.h	Mon Aug 06 15:19:16 2007 +0200
@@ -178,7 +178,7 @@ struct snd_vortex {
 	/* PCI hardware resources */
 	unsigned long io;
 	void __iomem *mmio;
-	unsigned int irq;
+	int irq;
 	spinlock_t lock;
 
 	/* PCI device */
@@ -186,6 +186,7 @@ struct snd_vortex {
 	u16 vendor;
 	u16 device;
 	u8 rev;
+	int pcifix;
 };
 
 /* Functions. */
@@ -233,7 +234,7 @@ static unsigned short vortex_codec_read(
 static unsigned short vortex_codec_read(struct snd_ac97 * codec, unsigned short addr);
 static void vortex_spdif_init(vortex_t * vortex, int spdif_sr, int spdif_mode);
 
-static int vortex_core_init(vortex_t * card);
+static int vortex_core_init(vortex_t * card, int do_resume);
 static int vortex_core_shutdown(vortex_t * card);
 static void vortex_enable_int(vortex_t * card);
 static irqreturn_t vortex_interrupt(int irq, void *dev_id);
diff -r 23fc708178e1 pci/au88x0/au88x0_a3d.c
--- a/pci/au88x0/au88x0_a3d.c	Mon Aug 06 14:05:27 2007 +0200
+++ b/pci/au88x0/au88x0_a3d.c	Mon Aug 06 15:19:16 2007 +0200
@@ -593,7 +593,7 @@ static int vortex_a3d_register_controls(
 static int vortex_a3d_register_controls(vortex_t * vortex);
 static void vortex_a3d_unregister_controls(vortex_t * vortex);
 /* A3D base support init/shudown */
-static void __devinit vortex_Vort3D_enable(vortex_t * v)
+static void vortex_Vort3D_enable(vortex_t * v)
 {
 	int i;
 
diff -r 23fc708178e1 pci/au88x0/au88x0_core.c
--- a/pci/au88x0/au88x0_core.c	Mon Aug 06 14:05:27 2007 +0200
+++ b/pci/au88x0/au88x0_core.c	Mon Aug 06 15:19:16 2007 +0200
@@ -2658,7 +2658,7 @@ static void vortex_spdif_init(vortex_t *
 
 /* Initialization */
 
-static int __devinit vortex_core_init(vortex_t * vortex)
+static int vortex_core_init(vortex_t * vortex, int do_resume)
 {
 
 	printk(KERN_INFO "Vortex: init.... ");
@@ -2688,7 +2688,8 @@ static int __devinit vortex_core_init(vo
 	vortex_mixer_init(vortex);
 	vortex_srcblock_init(vortex);
 #ifndef CHIP_AU8820
-	vortex_eq_init(vortex);
+	if (!do_resume)
+		vortex_eq_init(vortex);
 	vortex_spdif_init(vortex, 48000, 1);
 	vortex_Vort3D_enable(vortex);
 #endif
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux