Skip to content

Commit

Permalink
[ALSA] Various fixes for suspend/resume of ALSA PCI drivers
Browse files Browse the repository at this point in the history
- Check the return value of pci_enable_device() and request_irq()
  in the suspend.  If any error occurs there, disable the device
  using snd_card_disconnect().
- Call pci_set_power_state() properly with pci_choose_state().
- Fix the order to call pci_set_power_state().
- Removed obsolete house-made PM codes in some drivers.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
  • Loading branch information
Takashi Iwai authored and Jaroslav Kysela committed Oct 22, 2006
1 parent c06134d commit 30b3539
Show file tree
Hide file tree
Showing 26 changed files with 276 additions and 145 deletions.
11 changes: 10 additions & 1 deletion sound/pci/ali5451/ali5451.c
Original file line number Diff line number Diff line change
Expand Up @@ -2032,8 +2032,10 @@ static int ali_suspend(struct pci_dev *pci, pm_message_t state)
outl(0xffffffff, ALI_REG(chip, ALI_STOP));

spin_unlock_irq(&chip->reg_lock);

pci_disable_device(pci);
pci_save_state(pci);
pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}

Expand All @@ -2048,8 +2050,15 @@ static int ali_resume(struct pci_dev *pci)
if (! im)
return 0;

pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
pci_enable_device(pci);
if (pci_enable_device(pci) < 0) {
printk(KERN_ERR "ali5451: pci_enable_device failed, "
"disabling device\n");
snd_card_disconnect(card);
return -EIO;
}
pci_set_master(pci);

spin_lock_irq(&chip->reg_lock);

Expand Down
11 changes: 8 additions & 3 deletions sound/pci/als300.c
Original file line number Diff line number Diff line change
Expand Up @@ -768,9 +768,9 @@ static int snd_als300_suspend(struct pci_dev *pci, pm_message_t state)
snd_pcm_suspend_all(chip->pcm);
snd_ac97_suspend(chip->ac97);

pci_set_power_state(pci, PCI_D3hot);
pci_disable_device(pci);
pci_save_state(pci);
pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}

Expand All @@ -779,9 +779,14 @@ static int snd_als300_resume(struct pci_dev *pci)
struct snd_card *card = pci_get_drvdata(pci);
struct snd_als300 *chip = card->private_data;

pci_restore_state(pci);
pci_enable_device(pci);
pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
if (pci_enable_device(pci) < 0) {
printk(KERN_ERR "als300: pci_enable_device failed, "
"disabling device\n");
snd_card_disconnect(card);
return -EIO;
}
pci_set_master(pci);

snd_als300_init(chip);
Expand Down
11 changes: 8 additions & 3 deletions sound/pci/als4000.c
Original file line number Diff line number Diff line change
Expand Up @@ -804,9 +804,9 @@ static int snd_als4000_suspend(struct pci_dev *pci, pm_message_t state)
snd_pcm_suspend_all(chip->pcm);
snd_sbmixer_suspend(chip);

pci_set_power_state(pci, PCI_D3hot);
pci_disable_device(pci);
pci_save_state(pci);
pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}

Expand All @@ -816,9 +816,14 @@ static int snd_als4000_resume(struct pci_dev *pci)
struct snd_card_als4000 *acard = card->private_data;
struct snd_sb *chip = acard->chip;

pci_restore_state(pci);
pci_enable_device(pci);
pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
if (pci_enable_device(pci) < 0) {
printk(KERN_ERR "als4000: pci_enable_device failed, "
"disabling device\n");
snd_card_disconnect(card);
return -EIO;
}
pci_set_master(pci);

snd_als4000_configure(chip);
Expand Down
11 changes: 8 additions & 3 deletions sound/pci/atiixp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1442,9 +1442,9 @@ static int snd_atiixp_suspend(struct pci_dev *pci, pm_message_t state)
snd_atiixp_aclink_down(chip);
snd_atiixp_chip_stop(chip);

pci_set_power_state(pci, PCI_D3hot);
pci_disable_device(pci);
pci_save_state(pci);
pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}

Expand All @@ -1454,9 +1454,14 @@ static int snd_atiixp_resume(struct pci_dev *pci)
struct atiixp *chip = card->private_data;
int i;

pci_restore_state(pci);
pci_enable_device(pci);
pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
if (pci_enable_device(pci) < 0) {
printk(KERN_ERR "atiixp: pci_enable_device failed, "
"disabling device\n");
snd_card_disconnect(card);
return -EIO;
}
pci_set_master(pci);

snd_atiixp_aclink_reset(chip);
Expand Down
11 changes: 8 additions & 3 deletions sound/pci/atiixp_modem.c
Original file line number Diff line number Diff line change
Expand Up @@ -1128,9 +1128,9 @@ static int snd_atiixp_suspend(struct pci_dev *pci, pm_message_t state)
snd_atiixp_aclink_down(chip);
snd_atiixp_chip_stop(chip);

