示例#1
0
static void aes_dma_cleanup(struct aes_hwa_ctx *ctx)
{
	omap_free_dma(ctx->dma_lch_out);
	omap_free_dma(ctx->dma_lch_in);
	dma_free_coherent(NULL, ctx->buflen, ctx->buf_in, ctx->dma_addr_in);
	dma_free_coherent(NULL, ctx->buflen, ctx->buf_out, ctx->dma_addr_out);
	iounmap(omap_dma_base);
}
示例#2
0
static int __devexit omap2_onenand_remove(struct platform_device *pdev)
{
	struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);

	BUG_ON(c == NULL);

#ifdef CONFIG_MTD_PARTITIONS
	if (c->parts)
		del_mtd_partitions(&c->mtd);
	else
		del_mtd_device(&c->mtd);
#else
	del_mtd_device(&c->mtd);
#endif

	onenand_release(&c->mtd);
	if (c->dma_channel != -1)
		omap_free_dma(c->dma_channel);
	omap2_onenand_shutdown(pdev);
	platform_set_drvdata(pdev, NULL);
	if (c->gpio_irq) {
		free_irq(gpio_to_irq(c->gpio_irq), c);
		gpio_free(c->gpio_irq);
	}
	iounmap(c->onenand.base);
	release_mem_region(c->phys_base, ONENAND_IO_SIZE);
	gpmc_cs_free(c->gpmc_cs);
	kfree(c);

	return 0;
}
void omap3isp_hist_cleanup(struct isp_device *isp)
{
    if (HIST_USING_DMA(&isp->isp_hist))
        omap_free_dma(isp->isp_hist.dma_ch);
    kfree(isp->isp_hist.priv);
    omap3isp_stat_cleanup(&isp->isp_hist);
}
示例#4
0
static int __exit omap1_cam_remove(struct platform_device *pdev)
{
	struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
	struct omap1_cam_dev *pcdev = container_of(soc_host,
					struct omap1_cam_dev, soc_host);
	struct resource *res;

	free_irq(pcdev->irq, pcdev);

	omap_free_dma(pcdev->dma_ch);

	soc_camera_host_unregister(soc_host);

	iounmap(pcdev->base);

	res = pcdev->res;
	release_mem_region(res->start, resource_size(res));

	clk_put(pcdev->clk);

	kfree(pcdev);

	dev_info(&pdev->dev, "OMAP1 Camera Interface driver unloaded\n");

	return 0;
}
示例#5
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;
}
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);
}
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);
}
示例#8
0
文件: dma.c 项目: christinaa/Daisy
/**
 * @brief omap_free_dma_chain - Free all the logical channels in a chain.
 *
 * @param chain_id
 *
 * @return - Success : 0
 * 	     Failure : -EINVAL
 */
int omap_free_dma_chain(int chain_id)
{
	int *channels;
	u32 i;
	
	/* Check for input params */
	if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
		IOLog("Invalid chain id\n");
		return -EINVAL;
	}
	
	/* Check if the chain exists */
	if (dma_linked_lch[chain_id].linked_dmach_q == NULL) {
		IOLog("Chain doesn't exists\n");
		return -EINVAL;
	}
	
	channels = dma_linked_lch[chain_id].linked_dmach_q;
	for (i = 0; i < dma_linked_lch[chain_id].no_of_lchs_linked; i++) {
		dma_chan[channels[i]].next_linked_ch = -1;
		dma_chan[channels[i]].prev_linked_ch = -1;
		dma_chan[channels[i]].chain_id = -1;
		dma_chan[channels[i]].state = DMA_CH_NOTSTARTED;
		omap_free_dma(channels[i]);
	}
	
	free(channels);
	
	dma_linked_lch[chain_id].linked_dmach_q = NULL;
	dma_linked_lch[chain_id].chain_mode = -1;
	dma_linked_lch[chain_id].chain_state = -1;
	
	return (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) {
		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
}
示例#10
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);
}
示例#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);
}
/*
 * DMA call back function
 */
static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *data)
{
	struct omap_hsmmc_host *host = data;

	if (ch_status & OMAP2_DMA_MISALIGNED_ERR_IRQ)
		dev_dbg(mmc_dev(host->mmc), "MISALIGNED_ADRS_ERR\n");

	if (host->dma_ch < 0)
		return;

	host->dma_sg_idx++;
	if (host->dma_sg_idx < host->dma_len) {
		/* Fire up the next transfer. */
		omap_hsmmc_config_dma_params(host, host->data,
					   host->data->sg + host->dma_sg_idx);
		return;
	}

	omap_free_dma(host->dma_ch);
	host->dma_ch = -1;
	/*
	 * DMA Callback: run in interrupt context.
	 * mutex_unlock will throw a kernel warning if used.
	 */
	up(&host->sem);
}
示例#13
0
static void
mmc_omap_dma_timer(unsigned long data)
{
	struct mmc_omap_host *host = (struct mmc_omap_host *) data;

	BUG_ON(host->dma_ch < 0);
	omap_free_dma(host->dma_ch);
	host->dma_ch = -1;
}
/*
 * Routine to configure and start DMA for the MMC card
 */
