示例#1
0
static int aes_dma_stop(struct aes_hwa_ctx *ctx)
{
	struct tf_crypto_aes_operation_state *state =
		crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(ctx->req));
	int err = 0;
	size_t count;

	dprintk(KERN_INFO "aes_dma_stop(%p)\n", ctx);

	tf_aes_save_registers(state);

	if (!AES_CTRL_IS_MODE_ECB(state->CTRL)) {
		u32 *ptr = (u32 *) ctx->req->info;

		ptr[0] = state->AES_IV_0;
		ptr[1] = state->AES_IV_1;
		ptr[2] = state->AES_IV_2;
		ptr[3] = state->AES_IV_3;
	}

	OUTREG32(&paes_reg->AES_SYSCONFIG, 0);

	omap_stop_dma(ctx->dma_lch_in);
	omap_stop_dma(ctx->dma_lch_out);

	tf_crypto_disable_clock(PUBLIC_CRYPTO_AES1_CLOCK_REG);

	if (!(ctx->flags & FLAGS_FAST)) {
		dma_sync_single_for_device(NULL, ctx->dma_addr_out,
			ctx->dma_size, DMA_FROM_DEVICE);

#ifdef CONFIG_TF_DRIVER_FAULT_INJECTION
		tf_aes_fault_injection(paes_reg->AES_CTRL, ctx->buf_out);
#endif

		/* Copy data */
		count = sg_copy(&ctx->out_sg, &ctx->out_offset, ctx->buf_out,
			ctx->buflen, ctx->dma_size, 1);
		if (count != ctx->dma_size)
			err = -EINVAL;
	} else {
		dma_unmap_sg(NULL, ctx->out_sg, 1, DMA_FROM_DEVICE);
		dma_unmap_sg(NULL, ctx->in_sg, 1, DMA_TO_DEVICE);

#ifdef CONFIG_TF_DRIVER_FAULT_INJECTION
		tf_aes_fault_injection(paes_reg->AES_CTRL,
			sg_virt(ctx->out_sg));
#endif
	}

	if (err || !ctx->total)
		ctx->req->base.complete(&ctx->req->base, err);

	return err;
}
示例#2
0
static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct omap_runtime_data *prtd = runtime->private_data;
	struct omap_pcm_dma_data *dma_data = prtd->dma_data;
	unsigned long flags;
	int ret = 0;

	spin_lock_irqsave(&prtd->lock, flags);
	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		prtd->period_index = 0;
		/* Configure McBSP internal buffer usage */
		if (dma_data->set_threshold)
			dma_data->set_threshold(substream);

		omap_start_dma(prtd->dma_ch);
		break;

	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		prtd->period_index = -1;
		omap_stop_dma(prtd->dma_ch);
#if 0 // orig
			/* Since we are using self linking, there is a
		  	 chance that the DMA as re-enabled the channel
		 	  just after disabling it */
			while (omap_get_dma_active_status(prtd->dma_ch))
				omap_stop_dma(prtd->dma_ch);
#else // [email protected], TI patch error in the recording
       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 
           /* Fix: Ensure that the DMA channel is stopped 
           for self linked audio DMA channel */ 
           while (omap_get_dma_active_status(prtd->dma_ch))
		       omap_stop_dma(prtd->dma_ch); 
		}
