aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/sunzilog.c71
1 files changed, 35 insertions, 36 deletions
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index 18df10f49aff..47bc3d57e019 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -68,9 +68,6 @@ static int num_sunzilog;
68#define NUM_SUNZILOG num_sunzilog 68#define NUM_SUNZILOG num_sunzilog
69#define NUM_CHANNELS (NUM_SUNZILOG * 2) 69#define NUM_CHANNELS (NUM_SUNZILOG * 2)
70 70
71#define KEYBOARD_LINE 0x2
72#define MOUSE_LINE 0x3
73
74#define ZS_CLOCK 4915200 /* Zilog input clock rate. */ 71#define ZS_CLOCK 4915200 /* Zilog input clock rate. */
75#define ZS_CLOCK_DIVISOR 16 /* Divisor this driver uses. */ 72#define ZS_CLOCK_DIVISOR 16 /* Divisor this driver uses. */
76 73
@@ -1225,12 +1222,10 @@ static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channe
1225{ 1222{
1226 int baud, brg; 1223 int baud, brg;
1227 1224
1228 if (channel == KEYBOARD_LINE) { 1225 if (up->flags & SUNZILOG_FLAG_CONS_KEYB) {
1229 up->flags |= SUNZILOG_FLAG_CONS_KEYB;
1230 up->cflag = B1200 | CS8 | CLOCAL | CREAD; 1226 up->cflag = B1200 | CS8 | CLOCAL | CREAD;
1231 baud = 1200; 1227 baud = 1200;
1232 } else { 1228 } else {
1233 up->flags |= SUNZILOG_FLAG_CONS_MOUSE;
1234 up->cflag = B4800 | CS8 | CLOCAL | CREAD; 1229 up->cflag = B4800 | CS8 | CLOCAL | CREAD;
1235 baud = 4800; 1230 baud = 4800;
1236 } 1231 }
@@ -1243,14 +1238,14 @@ static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channe
1243} 1238}
1244 1239
1245#ifdef CONFIG_SERIO 1240#ifdef CONFIG_SERIO
1246static void __init sunzilog_register_serio(struct uart_sunzilog_port *up, int channel) 1241static void __init sunzilog_register_serio(struct uart_sunzilog_port *up)
1247{ 1242{
1248 struct serio *serio = &up->serio; 1243 struct serio *serio = &up->serio;
1249 1244
1250 serio->port_data = up; 1245 serio->port_data = up;
1251 1246
1252 serio->id.type = SERIO_RS232; 1247 serio->id.type = SERIO_RS232;
1253 if (channel == KEYBOARD_LINE) { 1248 if (up->flags & SUNZILOG_FLAG_CONS_KEYB) {
1254 serio->id.proto = SERIO_SUNKBD; 1249 serio->id.proto = SERIO_SUNKBD;
1255 strlcpy(serio->name, "zskbd", sizeof(serio->name)); 1250 strlcpy(serio->name, "zskbd", sizeof(serio->name));
1256 } else { 1251 } else {
@@ -1259,7 +1254,8 @@ static void __init sunzilog_register_serio(struct uart_sunzilog_port *up, int ch
1259 strlcpy(serio->name, "zsms", sizeof(serio->name)); 1254 strlcpy(serio->name, "zsms", sizeof(serio->name));
1260 } 1255 }
1261 strlcpy(serio->phys, 1256 strlcpy(serio->phys,
1262 (channel == KEYBOARD_LINE ? "zs/serio0" : "zs/serio1"), 1257 ((up->flags & SUNZILOG_FLAG_CONS_KEYB) ?
1258 "zs/serio0" : "zs/serio1"),
1263 sizeof(serio->phys)); 1259 sizeof(serio->phys));
1264 1260
1265 serio->write = sunzilog_serio_write; 1261 serio->write = sunzilog_serio_write;
@@ -1286,8 +1282,8 @@ static void __init sunzilog_init_hw(struct uart_sunzilog_port *up)
1286 (void) read_zsreg(channel, R0); 1282 (void) read_zsreg(channel, R0);
1287 } 1283 }
1288 1284
1289 if (up->port.line == KEYBOARD_LINE || 1285 if (up->flags & (SUNZILOG_FLAG_CONS_KEYB |
1290 up->port.line == MOUSE_LINE) { 1286 SUNZILOG_FLAG_CONS_MOUSE)) {
1291 sunzilog_init_kbdms(up, up->port.line); 1287 sunzilog_init_kbdms(up, up->port.line);
1292 up->curregs[R9] |= (NV | MIE); 1288 up->curregs[R9] |= (NV | MIE);
1293 write_zsreg(channel, R9, up->curregs[R9]); 1289 write_zsreg(channel, R9, up->curregs[R9]);
@@ -1313,36 +1309,26 @@ static void __init sunzilog_init_hw(struct uart_sunzilog_port *up)
1313 spin_unlock_irqrestore(&up->port.lock, flags); 1309 spin_unlock_irqrestore(&up->port.lock, flags);
1314 1310
1315#ifdef CONFIG_SERIO 1311#ifdef CONFIG_SERIO
1316 if (up->port.line == KEYBOARD_LINE || up->port.line == MOUSE_LINE) 1312 if (up->flags & (SUNZILOG_FLAG_CONS_KEYB |
1317 sunzilog_register_serio(up, up->port.line); 1313 SUNZILOG_FLAG_CONS_MOUSE))
1314 sunzilog_register_serio(up);
1318#endif 1315#endif
1319} 1316}
1320 1317
1321static int __devinit zs_get_instance(struct device_node *dp)
1322{
1323 int ret;
1324
1325 ret = of_getintprop_default(dp, "slave", -1);
1326 if (ret != -1)
1327 return ret;
1328
1329 if (of_find_property(dp, "keyboard", NULL))
1330 ret = 1;
1331 else
1332 ret = 0;
1333
1334 return ret;
1335}
1336
1337static int zilog_irq = -1; 1318static int zilog_irq = -1;
1338 1319
1339static int __devinit zs_probe(struct of_device *op, const struct of_device_id *match) 1320static int __devinit zs_probe(struct of_device *op, const struct of_device_id *match)
1340{ 1321{
1322 static int inst;
1341 struct uart_sunzilog_port *up; 1323 struct uart_sunzilog_port *up;
1342 struct zilog_layout __iomem *rp; 1324 struct zilog_layout __iomem *rp;
1343 int inst = zs_get_instance(op->node); 1325 int keyboard_mouse;
1344 int err; 1326 int err;
1345 1327
1328 keyboard_mouse = 0;
1329 if (of_find_property(op->node, "keyboard", NULL))
1330 keyboard_mouse = 1;
1331
1346 sunzilog_chip_regs[inst] = of_ioremap(&op->resource[0], 0, 1332 sunzilog_chip_regs[inst] = of_ioremap(&op->resource[0], 0,
1347 sizeof(struct zilog_layout), 1333 sizeof(struct zilog_layout),
1348 "zs"); 1334 "zs");
@@ -1369,7 +1355,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
1369 up[0].port.line = (inst * 2) + 0; 1355 up[0].port.line = (inst * 2) + 0;
1370 up[0].port.dev = &op->dev; 1356 up[0].port.dev = &op->dev;
1371 up[0].flags |= SUNZILOG_FLAG_IS_CHANNEL_A; 1357 up[0].flags |= SUNZILOG_FLAG_IS_CHANNEL_A;
1372 if (inst == 1) 1358 if (keyboard_mouse)
1373 up[0].flags |= SUNZILOG_FLAG_CONS_KEYB; 1359 up[0].flags |= SUNZILOG_FLAG_CONS_KEYB;
1374 sunzilog_init_hw(&up[0]); 1360 sunzilog_init_hw(&up[0]);
1375 1361
@@ -1386,11 +1372,11 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
1386 up[1].port.line = (inst * 2) + 1; 1372 up[1].port.line = (inst * 2) + 1;
1387 up[1].port.dev = &op->dev; 1373 up[1].port.dev = &op->dev;
1388 up[1].flags |= 0; 1374 up[1].flags |= 0;
1389 if (inst == 1) 1375 if (keyboard_mouse)
1390 up[1].flags |= SUNZILOG_FLAG_CONS_MOUSE; 1376 up[1].flags |= SUNZILOG_FLAG_CONS_MOUSE;
1391 sunzilog_init_hw(&up[1]); 1377 sunzilog_init_hw(&up[1]);
1392 1378
1393 if (inst != 1) { 1379 if (!keyboard_mouse) {
1394 err = uart_add_one_port(&sunzilog_reg, &up[0].port); 1380 err = uart_add_one_port(&sunzilog_reg, &up[0].port);
1395 if (err) { 1381 if (err) {
1396 of_iounmap(rp, sizeof(struct zilog_layout)); 1382 of_iounmap(rp, sizeof(struct zilog_layout));
@@ -1402,10 +1388,19 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
1402 of_iounmap(rp, sizeof(struct zilog_layout)); 1388 of_iounmap(rp, sizeof(struct zilog_layout));
1403 return err; 1389 return err;
1404 } 1390 }
1391 } else {
1392 printk(KERN_INFO "%s: Keyboard at MMIO %lx (irq = %d) "
1393 "is a zs\n",
1394 op->dev.bus_id, up[0].port.mapbase, op->irqs[0]);
1395 printk(KERN_INFO "%s: Mouse at MMIO %lx (irq = %d) "
1396 "is a zs\n",
1397 op->dev.bus_id, up[1].port.mapbase, op->irqs[0]);
1405 } 1398 }
1406 1399
1407 dev_set_drvdata(&op->dev, &up[0]); 1400 dev_set_drvdata(&op->dev, &up[0]);
1408 1401
1402 inst++;
1403
1409 return 0; 1404 return 0;
1410} 1405}
1411 1406
@@ -1454,10 +1449,15 @@ static int __init sunzilog_init(void)
1454{ 1449{
1455 struct device_node *dp; 1450 struct device_node *dp;
1456 int err, uart_count; 1451 int err, uart_count;
1452 int num_keybms;
1457 1453
1458 NUM_SUNZILOG = 0; 1454 NUM_SUNZILOG = 0;
1459 for_each_node_by_name(dp, "zs") 1455 num_keybms = 0;
1456 for_each_node_by_name(dp, "zs") {
1460 NUM_SUNZILOG++; 1457 NUM_SUNZILOG++;
1458 if (of_find_property(dp, "keyboard", NULL))
1459 num_keybms++;
1460 }
1461 1461
1462 uart_count = 0; 1462 uart_count = 0;
1463 if (NUM_SUNZILOG) { 1463 if (NUM_SUNZILOG) {
@@ -1467,8 +1467,7 @@ static int __init sunzilog_init(void)
1467 if (err) 1467 if (err)
1468 goto out; 1468 goto out;
1469 1469
1470 /* Subtract 1 for keyboard, 1 for mouse. */ 1470 uart_count = (NUM_SUNZILOG * 2) - (2 * num_keybms);
1471 uart_count = (NUM_SUNZILOG * 2) - 2;
1472 1471
1473 sunzilog_reg.nr = uart_count; 1472 sunzilog_reg.nr = uart_count;
1474 sunzilog_reg.minor = sunserial_current_minor; 1473 sunzilog_reg.minor = sunserial_current_minor;