ALSA: lola: Allocate resources with device-managed APIs
This patch converts the resource management in PCI lola driver with devres as a clean up. Each manual resource management is converted with the corresponding devres helper, the page allocations are done with the 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-41-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
b5cde369b6
commit
098fe3d6e7
@ -344,20 +344,18 @@ static void lola_irq_disable(struct lola *chip)
|
||||
|
||||
static int setup_corb_rirb(struct lola *chip)
|
||||
{
|
||||
int err;
|
||||
unsigned char tmp;
|
||||
unsigned long end_time;
|
||||
|
||||
err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
|
||||
&chip->pci->dev,
|
||||
PAGE_SIZE, &chip->rb);
|
||||
if (err < 0)
|
||||
return err;
|
||||
chip->rb = snd_devm_alloc_pages(&chip->pci->dev, SNDRV_DMA_TYPE_DEV,
|
||||
PAGE_SIZE);
|
||||
if (!chip->rb)
|
||||
return -ENOMEM;
|
||||
|
||||
chip->corb.addr = chip->rb.addr;
|
||||
chip->corb.buf = (__le32 *)chip->rb.area;
|
||||
chip->rirb.addr = chip->rb.addr + 2048;
|
||||
chip->rirb.buf = (__le32 *)(chip->rb.area + 2048);
|
||||
chip->corb.addr = chip->rb->addr;
|
||||
chip->corb.buf = (__le32 *)chip->rb->area;
|
||||
chip->rirb.addr = chip->rb->addr + 2048;
|
||||
chip->rirb.buf = (__le32 *)(chip->rb->area + 2048);
|
||||
|
||||
/* disable ringbuffer DMAs */
|
||||
lola_writeb(chip, BAR0, RIRBCTL, 0);
|
||||
@ -529,56 +527,31 @@ static void lola_stop_hw(struct lola *chip)
|
||||
lola_irq_disable(chip);
|
||||
}
|
||||
|
||||
static void lola_free(struct lola *chip)
|
||||
static void lola_free(struct snd_card *card)
|
||||
{
|
||||
struct lola *chip = card->private_data;
|
||||
|
||||
if (chip->initialized)
|
||||
lola_stop_hw(chip);
|
||||
lola_free_pcm(chip);
|
||||
lola_free_mixer(chip);
|
||||
if (chip->irq >= 0)
|
||||
free_irq(chip->irq, (void *)chip);
|
||||
iounmap(chip->bar[0].remap_addr);
|
||||
iounmap(chip->bar[1].remap_addr);
|
||||
if (chip->rb.area)
|
||||
snd_dma_free_pages(&chip->rb);
|
||||
pci_release_regions(chip->pci);
|
||||
pci_disable_device(chip->pci);
|
||||
kfree(chip);
|
||||
}
|
||||
|
||||
static int lola_dev_free(struct snd_device *device)
|
||||
static int lola_create(struct snd_card *card, struct pci_dev *pci, int dev)
|
||||
{
|
||||
lola_free(device->device_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lola_create(struct snd_card *card, struct pci_dev *pci,
|
||||
int dev, struct lola **rchip)
|
||||
{
|
||||
struct lola *chip;
|
||||
struct lola *chip = card->private_data;
|
||||
int err;
|
||||
unsigned int dever;
|
||||
static const struct snd_device_ops ops = {
|
||||
.dev_free = lola_dev_free,
|
||||
};
|
||||
|
||||
*rchip = NULL;
|
||||
|
||||
err = pci_enable_device(pci);
|
||||
err = pcim_enable_device(pci);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
|
||||
if (!chip) {
|
||||
pci_disable_device(pci);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
spin_lock_init(&chip->reg_lock);
|
||||
mutex_init(&chip->open_mutex);
|
||||
chip->card = card;
|
||||
chip->pci = pci;
|
||||
chip->irq = -1;
|
||||
card->private_free = lola_free;
|
||||
|
||||
chip->granularity = granularity[dev];
|
||||
switch (chip->granularity) {
|
||||
@ -607,34 +580,25 @@ static int lola_create(struct snd_card *card, struct pci_dev *pci,
|
||||
chip->sample_rate_min = 16000;
|
||||
}
|
||||
|
||||
err = pci_request_regions(pci, DRVNAME);
|
||||
if (err < 0) {
|
||||
kfree(chip);
|
||||
pci_disable_device(pci);
|
||||
err = pcim_iomap_regions(pci, (1 << 0) | (1 << 2), DRVNAME);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
chip->bar[0].addr = pci_resource_start(pci, 0);
|
||||
chip->bar[0].remap_addr = pci_ioremap_bar(pci, 0);
|
||||
chip->bar[0].remap_addr = pcim_iomap_table(pci)[0];
|
||||
chip->bar[1].addr = pci_resource_start(pci, 2);
|
||||
chip->bar[1].remap_addr = pci_ioremap_bar(pci, 2);
|
||||
if (!chip->bar[0].remap_addr || !chip->bar[1].remap_addr) {
|
||||
dev_err(chip->card->dev, "ioremap error\n");
|
||||
err = -ENXIO;
|
||||
goto errout;
|
||||
}
|
||||
chip->bar[1].remap_addr = pcim_iomap_table(pci)[2];
|
||||
|
||||
pci_set_master(pci);
|
||||
|
||||
err = reset_controller(chip);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
return err;
|
||||
|
||||
if (request_irq(pci->irq, lola_interrupt, IRQF_SHARED,
|
||||
KBUILD_MODNAME, chip)) {
|
||||
if (devm_request_irq(&pci->dev, pci->irq, lola_interrupt, IRQF_SHARED,
|
||||
KBUILD_MODNAME, chip)) {
|
||||
dev_err(chip->card->dev, "unable to grab IRQ %d\n", pci->irq);
|
||||
err = -EBUSY;
|
||||
goto errout;
|
||||
return -EBUSY;
|
||||
}
|
||||
chip->irq = pci->irq;
|
||||
card->sync_irq = chip->irq;
|
||||
@ -653,19 +617,12 @@ static int lola_create(struct snd_card *card, struct pci_dev *pci,
|
||||
(!chip->pcm[CAPT].num_streams &&
|
||||
!chip->pcm[PLAY].num_streams)) {
|
||||
dev_err(chip->card->dev, "invalid DEVER = %x\n", dever);
|
||||
err = -EINVAL;
|
||||
goto errout;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = setup_corb_rirb(chip);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
|
||||
if (err < 0) {
|
||||
dev_err(chip->card->dev, "Error creating device [card]!\n");
|
||||
goto errout;
|
||||
}
|
||||
return err;
|
||||
|
||||
strcpy(card->driver, "Lola");
|
||||
strscpy(card->shortname, "Digigram Lola", sizeof(card->shortname));
|
||||
@ -677,12 +634,7 @@ static int lola_create(struct snd_card *card, struct pci_dev *pci,
|
||||
lola_irq_enable(chip);
|
||||
|
||||
chip->initialized = 1;
|
||||
*rchip = chip;
|
||||
return 0;
|
||||
|
||||
errout:
|
||||
lola_free(chip);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int lola_probe(struct pci_dev *pci,
|
||||
@ -700,47 +652,39 @@ static int lola_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) {
|
||||
dev_err(&pci->dev, "Error creating card!\n");
|
||||
return err;
|
||||
}
|
||||
chip = card->private_data;
|
||||
|
||||
err = lola_create(card, pci, dev, &chip);
|
||||
err = lola_create(card, pci, dev);
|
||||
if (err < 0)
|
||||
goto out_free;
|
||||
card->private_data = chip;
|
||||
return err;
|
||||
|
||||
err = lola_parse_tree(chip);
|
||||
if (err < 0)
|
||||
goto out_free;
|
||||
return err;
|
||||
|
||||
err = lola_create_pcm(chip);
|
||||
if (err < 0)
|
||||
goto out_free;
|
||||
return err;
|
||||
|
||||
err = lola_create_mixer(chip);
|
||||
if (err < 0)
|
||||
goto out_free;
|
||||
return err;
|
||||
|
||||
lola_proc_debug_new(chip);
|
||||
|
||||
err = snd_card_register(card);
|
||||
if (err < 0)
|
||||
goto out_free;
|
||||
return err;
|
||||
|
||||
pci_set_drvdata(pci, card);
|
||||
dev++;
|
||||
return err;
|
||||
out_free:
|
||||
snd_card_free(card);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void lola_remove(struct pci_dev *pci)
|
||||
{
|
||||
snd_card_free(pci_get_drvdata(pci));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* PCI IDs */
|
||||
@ -755,7 +699,6 @@ static struct pci_driver lola_driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = lola_ids,
|
||||
.probe = lola_probe,
|
||||
.remove = lola_remove,
|
||||
};
|
||||
|
||||
module_pci_driver(lola_driver);
|
||||
|
@ -303,7 +303,7 @@ struct lola_stream {
|
||||
|
||||
struct lola_pcm {
|
||||
unsigned int num_streams;
|
||||
struct snd_dma_buffer bdl; /* BDL buffer */
|
||||
struct snd_dma_buffer *bdl; /* BDL buffer */
|
||||
struct lola_stream streams[MAX_STREAM_COUNT];
|
||||
};
|
||||
|
||||
@ -328,7 +328,7 @@ struct lola {
|
||||
unsigned int last_cmd_nid, last_verb, last_data, last_extdata;
|
||||
|
||||
/* CORB/RIRB buffers */
|
||||
struct snd_dma_buffer rb;
|
||||
struct snd_dma_buffer *rb;
|
||||
|
||||
/* unsolicited events */
|
||||
unsigned int last_unsol_res;
|
||||
@ -480,7 +480,6 @@ int lola_codec_flush(struct lola *chip);
|
||||
|
||||
/* PCM */
|
||||
int lola_create_pcm(struct lola *chip);
|
||||
void lola_free_pcm(struct lola *chip);
|
||||
int lola_init_pcm(struct lola *chip, int dir, int *nidp);
|
||||
void lola_pcm_update(struct lola *chip, struct lola_pcm *pcm, unsigned int bits);
|
||||
|
||||
|
@ -348,7 +348,7 @@ static int lola_setup_periods(struct lola *chip, struct lola_pcm *pcm,
|
||||
periods = str->bufsize / period_bytes;
|
||||
|
||||
/* program the initial BDL entries */
|
||||
bdl = (__le32 *)(pcm->bdl.area + LOLA_BDL_ENTRY_SIZE * str->index);
|
||||
bdl = (__le32 *)(pcm->bdl->area + LOLA_BDL_ENTRY_SIZE * str->index);
|
||||
ofs = 0;
|
||||
str->frags = 0;
|
||||
for (i = 0; i < periods; i++) {
|
||||
@ -433,7 +433,7 @@ static int lola_setup_controller(struct lola *chip, struct lola_pcm *pcm,
|
||||
return -EINVAL;
|
||||
|
||||
/* set up BDL */
|
||||
bdl = pcm->bdl.addr + LOLA_BDL_ENTRY_SIZE * str->index;
|
||||
bdl = pcm->bdl->addr + LOLA_BDL_ENTRY_SIZE * str->index;
|
||||
lola_dsd_write(chip, str->dsd, BDPL, (u32)bdl);
|
||||
lola_dsd_write(chip, str->dsd, BDPU, upper_32_bits(bdl));
|
||||
/* program the stream LVI (last valid index) of the BDL */
|
||||
@ -588,11 +588,11 @@ int lola_create_pcm(struct lola *chip)
|
||||
int i, err;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
|
||||
&chip->pci->dev,
|
||||
PAGE_SIZE, &chip->pcm[i].bdl);
|
||||
if (err < 0)
|
||||
return err;
|
||||
chip->pcm[i].bdl =
|
||||
snd_devm_alloc_pages(&chip->pci->dev, SNDRV_DMA_TYPE_DEV,
|
||||
PAGE_SIZE);
|
||||
if (!chip->pcm[i].bdl)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
err = snd_pcm_new(chip->card, "Digigram Lola", 0,
|
||||
@ -614,12 +614,6 @@ int lola_create_pcm(struct lola *chip)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lola_free_pcm(struct lola *chip)
|
||||
{
|
||||
snd_dma_free_pages(&chip->pcm[0].bdl);
|
||||
snd_dma_free_pages(&chip->pcm[1].bdl);
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user