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,
return -ENOENT;
}
err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
0, &card);
err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
sizeof(*chip), &card);
if (err < 0)
return err;
chip = card->private_data;
err = snd_cs46xx_create(card, pci,
external_amp[dev], thinkpad[dev],
&chip);
if (err < 0) {
snd_card_free(card);
external_amp[dev], thinkpad[dev]);
if (err < 0)
return err;
}
card->private_data = chip;
chip->accept_valid = mmap_valid[dev];
err = snd_cs46xx_pcm(chip, 0);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
#ifdef CONFIG_SND_CS46XX_NEW_DSP
err = snd_cs46xx_pcm_rear(chip, 1);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
err = snd_cs46xx_pcm_iec958(chip, 2);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
#endif
err = snd_cs46xx_mixer(chip, 2);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
#ifdef CONFIG_SND_CS46XX_NEW_DSP
if (chip->nr_ac97_codecs ==2) {
err = snd_cs46xx_pcm_center_lfe(chip, 3);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
}
#endif
err = snd_cs46xx_midi(chip, 0);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
err = snd_cs46xx_start_dsp(chip);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
snd_cs46xx_gameport(chip);
......@@ -133,26 +116,18 @@ static int snd_card_cs46xx_probe(struct pci_dev *pci,
chip->irq);
err = snd_card_register(card);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
pci_set_drvdata(pci, card);
dev++;
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 = {
.name = KBUILD_MODNAME,
.id_table = snd_cs46xx_ids,
.probe = snd_card_cs46xx_probe,
.remove = snd_card_cs46xx_remove,
#ifdef CONFIG_PM_SLEEP
.driver = {
.pm = &snd_cs46xx_pm,
......
......@@ -1635,7 +1635,6 @@ struct snd_cs46xx_region {
unsigned long base;
void __iomem *remap_addr;
unsigned long size;
struct resource *resource;
};
struct snd_cs46xx {
......@@ -1718,8 +1717,7 @@ struct snd_cs46xx {
int snd_cs46xx_create(struct snd_card *card,
struct pci_dev *pci,
int external_amp, int thinkpad,
struct snd_cs46xx **rcodec);
int external_amp, int thinkpad);
extern const struct dev_pm_ops snd_cs46xx_pm;
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)
/*
* 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)
{
struct snd_cs46xx *chip = ac97->private_data;
......@@ -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);
if (err < 0)
return err;
chip->ac97_bus->private_free = snd_cs46xx_mixer_free_ac97_bus;
if (cs46xx_detect_codec(chip, CS46XX_PRIMARY_CODEC_INDEX) < 0)
return -ENXIO;
......@@ -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;
if (snd_BUG_ON(!chip))
return -EINVAL;
#endif
if (chip->active_ctrl)
chip->active_ctrl(chip, 1);
......@@ -2930,22 +2922,11 @@ static int snd_cs46xx_free(struct snd_cs46xx *chip)
snd_cs46xx_proc_done(chip);
if (chip->region.idx[0].resource)
snd_cs46xx_hw_stop(chip);
if (chip->irq >= 0)
free_irq(chip->irq, chip);
if (chip->active_ctrl)
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
if (chip->dsp_spos_instance) {
cs46xx_dsp_spos_destroy(chip);
......@@ -2956,20 +2937,6 @@ static int snd_cs46xx_free(struct snd_cs46xx *chip)
#else
vfree(chip->ba1);
#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);
int snd_cs46xx_create(struct snd_card *card,
struct pci_dev *pci,
int external_amp, int thinkpad,
struct snd_cs46xx **rchip)
int external_amp, int thinkpad)
{
struct snd_cs46xx *chip;
struct snd_cs46xx *chip = card->private_data;
int err, idx;
struct snd_cs46xx_region *region;
struct cs_card_type *cp;
u16 ss_card, ss_vendor;
static const struct snd_device_ops ops = {
.dev_free = snd_cs46xx_dev_free,
};
*rchip = NULL;
/* enable PCI device */
err = pci_enable_device(pci);
err = pcim_enable_device(pci);
if (err < 0)
return err;
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL) {
pci_disable_device(pci);
return -ENOMEM;
}
spin_lock_init(&chip->reg_lock);
#ifdef CONFIG_SND_CS46XX_NEW_DSP
mutex_init(&chip->spos_mutex);
......@@ -3899,6 +3855,10 @@ int snd_cs46xx_create(struct snd_card *card,
chip->card = card;
chip->pci = pci;
chip->irq = -1;
err = pci_request_regions(pci, "CS46xx");
if (err < 0)
return err;
chip->ba0_addr = pci_resource_start(pci, 0);
chip->ba1_addr = pci_resource_start(pci, 1);
if (chip->ba0_addr == 0 || chip->ba0_addr == (unsigned long)~0 ||
......@@ -3906,7 +3866,6 @@ int snd_cs46xx_create(struct snd_card *card,
dev_err(chip->card->dev,
"wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n",
chip->ba0_addr, chip->ba1_addr);
snd_cs46xx_free(chip);
return -ENOMEM;
}
......@@ -3978,67 +3937,45 @@ int snd_cs46xx_create(struct snd_card *card,
for (idx = 0; idx < 5; idx++) {
region = &chip->region.idx[idx];
region->resource = request_mem_region(region->base, region->size,
region->name);
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);
region->remap_addr = devm_ioremap(&pci->dev, region->base,
region->size);
if (region->remap_addr == NULL) {
dev_err(chip->card->dev,
"%s ioremap problem\n", region->name);
snd_cs46xx_free(chip);
return -ENOMEM;
}
}
if (request_irq(pci->irq, snd_cs46xx_interrupt, IRQF_SHARED,
KBUILD_MODNAME, chip)) {
if (devm_request_irq(&pci->dev, pci->irq, snd_cs46xx_interrupt,
IRQF_SHARED, KBUILD_MODNAME, chip)) {
dev_err(chip->card->dev, "unable to grab IRQ %d\n", pci->irq);
snd_cs46xx_free(chip);
return -EBUSY;
}
chip->irq = pci->irq;
card->sync_irq = chip->irq;
card->private_free = snd_cs46xx_free;
#ifdef CONFIG_SND_CS46XX_NEW_DSP
chip->dsp_spos_instance = cs46xx_dsp_spos_create(chip);
if (chip->dsp_spos_instance == NULL) {
snd_cs46xx_free(chip);
if (!chip->dsp_spos_instance)
return -ENOMEM;
}
#endif
err = snd_cs46xx_chip_init(chip);
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);
if (err < 0)
return err;
}
snd_cs46xx_proc_init(card, chip);
#ifdef CONFIG_PM_SLEEP
chip->saved_regs = kmalloc_array(ARRAY_SIZE(saved_regs),
chip->saved_regs = devm_kmalloc_array(&pci->dev,
ARRAY_SIZE(saved_regs),
sizeof(*chip->saved_regs),
GFP_KERNEL);
if (!chip->saved_regs) {
snd_cs46xx_free(chip);
if (!chip->saved_regs)
return -ENOMEM;
}
#endif
chip->active_ctrl(chip, -1); /* disable CLKRUN */
*rchip = chip;
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