Commit 5bff69b3 authored by Takashi Iwai's avatar Takashi Iwai

ALSA: cs46xx: Allocate resources with device-managed APIs

This patch converts the resource management in PCI cs46xx driver with
devres as a clean up.  Each manual resource management is converted
with the corresponding devres helper, and the card object release is
managed now via card->private_free instead of a lowlevel snd_device.

This should give no user-visible functional changes.

Link: https://lore.kernel.org/r/20210715075941.23332-31-tiwai@suse.deSigned-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 1656fa6e
...@@ -66,61 +66,44 @@ static int snd_card_cs46xx_probe(struct pci_dev *pci, ...@@ -66,61 +66,44 @@ static int snd_card_cs46xx_probe(struct pci_dev *pci,
return -ENOENT; return -ENOENT;
} }
err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
0, &card); sizeof(*chip), &card);
if (err < 0) if (err < 0)
return err; return err;
chip = card->private_data;
err = snd_cs46xx_create(card, pci, err = snd_cs46xx_create(card, pci,
external_amp[dev], thinkpad[dev], external_amp[dev], thinkpad[dev]);
&chip); if (err < 0)
if (err < 0) {
snd_card_free(card);
return err; return err;
}
card->private_data = chip; card->private_data = chip;
chip->accept_valid = mmap_valid[dev]; chip->accept_valid = mmap_valid[dev];
err = snd_cs46xx_pcm(chip, 0); err = snd_cs46xx_pcm(chip, 0);
if (err < 0) { if (err < 0)
snd_card_free(card);
return err; return err;
}
#ifdef CONFIG_SND_CS46XX_NEW_DSP #ifdef CONFIG_SND_CS46XX_NEW_DSP
err = snd_cs46xx_pcm_rear(chip, 1); err = snd_cs46xx_pcm_rear(chip, 1);
if (err < 0) { if (err < 0)
snd_card_free(card);
return err; return err;
}
err = snd_cs46xx_pcm_iec958(chip, 2); err = snd_cs46xx_pcm_iec958(chip, 2);
if (err < 0) { if (err < 0)
snd_card_free(card);
return err; return err;
}
#endif #endif
err = snd_cs46xx_mixer(chip, 2); err = snd_cs46xx_mixer(chip, 2);
if (err < 0) { if (err < 0)
snd_card_free(card);
return err; return err;
}
#ifdef CONFIG_SND_CS46XX_NEW_DSP #ifdef CONFIG_SND_CS46XX_NEW_DSP
if (chip->nr_ac97_codecs ==2) { if (chip->nr_ac97_codecs ==2) {
err = snd_cs46xx_pcm_center_lfe(chip, 3); err = snd_cs46xx_pcm_center_lfe(chip, 3);
if (err < 0) { if (err < 0)
snd_card_free(card);
return err; return err;
}
} }
#endif #endif
err = snd_cs46xx_midi(chip, 0); err = snd_cs46xx_midi(chip, 0);
if (err < 0) { if (err < 0)
snd_card_free(card);
return err; return err;
}
err = snd_cs46xx_start_dsp(chip); err = snd_cs46xx_start_dsp(chip);
if (err < 0) { if (err < 0)
snd_card_free(card);
return err; return err;
}
snd_cs46xx_gameport(chip); snd_cs46xx_gameport(chip);
...@@ -133,26 +116,18 @@ static int snd_card_cs46xx_probe(struct pci_dev *pci, ...@@ -133,26 +116,18 @@ static int snd_card_cs46xx_probe(struct pci_dev *pci,
chip->irq); chip->irq);
err = snd_card_register(card); err = snd_card_register(card);
if (err < 0) { if (err < 0)
snd_card_free(card);
return err; return err;
}
pci_set_drvdata(pci, card); pci_set_drvdata(pci, card);
dev++; dev++;
return 0; return 0;
} }
static void snd_card_cs46xx_remove(struct pci_dev *pci)
{
snd_card_free(pci_get_drvdata(pci));
}
static struct pci_driver cs46xx_driver = { static struct pci_driver cs46xx_driver = {
.name = KBUILD_MODNAME, .name = KBUILD_MODNAME,
.id_table = snd_cs46xx_ids, .id_table = snd_cs46xx_ids,
.probe = snd_card_cs46xx_probe, .probe = snd_card_cs46xx_probe,
.remove = snd_card_cs46xx_remove,
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
.driver = { .driver = {
.pm = &snd_cs46xx_pm, .pm = &snd_cs46xx_pm,
......
...@@ -1635,7 +1635,6 @@ struct snd_cs46xx_region { ...@@ -1635,7 +1635,6 @@ struct snd_cs46xx_region {
unsigned long base; unsigned long base;
void __iomem *remap_addr; void __iomem *remap_addr;
unsigned long size; unsigned long size;
struct resource *resource;
}; };
struct snd_cs46xx { struct snd_cs46xx {
...@@ -1718,8 +1717,7 @@ struct snd_cs46xx { ...@@ -1718,8 +1717,7 @@ struct snd_cs46xx {
int snd_cs46xx_create(struct snd_card *card, int snd_cs46xx_create(struct snd_card *card,
struct pci_dev *pci, struct pci_dev *pci,
int external_amp, int thinkpad, int external_amp, int thinkpad);
struct snd_cs46xx **rcodec);
extern const struct dev_pm_ops snd_cs46xx_pm; extern const struct dev_pm_ops snd_cs46xx_pm;
int snd_cs46xx_pcm(struct snd_cs46xx *chip, int device); int snd_cs46xx_pcm(struct snd_cs46xx *chip, int device);
......
...@@ -1865,13 +1865,6 @@ int snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device) ...@@ -1865,13 +1865,6 @@ int snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device)
/* /*
* Mixer routines * Mixer routines
*/ */
static void snd_cs46xx_mixer_free_ac97_bus(struct snd_ac97_bus *bus)
{
struct snd_cs46xx *chip = bus->private_data;
chip->ac97_bus = NULL;
}
static void snd_cs46xx_mixer_free_ac97(struct snd_ac97 *ac97) static void snd_cs46xx_mixer_free_ac97(struct snd_ac97 *ac97)
{ {
struct snd_cs46xx *chip = ac97->private_data; struct snd_cs46xx *chip = ac97->private_data;
...@@ -2487,7 +2480,6 @@ int snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device) ...@@ -2487,7 +2480,6 @@ int snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device)
err = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus); err = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus);
if (err < 0) if (err < 0)
return err; return err;
chip->ac97_bus->private_free = snd_cs46xx_mixer_free_ac97_bus;
if (cs46xx_detect_codec(chip, CS46XX_PRIMARY_CODEC_INDEX) < 0) if (cs46xx_detect_codec(chip, CS46XX_PRIMARY_CODEC_INDEX) < 0)
return -ENXIO; return -ENXIO;
...@@ -2913,12 +2905,12 @@ static void snd_cs46xx_hw_stop(struct snd_cs46xx *chip) ...@@ -2913,12 +2905,12 @@ static void snd_cs46xx_hw_stop(struct snd_cs46xx *chip)
} }
static int snd_cs46xx_free(struct snd_cs46xx *chip) static void snd_cs46xx_free(struct snd_card *card)
{ {
struct snd_cs46xx *chip = card->private_data;
#ifdef CONFIG_SND_CS46XX_NEW_DSP
int idx; int idx;
#endif
if (snd_BUG_ON(!chip))
return -EINVAL;
if (chip->active_ctrl) if (chip->active_ctrl)
chip->active_ctrl(chip, 1); chip->active_ctrl(chip, 1);
...@@ -2930,22 +2922,11 @@ static int snd_cs46xx_free(struct snd_cs46xx *chip) ...@@ -2930,22 +2922,11 @@ static int snd_cs46xx_free(struct snd_cs46xx *chip)
snd_cs46xx_proc_done(chip); snd_cs46xx_proc_done(chip);
if (chip->region.idx[0].resource) snd_cs46xx_hw_stop(chip);
snd_cs46xx_hw_stop(chip);
if (chip->irq >= 0)
free_irq(chip->irq, chip);
if (chip->active_ctrl) if (chip->active_ctrl)
chip->active_ctrl(chip, -chip->amplifier); chip->active_ctrl(chip, -chip->amplifier);
for (idx = 0; idx < 5; idx++) {
struct snd_cs46xx_region *region = &chip->region.idx[idx];
iounmap(region->remap_addr);
release_and_free_resource(region->resource);
}
#ifdef CONFIG_SND_CS46XX_NEW_DSP #ifdef CONFIG_SND_CS46XX_NEW_DSP
if (chip->dsp_spos_instance) { if (chip->dsp_spos_instance) {
cs46xx_dsp_spos_destroy(chip); cs46xx_dsp_spos_destroy(chip);
...@@ -2956,20 +2937,6 @@ static int snd_cs46xx_free(struct snd_cs46xx *chip) ...@@ -2956,20 +2937,6 @@ static int snd_cs46xx_free(struct snd_cs46xx *chip)
#else #else
vfree(chip->ba1); vfree(chip->ba1);
#endif #endif
#ifdef CONFIG_PM_SLEEP
kfree(chip->saved_regs);
#endif
pci_disable_device(chip->pci);
kfree(chip);
return 0;
}
static int snd_cs46xx_dev_free(struct snd_device *device)
{
struct snd_cs46xx *chip = device->device_data;
return snd_cs46xx_free(chip);
} }
/* /*
...@@ -3868,30 +3835,19 @@ SIMPLE_DEV_PM_OPS(snd_cs46xx_pm, snd_cs46xx_suspend, snd_cs46xx_resume); ...@@ -3868,30 +3835,19 @@ SIMPLE_DEV_PM_OPS(snd_cs46xx_pm, snd_cs46xx_suspend, snd_cs46xx_resume);
int snd_cs46xx_create(struct snd_card *card, int snd_cs46xx_create(struct snd_card *card,
struct pci_dev *pci, struct pci_dev *pci,
int external_amp, int thinkpad, int external_amp, int thinkpad)
struct snd_cs46xx **rchip)
{ {
struct snd_cs46xx *chip; struct snd_cs46xx *chip = card->private_data;
int err, idx; int err, idx;
struct snd_cs46xx_region *region; struct snd_cs46xx_region *region;
struct cs_card_type *cp; struct cs_card_type *cp;
u16 ss_card, ss_vendor; u16 ss_card, ss_vendor;
static const struct snd_device_ops ops = {
.dev_free = snd_cs46xx_dev_free,
};
*rchip = NULL;
/* enable PCI device */ /* enable PCI device */
err = pci_enable_device(pci); err = pcim_enable_device(pci);
if (err < 0) if (err < 0)
return err; return err;
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL) {
pci_disable_device(pci);
return -ENOMEM;
}
spin_lock_init(&chip->reg_lock); spin_lock_init(&chip->reg_lock);
#ifdef CONFIG_SND_CS46XX_NEW_DSP #ifdef CONFIG_SND_CS46XX_NEW_DSP
mutex_init(&chip->spos_mutex); mutex_init(&chip->spos_mutex);
...@@ -3899,6 +3855,10 @@ int snd_cs46xx_create(struct snd_card *card, ...@@ -3899,6 +3855,10 @@ int snd_cs46xx_create(struct snd_card *card,
chip->card = card; chip->card = card;
chip->pci = pci; chip->pci = pci;
chip->irq = -1; chip->irq = -1;
err = pci_request_regions(pci, "CS46xx");
if (err < 0)
return err;
chip->ba0_addr = pci_resource_start(pci, 0); chip->ba0_addr = pci_resource_start(pci, 0);
chip->ba1_addr = pci_resource_start(pci, 1); chip->ba1_addr = pci_resource_start(pci, 1);
if (chip->ba0_addr == 0 || chip->ba0_addr == (unsigned long)~0 || if (chip->ba0_addr == 0 || chip->ba0_addr == (unsigned long)~0 ||
...@@ -3906,7 +3866,6 @@ int snd_cs46xx_create(struct snd_card *card, ...@@ -3906,7 +3866,6 @@ int snd_cs46xx_create(struct snd_card *card,
dev_err(chip->card->dev, dev_err(chip->card->dev,
"wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n", "wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n",
chip->ba0_addr, chip->ba1_addr); chip->ba0_addr, chip->ba1_addr);
snd_cs46xx_free(chip);
return -ENOMEM; return -ENOMEM;
} }
...@@ -3978,67 +3937,45 @@ int snd_cs46xx_create(struct snd_card *card, ...@@ -3978,67 +3937,45 @@ int snd_cs46xx_create(struct snd_card *card,
for (idx = 0; idx < 5; idx++) { for (idx = 0; idx < 5; idx++) {
region = &chip->region.idx[idx]; region = &chip->region.idx[idx];
region->resource = request_mem_region(region->base, region->size, region->remap_addr = devm_ioremap(&pci->dev, region->base,
region->name); region->size);
if (!region->resource) {
dev_err(chip->card->dev,
"unable to request memory region 0x%lx-0x%lx\n",
region->base, region->base + region->size - 1);
snd_cs46xx_free(chip);
return -EBUSY;
}
region->remap_addr = ioremap(region->base, region->size);
if (region->remap_addr == NULL) { if (region->remap_addr == NULL) {
dev_err(chip->card->dev, dev_err(chip->card->dev,
"%s ioremap problem\n", region->name); "%s ioremap problem\n", region->name);
snd_cs46xx_free(chip);
return -ENOMEM; return -ENOMEM;
} }
} }
if (request_irq(pci->irq, snd_cs46xx_interrupt, IRQF_SHARED, if (devm_request_irq(&pci->dev, pci->irq, snd_cs46xx_interrupt,
KBUILD_MODNAME, chip)) { IRQF_SHARED, KBUILD_MODNAME, chip)) {
dev_err(chip->card->dev, "unable to grab IRQ %d\n", pci->irq); dev_err(chip->card->dev, "unable to grab IRQ %d\n", pci->irq);
snd_cs46xx_free(chip);
return -EBUSY; return -EBUSY;
} }
chip->irq = pci->irq; chip->irq = pci->irq;
card->sync_irq = chip->irq; card->sync_irq = chip->irq;
card->private_free = snd_cs46xx_free;
#ifdef CONFIG_SND_CS46XX_NEW_DSP #ifdef CONFIG_SND_CS46XX_NEW_DSP
chip->dsp_spos_instance = cs46xx_dsp_spos_create(chip); chip->dsp_spos_instance = cs46xx_dsp_spos_create(chip);
if (chip->dsp_spos_instance == NULL) { if (!chip->dsp_spos_instance)
snd_cs46xx_free(chip);
return -ENOMEM; return -ENOMEM;
}
#endif #endif
err = snd_cs46xx_chip_init(chip); err = snd_cs46xx_chip_init(chip);
if (err < 0) { if (err < 0)
snd_cs46xx_free(chip);
return err;
}
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
if (err < 0) {
snd_cs46xx_free(chip);
return err; return err;
}
snd_cs46xx_proc_init(card, chip); snd_cs46xx_proc_init(card, chip);
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
chip->saved_regs = kmalloc_array(ARRAY_SIZE(saved_regs), chip->saved_regs = devm_kmalloc_array(&pci->dev,
sizeof(*chip->saved_regs), ARRAY_SIZE(saved_regs),
GFP_KERNEL); sizeof(*chip->saved_regs),
if (!chip->saved_regs) { GFP_KERNEL);
snd_cs46xx_free(chip); if (!chip->saved_regs)
return -ENOMEM; return -ENOMEM;
}
#endif #endif
chip->active_ctrl(chip, -1); /* disable CLKRUN */ chip->active_ctrl(chip, -1); /* disable CLKRUN */
*rchip = chip;
return 0; return 0;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment