void dma_txreclaim(dma_info_t *di, bool forceall) { void *p; DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, forceall ? "all" : "")); while ((p = dma_getnexttxp(di, forceall))) PKTFREE(di->drv, p, TRUE); }
irqreturn_t bcm947xx_i2s_isr(int irq, void *devid) { uint32 intstatus, intmask; uint32 intstatus_new = 0; uint32 int_errmask = I2S_INT_DESCERR | I2S_INT_DATAERR | I2S_INT_DESC_PROTO_ERR | I2S_INT_SPDIF_PAR_ERR; struct snd_pcm *pcm = devid; struct snd_soc_pcm_runtime *rtd = pcm->private_data; bcm947xx_i2s_info_t *snd_bcm = rtd->dai->cpu_dai->private_data; struct snd_pcm_substream *substream; struct bcm947xx_runtime_data *brtd; // DBG("%s enter\n", __FUNCTION__); intstatus = R_REG(snd_bcm->osh, &snd_bcm->regs->intstatus); if (BCM947XX_PCM_DEBUG_ON) { intmask = R_REG(snd_bcm->osh, &snd_bcm->regs->intmask); } else { (void)intmask; } // DBG("%s: intstatus 0x%x intmask 0x%x\n", __FUNCTION__, intstatus, intmask); /* Playback. */ substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; if ((brtd = bcm947xx_pcm_brtd_from_running_substream(substream))) { if (intstatus & I2S_INT_XMT_INT) { /* reclaim descriptors that have been TX'd */ spin_lock(&brtd->lock); dma_getnexttxp(snd_bcm->di[0], HNDDMA_RANGE_TRANSMITTED); spin_unlock(&brtd->lock); /* clear this bit by writing a "1" back, we've serviced this */ intstatus_new |= I2S_INT_XMT_INT; snd_pcm_period_elapsed(substream); spin_lock(&brtd->lock); snd_BUG_ON(0 == brtd->dma_loaded); brtd->dma_loaded--; spin_unlock(&brtd->lock); } if (intstatus & I2S_INT_XMTFIFO_UFLOW) { intstatus_new |= I2S_INT_XMTFIFO_UFLOW; bcm947xx_dma_abort(substream); } } /* Capture. */ substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; if ((brtd = bcm947xx_pcm_brtd_from_running_substream(substream))) { if (intstatus & I2S_INT_RCV_INT) { spin_lock(&brtd->lock); dma_getnextrxp(snd_bcm->di[0], false); spin_unlock(&brtd->lock); /* clear this bit by writing a "1" back, we've serviced this */ intstatus_new |= I2S_INT_RCV_INT; snd_pcm_period_elapsed(substream); spin_lock(&brtd->lock); snd_BUG_ON(0 == brtd->dma_loaded); brtd->dma_loaded--; spin_unlock(&brtd->lock); } if (intstatus & I2S_INT_RCVFIFO_OFLOW) { intstatus_new |= I2S_INT_RCVFIFO_OFLOW; bcm947xx_dma_abort(substream); } } /* Common.*/ if (intstatus & int_errmask) { DBG("\n\n%s: Turning off all interrupts due to error\n", __FUNCTION__); DBG("%s: intstatus 0x%x intmask 0x%x\n", __FUNCTION__, intstatus, intmask); /* something bad happened, turn off all interrupts */ W_REG(snd_bcm->osh, &snd_bcm->regs->intmask, 0); } /* Acknowledge interrupts. */ W_REG(snd_bcm->osh, &snd_bcm->regs->intstatus, intstatus_new); // DBG("%s exit\n", __FUNCTION__); return IRQ_RETVAL(intstatus); }