#endif
		break;
	default:
		ret = -EINVAL;
	}
	spin_unlock_irqrestore(&prtd->lock, flags);

	return ret;
}
static void uart_tx_dma_callback(int lch, u16 ch_status, void *data)
{
	struct uart_omap_port *up = (struct uart_omap_port *)data;
	struct circ_buf *xmit = &up->port.info->xmit;
	xmit->tail = (xmit->tail + up->uart_dma.tx_buf_size) & (UART_XMIT_SIZE - 1);
	up->port.icount.tx += up->uart_dma.tx_buf_size;

	/* Revisit: Not sure about the below two steps. Seen some instabilities
	* with them. might not be needed in the DMA path
	*/
	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(&up->port);

	if (uart_circ_empty(xmit)) {

		spin_lock(&(up->uart_dma.tx_lock));
		serial_omap_stop_tx(&up->port);
		up->uart_dma.tx_dma_state = 0;
		spin_unlock(&(up->uart_dma.tx_lock));
	} else {
		omap_stop_dma(up->uart_dma.tx_dma_channel);
		serial_omap_continue_tx(up);
	}
	isr8250_activity = jiffies;

	return;
}
static void serial_omap_stop_tx(struct uart_port *port)
{
	struct uart_omap_port *up = (struct uart_omap_port *)port;
	struct omap_uart_port_info *pdata = up->pdev->dev.platform_data;

	if (up->use_dma &&
		up->uart_dma.tx_dma_channel != OMAP_UART_DMA_CH_FREE) {
		if (omap_get_dma_active_status(up->uart_dma.tx_dma_channel))
			return;
		omap_stop_dma(up->uart_dma.tx_dma_channel);
		omap_free_dma(up->uart_dma.tx_dma_channel);
		up->uart_dma.tx_dma_channel = OMAP_UART_DMA_CH_FREE;
		pm_runtime_mark_last_busy(&up->pdev->dev);
		pm_runtime_put_autosuspend(&up->pdev->dev);
	}

	pm_runtime_get_sync(&up->pdev->dev);
	if (up->ier & UART_IER_THRI) {
		up->ier &= ~UART_IER_THRI;
		serial_out(up, UART_IER, up->ier);
	}

	if (!up->use_dma && pdata && pdata->set_forceidle)
		pdata->set_forceidle(up->pdev);

	pm_runtime_mark_last_busy(&up->pdev->dev);
	pm_runtime_put_autosuspend(&up->pdev->dev);
}
示例#5
0
static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct omap_runtime_data *prtd = runtime->private_data;
	unsigned long flags;
	int ret = 0;

	spin_lock_irqsave(&prtd->lock, flags);
	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		prtd->period_index = 0;
		omap_start_dma(prtd->dma_ch);
		break;

	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		prtd->period_index = -1;
		omap_stop_dma(prtd->dma_ch);
		break;
	default:
		ret = -EINVAL;
	}
	spin_unlock_irqrestore(&prtd->lock, flags);

	return ret;
}
示例#6
0
/*
 * omap24xxx_timeout_isr
 * Looks at DMA destination register and calls receive
 * callback if the destination register is the same on
 * two timer isr.
 */
