aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/serial/sunsu.c491
1 files changed, 157 insertions, 334 deletions
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index 6e28c25138cf..4ef47c810de9 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -40,11 +40,8 @@
40 40
41#include <asm/io.h> 41#include <asm/io.h>
42#include <asm/irq.h> 42#include <asm/irq.h>
43#include <asm/oplib.h> 43#include <asm/prom.h>
44#include <asm/ebus.h> 44#include <asm/of_device.h>
45#ifdef CONFIG_SPARC64
46#include <asm/isa.h>
47#endif
48 45
49#if defined(CONFIG_SERIAL_SUNSU_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) 46#if defined(CONFIG_SERIAL_SUNSU_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
50#define SUPPORT_SYSRQ 47#define SUPPORT_SYSRQ
@@ -94,10 +91,10 @@ struct uart_sunsu_port {
94 /* Probing information. */ 91 /* Probing information. */
95 enum su_type su_type; 92 enum su_type su_type;
96 unsigned int type_probed; /* XXX Stupid */ 93 unsigned int type_probed; /* XXX Stupid */
97 int port_node; 94 unsigned long reg_size;
98 95
99#ifdef CONFIG_SERIO 96#ifdef CONFIG_SERIO
100 struct serio *serio; 97 struct serio serio;
101 int serio_open; 98 int serio_open;
102#endif 99#endif
103}; 100};
@@ -509,7 +506,7 @@ static void receive_kbd_ms_chars(struct uart_sunsu_port *up, struct pt_regs *reg
509 /* Stop-A is handled by drivers/char/keyboard.c now. */ 506 /* Stop-A is handled by drivers/char/keyboard.c now. */
510 if (up->su_type == SU_PORT_KBD) { 507 if (up->su_type == SU_PORT_KBD) {
511#ifdef CONFIG_SERIO 508#ifdef CONFIG_SERIO
512 serio_interrupt(up->serio, ch, 0, regs); 509 serio_interrupt(&up->serio, ch, 0, regs);
513#endif 510#endif
514 } else if (up->su_type == SU_PORT_MS) { 511 } else if (up->su_type == SU_PORT_MS) {
515 int ret = suncore_mouse_baud_detection(ch, is_break); 512 int ret = suncore_mouse_baud_detection(ch, is_break);
@@ -523,7 +520,7 @@ static void receive_kbd_ms_chars(struct uart_sunsu_port *up, struct pt_regs *reg
523 520
524 case 0: 521 case 0:
525#ifdef CONFIG_SERIO 522#ifdef CONFIG_SERIO
526 serio_interrupt(up->serio, ch, 0, regs); 523 serio_interrupt(&up->serio, ch, 0, regs);
527#endif 524#endif
528 break; 525 break;
529 }; 526 };
@@ -1031,99 +1028,14 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up)
1031{ 1028{
1032 unsigned char status1, status2, scratch, scratch2, scratch3; 1029 unsigned char status1, status2, scratch, scratch2, scratch3;
1033 unsigned char save_lcr, save_mcr; 1030 unsigned char save_lcr, save_mcr;
1034 struct linux_ebus_device *dev = NULL;
1035 struct linux_ebus *ebus;
1036#ifdef CONFIG_SPARC64
1037 struct sparc_isa_bridge *isa_br;
1038 struct sparc_isa_device *isa_dev;
1039#endif
1040#ifndef CONFIG_SPARC64
1041 struct linux_prom_registers reg0;
1042#endif
1043 unsigned long flags; 1031 unsigned long flags;
1044 1032
1045 if (!up->port_node || !up->su_type) 1033 if (up->su_type == SU_PORT_NONE)
1046 return; 1034 return;
1047 1035
1048 up->type_probed = PORT_UNKNOWN; 1036 up->type_probed = PORT_UNKNOWN;
1049 up->port.iotype = UPIO_MEM; 1037 up->port.iotype = UPIO_MEM;
1050 1038
1051 /*
1052 * First we look for Ebus-bases su's
1053 */
1054 for_each_ebus(ebus) {
1055 for_each_ebusdev(dev, ebus) {
1056 if (dev->prom_node->node == up->port_node) {
1057 /*
1058 * The EBus is broken on sparc; it delivers
1059 * virtual addresses in resources. Oh well...
1060 * This is correct on sparc64, though.
1061 */
1062 up->port.membase = (char *) dev->resource[0].start;
1063 /*
1064 * This is correct on both architectures.
1065 */
1066 up->port.mapbase = dev->resource[0].start;
1067 up->port.irq = dev->irqs[0];
1068 goto ebus_done;
1069 }
1070 }
1071 }
1072
1073#ifdef CONFIG_SPARC64
1074 for_each_isa(isa_br) {
1075 for_each_isadev(isa_dev, isa_br) {
1076 if (isa_dev->prom_node->node == up->port_node) {
1077 /* Same on sparc64. Cool architecure... */
1078 up->port.membase = (char *) isa_dev->resource.start;
1079 up->port.mapbase = isa_dev->resource.start;
1080 up->port.irq = isa_dev->irq;
1081 goto ebus_done;
1082 }
1083 }
1084 }
1085#endif
1086
1087#ifdef CONFIG_SPARC64
1088 /*
1089 * Not on Ebus, bailing.
1090 */
1091 return;
1092#else
1093 /*
1094 * Not on Ebus, must be OBIO.
1095 */
1096 if (prom_getproperty(up->port_node, "reg",
1097 (char *)&reg0, sizeof(reg0)) == -1) {
1098 prom_printf("sunsu: no \"reg\" property\n");
1099 return;
1100 }
1101 prom_apply_obio_ranges(&reg0, 1);
1102 if (reg0.which_io != 0) { /* Just in case... */
1103 prom_printf("sunsu: bus number nonzero: 0x%x:%x\n",
1104 reg0.which_io, reg0.phys_addr);
1105 return;
1106 }
1107 up->port.mapbase = reg0.phys_addr;
1108 if ((up->port.membase = ioremap(reg0.phys_addr, reg0.reg_size)) == 0) {
1109 prom_printf("sunsu: Cannot map registers.\n");
1110 return;
1111 }
1112
1113 /*
1114 * 0x20 is sun4m thing, Dave Redman heritage.
1115 * See arch/sparc/kernel/irq.c.
1116 */
1117#define IRQ_4M(n) ((n)|0x20)
1118
1119 /*
1120 * There is no intr property on MrCoffee, so hardwire it.
1121 */
1122 up->port.irq = IRQ_4M(13);
1123#endif
1124
1125ebus_done:
1126
1127 spin_lock_irqsave(&up->port.lock, flags); 1039 spin_lock_irqsave(&up->port.lock, flags);
1128 1040
1129 if (!(up->port.flags & UPF_BUGGY_UART)) { 1041 if (!(up->port.flags & UPF_BUGGY_UART)) {
@@ -1269,18 +1181,13 @@ static struct uart_driver sunsu_reg = {
1269 .major = TTY_MAJOR, 1181 .major = TTY_MAJOR,
1270}; 1182};
1271 1183
1272static int __init sunsu_kbd_ms_init(struct uart_sunsu_port *up, int channel) 1184static int __init sunsu_kbd_ms_init(struct uart_sunsu_port *up)
1273{ 1185{
1274 int quot, baud; 1186 int quot, baud;
1275#ifdef CONFIG_SERIO 1187#ifdef CONFIG_SERIO
1276 struct serio *serio; 1188 struct serio *serio;
1277#endif 1189#endif
1278 1190
1279 spin_lock_init(&up->port.lock);
1280 up->port.line = channel;
1281 up->port.type = PORT_UNKNOWN;
1282 up->port.uartclk = (SU_BASE_BAUD * 16);
1283
1284 if (up->su_type == SU_PORT_KBD) { 1191 if (up->su_type == SU_PORT_KBD) {
1285 up->cflag = B1200 | CS8 | CLOCAL | CREAD; 1192 up->cflag = B1200 | CS8 | CLOCAL | CREAD;
1286 baud = 1200; 1193 baud = 1200;
@@ -1292,41 +1199,31 @@ static int __init sunsu_kbd_ms_init(struct uart_sunsu_port *up, int channel)
1292 1199
1293 sunsu_autoconfig(up); 1200 sunsu_autoconfig(up);
1294 if (up->port.type == PORT_UNKNOWN) 1201 if (up->port.type == PORT_UNKNOWN)
1295 return -1; 1202 return -ENODEV;
1296
1297 printk(KERN_INFO "su%d at 0x%p (irq = %d) is a %s\n",
1298 channel,
1299 up->port.membase, up->port.irq,
1300 sunsu_type(&up->port));
1301 1203
1302#ifdef CONFIG_SERIO 1204#ifdef CONFIG_SERIO
1303 up->serio = serio = kmalloc(sizeof(struct serio), GFP_KERNEL); 1205 serio = &up->serio;
1304 if (serio) { 1206 serio->port_data = up;
1305 memset(serio, 0, sizeof(*serio));
1306
1307 serio->port_data = up;
1308
1309 serio->id.type = SERIO_RS232;
1310 if (up->su_type == SU_PORT_KBD) {
1311 serio->id.proto = SERIO_SUNKBD;
1312 strlcpy(serio->name, "sukbd", sizeof(serio->name));
1313 } else {
1314 serio->id.proto = SERIO_SUN;
1315 serio->id.extra = 1;
1316 strlcpy(serio->name, "sums", sizeof(serio->name));
1317 }
1318 strlcpy(serio->phys, (channel == 0 ? "su/serio0" : "su/serio1"),
1319 sizeof(serio->phys));
1320 1207
1321 serio->write = sunsu_serio_write; 1208 serio->id.type = SERIO_RS232;
1322 serio->open = sunsu_serio_open; 1209 if (up->su_type == SU_PORT_KBD) {
1323 serio->close = sunsu_serio_close; 1210 serio->id.proto = SERIO_SUNKBD;
1324 1211 strlcpy(serio->name, "sukbd", sizeof(serio->name));
1325 serio_register_port(serio);
1326 } else { 1212 } else {
1327 printk(KERN_WARNING "su%d: not enough memory for serio port\n", 1213 serio->id.proto = SERIO_SUN;
1328 channel); 1214 serio->id.extra = 1;
1215 strlcpy(serio->name, "sums", sizeof(serio->name));
1329 } 1216 }
1217 strlcpy(serio->phys,
1218 (!(up->port.line & 1) ? "su/serio0" : "su/serio1"),
1219 sizeof(serio->phys));
1220
1221 serio->write = sunsu_serio_write;
1222 serio->open = sunsu_serio_open;
1223 serio->close = sunsu_serio_close;
1224 serio->dev.parent = up->port.dev;
1225
1226 serio_register_port(serio);
1330#endif 1227#endif
1331 1228
1332 sunsu_change_speed(&up->port, up->cflag, 0, quot); 1229 sunsu_change_speed(&up->port, up->cflag, 0, quot);
@@ -1458,22 +1355,20 @@ static struct console sunsu_cons = {
1458 * Register console. 1355 * Register console.
1459 */ 1356 */
1460 1357
1461static inline struct console *SUNSU_CONSOLE(void) 1358static inline struct console *SUNSU_CONSOLE(int num_uart)
1462{ 1359{
1463 int i; 1360 int i;
1464 1361
1465 if (con_is_present()) 1362 if (con_is_present())
1466 return NULL; 1363 return NULL;
1467 1364
1468 for (i = 0; i < UART_NR; i++) { 1365 for (i = 0; i < num_uart; i++) {
1469 int this_minor = sunsu_reg.minor + i; 1366 int this_minor = sunsu_reg.minor + i;
1470 1367
1471 if ((this_minor - 64) == (serial_console - 1)) 1368 if ((this_minor - 64) == (serial_console - 1))
1472 break; 1369 break;
1473 } 1370 }
1474 if (i == UART_NR) 1371 if (i == num_uart)
1475 return NULL;
1476 if (sunsu_ports[i].port_node == 0)
1477 return NULL; 1372 return NULL;
1478 1373
1479 sunsu_cons.index = i; 1374 sunsu_cons.index = i;
@@ -1481,252 +1376,180 @@ static inline struct console *SUNSU_CONSOLE(void)
1481 return &sunsu_cons; 1376 return &sunsu_cons;
1482} 1377}
1483#else 1378#else
1484#define SUNSU_CONSOLE() (NULL) 1379#define SUNSU_CONSOLE(num_uart) (NULL)
1485#define sunsu_serial_console_init() do { } while (0) 1380#define sunsu_serial_console_init() do { } while (0)
1486#endif 1381#endif
1487 1382
1488static int __init sunsu_serial_init(void) 1383static enum su_type __devinit su_get_type(struct device_node *dp)
1489{ 1384{
1490 int instance, ret, i; 1385 struct device_node *ap = of_find_node_by_path("/aliases");
1491
1492 /* How many instances do we need? */
1493 instance = 0;
1494 for (i = 0; i < UART_NR; i++) {
1495 struct uart_sunsu_port *up = &sunsu_ports[i];
1496 1386
1497 if (up->su_type == SU_PORT_MS || 1387 if (ap) {
1498 up->su_type == SU_PORT_KBD) 1388 char *keyb = of_get_property(ap, "keyboard", NULL);
1499 continue; 1389 char *ms = of_get_property(ap, "mouse", NULL);
1500 1390
1501 spin_lock_init(&up->port.lock); 1391 if (keyb) {
1502 up->port.flags |= UPF_BOOT_AUTOCONF; 1392 if (dp == of_find_node_by_path(keyb))
1503 up->port.type = PORT_UNKNOWN; 1393 return SU_PORT_KBD;
1504 up->port.uartclk = (SU_BASE_BAUD * 16); 1394 }
1395 if (ms) {
1396 if (dp == of_find_node_by_path(ms))
1397 return SU_PORT_MS;
1398 }
1399 }
1505 1400
1506 sunsu_autoconfig(up); 1401 return SU_PORT_PORT;
1507 if (up->port.type == PORT_UNKNOWN) 1402}
1508 continue;
1509 1403
1510 up->port.line = instance++; 1404static int __devinit su_probe(struct of_device *op, const struct of_device_id *match)
1511 up->port.ops = &sunsu_pops; 1405{
1512 } 1406 static int inst;
1407 struct device_node *dp = op->node;
1408 struct uart_sunsu_port *up;
1409 struct resource *rp;
1410 int err;
1513 1411
1514 sunsu_reg.minor = sunserial_current_minor; 1412 if (inst >= UART_NR)
1413 return -EINVAL;
1515 1414
1516 sunsu_reg.nr = instance; 1415 up = &sunsu_ports[inst];
1416 up->port.line = inst;
1517 1417
1518 ret = uart_register_driver(&sunsu_reg); 1418 spin_lock_init(&up->port.lock);
1519 if (ret < 0)
1520 return ret;
1521 1419
1522 sunsu_reg.tty_driver->name_base = sunsu_reg.minor - 64; 1420 up->su_type = su_get_type(dp);
1523 1421
1524 sunserial_current_minor += instance; 1422 rp = &op->resource[0];
1423 up->port.mapbase = op->resource[0].start;
1525 1424
1526 sunsu_reg.cons = SUNSU_CONSOLE(); 1425 up->reg_size = (rp->end - rp->start) + 1;
1426 up->port.membase = of_ioremap(rp, 0, up->reg_size, "su");
1427 if (!up->port.membase)
1428 return -ENOMEM;
1527 1429
1528 for (i = 0; i < UART_NR; i++) { 1430 up->port.irq = op->irqs[0];
1529 struct uart_sunsu_port *up = &sunsu_ports[i];
1530 1431
1531 /* Do not register Keyboard/Mouse lines with UART 1432 up->port.dev = &op->dev;
1532 * layer.
1533 */
1534 if (up->su_type == SU_PORT_MS ||
1535 up->su_type == SU_PORT_KBD)
1536 continue;
1537 1433
1538 if (up->port.type == PORT_UNKNOWN) 1434 up->port.type = PORT_UNKNOWN;
1539 continue; 1435 up->port.uartclk = (SU_BASE_BAUD * 16);
1540 1436
1541 uart_add_one_port(&sunsu_reg, &up->port); 1437 err = 0;
1438 if (up->su_type == SU_PORT_KBD || up->su_type == SU_PORT_MS) {
1439 err = sunsu_kbd_ms_init(up);
1440 if (err)
1441 goto out_unmap;
1542 } 1442 }
1543 1443
1544 return 0; 1444 up->port.flags |= UPF_BOOT_AUTOCONF;
1545}
1546 1445
1547static int su_node_ok(int node, char *name, int namelen) 1446 sunsu_autoconfig(up);
1548{
1549 if (strncmp(name, "su", namelen) == 0 ||
1550 strncmp(name, "su_pnp", namelen) == 0)
1551 return 1;
1552
1553 if (strncmp(name, "serial", namelen) == 0) {
1554 char compat[32];
1555 int clen;
1556
1557 /* Is it _really_ a 'su' device? */
1558 clen = prom_getproperty(node, "compatible", compat, sizeof(compat));
1559 if (clen > 0) {
1560 if (strncmp(compat, "sab82532", 8) == 0) {
1561 /* Nope, Siemens serial, not for us. */
1562 return 0;
1563 }
1564 }
1565 return 1;
1566 }
1567 1447
1568 return 0; 1448 err = -ENODEV;
1569} 1449 if (up->port.type == PORT_UNKNOWN)
1450 goto out_unmap;
1570 1451
1571#define SU_PROPSIZE 128 1452 up->port.ops = &sunsu_pops;
1572 1453
1573/* 1454 err = uart_add_one_port(&sunsu_reg, &up->port);
1574 * Scan status structure. 1455 if (err)
1575 * "prop" is a local variable but it eats stack to keep it in each 1456 goto out_unmap;
1576 * stack frame of a recursive procedure.
1577 */
1578struct su_probe_scan {
1579 int msnode, kbnode; /* PROM nodes for mouse and keyboard */
1580 int msx, kbx; /* minors for mouse and keyboard */
1581 int devices; /* scan index */
1582 char prop[SU_PROPSIZE];
1583};
1584 1457
1585/* 1458 dev_set_drvdata(&op->dev, up);
1586 * We have several platforms which present 'su' in different parts
1587 * of the device tree. 'su' may be found under obio, ebus, isa and pci.
1588 * We walk over the tree and find them wherever PROM hides them.
1589 */
1590static void __init su_probe_any(struct su_probe_scan *t, int sunode)
1591{
1592 struct uart_sunsu_port *up;
1593 int len;
1594 1459
1595 if (t->devices >= UART_NR) 1460 inst++;
1596 return;
1597 1461
1598 for (; sunode != 0; sunode = prom_getsibling(sunode)) { 1462 return 0;
1599 len = prom_getproperty(sunode, "name", t->prop, SU_PROPSIZE); 1463
1600 if (len <= 1) 1464out_unmap:
1601 continue; /* Broken PROM node */ 1465 of_iounmap(up->port.membase, up->reg_size);
1602 1466 return err;
1603 if (su_node_ok(sunode, t->prop, len)) {
1604 up = &sunsu_ports[t->devices];
1605 if (t->kbnode != 0 && sunode == t->kbnode) {
1606 t->kbx = t->devices;
1607 up->su_type = SU_PORT_KBD;
1608 } else if (t->msnode != 0 && sunode == t->msnode) {
1609 t->msx = t->devices;
1610 up->su_type = SU_PORT_MS;
1611 } else {
1612#ifdef CONFIG_SPARC64
1613 /*
1614 * Do not attempt to use the truncated
1615 * keyboard/mouse ports as serial ports
1616 * on Ultras with PC keyboard attached.
1617 */
1618 if (prom_getbool(sunode, "mouse"))
1619 continue;
1620 if (prom_getbool(sunode, "keyboard"))
1621 continue;
1622#endif
1623 up->su_type = SU_PORT_PORT;
1624 }
1625 up->port_node = sunode;
1626 ++t->devices;
1627 } else {
1628 su_probe_any(t, prom_getchild(sunode));
1629 }
1630 }
1631} 1467}
1632 1468
1633static int __init sunsu_probe(void) 1469static int __devexit su_remove(struct of_device *dev)
1634{ 1470{
1635 int node; 1471 struct uart_sunsu_port *up = dev_get_drvdata(&dev->dev);;
1636 int len;
1637 struct su_probe_scan scan;
1638 1472
1639 /* 1473 if (up->su_type == SU_PORT_MS ||
1640 * First, we scan the tree. 1474 up->su_type == SU_PORT_KBD) {
1641 */ 1475#ifdef CONFIG_SERIO
1642 scan.devices = 0; 1476 serio_unregister_port(&up->serio);
1643 scan.msx = -1; 1477#endif
1644 scan.kbx = -1; 1478 } else if (up->port.type != PORT_UNKNOWN)
1645 scan.kbnode = 0; 1479 uart_remove_one_port(&sunsu_reg, &up->port);
1646 scan.msnode = 0;
1647 1480
1648 /* 1481 return 0;
1649 * Get the nodes for keyboard and mouse from 'aliases'... 1482}
1650 */
1651 node = prom_getchild(prom_root_node);
1652 node = prom_searchsiblings(node, "aliases");
1653 if (node != 0) {
1654 len = prom_getproperty(node, "keyboard", scan.prop, SU_PROPSIZE);
1655 if (len > 0) {
1656 scan.prop[len] = 0;
1657 scan.kbnode = prom_finddevice(scan.prop);
1658 }
1659 1483
1660 len = prom_getproperty(node, "mouse", scan.prop, SU_PROPSIZE); 1484static struct of_device_id su_match[] = {
1661 if (len > 0) { 1485 {
1662 scan.prop[len] = 0; 1486 .name = "su",
1663 scan.msnode = prom_finddevice(scan.prop); 1487 },
1664 } 1488 {
1665 } 1489 .name = "su_pnp",
1490 },
1491 {
1492 .name = "serial",
1493 .compatible = "su",
1494 },
1495 {},
1496};
1497MODULE_DEVICE_TABLE(of, su_match);
1666 1498
1667 su_probe_any(&scan, prom_getchild(prom_root_node)); 1499static struct of_platform_driver su_driver = {
1500 .name = "su",
1501 .match_table = su_match,
1502 .probe = su_probe,
1503 .remove = __devexit_p(su_remove),
1504};
1668 1505
1669 /* 1506static int num_uart;
1670 * Second, we process the special case of keyboard and mouse.
1671 *
1672 * Currently if we got keyboard and mouse hooked to "su" ports
1673 * we do not use any possible remaining "su" as a serial port.
1674 * Thus, we ignore values of .msx and .kbx, then compact ports.
1675 */
1676 if (scan.msx != -1 && scan.kbx != -1) {
1677 sunsu_ports[0].su_type = SU_PORT_MS;
1678 sunsu_ports[0].port_node = scan.msnode;
1679 sunsu_kbd_ms_init(&sunsu_ports[0], 0);
1680 1507
1681 sunsu_ports[1].su_type = SU_PORT_KBD; 1508static int __init sunsu_init(void)
1682 sunsu_ports[1].port_node = scan.kbnode; 1509{
1683 sunsu_kbd_ms_init(&sunsu_ports[1], 1); 1510 struct device_node *dp;
1511 int err;
1684 1512
1685 return 0; 1513 num_uart = 0;
1514 for_each_node_by_name(dp, "su") {
1515 if (su_get_type(dp) == SU_PORT_PORT)
1516 num_uart++;
1686 } 1517 }
1687 1518 for_each_node_by_name(dp, "su_pnp") {
1688 if (scan.msx != -1 || scan.kbx != -1) { 1519 if (su_get_type(dp) == SU_PORT_PORT)
1689 printk("sunsu_probe: cannot match keyboard and mouse, confused\n"); 1520 num_uart++;
1690 return -ENODEV; 1521 }
1522 for_each_node_by_name(dp, "serial") {
1523 if (of_device_is_compatible(dp, "su")) {
1524 if (su_get_type(dp) == SU_PORT_PORT)
1525 num_uart++;
1526 }
1691 } 1527 }
1692 1528
1693 if (scan.devices == 0) 1529 if (num_uart) {
1694 return -ENODEV; 1530 sunsu_reg.minor = sunserial_current_minor;
1531 sunsu_reg.nr = num_uart;
1532 err = uart_register_driver(&sunsu_reg);
1533 if (err)
1534 return err;
1535 sunsu_reg.tty_driver->name_base = sunsu_reg.minor - 64;
1536 sunserial_current_minor += num_uart;
1537 sunsu_reg.cons = SUNSU_CONSOLE(num_uart);
1538 }
1695 1539
1696 /* 1540 err = of_register_driver(&su_driver, &of_bus_type);
1697 * Console must be initiated after the generic initialization. 1541 if (err && num_uart)
1698 */ 1542 uart_unregister_driver(&sunsu_reg);
1699 sunsu_serial_init();
1700 1543
1701 return 0; 1544 return err;
1702} 1545}
1703 1546
1704static void __exit sunsu_exit(void) 1547static void __exit sunsu_exit(void)
1705{ 1548{
1706 int i, saw_uart; 1549 if (num_uart)
1707
1708 saw_uart = 0;
1709 for (i = 0; i < UART_NR; i++) {
1710 struct uart_sunsu_port *up = &sunsu_ports[i];
1711
1712 if (up->su_type == SU_PORT_MS ||
1713 up->su_type == SU_PORT_KBD) {
1714#ifdef CONFIG_SERIO
1715 if (up->serio) {
1716 serio_unregister_port(up->serio);
1717 up->serio = NULL;
1718 }
1719#endif
1720 } else if (up->port.type != PORT_UNKNOWN) {
1721 uart_remove_one_port(&sunsu_reg, &up->port);
1722 saw_uart++;
1723 }
1724 }
1725
1726 if (saw_uart)
1727 uart_unregister_driver(&sunsu_reg); 1550 uart_unregister_driver(&sunsu_reg);
1728} 1551}
1729 1552
1730module_init(sunsu_probe); 1553module_init(sunsu_init);
1731module_exit(sunsu_exit); 1554module_exit(sunsu_exit);
1732MODULE_LICENSE("GPL"); 1555MODULE_LICENSE("GPL");