Loading drivers/serial/mpsc.c +147 −1 Original line number Diff line number Diff line Loading @@ -921,6 +921,10 @@ static int mpsc_make_ready(struct mpsc_port_info *pi) return 0; } #ifdef CONFIG_CONSOLE_POLL static int serial_polled; #endif /* ****************************************************************************** * Loading Loading @@ -956,7 +960,12 @@ static int mpsc_rx_intr(struct mpsc_port_info *pi) while (!((cmdstat = be32_to_cpu(rxre->cmdstat)) & SDMA_DESC_CMDSTAT_O)) { bytes_in = be16_to_cpu(rxre->bytecnt); #ifdef CONFIG_CONSOLE_POLL if (unlikely(serial_polled)) { serial_polled = 0; return 0; } #endif /* Following use of tty struct directly is deprecated */ if (unlikely(tty_buffer_request_room(tty, bytes_in) < bytes_in)) { Loading Loading @@ -1017,6 +1026,12 @@ static int mpsc_rx_intr(struct mpsc_port_info *pi) if (uart_handle_sysrq_char(&pi->port, *bp)) { bp++; bytes_in--; #ifdef CONFIG_CONSOLE_POLL if (unlikely(serial_polled)) { serial_polled = 0; return 0; } #endif goto next_frame; } Loading Loading @@ -1519,6 +1534,133 @@ static int mpsc_verify_port(struct uart_port *port, struct serial_struct *ser) return rc; } #ifdef CONFIG_CONSOLE_POLL /* Serial polling routines for writing and reading from the uart while * in an interrupt or debug context. */ static char poll_buf[2048]; static int poll_ptr; static int poll_cnt; static void mpsc_put_poll_char(struct uart_port *port, unsigned char c); static int mpsc_get_poll_char(struct uart_port *port) { struct mpsc_port_info *pi = (struct mpsc_port_info *)port; struct mpsc_rx_desc *rxre; u32 cmdstat, bytes_in, i; u8 *bp; if (!serial_polled) serial_polled = 1; pr_debug("mpsc_rx_intr[%d]: Handling Rx intr\n", pi->port.line); if (poll_cnt) { poll_cnt--; return poll_buf[poll_ptr++]; } poll_ptr = 0; poll_cnt = 0; while (poll_cnt == 0) { rxre = (struct mpsc_rx_desc *)(pi->rxr + (pi->rxr_posn*MPSC_RXRE_SIZE)); dma_cache_sync(pi->port.dev, (void *)rxre, MPSC_RXRE_SIZE, DMA_FROM_DEVICE); #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ invalidate_dcache_range((ulong)rxre, (ulong)rxre + MPSC_RXRE_SIZE); #endif /* * Loop through Rx descriptors handling ones that have * been completed. */ while (poll_cnt == 0 && !((cmdstat = be32_to_cpu(rxre->cmdstat)) & SDMA_DESC_CMDSTAT_O)){ bytes_in = be16_to_cpu(rxre->bytecnt); bp = pi->rxb + (pi->rxr_posn * MPSC_RXBE_SIZE); dma_cache_sync(pi->port.dev, (void *) bp, MPSC_RXBE_SIZE, DMA_FROM_DEVICE); #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ invalidate_dcache_range((ulong)bp, (ulong)bp + MPSC_RXBE_SIZE); #endif if ((unlikely(cmdstat & (SDMA_DESC_CMDSTAT_BR | SDMA_DESC_CMDSTAT_FR | SDMA_DESC_CMDSTAT_OR))) && !(cmdstat & pi->port.ignore_status_mask)) { poll_buf[poll_cnt] = *bp; poll_cnt++; } else { for (i = 0; i < bytes_in; i++) { poll_buf[poll_cnt] = *bp++; poll_cnt++; } pi->port.icount.rx += bytes_in; } rxre->bytecnt = cpu_to_be16(0); wmb(); rxre->cmdstat = cpu_to_be32(SDMA_DESC_CMDSTAT_O | SDMA_DESC_CMDSTAT_EI | SDMA_DESC_CMDSTAT_F | SDMA_DESC_CMDSTAT_L); wmb(); dma_cache_sync(pi->port.dev, (void *)rxre, MPSC_RXRE_SIZE, DMA_BIDIRECTIONAL); #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ flush_dcache_range((ulong)rxre, (ulong)rxre + MPSC_RXRE_SIZE); #endif /* Advance to next descriptor */ pi->rxr_posn = (pi->rxr_posn + 1) & (MPSC_RXR_ENTRIES - 1); rxre = (struct mpsc_rx_desc *)(pi->rxr + (pi->rxr_posn * MPSC_RXRE_SIZE)); dma_cache_sync(pi->port.dev, (void *)rxre, MPSC_RXRE_SIZE, DMA_FROM_DEVICE); #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ invalidate_dcache_range((ulong)rxre, (ulong)rxre + MPSC_RXRE_SIZE); #endif } /* Restart rx engine, if its stopped */ if ((readl(pi->sdma_base + SDMA_SDCM) & SDMA_SDCM_ERD) == 0) mpsc_start_rx(pi); } if (poll_cnt) { poll_cnt--; return poll_buf[poll_ptr++]; } return 0; } static void mpsc_put_poll_char(struct uart_port *port, unsigned char c) { struct mpsc_port_info *pi = (struct mpsc_port_info *)port; u32 data; data = readl(pi->mpsc_base + MPSC_MPCR); writeb(c, pi->mpsc_base + MPSC_CHR_1); mb(); data = readl(pi->mpsc_base + MPSC_CHR_2); data |= MPSC_CHR_2_TTCS; writel(data, pi->mpsc_base + MPSC_CHR_2); mb(); while (readl(pi->mpsc_base + MPSC_CHR_2) & MPSC_CHR_2_TTCS); } #endif static struct uart_ops mpsc_pops = { .tx_empty = mpsc_tx_empty, Loading @@ -1537,6 +1679,10 @@ static struct uart_ops mpsc_pops = { .request_port = mpsc_request_port, .config_port = mpsc_config_port, .verify_port = mpsc_verify_port, #ifdef CONFIG_CONSOLE_POLL .poll_get_char = mpsc_get_poll_char, .poll_put_char = mpsc_put_poll_char, #endif }; /* Loading Loading
drivers/serial/mpsc.c +147 −1 Original line number Diff line number Diff line Loading @@ -921,6 +921,10 @@ static int mpsc_make_ready(struct mpsc_port_info *pi) return 0; } #ifdef CONFIG_CONSOLE_POLL static int serial_polled; #endif /* ****************************************************************************** * Loading Loading @@ -956,7 +960,12 @@ static int mpsc_rx_intr(struct mpsc_port_info *pi) while (!((cmdstat = be32_to_cpu(rxre->cmdstat)) & SDMA_DESC_CMDSTAT_O)) { bytes_in = be16_to_cpu(rxre->bytecnt); #ifdef CONFIG_CONSOLE_POLL if (unlikely(serial_polled)) { serial_polled = 0; return 0; } #endif /* Following use of tty struct directly is deprecated */ if (unlikely(tty_buffer_request_room(tty, bytes_in) < bytes_in)) { Loading Loading @@ -1017,6 +1026,12 @@ static int mpsc_rx_intr(struct mpsc_port_info *pi) if (uart_handle_sysrq_char(&pi->port, *bp)) { bp++; bytes_in--; #ifdef CONFIG_CONSOLE_POLL if (unlikely(serial_polled)) { serial_polled = 0; return 0; } #endif goto next_frame; } Loading Loading @@ -1519,6 +1534,133 @@ static int mpsc_verify_port(struct uart_port *port, struct serial_struct *ser) return rc; } #ifdef CONFIG_CONSOLE_POLL /* Serial polling routines for writing and reading from the uart while * in an interrupt or debug context. */ static char poll_buf[2048]; static int poll_ptr; static int poll_cnt; static void mpsc_put_poll_char(struct uart_port *port, unsigned char c); static int mpsc_get_poll_char(struct uart_port *port) { struct mpsc_port_info *pi = (struct mpsc_port_info *)port; struct mpsc_rx_desc *rxre; u32 cmdstat, bytes_in, i; u8 *bp; if (!serial_polled) serial_polled = 1; pr_debug("mpsc_rx_intr[%d]: Handling Rx intr\n", pi->port.line); if (poll_cnt) { poll_cnt--; return poll_buf[poll_ptr++]; } poll_ptr = 0; poll_cnt = 0; while (poll_cnt == 0) { rxre = (struct mpsc_rx_desc *)(pi->rxr + (pi->rxr_posn*MPSC_RXRE_SIZE)); dma_cache_sync(pi->port.dev, (void *)rxre, MPSC_RXRE_SIZE, DMA_FROM_DEVICE); #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ invalidate_dcache_range((ulong)rxre, (ulong)rxre + MPSC_RXRE_SIZE); #endif /* * Loop through Rx descriptors handling ones that have * been completed. */ while (poll_cnt == 0 && !((cmdstat = be32_to_cpu(rxre->cmdstat)) & SDMA_DESC_CMDSTAT_O)){ bytes_in = be16_to_cpu(rxre->bytecnt); bp = pi->rxb + (pi->rxr_posn * MPSC_RXBE_SIZE); dma_cache_sync(pi->port.dev, (void *) bp, MPSC_RXBE_SIZE, DMA_FROM_DEVICE); #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ invalidate_dcache_range((ulong)bp, (ulong)bp + MPSC_RXBE_SIZE); #endif if ((unlikely(cmdstat & (SDMA_DESC_CMDSTAT_BR | SDMA_DESC_CMDSTAT_FR | SDMA_DESC_CMDSTAT_OR))) && !(cmdstat & pi->port.ignore_status_mask)) { poll_buf[poll_cnt] = *bp; poll_cnt++; } else { for (i = 0; i < bytes_in; i++) { poll_buf[poll_cnt] = *bp++; poll_cnt++; } pi->port.icount.rx += bytes_in; } rxre->bytecnt = cpu_to_be16(0); wmb(); rxre->cmdstat = cpu_to_be32(SDMA_DESC_CMDSTAT_O | SDMA_DESC_CMDSTAT_EI | SDMA_DESC_CMDSTAT_F | SDMA_DESC_CMDSTAT_L); wmb(); dma_cache_sync(pi->port.dev, (void *)rxre, MPSC_RXRE_SIZE, DMA_BIDIRECTIONAL); #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ flush_dcache_range((ulong)rxre, (ulong)rxre + MPSC_RXRE_SIZE); #endif /* Advance to next descriptor */ pi->rxr_posn = (pi->rxr_posn + 1) & (MPSC_RXR_ENTRIES - 1); rxre = (struct mpsc_rx_desc *)(pi->rxr + (pi->rxr_posn * MPSC_RXRE_SIZE)); dma_cache_sync(pi->port.dev, (void *)rxre, MPSC_RXRE_SIZE, DMA_FROM_DEVICE); #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ invalidate_dcache_range((ulong)rxre, (ulong)rxre + MPSC_RXRE_SIZE); #endif } /* Restart rx engine, if its stopped */ if ((readl(pi->sdma_base + SDMA_SDCM) & SDMA_SDCM_ERD) == 0) mpsc_start_rx(pi); } if (poll_cnt) { poll_cnt--; return poll_buf[poll_ptr++]; } return 0; } static void mpsc_put_poll_char(struct uart_port *port, unsigned char c) { struct mpsc_port_info *pi = (struct mpsc_port_info *)port; u32 data; data = readl(pi->mpsc_base + MPSC_MPCR); writeb(c, pi->mpsc_base + MPSC_CHR_1); mb(); data = readl(pi->mpsc_base + MPSC_CHR_2); data |= MPSC_CHR_2_TTCS; writel(data, pi->mpsc_base + MPSC_CHR_2); mb(); while (readl(pi->mpsc_base + MPSC_CHR_2) & MPSC_CHR_2_TTCS); } #endif static struct uart_ops mpsc_pops = { .tx_empty = mpsc_tx_empty, Loading @@ -1537,6 +1679,10 @@ static struct uart_ops mpsc_pops = { .request_port = mpsc_request_port, .config_port = mpsc_config_port, .verify_port = mpsc_verify_port, #ifdef CONFIG_CONSOLE_POLL .poll_get_char = mpsc_get_poll_char, .poll_put_char = mpsc_put_poll_char, #endif }; /* Loading