pci_set_power_state(pci, PCI_D3hot);
pci_disable_device(pci);
pci_save_state(pci);
pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}

Expand All @@ -1140,9 +1140,14 @@ static int snd_atiixp_resume(struct pci_dev *pci)
struct atiixp_modem *chip = card->private_data;
int i;

pci_restore_state(pci);
pci_enable_device(pci);
pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
if (pci_enable_device(pci) < 0) {
printk(KERN_ERR "atiixp-modem: pci_enable_device failed, "
"disabling device\n");
snd_card_disconnect(card);
return -EIO;
}
pci_set_master(pci);

snd_atiixp_aclink_reset(chip);
Expand Down
11 changes: 8 additions & 3 deletions sound/pci/azt3328.c
Original file line number Diff line number Diff line change
Expand Up @@ -1903,9 +1903,9 @@ snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
for (reg = 0; reg < AZF_IO_SIZE_SYNTH_PM / 2; reg++)
chip->saved_regs_synth[reg] = inw(chip->synth_port + reg * 2);

pci_set_power_state(pci, PCI_D3hot);
pci_disable_device(pci);
pci_save_state(pci);
pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}

Expand All @@ -1916,9 +1916,14 @@ snd_azf3328_resume(struct pci_dev *pci)
struct snd_azf3328 *chip = card->private_data;
int reg;

pci_restore_state(pci);
pci_enable_device(pci);
pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
if (pci_enable_device(pci) < 0) {
printk(KERN_ERR "azt3328: pci_enable_device failed, "
"disabling device\n");
snd_card_disconnect(card);
return -EIO;
}
pci_set_master(pci);

for (reg = 0; reg < AZF_IO_SIZE_IO2_PM / 2; reg++)
Expand Down
11 changes: 8 additions & 3 deletions sound/pci/cmipci.c
Original file line number Diff line number Diff line change
Expand Up @@ -3122,9 +3122,9 @@ static int snd_cmipci_suspend(struct pci_dev *pci, pm_message_t state)
/* disable ints */
snd_cmipci_write(cm, CM_REG_INT_HLDCLR, 0);

pci_set_power_state(pci, PCI_D3hot);
pci_disable_device(pci);
pci_save_state(pci);
pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}

Expand All @@ -3134,9 +3134,14 @@ static int snd_cmipci_resume(struct pci_dev *pci)
struct cmipci *cm = card->private_data;
int i;

pci_restore_state(pci);
pci_enable_device(pci);
pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
if (pci_enable_device(pci) < 0) {
printk(KERN_ERR "cmipci: pci_enable_device failed, "
"disabling device\n");
snd_card_disconnect(card);
return -EIO;
}
pci_set_master(pci);

/* reset / initialize to a sane state */
Expand Down
9 changes: 8 additions & 1 deletion sound/pci/cs4281.c
Original file line number Diff line number Diff line change
Expand Up @@ -2050,6 +2050,7 @@ static int cs4281_suspend(struct pci_dev *pci, pm_message_t state)

pci_disable_device(pci);
pci_save_state(pci);
pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}

Expand All @@ -2060,8 +2061,14 @@ static int cs4281_resume(struct pci_dev *pci)
unsigned int i;
u32 ulCLK;

pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
pci_enable_device(pci);
if (pci_enable_device(pci) < 0) {
printk(KERN_ERR "cs4281: pci_enable_device failed, "
"disabling device\n");
snd_card_disconnect(card);
return -EIO;
}
pci_set_master(pci);

ulCLK = snd_cs4281_peekBA0(chip, BA0_CLKCR1);
Expand Down
11 changes: 10 additions & 1 deletion sound/pci/cs46xx/cs46xx_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -3687,8 +3687,10 @@ int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state)
/* disable CLKRUN */
chip->active_ctrl(chip, -chip->amplifier);
chip->amplifier = amp_saved; /* restore the status */

pci_disable_device(pci);
pci_save_state(pci);
pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}

Expand All @@ -3698,9 +3700,16 @@ int snd_cs46xx_resume(struct pci_dev *pci)
struct snd_cs46xx *chip = card->private_data;
int amp_saved;

pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
pci_enable_device(pci);
if (pci_enable_device(pci) < 0) {
printk(KERN_ERR "cs46xx: pci_enable_device failed, "
"disabling device\n");
snd_card_disconnect(card);
return -EIO;
}
pci_set_master(pci);

amp_saved = chip->amplifier;
chip->amplifier = 0;
chip->active_ctrl(chip, 1); /* force to on */
Expand Down
11 changes: 9 additions & 2 deletions sound/pci/cs5535audio/cs5535audio_pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,10 @@ int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state)
snd_ac97_suspend(cs5535au->ac97);
/* save important regs, then disable aclink in hw */
snd_cs5535audio_stop_hardware(cs5535au);

pci_disable_device(pci);
pci_save_state(pci);

pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}

Expand All @@ -87,8 +88,14 @@ int snd_cs5535audio_resume(struct pci_dev *pci)
int timeout;
int i;

pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
pci_enable_device(pci);
if (pci_enable_device(pci) < 0) {
printk(KERN_ERR "cs5535audio: pci_enable_device failed, "
"disabling device\n");
snd_card_disconnect(card);
return -EIO;
}
pci_set_master(pci);

/* set LNK_WRM_RST to reset AC link */
Expand Down
13 changes: 9 additions & 4 deletions sound/pci/emu10k1/emu10k1.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,9 @@ static int snd_emu10k1_suspend(struct pci_dev *pci, pm_message_t state)

snd_emu10k1_done(emu);

pci_set_power_state(pci, PCI_D3hot);
pci_disable_device(pci);
pci_save_state(pci);
pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}

Expand All @@ -237,11 +237,16 @@ static int snd_emu10k1_resume(struct pci_dev *pci)
struct snd_card *card = pci_get_drvdata(pci);
struct snd_emu10k1 *emu = card->private_data;

pci_restore_state(pci);
pci_enable_device(pci);
pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
if (pci_enable_device(pci) < 0) {
printk(KERN_ERR "emu10k1: pci_enable_device failed, "
"disabling device\n");
snd_card_disconnect(card);
return -EIO;
}
pci_set_master(pci);

snd_emu10k1_resume_init(emu);
snd_emu10k1_efx_resume(emu);
snd_ac97_resume(emu->ac97);
Expand Down
12 changes: 9 additions & 3 deletions sound/pci/ens1370.c
Original file line number Diff line number Diff line change
Expand Up @@ -2072,9 +2072,10 @@ static int snd_ensoniq_suspend(struct pci_dev *pci, pm_message_t state)
udelay(100);
snd_ak4531_suspend(ensoniq->u.es1370.ak4531);
#endif
pci_set_power_state(pci, PCI_D3hot);

pci_disable_device(pci);
pci_save_state(pci);
pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}

Expand All @@ -2083,9 +2084,14 @@ static int snd_ensoniq_resume(struct pci_dev *pci)
struct snd_card *card = pci_get_drvdata(pci);
struct ensoniq *ensoniq = card->private_data;

pci_restore_state(pci);
pci_enable_device(pci);
pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
if (pci_enable_device(pci) < 0) {
printk(KERN_ERR DRIVER_NAME ": pci_enable_device failed, "
"disabling device\n");
snd_card_disconnect(card);
return -EIO;
}
pci_set_master(pci);

snd_ensoniq_chip_init(ensoniq);
Expand Down
29 changes: 24 additions & 5 deletions sound/pci/es1938.c
Original file line number Diff line number Diff line change
Expand Up @@ -1481,10 +1481,14 @@ static int es1938_suspend(struct pci_dev *pci, pm_message_t state)
*d = snd_es1938_reg_read(chip, *s);

outb(0x00, SLIO_REG(chip, IRQCONTROL)); /* disable irqs */
if (chip->irq >= 0)
if (chip->irq >= 0) {
synchronize_irq(chip->irq);
free_irq(chip->irq, chip);
chip->irq = -1;
}
pci_disable_device(pci);
pci_save_state(pci);
pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}

Expand All @@ -1494,10 +1498,22 @@ static int es1938_resume(struct pci_dev *pci)
struct es1938 *chip = card->private_data;
unsigned char *s, *d;

pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
pci_enable_device(pci);
request_irq(pci->irq, snd_es1938_interrupt,
IRQF_DISABLED|IRQF_SHARED, "ES1938", chip);
if (pci_enable_device(pci) < 0) {
printk(KERN_ERR "es1938: pci_enable_device failed, "
"disabling device\n");
snd_card_disconnect(card);
return -EIO;
}

if (request_irq(pci->irq, snd_es1938_interrupt,
IRQF_DISABLED|IRQF_SHARED, "ES1938", chip)) {
printk(KERN_ERR "es1938: unable to grab IRQ %d, "
"disabling device\n", pci->irq);
snd_card_disconnect(card);
return -EIO;
}
chip->irq = pci->irq;
snd_es1938_chip_init(chip);

Expand Down Expand Up @@ -1556,8 +1572,10 @@ static int snd_es1938_free(struct es1938 *chip)

snd_es1938_free_gameport(chip);

if (chip->irq >= 0)
if (chip->irq >= 0) {
synchronize_irq(chip->irq);
free_irq(chip->irq, chip);
}
pci_release_regions(chip->pci);
pci_disable_device(chip->pci);
kfree(chip);
Expand Down Expand Up @@ -1602,6 +1620,7 @@ static int __devinit snd_es1938_create(struct snd_card *card,
spin_lock_init(&chip->mixer_lock);
chip->card = card;
chip->pci = pci;
chip->irq = -1;
if ((err = pci_request_regions(pci, "ESS Solo-1")) < 0) {
kfree(chip);
pci_disable_device(pci);
Expand Down
Loading

0 comments on commit 30b3539

Please sign in to comment.