X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=drivers%2Fserial%2Fsunsu.c;h=d3a5aeee73a34b33bb4736b751a2aacab8ec5e8a;hb=bb0885900de49b5822d7e8c91c1adf9a0fcc228b;hp=72c86d0017f5dd4c70fa92208ac6bb81746ef6b3;hpb=e37a72de84d27ee8bc0e7dbb5c2f1774ed306dbb;p=powerpc.git diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index 72c86d0017..d3a5aeee73 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c @@ -667,10 +667,10 @@ static int sunsu_startup(struct uart_port *port) if (up->su_type != SU_PORT_PORT) { retval = request_irq(up->port.irq, sunsu_kbd_ms_interrupt, - SA_SHIRQ, su_typev[up->su_type], up); + IRQF_SHARED, su_typev[up->su_type], up); } else { retval = request_irq(up->port.irq, sunsu_serial_interrupt, - SA_SHIRQ, su_typev[up->su_type], up); + IRQF_SHARED, su_typev[up->su_type], up); } if (retval) { printk("su: Cannot register IRQ %d\n", up->port.irq); @@ -1200,6 +1200,11 @@ static int __init sunsu_kbd_ms_init(struct uart_sunsu_port *up) if (up->port.type == PORT_UNKNOWN) return -ENODEV; + printk("%s: %s port at %lx, irq %u\n", + to_of_device(up->port.dev)->node->full_name, + (up->su_type == SU_PORT_KBD) ? "Keyboard" : "Mouse", + up->port.mapbase, up->port.irq); + #ifdef CONFIG_SERIO serio = &up->serio; serio->port_data = up; @@ -1406,25 +1411,35 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m struct device_node *dp = op->node; struct uart_sunsu_port *up; struct resource *rp; + enum su_type type; int err; - if (inst >= UART_NR) - return -EINVAL; + type = su_get_type(dp); + if (type == SU_PORT_PORT) { + if (inst >= UART_NR) + return -EINVAL; + up = &sunsu_ports[inst]; + } else { + up = kzalloc(sizeof(*up), GFP_KERNEL); + if (!up) + return -ENOMEM; + } - up = &sunsu_ports[inst]; up->port.line = inst; spin_lock_init(&up->port.lock); - up->su_type = su_get_type(dp); + up->su_type = type; rp = &op->resource[0]; - up->port.mapbase = op->resource[0].start; - + up->port.mapbase = rp->start; up->reg_size = (rp->end - rp->start) + 1; up->port.membase = of_ioremap(rp, 0, up->reg_size, "su"); - if (!up->port.membase) + if (!up->port.membase) { + if (type != SU_PORT_PORT) + kfree(up); return -ENOMEM; + } up->port.irq = op->irqs[0]; @@ -1436,8 +1451,13 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m err = 0; if (up->su_type == SU_PORT_KBD || up->su_type == SU_PORT_MS) { err = sunsu_kbd_ms_init(up); - if (err) + if (err) { + kfree(up); goto out_unmap; + } + dev_set_drvdata(&op->dev, up); + + return 0; } up->port.flags |= UPF_BOOT_AUTOCONF; @@ -1474,8 +1494,12 @@ static int __devexit su_remove(struct of_device *dev) #ifdef CONFIG_SERIO serio_unregister_port(&up->serio); #endif - } else if (up->port.type != PORT_UNKNOWN) + kfree(up); + } else if (up->port.type != PORT_UNKNOWN) { uart_remove_one_port(&sunsu_reg, &up->port); + } + + dev_set_drvdata(&dev->dev, NULL); return 0; }