static int snd_stm_pcm_player_hw_free(struct snd_pcm_substream *substream) { struct snd_stm_pcm_player *pcm_player = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; snd_stm_printd(1, "snd_stm_pcm_player_hw_free(substream=0x%p)\n", substream); BUG_ON(!pcm_player); BUG_ON(!snd_stm_magic_valid(pcm_player)); BUG_ON(!runtime); /* This callback may be called more than once... */ if (snd_stm_buffer_is_allocated(pcm_player->buffer)) { /* Let the FDMA stop */ dma_wait_for_completion(pcm_player->fdma_channel); /* Free buffer */ snd_stm_buffer_free(pcm_player->buffer); /* Free FDMA parameters & configuration */ dma_params_free(&pcm_player->fdma_params); dma_req_free(pcm_player->fdma_channel, pcm_player->fdma_request); } return 0; }
static void exit_fdma_nand(struct stm_nand_emi *data) { int i; if (data->dma_chan < 0) return; /* Release DMA channel */ free_dma(data->dma_chan); /* Free DMA paramters (if they have actually been allocated) */ for (i = 0; i < 2; i++) { if (data->dma_params[i].params_ops) dma_params_free(&data->dma_params[i]); } }
void ksnd_pcm_streaming_stop(ksnd_pcm_streaming_t handle) { // Raise the flag set_bit(FLAG_STOPPED, &handle->flags); // Clean ALSA notifications handle->capture_handle->substream->runtime->transfer_ack_end = NULL; // Break transfer (if any) dma_stop_channel(handle->fdma_channel); dma_wait_for_completion(handle->fdma_channel); // Free FDMA resources dma_params_free(&handle->fdma_params); free_dma(handle->fdma_channel); // Free description memory handle->magic = magic_bad; kfree(handle); }