aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-12-28 19:54:33 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2008-12-28 19:54:33 -0500
commit3c92ec8ae91ecf59d88c798301833d7cf83f2179 (patch)
tree08a38cd3523c42bd49882f17cd501fd879e7ca1c /drivers/serial
parentc4c9f0183b7c4e97836e8fecbb67898b06c47e78 (diff)
parentca9153a3a2a7556d091dfe080e42b0e67881fff6 (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (144 commits) powerpc/44x: Support 16K/64K base page sizes on 44x powerpc: Force memory size to be a multiple of PAGE_SIZE powerpc/32: Wire up the trampoline code for kdump powerpc/32: Add the ability for a classic ppc kernel to be loaded at 32M powerpc/32: Allow __ioremap on RAM addresses for kdump kernel powerpc/32: Setup OF properties for kdump powerpc/32/kdump: Implement crash_setup_regs() using ppc_save_regs() powerpc: Prepare xmon_save_regs for use with kdump powerpc: Remove default kexec/crash_kernel ops assignments powerpc: Make default kexec/crash_kernel ops implicit powerpc: Setup OF properties for ppc32 kexec powerpc/pseries: Fix cpu hotplug powerpc: Fix KVM build on ppc440 powerpc/cell: add QPACE as a separate Cell platform powerpc/cell: fix build breakage with CONFIG_SPUFS disabled powerpc/mpc5200: fix error paths in PSC UART probe function powerpc/mpc5200: add rts/cts handling in PSC UART driver powerpc/mpc5200: Make PSC UART driver update serial errors counters powerpc/mpc5200: Remove obsolete code from mpc5200 MDIO driver powerpc/mpc5200: Add MDMA/UDMA support to MPC5200 ATA driver ... Fix trivial conflict in drivers/char/Makefile as per Paul's directions
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/mpc52xx_uart.c74
-rw-r--r--drivers/serial/pmac_zilog.c27
2 files changed, 87 insertions, 14 deletions
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 28c00c3d58f5..0c3a2ab1612c 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -429,14 +429,24 @@ mpc52xx_uart_tx_empty(struct uart_port *port)
429static void 429static void
430mpc52xx_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) 430mpc52xx_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
431{ 431{
432 /* Not implemented */ 432 if (mctrl & TIOCM_RTS)
433 out_8(&PSC(port)->op1, MPC52xx_PSC_OP_RTS);
434 else
435 out_8(&PSC(port)->op0, MPC52xx_PSC_OP_RTS);
433} 436}
434 437
435static unsigned int 438static unsigned int
436mpc52xx_uart_get_mctrl(struct uart_port *port) 439mpc52xx_uart_get_mctrl(struct uart_port *port)
437{ 440{
438 /* Not implemented */ 441 unsigned int ret = TIOCM_DSR;
439 return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; 442 u8 status = in_8(&PSC(port)->mpc52xx_psc_ipcr);
443
444 if (!(status & MPC52xx_PSC_CTS))
445 ret |= TIOCM_CTS;
446 if (!(status & MPC52xx_PSC_DCD))
447 ret |= TIOCM_CAR;
448
449 return ret;
440} 450}
441 451
442static void 452static void
@@ -479,7 +489,15 @@ mpc52xx_uart_stop_rx(struct uart_port *port)
479static void 489static void
480mpc52xx_uart_enable_ms(struct uart_port *port) 490mpc52xx_uart_enable_ms(struct uart_port *port)
481{ 491{
482 /* Not implemented */ 492 struct mpc52xx_psc __iomem *psc = PSC(port);
493
494 /* clear D_*-bits by reading them */
495 in_8(&psc->mpc52xx_psc_ipcr);
496 /* enable CTS and DCD as IPC interrupts */
497 out_8(&psc->mpc52xx_psc_acr, MPC52xx_PSC_IEC_CTS | MPC52xx_PSC_IEC_DCD);
498
499 port->read_status_mask |= MPC52xx_PSC_IMR_IPC;
500 out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask);
483} 501}
484 502
485static void 503static void
@@ -580,6 +598,10 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new,
580 MPC52xx_PSC_MODE_ONE_STOP_5_BITS : 598 MPC52xx_PSC_MODE_ONE_STOP_5_BITS :
581 MPC52xx_PSC_MODE_ONE_STOP; 599 MPC52xx_PSC_MODE_ONE_STOP;
582 600
601 if (new->c_cflag & CRTSCTS) {
602 mr1 |= MPC52xx_PSC_MODE_RXRTS;
603 mr2 |= MPC52xx_PSC_MODE_TXCTS;
604 }
583 605
584 baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16); 606 baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16);
585 quot = uart_get_divisor(port, baud); 607 quot = uart_get_divisor(port, baud);
@@ -617,6 +639,9 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new,
617 out_8(&psc->ctur, ctr >> 8); 639 out_8(&psc->ctur, ctr >> 8);
618 out_8(&psc->ctlr, ctr & 0xff); 640 out_8(&psc->ctlr, ctr & 0xff);
619 641
642 if (UART_ENABLE_MS(port, new->c_cflag))
643 mpc52xx_uart_enable_ms(port);
644
620 /* Reenable TX & RX */ 645 /* Reenable TX & RX */
621 out_8(&psc->command, MPC52xx_PSC_TX_ENABLE); 646 out_8(&psc->command, MPC52xx_PSC_TX_ENABLE);
622 out_8(&psc->command, MPC52xx_PSC_RX_ENABLE); 647 out_8(&psc->command, MPC52xx_PSC_RX_ENABLE);
@@ -752,10 +777,15 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port)
752 if (status & MPC52xx_PSC_SR_RB) { 777 if (status & MPC52xx_PSC_SR_RB) {
753 flag = TTY_BREAK; 778 flag = TTY_BREAK;
754 uart_handle_break(port); 779 uart_handle_break(port);
755 } else if (status & MPC52xx_PSC_SR_PE) 780 port->icount.brk++;
781 } else if (status & MPC52xx_PSC_SR_PE) {
756 flag = TTY_PARITY; 782 flag = TTY_PARITY;
757 else if (status & MPC52xx_PSC_SR_FE) 783 port->icount.parity++;
784 }
785 else if (status & MPC52xx_PSC_SR_FE) {
758 flag = TTY_FRAME; 786 flag = TTY_FRAME;
787 port->icount.frame++;
788 }
759 789
760 /* Clear error condition */ 790 /* Clear error condition */
761 out_8(&PSC(port)->command, MPC52xx_PSC_RST_ERR_STAT); 791 out_8(&PSC(port)->command, MPC52xx_PSC_RST_ERR_STAT);
@@ -769,6 +799,7 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port)
769 * affect the current character 799 * affect the current character
770 */ 800 */
771 tty_insert_flip_char(tty, 0, TTY_OVERRUN); 801 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
802 port->icount.overrun++;
772 } 803 }
773 } 804 }
774 805
@@ -826,6 +857,7 @@ mpc52xx_uart_int(int irq, void *dev_id)
826 struct uart_port *port = dev_id; 857 struct uart_port *port = dev_id;
827 unsigned long pass = ISR_PASS_LIMIT; 858 unsigned long pass = ISR_PASS_LIMIT;
828 unsigned int keepgoing; 859 unsigned int keepgoing;
860 u8 status;
829 861
830 spin_lock(&port->lock); 862 spin_lock(&port->lock);
831 863
@@ -842,6 +874,13 @@ mpc52xx_uart_int(int irq, void *dev_id)
842 if (psc_ops->tx_rdy(port)) 874 if (psc_ops->tx_rdy(port))
843 keepgoing |= mpc52xx_uart_int_tx_chars(port); 875 keepgoing |= mpc52xx_uart_int_tx_chars(port);
844 876
877 status = in_8(&PSC(port)->mpc52xx_psc_ipcr);
878 if (status & MPC52xx_PSC_D_DCD)
879 uart_handle_dcd_change(port, !(status & MPC52xx_PSC_DCD));
880
881 if (status & MPC52xx_PSC_D_CTS)
882 uart_handle_cts_change(port, !(status & MPC52xx_PSC_CTS));
883
845 /* Limit number of iteration */ 884 /* Limit number of iteration */
846 if (!(--pass)) 885 if (!(--pass))
847 keepgoing = 0; 886 keepgoing = 0;
@@ -1109,22 +1148,29 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match)
1109 return ret; 1148 return ret;
1110 1149
1111 port->mapbase = res.start; 1150 port->mapbase = res.start;
1151 if (!port->mapbase) {
1152 dev_dbg(&op->dev, "Could not allocate resources for PSC\n");
1153 return -EINVAL;
1154 }
1155
1112 port->irq = irq_of_parse_and_map(op->node, 0); 1156 port->irq = irq_of_parse_and_map(op->node, 0);
1157 if (port->irq == NO_IRQ) {
1158 dev_dbg(&op->dev, "Could not get irq\n");
1159 return -EINVAL;
1160 }
1113 1161
1114 dev_dbg(&op->dev, "mpc52xx-psc uart at %p, irq=%x, freq=%i\n", 1162 dev_dbg(&op->dev, "mpc52xx-psc uart at %p, irq=%x, freq=%i\n",
1115 (void *)port->mapbase, port->irq, port->uartclk); 1163 (void *)port->mapbase, port->irq, port->uartclk);
1116 1164
1117 if ((port->irq == NO_IRQ) || !port->mapbase) {
1118 printk(KERN_ERR "Could not allocate resources for PSC\n");
1119 return -EINVAL;
1120 }
1121
1122 /* Add the port to the uart sub-system */ 1165 /* Add the port to the uart sub-system */
1123 ret = uart_add_one_port(&mpc52xx_uart_driver, port); 1166 ret = uart_add_one_port(&mpc52xx_uart_driver, port);
1124 if (!ret) 1167 if (ret) {
1125 dev_set_drvdata(&op->dev, (void *)port); 1168 irq_dispose_mapping(port->irq);
1169 return ret;
1170 }
1126 1171
1127 return ret; 1172 dev_set_drvdata(&op->dev, (void *)port);
1173 return 0;
1128} 1174}
1129 1175
1130static int 1176static int
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c
index 317b061f7641..ad3488504010 100644
--- a/drivers/serial/pmac_zilog.c
+++ b/drivers/serial/pmac_zilog.c
@@ -1383,6 +1383,29 @@ static int pmz_verify_port(struct uart_port *port, struct serial_struct *ser)
1383 return -EINVAL; 1383 return -EINVAL;
1384} 1384}
1385 1385
1386#ifdef CONFIG_CONSOLE_POLL
1387
1388static int pmz_poll_get_char(struct uart_port *port)
1389{
1390 struct uart_pmac_port *uap = (struct uart_pmac_port *)port;
1391
1392 while ((read_zsreg(uap, R0) & Rx_CH_AV) == 0)
1393 udelay(5);
1394 return read_zsdata(uap);
1395}
1396
1397static void pmz_poll_put_char(struct uart_port *port, unsigned char c)
1398{
1399 struct uart_pmac_port *uap = (struct uart_pmac_port *)port;
1400
1401 /* Wait for the transmit buffer to empty. */
1402 while ((read_zsreg(uap, R0) & Tx_BUF_EMP) == 0)
1403 udelay(5);
1404 write_zsdata(uap, c);
1405}
1406
1407#endif
1408
1386static struct uart_ops pmz_pops = { 1409static struct uart_ops pmz_pops = {
1387 .tx_empty = pmz_tx_empty, 1410 .tx_empty = pmz_tx_empty,
1388 .set_mctrl = pmz_set_mctrl, 1411 .set_mctrl = pmz_set_mctrl,
@@ -1400,6 +1423,10 @@ static struct uart_ops pmz_pops = {
1400 .request_port = pmz_request_port, 1423 .request_port = pmz_request_port,
1401 .config_port = pmz_config_port, 1424 .config_port = pmz_config_port,
1402 .verify_port = pmz_verify_port, 1425 .verify_port = pmz_verify_port,
1426#ifdef CONFIG_CONSOLE_POLL
1427 .poll_get_char = pmz_poll_get_char,
1428 .poll_put_char = pmz_poll_put_char,
1429#endif
1403}; 1430};
1404 1431
1405/* 1432/*