diff options
| author | James Bottomley <jejb@raven.il.steeleye.com> | 2002-12-01 03:57:44 -0600 |
|---|---|---|
| committer | James Bottomley <jejb@raven.il.steeleye.com> | 2002-12-01 03:57:44 -0600 |
| commit | fba0a9a313f2d8df4884c2421618f48196c32a6b (patch) | |
| tree | cf1982dd4227c817eb99eef30eab6d773a3cd17f | |
| parent | 3e0bb0d1e29ccc655c3a749428c3dbaf087ab8bc (diff) | |
| parent | 493c66851eb42271bdcbb5a092f1402bce146872 (diff) | |
Merge ssh://mulgrave-w/BK/scsi-misc-2.5
into raven.il.steeleye.com:/home/jejb/BK/scsi-for-linus-2.5
| -rw-r--r-- | drivers/acorn/scsi/acornscsi.c | 4 | ||||
| -rw-r--r-- | drivers/acorn/scsi/arxescsi.c | 2 | ||||
| -rw-r--r-- | drivers/acorn/scsi/cumana_2.c | 2 | ||||
| -rw-r--r-- | drivers/acorn/scsi/eesox.c | 2 | ||||
| -rw-r--r-- | drivers/acorn/scsi/fas216.c | 2 | ||||
| -rw-r--r-- | drivers/acorn/scsi/powertec.c | 2 | ||||
| -rw-r--r-- | drivers/char/tty_io.c | 44 | ||||
| -rw-r--r-- | drivers/serial/8250.c | 20 | ||||
| -rw-r--r-- | drivers/serial/8250_pci.c | 11 | ||||
| -rw-r--r-- | drivers/serial/Makefile | 2 | ||||
| -rw-r--r-- | drivers/serial/core.c | 252 | ||||
| -rw-r--r-- | include/linux/serial.h | 1 | ||||
| -rw-r--r-- | include/linux/serial_core.h | 3 | ||||
| -rw-r--r-- | include/linux/tty.h | 1 | ||||
| -rw-r--r-- | kernel/ksyms.c | 5 |
15 files changed, 225 insertions, 128 deletions
diff --git a/drivers/acorn/scsi/acornscsi.c b/drivers/acorn/scsi/acornscsi.c index 23f7e3acba47..f37ff3f411ce 100644 --- a/drivers/acorn/scsi/acornscsi.c +++ b/drivers/acorn/scsi/acornscsi.c @@ -2935,9 +2935,9 @@ int acornscsi_proc_info(char *buffer, char **start, off_t offset, } } - p += sprintf(p, "\nAttached devices:%s\n", instance->host_queue ? "" : " none"); + p += sprintf(p, "\nAttached devices:\n"); - for (scd = instance->host_queue; scd; scd = scd->next) { + list_for_each_entry(scd, &instance->my_devices, siblings) { int len; proc_print_scsidevice(scd, p, &len, 0); diff --git a/drivers/acorn/scsi/arxescsi.c b/drivers/acorn/scsi/arxescsi.c index f64fce61b2c6..6a54f887b61a 100644 --- a/drivers/acorn/scsi/arxescsi.c +++ b/drivers/acorn/scsi/arxescsi.c @@ -311,7 +311,7 @@ int arxescsi_proc_info(char *buffer, char **start, off_t offset, pos += sprintf (buffer+pos, "\nAttached devices:\n"); - for (scd = host->host_queue; scd; scd = scd->next) { + list_for_each_entry(scd, &host->my_devices, siblings) { pos += fas216_print_device(&info->info, scd, buffer + pos); if (pos + begin < offset) { diff --git a/drivers/acorn/scsi/cumana_2.c b/drivers/acorn/scsi/cumana_2.c index 42486ea6b1e8..efd1ead5dd17 100644 --- a/drivers/acorn/scsi/cumana_2.c +++ b/drivers/acorn/scsi/cumana_2.c @@ -387,7 +387,7 @@ int cumanascsi_2_proc_info (char *buffer, char **start, off_t offset, pos += sprintf(buffer+pos, "\nAttached devices:\n"); - for (scd = host->host_queue; scd; scd = scd->next) { + list_for_each_entry(scd, &host->my_devices, siblings) { int len; proc_print_scsidevice(scd, buffer, &len, pos); diff --git a/drivers/acorn/scsi/eesox.c b/drivers/acorn/scsi/eesox.c index e0d6bc0d4f09..0d31f5740ffa 100644 --- a/drivers/acorn/scsi/eesox.c +++ b/drivers/acorn/scsi/eesox.c @@ -390,7 +390,7 @@ int eesoxscsi_proc_info(char *buffer, char **start, off_t offset, pos += sprintf(buffer+pos, "\nAttached devices:\n"); - for (scd = host->host_queue; scd; scd = scd->next) { + list_for_each_entry(scd, &host->my_devices, siblings) { int len; proc_print_scsidevice(scd, buffer, &len, pos); diff --git a/drivers/acorn/scsi/fas216.c b/drivers/acorn/scsi/fas216.c index 69894a1601d4..577888dfa5f2 100644 --- a/drivers/acorn/scsi/fas216.c +++ b/drivers/acorn/scsi/fas216.c @@ -2631,7 +2631,7 @@ int fas216_eh_bus_reset(Scsi_Cmnd *SCpnt) * all command structures. Leave the running * command in place. */ - for (SDpnt = info->host->host_queue; SDpnt; SDpnt = SDpnt->next) { + list_for_each_entry(SDpnt, &info->host->my_devices, siblings) { int i; if (SDpnt->soft_reset) diff --git a/drivers/acorn/scsi/powertec.c b/drivers/acorn/scsi/powertec.c index f1156e74cd15..877c3c8e0504 100644 --- a/drivers/acorn/scsi/powertec.c +++ b/drivers/acorn/scsi/powertec.c @@ -269,7 +269,7 @@ int powertecscsi_proc_info(char *buffer, char **start, off_t offset, pos += sprintf(buffer+pos, "\nAttached devices:\n"); - for (scd = host->host_queue; scd; scd = scd->next) { + list_for_each_entry(scd, &host->my_devices, siblings) { pos += fas216_print_device(&info->info, scd, buffer + pos); if (pos + begin < offset) { diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index d693b48f47db..cf880e8cacae 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -372,6 +372,8 @@ int tty_check_change(struct tty_struct * tty) return -ERESTARTSYS; } +EXPORT_SYMBOL(tty_check_change); + static ssize_t hung_up_tty_read(struct file * file, char * buf, size_t count, loff_t *ppos) { @@ -540,6 +542,8 @@ void tty_hangup(struct tty_struct * tty) schedule_work(&tty->hangup_work); } +EXPORT_SYMBOL(tty_hangup); + void tty_vhangup(struct tty_struct * tty) { #ifdef TTY_DEBUG_HANGUP @@ -556,6 +560,8 @@ int tty_hung_up_p(struct file * filp) return (filp->f_op == &hung_up_tty_fops); } +EXPORT_SYMBOL(tty_hung_up_p); + /* * This function is typically called only by the session leader, when * it wants to disassociate itself from its controlling tty. @@ -1886,6 +1892,8 @@ void do_SAK(struct tty_struct *tty) schedule_work(&tty->SAK_work); } +EXPORT_SYMBOL(do_SAK); + /* * This routine is called out of the software interrupt to flush data * from the flip buffer to the line discipline. @@ -1946,34 +1954,44 @@ static int baud_table[] = { #endif }; -static int n_baud_table = sizeof(baud_table)/sizeof(int); +static int n_baud_table = ARRAY_SIZE(baud_table); -int tty_get_baud_rate(struct tty_struct *tty) +int tty_termios_baud_rate(struct termios *termios) { - unsigned int cflag, i; + unsigned int cbaud = termios->c_cflag & CBAUD; - cflag = tty->termios->c_cflag; + if (cbaud & CBAUDEX) { + cbaud &= ~CBAUDEX; - i = cflag & CBAUD; - if (i & CBAUDEX) { - i &= ~CBAUDEX; - if (i < 1 || i+15 >= n_baud_table) - tty->termios->c_cflag &= ~CBAUDEX; + if (cbaud < 1 || cbaud + 15 > n_baud_table) + termios->c_cflag &= ~CBAUDEX; else - i += 15; + cbaud += 15; } - if (i==15 && tty->alt_speed) { + + return baud_table[cbaud]; +} + +EXPORT_SYMBOL(tty_termios_baud_rate); + +int tty_get_baud_rate(struct tty_struct *tty) +{ + int baud = tty_termios_baud_rate(tty->termios); + + if (baud == 38400 && tty->alt_speed) { if (!tty->warned) { printk(KERN_WARNING "Use of setserial/setrocket to " "set SPD_* flags is deprecated\n"); tty->warned = 1; } - return(tty->alt_speed); + baud = tty->alt_speed; } - return baud_table[i]; + return baud; } +EXPORT_SYMBOL(tty_get_baud_rate); + void tty_flip_buffer_push(struct tty_struct *tty) { if (tty->low_latency) diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 16951465bff1..a1f70113a338 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -517,7 +517,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) unsigned char save_lcr, save_mcr; unsigned long flags; - if (!up->port.iobase && !up->port.membase) + if (!up->port.iobase && !up->port.mapbase && !up->port.membase) return; DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04x, 0x%08lx): ", @@ -1031,7 +1031,7 @@ static int serial_link_irq_chain(struct uart_8250_port *up) ret = request_irq(up->port.irq, serial8250_interrupt, irq_flags, "serial", i); - if (ret) + if (ret < 0) serial_do_unlink(i, up); } @@ -1623,7 +1623,7 @@ static int serial8250_request_port(struct uart_port *port) if (up->port.flags & UPF_RESOURCES) { if (up->port.type == PORT_RSA) { ret = serial8250_request_rsa_resource(up, &res_rsa); - if (ret) + if (ret < 0) return ret; } @@ -1641,7 +1641,7 @@ static int serial8250_request_port(struct uart_port *port) ret = -ENOMEM; } - if (ret) { + if (ret < 0) { if (res_rsa) release_resource(res_rsa); if (res) @@ -1671,11 +1671,11 @@ static void serial8250_config_port(struct uart_port *port, int flags) */ if (up->port.flags & UPF_RESOURCES) { ret = serial8250_request_std_resource(up, &res_std); - if (ret) + if (ret < 0) return; ret = serial8250_request_rsa_resource(up, &res_rsa); - if (ret) + if (ret < 0) probeflags &= ~PROBE_RSA; } else { probeflags &= ~PROBE_RSA; @@ -1950,6 +1950,7 @@ static int __register_serial(struct serial_struct *req, int line) port.regshift = req->iomem_reg_shift; port.iotype = req->io_type; port.flags = req->flags | UPF_BOOT_AUTOCONF; + port.mapbase = req->iomap_base; port.line = line; if (share_irqs) @@ -2029,11 +2030,10 @@ static int __init serial8250_init(void) spin_lock_init(&irq_lists[i].lock); ret = uart_register_driver(&serial8250_reg); - if (ret) - return ret; + if (ret >= 0) + serial8250_register_ports(&serial8250_reg); - serial8250_register_ports(&serial8250_reg); - return 0; + return ret; } static void __exit serial8250_exit(void) diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index 44b178e2d1e4..30fc603e1152 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c @@ -176,6 +176,7 @@ get_pci_port(struct pci_dev *dev, struct pci_board *board, return 0; } req->io_type = SERIAL_IO_MEM; + req->iomap_base = port; req->iomem_base = ioremap(port, board->uart_offset); if (req->iomem_base == NULL) return -ENOMEM; @@ -262,12 +263,14 @@ static int __devinit pci_plx9050_fn(struct pci_dev *dev, int enable) * interface chip and different configuration methods: * - 10x cards have control registers in IO and/or memory space; * - 20x cards have control registers in standard PCI configuration space. + * + * Note: some SIIG cards are probed by the parport_serial object. */ #define PCI_DEVICE_ID_SIIG_1S_10x (PCI_DEVICE_ID_SIIG_1S_10x_550 & 0xfffc) #define PCI_DEVICE_ID_SIIG_2S_10x (PCI_DEVICE_ID_SIIG_2S_10x_550 & 0xfff8) -static int __devinit pci_siig10x_fn(struct pci_dev *dev, int enable) +int pci_siig10x_fn(struct pci_dev *dev, int enable) { u16 data, *p; @@ -295,10 +298,12 @@ static int __devinit pci_siig10x_fn(struct pci_dev *dev, int enable) return 0; } +EXPORT_SYMBOL(pci_siig10x_fn); + #define PCI_DEVICE_ID_SIIG_2S_20x (PCI_DEVICE_ID_SIIG_2S_20x_550 & 0xfffc) #define PCI_DEVICE_ID_SIIG_2S1P_20x (PCI_DEVICE_ID_SIIG_2S1P_20x_550 & 0xfffc) -static int __devinit pci_siig20x_fn(struct pci_dev *dev, int enable) +int pci_siig20x_fn(struct pci_dev *dev, int enable) { u8 data; @@ -318,6 +323,8 @@ static int __devinit pci_siig20x_fn(struct pci_dev *dev, int enable) return 0; } +EXPORT_SYMBOL(pci_siig20x_fn); + /* Added for EKF Intel i960 serial boards */ static int __devinit pci_inteli960ni_fn(struct pci_dev *dev, int enable) { diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 2629e7620807..27a1da37eec1 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -4,7 +4,7 @@ # $Id: Makefile,v 1.8 2002/07/21 21:32:30 rmk Exp $ # -export-objs := core.o 8250.o suncore.o +export-objs := core.o 8250.o 8250_pci.o suncore.o serial-8250-y := serial-8250-$(CONFIG_GSC) += 8250_gsc.o diff --git a/drivers/serial/core.c b/drivers/serial/core.c index 2229e6d938c4..118e92152fd6 100644 --- a/drivers/serial/core.c +++ b/drivers/serial/core.c @@ -135,20 +135,6 @@ uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear) #define uart_set_mctrl(port,set) uart_update_mctrl(port,set,0) #define uart_clear_mctrl(port,clear) uart_update_mctrl(port,0,clear) -static inline void uart_update_altspeed(struct uart_info *info) -{ - unsigned int flags = info->port->flags & UPF_SPD_MASK; - - if (flags == UPF_SPD_HI) - info->tty->alt_speed = 57600; - if (flags == UPF_SPD_VHI) - info->tty->alt_speed = 115200; - if (flags == UPF_SPD_SHI) - info->tty->alt_speed = 230400; - if (flags == UPF_SPD_WARP) - info->tty->alt_speed = 460800; -} - /* * Startup the port. This will be called once per open. All calls * will be serialised by the global port semaphore. @@ -167,10 +153,8 @@ static int uart_startup(struct uart_info *info, int init_hw) * once we have successfully opened the port. Also set * up the tty->alt_speed kludge */ - if (info->tty) { + if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags); - uart_update_altspeed(info); - } if (port->type == PORT_UNKNOWN) return 0; @@ -276,43 +260,20 @@ static void uart_shutdown(struct uart_info *info) info->flags &= ~UIF_INITIALIZED; } -static inline -unsigned int uart_calculate_quot(struct uart_info *info, unsigned int baud) -{ - struct uart_port *port = info->port; - unsigned int quot; - - /* Special case: B0 rate */ - if (baud == 0) - baud = 9600; - - /* Old HI/VHI/custom speed handling */ - if (baud == 38400 && - ((port->flags & UPF_SPD_MASK) == UPF_SPD_CUST)) - quot = info->state->custom_divisor; - else - quot = port->uartclk / (16 * baud); - - return quot; -} - -static void -uart_change_speed(struct uart_info *info, struct termios *old_termios) +/** + * uart_update_timeout - update per-port FIFO timeout. + * @port: uart_port structure describing the port. + * @cflag: termios cflag value + * @quot: uart clock divisor quotient + * + * Set the port FIFO timeout value. The @cflag value should + * reflect the actual hardware settings. + */ +void +uart_update_timeout(struct uart_port *port, unsigned int cflag, + unsigned int quot) { - struct uart_port *port = info->port; - unsigned int quot, cflag, bits, try; - - /* - * If we have no tty, termios, or the port does not exist, - * then we can't set the parameters for this port. - */ - if (!info->tty || !info->tty->termios || port->type == PORT_UNKNOWN) - return; - - /* - * Set flags based on termios cflag - */ - cflag = info->tty->termios->c_cflag; + unsigned int bits; /* byte size and parity */ switch (cflag & CSIZE) { @@ -335,12 +296,105 @@ uart_change_speed(struct uart_info *info, struct termios *old_termios) if (cflag & PARENB) bits++; + /* + * The total number of bits to be transmitted in the fifo. + */ + bits = bits * port->fifosize; + + /* + * Figure the timeout to send the above number of bits. + * Add .02 seconds of slop + */ + port->timeout = (HZ * bits) / (port->uartclk / (16 * quot)) + HZ/50; +} + +EXPORT_SYMBOL(uart_update_timeout); + +/** + * uart_get_baud_rate - return baud rate for a particular port + * @port: uart_port structure describing the port in question. + * @termios: desired termios settings. + * + * Decode the termios structure into a numeric baud rate, + * taking account of the magic 38400 baud rate (with spd_* + * flags), and mapping the %B0 rate to 9600 baud. + */ +unsigned int +uart_get_baud_rate(struct uart_port *port, struct termios *termios) +{ + unsigned int baud = tty_termios_baud_rate(termios); + + /* + * The spd_hi, spd_vhi, spd_shi, spd_warp kludge... + * Die! Die! Die! + */ + if (baud == 38400) { + unsigned int flags = port->flags & UPF_SPD_MASK; + + if (flags == UPF_SPD_HI) + baud = 57600; + if (flags == UPF_SPD_VHI) + baud = 115200; + if (flags == UPF_SPD_SHI) + baud = 230400; + if (flags == UPF_SPD_WARP) + baud = 460800; + } + + /* + * Special case: B0 rate. + */ + if (baud == 0) + baud = 9600; + + return baud; +} + +EXPORT_SYMBOL(uart_get_baud_rate); + +static inline unsigned int +uart_calculate_quot(struct uart_port *port, unsigned int baud) +{ + unsigned int quot; + + /* + * Old custom speed handling. + */ + if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST) + quot = port->custom_divisor; + else + quot = port->uartclk / (16 * baud); + + return quot; +} + +/** + * uart_get_divisor - return uart clock divisor + * @port: uart_port structure describing the port. + * @termios: desired termios settings + * @old_termios: the original port settings, or NULL + * + * Calculate the uart clock divisor for the port. If the + * divisor is invalid, try the old termios setting. If + * the divisor is still invalid, we try 9600 baud. + * + * Update the @termios structure to reflect the baud rate + * we're actually going to be using. + * + * If 9600 baud fails, we return a zero divisor. + */ +unsigned int +uart_get_divisor(struct uart_port *port, struct termios *termios, + struct termios *old_termios) +{ + unsigned int quot, try; + for (try = 0; try < 3; try ++) { unsigned int baud; /* Determine divisor based on baud rate */ - baud = tty_get_baud_rate(info->tty); - quot = uart_calculate_quot(info, baud); + baud = uart_get_baud_rate(port, termios); + quot = uart_calculate_quot(port, baud); if (quot) break; @@ -348,10 +402,9 @@ uart_change_speed(struct uart_info *info, struct termios *old_termios) * Oops, the quotient was zero. Try again with * the old baud rate if possible. */ - info->tty->termios->c_cflag &= ~CBAUD; + termios->c_cflag &= ~CBAUD; if (old_termios) { - info->tty->termios->c_cflag |= - (old_termios->c_cflag & CBAUD); + termios->c_cflag |= old_termios->c_cflag & CBAUD; old_termios = NULL; continue; } @@ -360,30 +413,48 @@ uart_change_speed(struct uart_info *info, struct termios *old_termios) * As a last resort, if the quotient is zero, * default to 9600 bps */ - info->tty->termios->c_cflag |= B9600; + termios->c_cflag |= B9600; } + return quot; +} + +EXPORT_SYMBOL(uart_get_divisor); + +static void +uart_change_speed(struct uart_info *info, struct termios *old_termios) +{ + struct tty_struct *tty = info->tty; + struct uart_port *port = info->port; + struct termios *termios; + unsigned int quot; + /* - * The total number of bits to be transmitted in the fifo. + * If we have no tty, termios, or the port does not exist, + * then we can't set the parameters for this port. */ - bits = bits * port->fifosize; + if (!tty || !tty->termios || port->type == PORT_UNKNOWN) + return; + + termios = tty->termios; /* - * Figure the timeout to send the above number of bits. - * Add .02 seconds of slop + * Set flags based on termios cflag */ - port->timeout = (HZ * bits) / (port->uartclk / (16 * quot)) + HZ/50; - - if (cflag & CRTSCTS) + if (termios->c_cflag & CRTSCTS) info->flags |= UIF_CTS_FLOW; else info->flags &= ~UIF_CTS_FLOW; - if (cflag & CLOCAL) + + if (termios->c_cflag & CLOCAL) info->flags &= ~UIF_CHECK_CD; else info->flags |= UIF_CHECK_CD; - port->ops->change_speed(port, cflag, info->tty->termios->c_iflag, quot); + quot = uart_get_divisor(port, termios, old_termios); + uart_update_timeout(port, termios->c_cflag, quot); + + port->ops->change_speed(port, termios->c_cflag, termios->c_iflag, quot); } static inline void @@ -597,7 +668,7 @@ static int uart_get_info(struct uart_info *info, struct serial_struct *retinfo) tmp.baud_base = port->uartclk / 16; tmp.close_delay = state->close_delay; tmp.closing_wait = state->closing_wait; - tmp.custom_divisor = state->custom_divisor; + tmp.custom_divisor = port->custom_divisor; tmp.hub6 = port->hub6; tmp.io_type = port->iotype; tmp.iomem_reg_shift = port->regshift; @@ -652,7 +723,7 @@ uart_set_info(struct uart_info *info, struct serial_struct *newinfo) new_serial.type != port->type; old_flags = port->flags; - old_custom_divisor = state->custom_divisor; + old_custom_divisor = port->custom_divisor; if (!capable(CAP_SYS_ADMIN)) { retval = -EPERM; @@ -665,7 +736,7 @@ uart_set_info(struct uart_info *info, struct serial_struct *newinfo) goto exit; port->flags = ((port->flags & ~UPF_USR_MASK) | (new_serial.flags & UPF_USR_MASK)); - state->custom_divisor = new_serial.custom_divisor; + port->custom_divisor = new_serial.custom_divisor; goto check_and_exit; } @@ -757,7 +828,7 @@ uart_set_info(struct uart_info *info, struct serial_struct *newinfo) port->irq = new_serial.irq; port->uartclk = new_serial.baud_base * 16; port->flags = new_serial.flags & UPF_FLAGS; - state->custom_divisor = new_serial.custom_divisor; + port->custom_divisor = new_serial.custom_divisor; state->close_delay = new_serial.close_delay * HZ / 100; state->closing_wait = new_serial.closing_wait * HZ / 100; port->fifosize = new_serial.xmit_fifo_size; @@ -769,10 +840,8 @@ uart_set_info(struct uart_info *info, struct serial_struct *newinfo) goto exit; if (info->flags & UIF_INITIALIZED) { if (((old_flags ^ port->flags) & UPF_SPD_MASK) || - old_custom_divisor != state->custom_divisor) { - uart_update_altspeed(info); + old_custom_divisor != port->custom_divisor) uart_change_speed(info, NULL); - } } else retval = uart_startup(info, 1); exit: @@ -1540,8 +1609,9 @@ static int uart_open(struct tty_struct *tty, struct file *filp) * Any failures from here onwards should not touch the count. */ tty->driver_data = info; + tty->low_latency = (info->port->flags & UPF_LOW_LATENCY) ? 1 : 0; + tty->alt_speed = 0; info->tty = tty; - info->tty->low_latency = (info->port->flags & UPF_LOW_LATENCY) ? 1 : 0; /* * If the port is in the middle of closing, bail out now. @@ -2009,7 +2079,7 @@ __uart_register_port(struct uart_driver *drv, struct uart_state *state, /* * If there isn't a port here, don't do anything further. */ - if (!port->iobase && !port->mapbase) + if (!port->iobase && !port->mapbase && !port->membase) return; /* @@ -2405,17 +2475,23 @@ int uart_register_port(struct uart_driver *drv, struct uart_port *port) goto out; } - state->port->iobase = port->iobase; - state->port->membase = port->membase; - state->port->irq = port->irq; - state->port->uartclk = port->uartclk; - state->port->fifosize = port->fifosize; - state->port->regshift = port->regshift; - state->port->iotype = port->iotype; - state->port->flags = port->flags; - state->port->line = state - drv->state; - - __uart_register_port(drv, state, state->port); + /* + * If the port is already initialised, don't touch it. + */ + if (state->port->type == PORT_UNKNOWN) { + state->port->iobase = port->iobase; + state->port->membase = port->membase; + state->port->irq = port->irq; + state->port->uartclk = port->uartclk; + state->port->fifosize = port->fifosize; + state->port->regshift = port->regshift; + state->port->iotype = port->iotype; + state->port->flags = port->flags; + state->port->line = state - drv->state; + state->port->mapbase = port->mapbase; + + __uart_register_port(drv, state, state->port); + } ret = state->port->line; } else diff --git a/include/linux/serial.h b/include/linux/serial.h index d9d93ae8ad3b..b0469a236a13 100644 --- a/include/linux/serial.h +++ b/include/linux/serial.h @@ -48,6 +48,7 @@ struct serial_struct { unsigned char *iomem_base; unsigned short iomem_reg_shift; unsigned int port_high; + unsigned long iomap_base; /* cookie passed into ioremap */ int reserved[1]; }; diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index fe25d0fa6b94..84e021607be9 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -186,6 +186,7 @@ struct uart_port { unsigned int timeout; /* character-based timeout */ unsigned int type; /* port type */ struct uart_ops *ops; + unsigned int custom_divisor; unsigned int line; /* port index */ unsigned long mapbase; /* for ioremap */ unsigned char hub6; /* this should be in the 8250 driver */ @@ -204,8 +205,6 @@ struct uart_state { #define USF_CLOSING_WAIT_INF (0) #define USF_CLOSING_WAIT_NONE (65535) - unsigned int custom_divisor; - int count; struct uart_info *info; struct uart_port *port; diff --git a/include/linux/tty.h b/include/linux/tty.h index 81c8d745f708..11b82d2c98ae 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -397,6 +397,7 @@ extern void do_SAK(struct tty_struct *tty); extern void disassociate_ctty(int priv); extern void tty_flip_buffer_push(struct tty_struct *tty); extern int tty_get_baud_rate(struct tty_struct *tty); +extern int tty_termios_baud_rate(struct termios *termios); /* n_tty.c */ extern struct tty_ldisc tty_ldisc_N_TTY; diff --git a/kernel/ksyms.c b/kernel/ksyms.c index 092018c75a66..98093272d3e8 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -353,13 +353,8 @@ EXPORT_SYMBOL(generic_file_writev); EXPORT_SYMBOL(iov_shorten); /* tty routines */ -EXPORT_SYMBOL(tty_hangup); EXPORT_SYMBOL(tty_wait_until_sent); -EXPORT_SYMBOL(tty_check_change); -EXPORT_SYMBOL(tty_hung_up_p); EXPORT_SYMBOL(tty_flip_buffer_push); -EXPORT_SYMBOL(tty_get_baud_rate); -EXPORT_SYMBOL(do_SAK); /* filesystem registration */ EXPORT_SYMBOL(register_filesystem); |
