aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/sunsu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial/sunsu.c')
-rw-r--r--drivers/serial/sunsu.c40
1 files changed, 31 insertions, 9 deletions
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index f9013baba05b..d3a5aeee73a3 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -1200,6 +1200,11 @@ static int __init sunsu_kbd_ms_init(struct uart_sunsu_port *up)
1200 if (up->port.type == PORT_UNKNOWN) 1200 if (up->port.type == PORT_UNKNOWN)
1201 return -ENODEV; 1201 return -ENODEV;
1202 1202
1203 printk("%s: %s port at %lx, irq %u\n",
1204 to_of_device(up->port.dev)->node->full_name,
1205 (up->su_type == SU_PORT_KBD) ? "Keyboard" : "Mouse",
1206 up->port.mapbase, up->port.irq);
1207
1203#ifdef CONFIG_SERIO 1208#ifdef CONFIG_SERIO
1204 serio = &up->serio; 1209 serio = &up->serio;
1205 serio->port_data = up; 1210 serio->port_data = up;
@@ -1406,25 +1411,35 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m
1406 struct device_node *dp = op->node; 1411 struct device_node *dp = op->node;
1407 struct uart_sunsu_port *up; 1412 struct uart_sunsu_port *up;
1408 struct resource *rp; 1413 struct resource *rp;
1414 enum su_type type;
1409 int err; 1415 int err;
1410 1416
1411 if (inst >= UART_NR) 1417 type = su_get_type(dp);
1412 return -EINVAL; 1418 if (type == SU_PORT_PORT) {
1419 if (inst >= UART_NR)
1420 return -EINVAL;
1421 up = &sunsu_ports[inst];
1422 } else {
1423 up = kzalloc(sizeof(*up), GFP_KERNEL);
1424 if (!up)
1425 return -ENOMEM;
1426 }
1413 1427
1414 up = &sunsu_ports[inst];
1415 up->port.line = inst; 1428 up->port.line = inst;
1416 1429
1417 spin_lock_init(&up->port.lock); 1430 spin_lock_init(&up->port.lock);
1418 1431
1419 up->su_type = su_get_type(dp); 1432 up->su_type = type;
1420 1433
1421 rp = &op->resource[0]; 1434 rp = &op->resource[0];
1422 up->port.mapbase = op->resource[0].start; 1435 up->port.mapbase = rp->start;
1423
1424 up->reg_size = (rp->end - rp->start) + 1; 1436 up->reg_size = (rp->end - rp->start) + 1;
1425 up->port.membase = of_ioremap(rp, 0, up->reg_size, "su"); 1437 up->port.membase = of_ioremap(rp, 0, up->reg_size, "su");
1426 if (!up->port.membase) 1438 if (!up->port.membase) {
1439 if (type != SU_PORT_PORT)
1440 kfree(up);
1427 return -ENOMEM; 1441 return -ENOMEM;
1442 }
1428 1443
1429 up->port.irq = op->irqs[0]; 1444 up->port.irq = op->irqs[0];
1430 1445
@@ -1436,8 +1451,11 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m
1436 err = 0; 1451 err = 0;
1437 if (up->su_type == SU_PORT_KBD || up->su_type == SU_PORT_MS) { 1452 if (up->su_type == SU_PORT_KBD || up->su_type == SU_PORT_MS) {
1438 err = sunsu_kbd_ms_init(up); 1453 err = sunsu_kbd_ms_init(up);
1439 if (err) 1454 if (err) {
1455 kfree(up);
1440 goto out_unmap; 1456 goto out_unmap;
1457 }
1458 dev_set_drvdata(&op->dev, up);
1441 1459
1442 return 0; 1460 return 0;
1443 } 1461 }
@@ -1476,8 +1494,12 @@ static int __devexit su_remove(struct of_device *dev)
1476#ifdef CONFIG_SERIO 1494#ifdef CONFIG_SERIO
1477 serio_unregister_port(&up->serio); 1495 serio_unregister_port(&up->serio);
1478#endif 1496#endif
1479 } else if (up->port.type != PORT_UNKNOWN) 1497 kfree(up);
1498 } else if (up->port.type != PORT_UNKNOWN) {
1480 uart_remove_one_port(&sunsu_reg, &up->port); 1499 uart_remove_one_port(&sunsu_reg, &up->port);
1500 }
1501
1502 dev_set_drvdata(&dev->dev, NULL);
1481 1503
1482 return 0; 1504 return 0;
1483} 1505}