diff options
-rw-r--r-- | drivers/serial/suncore.c | 33 | ||||
-rw-r--r-- | drivers/serial/suncore.h | 3 | ||||
-rw-r--r-- | drivers/serial/sunhv.c | 14 | ||||
-rw-r--r-- | drivers/serial/sunsab.c | 16 | ||||
-rw-r--r-- | drivers/serial/sunsu.c | 16 | ||||
-rw-r--r-- | drivers/serial/sunzilog.c | 41 |
6 files changed, 58 insertions, 65 deletions
diff --git a/drivers/serial/suncore.c b/drivers/serial/suncore.c index 70a09a3d5af0..707c5b03bce9 100644 --- a/drivers/serial/suncore.c +++ b/drivers/serial/suncore.c | |||
@@ -23,11 +23,36 @@ | |||
23 | 23 | ||
24 | #include "suncore.h" | 24 | #include "suncore.h" |
25 | 25 | ||
26 | int sunserial_current_minor = 64; | 26 | static int sunserial_current_minor = 64; |
27 | 27 | ||
28 | EXPORT_SYMBOL(sunserial_current_minor); | 28 | int sunserial_register_minors(struct uart_driver *drv, int count) |
29 | { | ||
30 | int err = 0; | ||
31 | |||
32 | drv->minor = sunserial_current_minor; | ||
33 | drv->nr += count; | ||
34 | /* Register the driver on the first call */ | ||
35 | if (drv->nr == count) | ||
36 | err = uart_register_driver(drv); | ||
37 | if (err == 0) { | ||
38 | sunserial_current_minor += count; | ||
39 | drv->tty_driver->name_base = drv->minor - 64; | ||
40 | } | ||
41 | return err; | ||
42 | } | ||
43 | EXPORT_SYMBOL(sunserial_register_minors); | ||
44 | |||
45 | void sunserial_unregister_minors(struct uart_driver *drv, int count) | ||
46 | { | ||
47 | drv->nr -= count; | ||
48 | sunserial_current_minor -= count; | ||
49 | |||
50 | if (drv->nr == 0) | ||
51 | uart_unregister_driver(drv); | ||
52 | } | ||
53 | EXPORT_SYMBOL(sunserial_unregister_minors); | ||
29 | 54 | ||
30 | int sunserial_console_match(struct console *con, struct device_node *dp, | 55 | int __init sunserial_console_match(struct console *con, struct device_node *dp, |
31 | struct uart_driver *drv, int line) | 56 | struct uart_driver *drv, int line) |
32 | { | 57 | { |
33 | int off; | 58 | int off; |
@@ -133,8 +158,6 @@ sunserial_console_termios(struct console *con) | |||
133 | con->cflag = cflag; | 158 | con->cflag = cflag; |
134 | } | 159 | } |
135 | 160 | ||
136 | EXPORT_SYMBOL(sunserial_console_termios); | ||
137 | |||
138 | /* Sun serial MOUSE auto baud rate detection. */ | 161 | /* Sun serial MOUSE auto baud rate detection. */ |
139 | static struct mouse_baud_cflag { | 162 | static struct mouse_baud_cflag { |
140 | int baud; | 163 | int baud; |
diff --git a/drivers/serial/suncore.h b/drivers/serial/suncore.h index 829d7d65d6db..042668aa602e 100644 --- a/drivers/serial/suncore.h +++ b/drivers/serial/suncore.h | |||
@@ -22,7 +22,8 @@ | |||
22 | extern unsigned int suncore_mouse_baud_cflag_next(unsigned int, int *); | 22 | extern unsigned int suncore_mouse_baud_cflag_next(unsigned int, int *); |
23 | extern int suncore_mouse_baud_detection(unsigned char, int); | 23 | extern int suncore_mouse_baud_detection(unsigned char, int); |
24 | 24 | ||
25 | extern int sunserial_current_minor; | 25 | extern int sunserial_register_minors(struct uart_driver *, int); |
26 | extern void sunserial_unregister_minors(struct uart_driver *, int); | ||
26 | 27 | ||
27 | extern int sunserial_console_match(struct console *, struct device_node *, | 28 | extern int sunserial_console_match(struct console *, struct device_node *, |
28 | struct uart_driver *, int); | 29 | struct uart_driver *, int); |
diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c index 8ff900b09811..be0fe152891b 100644 --- a/drivers/serial/sunhv.c +++ b/drivers/serial/sunhv.c | |||
@@ -562,16 +562,10 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m | |||
562 | 562 | ||
563 | port->dev = &op->dev; | 563 | port->dev = &op->dev; |
564 | 564 | ||
565 | sunhv_reg.minor = sunserial_current_minor; | 565 | err = sunserial_register_minors(&sunhv_reg, 1); |
566 | sunhv_reg.nr = 1; | ||
567 | |||
568 | err = uart_register_driver(&sunhv_reg); | ||
569 | if (err) | 566 | if (err) |
570 | goto out_free_con_read_page; | 567 | goto out_free_con_read_page; |
571 | 568 | ||
572 | sunhv_reg.tty_driver->name_base = sunhv_reg.minor - 64; | ||
573 | sunserial_current_minor += 1; | ||
574 | |||
575 | sunserial_console_match(&sunhv_console, op->node, | 569 | sunserial_console_match(&sunhv_console, op->node, |
576 | &sunhv_reg, port->line); | 570 | &sunhv_reg, port->line); |
577 | 571 | ||
@@ -591,8 +585,7 @@ out_remove_port: | |||
591 | uart_remove_one_port(&sunhv_reg, port); | 585 | uart_remove_one_port(&sunhv_reg, port); |
592 | 586 | ||
593 | out_unregister_driver: | 587 | out_unregister_driver: |
594 | sunserial_current_minor -= 1; | 588 | sunserial_unregister_minors(&sunhv_reg, 1); |
595 | uart_unregister_driver(&sunhv_reg); | ||
596 | 589 | ||
597 | out_free_con_read_page: | 590 | out_free_con_read_page: |
598 | kfree(con_read_page); | 591 | kfree(con_read_page); |
@@ -614,8 +607,7 @@ static int __devexit hv_remove(struct of_device *dev) | |||
614 | 607 | ||
615 | uart_remove_one_port(&sunhv_reg, port); | 608 | uart_remove_one_port(&sunhv_reg, port); |
616 | 609 | ||
617 | sunserial_current_minor -= 1; | 610 | sunserial_unregister_minors(&sunhv_reg, 1); |
618 | uart_unregister_driver(&sunhv_reg); | ||
619 | 611 | ||
620 | kfree(port); | 612 | kfree(port); |
621 | sunhv_port = NULL; | 613 | sunhv_port = NULL; |
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index ff610c23314b..543f93741e6f 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c | |||
@@ -832,7 +832,6 @@ static struct uart_driver sunsab_reg = { | |||
832 | }; | 832 | }; |
833 | 833 | ||
834 | static struct uart_sunsab_port *sunsab_ports; | 834 | static struct uart_sunsab_port *sunsab_ports; |
835 | static int num_channels; | ||
836 | 835 | ||
837 | #ifdef CONFIG_SERIAL_SUNSAB_CONSOLE | 836 | #ifdef CONFIG_SERIAL_SUNSAB_CONSOLE |
838 | 837 | ||
@@ -1102,8 +1101,8 @@ static int __init sunsab_init(void) | |||
1102 | { | 1101 | { |
1103 | struct device_node *dp; | 1102 | struct device_node *dp; |
1104 | int err; | 1103 | int err; |
1104 | int num_channels = 0; | ||
1105 | 1105 | ||
1106 | num_channels = 0; | ||
1107 | for_each_node_by_name(dp, "se") | 1106 | for_each_node_by_name(dp, "se") |
1108 | num_channels += 2; | 1107 | num_channels += 2; |
1109 | for_each_node_by_name(dp, "serial") { | 1108 | for_each_node_by_name(dp, "serial") { |
@@ -1117,20 +1116,14 @@ static int __init sunsab_init(void) | |||
1117 | if (!sunsab_ports) | 1116 | if (!sunsab_ports) |
1118 | return -ENOMEM; | 1117 | return -ENOMEM; |
1119 | 1118 | ||
1120 | sunsab_reg.minor = sunserial_current_minor; | ||
1121 | sunsab_reg.nr = num_channels; | ||
1122 | sunsab_reg.cons = SUNSAB_CONSOLE(); | 1119 | sunsab_reg.cons = SUNSAB_CONSOLE(); |
1123 | 1120 | err = sunserial_register_minors(&sunsab_reg, num_channels); | |
1124 | err = uart_register_driver(&sunsab_reg); | ||
1125 | if (err) { | 1121 | if (err) { |
1126 | kfree(sunsab_ports); | 1122 | kfree(sunsab_ports); |
1127 | sunsab_ports = NULL; | 1123 | sunsab_ports = NULL; |
1128 | 1124 | ||
1129 | return err; | 1125 | return err; |
1130 | } | 1126 | } |
1131 | |||
1132 | sunsab_reg.tty_driver->name_base = sunsab_reg.minor - 64; | ||
1133 | sunserial_current_minor += num_channels; | ||
1134 | } | 1127 | } |
1135 | 1128 | ||
1136 | return of_register_driver(&sab_driver, &of_bus_type); | 1129 | return of_register_driver(&sab_driver, &of_bus_type); |
@@ -1139,9 +1132,8 @@ static int __init sunsab_init(void) | |||
1139 | static void __exit sunsab_exit(void) | 1132 | static void __exit sunsab_exit(void) |
1140 | { | 1133 | { |
1141 | of_unregister_driver(&sab_driver); | 1134 | of_unregister_driver(&sab_driver); |
1142 | if (num_channels) { | 1135 | if (sunsab_reg.nr) { |
1143 | sunserial_current_minor -= num_channels; | 1136 | sunserial_unregister_minors(&sunsab_reg, sunsab_reg.nr); |
1144 | uart_unregister_driver(&sunsab_reg); | ||
1145 | } | 1137 | } |
1146 | 1138 | ||
1147 | kfree(sunsab_ports); | 1139 | kfree(sunsab_ports); |
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index e074943feff5..4e2302d43ab1 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c | |||
@@ -1528,14 +1528,12 @@ static struct of_platform_driver su_driver = { | |||
1528 | .remove = __devexit_p(su_remove), | 1528 | .remove = __devexit_p(su_remove), |
1529 | }; | 1529 | }; |
1530 | 1530 | ||
1531 | static int num_uart; | ||
1532 | |||
1533 | static int __init sunsu_init(void) | 1531 | static int __init sunsu_init(void) |
1534 | { | 1532 | { |
1535 | struct device_node *dp; | 1533 | struct device_node *dp; |
1536 | int err; | 1534 | int err; |
1535 | int num_uart = 0; | ||
1537 | 1536 | ||
1538 | num_uart = 0; | ||
1539 | for_each_node_by_name(dp, "su") { | 1537 | for_each_node_by_name(dp, "su") { |
1540 | if (su_get_type(dp) == SU_PORT_PORT) | 1538 | if (su_get_type(dp) == SU_PORT_PORT) |
1541 | num_uart++; | 1539 | num_uart++; |
@@ -1552,26 +1550,22 @@ static int __init sunsu_init(void) | |||
1552 | } | 1550 | } |
1553 | 1551 | ||
1554 | if (num_uart) { | 1552 | if (num_uart) { |
1555 | sunsu_reg.minor = sunserial_current_minor; | 1553 | err = sunserial_register_minors(&sunsu_reg, num_uart); |
1556 | sunsu_reg.nr = num_uart; | ||
1557 | err = uart_register_driver(&sunsu_reg); | ||
1558 | if (err) | 1554 | if (err) |
1559 | return err; | 1555 | return err; |
1560 | sunsu_reg.tty_driver->name_base = sunsu_reg.minor - 64; | ||
1561 | sunserial_current_minor += num_uart; | ||
1562 | } | 1556 | } |
1563 | 1557 | ||
1564 | err = of_register_driver(&su_driver, &of_bus_type); | 1558 | err = of_register_driver(&su_driver, &of_bus_type); |
1565 | if (err && num_uart) | 1559 | if (err && num_uart) |
1566 | uart_unregister_driver(&sunsu_reg); | 1560 | sunserial_unregister_minors(&sunsu_reg, num_uart); |
1567 | 1561 | ||
1568 | return err; | 1562 | return err; |
1569 | } | 1563 | } |
1570 | 1564 | ||
1571 | static void __exit sunsu_exit(void) | 1565 | static void __exit sunsu_exit(void) |
1572 | { | 1566 | { |
1573 | if (num_uart) | 1567 | if (sunsu_reg.nr) |
1574 | uart_unregister_driver(&sunsu_reg); | 1568 | sunserial_unregister_minors(&sunsu_reg, sunsu_reg.nr); |
1575 | } | 1569 | } |
1576 | 1570 | ||
1577 | module_init(sunsu_init); | 1571 | module_init(sunsu_init); |
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index 283bef0d24cb..cb2e40506379 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c | |||
@@ -63,10 +63,6 @@ | |||
63 | readb(&((__channel)->control)) | 63 | readb(&((__channel)->control)) |
64 | #endif | 64 | #endif |
65 | 65 | ||
66 | static int num_sunzilog; | ||
67 | #define NUM_SUNZILOG num_sunzilog | ||
68 | #define NUM_CHANNELS (NUM_SUNZILOG * 2) | ||
69 | |||
70 | #define ZS_CLOCK 4915200 /* Zilog input clock rate. */ | 66 | #define ZS_CLOCK 4915200 /* Zilog input clock rate. */ |
71 | #define ZS_CLOCK_DIVISOR 16 /* Divisor this driver uses. */ | 67 | #define ZS_CLOCK_DIVISOR 16 /* Divisor this driver uses. */ |
72 | 68 | ||
@@ -1031,18 +1027,19 @@ static struct uart_driver sunzilog_reg = { | |||
1031 | .major = TTY_MAJOR, | 1027 | .major = TTY_MAJOR, |
1032 | }; | 1028 | }; |
1033 | 1029 | ||
1034 | static int __init sunzilog_alloc_tables(void) | 1030 | static int __init sunzilog_alloc_tables(int num_sunzilog) |
1035 | { | 1031 | { |
1036 | struct uart_sunzilog_port *up; | 1032 | struct uart_sunzilog_port *up; |
1037 | unsigned long size; | 1033 | unsigned long size; |
1034 | int num_channels = num_sunzilog * 2; | ||
1038 | int i; | 1035 | int i; |
1039 | 1036 | ||
1040 | size = NUM_CHANNELS * sizeof(struct uart_sunzilog_port); | 1037 | size = num_channels * sizeof(struct uart_sunzilog_port); |
1041 | sunzilog_port_table = kzalloc(size, GFP_KERNEL); | 1038 | sunzilog_port_table = kzalloc(size, GFP_KERNEL); |
1042 | if (!sunzilog_port_table) | 1039 | if (!sunzilog_port_table) |
1043 | return -ENOMEM; | 1040 | return -ENOMEM; |
1044 | 1041 | ||
1045 | for (i = 0; i < NUM_CHANNELS; i++) { | 1042 | for (i = 0; i < num_channels; i++) { |
1046 | up = &sunzilog_port_table[i]; | 1043 | up = &sunzilog_port_table[i]; |
1047 | 1044 | ||
1048 | spin_lock_init(&up->port.lock); | 1045 | spin_lock_init(&up->port.lock); |
@@ -1050,13 +1047,13 @@ static int __init sunzilog_alloc_tables(void) | |||
1050 | if (i == 0) | 1047 | if (i == 0) |
1051 | sunzilog_irq_chain = up; | 1048 | sunzilog_irq_chain = up; |
1052 | 1049 | ||
1053 | if (i < NUM_CHANNELS - 1) | 1050 | if (i < num_channels - 1) |
1054 | up->next = up + 1; | 1051 | up->next = up + 1; |
1055 | else | 1052 | else |
1056 | up->next = NULL; | 1053 | up->next = NULL; |
1057 | } | 1054 | } |
1058 | 1055 | ||
1059 | size = NUM_SUNZILOG * sizeof(struct zilog_layout __iomem *); | 1056 | size = num_sunzilog * sizeof(struct zilog_layout __iomem *); |
1060 | sunzilog_chip_regs = kzalloc(size, GFP_KERNEL); | 1057 | sunzilog_chip_regs = kzalloc(size, GFP_KERNEL); |
1061 | if (!sunzilog_chip_regs) { | 1058 | if (!sunzilog_chip_regs) { |
1062 | kfree(sunzilog_port_table); | 1059 | kfree(sunzilog_port_table); |
@@ -1496,34 +1493,28 @@ static int __init sunzilog_init(void) | |||
1496 | struct device_node *dp; | 1493 | struct device_node *dp; |
1497 | int err, uart_count; | 1494 | int err, uart_count; |
1498 | int num_keybms; | 1495 | int num_keybms; |
1496 | int num_sunzilog = 0; | ||
1499 | 1497 | ||
1500 | NUM_SUNZILOG = 0; | ||
1501 | num_keybms = 0; | 1498 | num_keybms = 0; |
1502 | for_each_node_by_name(dp, "zs") { | 1499 | for_each_node_by_name(dp, "zs") { |
1503 | NUM_SUNZILOG++; | 1500 | num_sunzilog++; |
1504 | if (of_find_property(dp, "keyboard", NULL)) | 1501 | if (of_find_property(dp, "keyboard", NULL)) |
1505 | num_keybms++; | 1502 | num_keybms++; |
1506 | } | 1503 | } |
1507 | 1504 | ||
1508 | uart_count = 0; | 1505 | uart_count = 0; |
1509 | if (NUM_SUNZILOG) { | 1506 | if (num_sunzilog) { |
1510 | int uart_count; | 1507 | int uart_count; |
1511 | 1508 | ||
1512 | err = sunzilog_alloc_tables(); | 1509 | err = sunzilog_alloc_tables(num_sunzilog); |
1513 | if (err) | 1510 | if (err) |
1514 | goto out; | 1511 | goto out; |
1515 | 1512 | ||
1516 | uart_count = (NUM_SUNZILOG * 2) - (2 * num_keybms); | 1513 | uart_count = (num_sunzilog * 2) - (2 * num_keybms); |
1517 | 1514 | ||
1518 | sunzilog_reg.nr = uart_count; | 1515 | err = sunserial_register_minors(&sunzilog_reg, uart_count); |
1519 | sunzilog_reg.minor = sunserial_current_minor; | ||
1520 | err = uart_register_driver(&sunzilog_reg); | ||
1521 | if (err) | 1516 | if (err) |
1522 | goto out_free_tables; | 1517 | goto out_free_tables; |
1523 | |||
1524 | sunzilog_reg.tty_driver->name_base = sunzilog_reg.minor - 64; | ||
1525 | |||
1526 | sunserial_current_minor += uart_count; | ||
1527 | } | 1518 | } |
1528 | 1519 | ||
1529 | err = of_register_driver(&zs_driver, &of_bus_type); | 1520 | err = of_register_driver(&zs_driver, &of_bus_type); |
@@ -1557,8 +1548,8 @@ out_unregister_driver: | |||
1557 | of_unregister_driver(&zs_driver); | 1548 | of_unregister_driver(&zs_driver); |
1558 | 1549 | ||
1559 | out_unregister_uart: | 1550 | out_unregister_uart: |
1560 | if (NUM_SUNZILOG) { | 1551 | if (num_sunzilog) { |
1561 | uart_unregister_driver(&sunzilog_reg); | 1552 | sunserial_unregister_minors(&sunzilog_reg, num_sunzilog); |
1562 | sunzilog_reg.cons = NULL; | 1553 | sunzilog_reg.cons = NULL; |
1563 | } | 1554 | } |
1564 | 1555 | ||
@@ -1590,8 +1581,8 @@ static void __exit sunzilog_exit(void) | |||
1590 | zilog_irq = -1; | 1581 | zilog_irq = -1; |
1591 | } | 1582 | } |
1592 | 1583 | ||
1593 | if (NUM_SUNZILOG) { | 1584 | if (sunzilog_reg.nr) { |
1594 | uart_unregister_driver(&sunzilog_reg); | 1585 | sunserial_unregister_minors(&sunzilog_reg, sunzilog_reg.nr); |
1595 | sunzilog_free_tables(); | 1586 | sunzilog_free_tables(); |
1596 | } | 1587 | } |
1597 | } | 1588 | } |