diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 3742753241ee8e5b1ff2e34664d2f7540b406136..e08510d09ff6fa6ef26ec6832781b6dd90ef9b2a 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -999,7 +999,10 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) serial_outp(up, UART_MCR, save_mcr); serial8250_clear_fifos(up); (void)serial_in(up, UART_RX); - serial_outp(up, UART_IER, 0); + if (up->capabilities & UART_CAP_UUE) + serial_outp(up, UART_IER, UART_IER_UUE); + else + serial_outp(up, UART_IER, 0); out: spin_unlock_irqrestore(&up->port.lock, flags); diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c index 5d8660a42b77e1a77e805c433e632c34d98a32c5..b79ed0665d519f199c6bb16cf946d42bd7626754 100644 --- a/drivers/serial/8250_pnp.c +++ b/drivers/serial/8250_pnp.c @@ -323,6 +323,8 @@ static const struct pnp_device_id pnp_dev_table[] = { { "USR9180", 0 }, /* U.S. Robotics 56K Voice INT PnP*/ { "USR9190", 0 }, + /* HP Compaq Tablet PC tc1100 Wacom tablet */ + { "WACF005", 0 }, /* Rockwell's (PORALiNK) 33600 INT PNP */ { "WCI0003", 0 }, /* Unkown PnP modems */ diff --git a/drivers/serial/dz.c b/drivers/serial/dz.c index e63b9dffc8d7304ecd6fcfaa2b363ffd07838131..4d8516d1bb71692d217e50ab5934c8862643b3ab 100644 --- a/drivers/serial/dz.c +++ b/drivers/serial/dz.c @@ -1,9 +1,9 @@ /* - * dz.c: Serial port driver for DECStations equiped + * dz.c: Serial port driver for DECStations equiped * with the DZ chipset. * - * Copyright (C) 1998 Olivier A. D. Lebaillif - * + * Copyright (C) 1998 Olivier A. D. Lebaillif + * * Email: olivier.lebaillif@ifrsys.com * * [31-AUG-98] triemer @@ -11,14 +11,14 @@ * removed base_addr code - moving address assignment to setup.c * Changed name of dz_init to rs_init to be consistent with tc code * [13-NOV-98] triemer fixed code to receive characters - * after patches by harald to irq code. + * after patches by harald to irq code. * [09-JAN-99] triemer minor fix for schedule - due to removal of timeout * field from "current" - somewhere between 2.1.121 and 2.1.131 Qua Jun 27 15:02:26 BRT 2001 * [27-JUN-2001] Arnaldo Carvalho de Melo - cleanups - * - * Parts (C) 1999 David Airlie, airlied@linux.ie - * [07-SEP-99] Bugfixes + * + * Parts (C) 1999 David Airlie, airlied@linux.ie + * [07-SEP-99] Bugfixes * * [06-Jan-2002] Russell King * Converted to new serial core @@ -64,7 +64,7 @@ static struct dz_port dz_ports[DZ_NB_PORT]; #ifdef DEBUG_DZ /* - * debugging code to send out chars via prom + * debugging code to send out chars via prom */ static void debug_console(const char *s, int count) { @@ -82,7 +82,7 @@ static void debug_console(const char *s, int count) * ------------------------------------------------------------ * dz_in () and dz_out () * - * These routines are used to access the registers of the DZ + * These routines are used to access the registers of the DZ * chip, hiding relocation differences between implementation. * ------------------------------------------------------------ */ @@ -106,8 +106,8 @@ static inline void dz_out(struct dz_port *dport, unsigned offset, * ------------------------------------------------------------ * rs_stop () and rs_start () * - * These routines are called before setting or resetting - * tty->stopped. They enable or disable transmitter interrupts, + * These routines are called before setting or resetting + * tty->stopped. They enable or disable transmitter interrupts, * as necessary. * ------------------------------------------------------------ */ @@ -156,17 +156,17 @@ static void dz_enable_ms(struct uart_port *port) /* * ------------------------------------------------------------ - * Here starts the interrupt handling routines. All of the - * following subroutines are declared as inline and are folded - * into dz_interrupt. They were separated out for readability's - * sake. + * Here starts the interrupt handling routines. All of the + * following subroutines are declared as inline and are folded + * into dz_interrupt. They were separated out for readability's + * sake. * * Note: rs_interrupt() is a "fast" interrupt, which means that it * runs with interrupts turned off. People who may want to modify * rs_interrupt() should try to keep the interrupt handler as fast as * possible. After you are done making modifications, it is not a bad * idea to do: - * + * * make drivers/serial/dz.s * * and look at the resulting assemble code in dz.s. @@ -403,7 +403,7 @@ static void dz_set_mctrl(struct uart_port *uport, unsigned int mctrl) * startup () * * various initialization tasks - * ------------------------------------------------------------------- + * ------------------------------------------------------------------- */ static int dz_startup(struct uart_port *uport) { @@ -430,13 +430,13 @@ static int dz_startup(struct uart_port *uport) return 0; } -/* +/* * ------------------------------------------------------------------- * shutdown () * * This routine will shutdown a serial port; interrupts are disabled, and * DTR is dropped if the hangup on close termio flag is on. - * ------------------------------------------------------------------- + * ------------------------------------------------------------------- */ static void dz_shutdown(struct uart_port *uport) { @@ -451,7 +451,7 @@ static void dz_shutdown(struct uart_port *uport) * release the bus after transmitting. This must be done when * the transmit shift register is empty, not be done when the * transmit holding register is empty. This functionality - * allows an RS485 driver to be written in user space. + * allows an RS485 driver to be written in user space. */ static unsigned int dz_tx_empty(struct uart_port *uport) { @@ -645,9 +645,9 @@ static void __init dz_init_ports(void) if (mips_machtype == MACH_DS23100 || mips_machtype == MACH_DS5100) - base = (unsigned long) KN01_DZ11_BASE; + base = CKSEG1ADDR(KN01_SLOT_BASE + KN01_DZ11); else - base = (unsigned long) KN02_DZ11_BASE; + base = CKSEG1ADDR(KN02_SLOT_BASE + KN02_DZ11); for (i = 0, dport = dz_ports; i < DZ_NB_PORT; i++, dport++) { spin_lock_init(&dport->port.lock); @@ -695,13 +695,13 @@ static void dz_console_put_char(struct dz_port *dport, unsigned char ch) spin_unlock_irqrestore(&dport->port.lock, flags); } -/* +/* * ------------------------------------------------------------------- * dz_console_print () * * dz_console_print is registered for printk. * The console must be locked when we get here. - * ------------------------------------------------------------------- + * ------------------------------------------------------------------- */ static void dz_console_print(struct console *cons, const char *str, diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index 5d3cb84864474b0449afc551caf8c2d2aa0c80dd..b8727d9bf690d7322007301c70646d8ebd136860 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c @@ -725,7 +725,7 @@ mpc52xx_uart_probe(struct platform_device *dev) int i, idx, ret; /* Check validity & presence */ - idx = pdev->id; + idx = dev->id; if (idx < 0 || idx >= MPC52xx_PSC_MAXNUM) return -EINVAL; @@ -748,7 +748,7 @@ mpc52xx_uart_probe(struct platform_device *dev) port->ops = &mpc52xx_uart_ops; /* Search for IRQ and mapbase */ - for (i=0 ; inum_resources ; i++, res++) { + for (i=0 ; inum_resources ; i++, res++) { if (res->flags & IORESOURCE_MEM) port->mapbase = res->start; else if (res->flags & IORESOURCE_IRQ) diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c index fd9deee20e05108c7f35c0996878200ff4a716db..0e3daf6d7b502575f05baf78d90bb7f37919f2d2 100644 --- a/drivers/serial/sa1100.c +++ b/drivers/serial/sa1100.c @@ -156,7 +156,7 @@ static void sa1100_stop_tx(struct uart_port *port) } /* - * interrupts may not be disabled on entry + * port locked and interrupts disabled */ static void sa1100_start_tx(struct uart_port *port) { @@ -164,11 +164,9 @@ static void sa1100_start_tx(struct uart_port *port) unsigned long flags; u32 utcr3; - spin_lock_irqsave(&sport->port.lock, flags); utcr3 = UART_GET_UTCR3(sport); sport->port.read_status_mask |= UTSR0_TO_SM(UTSR0_TFS); UART_PUT_UTCR3(sport, utcr3 | UTCR3_TIE); - spin_unlock_irqrestore(&sport->port.lock, flags); } /* diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 427a23858076ffe03fcf9a166b7ca852a37533cb..2331296e1e17b068db98d8097bd85e1c80341898 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c @@ -209,33 +209,45 @@ static void uart_shutdown(struct uart_state *state) struct uart_info *info = state->info; struct uart_port *port = state->port; - if (!(info->flags & UIF_INITIALIZED)) - return; - /* - * Turn off DTR and RTS early. + * Set the TTY IO error marker */ - if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) - uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); + if (info->tty) + set_bit(TTY_IO_ERROR, &info->tty->flags); - /* - * clear delta_msr_wait queue to avoid mem leaks: we may free - * the irq here so the queue might never be woken up. Note - * that we won't end up waiting on delta_msr_wait again since - * any outstanding file descriptors should be pointing at - * hung_up_tty_fops now. - */ - wake_up_interruptible(&info->delta_msr_wait); + if (info->flags & UIF_INITIALIZED) { + info->flags &= ~UIF_INITIALIZED; - /* - * Free the IRQ and disable the port. - */ - port->ops->shutdown(port); + /* + * Turn off DTR and RTS early. + */ + if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) + uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); + + /* + * clear delta_msr_wait queue to avoid mem leaks: we may free + * the irq here so the queue might never be woken up. Note + * that we won't end up waiting on delta_msr_wait again since + * any outstanding file descriptors should be pointing at + * hung_up_tty_fops now. + */ + wake_up_interruptible(&info->delta_msr_wait); + + /* + * Free the IRQ and disable the port. + */ + port->ops->shutdown(port); + + /* + * Ensure that the IRQ handler isn't running on another CPU. + */ + synchronize_irq(port->irq); + } /* - * Ensure that the IRQ handler isn't running on another CPU. + * kill off our tasklet */ - synchronize_irq(port->irq); + tasklet_kill(&info->tlet); /* * Free the transmit buffer page. @@ -244,15 +256,6 @@ static void uart_shutdown(struct uart_state *state) free_page((unsigned long)info->xmit.buf); info->xmit.buf = NULL; } - - /* - * kill off our tasklet - */ - tasklet_kill(&info->tlet); - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); - - info->flags &= ~UIF_INITIALIZED; } /** @@ -1928,14 +1931,25 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port) if (state->info && state->info->flags & UIF_INITIALIZED) { struct uart_ops *ops = port->ops; + int ret; ops->set_mctrl(port, 0); - ops->startup(port); - uart_change_speed(state, NULL); - spin_lock_irq(&port->lock); - ops->set_mctrl(port, port->mctrl); - ops->start_tx(port); - spin_unlock_irq(&port->lock); + ret = ops->startup(port); + if (ret == 0) { + uart_change_speed(state, NULL); + spin_lock_irq(&port->lock); + ops->set_mctrl(port, port->mctrl); + ops->start_tx(port); + spin_unlock_irq(&port->lock); + } else { + /* + * Failed to resume - maybe hardware went away? + * Clear the "initialized" flag so we won't try + * to call the low level drivers shutdown method. + */ + state->info->flags &= ~UIF_INITIALIZED; + uart_shutdown(state); + } } up(&state->sem);