int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab) { struct snd_sg_buf *sgbuf = dmab->private_data; struct snd_dma_buffer tmpb; int i; if (! sgbuf) return -EINVAL; if (dmab->area) vunmap(dmab->area); dmab->area = NULL; tmpb.dev.type = SNDRV_DMA_TYPE_DEV; tmpb.dev.dev = sgbuf->dev; for (i = 0; i < sgbuf->pages; i++) { if (!(sgbuf->table[i].addr & ~PAGE_MASK)) continue; /* continuous pages */ tmpb.area = sgbuf->table[i].buf; tmpb.addr = sgbuf->table[i].addr & PAGE_MASK; tmpb.bytes = (sgbuf->table[i].addr & ~PAGE_MASK) << PAGE_SHIFT; snd_dma_free_pages(&tmpb); } kfree(sgbuf->table); kfree(sgbuf->page_table); kfree(sgbuf); dmab->private_data = NULL; return 0; }
/* * try to allocate as the large pages as possible. * stores the resultant memory size in *res_size. * * the minimum size is snd_minimum_buffer. it should be power of 2. */ static int preallocate_pcm_pages(snd_pcm_substream_t *substream, size_t size) { struct snd_dma_buffer *dmab = &substream->dma_buffer; int err; snd_assert(size > 0, return -EINVAL); /* already reserved? */ if (snd_dma_get_reserved_buf(dmab, substream->dma_buf_id) > 0) { if (dmab->bytes >= size) return 0; /* yes */ /* no, free the reserved block */ snd_dma_free_pages(dmab); dmab->bytes = 0; } do { if ((err = snd_dma_alloc_pages(dmab->dev.type, dmab->dev.dev, size, dmab)) < 0) { if (err != -ENOMEM) return err; /* fatal error */ } else return 0; size >>= 1; } while (size >= snd_minimum_buffer); dmab->bytes = 0; /* tell error */ return 0; }
/* * release the preallocated buffer if not yet done. */ static void snd_pcm_lib_preallocate_dma_free(struct snd_pcm_substream *substream) { if (substream->dma_buffer.area == NULL) return; snd_dma_free_pages(&substream->dma_buffer); substream->dma_buffer.area = NULL; }
int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab) { struct snd_sg_buf *sgbuf = dmab->private_data; struct snd_dma_buffer tmpb; int i; if (! sgbuf) return -EINVAL; tmpb.dev.type = SNDRV_DMA_TYPE_DEV; tmpb.dev.dev = sgbuf->dev; for (i = 0; i < sgbuf->pages; i++) { tmpb.area = sgbuf->table[i].buf; tmpb.addr = sgbuf->table[i].addr; tmpb.bytes = PAGE_SIZE; snd_dma_free_pages(&tmpb); } if (dmab->area) vunmap(dmab->area); dmab->area = NULL; kfree(sgbuf->table); kfree(sgbuf->page_table); kfree(sgbuf); dmab->private_data = NULL; return 0; }
/* * try to allocate as the large pages as possible. * stores the resultant memory size in *res_size. * * the minimum size is snd_minimum_buffer. it should be power of 2. */ static int preallocate_pcm_pages(struct snd_pcm_substream *substream, size_t size) { struct snd_dma_buffer *dmab = &substream->dma_buffer; size_t orig_size = size; int err; /* already reserved? */ if (snd_dma_get_reserved_buf(dmab, substream->dma_buf_id) > 0) { if (dmab->bytes >= size) return 0; /* yes */ /* no, free the reserved block */ snd_dma_free_pages(dmab); dmab->bytes = 0; } do { if ((err = snd_dma_alloc_pages(dmab->dev.type, dmab->dev.dev, size, dmab)) < 0) { if (err != -ENOMEM) return err; /* fatal error */ } else return 0; size >>= 1; } while (size >= snd_minimum_buffer); dmab->bytes = 0; /* tell error */ pr_warn("ALSA pcmC%dD%d%c,%d:%s: cannot preallocate for size %zu\n", substream->pcm->card->number, substream->pcm->device, substream->stream ? 'c' : 'p', substream->number, substream->pcm->name, orig_size); return 0; }
static void snd_bt87x_free_risc(bt87x_t *chip) { if (chip->dma_risc.area) { snd_dma_free_pages(&chip->dma_risc); chip->dma_risc.area = NULL; } }
/* * remove the ring buffer and release it if assigned */ static void atiixp_clear_dma_packets(atiixp_t *chip, atiixp_dma_t *dma, snd_pcm_substream_t *substream) { if (dma->desc_buf.area) { writel(0, chip->remap_addr + dma->ops->llp_offset); snd_dma_free_pages(&dma->desc_buf); dma->desc_buf.area = NULL; } }
static void cs5535audio_clear_dma_packets(struct cs5535audio *cs5535au, struct cs5535audio_dma *dma, struct snd_pcm_substream *substream) { snd_dma_free_pages(&dma->desc_buf); dma->desc_buf.area = NULL; dma->substream = NULL; }
int snd_p16v_free(struct snd_emu10k1 *chip) { // release the data if (chip->p16v_buffer.area) { snd_dma_free_pages(&chip->p16v_buffer); //snd_printk("period lables free: %p\n", &chip->p16v_buffer); } return 0; }
/* * release all the cards assigned to a manager instance */ static int snd_mixart_free(struct mixart_mgr *mgr) { unsigned int i; for (i = 0; i < mgr->num_cards; i++) { if (mgr->chip[i]) snd_card_free(mgr->chip[i]->card); } /* stop mailbox */ snd_mixart_exit_mailbox(mgr); /* release irq */ if (mgr->irq >= 0) free_irq(mgr->irq, mgr); /* reset board if some firmware was loaded */ if(mgr->dsp_loaded) { snd_mixart_reset_board(mgr); snd_printdd("reset miXart !\n"); } /* release the i/o ports */ for (i = 0; i < 2; i++) { if (mgr->mem[i].virt) iounmap(mgr->mem[i].virt); } pci_release_regions(mgr->pci); /* free flowarray */ if(mgr->flowinfo.area) { snd_dma_free_pages(&mgr->flowinfo); mgr->flowinfo.area = NULL; } /* free bufferarray */ if(mgr->bufferinfo.area) { snd_dma_free_pages(&mgr->bufferinfo); mgr->bufferinfo.area = NULL; } pci_disable_device(mgr->pci); kfree(mgr); return 0; }
/* * release the preallocated buffer if not yet done. */ static void snd_pcm_lib_preallocate_dma_free(struct snd_pcm_substream *substream) { if (substream->dma_buffer.area == NULL) return; if (substream->dma_buf_id) snd_dma_reserve_buf(&substream->dma_buffer, substream->dma_buf_id); else snd_dma_free_pages(&substream->dma_buffer); substream->dma_buffer.area = NULL; }
static int clean_via_table(struct viadev *dev, struct snd_pcm_substream *substream, struct pci_dev *pci) { if (dev->table.area) { snd_dma_free_pages(&dev->table); dev->table.area = NULL; } kfree(dev->idx_table); dev->idx_table = NULL; return 0; }
static int stm32_spdifrx_remove(struct platform_device *pdev) { struct stm32_spdifrx_data *spdifrx = platform_get_drvdata(pdev); if (spdifrx->ctrl_chan) dma_release_channel(spdifrx->ctrl_chan); if (spdifrx->dmab) snd_dma_free_pages(spdifrx->dmab); return 0; }
int snd_p16v_free(struct snd_emu10k1 *chip) { // release the data if (chip->p16v_buffer.area) { snd_dma_free_pages(&chip->p16v_buffer); /* dev_dbg(chip->card->dev, "period lables free: %p\n", &chip->p16v_buffer); */ } return 0; }
/** * snd_pcm_lib_free_pages - release the allocated DMA buffer. * @substream: the substream to release the DMA buffer * * Releases the DMA buffer allocated via snd_pcm_lib_malloc_pages(). * * Returns zero if successful, or a negative error code on failure. */ int snd_pcm_lib_free_pages(snd_pcm_substream_t *substream) { snd_pcm_runtime_t *runtime; snd_assert(substream != NULL, return -EINVAL); runtime = substream->runtime; snd_assert(runtime != NULL, return -EINVAL); if (runtime->dma_area == NULL) return 0; if (runtime->dma_buffer_p != &substream->dma_buffer) { /* it's a newly allocated buffer. release it now. */ snd_dma_free_pages(runtime->dma_buffer_p); kfree(runtime->dma_buffer_p); } snd_pcm_set_runtime_buffer(substream, NULL); return 0; }
/** * snd_pcm_lib_free_pages - release the allocated DMA buffer. * @substream: the substream to release the DMA buffer * * Releases the DMA buffer allocated via snd_pcm_lib_malloc_pages(). * * Return: Zero if successful, or a negative error code on failure. */ int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime; if (PCM_RUNTIME_CHECK(substream)) return -EINVAL; runtime = substream->runtime; if (runtime->dma_area == NULL) return 0; if (runtime->dma_buffer_p != &substream->dma_buffer) { /* it's a newly allocated buffer. release it now. */ snd_dma_free_pages(runtime->dma_buffer_p); kfree(runtime->dma_buffer_p); } snd_pcm_set_runtime_buffer(substream, NULL); return 0; }
static void lola_free(struct lola *chip) { 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); if (chip->bar[0].remap_addr) iounmap(chip->bar[0].remap_addr); if (chip->bar[1].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); }
/* * write callback for prealloc proc file * * accepts the preallocation size in kB. */ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { struct snd_pcm_substream *substream = entry->private_data; char line[64], str[64]; size_t size; struct snd_dma_buffer new_dmab; if (substream->runtime) { buffer->error = -EBUSY; return; } if (!snd_info_get_line(buffer, line, sizeof(line))) { snd_info_get_str(str, line, sizeof(str)); size = simple_strtoul(str, NULL, 10) * 1024; if ((size != 0 && size < 8192) || size > substream->dma_max) { buffer->error = -EINVAL; return; } if (substream->dma_buffer.bytes == size) return; memset(&new_dmab, 0, sizeof(new_dmab)); new_dmab.dev = substream->dma_buffer.dev; if (size > 0) { if (snd_dma_alloc_pages(substream->dma_buffer.dev.type, substream->dma_buffer.dev.dev, size, &new_dmab) < 0) { buffer->error = -ENOMEM; return; } substream->buffer_bytes_max = size; } else { substream->buffer_bytes_max = UINT_MAX; } if (substream->dma_buffer.area) snd_dma_free_pages(&substream->dma_buffer); substream->dma_buffer = new_dmab; } else { buffer->error = -EINVAL; } }
static void dma_free_pages(struct azx *chip, struct snd_dma_buffer *buf) { snd_dma_free_pages(buf); }
static void dma_free_pages(struct hdac_bus *bus, struct snd_dma_buffer *buf) { snd_dma_free_pages(buf); }
void lola_free_pcm(struct lola *chip) { snd_dma_free_pages(&chip->pcm[0].bdl); snd_dma_free_pages(&chip->pcm[1].bdl); }
static void snd_hammerfall_free_buffer(struct snd_dma_buffer *dmab, struct pci_dev *pci) { if (dmab->area) snd_dma_free_pages(dmab); }
static int stm32_spdifrx_probe(struct platform_device *pdev) { struct stm32_spdifrx_data *spdifrx; struct reset_control *rst; const struct snd_dmaengine_pcm_config *pcm_config = NULL; int ret; spdifrx = devm_kzalloc(&pdev->dev, sizeof(*spdifrx), GFP_KERNEL); if (!spdifrx) return -ENOMEM; spdifrx->pdev = pdev; init_completion(&spdifrx->cs_completion); spin_lock_init(&spdifrx->lock); platform_set_drvdata(pdev, spdifrx); ret = stm_spdifrx_parse_of(pdev, spdifrx); if (ret) return ret; spdifrx->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "kclk", spdifrx->base, spdifrx->regmap_conf); if (IS_ERR(spdifrx->regmap)) { dev_err(&pdev->dev, "Regmap init failed\n"); return PTR_ERR(spdifrx->regmap); } ret = devm_request_irq(&pdev->dev, spdifrx->irq, stm32_spdifrx_isr, 0, dev_name(&pdev->dev), spdifrx); if (ret) { dev_err(&pdev->dev, "IRQ request returned %d\n", ret); return ret; } rst = devm_reset_control_get(&pdev->dev, NULL); if (!IS_ERR(rst)) { reset_control_assert(rst); udelay(2); reset_control_deassert(rst); } ret = devm_snd_soc_register_component(&pdev->dev, &stm32_spdifrx_component, stm32_spdifrx_dai, ARRAY_SIZE(stm32_spdifrx_dai)); if (ret) return ret; ret = stm32_spdifrx_dma_ctrl_register(&pdev->dev, spdifrx); if (ret) goto error; pcm_config = &stm32_spdifrx_pcm_config; ret = devm_snd_dmaengine_pcm_register(&pdev->dev, pcm_config, 0); if (ret) { dev_err(&pdev->dev, "PCM DMA register returned %d\n", ret); goto error; } return 0; error: if (spdifrx->ctrl_chan) dma_release_channel(spdifrx->ctrl_chan); if (spdifrx->dmab) snd_dma_free_pages(spdifrx->dmab); return ret; }
/* * Release the DMA-able kernel memory ... */ static void free_dmabuf(struct snd_dma_buffer *buf) { if (buf && buf->area) snd_dma_free_pages(buf); }