aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/sunzilog.c
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2010-08-06 13:13:54 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-08-06 13:13:54 -0400
commit11e4afb49b7fa1fc8e1ffd850c1806dd86a08204 (patch)
tree9e57efcb106ae912f7bec718feb3f8ec607559bb /drivers/serial/sunzilog.c
parent162500b3a3ff39d941d29db49b41a16667ae44f0 (diff)
parent9b2a606d3898fcb2eedb6faded3bb37549590ac4 (diff)
Merge branches 'gemini' and 'misc' into devel
Diffstat (limited to 'drivers/serial/sunzilog.c')
-rw-r--r--drivers/serial/sunzilog.c65
1 files changed, 59 insertions, 6 deletions
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index 2c7a66af4f52..f9a24f4ebb34 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -102,6 +102,8 @@ struct uart_sunzilog_port {
102#endif 102#endif
103}; 103};
104 104
105static void sunzilog_putchar(struct uart_port *port, int ch);
106
105#define ZILOG_CHANNEL_FROM_PORT(PORT) ((struct zilog_channel __iomem *)((PORT)->membase)) 107#define ZILOG_CHANNEL_FROM_PORT(PORT) ((struct zilog_channel __iomem *)((PORT)->membase))
106#define UART_ZILOG(PORT) ((struct uart_sunzilog_port *)(PORT)) 108#define UART_ZILOG(PORT) ((struct uart_sunzilog_port *)(PORT))
107 109
@@ -996,6 +998,50 @@ static int sunzilog_verify_port(struct uart_port *port, struct serial_struct *se
996 return -EINVAL; 998 return -EINVAL;
997} 999}
998 1000
1001#ifdef CONFIG_CONSOLE_POLL
1002static int sunzilog_get_poll_char(struct uart_port *port)
1003{
1004 unsigned char ch, r1;
1005 struct uart_sunzilog_port *up = (struct uart_sunzilog_port *) port;
1006 struct zilog_channel __iomem *channel
1007 = ZILOG_CHANNEL_FROM_PORT(&up->port);
1008
1009
1010 r1 = read_zsreg(channel, R1);
1011 if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR)) {
1012 writeb(ERR_RES, &channel->control);
1013 ZSDELAY();
1014 ZS_WSYNC(channel);
1015 }
1016
1017 ch = readb(&channel->control);
1018 ZSDELAY();
1019
1020 /* This funny hack depends upon BRK_ABRT not interfering
1021 * with the other bits we care about in R1.
1022 */
1023 if (ch & BRK_ABRT)
1024 r1 |= BRK_ABRT;
1025
1026 if (!(ch & Rx_CH_AV))
1027 return NO_POLL_CHAR;
1028
1029 ch = readb(&channel->data);
1030 ZSDELAY();
1031
1032 ch &= up->parity_mask;
1033 return ch;
1034}
1035
1036static void sunzilog_put_poll_char(struct uart_port *port,
1037 unsigned char ch)
1038{
1039 struct uart_sunzilog_port *up = (struct uart_sunzilog_port *)port;
1040
1041 sunzilog_putchar(&up->port, ch);
1042}
1043#endif /* CONFIG_CONSOLE_POLL */
1044
999static struct uart_ops sunzilog_pops = { 1045static struct uart_ops sunzilog_pops = {
1000 .tx_empty = sunzilog_tx_empty, 1046 .tx_empty = sunzilog_tx_empty,
1001 .set_mctrl = sunzilog_set_mctrl, 1047 .set_mctrl = sunzilog_set_mctrl,
@@ -1013,6 +1059,10 @@ static struct uart_ops sunzilog_pops = {
1013 .request_port = sunzilog_request_port, 1059 .request_port = sunzilog_request_port,
1014 .config_port = sunzilog_config_port, 1060 .config_port = sunzilog_config_port,
1015 .verify_port = sunzilog_verify_port, 1061 .verify_port = sunzilog_verify_port,
1062#ifdef CONFIG_CONSOLE_POLL
1063 .poll_get_char = sunzilog_get_poll_char,
1064 .poll_put_char = sunzilog_put_poll_char,
1065#endif
1016}; 1066};
1017 1067
1018static int uart_chip_count; 1068static int uart_chip_count;
@@ -1180,7 +1230,7 @@ static int __init sunzilog_console_setup(struct console *con, char *options)
1180 (sunzilog_reg.minor - 64) + con->index, con->index); 1230 (sunzilog_reg.minor - 64) + con->index, con->index);
1181 1231
1182 /* Get firmware console settings. */ 1232 /* Get firmware console settings. */
1183 sunserial_console_termios(con, to_of_device(up->port.dev)->node); 1233 sunserial_console_termios(con, to_of_device(up->port.dev)->dev.of_node);
1184 1234
1185 /* Firmware console speed is limited to 150-->38400 baud so 1235 /* Firmware console speed is limited to 150-->38400 baud so
1186 * this hackish cflag thing is OK. 1236 * this hackish cflag thing is OK.
@@ -1358,7 +1408,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
1358 int keyboard_mouse = 0; 1408 int keyboard_mouse = 0;
1359 int err; 1409 int err;
1360 1410
1361 if (of_find_property(op->node, "keyboard", NULL)) 1411 if (of_find_property(op->dev.of_node, "keyboard", NULL))
1362 keyboard_mouse = 1; 1412 keyboard_mouse = 1;
1363 1413
1364 /* uarts must come before keyboards/mice */ 1414 /* uarts must come before keyboards/mice */
@@ -1415,7 +1465,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
1415 sunzilog_init_hw(&up[1]); 1465 sunzilog_init_hw(&up[1]);
1416 1466
1417 if (!keyboard_mouse) { 1467 if (!keyboard_mouse) {
1418 if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node, 1468 if (sunserial_console_match(SUNZILOG_CONSOLE(), op->dev.of_node,
1419 &sunzilog_reg, up[0].port.line, 1469 &sunzilog_reg, up[0].port.line,
1420 false)) 1470 false))
1421 up->flags |= SUNZILOG_FLAG_IS_CONS; 1471 up->flags |= SUNZILOG_FLAG_IS_CONS;
@@ -1425,7 +1475,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
1425 rp, sizeof(struct zilog_layout)); 1475 rp, sizeof(struct zilog_layout));
1426 return err; 1476 return err;
1427 } 1477 }
1428 if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node, 1478 if (sunserial_console_match(SUNZILOG_CONSOLE(), op->dev.of_node,
1429 &sunzilog_reg, up[1].port.line, 1479 &sunzilog_reg, up[1].port.line,
1430 false)) 1480 false))
1431 up->flags |= SUNZILOG_FLAG_IS_CONS; 1481 up->flags |= SUNZILOG_FLAG_IS_CONS;
@@ -1491,8 +1541,11 @@ static const struct of_device_id zs_match[] = {
1491MODULE_DEVICE_TABLE(of, zs_match); 1541MODULE_DEVICE_TABLE(of, zs_match);
1492 1542
1493static struct of_platform_driver zs_driver = { 1543static struct of_platform_driver zs_driver = {
1494 .name = "zs", 1544 .driver = {
1495 .match_table = zs_match, 1545 .name = "zs",
1546 .owner = THIS_MODULE,
1547 .of_match_table = zs_match,
1548 },
1496 .probe = zs_probe, 1549 .probe = zs_probe,
1497 .remove = __devexit_p(zs_remove), 1550 .remove = __devexit_p(zs_remove),
1498}; 1551};