summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Bottomley <jejb@raven.il.steeleye.com>2002-12-01 03:57:44 -0600
committerJames Bottomley <jejb@raven.il.steeleye.com>2002-12-01 03:57:44 -0600
commitfba0a9a313f2d8df4884c2421618f48196c32a6b (patch)
treecf1982dd4227c817eb99eef30eab6d773a3cd17f
parent3e0bb0d1e29ccc655c3a749428c3dbaf087ab8bc (diff)
parent493c66851eb42271bdcbb5a092f1402bce146872 (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.c4
-rw-r--r--drivers/acorn/scsi/arxescsi.c2
-rw-r--r--drivers/acorn/scsi/cumana_2.c2
-rw-r--r--drivers/acorn/scsi/eesox.c2
-rw-r--r--drivers/acorn/scsi/fas216.c2
-rw-r--r--drivers/acorn/scsi/powertec.c2
-rw-r--r--drivers/char/tty_io.c44
-rw-r--r--drivers/serial/8250.c20
-rw-r--r--drivers/serial/8250_pci.c11
-rw-r--r--drivers/serial/Makefile2
-rw-r--r--drivers/serial/core.c252
-rw-r--r--include/linux/serial.h1
-rw-r--r--include/linux/serial_core.h3
-rw-r--r--include/linux/tty.h1
-rw-r--r--kernel/ksyms.c5
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);