static void
omap24xx_timeout_isr(unsigned long uart_no)
{
	u32	w = 0;
	int	lch;
	int	curr_pos;
	static int	prev_pos = 0;
	struct	omap24xx_uart *hsuart = &ui[uart_no];
	FN_IN;
	lch = hsuart->rx_dma_channel;

	curr_pos = omap_get_dma_dst_pos(lch);
	if ((curr_pos == prev_pos) && (curr_pos != hsuart->rx_buf_dma_phys)) {
		omap_stop_dma(lch);
		w = OMAP_DMA_CSR_REG(lch);

		uart_rx_dma_callback(lch, w, uart_cb[hsuart->uart_no].dev);

		prev_pos = 0;
	}
	else {
		prev_pos = curr_pos;
		mod_timer(&hsuart->timer, jiffies +
				msecs_to_jiffies(hsuart->timeout));

	}
	FN_OUT(0);
}
示例#7
0
static void serial_omap_stop_tx(struct uart_port *port)
{
	struct uart_omap_port *up = (struct uart_omap_port *)port;

	if (up->use_dma &&
		up->uart_dma.tx_dma_channel != OMAP_UART_DMA_CH_FREE) {
		/*
		 * Check if dma is still active. If yes do nothing,
		 * return. Else stop dma
		 */
		if (omap_get_dma_active_status(up->uart_dma.tx_dma_channel))
			return;
		omap_stop_dma(up->uart_dma.tx_dma_channel);
		omap_free_dma(up->uart_dma.tx_dma_channel);
		up->uart_dma.tx_dma_channel = OMAP_UART_DMA_CH_FREE;
		pm_runtime_mark_last_busy(&up->pdev->dev);
		pm_runtime_put_autosuspend(&up->pdev->dev);
	}

	pm_runtime_get_sync(&up->pdev->dev);
	if (up->ier & UART_IER_THRI) {
		up->ier &= ~UART_IER_THRI;
		serial_out(up, UART_IER, up->ier);
	}

	pm_runtime_mark_last_busy(&up->pdev->dev);
	pm_runtime_put_autosuspend(&up->pdev->dev);
}
static void serial_omap_stop_tx(struct uart_port *port)
{
	struct uart_omap_port *up = (struct uart_omap_port *)port;
	if (up->use_dma) {
		if (up->uart_dma.tx_dma_channel != 0xFF) {
		/*
		 * Check if dma is still active . If yes do nothing , return.
		 * Else stop dma
		 */
			int status = omap_readl(OMAP34XX_DMA4_BASE + OMAP_DMA4_CCR(up->uart_dma.tx_dma_channel));
			if (status & (1 << 7))
				return;
			omap_stop_dma(up->uart_dma.tx_dma_channel);
			omap_free_dma(up->uart_dma.tx_dma_channel);
			up->uart_dma.tx_dma_channel = 0xFF;
		}
	}

	if (up->ier & UART_IER_THRI) {
		up->ier &= ~UART_IER_THRI;
		serial_out(up, UART_IER, up->ier);
	}
#ifdef CONFIG_OMAP3_PM
	if (!up->uart_dma.rx_dma_state) {
		unsigned int tmp;
		tmp = (serial_in(up, UART_OMAP_SYSC) & 0x7) | (2 << 3);
		serial_out(up, UART_OMAP_SYSC, tmp); /* smart-idle */
	}
#endif
}
示例#9
0
static void suspend_capture(struct omap1_cam_dev *pcdev)
{
	u32 ctrlclock = CAM_READ_CACHE(pcdev, CTRLCLOCK);

	CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~LCLK_EN);
	omap_stop_dma(pcdev->dma_ch);
}
示例#10
0
int omap_free_sound_dma(void *data, int **channels)
{
	int i;
	int *chan = NULL;
	FN_IN;
	if (unlikely(NULL == channels)) {
		BUG();
		return -EPERM;
	}
	if (unlikely(NULL == *channels)) {
		BUG();
		return -EPERM;
	}
	chan = (*channels);

	if (!cpu_is_omap1510())
		omap_sound_dma_unlink_lch(data);
	for (i = 0; i < nr_linked_channels; i++) {
		int cur_chan = chan[i];
		omap_stop_dma(cur_chan);
		omap_free_dma(cur_chan);
	}
	kfree(*channels);
	*channels = NULL;
	FN_OUT(0);
	return 0;
}
示例#11
0
static void serial_omap_stop_tx(struct uart_port *port)
{
	struct uart_omap_port *up = (struct uart_omap_port *)port;

	if (up->use_dma &&
		up->uart_dma.tx_dma_channel != OMAP_UART_DMA_CH_FREE) {
		/*
		 * Check if dma is still active. If yes do nothing,
		 * return. Else stop dma
		 */
		if (omap_get_dma_active_status(up->uart_dma.tx_dma_channel))
			return;
		omap_stop_dma(up->uart_dma.tx_dma_channel);
		omap_free_dma(up->uart_dma.tx_dma_channel);
		up->uart_dma.tx_dma_channel = OMAP_UART_DMA_CH_FREE;
	}

	if (!(up->rs485.flags & SER_RS485_ENABLED)) {
		serial_omap_disable_ier_thri(up);
		return;
	}

	up->tx_wait_end = 1;
	serial_omap_thri_mode(up);
	serial_omap_enable_ier_thri(up);
}
static void serial_omap_stop_tx(struct uart_port *port)
{
	struct uart_omap_port *up = (struct uart_omap_port *)port;

	if (up->use_dma &&
		up->uart_dma.tx_dma_channel != OMAP_UART_DMA_CH_FREE) {
		/*
		 * Check if dma is still active. If yes do nothing,
		 * return. Else stop dma
		 */
		if (omap_get_dma_active_status(up->uart_dma.tx_dma_channel))
			return;
		omap_stop_dma(up->uart_dma.tx_dma_channel);
		omap_free_dma(up->uart_dma.tx_dma_channel);
		up->uart_dma.tx_dma_channel = OMAP_UART_DMA_CH_FREE;
		serial_omap_port_disable(up);
	}

	serial_omap_port_enable(up);
	if (up->ier & UART_IER_THRI) {
		up->ier &= ~UART_IER_THRI;
		serial_out(up, UART_IER, up->ier);
	}

	serial_omap_port_disable(up);
}
示例#13
0
/* DMA TX callback - calling when frame transfer has been finished */
static void omap_irda_tx_dma_callback(int lch, u16 ch_status, void *data)
{
	struct net_device *dev = data;
	struct omap_irda *omap_ir = netdev_priv(dev);

	/*Stop DMA controller */
	omap_stop_dma(omap_ir->tx_dma_channel);
}
示例#14
0
static void serial_omap_stop_rxdma(struct uart_omap_port *up)
{
	if (up->uart_dma.rx_dma_used) {
		del_timer(&up->uart_dma.rx_timer);
		omap_stop_dma(up->uart_dma.rx_dma_channel);
		omap_free_dma(up->uart_dma.rx_dma_channel);
		up->uart_dma.rx_dma_channel = OMAP_UART_DMA_CH_FREE;
		up->uart_dma.rx_dma_used = false;
	}
}
static void serial_omap_stop_rxdma(struct uart_omap_port *up)
{
	if (up->uart_dma.rx_dma_state) {
		del_timer(&up->uart_dma.rx_timer);
		omap_stop_dma(up->uart_dma.rx_dma_channel);
		omap_free_dma(up->uart_dma.rx_dma_channel);
		up->uart_dma.rx_dma_channel = 0xFF;
		up->uart_dma.rx_dma_state = 0x0;
	}
}
示例#16
0
文件: omap-pcm.c 项目: UAVXP/A10
static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct omap_runtime_data *prtd = runtime->private_data;
	struct omap_pcm_dma_data *dma_data = prtd->dma_data;
	unsigned long flags;
	int ret = 0;

	spin_lock_irqsave(&prtd->lock, flags);
	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		prtd->period_index = 0;
		/* Configure McBSP internal buffer usage */
		if (dma_data->set_threshold)
			dma_data->set_threshold(substream);

		omap_start_dma(prtd->dma_ch);
		break;

	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		prtd->period_index = -1;
		omap_stop_dma(prtd->dma_ch);
		if (cpu_is_omap44xx()) {
			/* Since we are using self linking, there is a
		  	 chance that the DMA as re-enabled the channel
		 	  just after disabling it */
			while (omap_get_dma_active_status(prtd->dma_ch))
				omap_stop_dma(prtd->dma_ch);
		}
		break;
	default:
		ret = -EINVAL;
	}
	spin_unlock_irqrestore(&prtd->lock, flags);

	return ret;
}
示例#17
0
static void serial_omap_stop_rxdma(struct uart_omap_port *up)
{
	if (up->uart_dma.rx_dma_used) {
		del_timer(&up->uart_dma.rx_timer);
		omap_stop_dma(up->uart_dma.rx_dma_channel);
		omap_free_dma(up->uart_dma.rx_dma_channel);
		up->uart_dma.rx_dma_channel = OMAP_UART_DMA_CH_FREE;
		up->uart_dma.rx_dma_used = false;
		pm_runtime_mark_last_busy(&up->pdev->dev);
		pm_runtime_put_autosuspend(&up->pdev->dev);
	}
}
示例#18
0
static void omap1610_irda_tx_dma_callback(int lch, u16 ch_status, void *data)
{
	struct net_device *dev = data;
	struct omap1610_irda *si = dev->priv;

	__ECHO_IN;

	/*Stop DMA controller */
	omap_stop_dma(si->tx_dma_channel);

	__ECHO_OUT;

}
static void abe_dbg_stop_dma(struct omap_abe *abe)
{
    /* Since we are using self linking, there is a
    chance that the DMA as re-enabled the channel just after disabling it */
    while (omap_get_dma_active_status(abe->debugfs.dma_ch))
        omap_stop_dma(abe->debugfs.dma_ch);

    if (abe->debugfs.circular)
        omap_dma_unlink_lch(abe->debugfs.dma_ch, abe->debugfs.dma_ch);

    omap_free_dma(abe->debugfs.dma_ch);
    pm_runtime_put_sync(abe->dev);
}
示例#20
0
static int dma_channel_abort(struct dma_channel *channel)
{
	struct musb_dma_channel *musb_channel = channel->private_data;
	void __iomem *mbase = musb_channel->controller->base;

	u8 bchannel = musb_channel->idx;
	int offset;
	u16 csr;

	if (channel->status == MUSB_DMA_STATUS_BUSY) {
		if (musb_channel->transmit) {
			offset = MUSB_EP_OFFSET(musb_channel->epnum,
						MUSB_TXCSR);

			/*
			 * The programming guide says that we must clear
			 * the DMAENAB bit before the DMAMODE bit...
			 */
			csr = musb_readw(mbase, offset);
			csr &= ~(MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAENAB);
			musb_writew(mbase, offset, csr);
			csr &= ~MUSB_TXCSR_DMAMODE;
			musb_writew(mbase, offset, csr);
		} else {
			if (musb_channel->sysdma_channel != -1)
				omap_stop_dma(musb_channel->sysdma_channel);

			offset = MUSB_EP_OFFSET(musb_channel->epnum,
						MUSB_RXCSR);

			csr = musb_readw(mbase, offset);
			csr &= ~(MUSB_RXCSR_AUTOCLEAR |
				 MUSB_RXCSR_DMAENAB |
				 MUSB_RXCSR_DMAMODE);
			musb_writew(mbase, offset, csr);
		}

		musb_writew(mbase,
			MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_CONTROL),
			0);
		musb_write_hsdma_addr(mbase, bchannel, 0);
		musb_write_hsdma_count(mbase, bchannel, 0);
		channel->status = MUSB_DMA_STATUS_FREE;
	}

	return 0;
}
示例#21
0
/***************************************************************************************
 *
 * Stop all the DMA channels of the stream
 *
 **************************************************************************************/