static int omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host,
					struct mmc_request *req)
{
	int dma_ch = 0, ret = 0, err = 1, i;
	struct mmc_data *data = req->data;

	/* Sanity check: all the SG entries must be aligned by block size. */
	for (i = 0; i < data->sg_len; i++) {
		struct scatterlist *sgl;

		sgl = data->sg + i;
		if (sgl->length % data->blksz)
			return -EINVAL;
	}
	if ((data->blksz % 4) != 0)
		/* REVISIT: The MMC buffer increments only when MSB is written.
		 * Return error for blksz which is non multiple of four.
		 */
		return -EINVAL;

	/*
	 * If for some reason the DMA transfer is still active,
	 * we wait for timeout period and free the dma
	 */
	if (host->dma_ch != -1) {
		set_current_state(TASK_UNINTERRUPTIBLE);
		schedule_timeout(100);
		if (down_trylock(&host->sem)) {
			omap_free_dma(host->dma_ch);
			host->dma_ch = -1;
			up(&host->sem);
			return err;
		}
	} else {
		if (down_trylock(&host->sem))
			return err;
	}

	ret = omap_request_dma(omap_hsmmc_get_dma_sync_dev(host, data),
			       "MMC/SD", omap_hsmmc_dma_cb, host, &dma_ch);
	if (ret != 0) {
		dev_err(mmc_dev(host->mmc),
			"%s: omap_request_dma() failed with %d\n",
			mmc_hostname(host->mmc), ret);
		return ret;
	}

	host->dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg,
			data->sg_len, omap_hsmmc_get_dma_dir(host, data));
	host->dma_ch = dma_ch;
	host->dma_sg_idx = 0;

	omap_hsmmc_config_dma_params(host, data, data->sg);

	return 0;
}
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
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;
	}
}
示例#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 omap_mmc_tx_dma_callback (void *data, int size)
{

        omap_free_dma(g_omap_mmc_data.dma_regs);
        g_omap_mmc_data.dma_regs = NULL; 

        g_omap_mmc_data.request->buffer +=  g_omap_mmc_data.request->block_len;

        g_omap_mmc_data.request->nob--;

	DEBUG(3, ": TX Transfer finished. Status: %d\n", inw(OMAP_MMC_STAT));
}
示例#19
0
/*
 * Release the VRFB context once the module exits
 */
void omap_vout_release_vrfb(struct omap_vout_device *vout)
{
	int i;

	for (i = 0; i < VRFB_NUM_BUFS; i++)
		omap_vrfb_release_ctx(&vout->vrfb_context[i]);

	if (vout->vrfb_dma_tx.req_status == DMA_CHAN_ALLOTED) {
		vout->vrfb_dma_tx.req_status = DMA_CHAN_NOT_ALLOTED;
		omap_free_dma(vout->vrfb_dma_tx.dma_ch);
	}
}
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);
}
/*
 * DMA clean up for command errors
 */
static void omap_hsmmc_dma_cleanup(struct omap_hsmmc_host *host, int errno)
{
	host->data->error = errno;

	if (host->use_dma && host->dma_ch != -1) {
		dma_unmap_sg(mmc_dev(host->mmc), host->data->sg, host->dma_len,
			omap_hsmmc_get_dma_dir(host, host->data));
		omap_free_dma(host->dma_ch);
		host->dma_ch = -1;
		up(&host->sem);
	}
	host->data = NULL;
}
示例#22
0
int omap_request_alsa_sound_dma(int device_id, const char *device_name,
			   void *data, int **channels)
{
	int i, err = 0;
	int *chan = NULL;
	FN_IN;
	if (unlikely((NULL == channels) || (NULL == device_name))) {
		BUG();
		return -EPERM;
	}
	/* Try allocate memory for the num channels */
	*channels = kmalloc(sizeof(int) * nr_linked_channels, GFP_KERNEL);
	chan = *channels;
	if (NULL == chan) {
		ERR("No Memory for channel allocs!\n");
		FN_OUT(-ENOMEM);
		return -ENOMEM;
	}
	spin_lock(&dma_list_lock);
	for (i = 0; i < nr_linked_channels; i++) {
		err = omap_request_dma(device_id,
				device_name,
				sound_dma_irq_handler,
				data,
				&chan[i]);

		/* Handle Failure condition here */
		if (err < 0) {
			int j;

			for (j = 0; j < i; j++)
				omap_free_dma(chan[j]);

			spin_unlock(&dma_list_lock);
			kfree(chan);
			*channels = NULL;
			ERR("Error in requesting channel %d=0x%x\n", i,
			    err);
			FN_OUT(err);
			return err;
		}
	}

	/* Chain the channels together */
	if (!cpu_is_omap15xx())
		omap_sound_dma_link_lch(data);

	spin_unlock(&dma_list_lock);
	FN_OUT(0);
	return 0;
}
示例#23
0
/*
 * DMA clean up for command errors
 */
