ALSA: hdsp: Allocate resources with device-managed APIs

This patch converts the resource management in PCI hdsp 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-46-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Takashi Iwai 2021-07-15 09:59:07 +02:00
Родитель 546c201a89
Коммит d136b8e54f
1 изменённых файлов: 25 добавлений и 64 удалений

Просмотреть файл

@ -468,8 +468,8 @@ struct hdsp {
unsigned char ss_out_channels;
u32 io_loopback; /* output loopback channel states*/
struct snd_dma_buffer capture_dma_buf;
struct snd_dma_buffer playback_dma_buf;
struct snd_dma_buffer *capture_dma_buf;
struct snd_dma_buffer *playback_dma_buf;
unsigned char *capture_buffer; /* suitably aligned address */
unsigned char *playback_buffer; /* suitably aligned address */
@ -565,18 +565,12 @@ static const char channel_map_H9632_qs[HDSP_MAX_CHANNELS] = {
-1, -1
};
static int snd_hammerfall_get_buffer(struct pci_dev *pci, struct snd_dma_buffer *dmab, size_t size)
static struct snd_dma_buffer *
snd_hammerfall_get_buffer(struct pci_dev *pci, size_t size)
{
return snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev, size, dmab);
return snd_devm_alloc_pages(&pci->dev, SNDRV_DMA_TYPE_DEV, size);
}
static void snd_hammerfall_free_buffer(struct snd_dma_buffer *dmab, struct pci_dev *pci)
{
if (dmab->area)
snd_dma_free_pages(dmab);
}
static const struct pci_device_id snd_hdsp_ids[] = {
{
.vendor = PCI_VENDOR_ID_XILINX,
@ -3768,20 +3762,15 @@ static void snd_hdsp_proc_init(struct hdsp *hdsp)
snd_card_ro_proc_new(hdsp->card, "hdsp", hdsp, snd_hdsp_proc_read);
}
static void snd_hdsp_free_buffers(struct hdsp *hdsp)
{
snd_hammerfall_free_buffer(&hdsp->capture_dma_buf, hdsp->pci);
snd_hammerfall_free_buffer(&hdsp->playback_dma_buf, hdsp->pci);
}
static int snd_hdsp_initialize_memory(struct hdsp *hdsp)
{
unsigned long pb_bus, cb_bus;
if (snd_hammerfall_get_buffer(hdsp->pci, &hdsp->capture_dma_buf, HDSP_DMA_AREA_BYTES) < 0 ||
snd_hammerfall_get_buffer(hdsp->pci, &hdsp->playback_dma_buf, HDSP_DMA_AREA_BYTES) < 0) {
if (hdsp->capture_dma_buf.area)
snd_dma_free_pages(&hdsp->capture_dma_buf);
hdsp->capture_dma_buf =
snd_hammerfall_get_buffer(hdsp->pci, HDSP_DMA_AREA_BYTES);
hdsp->playback_dma_buf =
snd_hammerfall_get_buffer(hdsp->pci, HDSP_DMA_AREA_BYTES);
if (!hdsp->capture_dma_buf || !hdsp->playback_dma_buf) {
dev_err(hdsp->card->dev,
"%s: no buffers available\n", hdsp->card_name);
return -ENOMEM;
@ -3789,16 +3778,16 @@ static int snd_hdsp_initialize_memory(struct hdsp *hdsp)
/* Align to bus-space 64K boundary */
cb_bus = ALIGN(hdsp->capture_dma_buf.addr, 0x10000ul);
pb_bus = ALIGN(hdsp->playback_dma_buf.addr, 0x10000ul);
cb_bus = ALIGN(hdsp->capture_dma_buf->addr, 0x10000ul);
pb_bus = ALIGN(hdsp->playback_dma_buf->addr, 0x10000ul);
/* Tell the card where it is */
hdsp_write(hdsp, HDSP_inputBufferAddress, cb_bus);
hdsp_write(hdsp, HDSP_outputBufferAddress, pb_bus);
hdsp->capture_buffer = hdsp->capture_dma_buf.area + (cb_bus - hdsp->capture_dma_buf.addr);
hdsp->playback_buffer = hdsp->playback_dma_buf.area + (pb_bus - hdsp->playback_dma_buf.addr);
hdsp->capture_buffer = hdsp->capture_dma_buf->area + (cb_bus - hdsp->capture_dma_buf->addr);
hdsp->playback_buffer = hdsp->playback_dma_buf->area + (pb_bus - hdsp->playback_dma_buf->addr);
return 0;
}
@ -5313,7 +5302,7 @@ static int snd_hdsp_create(struct snd_card *card,
is_9632 = 1;
}
err = pci_enable_device(pci);
err = pcim_enable_device(pci);
if (err < 0)
return err;
@ -5323,15 +5312,15 @@ static int snd_hdsp_create(struct snd_card *card,
if (err < 0)
return err;
hdsp->port = pci_resource_start(pci, 0);
hdsp->iobase = ioremap(hdsp->port, HDSP_IO_EXTENT);
hdsp->iobase = devm_ioremap(&pci->dev, hdsp->port, HDSP_IO_EXTENT);
if (!hdsp->iobase) {
dev_err(hdsp->card->dev, "unable to remap region 0x%lx-0x%lx\n",
hdsp->port, hdsp->port + HDSP_IO_EXTENT - 1);
return -EBUSY;
}
if (request_irq(pci->irq, snd_hdsp_interrupt, IRQF_SHARED,
KBUILD_MODNAME, hdsp)) {
if (devm_request_irq(&pci->dev, pci->irq, snd_hdsp_interrupt,
IRQF_SHARED, KBUILD_MODNAME, hdsp)) {
dev_err(hdsp->card->dev, "unable to use IRQ %d\n", pci->irq);
return -EBUSY;
}
@ -5411,8 +5400,10 @@ static int snd_hdsp_create(struct snd_card *card,
return 0;
}
static int snd_hdsp_free(struct hdsp *hdsp)
static void snd_hdsp_card_free(struct snd_card *card)
{
struct hdsp *hdsp = card->private_data;
if (hdsp->port) {
/* stop the audio, and cancel all interrupts */
cancel_work_sync(&hdsp->midi_work);
@ -5420,29 +5411,8 @@ static int snd_hdsp_free(struct hdsp *hdsp)
hdsp_write (hdsp, HDSP_controlRegister, hdsp->control_register);
}
if (hdsp->irq >= 0)
free_irq(hdsp->irq, (void *)hdsp);
snd_hdsp_free_buffers(hdsp);
release_firmware(hdsp->firmware);
vfree(hdsp->fw_uploaded);
iounmap(hdsp->iobase);
if (hdsp->port)
pci_release_regions(hdsp->pci);
if (pci_is_enabled(hdsp->pci))
pci_disable_device(hdsp->pci);
return 0;
}
static void snd_hdsp_card_free(struct snd_card *card)
{
struct hdsp *hdsp = card->private_data;
if (hdsp)
snd_hdsp_free(hdsp);
}
static int snd_hdsp_probe(struct pci_dev *pci,
@ -5460,8 +5430,8 @@ static int snd_hdsp_probe(struct pci_dev *pci,
return -ENOENT;
}
err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
sizeof(struct hdsp), &card);
err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
sizeof(struct hdsp), &card);
if (err < 0)
return err;
@ -5471,32 +5441,23 @@ static int snd_hdsp_probe(struct pci_dev *pci,
hdsp->pci = pci;
err = snd_hdsp_create(card, hdsp);
if (err)
goto free_card;
return err;
strcpy(card->shortname, "Hammerfall DSP");
sprintf(card->longname, "%s at 0x%lx, irq %d", hdsp->card_name,
hdsp->port, hdsp->irq);
err = snd_card_register(card);
if (err) {
free_card:
snd_card_free(card);
if (err)
return err;
}
pci_set_drvdata(pci, card);
dev++;
return 0;
}
static void snd_hdsp_remove(struct pci_dev *pci)
{
snd_card_free(pci_get_drvdata(pci));
}
static struct pci_driver hdsp_driver = {
.name = KBUILD_MODNAME,
.id_table = snd_hdsp_ids,
.probe = snd_hdsp_probe,
.remove = snd_hdsp_remove,
};
module_pci_driver(hdsp_driver);