Commit 3b216c9ed347924efb5e7a66b3257c40a5596d30

Authored by Jason Wessel
1 parent 8e21d04c07

kgdb: kgdboc console poll hooks for mpsc uart

Add in console polling hooks for the mpsc uart for use with kgdb and
kgdboc.

Signed-off-by: Jason Wessel <jason.wessel@windriver.com>

Showing 1 changed file with 147 additions and 1 deletions Side-by-side Diff

drivers/serial/mpsc.c
... ... @@ -921,6 +921,10 @@
921 921 return 0;
922 922 }
923 923  
  924 +#ifdef CONFIG_CONSOLE_POLL
  925 +static int serial_polled;
  926 +#endif
  927 +
924 928 /*
925 929 ******************************************************************************
926 930 *
... ... @@ -956,7 +960,12 @@
956 960 while (!((cmdstat = be32_to_cpu(rxre->cmdstat))
957 961 & SDMA_DESC_CMDSTAT_O)) {
958 962 bytes_in = be16_to_cpu(rxre->bytecnt);
959   -
  963 +#ifdef CONFIG_CONSOLE_POLL
  964 + if (unlikely(serial_polled)) {
  965 + serial_polled = 0;
  966 + return 0;
  967 + }
  968 +#endif
960 969 /* Following use of tty struct directly is deprecated */
961 970 if (unlikely(tty_buffer_request_room(tty, bytes_in)
962 971 < bytes_in)) {
... ... @@ -1017,6 +1026,12 @@
1017 1026 if (uart_handle_sysrq_char(&pi->port, *bp)) {
1018 1027 bp++;
1019 1028 bytes_in--;
  1029 +#ifdef CONFIG_CONSOLE_POLL
  1030 + if (unlikely(serial_polled)) {
  1031 + serial_polled = 0;
  1032 + return 0;
  1033 + }
  1034 +#endif
1020 1035 goto next_frame;
1021 1036 }
1022 1037  
1023 1038  
... ... @@ -1519,7 +1534,134 @@
1519 1534  
1520 1535 return rc;
1521 1536 }
  1537 +#ifdef CONFIG_CONSOLE_POLL
  1538 +/* Serial polling routines for writing and reading from the uart while
  1539 + * in an interrupt or debug context.
  1540 + */
