Commit 499ddc16 authored by Takashi Iwai's avatar Takashi Iwai

ALSA: sis7019: Allocate resources with device-managed APIs

This patch converts the resource management in PCI sis7019 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-24-tiwai@suse.deSigned-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent df06df7c
...@@ -1007,16 +1007,10 @@ static int sis_mixer_create(struct sis7019 *sis) ...@@ -1007,16 +1007,10 @@ static int sis_mixer_create(struct sis7019 *sis)
return rc; return rc;
} }
static void sis_free_suspend(struct sis7019 *sis) static void sis_chip_free(struct snd_card *card)
{ {
int i; struct sis7019 *sis = card->private_data;
for (i = 0; i < SIS_SUSPEND_PAGES; i++)
kfree(sis->suspend_state[i]);
}
static int sis_chip_free(struct sis7019 *sis)
{
/* Reset the chip, and disable all interrputs. /* Reset the chip, and disable all interrputs.
*/ */
outl(SIS_GCR_SOFTWARE_RESET, sis->ioport + SIS_GCR); outl(SIS_GCR_SOFTWARE_RESET, sis->ioport + SIS_GCR);
...@@ -1028,18 +1022,6 @@ static int sis_chip_free(struct sis7019 *sis) ...@@ -1028,18 +1022,6 @@ static int sis_chip_free(struct sis7019 *sis)
*/ */
if (sis->irq >= 0) if (sis->irq >= 0)
free_irq(sis->irq, sis); free_irq(sis->irq, sis);
iounmap(sis->ioaddr);
pci_release_regions(sis->pci);
pci_disable_device(sis->pci);
sis_free_suspend(sis);
return 0;
}
static int sis_dev_free(struct snd_device *dev)
{
struct sis7019 *sis = dev->device_data;
return sis_chip_free(sis);
} }
static int sis_chip_init(struct sis7019 *sis) static int sis_chip_init(struct sis7019 *sis)
...@@ -1265,7 +1247,8 @@ static int sis_alloc_suspend(struct sis7019 *sis) ...@@ -1265,7 +1247,8 @@ static int sis_alloc_suspend(struct sis7019 *sis)
* buffer. * buffer.
*/ */
for (i = 0; i < SIS_SUSPEND_PAGES; i++) { for (i = 0; i < SIS_SUSPEND_PAGES; i++) {
sis->suspend_state[i] = kmalloc(4096, GFP_KERNEL); sis->suspend_state[i] = devm_kmalloc(&sis->pci->dev, 4096,
GFP_KERNEL);
if (!sis->suspend_state[i]) if (!sis->suspend_state[i])
return -ENOMEM; return -ENOMEM;
} }
...@@ -1279,23 +1262,19 @@ static int sis_chip_create(struct snd_card *card, ...@@ -1279,23 +1262,19 @@ static int sis_chip_create(struct snd_card *card,
{ {
struct sis7019 *sis = card->private_data; struct sis7019 *sis = card->private_data;
struct voice *voice; struct voice *voice;
static const struct snd_device_ops ops = {
.dev_free = sis_dev_free,
};
int rc; int rc;
int i; int i;
rc = pci_enable_device(pci); rc = pcim_enable_device(pci);
if (rc) if (rc)
goto error_out; return rc;
rc = dma_set_mask(&pci->dev, DMA_BIT_MASK(30)); rc = dma_set_mask(&pci->dev, DMA_BIT_MASK(30));
if (rc < 0) { if (rc < 0) {
dev_err(&pci->dev, "architecture does not support 30-bit PCI busmaster DMA"); dev_err(&pci->dev, "architecture does not support 30-bit PCI busmaster DMA");
goto error_out_enabled; return -ENXIO;
} }
memset(sis, 0, sizeof(*sis));
mutex_init(&sis->ac97_mutex); mutex_init(&sis->ac97_mutex);
spin_lock_init(&sis->voice_lock); spin_lock_init(&sis->voice_lock);
sis->card = card; sis->card = card;
...@@ -1306,31 +1285,31 @@ static int sis_chip_create(struct snd_card *card, ...@@ -1306,31 +1285,31 @@ static int sis_chip_create(struct snd_card *card,
rc = pci_request_regions(pci, "SiS7019"); rc = pci_request_regions(pci, "SiS7019");
if (rc) { if (rc) {
dev_err(&pci->dev, "unable request regions\n"); dev_err(&pci->dev, "unable request regions\n");
goto error_out_enabled; return rc;
} }
rc = -EIO; sis->ioaddr = devm_ioremap(&pci->dev, pci_resource_start(pci, 1), 0x4000);
sis->ioaddr = ioremap(pci_resource_start(pci, 1), 0x4000);
if (!sis->ioaddr) { if (!sis->ioaddr) {
dev_err(&pci->dev, "unable to remap MMIO, aborting\n"); dev_err(&pci->dev, "unable to remap MMIO, aborting\n");
goto error_out_cleanup; return -EIO;
} }
rc = sis_alloc_suspend(sis); rc = sis_alloc_suspend(sis);
if (rc < 0) { if (rc < 0) {
dev_err(&pci->dev, "unable to allocate state storage\n"); dev_err(&pci->dev, "unable to allocate state storage\n");
goto error_out_cleanup; return rc;
} }
rc = sis_chip_init(sis); rc = sis_chip_init(sis);
if (rc) if (rc)
goto error_out_cleanup; return rc;
card->private_free = sis_chip_free;
rc = request_irq(pci->irq, sis_interrupt, IRQF_SHARED, KBUILD_MODNAME, rc = request_irq(pci->irq, sis_interrupt, IRQF_SHARED, KBUILD_MODNAME,
sis); sis);
if (rc) { if (rc) {
dev_err(&pci->dev, "unable to allocate irq %d\n", sis->irq); dev_err(&pci->dev, "unable to allocate irq %d\n", sis->irq);
goto error_out_cleanup; return rc;
} }
sis->irq = pci->irq; sis->irq = pci->irq;
...@@ -1349,20 +1328,7 @@ static int sis_chip_create(struct snd_card *card, ...@@ -1349,20 +1328,7 @@ static int sis_chip_create(struct snd_card *card,
voice->num = SIS_CAPTURE_CHAN_AC97_PCM_IN; voice->num = SIS_CAPTURE_CHAN_AC97_PCM_IN;
voice->ctrl_base = SIS_CAPTURE_DMA_ADDR(sis->ioaddr, voice->num); voice->ctrl_base = SIS_CAPTURE_DMA_ADDR(sis->ioaddr, voice->num);
rc = snd_device_new(card, SNDRV_DEV_LOWLEVEL, sis, &ops);
if (rc)
goto error_out_cleanup;
return 0; return 0;
error_out_cleanup:
sis_chip_free(sis);
error_out_enabled:
pci_disable_device(pci);
error_out:
return rc;
} }
static int snd_sis7019_probe(struct pci_dev *pci, static int snd_sis7019_probe(struct pci_dev *pci,
...@@ -1372,9 +1338,8 @@ static int snd_sis7019_probe(struct pci_dev *pci, ...@@ -1372,9 +1338,8 @@ static int snd_sis7019_probe(struct pci_dev *pci,
struct sis7019 *sis; struct sis7019 *sis;
int rc; int rc;
rc = -ENOENT;
if (!enable) if (!enable)
goto error_out; return -ENOENT;
/* The user can specify which codecs should be present so that we /* The user can specify which codecs should be present so that we
* can wait for them to show up if they are slow to recover from * can wait for them to show up if they are slow to recover from
...@@ -1390,23 +1355,23 @@ static int snd_sis7019_probe(struct pci_dev *pci, ...@@ -1390,23 +1355,23 @@ static int snd_sis7019_probe(struct pci_dev *pci,
rc = snd_card_new(&pci->dev, index, id, THIS_MODULE, rc = snd_card_new(&pci->dev, index, id, THIS_MODULE,
sizeof(*sis), &card); sizeof(*sis), &card);
if (rc < 0) if (rc < 0)
goto error_out; return rc;
strcpy(card->driver, "SiS7019"); strcpy(card->driver, "SiS7019");
strcpy(card->shortname, "SiS7019"); strcpy(card->shortname, "SiS7019");
rc = sis_chip_create(card, pci); rc = sis_chip_create(card, pci);
if (rc) if (rc)
goto card_error_out; return rc;
sis = card->private_data; sis = card->private_data;
rc = sis_mixer_create(sis); rc = sis_mixer_create(sis);
if (rc) if (rc)
goto card_error_out; return rc;
rc = sis_pcm_create(sis); rc = sis_pcm_create(sis);
if (rc) if (rc)
goto card_error_out; return rc;
snprintf(card->longname, sizeof(card->longname), snprintf(card->longname, sizeof(card->longname),
"%s Audio Accelerator with %s at 0x%lx, irq %d", "%s Audio Accelerator with %s at 0x%lx, irq %d",
...@@ -1415,28 +1380,16 @@ static int snd_sis7019_probe(struct pci_dev *pci, ...@@ -1415,28 +1380,16 @@ static int snd_sis7019_probe(struct pci_dev *pci,
rc = snd_card_register(card); rc = snd_card_register(card);
if (rc) if (rc)
goto card_error_out; return rc;
pci_set_drvdata(pci, card); pci_set_drvdata(pci, card);
return 0; return 0;
card_error_out:
snd_card_free(card);
error_out:
return rc;
}
static void snd_sis7019_remove(struct pci_dev *pci)
{
snd_card_free(pci_get_drvdata(pci));
} }
static struct pci_driver sis7019_driver = { static struct pci_driver sis7019_driver = {
.name = KBUILD_MODNAME, .name = KBUILD_MODNAME,
.id_table = snd_sis7019_ids, .id_table = snd_sis7019_ids,
.probe = snd_sis7019_probe, .probe = snd_sis7019_probe,
.remove = snd_sis7019_remove,
.driver = { .driver = {
.pm = SIS_PM_OPS, .pm = SIS_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