Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1765514AbXHFNa7 (ORCPT ); Mon, 6 Aug 2007 09:30:59 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S932917AbXHFNVT (ORCPT ); Mon, 6 Aug 2007 09:21:19 -0400 Received: from mx1.suse.de ([195.135.220.2]:35563 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932819AbXHFNVS (ORCPT ); Mon, 6 Aug 2007 09:21:18 -0400 Date: Mon, 06 Aug 2007 15:21:16 +0200 Message-ID: From: Takashi Iwai To: Gert Robben Cc: alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, mjander@embedded.cl Subject: Re: [alsa-devel] PROBLEM: snd-au8830: dead after software suspend In-Reply-To: <46B3CDA0.90804@gert.robben.nu> References: <46B3A4F5.2000708@gert.robben.nu> <46B3C44D.7020801@gert.robben.nu> <46B3CDA0.90804@gert.robben.nu> User-Agent: Wanderlust/2.15.5 (Almost Unreal) SEMI/1.14.6 (Maruoka) FLIM/1.14.7 (=?ISO-8859-4?Q?Sanj=F2?=) APEL/10.6 MULE XEmacs/21.5 (beta27) (fiddleheads) (+CVS-20060704) (i386-suse-linux) MIME-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-Type: text/plain; charset=US-ASCII Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 6134 Lines: 193 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 majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/