1522 1541  
  1542 +static char poll_buf[2048];
  1543 +static int poll_ptr;
  1544 +static int poll_cnt;
  1545 +static void mpsc_put_poll_char(struct uart_port *port,
  1546 + unsigned char c);
  1547 +
  1548 +static int mpsc_get_poll_char(struct uart_port *port)
  1549 +{
  1550 + struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
  1551 + struct mpsc_rx_desc *rxre;
  1552 + u32 cmdstat, bytes_in, i;
  1553 + u8 *bp;
  1554 +
  1555 + if (!serial_polled)
  1556 + serial_polled = 1;
  1557 +
  1558 + pr_debug("mpsc_rx_intr[%d]: Handling Rx intr\n", pi->port.line);
  1559 +
  1560 + if (poll_cnt) {
  1561 + poll_cnt--;
  1562 + return poll_buf[poll_ptr++];
  1563 + }
  1564 + poll_ptr = 0;
  1565 + poll_cnt = 0;
  1566 +
  1567 + while (poll_cnt == 0) {
  1568 + rxre = (struct mpsc_rx_desc *)(pi->rxr +
  1569 + (pi->rxr_posn*MPSC_RXRE_SIZE));
  1570 + dma_cache_sync(pi->port.dev, (void *)rxre,
  1571 + MPSC_RXRE_SIZE, DMA_FROM_DEVICE);
  1572 +#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
  1573 + if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
  1574 + invalidate_dcache_range((ulong)rxre,
  1575 + (ulong)rxre + MPSC_RXRE_SIZE);
  1576 +#endif
  1577 + /*
  1578 + * Loop through Rx descriptors handling ones that have
  1579 + * been completed.
  1580 + */
  1581 + while (poll_cnt == 0 &&
  1582 + !((cmdstat = be32_to_cpu(rxre->cmdstat)) &
  1583 + SDMA_DESC_CMDSTAT_O)){
  1584 + bytes_in = be16_to_cpu(rxre->bytecnt);
  1585 + bp = pi->rxb + (pi->rxr_posn * MPSC_RXBE_SIZE);
  1586 + dma_cache_sync(pi->port.dev, (void *) bp,
  1587 + MPSC_RXBE_SIZE, DMA_FROM_DEVICE);
  1588 +#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
  1589 + if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
  1590 + invalidate_dcache_range((ulong)bp,
  1591 + (ulong)bp + MPSC_RXBE_SIZE);
  1592 +#endif
  1593 + if ((unlikely(cmdstat & (SDMA_DESC_CMDSTAT_BR |
  1594 + SDMA_DESC_CMDSTAT_FR | SDMA_DESC_CMDSTAT_OR))) &&
  1595 + !(cmdstat & pi->port.ignore_status_mask)) {
  1596 + poll_buf[poll_cnt] = *bp;
  1597 + poll_cnt++;
  1598 + } else {
  1599 + for (i = 0; i < bytes_in; i++) {
  1600 + poll_buf[poll_cnt] = *bp++;
  1601 + poll_cnt++;
  1602 + }
  1603 + pi->port.icount.rx += bytes_in;
  1604 + }
  1605 + rxre->bytecnt = cpu_to_be16(0);
  1606 + wmb();
  1607 + rxre->cmdstat = cpu_to_be32(SDMA_DESC_CMDSTAT_O |
  1608 + SDMA_DESC_CMDSTAT_EI |
  1609 + SDMA_DESC_CMDSTAT_F |
  1610 + SDMA_DESC_CMDSTAT_L);
  1611 + wmb();
  1612 + dma_cache_sync(pi->port.dev, (void *)rxre,
  1613 + MPSC_RXRE_SIZE, DMA_BIDIRECTIONAL);
  1614 +#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
  1615 + if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
  1616 + flush_dcache_range((ulong)rxre,
  1617 + (ulong)rxre + MPSC_RXRE_SIZE);
  1618 +#endif
  1619 +
  1620 + /* Advance to next descriptor */
  1621 + pi->rxr_posn = (pi->rxr_posn + 1) &
  1622 + (MPSC_RXR_ENTRIES - 1);
  1623 + rxre = (struct mpsc_rx_desc *)(pi->rxr +
  1624 + (pi->rxr_posn * MPSC_RXRE_SIZE));
  1625 + dma_cache_sync(pi->port.dev, (void *)rxre,
  1626 + MPSC_RXRE_SIZE, DMA_FROM_DEVICE);
  1627 +#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
  1628 + if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
  1629 + invalidate_dcache_range((ulong)rxre,
  1630 + (ulong)rxre + MPSC_RXRE_SIZE);
  1631 +#endif
  1632 + }
  1633 +
  1634 + /* Restart rx engine, if its stopped */
  1635 + if ((readl(pi->sdma_base + SDMA_SDCM) & SDMA_SDCM_ERD) == 0)
  1636 + mpsc_start_rx(pi);
  1637 + }
  1638 + if (poll_cnt) {
  1639 + poll_cnt--;
  1640 + return poll_buf[poll_ptr++];
  1641 + }
  1642 +
  1643 + return 0;
  1644 +}
  1645 +
  1646 +
  1647 +static void mpsc_put_poll_char(struct uart_port *port,
  1648 + unsigned char c)
  1649 +{
  1650 + struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
  1651 + u32 data;
  1652 +
  1653 + data = readl(pi->mpsc_base + MPSC_MPCR);
  1654 + writeb(c, pi->mpsc_base + MPSC_CHR_1);
  1655 + mb();
  1656 + data = readl(pi->mpsc_base + MPSC_CHR_2);
  1657 + data |= MPSC_CHR_2_TTCS;
  1658 + writel(data, pi->mpsc_base + MPSC_CHR_2);
  1659 + mb();
  1660 +
  1661 + while (readl(pi->mpsc_base + MPSC_CHR_2) & MPSC_CHR_2_TTCS);
  1662 +}
  1663 +#endif
  1664 +
1523 1665 static struct uart_ops mpsc_pops = {
1524 1666 .tx_empty = mpsc_tx_empty,
1525 1667 .set_mctrl = mpsc_set_mctrl,
... ... @@ -1537,6 +1679,10 @@
1537 1679 .request_port = mpsc_request_port,
1538 1680 .config_port = mpsc_config_port,
1539 1681 .verify_port = mpsc_verify_port,
  1682 +#ifdef CONFIG_CONSOLE_POLL
  1683 + .poll_get_char = mpsc_get_poll_char,
  1684 + .poll_put_char = mpsc_put_poll_char,
  1685 +#endif
1540 1686 };
1541 1687  
1542 1688 /*