]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - drivers/serial/sunsu.c
[SPARC/64] constify of_get_property return: drivers
[linux-2.6.git] / drivers / serial / sunsu.c
index 73a043b914ef61a1f32b3e9d35b9d9e3e595af98..bfd44177a2152cd9f9d078cecd5c559ad350f4dd 100644 (file)
  *   David S. Miller (davem@davemloft.net), 2002-Jul-29
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/errno.h>
 #include <linux/tty.h>
@@ -311,7 +309,7 @@ static void sunsu_enable_ms(struct uart_port *port)
 }
 
 static struct tty_struct *
-receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs *regs)
+receive_chars(struct uart_sunsu_port *up, unsigned char *status)
 {
        struct tty_struct *tty = up->port.info->tty;
        unsigned char ch, flag;
@@ -368,7 +366,7 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs
                        else if (*status & UART_LSR_FE)
                                flag = TTY_FRAME;
                }
-               if (uart_handle_sysrq_char(&up->port, ch, regs))
+               if (uart_handle_sysrq_char(&up->port, ch))
                        goto ignore_char;
                if ((*status & up->port.ignore_status_mask) == 0)
                        tty_insert_flip_char(tty, ch, flag);
@@ -446,7 +444,7 @@ static void check_modem_status(struct uart_sunsu_port *up)
        wake_up_interruptible(&up->port.info->delta_msr_wait);
 }
 
-static irqreturn_t sunsu_serial_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sunsu_serial_interrupt(int irq, void *dev_id)
 {
        struct uart_sunsu_port *up = dev_id;
        unsigned long flags;
@@ -460,7 +458,7 @@ static irqreturn_t sunsu_serial_interrupt(int irq, void *dev_id, struct pt_regs
                status = serial_inp(up, UART_LSR);
                tty = NULL;
                if (status & UART_LSR_DR)
-                       tty = receive_chars(up, &status, regs);
+                       tty = receive_chars(up, &status);
                check_modem_status(up);
                if (status & UART_LSR_THRE)
                        transmit_chars(up);
@@ -498,7 +496,7 @@ static void sunsu_change_mouse_baud(struct uart_sunsu_port *up)
        sunsu_change_speed(&up->port, up->cflag, 0, quot);
 }
 
-static void receive_kbd_ms_chars(struct uart_sunsu_port *up, struct pt_regs *regs, int is_break)
+static void receive_kbd_ms_chars(struct uart_sunsu_port *up, int is_break)
 {
        do {
                unsigned char ch = serial_inp(up, UART_RX);
@@ -506,7 +504,7 @@ static void receive_kbd_ms_chars(struct uart_sunsu_port *up, struct pt_regs *reg
                /* Stop-A is handled by drivers/char/keyboard.c now. */
                if (up->su_type == SU_PORT_KBD) {
 #ifdef CONFIG_SERIO
-                       serio_interrupt(&up->serio, ch, 0, regs);
+                       serio_interrupt(&up->serio, ch, 0);
 #endif
                } else if (up->su_type == SU_PORT_MS) {
                        int ret = suncore_mouse_baud_detection(ch, is_break);
@@ -520,7 +518,7 @@ static void receive_kbd_ms_chars(struct uart_sunsu_port *up, struct pt_regs *reg
 
                        case 0:
 #ifdef CONFIG_SERIO
-                               serio_interrupt(&up->serio, ch, 0, regs);
+                               serio_interrupt(&up->serio, ch, 0);
 #endif
                                break;
                        };
@@ -528,7 +526,7 @@ static void receive_kbd_ms_chars(struct uart_sunsu_port *up, struct pt_regs *reg
        } while (serial_in(up, UART_LSR) & UART_LSR_DR);
 }
 
-static irqreturn_t sunsu_kbd_ms_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sunsu_kbd_ms_interrupt(int irq, void *dev_id)
 {
        struct uart_sunsu_port *up = dev_id;
 
@@ -536,8 +534,7 @@ static irqreturn_t sunsu_kbd_ms_interrupt(int irq, void *dev_id, struct pt_regs
                unsigned char status = serial_inp(up, UART_LSR);
 
                if ((status & UART_LSR_DR) || (status & UART_LSR_BI))
-                       receive_kbd_ms_chars(up, regs,
-                                            (status & UART_LSR_BI) != 0);
+                       receive_kbd_ms_chars(up, (status & UART_LSR_BI) != 0);
        }
 
        return IRQ_HANDLED;
@@ -668,10 +665,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);
@@ -895,8 +892,8 @@ sunsu_change_speed(struct uart_port *port, unsigned int cflag,
 }
 
 static void
-sunsu_set_termios(struct uart_port *port, struct termios *termios,
-                 struct termios *old)
+sunsu_set_termios(struct uart_port *port, struct ktermios *termios,
+                 struct ktermios *old)
 {
        unsigned int baud, quot;
 
@@ -1201,6 +1198,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;
@@ -1385,8 +1387,8 @@ static enum su_type __devinit su_get_type(struct device_node *dp)
        struct device_node *ap = of_find_node_by_path("/aliases");
 
        if (ap) {
-               char *keyb = of_get_property(ap, "keyboard", NULL);
-               char *ms = of_get_property(ap, "mouse", NULL);
+               const char *keyb = of_get_property(ap, "keyboard", NULL);
+               const char *ms = of_get_property(ap, "mouse", NULL);
 
                if (keyb) {
                        if (dp == of_find_node_by_path(keyb))
@@ -1407,25 +1409,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];
 
@@ -1437,8 +1449,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;
@@ -1462,21 +1479,28 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m
        return 0;
 
 out_unmap:
-       of_iounmap(up->port.membase, up->reg_size);
+       of_iounmap(&op->resource[0], up->port.membase, up->reg_size);
        return err;
 }
 
-static int __devexit su_remove(struct of_device *dev)
+static int __devexit su_remove(struct of_device *op)
 {
-       struct uart_sunsu_port *up = dev_get_drvdata(&dev->dev);;
+       struct uart_sunsu_port *up = dev_get_drvdata(&op->dev);
 
        if (up->su_type == SU_PORT_MS ||
            up->su_type == SU_PORT_KBD) {
 #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);
+       }
+
+       if (up->port.membase)
+               of_iounmap(&op->resource[0], up->port.membase, up->reg_size);
+
+       dev_set_drvdata(&op->dev, NULL);
 
        return 0;
 }