Commit 098fe3d6 authored by Takashi Iwai's avatar Takashi Iwai

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.deSigned-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent b5cde369
......@@ -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);
}
/*
*/
......
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