aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-07-23 14:59:37 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-23 14:59:37 -0400
commit0f6e38a6381446eff5175b77d1094834a633a90f (patch)
treee5295c372b6a73fa84b4d14b86ea9fa626d3f030 /drivers
parente669e8179d364bb11ed51504e1a1c60830bff4c5 (diff)
parent3b216c9ed347924efb5e7a66b3257c40a5596d30 (diff)
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/linux-2.6-kgdb
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/linux-2.6-kgdb: kgdb: kgdboc console poll hooks for mpsc uart kgdb: kgdboc console poll hooks for cpm uart kgdb, powerpc: arch specific powerpc kgdb support kgdb: support for ARCH=arm kgdb: remove unused HAVE_ARCH_KGDB_SHADOW_INFO config variable
Diffstat (limited to 'drivers')
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_core.c95
-rw-r--r--drivers/serial/mpsc.c148
2 files changed, 241 insertions, 2 deletions
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index 93e407ee08b9..1ff80de177db 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -201,6 +201,10 @@ static void cpm_uart_int_tx(struct uart_port *port)
201 cpm_uart_tx_pump(port); 201 cpm_uart_tx_pump(port);
202} 202}
203 203
204#ifdef CONFIG_CONSOLE_POLL
205static int serial_polled;
206#endif
207
204/* 208/*
205 * Receive characters 209 * Receive characters
206 */ 210 */
@@ -222,6 +226,12 @@ static void cpm_uart_int_rx(struct uart_port *port)
222 */ 226 */
223 bdp = pinfo->rx_cur; 227 bdp = pinfo->rx_cur;
224 for (;;) { 228 for (;;) {
229#ifdef CONFIG_CONSOLE_POLL
230 if (unlikely(serial_polled)) {
231 serial_polled = 0;
232 return;
233 }
234#endif
225 /* get status */ 235 /* get status */
226 status = in_be16(&bdp->cbd_sc); 236 status = in_be16(&bdp->cbd_sc);
227 /* If this one is empty, return happy */ 237 /* If this one is empty, return happy */
@@ -253,7 +263,12 @@ static void cpm_uart_int_rx(struct uart_port *port)
253 goto handle_error; 263 goto handle_error;
254 if (uart_handle_sysrq_char(port, ch)) 264 if (uart_handle_sysrq_char(port, ch))
255 continue; 265 continue;
256 266#ifdef CONFIG_CONSOLE_POLL
267 if (unlikely(serial_polled)) {
268 serial_polled = 0;
269 return;
270 }
271#endif
257 error_return: 272 error_return:
258 tty_insert_flip_char(tty, ch, flg); 273 tty_insert_flip_char(tty, ch, flg);
259 274
@@ -865,6 +880,80 @@ static void cpm_uart_config_port(struct uart_port *port, int flags)
865 cpm_uart_request_port(port); 880 cpm_uart_request_port(port);
866 } 881 }
867} 882}
883
884#ifdef CONFIG_CONSOLE_POLL
885/* Serial polling routines for writing and reading from the uart while
886 * in an interrupt or debug context.
887 */
888
889#define GDB_BUF_SIZE 512 /* power of 2, please */
890
891static char poll_buf[GDB_BUF_SIZE];
892static char *pollp;
893static int poll_chars;
894
895static int poll_wait_key(char *obuf, struct uart_cpm_port *pinfo)
896{
897 u_char c, *cp;
898 volatile cbd_t *bdp;
899 int i;
900
901 /* Get the address of the host memory buffer.
902 */
903 bdp = pinfo->rx_cur;
904 while (bdp->cbd_sc & BD_SC_EMPTY)
905 ;
906
907 /* If the buffer address is in the CPM DPRAM, don't
908 * convert it.
909 */
910 cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
911
912 if (obuf) {
913 i = c = bdp->cbd_datlen;
914 while (i-- > 0)
915 *obuf++ = *cp++;
916 } else
917 c = *cp;
918 bdp->cbd_sc &= ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV | BD_SC_ID);
919 bdp->cbd_sc |= BD_SC_EMPTY;
920
921 if (bdp->cbd_sc & BD_SC_WRAP)
922 bdp = pinfo->rx_bd_base;
923 else
924 bdp++;
925 pinfo->rx_cur = (cbd_t *)bdp;
926
927 return (int)c;
928}
929
930static int cpm_get_poll_char(struct uart_port *port)
931{
932 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
933
934 if (!serial_polled) {
935 serial_polled = 1;
936 poll_chars = 0;
937 }
938 if (poll_chars <= 0) {
939 poll_chars = poll_wait_key(poll_buf, pinfo);
940 pollp = poll_buf;
941 }
942 poll_chars--;
943 return *pollp++;
944}
945
946static void cpm_put_poll_char(struct uart_port *port,
947 unsigned char c)
948{
949 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
950 static char ch[2];
951
952 ch[0] = (char)c;
953 cpm_uart_early_write(pinfo->port.line, ch, 1);
954}
955#endif /* CONFIG_CONSOLE_POLL */
956
868static struct uart_ops cpm_uart_pops = { 957static struct uart_ops cpm_uart_pops = {
869 .tx_empty = cpm_uart_tx_empty, 958 .tx_empty = cpm_uart_tx_empty,
870 .set_mctrl = cpm_uart_set_mctrl, 959 .set_mctrl = cpm_uart_set_mctrl,
@@ -882,6 +971,10 @@ static struct uart_ops cpm_uart_pops = {
882 .request_port = cpm_uart_request_port, 971 .request_port = cpm_uart_request_port,
883 .config_port = cpm_uart_config_port, 972 .config_port = cpm_uart_config_port,
884 .verify_port = cpm_uart_verify_port, 973 .verify_port = cpm_uart_verify_port,
974#ifdef CONFIG_CONSOLE_POLL
975 .poll_get_char = cpm_get_poll_char,
976 .poll_put_char = cpm_put_poll_char,
977#endif
885}; 978};
886 979
887struct uart_cpm_port cpm_uart_ports[UART_NR]; 980struct uart_cpm_port cpm_uart_ports[UART_NR];
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c
index c9f53e71f252..61d3ade5286c 100644
--- a/drivers/serial/mpsc.c
+++ b/drivers/serial/mpsc.c
@@ -921,6 +921,10 @@ static int mpsc_make_ready(struct mpsc_port_info *pi)
921 return 0; 921 return 0;
922} 922}
923 923
924#ifdef CONFIG_CONSOLE_POLL
925static int serial_polled;
926#endif
927
924/* 928/*
925 ****************************************************************************** 929 ******************************************************************************
926 * 930 *
@@ -956,7 +960,12 @@ static int mpsc_rx_intr(struct mpsc_port_info *pi)
956 while (!((cmdstat = be32_to_cpu(rxre->cmdstat)) 960 while (!((cmdstat = be32_to_cpu(rxre->cmdstat))
957 & SDMA_DESC_CMDSTAT_O)) { 961 & SDMA_DESC_CMDSTAT_O)) {
958 bytes_in = be16_to_cpu(rxre->bytecnt); 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 /* Following use of tty struct directly is deprecated */ 969 /* Following use of tty struct directly is deprecated */
961 if (unlikely(tty_buffer_request_room(tty, bytes_in) 970 if (unlikely(tty_buffer_request_room(tty, bytes_in)
962 < bytes_in)) { 971 < bytes_in)) {
@@ -1017,6 +1026,12 @@ static int mpsc_rx_intr(struct mpsc_port_info *pi)
1017 if (uart_handle_sysrq_char(&pi->port, *bp)) { 1026 if (uart_handle_sysrq_char(&pi->port, *bp)) {
1018 bp++; 1027 bp++;
1019 bytes_in--; 1028 bytes_in--;
1029#ifdef CONFIG_CONSOLE_POLL
1030 if (unlikely(serial_polled)) {
1031 serial_polled = 0;
1032 return 0;
1033 }
1034#endif
1020 goto next_frame; 1035 goto next_frame;
1021 } 1036 }
1022 1037
@@ -1519,6 +1534,133 @@ static int mpsc_verify_port(struct uart_port *port, struct serial_struct *ser)
1519 1534
1520 return rc; 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 */
1541
1542static char poll_buf[2048];
1543static int poll_ptr;
1544static int poll_cnt;
1545static void mpsc_put_poll_char(struct uart_port *port,
1546 unsigned char c);
1547
1548static 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
1647static 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
1522 1664
1523static struct uart_ops mpsc_pops = { 1665static struct uart_ops mpsc_pops = {
1524 .tx_empty = mpsc_tx_empty, 1666 .tx_empty = mpsc_tx_empty,
@@ -1537,6 +1679,10 @@ static struct uart_ops mpsc_pops = {
1537 .request_port = mpsc_request_port, 1679 .request_port = mpsc_request_port,
1538 .config_port = mpsc_config_port, 1680 .config_port = mpsc_config_port,
1539 .verify_port = mpsc_verify_port, 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/*