[PATCH] ioc4 serial support - mostly cleanup
authorPat Gefre <pfg@sgi.com>
Sun, 30 Oct 2005 23:02:49 +0000 (15:02 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Mon, 31 Oct 2005 01:37:24 +0000 (17:37 -0800)
Various small mods for the Altix ioc4 serial driver - mostly cleanup:
- remove UIF_INITIALIZED usage
- use the 'lock' from uart_port
- better multiple card support

Signed-off-by: Patrick Gefre <pfg@sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
drivers/serial/ioc4_serial.c

index f88fdd48068584bae364d291d6eb0f399ce47948..771676abee60195dc07eeabe652719e9cbbc02c4 100644 (file)
@@ -308,6 +308,8 @@ struct ioc4_serial {
 typedef void ioc4_intr_func_f(void *, uint32_t);
 typedef ioc4_intr_func_f *ioc4_intr_func_t;
 
+static unsigned int Num_of_ioc4_cards;
+
 /* defining this will get you LOTS of great debug info */
 //#define DEBUG_INTERRUPTS
 #define DPRINT_CONFIG(_x...)   ;
@@ -317,7 +319,8 @@ typedef ioc4_intr_func_f *ioc4_intr_func_t;
 #define WAKEUP_CHARS   256
 
 /* number of characters we want to transmit to the lower level at a time */
-#define IOC4_MAX_CHARS 128
+#define IOC4_MAX_CHARS 256
+#define IOC4_FIFO_CHARS        255
 
 /* Device name we're using */
 #define DEVICE_NAME    "ttyIOC"
@@ -1038,6 +1041,7 @@ static int inline ioc4_attach_local(struct ioc4_driver_data *idd)
                        return -ENOMEM;
                }
                memset(port, 0, sizeof(struct ioc4_port));
+               spin_lock_init(&port->ip_lock);
 
                /* we need to remember the previous ones, to point back to
                 * them farther down - setting up the ring buffers.
@@ -1691,12 +1695,14 @@ ioc4_change_speed(struct uart_port *the_port,
                baud = 9600;
 
        if (!the_port->fifosize)
-               the_port->fifosize = IOC4_MAX_CHARS;
+               the_port->fifosize = IOC4_FIFO_CHARS;
        the_port->timeout = ((the_port->fifosize * HZ * bits) / (baud / 10));
        the_port->timeout += HZ / 50;   /* Add .02 seconds of slop */
 
        the_port->ignore_status_mask = N_ALL_INPUT;
 
+       info->tty->low_latency = 1;
+
        if (I_IGNPAR(info->tty))
                the_port->ignore_status_mask &= ~(N_PARITY_ERROR
                                                | N_FRAMING_ERROR);
@@ -1742,7 +1748,6 @@ ioc4_change_speed(struct uart_port *the_port,
  */
 static inline int ic4_startup_local(struct uart_port *the_port)
 {
-       int retval = 0;
        struct ioc4_port *port;
        struct uart_info *info;
 
@@ -1754,9 +1759,6 @@ static inline int ic4_startup_local(struct uart_port *the_port)
                return -1;
 
        info = the_port->info;
-       if (info->flags & UIF_INITIALIZED) {
-               return retval;
-       }
 
        if (info->tty) {
                set_bit(TTY_IO_ERROR, &info->tty->flags);
@@ -1775,7 +1777,6 @@ static inline int ic4_startup_local(struct uart_port *the_port)
        /* set the speed of the serial port */
        ioc4_change_speed(the_port, info->tty->termios, (struct termios *)0);
 
-       info->flags |= UIF_INITIALIZED;
        return 0;
 }
 
@@ -1785,9 +1786,13 @@ static inline int ic4_startup_local(struct uart_port *the_port)
  */
 static void ioc4_cb_output_lowat(struct ioc4_port *port)
 {
+       unsigned long pflags;
+
        /* ip_lock is set on the call here */
        if (port->ip_port) {
+               spin_lock_irqsave(&port->ip_port->lock, pflags);
                transmit_chars(port->ip_port);
+               spin_unlock_irqrestore(&port->ip_port->lock, pflags);
        }
 }
 
@@ -2064,8 +2069,7 @@ static inline int do_read(struct uart_port *the_port, unsigned char *buf,
         * available data as long as it returns some.
         */
        /* Re-arm the timer */
-       writel(port->ip_rx_cons | IOC4_SRCIR_ARM,
-                       &port->ip_serial_regs->srcir);
+       writel(port->ip_rx_cons | IOC4_SRCIR_ARM, &port->ip_serial_regs->srcir);
 
        prod_ptr = readl(&port->ip_serial_regs->srpir) & PROD_CONS_MASK;
        cons_ptr = port->ip_rx_cons;
@@ -2299,6 +2303,7 @@ static inline int do_read(struct uart_port *the_port, unsigned char *buf,
        }
        return total;
 }
+
 /**
  * receive_chars - upper level read. Called with ip_lock.
  * @the_port: port to read from
@@ -2307,9 +2312,11 @@ static void receive_chars(struct uart_port *the_port)
 {
        struct tty_struct *tty;
        unsigned char ch[IOC4_MAX_CHARS];
-       int read_count, request_count;
+       int read_count, request_count = IOC4_MAX_CHARS;
        struct uart_icount *icount;
        struct uart_info *info = the_port->info;
+       int flip = 0;
+       unsigned long pflags;
 
        /* Make sure all the pointers are "good" ones */
        if (!info)
@@ -2317,16 +2324,17 @@ static void receive_chars(struct uart_port *the_port)
        if (!info->tty)
                return;
 
+       spin_lock_irqsave(&the_port->lock, pflags);
        tty = info->tty;
 
-       request_count = TTY_FLIPBUF_SIZE - tty->flip.count - 1;
+       if (request_count > TTY_FLIPBUF_SIZE - tty->flip.count)
+               request_count = TTY_FLIPBUF_SIZE - tty->flip.count;
 
        if (request_count > 0) {
-               if (request_count > IOC4_MAX_CHARS - 2)
-                       request_count = IOC4_MAX_CHARS - 2;
                icount = &the_port->icount;
                read_count = do_read(the_port, ch, request_count);
                if (read_count > 0) {
+                       flip = 1;
                        memcpy(tty->flip.char_buf_ptr, ch, read_count);
                        memset(tty->flip.flag_buf_ptr, TTY_NORMAL, read_count);
                        tty->flip.char_buf_ptr += read_count;
@@ -2335,7 +2343,11 @@ static void receive_chars(struct uart_port *the_port)
                        icount->rx += read_count;
                }
        }
-       tty_flip_buffer_push(tty);
+
+       spin_unlock_irqrestore(&the_port->lock, pflags);
+
+       if (flip)
+               tty_flip_buffer_push(tty);
 }
 
 /**
@@ -2393,18 +2405,14 @@ static void ic4_shutdown(struct uart_port *the_port)
 
        info = the_port->info;
 
-       if (!(info->flags & UIF_INITIALIZED))
-               return;
-
        wake_up_interruptible(&info->delta_msr_wait);
 
        if (info->tty)
                set_bit(TTY_IO_ERROR, &info->tty->flags);
 
-       spin_lock_irqsave(&port->ip_lock, port_flags);
+       spin_lock_irqsave(&the_port->lock, port_flags);
        set_notification(port, N_ALL, 0);
-       info->flags &= ~UIF_INITIALIZED;
-       spin_unlock_irqrestore(&port->ip_lock, port_flags);
+       spin_unlock_irqrestore(&the_port->lock, port_flags);
 }
 
 /**
@@ -2463,12 +2471,10 @@ static unsigned int ic4_get_mctrl(struct uart_port *the_port)
 static void ic4_start_tx(struct uart_port *the_port)
 {
        struct ioc4_port *port = get_ioc4_port(the_port);
-       unsigned long flags;
 
        if (port) {
-               spin_lock_irqsave(&port->ip_lock, flags);
-               transmit_chars(the_port);
-               spin_unlock_irqrestore(&port->ip_lock, flags);
+               set_notification(port, N_OUTPUT_LOWAT, 1);
+               enable_intrs(port, port->ip_hooks->intr_tx_mt);
        }
 }
 
@@ -2510,9 +2516,9 @@ static int ic4_startup(struct uart_port *the_port)
        }
 
        /* Start up the serial port */
-       spin_lock_irqsave(&port->ip_lock, port_flags);
+       spin_lock_irqsave(&the_port->lock, port_flags);
        retval = ic4_startup_local(the_port);
-       spin_unlock_irqrestore(&port->ip_lock, port_flags);
+       spin_unlock_irqrestore(&the_port->lock, port_flags);
        return retval;
 }
 
@@ -2527,12 +2533,11 @@ static void
 ic4_set_termios(struct uart_port *the_port,
                struct termios *termios, struct termios *old_termios)
 {
-       struct ioc4_port *port = get_ioc4_port(the_port);
        unsigned long port_flags;
 
-       spin_lock_irqsave(&port->ip_lock, port_flags);
+       spin_lock_irqsave(&the_port->lock, port_flags);
        ioc4_change_speed(the_port, termios, old_termios);
-       spin_unlock_irqrestore(&port->ip_lock, port_flags);
+       spin_unlock_irqrestore(&the_port->lock, port_flags);
 }
 
 /**
@@ -2607,24 +2612,25 @@ ioc4_serial_core_attach(struct pci_dev *pdev)
                                __FUNCTION__, (void *)the_port,
                                (void *)port));
 
-               spin_lock_init(&the_port->lock);
                /* membase, iobase and mapbase just need to be non-0 */
                the_port->membase = (unsigned char __iomem *)1;
-               the_port->line = the_port->iobase = ii;
+               the_port->iobase = (pdev->bus->number << 16) |  ii;
+               the_port->line = (Num_of_ioc4_cards << 2) | ii;
                the_port->mapbase = 1;
                the_port->type = PORT_16550A;
-               the_port->fifosize = IOC4_MAX_CHARS;
+               the_port->fifosize = IOC4_FIFO_CHARS;
                the_port->ops = &ioc4_ops;
                the_port->irq = control->ic_irq;
                the_port->dev = &pdev->dev;
+               spin_lock_init(&the_port->lock);
                if (uart_add_one_port(&ioc4_uart, the_port) < 0) {
                        printk(KERN_WARNING
-                                      "%s: unable to add port %d\n",
-                                      __FUNCTION__, the_port->line);
+                          "%s: unable to add port %d bus %d\n",
+                              __FUNCTION__, the_port->line, pdev->bus->number);
                } else {
                        DPRINT_CONFIG(
-                                   ("IOC4 serial driver port %d irq = %d\n",
-                                      the_port->line, the_port->irq));
+                           ("IOC4 serial port %d irq = %d, bus %d\n",
+                              the_port->line, the_port->irq, pdev->bus->number));
                }
                /* all ports are rs232 for now */
                ioc4_set_proto(port, PROTO_RS232);
@@ -2734,6 +2740,8 @@ ioc4_serial_attach_one(struct ioc4_driver_data *idd)
        if ((ret = ioc4_serial_core_attach(idd->idd_pdev)))
                goto out4;
 
+       Num_of_ioc4_cards++;
+
        return ret;
 
        /* error exits that give back resources */