diff options
Diffstat (limited to 'drivers/serial/sunzilog.c')
| -rw-r--r-- | drivers/serial/sunzilog.c | 65 |
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 | ||
| 105 | static 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 | ||
| 1002 | static 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 | |||
| 1036 | static 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 | |||
| 999 | static struct uart_ops sunzilog_pops = { | 1045 | static 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 | ||
| 1018 | static int uart_chip_count; | 1068 | static 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[] = { | |||
| 1491 | MODULE_DEVICE_TABLE(of, zs_match); | 1541 | MODULE_DEVICE_TABLE(of, zs_match); |
| 1492 | 1542 | ||
| 1493 | static struct of_platform_driver zs_driver = { | 1543 | static 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 | }; |
