static void musb_sysdma_completion(int lch, u16 ch_status, void *data) { u32 addr; unsigned long flags; struct dma_channel *channel; struct musb_dma_channel *musb_channel = (struct musb_dma_channel *) data; struct musb_dma_controller *controller = musb_channel->controller; struct musb *musb = controller->private_data; channel = &musb_channel->channel; DBG(2, "lch = 0x%d, ch_status = 0x%x\n", lch, ch_status); spin_lock_irqsave(&musb->lock, flags); addr = (u32) omap_get_dma_dst_pos(musb_channel->sysdma_channel); if (musb_channel->len == 0) channel->actual_len = 0; else channel->actual_len = addr - musb_channel->start_addr; DBG(2, "ch %p, 0x%x -> 0x%x (%d / %d) %s\n", channel, musb_channel->start_addr, addr, channel->actual_len, musb_channel->len, (channel->actual_len < musb_channel->len) ? "=> reconfig 0 " : " => complete"); channel->status = MUSB_DMA_STATUS_FREE; musb_dma_completion(musb, musb_channel->epnum, musb_channel->transmit); spin_unlock_irqrestore(&musb->lock, flags); return; }
/* * 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); }
static void musb_sysdma_completion(int lch, u16 ch_status, void *data) { u32 addr; unsigned long flags; struct dma_channel *channel; struct musb_dma_channel *musb_channel = (struct musb_dma_channel *) data; struct musb_dma_controller *controller = musb_channel->controller; struct musb *musb = controller->private_data; void __iomem *mbase = controller->base; channel = &musb_channel->channel; DBG(2, "lch = 0x%d, ch_status = 0x%x\n", lch, ch_status); spin_lock_irqsave(&musb->lock, flags); if (musb_channel->transmit) addr = (u32) omap_get_dma_src_pos(musb_channel->sysdma_channel); else addr = (u32) omap_get_dma_dst_pos(musb_channel->sysdma_channel); if (musb_channel->len == 0) channel->actual_len = 0; else channel->actual_len = addr - musb_channel->start_addr; DBG(2, "ch %p, 0x%x -> 0x%x (%d / %d) %s\n", channel, musb_channel->start_addr, addr, channel->actual_len, musb_channel->len, (channel->actual_len < musb_channel->len) ? "=> reconfig 0 " : " => complete"); channel->status = MUSB_DMA_STATUS_FREE; /* completed */ if ((musb_channel->transmit) && (channel->desired_mode == 0) && (channel->actual_len == musb_channel->max_packet_sz)) { u8 epnum = musb_channel->epnum; int offset = MUSB_EP_OFFSET(musb, epnum, MUSB_TXCSR); u16 txcsr; /* * The programming guide says that we * must clear DMAENAB before DMAMODE. */ musb_ep_select(musb, mbase, epnum); txcsr = musb_readw(mbase, offset); txcsr |= MUSB_TXCSR_TXPKTRDY; musb_writew(mbase, offset, txcsr); } musb_dma_completion(musb, musb_channel->epnum, musb_channel->transmit); spin_unlock_irqrestore(&musb->lock, flags); return; }
static void serial_omap_rxdma_poll(unsigned long uart_no) { struct uart_omap_port *up = ui[uart_no]; unsigned int curr_dma_pos, curr_transmitted_size; int ret = 0; curr_dma_pos = omap_get_dma_dst_pos(up->uart_dma.rx_dma_channel); if ((curr_dma_pos == up->uart_dma.prev_rx_dma_pos) || (curr_dma_pos == 0)) { if (jiffies_to_msecs(jiffies - up->port_activity) < up->uart_dma.rx_timeout) { mod_timer(&up->uart_dma.rx_timer, jiffies + usecs_to_jiffies(up->uart_dma.rx_poll_rate)); } else { serial_omap_stop_rxdma(up); up->ier |= (UART_IER_RDI | UART_IER_RLSI); serial_out(up, UART_IER, up->ier); } return; } curr_transmitted_size = curr_dma_pos - up->uart_dma.prev_rx_dma_pos; up->port.icount.rx += curr_transmitted_size; tty_insert_flip_string(up->port.state->port.tty, up->uart_dma.rx_buf + (up->uart_dma.prev_rx_dma_pos - up->uart_dma.rx_buf_dma_phys), curr_transmitted_size); tty_flip_buffer_push(up->port.state->port.tty); up->uart_dma.prev_rx_dma_pos = curr_dma_pos; if (up->uart_dma.rx_buf_size + up->uart_dma.rx_buf_dma_phys == curr_dma_pos) { ret = serial_omap_start_rxdma(up); if (ret < 0) { serial_omap_stop_rxdma(up); up->ier |= (UART_IER_RDI | UART_IER_RLSI); serial_out(up, UART_IER, up->ier); } } else { mod_timer(&up->uart_dma.rx_timer, jiffies + usecs_to_jiffies(up->uart_dma.rx_poll_rate)); } up->port_activity = jiffies; }
static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct omap_runtime_data *prtd = runtime->private_data; dma_addr_t ptr; snd_pcm_uframes_t offset; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ptr = omap_get_dma_src_pos(prtd->dma_ch); else ptr = omap_get_dma_dst_pos(prtd->dma_ch); offset = bytes_to_frames(runtime, ptr - runtime->dma_addr); if (offset >= runtime->buffer_size) offset = 0; return offset; }
static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct omap_runtime_data *prtd = runtime->private_data; dma_addr_t ptr; snd_pcm_uframes_t offset; if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { ptr = omap_get_dma_dst_pos(prtd->dma_ch); offset = bytes_to_frames(runtime, ptr - runtime->dma_addr); } else if (!(cpu_is_omap1510())) { ptr = omap_get_dma_src_pos(prtd->dma_ch); offset = bytes_to_frames(runtime, ptr - runtime->dma_addr); } else offset = prtd->period_index * runtime->period_size; if (offset >= runtime->buffer_size) offset = 0; return offset; }
static int abe_dbg_get_dma_pos(struct omap_abe *abe) { return omap_get_dma_dst_pos(abe->debugfs.dma_ch) - abe->debugfs.buffer_addr; }