stream);
	}

	return IRQ_HANDLED;
}

/*
 * Startup.  Only that one substream allowed in each direction.
 */
static int at91_ssc_startup(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
	int dir_mask;

	DBG("ssc_startup: SSC_SR=0x%08lx\n",
			at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR));
	dir_mask = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0x1 : 0x2;

	spin_lock_irq(&ssc_p->lock);
	if (ssc_p->dir_mask & dir_mask) {
		spin_unlock_irq(&ssc_p->lock);
		return -EBUSY;
	}
	ssc_p->dir_mask |= dir_mask;
	spin_unlock_irq(&ssc_p->lock);

	return 0;
}

/*
 * Shutdown.  Clear DMA parameters and shutdown the SSC if there
 * are no other substreams open.
 */
static void at91_ssc_shutdown(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
	struct at91_pcm_dma_params *dma_params;
	int dir, dir_mask;

	dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
	dma_params = ssc_p->dma_params[dir];

	if (dma_params != NULL) {
		at91_ssc_write(dma_params->ssc_base + AT91_SSC_CR,
				dma_params->mask->ssc_disable);
		DBG("%s disabled SSC_SR=0x%08lx\n", (dir ? "receive" : "transmit"),
			at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR));

		dma_params->ssc_base = NULL;
		dma_params->substream = NULL;
		ssc_p->dma_params[dir] = NULL;
	}

	dir_mask = 1 << dir;

	spin_lock_irq(&ssc_p->lock);
	ssc_p->dir_mask &= ~dir_mask;
	if (!ssc_p->dir_mask) {
		/* Shutdown the SSC clock. */
		DBG("Stopping pid %d clock\n", ssc_p->ssc.pid);
		at91_sys_write(AT91_PMC_PCDR, 1<<ssc_p->ssc.pid);

		if (ssc_p->initialized) {
			free_irq(ssc_p->ssc.pid, ssc_p);
			ssc_p->initialized = 0;
		}

		/* Reset the SSC */
		at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR, AT91_SSC_SWRST);

		/* Clear the SSC dividers */
		ssc_p->cmr_div = ssc_p->tcmr_period = ssc_p->rcmr_period = 0;
	}
	spin_unlock_irq(&ssc_p->lock);
}

/*
 * Record th