コード例 #1
0
ファイル: davinci-pcm.c プロジェクト: 454053205/linux
static int davinci_pcm_close(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct davinci_runtime_data *prtd = runtime->private_data;

	if (prtd->ram_channel >= 0)
		edma_stop(prtd->ram_channel);
	if (prtd->asp_channel >= 0)
		edma_stop(prtd->asp_channel);
	if (prtd->asp_link[0] >= 0)
		edma_unlink(prtd->asp_link[0]);
	if (prtd->asp_link[1] >= 0)
		edma_unlink(prtd->asp_link[1]);
	if (prtd->ram_link >= 0)
		edma_unlink(prtd->ram_link);

	if (prtd->asp_link[0] >= 0)
		edma_free_slot(prtd->asp_link[0]);
	if (prtd->asp_link[1] >= 0)
		edma_free_slot(prtd->asp_link[1]);
	if (prtd->asp_channel >= 0)
		edma_free_channel(prtd->asp_channel);
	if (prtd->ram_link >= 0)
		edma_free_slot(prtd->ram_link);
	if (prtd->ram_link2 >= 0)
		edma_free_slot(prtd->ram_link2);
	if (prtd->ram_channel >= 0)
		edma_free_channel(prtd->ram_channel);

	kfree(prtd);

	return 0;
}
コード例 #2
0
/* release_channel() must be called with the edma_mutex held */
static void release_channel(int chan)
{
    int localChan;
    int i;

    /*
     * The non-LSP_210 EDMA interface returns a "magic" value that represents
     * the controller number and channel number muxed together in one UInt32.
     * This module doesn't yet support a controller other than 0, however, this
     * function needs to accommodate being called with a controller > 0 since
     * it's called to release a channel on a controller > 0 when the
     * REQUESTDMA ioctl() receives a controller > 0 that it can't handle and
     * needs to clean up after itself.
     */
    /*
     * In order to not be dependent on the LSP #defines, we need to
     * translate our EDMA interface's #defines to the LSP ones.
     */
#if defined(LSP_210)

    localChan = chan;
    if (chan >= EDMA_QDMA0 && chan <= EDMA_QDMA7) {
        __D("  release_channel: translating QDMA channel %d to LSP namespace ...\n", chan);
        localChan = EDMA_QDMA_CHANNEL_0 + (chan - EDMA_QDMA0);
    }

    for (i = 0; i < channels[localChan].nParam; i++) {
        __D("  release_channel: freeing channel %d...\n", localChan + i);

        davinci_free_dma(localChan + i);
    }

    INIT_LIST_HEAD(&channels[localChan].users);
    channels[localChan].nParam = 0;
    channels[localChan].isParam = 0;

#else   /* defined(LSP_210) */

    localChan = EDMA_CHAN_SLOT(chan);
    if (localChan >= EDMA_QDMA0 && localChan <= EDMA_QDMA7) {
        __E("  release_channel: QDMA is not supported: chan %d\n", chan);
                
        return;
    }

    for (i = 0; i < channels[localChan].nParam; i++) {
        if (channels[localChan].isParam) {
            __D("  release_channel: calling edma_free_slot(%d)...\n",
                chan + i);

            edma_free_slot(chan + i);
        }
        else {
            __D("  release_channel: calling edma_free_channel(%d)...\n",
                chan + i);

            edma_clean_channel(chan + i);
            edma_free_channel(chan + i);
        }
    }

    if (EDMA_CTLR(chan) == 0) {
        INIT_LIST_HEAD(&channels[localChan].users);
        channels[localChan].nParam = 0;
        channels[localChan].isParam = 0;
    }

#endif  /* defined(LSP_210) */
}