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