ALSA: emu10k1x: Allocate resources with device-managed APIs

This patch converts the resource management in PCI emu10k1x 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-35-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Takashi Iwai 2021-07-15 09:58:56 +02:00
parent 79e8b218b3
commit 2b377c6b60

View file

@ -216,7 +216,6 @@ struct emu10k1x {
struct pci_dev *pci;
unsigned long port;
struct resource *res_port;
int irq;
unsigned char revision; /* chip revision */
@ -233,7 +232,7 @@ struct emu10k1x {
struct emu10k1x_voice capture_voice;
u32 spdif_bits[3]; // SPDIF out setup
struct snd_dma_buffer dma_buffer;
struct snd_dma_buffer *dma_buffer;
struct emu10k1x_midi midi;
};
@ -442,7 +441,7 @@ static int snd_emu10k1x_pcm_prepare(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
struct emu10k1x_pcm *epcm = runtime->private_data;
int voice = epcm->voice->number;
u32 *table_base = (u32 *)(emu->dma_buffer.area+1024*voice);
u32 *table_base = (u32 *)(emu->dma_buffer->area+1024*voice);
u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size);
int i;
@ -451,7 +450,7 @@ static int snd_emu10k1x_pcm_prepare(struct snd_pcm_substream *substream)
*table_base++=period_size_bytes<<16;
}
snd_emu10k1x_ptr_write(emu, PLAYBACK_LIST_ADDR, voice, emu->dma_buffer.addr+1024*voice);
snd_emu10k1x_ptr_write(emu, PLAYBACK_LIST_ADDR, voice, emu->dma_buffer->addr+1024*voice);
snd_emu10k1x_ptr_write(emu, PLAYBACK_LIST_SIZE, voice, (runtime->periods - 1) << 19);
snd_emu10k1x_ptr_write(emu, PLAYBACK_LIST_PTR, voice, 0);
snd_emu10k1x_ptr_write(emu, PLAYBACK_POINTER, voice, 0);
@ -737,37 +736,15 @@ static int snd_emu10k1x_ac97(struct emu10k1x *chip)
return snd_ac97_mixer(pbus, &ac97, &chip->ac97);
}
static int snd_emu10k1x_free(struct emu10k1x *chip)
static void snd_emu10k1x_free(struct snd_card *card)
{
struct emu10k1x *chip = card->private_data;
snd_emu10k1x_ptr_write(chip, TRIGGER_CHANNEL, 0, 0);
// disable interrupts
outl(0, chip->port + INTE);
// disable audio
outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG);
/* release the irq */
if (chip->irq >= 0)
free_irq(chip->irq, chip);
// release the i/o port
release_and_free_resource(chip->res_port);
// release the DMA
if (chip->dma_buffer.area) {
snd_dma_free_pages(&chip->dma_buffer);
}
pci_disable_device(chip->pci);
// release the data
kfree(chip);
return 0;
}
static int snd_emu10k1x_dev_free(struct snd_device *device)
{
struct emu10k1x *chip = device->device_data;
return snd_emu10k1x_free(chip);
}
static irqreturn_t snd_emu10k1x_interrupt(int irq, void *dev_id)
@ -885,34 +862,21 @@ static int snd_emu10k1x_pcm(struct emu10k1x *emu, int device)
}
static int snd_emu10k1x_create(struct snd_card *card,
struct pci_dev *pci,
struct emu10k1x **rchip)
struct pci_dev *pci)
{
struct emu10k1x *chip;
struct emu10k1x *chip = card->private_data;
int err;
int ch;
static const struct snd_device_ops ops = {
.dev_free = snd_emu10k1x_dev_free,
};
*rchip = NULL;
err = pci_enable_device(pci);
err = pcim_enable_device(pci);
if (err < 0)
return err;
if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(28)) < 0) {
dev_err(card->dev, "error to set 28bit mask DMA\n");
pci_disable_device(pci);
return -ENXIO;
}
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL) {
pci_disable_device(pci);
return -ENOMEM;
}
chip->card = card;
chip->pci = pci;
chip->irq = -1;
@ -920,29 +884,24 @@ static int snd_emu10k1x_create(struct snd_card *card,
spin_lock_init(&chip->emu_lock);
spin_lock_init(&chip->voice_lock);
err = pci_request_regions(pci, "EMU10K1X");
if (err < 0)
return err;
chip->port = pci_resource_start(pci, 0);
chip->res_port = request_region(chip->port, 8, "EMU10K1X");
if (!chip->res_port) {
dev_err(card->dev, "cannot allocate the port 0x%lx\n",
chip->port);
snd_emu10k1x_free(chip);
return -EBUSY;
}
if (request_irq(pci->irq, snd_emu10k1x_interrupt,
IRQF_SHARED, KBUILD_MODNAME, chip)) {
if (devm_request_irq(&pci->dev, pci->irq, snd_emu10k1x_interrupt,
IRQF_SHARED, KBUILD_MODNAME, chip)) {
dev_err(card->dev, "cannot grab irq %d\n", pci->irq);
snd_emu10k1x_free(chip);
return -EBUSY;
}
chip->irq = pci->irq;
card->sync_irq = chip->irq;
card->private_free = snd_emu10k1x_free;
if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
4 * 1024, &chip->dma_buffer) < 0) {
snd_emu10k1x_free(chip);
chip->dma_buffer = snd_devm_alloc_pages(&pci->dev, SNDRV_DMA_TYPE_DEV,
4 * 1024);
if (!chip->dma_buffer)
return -ENOMEM;
}
pci_set_master(pci);
/* read revision & serial */
@ -998,12 +957,6 @@ static int snd_emu10k1x_create(struct snd_card *card,
outl(HCFG_LOCKSOUNDCACHE|HCFG_AUDIOENABLE, chip->port+HCFG);
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
if (err < 0) {
snd_emu10k1x_free(chip);
return err;
}
*rchip = chip;
return 0;
}
@ -1553,50 +1506,37 @@ static int snd_emu10k1x_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_emu10k1x_create(card, pci);
if (err < 0)
return err;
err = snd_emu10k1x_create(card, pci, &chip);
if (err < 0) {
snd_card_free(card);
return err;
}
err = snd_emu10k1x_pcm(chip, 0);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
err = snd_emu10k1x_pcm(chip, 1);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
err = snd_emu10k1x_pcm(chip, 2);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
err = snd_emu10k1x_ac97(chip);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
err = snd_emu10k1x_mixer(chip);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
err = snd_emu10k1x_midi(chip);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
snd_emu10k1x_proc_init(chip);
@ -1606,21 +1546,14 @@ static int snd_emu10k1x_probe(struct pci_dev *pci,
card->shortname, chip->port, 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_emu10k1x_remove(struct pci_dev *pci)
{
snd_card_free(pci_get_drvdata(pci));
}
// PCI IDs
static const struct pci_device_id snd_emu10k1x_ids[] = {
{ PCI_VDEVICE(CREATIVE, 0x0006), 0 }, /* Dell OEM version (EMU10K1) */
@ -1633,7 +1566,6 @@ static struct pci_driver emu10k1x_driver = {
.name = KBUILD_MODNAME,
.id_table = snd_emu10k1x_ids,
.probe = snd_emu10k1x_probe,
.remove = snd_emu10k1x_remove,
};
module_pci_driver(emu10k1x_driver);