void audio_stop_dma(audio_stream_t * s)
{
	int *chan = s->lch;
	int i;
	FN_IN;
	if (unlikely(NULL == chan)) {
		BUG();
		return;
	}
	for (i = 0; i < nr_linked_channels; i++) {
		int cur_chan = chan[i];
		omap_stop_dma(cur_chan);
	}
	s->started = 0;
	FN_OUT(0);
	return;
}
示例#22
0
/* ISRs have to be short and smart.. So we transfer every heavy duty stuff to the 
 * work item
 */
static void sound_dma_irq_handler(int sound_curr_lch, u16 ch_status, void *data)
{
	int dma_status = ch_status;
	audio_stream_t *s = (audio_stream_t *) data;
	FN_IN;
#ifdef IRQ_TRACE
	xyz[h++] = '0' + sound_curr_lch;
	if (h == MAX_UP - 1) {
		printk("%s-", xyz);
		h = 0;
	}
#endif
	DPRINTK("lch=%d,status=0x%x, dma_status=%d, data=%p\n", sound_curr_lch,
		ch_status, dma_status, data);

	if (dma_status & (DCSR_ERROR)) {
		if (cpu_is_omap15xx() || cpu_is_omap16xx())
			omap_stop_dma(sound_curr_lch);
		ERR("DCSR_ERROR!\n");
		FN_OUT(-1);
		return;
	}

	if (AUDIO_QUEUE_LAST(s))
		audio_stop_dma(s);

	/* Start the work item  - we ping pong the work items */
	if (!work_item_running) {
		work1.current_lch = sound_curr_lch;
		work1.ch_status = ch_status;
		work1.s = s;
		/* schedule tasklet 1 */
		tasklet_schedule(&audio_isr_work1);
		work_item_running = 1;
	} else {
		work2.current_lch = sound_curr_lch;
		work2.ch_status = ch_status;
		work2.s = s;
		/* schedule tasklet 2 */
		tasklet_schedule(&audio_isr_work2);
		work_item_running = 0;
	}
	FN_OUT(0);
	return;
}
示例#23
0
static int dma_channel_abort(struct dma_channel *channel)
{
	struct musb_dma_channel *musb_channel = channel->private_data;
	void __iomem *mbase = musb_channel->controller->base;

	u8 bchannel = musb_channel->idx;
	u16 csr;

	if (channel->status == MUSB_DMA_STATUS_BUSY) {
		if (musb_channel->transmit) {

			csr = musb_readw(mbase,
				MUSB_EP_OFFSET(musb_channel->epnum,
						MUSB_TXCSR));
			csr &= ~(MUSB_TXCSR_AUTOSET |
				 MUSB_TXCSR_DMAENAB |
				 MUSB_TXCSR_DMAMODE);
			musb_writew(mbase,
				MUSB_EP_OFFSET(musb_channel->epnum, MUSB_TXCSR),
				csr);
		} else {
			if (musb_channel->sysdma_channel != -1)
				omap_stop_dma(musb_channel->sysdma_channel);

			csr = musb_readw(mbase,
				MUSB_EP_OFFSET(musb_channel->epnum,
						MUSB_RXCSR));
			csr &= ~(MUSB_RXCSR_AUTOCLEAR |
				 MUSB_RXCSR_DMAENAB |
				 MUSB_RXCSR_DMAMODE);
			musb_writew(mbase,
				MUSB_EP_OFFSET(musb_channel->epnum, MUSB_RXCSR),
				csr);
		}

		musb_writew(mbase,
			MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_CONTROL),
			0);
		musb_write_hsdma_addr(mbase, bchannel, 0);
		musb_write_hsdma_count(mbase, bchannel, 0);
		channel->status = MUSB_DMA_STATUS_FREE;
	}

	return 0;
}
示例#24
0
/*
 * Stop all the DMA channels of the stream
 */
