Commit 10ed6eaf authored by Takashi Iwai's avatar Takashi Iwai

ALSA: ens137x: Allocate resources with device-managed APIs

This patch converts the resource management in PCI esn137x drivers
with devres as a clean up.  Each manual resource management is
converted with the corresponding devres helper, the devres helper is
used for the DMA buffer page allocations, 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-17-tiwai@suse.deSigned-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 2e11e3ff
...@@ -414,7 +414,7 @@ struct ensoniq { ...@@ -414,7 +414,7 @@ struct ensoniq {
unsigned int spdif_stream; unsigned int spdif_stream;
#ifdef CHIP1370 #ifdef CHIP1370
struct snd_dma_buffer dma_bug; struct snd_dma_buffer *dma_bug;
#endif #endif
#ifdef SUPPORT_JOYSTICK #ifdef SUPPORT_JOYSTICK
...@@ -1872,11 +1872,11 @@ static void snd_ensoniq_proc_init(struct ensoniq *ensoniq) ...@@ -1872,11 +1872,11 @@ static void snd_ensoniq_proc_init(struct ensoniq *ensoniq)
*/ */
static int snd_ensoniq_free(struct ensoniq *ensoniq) static void snd_ensoniq_free(struct snd_card *card)
{ {
struct ensoniq *ensoniq = card->private_data;
snd_ensoniq_free_gameport(ensoniq); snd_ensoniq_free_gameport(ensoniq);
if (ensoniq->irq < 0)
goto __hw_end;
#ifdef CHIP1370 #ifdef CHIP1370
outl(ES_1370_SERR_DISABLE, ES_REG(ensoniq, CONTROL)); /* switch everything off */ outl(ES_1370_SERR_DISABLE, ES_REG(ensoniq, CONTROL)); /* switch everything off */
outl(0, ES_REG(ensoniq, SERIAL)); /* clear serial interface */ outl(0, ES_REG(ensoniq, SERIAL)); /* clear serial interface */
...@@ -1884,24 +1884,6 @@ static int snd_ensoniq_free(struct ensoniq *ensoniq) ...@@ -1884,24 +1884,6 @@ static int snd_ensoniq_free(struct ensoniq *ensoniq)
outl(0, ES_REG(ensoniq, CONTROL)); /* switch everything off */ outl(0, ES_REG(ensoniq, CONTROL)); /* switch everything off */
outl(0, ES_REG(ensoniq, SERIAL)); /* clear serial interface */ outl(0, ES_REG(ensoniq, SERIAL)); /* clear serial interface */
#endif #endif
pci_set_power_state(ensoniq->pci, PCI_D3hot);
__hw_end:
#ifdef CHIP1370
if (ensoniq->dma_bug.area)
snd_dma_free_pages(&ensoniq->dma_bug);
#endif
if (ensoniq->irq >= 0)
free_irq(ensoniq->irq, ensoniq);
pci_release_regions(ensoniq->pci);
pci_disable_device(ensoniq->pci);
kfree(ensoniq);
return 0;
}
static int snd_ensoniq_dev_free(struct snd_device *device)
{
struct ensoniq *ensoniq = device->device_data;
return snd_ensoniq_free(ensoniq);
} }
#ifdef CHIP1371 #ifdef CHIP1371
...@@ -1935,7 +1917,7 @@ static void snd_ensoniq_chip_init(struct ensoniq *ensoniq) ...@@ -1935,7 +1917,7 @@ static void snd_ensoniq_chip_init(struct ensoniq *ensoniq)
outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE)); outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE));
outl(ensoniq->dma_bug.addr, ES_REG(ensoniq, PHANTOM_FRAME)); outl(ensoniq->dma_bug->addr, ES_REG(ensoniq, PHANTOM_FRAME));
outl(0, ES_REG(ensoniq, PHANTOM_COUNT)); outl(0, ES_REG(ensoniq, PHANTOM_COUNT));
#else #else
outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
...@@ -2032,51 +2014,35 @@ static SIMPLE_DEV_PM_OPS(snd_ensoniq_pm, snd_ensoniq_suspend, snd_ensoniq_resume ...@@ -2032,51 +2014,35 @@ static SIMPLE_DEV_PM_OPS(snd_ensoniq_pm, snd_ensoniq_suspend, snd_ensoniq_resume
#endif /* CONFIG_PM_SLEEP */ #endif /* CONFIG_PM_SLEEP */
static int snd_ensoniq_create(struct snd_card *card, static int snd_ensoniq_create(struct snd_card *card,
struct pci_dev *pci, struct pci_dev *pci)
struct ensoniq **rensoniq)
{ {
struct ensoniq *ensoniq; struct ensoniq *ensoniq = card->private_data;
int err; int err;
static const struct snd_device_ops ops = {
.dev_free = snd_ensoniq_dev_free,
};
*rensoniq = NULL; err = pcim_enable_device(pci);
err = pci_enable_device(pci);
if (err < 0) if (err < 0)
return err; return err;
ensoniq = kzalloc(sizeof(*ensoniq), GFP_KERNEL);
if (ensoniq == NULL) {
pci_disable_device(pci);
return -ENOMEM;
}
spin_lock_init(&ensoniq->reg_lock); spin_lock_init(&ensoniq->reg_lock);
mutex_init(&ensoniq->src_mutex); mutex_init(&ensoniq->src_mutex);
ensoniq->card = card; ensoniq->card = card;
ensoniq->pci = pci; ensoniq->pci = pci;
ensoniq->irq = -1; ensoniq->irq = -1;
err = pci_request_regions(pci, "Ensoniq AudioPCI"); err = pci_request_regions(pci, "Ensoniq AudioPCI");
if (err < 0) { if (err < 0)
kfree(ensoniq);
pci_disable_device(pci);
return err; return err;
}
ensoniq->port = pci_resource_start(pci, 0); ensoniq->port = pci_resource_start(pci, 0);
if (request_irq(pci->irq, snd_audiopci_interrupt, IRQF_SHARED, if (devm_request_irq(&pci->dev, pci->irq, snd_audiopci_interrupt,
KBUILD_MODNAME, ensoniq)) { IRQF_SHARED, KBUILD_MODNAME, ensoniq)) {
dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq); dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq);
snd_ensoniq_free(ensoniq);
return -EBUSY; return -EBUSY;
} }
ensoniq->irq = pci->irq; ensoniq->irq = pci->irq;
card->sync_irq = ensoniq->irq; card->sync_irq = ensoniq->irq;
#ifdef CHIP1370 #ifdef CHIP1370
if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev, ensoniq->dma_bug =
16, &ensoniq->dma_bug) < 0) { snd_devm_alloc_pages(&pci->dev, SNDRV_DMA_TYPE_DEV, 16);
dev_err(card->dev, "unable to allocate space for phantom area - dma_bug\n"); if (!ensoniq->dma_bug)
snd_ensoniq_free(ensoniq); return -ENOMEM;
return -EBUSY;
}
#endif #endif
pci_set_master(pci); pci_set_master(pci);
ensoniq->rev = pci->revision; ensoniq->rev = pci->revision;
...@@ -2099,17 +2065,10 @@ static int snd_ensoniq_create(struct snd_card *card, ...@@ -2099,17 +2065,10 @@ static int snd_ensoniq_create(struct snd_card *card,
ensoniq->cssr |= ES_1371_ST_AC97_RST; ensoniq->cssr |= ES_1371_ST_AC97_RST;
#endif #endif
card->private_free = snd_ensoniq_free;
snd_ensoniq_chip_init(ensoniq); snd_ensoniq_chip_init(ensoniq);
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ensoniq, &ops);
if (err < 0) {
snd_ensoniq_free(ensoniq);
return err;
}
snd_ensoniq_proc_init(ensoniq); snd_ensoniq_proc_init(ensoniq);
*rensoniq = ensoniq;
return 0; return 0;
} }
...@@ -2360,47 +2319,35 @@ static int snd_audiopci_probe(struct pci_dev *pci, ...@@ -2360,47 +2319,35 @@ static int snd_audiopci_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(*ensoniq), &card);
if (err < 0) if (err < 0)
return err; return err;
ensoniq = card->private_data;
err = snd_ensoniq_create(card, pci, &ensoniq); err = snd_ensoniq_create(card, pci);
if (err < 0) { if (err < 0)
snd_card_free(card);
return err; return err;
}
card->private_data = ensoniq;
#ifdef CHIP1370 #ifdef CHIP1370
err = snd_ensoniq_1370_mixer(ensoniq); err = snd_ensoniq_1370_mixer(ensoniq);
if (err < 0) { if (err < 0)
snd_card_free(card);
return err; return err;
}
#endif #endif
#ifdef CHIP1371 #ifdef CHIP1371
err = snd_ensoniq_1371_mixer(ensoniq, spdif[dev], lineio[dev]); err = snd_ensoniq_1371_mixer(ensoniq, spdif[dev], lineio[dev]);
if (err < 0) { if (err < 0)
snd_card_free(card);
return err; return err;
}
#endif #endif
err = snd_ensoniq_pcm(ensoniq, 0); err = snd_ensoniq_pcm(ensoniq, 0);
if (err < 0) { if (err < 0)
snd_card_free(card);
return err; return err;
}
err = snd_ensoniq_pcm2(ensoniq, 1); err = snd_ensoniq_pcm2(ensoniq, 1);
if (err < 0) { if (err < 0)
snd_card_free(card);
return err; return err;
}
err = snd_ensoniq_midi(ensoniq, 0); err = snd_ensoniq_midi(ensoniq, 0);
if (err < 0) { if (err < 0)
snd_card_free(card);
return err; return err;
}
snd_ensoniq_create_gameport(ensoniq, dev); snd_ensoniq_create_gameport(ensoniq, dev);
...@@ -2414,26 +2361,18 @@ static int snd_audiopci_probe(struct pci_dev *pci, ...@@ -2414,26 +2361,18 @@ static int snd_audiopci_probe(struct pci_dev *pci,
ensoniq->irq); ensoniq->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_audiopci_remove(struct pci_dev *pci)
{
snd_card_free(pci_get_drvdata(pci));
}
static struct pci_driver ens137x_driver = { static struct pci_driver ens137x_driver = {
.name = KBUILD_MODNAME, .name = KBUILD_MODNAME,
.id_table = snd_audiopci_ids, .id_table = snd_audiopci_ids,
.probe = snd_audiopci_probe, .probe = snd_audiopci_probe,
.remove = snd_audiopci_remove,
.driver = { .driver = {
.pm = SND_ENSONIQ_PM_OPS, .pm = SND_ENSONIQ_PM_OPS,
}, },
......
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