static void mmc_dma_cleanup(struct mmc_omap_host *host)
{
	host->data->error = -ETIMEDOUT;

	if (host->use_dma && host->dma_ch != -1) {
		dma_unmap_sg(mmc_dev(host->mmc), host->data->sg, host->dma_len,
			host->dma_dir);
		omap_free_dma(host->dma_ch);
		host->dma_ch = -1;
		up(&host->sem);
	}
	host->data = NULL;
	host->datadir = OMAP_MMC_DATADIR_NONE;
}
示例#24
0
static int omap_irda_stop(struct net_device *dev)
{
	struct omap_irda *omap_ir = netdev_priv(dev);

	disable_irq(dev->irq);

	netif_stop_queue(dev);

	omap_free_dma(omap_ir->rx_dma_channel);
	omap_free_dma(omap_ir->tx_dma_channel);

	if (omap_ir->rx_buf_dma_virt)
		dma_free_coherent(NULL, IRDA_SKB_MAX_MTU,
				omap_ir->rx_buf_dma_virt,
				omap_ir->rx_buf_dma_phys);
	if (omap_ir->tx_buf_dma_virt)
		dma_free_coherent(NULL, IRDA_SIR_MAX_FRAME,
				omap_ir->tx_buf_dma_virt,
				omap_ir->tx_buf_dma_phys);

	omap_irda_shutdown(omap_ir);

	/* Stop IrLAP */
	if (omap_ir->irlap) {
		irlap_close(omap_ir->irlap);
		omap_ir->irlap = NULL;
	}

	omap_ir->open = 0;

	/*
	 * Free resources
	 */
	free_irq(dev->irq, dev);

	return 0;
}
示例#25
0
static int omap1610_irda_stop(struct net_device *dev)
{
	struct omap1610_irda *si = dev->priv;

	__ECHO_IN;

	disable_irq(dev->irq);

	netif_stop_queue(dev);

	omap_free_dma(si->rx_dma_channel);
	omap_free_dma(si->tx_dma_channel);

	dma_free_coherent(NULL, 4096, si->rx_buf_dma_virt, si->rx_buf_dma_phys);
	dma_free_coherent(NULL, 4096, si->tx_buf_dma_virt, si->tx_buf_dma_phys);

	omap1610_irda_shutdown(si);

	/* Stop IrLAP */
	if (si->irlap) {
		irlap_close(si->irlap);
		si->irlap = NULL;
	}

	si->open = 0;

	/*
	 * Free resources
	 */

	free_irq(dev->irq, dev);

	__ECHO_OUT;

	return 0;
}
示例#26
0
static int omap_pcm_hw_free(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct omap_runtime_data *prtd = runtime->private_data;

	if (prtd->dma_data == NULL)
		return 0;

	omap_dma_unlink_lch(prtd->dma_ch, prtd->dma_ch);
	omap_free_dma(prtd->dma_ch);
	prtd->dma_data = NULL;

	snd_pcm_set_runtime_buffer(substream, NULL);

	return 0;
}
示例#27
0
static void omap_mmc_rx_dma_callback (void *data, int size)
{

        memcpy(g_omap_mmc_data.request->buffer, g_omap_mmc_data.buf_dma_virt,
               g_omap_mmc_data.request->block_len);

        omap_free_dma(g_omap_mmc_data.dma_regs);
        g_omap_mmc_data.dma_regs = NULL;

        g_omap_mmc_data.request->buffer +=  g_omap_mmc_data.request->block_len;

	DEBUG(3,": RX Transfer finished\n");

        g_omap_mmc_data.request->nob--;

        omap_mmc_handle_int( &g_omap_mmc_data, inw(OMAP_MMC_STAT));
}
示例#28
0
/*
 * DMA call back function
 */
static void mmc_omap_dma_cb(int lch, u16 ch_status, void *data)
{
	struct mmc_omap_host *host = data;

	if (ch_status & OMAP2_DMA_MISALIGNED_ERR_IRQ)
		dev_dbg(mmc_dev(host->mmc), "MISALIGNED_ADRS_ERR\n");

	if (host->dma_ch < 0)
		return;

	omap_free_dma(host->dma_ch);
	host->dma_ch = -1;
	/*
	 * DMA Callback: run in interrupt context.
	 * mutex_unlock will through a kernel warning if used.
	 */
	up(&host->sem);
}
示例#29
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;
	}
}
示例#30
0
文件: omap2.c 项目: 03199618/linux
static int omap2_onenand_remove(struct platform_device *pdev)
{
	struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);

	onenand_release(&c->mtd);
	regulator_put(c->regulator);
	if (c->dma_channel != -1)
		omap_free_dma(c->dma_channel);
	omap2_onenand_shutdown(pdev);
	if (c->gpio_irq) {
		free_irq(gpio_to_irq(c->gpio_irq), c);
		gpio_free(c->gpio_irq);
	}
	iounmap(c->onenand.base);
	release_mem_region(c->phys_base, c->mem_size);
	kfree(c);

	return 0;
}