void omap_stop_alsa_sound_dma(struct audio_stream *s)
{
	int *chan = s->lch;
	int i;

	FN_IN;
	if (unlikely(NULL == chan)) {
		BUG();
		return -1;
	}
	for (i = 0; i < nr_linked_channels; i++) {
		int cur_chan = chan[i];
		omap_stop_dma(cur_chan);
	}
	s->started = 0;
	FN_OUT(0);
	return 0;
}
示例#25
0
static void
mmc_omap_release_dma(struct mmc_omap_host *host, struct mmc_data *data,
		     int abort)
{
	enum dma_data_direction dma_data_dir;

	BUG_ON(host->dma_ch < 0);
	if (data->error)
		omap_stop_dma(host->dma_ch);
	/* Release DMA channel lazily */
	mod_timer(&host->dma_timer, jiffies + HZ);
	if (data->flags & MMC_DATA_WRITE)
		dma_data_dir = DMA_TO_DEVICE;
	else
		dma_data_dir = DMA_FROM_DEVICE;
	dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_len,
		     dma_data_dir);
}
static void hist_dma_cb(int lch, u16 ch_status, void *data)
{
    struct ispstat *hist = data;

    if (ch_status & ~OMAP_DMA_BLOCK_IRQ) {
        dev_dbg(hist->isp->dev, "hist: DMA error. status = 0x%04x\n",
                ch_status);
        omap_stop_dma(lch);
        hist_reset_mem(hist);
        atomic_set(&hist->buf_err, 1);
    }
    isp_reg_clr(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT,
                ISPHIST_CNT_CLEAR);

    omap3isp_stat_dma_isr(hist);
    if (hist->state != ISPSTAT_DISABLED)
        omap3isp_hist_dma_done(hist->isp);
}
示例#27
0
static void dma_channel_release(struct dma_channel *channel)
{
	struct musb_dma_channel *musb_channel = channel->private_data;

	channel->actual_len = 0;
	musb_channel->start_addr = 0;
	musb_channel->len = 0;

	musb_channel->controller->used_channels &=
		~(1 << musb_channel->idx);

	channel->status = MUSB_DMA_STATUS_UNKNOWN;

	if (musb_channel->sysdma_channel != -1) {
		omap_stop_dma(musb_channel->sysdma_channel);
		omap_free_dma(musb_channel->sysdma_channel);
		musb_channel->sysdma_channel = -1;
	}
}
示例#28
0
static int tusb_omap_dma_abort(struct dma_channel *channel)
{
	struct tusb_omap_dma_ch	*chdat = to_chdat(channel);
	struct tusb_omap_dma	*tusb_dma = chdat->tusb_dma;

	if (!tusb_dma->multichannel) {
		if (tusb_dma->ch >= 0) {
			omap_stop_dma(tusb_dma->ch);
			omap_free_dma(tusb_dma->ch);
			tusb_dma->ch = -1;
		}

		tusb_dma->dmareq = -1;
		tusb_dma->sync_dev = -1;
	}

	channel->status = MUSB_DMA_STATUS_FREE;

	return 0;
}
示例#29
0
/*
 * ISRs have to be short and smart..
 * Here we call alsa handling, after some error checking
 */
