diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-12-28 19:54:33 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-12-28 19:54:33 -0500 |
commit | 3c92ec8ae91ecf59d88c798301833d7cf83f2179 (patch) | |
tree | 08a38cd3523c42bd49882f17cd501fd879e7ca1c /drivers/serial | |
parent | c4c9f0183b7c4e97836e8fecbb67898b06c47e78 (diff) | |
parent | ca9153a3a2a7556d091dfe080e42b0e67881fff6 (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.c | 74 | ||||
-rw-r--r-- | drivers/serial/pmac_zilog.c | 27 |
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) | |||
429 | static void | 429 | static void |
430 | mpc52xx_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) | 430 | mpc52xx_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 | ||
435 | static unsigned int | 438 | static unsigned int |
436 | mpc52xx_uart_get_mctrl(struct uart_port *port) | 439 | mpc52xx_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 | ||
442 | static void | 452 | static void |
@@ -479,7 +489,15 @@ mpc52xx_uart_stop_rx(struct uart_port *port) | |||
479 | static void | 489 | static void |
480 | mpc52xx_uart_enable_ms(struct uart_port *port) | 490 | mpc52xx_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 | ||
485 | static void | 503 | static 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 | ||
1130 | static int | 1176 | static 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 | |||
1388 | static 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 | |||
1397 | static 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 | |||
1386 | static struct uart_ops pmz_pops = { | 1409 | static 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 | /* |