static void serial_omap_rx_timeout(unsigned long uart_no) { struct uart_omap_port *up = ui[uart_no - 1]; unsigned int curr_dma_pos; curr_dma_pos = omap_readl(OMAP34XX_DMA4_BASE + OMAP_DMA4_CDAC(up->uart_dma.rx_dma_channel)); if ((curr_dma_pos == up->uart_dma.prev_rx_dma_pos) || (curr_dma_pos == 0)) { /* * If there is no transfer rx happening for 10sec then stop the dma * else just restart the timer. See if 10 sec can be improved. */ if (jiffies_to_msecs(jiffies - isr8250_activity) < 10000) mod_timer(&up->uart_dma.rx_timer, jiffies + usecs_to_jiffies(up->uart_dma.rx_timeout)); else { del_timer(&up->uart_dma.rx_timer); serial_omap_stop_rxdma(up); up->ier |= UART_IER_RDI; serial_out(up, UART_IER, up->ier); } return; } else { unsigned int 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); queue_work(omap_serial_workqueue, &up->tty_work); 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) { serial_omap_start_rxdma(up); } else mod_timer(&up->uart_dma.rx_timer, jiffies + usecs_to_jiffies(up->uart_dma.rx_timeout)); isr8250_activity = jiffies; } }
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 void serial_omap_stop_rx(struct uart_port *port) { struct uart_omap_port *up = (struct uart_omap_port *)port; serial_omap_stop_rxdma(up); up->ier &= ~UART_IER_RLSI; up->port.read_status_mask &= ~UART_LSR_DR; serial_out(up, UART_IER, up->ier); }
static void serial_omap_stop_rx(struct uart_port *port) { struct uart_omap_port *up = (struct uart_omap_port *)port; pm_runtime_get_sync(&up->pdev->dev); if (up->use_dma) serial_omap_stop_rxdma(up); up->ier &= ~UART_IER_RLSI; up->port.read_status_mask &= ~UART_LSR_DR; serial_out(up, UART_IER, up->ier); pm_runtime_mark_last_busy(&up->pdev->dev); pm_runtime_put_autosuspend(&up->pdev->dev); }
/** * are_driver8250_uarts_active() - Check if any ports managed by this * driver are currently busy. This should be called with interrupts * disabled. */ int are_driveromap_uarts_active(int num) { struct circ_buf *xmit; unsigned int status; struct uart_omap_port *up = ui[num]; if (!up) return 0; /* check ownership of port */ /* Check only ports managed by this driver and open */ if ((up->port.dev == NULL) || (up->port.type == PORT_UNKNOWN)) return 0; /* driver owns this port but it's closed */ if (up->port.state == NULL) return 0; /* check for any current pending activity */ /* Any queued work in ring buffer which can be handled still? */ xmit = &up->port.state->xmit; if (!(uart_circ_empty(xmit) || uart_tx_stopped(&up->port))) return 1; status = serial_in(up, UART_LSR); /* TX hardware not empty */ if (!(status & (UART_LSR_TEMT | UART_LSR_THRE))) return 1; /* Any rx activity? */ if (status & UART_LSR_DR) return 1; if (up->use_dma) { /* * Silicon Errata i291 workaround. * UART Module has to be put in force idle if it is * configured in DMA mode and when there is no activity * expected. */ unsigned int tmp; del_timer(&up->uart_dma.rx_timer); serial_omap_stop_rxdma(up); up->ier |= UART_IER_RDI; serial_out(up, UART_IER, up->ier); tmp = (serial_in(up, UART_OMAP_SYSC) & 0x7); serial_out(up, UART_OMAP_SYSC, tmp); /* force-idle */ } return 0; }
static void serial_omap_stop_rx(struct uart_port *port) { struct uart_omap_port *up = (struct uart_omap_port *)port; if (up->use_dma) serial_omap_stop_rxdma(up); up->ier &= ~UART_IER_RLSI; up->port.read_status_mask &= ~UART_LSR_DR; serial_out(up, UART_IER, up->ier); /*Disable the UART CTS wakeup for UART1,UART2*/ if (!port->suspended) omap_uart_cts_wakeup(up->pdev->id, 0); }
static void serial_omap_stop_rx(struct uart_port *port) { struct uart_omap_port *up = (struct uart_omap_port *)port; if (up->use_dma) serial_omap_stop_rxdma(up); up->ier &= ~UART_IER_RLSI; up->port.read_status_mask &= ~UART_LSR_DR; serial_out(up, UART_IER, up->ier); /*Disable the UART CTS wakeup for UARTs, Only for UARTs * Which have the platform Data defined for CTS wake-up * In the Board File. Else even if this function gets * called it wont have any impact on the register values * for MUX configuration. */ if (!port->suspended) omap_uart_cts_wakeup(up->pdev->id, 0); }