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); }
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); }
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; }
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); }
/** * @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 }
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 && 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); }
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; } }
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_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); } }
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)); }
/* * 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; }
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; }
/* * 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; }
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; }
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; }
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; }
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)); }
/* * 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); }
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; } }
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; }