static void tegra_uart_handle_rx_dma(struct tegra_uart_port *tup, unsigned long *flags) { struct dma_tx_state state; struct tty_struct *tty = tty_port_tty_get(&tup->uport.state->port); struct tty_port *port = &tup->uport.state->port; struct uart_port *u = &tup->uport; int count; /* Deactivate flow control to stop sender */ if (tup->rts_active) set_rts(tup, false); dmaengine_terminate_all(tup->rx_dma_chan); dmaengine_tx_status(tup->rx_dma_chan, tup->rx_cookie, &state); async_tx_ack(tup->rx_dma_desc); count = tup->rx_bytes_requested - state.residue; /* If we are here, DMA is stopped */ if (count) tegra_uart_copy_rx_to_tty(tup, port, count); tegra_uart_handle_rx_pio(tup, port); if (tty) { spin_unlock_irqrestore(&u->lock, *flags); tty_flip_buffer_push(port); spin_lock_irqsave(&u->lock, *flags); tty_kref_put(tty); } tegra_uart_start_rx_dma(tup); if (tup->rts_active) set_rts(tup, true); }
/* Set the modem control signals state of uart controller. */ void tegra_uart_set_mctrl(struct uart_port *uport, unsigned int mctrl) { unsigned long flags; struct tegra_uart_port *t; t = container_of(uport, struct tegra_uart_port, uport); if (t->uart_state != TEGRA_UART_OPENED) { dev_err(t->uport.dev, "Uart is in invalid state\n"); return; } spin_lock_irqsave(&uport->lock, flags); if (mctrl & TIOCM_RTS) { t->rts_active = true; set_rts(t, true); } else { t->rts_active = false; set_rts(t, false); } if (mctrl & TIOCM_DTR) set_dtr(t, true); else set_dtr(t, false); spin_unlock_irqrestore(&uport->lock, flags); return; }
static void tegra_uart_rx_dma_complete(void *args) { struct tegra_uart_port *tup = args; struct uart_port *u = &tup->uport; int count = tup->rx_bytes_requested; struct tty_struct *tty = tty_port_tty_get(&tup->uport.state->port); struct tty_port *port = &u->state->port; unsigned long flags; async_tx_ack(tup->rx_dma_desc); spin_lock_irqsave(&u->lock, flags); /* Deactivate flow control to stop sender */ if (tup->rts_active) set_rts(tup, false); /* If we are here, DMA is stopped */ if (count) tegra_uart_copy_rx_to_tty(tup, port, count); tegra_uart_handle_rx_pio(tup, port); if (tty) { spin_unlock_irqrestore(&u->lock, flags); tty_flip_buffer_push(port); spin_lock_irqsave(&u->lock, flags); tty_kref_put(tty); } tegra_uart_start_rx_dma(tup); /* Activate flow control to start transfer */ if (tup->rts_active) set_rts(tup, true); spin_unlock_irqrestore(&u->lock, flags); }
static void tegra_uart_rx_dma_complete(void *args) { struct tegra_uart_port *tup = args; struct uart_port *u = &tup->uport; unsigned long flags; struct dma_tx_state state; enum dma_status status; spin_lock_irqsave(&u->lock, flags); status = dmaengine_tx_status(tup->rx_dma_chan, tup->rx_cookie, &state); if (status == DMA_IN_PROGRESS) { dev_dbg(tup->uport.dev, "RX DMA is in progress\n"); goto done; } /* Deactivate flow control to stop sender */ if (tup->rts_active) set_rts(tup, false); tegra_uart_rx_buffer_push(tup, 0); tegra_uart_start_rx_dma(tup); /* Activate flow control to start transfer */ if (tup->rts_active) set_rts(tup, true); done: spin_unlock_irqrestore(&u->lock, flags); }
static void tegra_uart_rx_dma_complete(void *args) { struct tegra_uart_port *tup = args; struct uart_port *u = &tup->uport; int count = tup->rx_bytes_requested; struct tty_struct *tty = tty_port_tty_get(&tup->uport.state->port); struct tty_port *port = &u->state->port; unsigned long flags; int rx_level = 0; struct dma_tx_state state; enum dma_status status; spin_lock_irqsave(&u->lock, flags); async_tx_ack(tup->rx_dma_desc); status = dmaengine_tx_status(tup->rx_dma_chan, tup->rx_cookie, &state); if (status == DMA_IN_PROGRESS) { dev_info(tup->uport.dev, "RX DMA is in progress\n"); goto done; } /* Deactivate flow control to stop sender */ if (tup->rts_active) set_rts(tup, false); /* If we are here, DMA is stopped */ if (count) tegra_uart_copy_rx_to_tty(tup, port, count); tegra_uart_handle_rx_pio(tup, port); if (tup->enable_rx_buffer_throttle) { rx_level = tty_buffer_get_level(port); if (rx_level > 70) mod_timer(&tup->timer, jiffies + tup->timer_timeout_jiffies); } if (tty) { tty_flip_buffer_push(port); tty_kref_put(tty); } tegra_uart_start_rx_dma(tup); /* Activate flow control to start transfer */ if (tup->enable_rx_buffer_throttle) { if ((rx_level <= 70) && tup->rts_active) set_rts(tup, true); } else if (tup->rts_active) set_rts(tup, true); done: spin_unlock_irqrestore(&u->lock, flags); }
/* Lock already taken */ static void do_handle_rx_dma(struct tegra_uart_port *t) { struct uart_port *u = &t->uport; if (t->rts_active) set_rts(t, false); tegra_dma_dequeue_req(t->rx_dma, &t->rx_dma_req); tty_flip_buffer_push(u->state->port.tty); /* enqueue the request again */ tegra_start_dma_rx(t); if (t->rts_active) set_rts(t, true); }
void tms9902_device::initiate_transmit() { if (m_BRKON && m_CTSin) /* enter break mode */ send_break(true); else { if (!m_RTSON && (!m_CTSin || (m_XBRE && !m_BRKout))) /* clear RTS output */ set_rts(CLEAR_LINE); else { if (VERBOSE>5) LOG("TMS9902: transferring XBR to XSR; XSRE=false, XBRE=true\n"); m_XSR = m_XBR; m_XSRE = false; m_XBRE = true; field_interrupts(); if (VERBOSE>4) LOG("TMS9902: transmit XSR=%02x, RCL=%02x\n", m_XSR, m_RCL); xmit_callback(0, m_XSR & (0xff >> (3-m_RCL))); // Should store that somewhere (but the CPU is fast enough, can afford to recalc :-) ) double fint = m_clock_rate / ((m_CLK4M) ? 4.0 : 3.0); double baud = fint / (2.0 * ((m_RDV8)? 8:1) * m_RDR); // Time for transmitting 10 bit (8 bit + start + stop) m_sendtimer->adjust(attotime::from_hz(baud/10.0)); } } }
static void tegra_uart_handle_rx_dma(struct tegra_uart_port *tup) { struct dma_tx_state state; /* Deactivate flow control to stop sender */ if (tup->rts_active) set_rts(tup, false); dmaengine_terminate_all(tup->rx_dma_chan); dmaengine_tx_status(tup->rx_dma_chan, tup->rx_cookie, &state); tegra_uart_rx_buffer_push(tup, state.residue); tegra_uart_start_rx_dma(tup); if (tup->rts_active) set_rts(tup, true); }
//------------------------------------------------- // reset - reset channel status //------------------------------------------------- void z80sio_channel::device_reset() { LOG("%s\n", FUNCNAME); // Reset RS232 emulation receive_register_reset(); transmit_register_reset(); // disable receiver m_wr3 &= ~WR3_RX_ENABLE; // disable transmitter m_wr5 &= ~WR5_TX_ENABLE; m_rr0 |= RR0_TX_BUFFER_EMPTY; m_rr1 |= RR1_ALL_SENT; // reset external lines set_rts(1); set_dtr(1); // reset interrupts if (m_index == z80sio_device::CHANNEL_A) { m_uart->reset_interrupts(); } }
static void tegra_start_rx(struct uart_port *u) { struct tegra_uart_port *t; unsigned char ier; t = container_of(u, struct tegra_uart_port, uport); if (t->rts_active) set_rts(t, true); if (!t->rx_in_progress) { wait_sym_time(t, 1); /* wait a character interval */ /* Clear the received Bytes from FIFO */ tegra_fifo_reset(t, UART_FCR_CLEAR_RCVR); uart_readb(t, UART_LSR); ier = 0; ier |= (UART_IER_RLSI | UART_IER_RTOIE); if (t->use_rx_dma) ier |= UART_IER_EORD; else ier |= UART_IER_RDI; t->ier_shadow |= ier; uart_writeb(t, t->ier_shadow, UART_IER); t->rx_in_progress = 1; if (t->use_rx_dma && t->rx_dma) tegra_dma_enqueue_req(t->rx_dma, &t->rx_dma_req); tty_flip_buffer_push(u->state->port.tty); } return; }
static void tegra_stop_rx(struct uart_port *u) { struct tegra_uart_port *t; unsigned char ier; t = container_of(u, struct tegra_uart_port, uport); if (t->rts_active) set_rts(t, false); if (t->rx_in_progress) { wait_sym_time(t, 1); /* wait a character interval */ ier = t->ier_shadow; ier &= ~(UART_IER_RDI | UART_IER_RLSI | UART_IER_RTOIE | UART_IER_EORD); t->ier_shadow = ier; uart_writeb(t, ier, UART_IER); t->rx_in_progress = 0; if (t->use_rx_dma && t->rx_dma) tegra_dma_dequeue_req(t->rx_dma, &t->rx_dma_req); else do_handle_rx_pio(t); tty_flip_buffer_push(u->state->port.tty); } return; }
RBAPI(bool) com_Send(int com, unsigned char* buf, int bsize) { unsigned long nowtime; int numbytes = 0, bsize2; if (COM_duplex[com] == COM_HDUPLEX_RTS) { MPOS_Start(); set_rts(com); } while (bsize > 0) { bsize2 = (bsize <= MAXRWSIZE)? bsize : MAXRWSIZE; for (nowtime = timer_nowtime(); bsize2 > 0; buf += numbytes, bsize2 -= numbytes, bsize -= numbytes) { #if defined(RB_MSVC_WIN32) || defined(RB_MSVC_WINCE) if (WriteFile(COM_info[com].fp, buf, bsize2, (LPDWORD)&numbytes, NULL) == FALSE) { err_SetMsg(ERROR_COM_SENDFAIL, "WriteFile() fails"); goto SEND_FAIL; } #elif defined(RB_LINUX) if ((numbytes = write(COM_info[com].fp, buf, bsize2)) < 0) { err_SetMsg(ERROR_COM_SENDFAIL, "write() fails"); goto SEND_FAIL; } #else // TODO ... err_SetMsg(ERROR_COM_INVALID, "unsupported platform"); goto SEND_FAIL; #endif if ((timer_nowtime() - nowtime) > COM_TIMEOUT) { err_SetMsg(ERROR_COM_SENDFAIL, "time-out to write bytes"); goto SEND_FAIL; } } // for (nowtime... } // end while (bsize... if (COM_duplex[com] == COM_HDUPLEX_RTS) { com_FlushWFIFO(com); clear_rts(com); MPOS_End(); } return true; SEND_FAIL: if (COM_duplex[com] == COM_HDUPLEX_RTS) { clear_rts(com); MPOS_End(); } return false; }
/* * Called by the upper tty layer when the tty buffers are almost full. * The driver should stop send more data. */ static void ntty_throttle(struct tty_struct *tty) { struct nozomi *dc = get_dc_by_tty(tty); unsigned long flags; DBG1("THROTTLE"); spin_lock_irqsave(&dc->spin_mutex, flags); set_rts(tty, 0); spin_unlock_irqrestore(&dc->spin_mutex, flags); }
static void tegra_uart_handle_rx_dma(struct tegra_uart_port *tup) { struct dma_tx_state state; struct tty_struct *tty = tty_port_tty_get(&tup->uport.state->port); struct tty_port *port = &tup->uport.state->port; int count; int rx_level = 0; /* Deactivate flow control to stop sender */ if (tup->rts_active) set_rts(tup, false); dmaengine_terminate_all(tup->rx_dma_chan); dmaengine_tx_status(tup->rx_dma_chan, tup->rx_cookie, &state); async_tx_ack(tup->rx_dma_desc); count = tup->rx_bytes_requested - state.residue; /* If we are here, DMA is stopped */ if (count) tegra_uart_copy_rx_to_tty(tup, port, count); tegra_uart_handle_rx_pio(tup, port); if (tup->enable_rx_buffer_throttle) { rx_level = tty_buffer_get_level(port); if (rx_level > 70) mod_timer(&tup->timer, jiffies + tup->timer_timeout_jiffies); } if (tty) { tty_flip_buffer_push(port); tty_kref_put(tty); } tegra_uart_start_rx_dma(tup); if (tup->enable_rx_buffer_throttle) { if ((rx_level <= 70) && tup->rts_active) set_rts(tup, true); } else if (tup->rts_active) set_rts(tup, true); }
/* Sets io controls parameters */ static int ntty_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct nozomi *dc = get_dc_by_tty(tty); unsigned long flags; spin_lock_irqsave(&dc->spin_mutex, flags); if (set & TIOCM_RTS) set_rts(tty, 1); else if (clear & TIOCM_RTS) set_rts(tty, 0); if (set & TIOCM_DTR) set_dtr(tty, 1); else if (clear & TIOCM_DTR) set_dtr(tty, 0); spin_unlock_irqrestore(&dc->spin_mutex, flags); return 0; }
static void tegra_uart_set_mctrl(struct uart_port *u, unsigned int mctrl) { struct tegra_uart_port *tup = to_tegra_uport(u); int dtr_enable; tup->rts_active = !!(mctrl & TIOCM_RTS); set_rts(tup, tup->rts_active); dtr_enable = !!(mctrl & TIOCM_DTR); set_dtr(tup, dtr_enable); }
/* * Called by the upper tty layer when tty buffers are ready * to receive data again after a call to throttle. */ static void ntty_unthrottle(struct tty_struct *tty) { struct nozomi *dc = get_dc_by_tty(tty); unsigned long flags; DBG1("UNTHROTTLE"); spin_lock_irqsave(&dc->spin_mutex, flags); enable_transmit_dl(tty->index % MAX_PORT, dc); set_rts(tty, 1); spin_unlock_irqrestore(&dc->spin_mutex, flags); }
/* Set the modem control signals state of uart controller. */ void tegra_uart_set_mctrl(struct uart_port *uport, unsigned int mctrl) { unsigned long flags; struct tegra_uart_port *t; t = container_of(uport, struct tegra_uart_port, uport); spin_lock_irqsave(&uport->lock, flags); if (mctrl & TIOCM_RTS) { t->rts_active = true; set_rts(t, true); } else { t->rts_active = false; set_rts(t, false); } if (mctrl & TIOCM_DTR) set_dtr(t, true); else set_dtr(t, false); spin_unlock_irqrestore(&uport->lock, flags); return; }
void tms9902_device::reset_uart() { logerror("resetting UART\n"); /* disable all interrupts */ m_DSCENB = false; // Data Set Change Interrupt Enable m_TIMENB = false; // Timer Interrupt Enable m_XBIENB = false; // Transmit Buffer Interrupt Enable m_RIENB = false; // Read Buffer Interrupt Enable /* initialize transmitter */ m_XBRE = true; // Transmit Buffer Register Empty m_XSRE = true; // Transmit Shift Register Empty /* initialize receiver */ m_RBRL = false; // Read Buffer Register Loaded /* clear RTS */ m_RTSON = false; // Request-to-send on (flag) m_RTSout = true; // Note we are doing this to ensure the state is sent to the interface set_rts(CLEAR_LINE); m_RTSout = false; // what we actually want /* set all register load flags to 1 */ m_LDCTRL = true; m_LDIR = true; m_LRDR = true; m_LXDR = true; /* clear break condition */ m_BRKON = false; m_BRKout = false; m_DSCH = false; m_TIMELP = false; // m_CTSin = false; // not a good idea - this is the latch of an incoming line m_TMR = 0; m_STOPB = 0; m_RCL = 0; m_XDR = 0; m_RDR = 0; m_RBR = 0; m_XBR = 0; m_XSR = 0; // m_INT will be cleared in field_interrupts; setting to true is required // to trigger the INT line update m_INT = true; field_interrupts(); }
static void tegra_set_mctrl(struct uart_port *u, unsigned int mctrl) { unsigned char mcr; struct tegra_uart_port *t; dev_dbg(u->dev, "tegra_set_mctrl called with %d\n", mctrl); t = container_of(u, struct tegra_uart_port, uport); mcr = t->mcr_shadow; if (mctrl & TIOCM_RTS) { t->rts_active = true; set_rts(t, true); } else { t->rts_active = false; set_rts(t, false); } if (mctrl & TIOCM_DTR) set_dtr(t, true); else set_dtr(t, false); return; }
void tms9902_device::reset_uart() { if (VERBOSE>1) LOG("TMS9902: resetting\n"); /* disable all interrupts */ m_DSCENB = false; // Data Set Change Interrupt Enable m_TIMENB = false; // Timer Interrupt Enable m_XBIENB = false; // Transmit Buffer Interrupt Enable m_RIENB = false; // Read Buffer Interrupt Enable /* initialize transmitter */ m_XBRE = true; // Transmit Buffer Register Empty m_XSRE = true; // Transmit Shift Register Empty /* initialize receiver */ m_RBRL = false; // Read Buffer Register Loaded /* clear RTS */ m_RTSON = false; // Request-to-send on (flag) m_RTSout = true; // Note we are doing this to ensure the state is sent to the interface set_rts(CLEAR_LINE); m_RTSout = false; // what we actually want /* set all register load flags to 1 */ m_LDCTRL = true; m_LDIR = true; m_LRDR = true; m_LXDR = true; /* clear break condition */ m_BRKON = false; m_BRKout = false; m_DSCH = false; m_TIMELP = false; m_INT = false; m_CTSin = false; m_TMR = 0; m_STOPB = 0; m_RCL = 0; m_XDR = 0; m_RDR = 0; m_RBR = 0; m_XBR = 0; m_XSR = 0; // m_INT will be cleared in field_interrupts field_interrupts(); }
static void tegra_uart_set_mctrl(struct uart_port *u, unsigned int mctrl) { struct tegra_uart_port *tup = to_tegra_uport(u); unsigned long mcr; int dtr_enable; mcr = tup->mcr_shadow; tup->rts_active = !!(mctrl & TIOCM_RTS); set_rts(tup, tup->rts_active); dtr_enable = !!(mctrl & TIOCM_DTR); set_dtr(tup, dtr_enable); return; }
//------------------------------------------------- // tra_complete - //------------------------------------------------- void z80sio_channel::tra_complete() { LOG("%s %s\n",FUNCNAME, tag()); if ((m_wr5 & WR5_TX_ENABLE) && !(m_wr5 & WR5_SEND_BREAK) && !(m_rr0 & RR0_TX_BUFFER_EMPTY)) { LOG("%s() \"%s \"Channel %c Transmit Data Byte '%02x' m_wr5:%02x\n", FUNCNAME, m_owner->tag(), 'A' + m_index, m_tx_data, m_wr5); transmit_register_setup(m_tx_data); // empty transmit buffer m_rr0 |= RR0_TX_BUFFER_EMPTY; if (m_wr1 & WR1_TX_INT_ENABLE) m_uart->trigger_interrupt(m_index, INT_TRANSMIT); } else if (m_wr5 & WR5_SEND_BREAK) { LOG("%s() \"%s \"Channel %c Transmit Break 0 m_wr5:%02x\n", FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5); // transmit break if (m_index == z80sio_device::CHANNEL_A) m_uart->m_out_txda_cb(0); else m_uart->m_out_txdb_cb(0); } else { LOG("%s() \"%s \"Channel %c Transmit Mark 1 m_wr5:%02x\n", FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5); // transmit mark if (m_index == z80sio_device::CHANNEL_A) m_uart->m_out_txda_cb(1); else m_uart->m_out_txdb_cb(1); } // if transmit buffer is empty if (m_rr0 & RR0_TX_BUFFER_EMPTY) { LOG("%s() \"%s \"Channel %c Transmit buffer empty m_wr5:%02x\n", FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5); // then all characters have been sent m_rr1 |= RR1_ALL_SENT; // when the RTS bit is reset, the _RTS output goes high after the transmitter empties if (!m_rts) set_rts(1); } }
void z80sio_channel::update_rts() { // LOG("%s(%d) \"%s\" Channel %c \n", FUNCNAME, state, m_owner->tag(), 'A' + m_index); LOG("%s() \"%s\" Channel %c \n", FUNCNAME, m_owner->tag(), 'A' + m_index); if (m_wr5 & WR5_RTS) { // when the RTS bit is set, the _RTS output goes low set_rts(0); m_rts = 1; } else { // when the RTS bit is reset, the _RTS output goes high after the transmitter empties m_rts = 0; } // data terminal ready output follows the state programmed into the DTR bit*/ set_dtr((m_wr5 & WR5_DTR) ? 0 : 1); }
static void tegra_uart_stop_rx(struct uart_port *u) { struct tegra_uart_port *tup = to_tegra_uport(u); struct tty_struct *tty; struct tty_port *port = &u->state->port; struct dma_tx_state state; unsigned long ier; int count; if (tup->rts_active) set_rts(tup, false); if (!tup->rx_in_progress) return; tty = tty_port_tty_get(&tup->uport.state->port); tegra_uart_wait_sym_time(tup, 1); /* wait a character interval */ ier = tup->ier_shadow; ier &= ~(UART_IER_RDI | UART_IER_RLSI | UART_IER_RTOIE | TEGRA_UART_IER_EORD); tup->ier_shadow = ier; tegra_uart_write(tup, ier, UART_IER); tup->rx_in_progress = 0; if (tup->rx_dma_chan && !tup->use_rx_pio) { dmaengine_terminate_all(tup->rx_dma_chan); dmaengine_tx_status(tup->rx_dma_chan, tup->rx_cookie, &state); async_tx_ack(tup->rx_dma_desc); count = tup->rx_bytes_requested - state.residue; if (count) tegra_uart_copy_rx_to_tty(tup, port, count); tegra_uart_handle_rx_pio(tup, port); } else { tegra_uart_handle_rx_pio(tup, port); } if (tty) { tty_flip_buffer_push(port); tty_kref_put(tty); } return; }
void z80dart_channel::tra_complete() { if ((m_wr[5] & WR5_TX_ENABLE) && !(m_wr[5] & WR5_SEND_BREAK) && !(m_rr[0] & RR0_TX_BUFFER_EMPTY)) { LOG(("Z80DART \"%s\" Channel %c : Transmit Data Byte '%02x'\n", m_owner->tag(), 'A' + m_index, m_tx_data)); transmit_register_setup(m_tx_data); // empty transmit buffer m_rr[0] |= RR0_TX_BUFFER_EMPTY; if (m_wr[1] & WR1_TX_INT_ENABLE) m_uart->trigger_interrupt(m_index, INT_TRANSMIT); } else if (m_wr[5] & WR5_SEND_BREAK) { // transmit break if (m_index == z80dart_device::CHANNEL_A) m_uart->m_out_txda_cb(0); else m_uart->m_out_txdb_cb(0); } else { // transmit mark if (m_index == z80dart_device::CHANNEL_A) m_uart->m_out_txda_cb(1); else m_uart->m_out_txdb_cb(1); } // if transmit buffer is empty if (m_rr[0] & RR0_TX_BUFFER_EMPTY) { // then all characters have been sent m_rr[1] |= RR1_ALL_SENT; // when the RTS bit is reset, the _RTS output goes high after the transmitter empties if (!m_rts) set_rts(1); } }
void z80dart_channel::device_reset() { receive_register_reset(); transmit_register_reset(); // disable receiver m_wr[3] &= ~WR3_RX_ENABLE; // disable transmitter m_wr[5] &= ~WR5_TX_ENABLE; m_rr[0] |= RR0_TX_BUFFER_EMPTY; // reset external lines set_rts(1); set_dtr(1); // reset interrupts if (m_index == z80dart_device::CHANNEL_A) { m_uart->reset_interrupts(); } }
static void tegra_uart_rx_buffer_throttle_timer(unsigned long _data) { struct tegra_uart_port *tup = (struct tegra_uart_port *)_data; struct uart_port *u = &tup->uport; struct tty_struct *tty = tty_port_tty_get(&tup->uport.state->port); struct tty_port *port = &tup->uport.state->port; int rx_level; unsigned long flags; spin_lock_irqsave(&u->lock, flags); rx_level = tty_buffer_get_level(port); if (rx_level < 30) { if (tup->rts_active) set_rts(tup, true); } else { mod_timer(&tup->timer, jiffies + tup->timer_timeout_jiffies); } if (tty) tty_kref_put(tty); spin_unlock_irqrestore(&u->lock, flags); }
static void tegra_uart_stop_rx(struct uart_port *u) { struct tegra_uart_port *tup = to_tegra_uport(u); struct dma_tx_state state; unsigned long ier; if (tup->rts_active) set_rts(tup, false); if (!tup->rx_in_progress) return; tegra_uart_wait_sym_time(tup, 1); /* wait a character interval */ ier = tup->ier_shadow; ier &= ~(UART_IER_RDI | UART_IER_RLSI | UART_IER_RTOIE | TEGRA_UART_IER_EORD); tup->ier_shadow = ier; tegra_uart_write(tup, ier, UART_IER); tup->rx_in_progress = 0; dmaengine_terminate_all(tup->rx_dma_chan); dmaengine_tx_status(tup->rx_dma_chan, tup->rx_cookie, &state); tegra_uart_rx_buffer_push(tup, state.residue); }
static void tegra_set_termios(struct uart_port *u, struct ktermios *termios, struct ktermios *oldtermios) { struct tegra_uart_port *t; unsigned int baud; unsigned long flags; unsigned int lcr; unsigned int c_cflag = termios->c_cflag; unsigned char mcr; t = container_of(u, struct tegra_uart_port, uport); dev_vdbg(t->uport.dev, "+tegra_set_termios\n"); spin_lock_irqsave(&u->lock, flags); /* Changing configuration, it is safe to stop any rx now */ if (t->rts_active) set_rts(t, false); /* Clear all interrupts as configuration is going to be change */ uart_writeb(t, t->ier_shadow | UART_IER_RDI, UART_IER); uart_readb(t, UART_IER); uart_writeb(t, 0, UART_IER); uart_readb(t, UART_IER); /* Parity */ lcr = t->lcr_shadow; lcr &= ~UART_LCR_PARITY; if (PARENB == (c_cflag & PARENB)) { if (CMSPAR == (c_cflag & CMSPAR)) { /* FIXME What is space parity? */ /* data |= SPACE_PARITY; */ } else if (c_cflag & PARODD) { lcr |= UART_LCR_PARITY; lcr &= ~UART_LCR_EPAR; lcr &= ~UART_LCR_SPAR; } else { lcr |= UART_LCR_PARITY; lcr |= UART_LCR_EPAR; lcr &= ~UART_LCR_SPAR; } } lcr &= ~UART_LCR_WLEN8; switch (c_cflag & CSIZE) { case CS5: lcr |= UART_LCR_WLEN5; break; case CS6: lcr |= UART_LCR_WLEN6; break; case CS7: lcr |= UART_LCR_WLEN7; break; default: lcr |= UART_LCR_WLEN8; break; } /* Stop bits */ if (termios->c_cflag & CSTOPB) lcr |= UART_LCR_STOP; else lcr &= ~UART_LCR_STOP; uart_writeb(t, lcr, UART_LCR); t->lcr_shadow = lcr; /* Baud rate. */ baud = uart_get_baud_rate(u, termios, oldtermios, 200, 4000000); spin_unlock_irqrestore(&u->lock, flags); tegra_set_baudrate(t, baud); spin_lock_irqsave(&u->lock, flags); /* Flow control */ if (termios->c_cflag & CRTSCTS) { mcr = t->mcr_shadow; mcr |= UART_MCR_CTS_EN; mcr &= ~UART_MCR_RTS_EN; t->mcr_shadow = mcr; uart_writeb(t, mcr, UART_MCR); t->use_cts_control = true; /* if top layer has asked to set rts active then do so here */ if (t->rts_active) set_rts(t, true); } else { mcr = t->mcr_shadow; mcr &= ~UART_MCR_CTS_EN; mcr &= ~UART_MCR_RTS_EN; t->mcr_shadow = mcr; uart_writeb(t, mcr, UART_MCR); t->use_cts_control = false; } /* update the port timeout based on new settings */ uart_update_timeout(u, termios->c_cflag, baud); /* Make sure all write has completed */ uart_readb(t, UART_IER); /* Reenable interrupt */ uart_writeb(t, t->ier_shadow, UART_IER); uart_readb(t, UART_IER); spin_unlock_irqrestore(&u->lock, flags); dev_vdbg(t->uport.dev, "-tegra_set_termios\n"); return; }