static void sound_dma_irq_handler(int sound_curr_lch, u16 ch_status,
				  void *data)
{
	int dma_status = ch_status;
	struct audio_stream *s = (struct audio_stream *) data;
	FN_IN;

	/* some register checking */
	DPRINTK("lch=%d,status=0x%x, dma_status=%d, data=%p\n",
		sound_curr_lch, ch_status, dma_status, data);

	if (dma_status & (DCSR_ERROR)) {
		omap_stop_dma(sound_curr_lch);
		ERR("DCSR_ERROR!\n");
		FN_OUT(-1);
		return;
	}

	if (ch_status & DCSR_END_BLOCK)
		callback_omap_alsa_sound_dma(s);
	FN_OUT(0);
	return;
}
示例#30
0
static void uart_tx_dma_callback(int lch, u16 ch_status, void *data)
{
	struct uart_omap_port *up = (struct uart_omap_port *)data;
	struct circ_buf *xmit = &up->port.state->xmit;

	xmit->tail = (xmit->tail + up->uart_dma.tx_buf_size) & \
			(UART_XMIT_SIZE - 1);
	up->port.icount.tx += up->uart_dma.tx_buf_size;

	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(&up->port);

	if (uart_circ_empty(xmit)) {
		spin_lock(&(up->uart_dma.tx_lock));
		serial_omap_stop_tx(&up->port);
		up->uart_dma.tx_dma_used = false;
		spin_unlock(&(up->uart_dma.tx_lock));
			if (up->plat_hold_wakelock)
				(up->plat_hold_wakelock(up, WAKELK_TX));
	} else {

#ifdef CONFIG_PM
		/*
		 * This will enable the clock for some reason if the
		 * clocks get disabled. This would enable the ICK also
		 * in case if the Idle state is set and the PRCM modul
		 * just shutdown the ICK because of inactivity.
		 */
		omap_uart_enable_clock_from_irq(up->pdev->id);
#endif

		omap_stop_dma(up->uart_dma.tx_dma_channel);
		serial_omap_continue_tx(up);
	}
	up->port_activity = jiffies;
	return;
}