From: James S. <jsi...@us...> - 2001-11-01 21:38:39
|
Update of /cvsroot/linuxconsole/ruby/linux/drivers/serial In directory usw-pr-cvs1:/tmp/cvs-serv18808 Modified Files: Config.in Makefile serial_21285.c serial_8250.c serial_8250_pci.c serial_8250_pnp.c serial_amba.c serial_clps711x.c serial_core.c serial_sa1100.c Log Message: Synced to Russell King's latest work. Index: Config.in =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/Config.in,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- Config.in 2001/08/23 02:46:17 1.6 +++ Config.in 2001/11/01 21:38:35 1.7 @@ -28,6 +28,9 @@ dep_bool ' Use /dev/ttyS0 device (OBSOLETE)' CONFIG_SERIAL_21285_OLD $CONFIG_SERIAL_21285 $CONFIG_OBSOLETE dep_bool ' Console on DC21285 serial port' CONFIG_SERIAL_21285_CONSOLE $CONFIG_SERIAL_21285 + dep_bool 'Excalibur serial port (uart00) support' CONFIG_SERIAL_UART00 $CONFIG_ARCH_CAMELOT + dep_bool ' Support for console on Excalibur serial port' CONFIG_SERIAL_UART00_CONSOLE $CONFIG_SERIAL_UART00 + dep_bool 'SA1100 serial port support' CONFIG_SERIAL_SA1100 $CONFIG_ARCH_SA1100 dep_bool ' Console on SA1100 serial port' CONFIG_SERIAL_SA1100_CONSOLE $CONFIG_SERIAL_SA1100 if [ "$CONFIG_ARCH_SA1100" = "y" ]; then @@ -46,21 +49,6 @@ dep_bool ' Support special multiport boards' CONFIG_SERIAL_8250_MULTIPORT $CONFIG_SERIAL_8250_EXTENDED dep_bool ' Support Bell Technologies HUB6 card' CONFIG_SERIAL_8250_HUB6 $CONFIG_SERIAL_8250_EXTENDED - if [ "$CONFIG_SERIAL_AMBA" = "y" -o \ - "$CONFIG_SERIAL_CLPS711X" = "y" -o \ - "$CONFIG_SERIAL_SA1100" = "y" -o \ - "$CONFIG_SERIAL_ANAKIN" = "y" -o \ - "$CONFIG_SERIAL_8250" = "y" ]; then - define_bool CONFIG_SERIAL_CORE y - else - if [ "$CONFIG_SERIAL_AMBA" = "m" -o \ - "$CONFIG_SERIAL_CLPS711X" = "m" -o \ - "$CONFIG_SERIAL_SA1100" = "m" -o \ - "$CONFIG_SERIAL_ANAKIN" = "m" -o \ - "$CONFIG_SERIAL_8250" = "m" ]; then - define_bool CONFIG_SERIAL_CORE m - fi - fi if [ "$CONFIG_SERIAL_AMBA_CONSOLE" = "y" -o \ "$CONFIG_SERIAL_CLPS711X_CONSOLE" = "y" -o \ "$CONFIG_SERIAL_SA1100_CONSOLE" = "y" -o \ Index: Makefile =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/Makefile,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- Makefile 2001/08/30 18:01:58 1.8 +++ Makefile 2001/11/01 21:38:35 1.9 @@ -30,6 +30,7 @@ obj-$(CONFIG_SERIAL_AMBA) += serial_amba.o obj-$(CONFIG_SERIAL_CLPS711X) += serial_clps711x.o obj-$(CONFIG_SERIAL_SA1100) += serial_sa1100.o +obj-$(CONFIG_SERIAL_UART00) += serial_uart00.o include $(TOPDIR)/Rules.make Index: serial_21285.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/serial_21285.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 Index: serial_8250.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/serial_8250.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 Index: serial_8250_pci.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/serial_8250_pci.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 Index: serial_8250_pnp.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/serial_8250_pnp.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 Index: serial_amba.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/serial_amba.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 Index: serial_clps711x.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/serial_clps711x.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- serial_clps711x.c 2001/10/08 04:33:45 1.7 +++ serial_clps711x.c 2001/11/01 21:38:35 1.8 @@ -396,6 +396,8 @@ port->ignore_status_mask |= UARTDR_OVERR; } + quot -= 1; + /* first, disable everything */ save_flags(flags); cli(); @@ -435,8 +437,8 @@ shutdown: clps711xuart_shutdown, change_speed: clps711xuart_change_speed, config_port: clps711xuart_config_port, - release_port: clps711xuart_request_port, - request_port: clps711xuart_release_port, + release_port: clps711xuart_release_port, + request_port: clps711xuart_request_port, }; static struct uart_port clps711x_ports[UART_NR] = { @@ -618,6 +620,7 @@ } static struct console clps711x_console = { + name: SERIAL_CLPS711X_NAME, write: clps711xuart_console_write, #ifdef used_and_not_const_char_pointer read: clps711xuart_console_read, Index: serial_core.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/serial_core.c,v retrieving revision 1.13 retrieving revision 1.14 diff -u -d -r1.13 -r1.14 --- serial_core.c 2001/10/08 04:33:45 1.13 +++ serial_core.c 2001/11/01 21:38:35 1.14 @@ -99,9 +99,9 @@ struct uart_info *info = tty->driver_data; unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&info->lock, flags); info->ops->stop_tx(info->port, 1); - restore_flags(flags); + spin_unlock_irqrestore(&info->lock, flags); } static void uart_start(struct tty_struct *tty) @@ -112,10 +112,10 @@ pm_access(info->state->pm); - save_flags(flags); cli(); + spin_lock_irqsave(&info->lock, flags); nonempty = (info->xmit.head != info->xmit.tail && info->xmit.buf); info->ops->start_tx(info->port, nonempty, 1); - restore_flags(flags); + spin_unlock_irqrestore(&info->lock, flags); } static void uart_tasklet_action(unsigned long data) @@ -363,12 +363,12 @@ if (!tty || !info->xmit.buf) return; - save_flags(flags); cli(); + spin_lock_irqsave(&info->lock, flags); if (CIRC_SPACE(info->xmit.head, info->xmit.tail, UART_XMIT_SIZE) != 0) { info->xmit.buf[info->xmit.head] = ch; info->xmit.head = (info->xmit.head + 1) & (UART_XMIT_SIZE - 1); } - restore_flags(flags); + spin_unlock_irqrestore(&info->lock, flags); } static void uart_flush_chars(struct tty_struct *tty) @@ -384,9 +384,9 @@ || !info->xmit.buf) return; - save_flags(flags); cli(); + spin_lock_irqsave(&info->lock, flags); info->ops->start_tx(info->port, 1, 0); - restore_flags(flags); + spin_unlock_irqrestore(&info->lock, flags); } static int uart_write(struct tty_struct *tty, int from_user, @@ -399,7 +399,6 @@ if (!tty || !info->xmit.buf || !tmp_buf) return 0; - save_flags(flags); if (from_user) { down(&tmp_buf_sem); while (1) { @@ -418,7 +417,7 @@ ret = -EFAULT; break; } - cli(); + spin_lock_irqsave(&info->lock, flags); c1 = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, UART_XMIT_SIZE); @@ -427,14 +426,14 @@ memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c); info->xmit.head = (info->xmit.head + c) & (UART_XMIT_SIZE - 1); - restore_flags(flags); + spin_unlock_irqrestore(&info->lock, flags); buf += c; count -= c; ret += c; } up(&tmp_buf_sem); } else { - cli(); + spin_lock_irqsave(&info->lock, flags); while (1) { c = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, @@ -450,7 +449,7 @@ count -= c; ret += c; } - restore_flags(flags); + spin_unlock_irqrestore(&info->lock, flags); } pm_access(info->state->pm); @@ -485,9 +484,9 @@ printk("uart_flush_buffer(%d) called\n", MINOR(tty->device) - tty->driver.minor_start); #endif - save_flags(flags); cli(); + spin_lock_irqsave(&info->lock, flags); info->xmit.head = info->xmit.tail = 0; - restore_flags(flags); + spin_unlock_irqrestore(&info->lock, flags); wake_up_interruptible(&tty->write_wait); if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) @@ -516,10 +515,10 @@ uart_send_xchar(tty, STOP_CHAR(tty)); if (tty->termios->c_cflag & CRTSCTS) { - save_flags(flags); cli(); + spin_lock_irqsave(&info->lock, flags); info->mctrl &= ~TIOCM_RTS; info->ops->set_mctrl(info->port, info->mctrl); - restore_flags(flags); + spin_unlock_irqrestore(&info->lock, flags); } } @@ -536,10 +535,10 @@ } if (tty->termios->c_cflag & CRTSCTS) { - save_flags(flags); cli(); + spin_lock_irqsave(&info->lock, flags); info->mctrl |= TIOCM_RTS; info->ops->set_mctrl(info->port, info->mctrl); - restore_flags(flags); + spin_unlock_irqrestore(&info->lock, flags); } } @@ -761,9 +760,9 @@ u_int result; unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&info->lock, flags); result = info->ops->tx_empty(info->port); - restore_flags(flags); + spin_unlock_irqrestore(&info->lock, flags); /* * If we're about to load something into the transmit @@ -793,13 +792,12 @@ unsigned int *value) { unsigned int arg, old; - unsigned long flags; int ret = 0; if (get_user(arg, value)) return -EFAULT; - save_flags(flags); cli(); + spin_lock_irq(&info->lock, flags); old = info->mctrl; switch (cmd) { case TIOCMBIS: info->mctrl |= arg; break; @@ -809,7 +807,7 @@ } if (old != info->mctrl) info->ops->set_mctrl(info->port, info->mctrl); - restore_flags(flags); + spin_unlock_irq(&info->lock); return ret; } @@ -819,9 +817,9 @@ unsigned long flags; if (info->port->type != PORT_UNKNOWN) { - save_flags(flags); cli(); + spin_lock_irqsave(&info->lock, flags); info->ops->break_ctl(info->port, break_state); - restore_flags(flags); + spin_unlock_irqrestore(&info->lock, flags); } } @@ -867,13 +865,15 @@ return ret; } +/* + * Called from userspace. We can use spin_lock_irq() here. + */ static int uart_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { struct uart_info *info = tty->driver_data; struct uart_icount cprev, cnow; struct serial_icounter_struct icount; - unsigned long flags; int ret = -ENOIOCTLCMD; if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && @@ -918,12 +918,12 @@ * Caller should use TIOCGICOUNT to see which one it was */ case TIOCMIWAIT: - save_flags(flags); cli(); + spin_lock_irq(&info->lock); /* note the counters on entry */ cprev = info->port->icount; /* Force modem status interrupts on */ info->ops->enable_ms(info->port); - restore_flags(flags); + spin_unlock_irq(&info->lock); while (1) { interruptible_sleep_on(&info->delta_msr_wait); /* see if a signal did it */ @@ -931,9 +931,9 @@ ret = -ERESTARTSYS; break; } - save_flags(flags); cli(); + spin_lock_irq(&info->lock); cnow = info->port->icount; /* atomic copy */ - restore_flags(flags); + spin_unlock_irq(&info->lock); if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) { ret = -EIO; /* no change => error */ @@ -957,9 +957,9 @@ * RI where only 0->1 is counted. */ case TIOCGICOUNT: - save_flags(flags); cli(); + spin_lock_irq(&info->lock); cnow = info->port->icount; - restore_flags(flags); + spin_unlock_irq(&info->lock); icount.cts = cnow.cts; icount.dsr = cnow.dsr; @@ -1005,22 +1005,22 @@ /* Handle transition to B0 status */ if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD)) { - save_flags(flags); cli(); + spin_lock_irqsave(&info->lock, flags); info->mctrl &= ~(TIOCM_RTS | TIOCM_DTR); info->ops->set_mctrl(info->port, info->mctrl); - restore_flags(flags); + spin_unlock_irqrestore(&info->lock, flags); } /* Handle transition away from B0 status */ if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { - save_flags(flags); cli(); + spin_lock_irqsave(&info->lock, flags); info->mctrl |= TIOCM_DTR; if (!(cflag & CRTSCTS) || !test_bit(TTY_THROTTLED, &tty->flags)) info->mctrl |= TIOCM_RTS; info->ops->set_mctrl(info->port, info->mctrl); - restore_flags(flags); + spin_unlock_irqrestore(&info->lock, flags); } /* Handle turning off CRTSCTS */ @@ -1044,7 +1044,9 @@ } /* - * In 2.4.5, calls to this will be serialized via the BKL + * In 2.4.5, calls to this will be serialized via the BKL in + * linux/drivers/char/tty_io.c:tty_release() + * linux/drivers/char/tty_io.c:do_tty_handup() */ static void uart_close(struct tty_struct *tty, struct file *filp) { @@ -1061,16 +1063,16 @@ #ifdef DEBUG printk("uart_close() called\n"); #endif - - down(&state->count_sem); - save_flags(flags); cli(); - if (tty_hung_up_p(filp)) { - restore_flags(flags); - up(&state->count_sem); + /* + * This is safe, as long as the BKL exists in + * do_tty_hangup(), and we're protected by the BKL. + */ + if (tty_hung_up_p(filp)) goto done; - } + down(&state->count_sem); + spin_lock_irqsave(&info->lock, flags); if ((tty->count == 1) && (state->count != 1)) { /* * Uh, oh. tty->count is 1, which means that the tty @@ -1089,12 +1091,12 @@ state->count = 0; } if (state->count) { - restore_flags(flags); + spin_unlock_irqrestore(&info->lock, flags); up(&state->count_sem); goto done; } info->flags |= ASYNC_CLOSING; - restore_flags(flags); + spin_unlock_irqrestore(&info->lock, flags); up(&state->count_sem); /* @@ -1213,6 +1215,10 @@ set_current_state(TASK_RUNNING); /* might not be needed */ } +/* + * This is called with the BKL in effect + * linux/drivers/char/tty_io.c:do_tty_hangup() + */ static void uart_hangup(struct tty_struct *tty) { struct uart_info *info = tty->driver_data; @@ -1299,22 +1305,22 @@ retval = 0; add_wait_queue(&info->open_wait, &wait); down(&state->count_sem); - save_flags(flags); cli(); + spin_lock_irqsave(&info->lock, flags); if (!tty_hung_up_p(filp)) { extra_count = 1; state->count--; } - restore_flags(flags); + spin_unlock_irqrestore(&info->lock, flags); info->blocked_open++; up(&state->count_sem); while (1) { - save_flags(flags); cli(); + spin_lock_irqsave(&info->lock, flags); if (!(info->flags & ASYNC_CALLOUT_ACTIVE) && (tty->termios->c_cflag & CBAUD)) { info->mctrl = TIOCM_DTR | TIOCM_RTS; info->ops->set_mctrl(info->port, info->mctrl); } - restore_flags(flags); + spin_unlock_irqrestore(&info->lock, flags); set_current_state(TASK_INTERRUPTIBLE); if (tty_hung_up_p(filp) || !(info->flags & ASYNC_INITIALIZED)) { @@ -1381,8 +1387,29 @@ } /* - * Ugg, calls to uart_open are not serialised. + * Make sure we have the temporary buffer allocated. Note + * that we set retval appropriately above, and we rely on + * this. */ +static inline int uart_alloc_tmpbuf(void) +{ + if (!tmp_buf) { + unsigned long buf = get_zeroed_page(GFP_KERNEL); + if (!tmp_buf) { + if (buf) + tmp_buf = (u_char *)buf; + else + return -ENOMEM; + } else + free_page(buf); + } + return 0; +} + +/* + * In 2.4.5, calls to uart_open are serialised by the BKL in + * linux/fs/devices.c:chrdev_open() + */ static int uart_open(struct tty_struct *tty, struct file *filp) { struct uart_driver *drv = (struct uart_driver *)tty->driver.driver_state; @@ -1409,21 +1436,8 @@ info->tty = tty; info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; - /* - * Make sure we have the temporary buffer allocated. Note - * that we set retval appropriately above, and we rely on - * this. - */ - if (!tmp_buf) { - unsigned long buf = get_zeroed_page(GFP_KERNEL); - if (!tmp_buf) { - if (buf) - tmp_buf = (u_char *)buf; - else - goto out; - } else - free_page(buf); - } + if (uart_alloc_tmpbuf()) + goto out; /* * If the port is in the middle of closing, bail out now. @@ -1724,6 +1738,9 @@ #endif #ifdef CONFIG_SERIAL_8250_CONSOLE serial8250_console_init(); +#endif +#ifdef CONFIG_SERIAL_UART00_CONSOLE + uart00_console_init(); #endif } #endif /* CONFIG_SERIAL_CORE_CONSOLE */ Index: serial_sa1100.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/serial/serial_sa1100.c,v retrieving revision 1.12 retrieving revision 1.13 diff -u -d -r1.12 -r1.13 --- serial_sa1100.c 2001/10/08 04:33:45 1.12 +++ serial_sa1100.c 2001/11/01 21:38:35 1.13 @@ -122,9 +122,14 @@ static void sa1100_start_tx(struct uart_port *port, u_int nonempty, u_int from_tty) { if (nonempty) { - u32 utcr3 = UART_GET_UTCR3(port); + unsigned long flags; + u32 utcr3; + + local_irq_save(flags); + utcr3 = UART_GET_UTCR3(port); port->read_status_mask |= UTSR0_TO_SM(UTSR0_TFS); UART_PUT_UTCR3(port, utcr3 | UTCR3_TIE); + local_irq_restore(flags); } } @@ -315,6 +320,9 @@ { } +/* + * Interrupts always disabled. + */ static void sa1100_break_ctl(struct uart_port *port, int break_state) { u_int utcr3; @@ -397,7 +405,7 @@ utcr0 |= UTCR0_OES; } - port->read_status_mask &= UTSR1_TO_SM(UTSR0_TFS); + port->read_status_mask &= UTSR0_TO_SM(UTSR0_TFS); port->read_status_mask |= UTSR1_TO_SM(UTSR1_ROR); if (iflag & INPCK) port->read_status_mask |= UTSR1_TO_SM(UTSR1_FRE | UTSR1_PRE); @@ -421,10 +429,10 @@ } /* first, disable interrupts and drain transmitter */ - save_flags_cli(flags); + local_irq_save(flags); old_utcr3 = UART_GET_UTCR3(port); UART_PUT_UTCR3(port, old_utcr3 & ~(UTCR3_RIE | UTCR3_TIE)); - restore_flags(flags); + local_irq_restore(flags); while (UART_GET_UTSR1(port) & UTSR1_TBY); /* then, disable everything */ |