[PATCH 0/4] ALSA: ymfpci: PM related cleanups and fixes
Hi,
This series started while attempting to fix the OPL not being detected after restoring from S4 on a YMF744. While attempting to debug the issue, it was found that SIMPLE_DEV_PM_OPS was deprecated, and thus replaced, and a few cleanups were made along the way.
Tasos Sahanidis (4): ALSA: ymfpci: Switch to DEFINE_SIMPLE_DEV_PM_OPS() ALSA: ymfpci: Move allocation of saved registers to struct snd_ymfpci ALSA: ymfpci: Store saved legacy registers in an array ALSA: ymfpci: Store additional legacy registers on suspend
sound/pci/ymfpci/ymfpci.c | 4 +- sound/pci/ymfpci/ymfpci.h | 50 +++++++++++++++++++++--- sound/pci/ymfpci/ymfpci_main.c | 70 ++++++++++------------------------ 3 files changed, 66 insertions(+), 58 deletions(-)
Since commit 1a3c7bb08826 ("PM: core: Add new *_PM_OPS macros, deprecate old ones") SIMPLE_DEV_PM_OPS has been marked deprecated.
The intent is to remove CONFIG_PM_SLEEP guards for PM callbacks. As such the ifdefs are now removed.
Signed-off-by: Tasos Sahanidis tasos@tasossah.com --- sound/pci/ymfpci/ymfpci.c | 4 +--- sound/pci/ymfpci/ymfpci.h | 2 -- sound/pci/ymfpci/ymfpci_main.c | 6 +----- 3 files changed, 2 insertions(+), 10 deletions(-)
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c index 1e198e4d5..30109aa0f 100644 --- a/sound/pci/ymfpci/ymfpci.c +++ b/sound/pci/ymfpci/ymfpci.c @@ -337,11 +337,9 @@ static struct pci_driver ymfpci_driver = { .name = KBUILD_MODNAME, .id_table = snd_ymfpci_ids, .probe = snd_card_ymfpci_probe, -#ifdef CONFIG_PM_SLEEP .driver = { - .pm = &snd_ymfpci_pm, + .pm = pm_sleep_ptr(&snd_ymfpci_pm), }, -#endif };
module_pci_driver(ymfpci_driver); diff --git a/sound/pci/ymfpci/ymfpci.h b/sound/pci/ymfpci/ymfpci.h index 669687764..2103654c6 100644 --- a/sound/pci/ymfpci/ymfpci.h +++ b/sound/pci/ymfpci/ymfpci.h @@ -345,12 +345,10 @@ struct snd_ymfpci { const struct firmware *dsp_microcode; const struct firmware *controller_microcode;
-#ifdef CONFIG_PM_SLEEP u32 *saved_regs; u32 saved_ydsxgr_mode; u16 saved_dsxg_legacy; u16 saved_dsxg_elegacy; -#endif };
int snd_ymfpci_create(struct snd_card *card, diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index 2858736ed..6d13f4152 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -2220,7 +2220,6 @@ static void snd_ymfpci_free(struct snd_card *card) release_firmware(chip->controller_microcode); }
-#ifdef CONFIG_PM_SLEEP static const int saved_regs_index[] = { /* spdif */ YDSXGR_SPDIFOUTCTRL, @@ -2304,8 +2303,7 @@ static int snd_ymfpci_resume(struct device *dev) return 0; }
-SIMPLE_DEV_PM_OPS(snd_ymfpci_pm, snd_ymfpci_suspend, snd_ymfpci_resume); -#endif /* CONFIG_PM_SLEEP */ +DEFINE_SIMPLE_DEV_PM_OPS(snd_ymfpci_pm, snd_ymfpci_suspend, snd_ymfpci_resume);
int snd_ymfpci_create(struct snd_card *card, struct pci_dev *pci, @@ -2374,12 +2372,10 @@ int snd_ymfpci_create(struct snd_card *card, if (err < 0) return err;
-#ifdef CONFIG_PM_SLEEP chip->saved_regs = devm_kmalloc_array(&pci->dev, YDSXGR_NUM_SAVED_REGS, sizeof(u32), GFP_KERNEL); if (!chip->saved_regs) return -ENOMEM; -#endif
snd_ymfpci_proc_init(card, chip);
The registers were previously allocated when CONFIG_PM_SLEEP was set, however this only saved an insignificant amount of memory otherwise.
Signed-off-by: Tasos Sahanidis tasos@tasossah.com --- sound/pci/ymfpci/ymfpci.h | 31 ++++++++++++++++++++++++++++++- sound/pci/ymfpci/ymfpci_main.c | 34 ---------------------------------- 2 files changed, 30 insertions(+), 35 deletions(-)
diff --git a/sound/pci/ymfpci/ymfpci.h b/sound/pci/ymfpci/ymfpci.h index 2103654c6..04e280004 100644 --- a/sound/pci/ymfpci/ymfpci.h +++ b/sound/pci/ymfpci/ymfpci.h @@ -268,6 +268,35 @@ struct snd_ymfpci_pcm { u32 shift; };
+static const int saved_regs_index[] = { + /* spdif */ + YDSXGR_SPDIFOUTCTRL, + YDSXGR_SPDIFOUTSTATUS, + YDSXGR_SPDIFINCTRL, + /* volumes */ + YDSXGR_PRIADCLOOPVOL, + YDSXGR_NATIVEDACINVOL, + YDSXGR_NATIVEDACOUTVOL, + YDSXGR_BUF441OUTVOL, + YDSXGR_NATIVEADCINVOL, + YDSXGR_SPDIFLOOPVOL, + YDSXGR_SPDIFOUTVOL, + YDSXGR_ZVOUTVOL, + YDSXGR_LEGACYOUTVOL, + /* address bases */ + YDSXGR_PLAYCTRLBASE, + YDSXGR_RECCTRLBASE, + YDSXGR_EFFCTRLBASE, + YDSXGR_WORKBASE, + /* capture set up */ + YDSXGR_MAPOFREC, + YDSXGR_RECFORMAT, + YDSXGR_RECSLOTSR, + YDSXGR_ADCFORMAT, + YDSXGR_ADCSLOTSR, +}; +#define YDSXGR_NUM_SAVED_REGS ARRAY_SIZE(saved_regs_index) + struct snd_ymfpci { int irq;
@@ -345,7 +374,7 @@ struct snd_ymfpci { const struct firmware *dsp_microcode; const struct firmware *controller_microcode;
- u32 *saved_regs; + u32 saved_regs[YDSXGR_NUM_SAVED_REGS]; u32 saved_ydsxgr_mode; u16 saved_dsxg_legacy; u16 saved_dsxg_elegacy; diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index 6d13f4152..8bf647824 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -2220,35 +2220,6 @@ static void snd_ymfpci_free(struct snd_card *card) release_firmware(chip->controller_microcode); }
-static const int saved_regs_index[] = { - /* spdif */ - YDSXGR_SPDIFOUTCTRL, - YDSXGR_SPDIFOUTSTATUS, - YDSXGR_SPDIFINCTRL, - /* volumes */ - YDSXGR_PRIADCLOOPVOL, - YDSXGR_NATIVEDACINVOL, - YDSXGR_NATIVEDACOUTVOL, - YDSXGR_BUF441OUTVOL, - YDSXGR_NATIVEADCINVOL, - YDSXGR_SPDIFLOOPVOL, - YDSXGR_SPDIFOUTVOL, - YDSXGR_ZVOUTVOL, - YDSXGR_LEGACYOUTVOL, - /* address bases */ - YDSXGR_PLAYCTRLBASE, - YDSXGR_RECCTRLBASE, - YDSXGR_EFFCTRLBASE, - YDSXGR_WORKBASE, - /* capture set up */ - YDSXGR_MAPOFREC, - YDSXGR_RECFORMAT, - YDSXGR_RECSLOTSR, - YDSXGR_ADCFORMAT, - YDSXGR_ADCSLOTSR, -}; -#define YDSXGR_NUM_SAVED_REGS ARRAY_SIZE(saved_regs_index) - static int snd_ymfpci_suspend(struct device *dev) { struct snd_card *card = dev_get_drvdata(dev); @@ -2372,11 +2343,6 @@ int snd_ymfpci_create(struct snd_card *card, if (err < 0) return err;
- chip->saved_regs = devm_kmalloc_array(&pci->dev, YDSXGR_NUM_SAVED_REGS, - sizeof(u32), GFP_KERNEL); - if (!chip->saved_regs) - return -ENOMEM; - snd_ymfpci_proc_init(card, chip);
return 0;
In preparation for storing more than two legacy PCI registers, the existing ones are moved into a new array.
Signed-off-by: Tasos Sahanidis tasos@tasossah.com --- sound/pci/ymfpci/ymfpci.h | 9 +++++++-- sound/pci/ymfpci/ymfpci_main.c | 18 ++++++++++-------- 2 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/sound/pci/ymfpci/ymfpci.h b/sound/pci/ymfpci/ymfpci.h index 04e280004..192f6ce9b 100644 --- a/sound/pci/ymfpci/ymfpci.h +++ b/sound/pci/ymfpci/ymfpci.h @@ -297,6 +297,12 @@ static const int saved_regs_index[] = { }; #define YDSXGR_NUM_SAVED_REGS ARRAY_SIZE(saved_regs_index)
+static const int pci_saved_regs_index[] = { + PCIR_DSXG_LEGACY, + PCIR_DSXG_ELEGACY, +}; +#define DSXG_PCI_NUM_SAVED_REGS ARRAY_SIZE(pci_saved_regs_index) + struct snd_ymfpci { int irq;
@@ -376,8 +382,7 @@ struct snd_ymfpci {
u32 saved_regs[YDSXGR_NUM_SAVED_REGS]; u32 saved_ydsxgr_mode; - u16 saved_dsxg_legacy; - u16 saved_dsxg_elegacy; + u16 saved_dsxg_pci_regs[DSXG_PCI_NUM_SAVED_REGS]; };
int snd_ymfpci_create(struct snd_card *card, diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index 8bf647824..02c9e454c 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -2228,13 +2228,16 @@ static int snd_ymfpci_suspend(struct device *dev) snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); snd_ac97_suspend(chip->ac97); + for (i = 0; i < YDSXGR_NUM_SAVED_REGS; i++) chip->saved_regs[i] = snd_ymfpci_readl(chip, saved_regs_index[i]); + chip->saved_ydsxgr_mode = snd_ymfpci_readl(chip, YDSXGR_MODE); - pci_read_config_word(chip->pci, PCIR_DSXG_LEGACY, - &chip->saved_dsxg_legacy); - pci_read_config_word(chip->pci, PCIR_DSXG_ELEGACY, - &chip->saved_dsxg_elegacy); + + for (i = 0; i < DSXG_PCI_NUM_SAVED_REGS; i++) + pci_read_config_word(chip->pci, pci_saved_regs_index[i], + chip->saved_dsxg_pci_regs + i); + snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0); snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0); snd_ymfpci_disable_dsp(chip); @@ -2258,10 +2261,9 @@ static int snd_ymfpci_resume(struct device *dev)
snd_ac97_resume(chip->ac97);
- pci_write_config_word(chip->pci, PCIR_DSXG_LEGACY, - chip->saved_dsxg_legacy); - pci_write_config_word(chip->pci, PCIR_DSXG_ELEGACY, - chip->saved_dsxg_elegacy); + for (i = 0; i < DSXG_PCI_NUM_SAVED_REGS; i++) + pci_write_config_word(chip->pci, pci_saved_regs_index[i], + chip->saved_dsxg_pci_regs[i]);
/* start hw again */ if (chip->start_count > 0) {
YMF744 and newer store the base IO ports in separate PCI config registers.
Since these registers were not restored, when set to a non-default value, features that rely on them (FM, MPU401, gameport) were not functional after restore, as their respective IO ports were reset to their defaults.
Signed-off-by: Tasos Sahanidis tasos@tasossah.com --- sound/pci/ymfpci/ymfpci.h | 8 ++++++++ sound/pci/ymfpci/ymfpci_main.c | 16 +++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/sound/pci/ymfpci/ymfpci.h b/sound/pci/ymfpci/ymfpci.h index 192f6ce9b..d5dd0e5ae 100644 --- a/sound/pci/ymfpci/ymfpci.h +++ b/sound/pci/ymfpci/ymfpci.h @@ -298,10 +298,18 @@ static const int saved_regs_index[] = { #define YDSXGR_NUM_SAVED_REGS ARRAY_SIZE(saved_regs_index)
static const int pci_saved_regs_index[] = { + /* All Chips */ PCIR_DSXG_LEGACY, PCIR_DSXG_ELEGACY, + /* YMF 744/754 */ + PCIR_DSXG_FMBASE, + PCIR_DSXG_SBBASE, + PCIR_DSXG_MPU401BASE, + PCIR_DSXG_JOYBASE, }; #define DSXG_PCI_NUM_SAVED_REGS ARRAY_SIZE(pci_saved_regs_index) +#define DSXG_PCI_NUM_SAVED_LEGACY_REGS 2 +static_assert(DSXG_PCI_NUM_SAVED_LEGACY_REGS <= DSXG_PCI_NUM_SAVED_REGS);
struct snd_ymfpci { int irq; diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index 02c9e454c..0963f3ae3 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -2224,8 +2224,11 @@ static int snd_ymfpci_suspend(struct device *dev) { struct snd_card *card = dev_get_drvdata(dev); struct snd_ymfpci *chip = card->private_data; - unsigned int i; - + unsigned int i, legacy_reg_count = DSXG_PCI_NUM_SAVED_LEGACY_REGS; + + if (chip->pci->device >= 0x0010) /* YMF 744/754 */ + legacy_reg_count = DSXG_PCI_NUM_SAVED_REGS; + snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); snd_ac97_suspend(chip->ac97);
@@ -2234,7 +2237,7 @@ static int snd_ymfpci_suspend(struct device *dev)
chip->saved_ydsxgr_mode = snd_ymfpci_readl(chip, YDSXGR_MODE);
- for (i = 0; i < DSXG_PCI_NUM_SAVED_REGS; i++) + for (i = 0; i < legacy_reg_count; i++) pci_read_config_word(chip->pci, pci_saved_regs_index[i], chip->saved_dsxg_pci_regs + i);
@@ -2249,7 +2252,10 @@ static int snd_ymfpci_resume(struct device *dev) struct pci_dev *pci = to_pci_dev(dev); struct snd_card *card = dev_get_drvdata(dev); struct snd_ymfpci *chip = card->private_data; - unsigned int i; + unsigned int i, legacy_reg_count = DSXG_PCI_NUM_SAVED_LEGACY_REGS; + + if (chip->pci->device >= 0x0010) /* YMF 744/754 */ + legacy_reg_count = DSXG_PCI_NUM_SAVED_REGS;
snd_ymfpci_aclink_reset(pci); snd_ymfpci_codec_ready(chip, 0); @@ -2261,7 +2267,7 @@ static int snd_ymfpci_resume(struct device *dev)
snd_ac97_resume(chip->ac97);
- for (i = 0; i < DSXG_PCI_NUM_SAVED_REGS; i++) + for (i = 0; i < legacy_reg_count; i++) pci_write_config_word(chip->pci, pci_saved_regs_index[i], chip->saved_dsxg_pci_regs[i]);
On Wed, 29 Mar 2023 06:14:36 +0200, Tasos Sahanidis wrote:
Hi,
This series started while attempting to fix the OPL not being detected after restoring from S4 on a YMF744. While attempting to debug the issue, it was found that SIMPLE_DEV_PM_OPS was deprecated, and thus replaced, and a few cleanups were made along the way.
Tasos Sahanidis (4): ALSA: ymfpci: Switch to DEFINE_SIMPLE_DEV_PM_OPS() ALSA: ymfpci: Move allocation of saved registers to struct snd_ymfpci ALSA: ymfpci: Store saved legacy registers in an array ALSA: ymfpci: Store additional legacy registers on suspend
Applied all four patches to for-next branch.
thanks,
Takashi
participants (2)
-
Takashi Iwai
-
Tasos Sahanidis