aboutsummaryrefslogtreecommitdiff
path: root/drivers/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/68328serial.c26
-rw-r--r--drivers/serial/68360serial.c9
-rw-r--r--drivers/serial/8250.c125
-rw-r--r--drivers/serial/8250.h3
-rw-r--r--drivers/serial/8250_accent.c47
-rw-r--r--drivers/serial/8250_boca.c61
-rw-r--r--drivers/serial/8250_fourport.c53
-rw-r--r--drivers/serial/8250_hub6.c58
-rw-r--r--drivers/serial/8250_mca.c64
-rw-r--r--drivers/serial/Kconfig88
-rw-r--r--drivers/serial/Makefile7
-rw-r--r--drivers/serial/au1x00_uart.c13
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm1.c32
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm2.c9
-rw-r--r--drivers/serial/icom.h2
-rw-r--r--drivers/serial/ioc4_serial.c336
-rw-r--r--drivers/serial/ip22zilog.c13
-rw-r--r--drivers/serial/m32r_sio.c10
-rw-r--r--drivers/serial/mpsc.c11
-rw-r--r--drivers/serial/pmac_zilog.c13
-rw-r--r--drivers/serial/pxa.c13
-rw-r--r--drivers/serial/s3c2410.c9
-rw-r--r--drivers/serial/serial_core.c42
-rw-r--r--drivers/serial/serial_cs.c113
-rw-r--r--drivers/serial/serial_txx9.c3
-rw-r--r--drivers/serial/sn_console.c1
-rw-r--r--drivers/serial/sunsab.c7
-rw-r--r--drivers/serial/sunsu.c3
-rw-r--r--drivers/serial/sunzilog.c21
29 files changed, 824 insertions, 368 deletions
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c
index db92a0ceda7..d27fb4c881d 100644
--- a/drivers/serial/68328serial.c
+++ b/drivers/serial/68328serial.c
@@ -992,18 +992,17 @@ static int get_lsr_info(struct m68k_serial * info, unsigned int *value)
/*
* This routine sends a break character out the serial port.
*/
-static void send_break( struct m68k_serial * info, int duration)
+static void send_break(struct m68k_serial * info, unsigned int duration)
{
m68328_uart *uart = &uart_addr[info->line];
unsigned long flags;
if (!info->port)
return;
- set_current_state(TASK_INTERRUPTIBLE);
save_flags(flags);
cli();
#ifdef USE_INTS
uart->utx.w |= UTX_SEND_BREAK;
- schedule_timeout(duration);
+ msleep_interruptible(duration);
uart->utx.w &= ~UTX_SEND_BREAK;
#endif
restore_flags(flags);
@@ -1033,14 +1032,14 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
return retval;
tty_wait_until_sent(tty, 0);
if (!arg)
- send_break(info, HZ/4); /* 1/4 second */
+ send_break(info, 250); /* 1/4 second */
return 0;
case TCSBRKP: /* support for POSIX tcsendbreak() */
retval = tty_check_change(tty);
if (retval)
return retval;
tty_wait_until_sent(tty, 0);
- send_break(info, arg ? arg*(HZ/10) : HZ/4);
+ send_break(info, arg ? arg*(100) : 250);
return 0;
case TIOCGSOFTCAR:
error = put_user(C_CLOCAL(tty) ? 1 : 0,
@@ -1498,23 +1497,6 @@ rs68328_init(void)
return 0;
}
-
-
-/*
- * register_serial and unregister_serial allows for serial ports to be
- * configured at run-time, to support PCMCIA modems.
- */
-/* SPARC: Unused at this time, just here to make things link. */
-int register_serial(struct serial_struct *req)
-{
- return -1;
-}
-
-void unregister_serial(int line)
-{
- return;
-}
-
module_init(rs68328_init);
diff --git a/drivers/serial/68360serial.c b/drivers/serial/68360serial.c
index f148022b6b4..b116122e569 100644
--- a/drivers/serial/68360serial.c
+++ b/drivers/serial/68360serial.c
@@ -1394,14 +1394,13 @@ static void end_break(ser_info_t *info)
/*
* This routine sends a break character out the serial port.
*/
-static void send_break(ser_info_t *info, int duration)
+static void send_break(ser_info_t *info, unsigned int duration)
{
- set_current_state(TASK_INTERRUPTIBLE);
#ifdef SERIAL_DEBUG_SEND_BREAK
printk("rs_send_break(%d) jiff=%lu...", duration, jiffies);
#endif
begin_break(info);
- schedule_timeout(duration);
+ msleep_interruptible(duration);
end_break(info);
#ifdef SERIAL_DEBUG_SEND_BREAK
printk("done jiffies=%lu\n", jiffies);
@@ -1436,7 +1435,7 @@ static int rs_360_ioctl(struct tty_struct *tty, struct file * file,
if (signal_pending(current))
return -EINTR;
if (!arg) {
- send_break(info, HZ/4); /* 1/4 second */
+ send_break(info, 250); /* 1/4 second */
if (signal_pending(current))
return -EINTR;
}
@@ -1448,7 +1447,7 @@ static int rs_360_ioctl(struct tty_struct *tty, struct file * file,
tty_wait_until_sent(tty, 0);
if (signal_pending(current))
return -EINTR;
- send_break(info, arg ? arg*(HZ/10) : HZ/4);
+ send_break(info, arg ? arg*100 : 250);
if (signal_pending(current))
return -EINTR;
return 0;
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 30e8beb7143..7e8fc7c1d4c 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -77,23 +77,9 @@ static unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
*/
#define is_real_interrupt(irq) ((irq) != 0)
-/*
- * This converts from our new CONFIG_ symbols to the symbols
- * that asm/serial.h expects. You _NEED_ to comment out the
- * linux/config.h include contained inside asm/serial.h for
- * this to work.
- */
-#undef CONFIG_SERIAL_MANY_PORTS
-#undef CONFIG_SERIAL_DETECT_IRQ
-#undef CONFIG_SERIAL_MULTIPORT
-#undef CONFIG_HUB6
-
#ifdef CONFIG_SERIAL_8250_DETECT_IRQ
#define CONFIG_SERIAL_DETECT_IRQ 1
#endif
-#ifdef CONFIG_SERIAL_8250_MULTIPORT
-#define CONFIG_SERIAL_MULTIPORT 1
-#endif
#ifdef CONFIG_SERIAL_8250_MANY_PORTS
#define CONFIG_SERIAL_MANY_PORTS 1
#endif
@@ -119,7 +105,7 @@ static struct old_serial_port old_serial_port[] = {
SERIAL_PORT_DFNS /* defined in asm/serial.h */
};
-#define UART_NR (ARRAY_SIZE(old_serial_port) + CONFIG_SERIAL_8250_NR_UARTS)
+#define UART_NR CONFIG_SERIAL_8250_NR_UARTS
#ifdef CONFIG_SERIAL_8250_RSA
@@ -132,9 +118,9 @@ struct uart_8250_port {
struct uart_port port;
struct timer_list timer; /* "no irq" timer */
struct list_head list; /* ports on this IRQ */
- unsigned int capabilities; /* port capabilities */
+ unsigned short capabilities; /* port capabilities */
+ unsigned short bugs; /* port bugs */
unsigned int tx_loadsz; /* transmit fifo load size */
- unsigned short rev;
unsigned char acr;
unsigned char ier;
unsigned char lcr;
@@ -560,7 +546,14 @@ static void autoconfig_has_efr(struct uart_8250_port *up)
if (id1 == 0x16 && id2 == 0xC9 &&
(id3 == 0x50 || id3 == 0x52 || id3 == 0x54)) {
up->port.type = PORT_16C950;
- up->rev = rev | (id3 << 8);
+
+ /*
+ * Enable work around for the Oxford Semiconductor 952 rev B
+ * chip which causes it to seriously miscalculate baud rates
+ * when DLL is 0.
+ */
+ if (id3 == 0x52 && rev == 0x01)
+ up->bugs |= UART_BUG_QUOT;
return;
}
@@ -577,8 +570,6 @@ static void autoconfig_has_efr(struct uart_8250_port *up)
id2 = id1 >> 8;
if (id2 == 0x10 || id2 == 0x12 || id2 == 0x14) {
- if (id2 == 0x10)
- up->rev = id1 & 255;
up->port.type = PORT_16850;
return;
}
@@ -809,6 +800,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
// save_flags(flags); cli();
up->capabilities = 0;
+ up->bugs = 0;
if (!(up->port.flags & UPF_BUGGY_UART)) {
/*
@@ -1001,26 +993,31 @@ static void autoconfig_irq(struct uart_8250_port *up)
up->port.irq = (irq > 0) ? irq : 0;
}
+static inline void __stop_tx(struct uart_8250_port *p)
+{
+ if (p->ier & UART_IER_THRI) {
+ p->ier &= ~UART_IER_THRI;
+ serial_out(p, UART_IER, p->ier);
+ }
+}
+
static void serial8250_stop_tx(struct uart_port *port, unsigned int tty_stop)
{
struct uart_8250_port *up = (struct uart_8250_port *)port;
- if (up->ier & UART_IER_THRI) {
- up->ier &= ~UART_IER_THRI;
- serial_out(up, UART_IER, up->ier);
- }
+ __stop_tx(up);
/*
- * We only do this from uart_stop - if we run out of
- * characters to send, we don't want to prevent the
- * FIFO from emptying.
+ * We really want to stop the transmitter from sending.
*/
- if (up->port.type == PORT_16C950 && tty_stop) {
+ if (up->port.type == PORT_16C950) {
up->acr |= UART_ACR_TXDIS;
serial_icr_write(up, UART_ACR, up->acr);
}
}
+static void transmit_chars(struct uart_8250_port *up);
+
static void serial8250_start_tx(struct uart_port *port, unsigned int tty_start)
{
struct uart_8250_port *up = (struct uart_8250_port *)port;
@@ -1028,11 +1025,20 @@ static void serial8250_start_tx(struct uart_port *port, unsigned int tty_start)
if (!(up->ier & UART_IER_THRI)) {
up->ier |= UART_IER_THRI;
serial_out(up, UART_IER, up->ier);
+
+ if (up->bugs & UART_BUG_TXEN) {
+ unsigned char lsr, iir;
+ lsr = serial_in(up, UART_LSR);
+ iir = serial_in(up, UART_IIR);
+ if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT)
+ transmit_chars(up);
+ }
}
+
/*
- * We only do this from uart_start
+ * Re-enable the transmitter if we disabled it.
*/
- if (tty_start && up->port.type == PORT_16C950) {
+ if (up->port.type == PORT_16C950 && up->acr & UART_ACR_TXDIS) {
up->acr &= ~UART_ACR_TXDIS;
serial_icr_write(up, UART_ACR, up->acr);
}
@@ -1153,7 +1159,7 @@ static _INLINE_ void transmit_chars(struct uart_8250_port *up)
return;
}
if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
- serial8250_stop_tx(&up->port, 0);
+ __stop_tx(up);
return;
}
@@ -1172,7 +1178,7 @@ static _INLINE_ void transmit_chars(struct uart_8250_port *up)
DEBUG_INTR("THRE...");
if (uart_circ_empty(xmit))
- serial8250_stop_tx(&up->port, 0);
+ __stop_tx(up);
}
static _INLINE_ void check_modem_status(struct uart_8250_port *up)
@@ -1374,13 +1380,10 @@ static unsigned int serial8250_tx_empty(struct uart_port *port)
static unsigned int serial8250_get_mctrl(struct uart_port *port)
{
struct uart_8250_port *up = (struct uart_8250_port *)port;
- unsigned long flags;
unsigned char status;
unsigned int ret;
- spin_lock_irqsave(&up->port.lock, flags);
status = serial_in(up, UART_MSR);
- spin_unlock_irqrestore(&up->port.lock, flags);
ret = 0;
if (status & UART_MSR_DCD)
@@ -1433,6 +1436,7 @@ static int serial8250_startup(struct uart_port *port)
{
struct uart_8250_port *up = (struct uart_8250_port *)port;
unsigned long flags;
+ unsigned char lsr, iir;
int retval;
up->capabilities = uart_config[up->port.type].flags;
@@ -1536,6 +1540,26 @@ static int serial8250_startup(struct uart_port *port)
up->port.mctrl |= TIOCM_OUT2;
serial8250_set_mctrl(&up->port, up->port.mctrl);
+
+ /*
+ * Do a quick test to see if we receive an
+ * interrupt when we enable the TX irq.
+ */
+ serial_outp(up, UART_IER, UART_IER_THRI);
+ lsr = serial_in(up, UART_LSR);
+ iir = serial_in(up, UART_IIR);
+ serial_outp(up, UART_IER, 0);
+
+ if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) {
+ if (!(up->bugs & UART_BUG_TXEN)) {
+ up->bugs |= UART_BUG_TXEN;
+ pr_debug("ttyS%d - enabling bad tx status workarounds\n",
+ port->line);
+ }
+ } else {
+ up->bugs &= ~UART_BUG_TXEN;
+ }
+
spin_unlock_irqrestore(&up->port.lock, flags);
/*
@@ -1645,22 +1669,22 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios,
switch (termios->c_cflag & CSIZE) {
case CS5:
- cval = 0x00;
+ cval = UART_LCR_WLEN5;
break;
case CS6:
- cval = 0x01;
+ cval = UART_LCR_WLEN6;
break;
case CS7:
- cval = 0x02;
+ cval = UART_LCR_WLEN7;
break;
default:
case CS8:
- cval = 0x03;
+ cval = UART_LCR_WLEN8;
break;
}
if (termios->c_cflag & CSTOPB)
- cval |= 0x04;
+ cval |= UART_LCR_STOP;
if (termios->c_cflag & PARENB)
cval |= UART_LCR_PARITY;
if (!(termios->c_cflag & PARODD))
@@ -1677,12 +1701,9 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios,
quot = serial8250_get_divisor(port, baud);
/*
- * Work around a bug in the Oxford Semiconductor 952 rev B
- * chip which causes it to seriously miscalculate baud rates
- * when DLL is 0.
+ * Oxford Semi 952 rev B workaround
*/
- if ((quot & 0xff) == 0 && up->port.type == PORT_16C950 &&
- up->rev == 0x5201)
+ if (up->bugs & UART_BUG_QUOT && (quot & 0xff) == 0)
quot ++;
if (up->capabilities & UART_CAP_FIFO && up->port.fifosize > 1) {
@@ -2040,7 +2061,8 @@ static void __init serial8250_isa_init_ports(void)
up->port.ops = &serial8250_pops;
}
- for (i = 0, up = serial8250_ports; i < ARRAY_SIZE(old_serial_port);
+ for (i = 0, up = serial8250_ports;
+ i < ARRAY_SIZE(old_serial_port) && i < UART_NR;
i++, up++) {
up->port.iobase = old_serial_port[i].port;
up->port.irq = irq_canonicalize(old_serial_port[i].irq);
@@ -2289,10 +2311,11 @@ static int __devinit serial8250_probe(struct device *dev)
{
struct plat_serial8250_port *p = dev->platform_data;
struct uart_port port;
+ int ret, i;
memset(&port, 0, sizeof(struct uart_port));
- for (; p && p->flags != 0; p++) {
+ for (i = 0; p && p->flags != 0; p++, i++) {
port.iobase = p->iobase;
port.membase = p->membase;
port.irq = p->irq;
@@ -2301,10 +2324,16 @@ static int __devinit serial8250_probe(struct device *dev)
port.iotype = p->iotype;
port.flags = p->flags;
port.mapbase = p->mapbase;
+ port.hub6 = p->hub6;
port.dev = dev;
if (share_irqs)
port.flags |= UPF_SHARE_IRQ;
- serial8250_register_port(&port);
+ ret = serial8250_register_port(&port);
+ if (ret < 0) {
+ dev_err(dev, "unable to register port at index %d "
+ "(IO%lx MEM%lx IRQ%d): %d\n", i,
+ p->iobase, p->mapbase, p->irq, ret);
+ }
}
return 0;
}
diff --git a/drivers/serial/8250.h b/drivers/serial/8250.h
index 4f3d62f222f..9225c82faeb 100644
--- a/drivers/serial/8250.h
+++ b/drivers/serial/8250.h
@@ -51,6 +51,9 @@ struct serial8250_config {
#define UART_CAP_AFE (1 << 11) /* MCR-based hw flow control */
#define UART_CAP_UUE (1 << 12) /* UART needs IER bit 6 set (Xscale) */
+#define UART_BUG_QUOT (1 << 0) /* UART has buggy quot LSB */
+#define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */
+
#if defined(__i386__) && (defined(CONFIG_M386) || defined(CONFIG_M486))
#define _INLINE_ inline
#else
diff --git a/drivers/serial/8250_accent.c b/drivers/serial/8250_accent.c
new file mode 100644
index 00000000000..1f2c276063e
--- /dev/null
+++ b/drivers/serial/8250_accent.c
@@ -0,0 +1,47 @@
+/*
+ * linux/drivers/serial/8250_accent.c
+ *
+ * Copyright (C) 2005 Russell King.
+ * Data taken from include/asm-i386/serial.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+
+#define PORT(_base,_irq) \
+ { \
+ .iobase = _base, \
+ .irq = _irq, \
+ .uartclk = 1843200, \
+ .iotype = UPIO_PORT, \
+ .flags = UPF_BOOT_AUTOCONF, \
+ }
+
+static struct plat_serial8250_port accent_data[] = {
+ PORT(0x330, 4),
+ PORT(0x338, 4),
+ { },
+};
+
+static struct platform_device accent_device = {
+ .name = "serial8250",
+ .id = 2,
+ .dev = {
+ .platform_data = accent_data,
+ },
+};
+
+static int __init accent_init(void)
+{
+ return platform_device_register(&accent_device);
+}
+
+module_init(accent_init);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("8250 serial probe module for Accent Async cards");
+MODULE_LICENSE("GPL");
diff --git a/drivers/serial/8250_boca.c b/drivers/serial/8250_boca.c
new file mode 100644
index 00000000000..465c9ea1e7a
--- /dev/null
+++ b/drivers/serial/8250_boca.c
@@ -0,0 +1,61 @@
+/*
+ * linux/drivers/serial/8250_boca.c
+ *
+ * Copyright (C) 2005 Russell King.
+ * Data taken from include/asm-i386/serial.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+
+#define PORT(_base,_irq) \
+ { \
+ .iobase = _base, \
+ .irq = _irq, \
+ .uartclk = 1843200, \
+ .iotype = UPIO_PORT, \
+ .flags = UPF_BOOT_AUTOCONF, \
+ }
+
+static struct plat_serial8250_port boca_data[] = {
+ PORT(0x100, 12),
+ PORT(0x108, 12),
+ PORT(0x110, 12),
+ PORT(0x118, 12),
+ PORT(0x120, 12),
+ PORT(0x128, 12),
+ PORT(0x130, 12),
+ PORT(0x138, 12),
+ PORT(0x140, 12),
+ PORT(0x148, 12),
+ PORT(0x150, 12),
+ PORT(0x158, 12),
+ PORT(0x160, 12),
+ PORT(0x168, 12),
+ PORT(0x170, 12),
+ PORT(0x178, 12),
+ { },
+};
+
+static struct platform_device boca_device = {
+ .name = "serial8250",
+ .id = 3,
+ .dev = {
+ .platform_data = boca_data,
+ },
+};
+
+static int __init boca_init(void)
+{
+ return platform_device_register(&boca_device);
+}
+
+module_init(boca_init);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("8250 serial probe module for Boca cards");
+MODULE_LICENSE("GPL");
diff --git a/drivers/serial/8250_fourport.c b/drivers/serial/8250_fourport.c
new file mode 100644
index 00000000000..e9b4d908ef4
--- /dev/null
+++ b/drivers/serial/8250_fourport.c
@@ -0,0 +1,53 @@
+/*
+ * linux/drivers/serial/8250_fourport.c
+ *
+ * Copyright (C) 2005 Russell King.
+ * Data taken from include/asm-i386/serial.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+
+#define PORT(_base,_irq) \
+ { \
+ .iobase = _base, \
+ .irq = _irq, \
+ .uartclk = 1843200, \
+ .iotype = UPIO_PORT, \
+ .flags = UPF_BOOT_AUTOCONF | UPF_FOURPORT, \
+ }
+
+static struct plat_serial8250_port fourport_data[] = {
+ PORT(0x1a0, 9),
+ PORT(0x1a8, 9),
+ PORT(0x1b0, 9),
+ PORT(0x1b8, 9),
+ PORT(0x2a0, 5),
+ PORT(0x2a8, 5),
+ PORT(0x2b0, 5),
+ PORT(0x2b8, 5),
+ { },
+};
+
+static struct platform_device fourport_device = {
+ .name = "serial8250",
+ .id = 1,
+ .dev = {
+ .platform_data = fourport_data,
+ },
+};
+
+static int __init fourport_init(void)
+{
+ return platform_device_register(&fourport_device);
+}
+
+module_init(fourport_init);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("8250 serial probe module for AST Fourport cards");
+MODULE_LICENSE("GPL");
diff --git a/drivers/serial/8250_hub6.c b/drivers/serial/8250_hub6.c
new file mode 100644
index 00000000000..77f396f84b4
--- /dev/null
+++ b/drivers/serial/8250_hub6.c
@@ -0,0 +1,58 @@
+/*
+ * linux/drivers/serial/8250_hub6.c
+ *
+ * Copyright (C) 2005 Russell King.
+ * Data taken from include/asm-i386/serial.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+
+#define HUB6(card,port) \
+ { \
+ .iobase = 0x302, \
+ .irq = 3, \
+ .uartclk = 1843200, \
+ .iotype = UPIO_HUB6, \
+ .flags = UPF_BOOT_AUTOCONF, \
+ .hub6 = (card) << 6 | (port) << 3 | 1, \
+ }
+
+static struct plat_serial8250_port hub6_data[] = {
+ HUB6(0,0),
+ HUB6(0,1),
+ HUB6(0,2),
+ HUB6(0,3),
+ HUB6(0,4),
+ HUB6(0,5),
+ HUB6(1,0),
+ HUB6(1,1),
+ HUB6(1,2),
+ HUB6(1,3),
+ HUB6(1,4),
+ HUB6(1,5),
+ { },
+};
+
+static struct platform_device hub6_device = {
+ .name = "serial8250",
+ .id = 4,
+ .dev = {
+ .platform_data = hub6_data,
+ },
+};
+
+static int __init hub6_init(void)
+{
+ return platform_device_register(&hub6_device);
+}
+
+module_init(hub6_init);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("8250 serial probe module for Hub6 cards");
+MODULE_LICENSE("GPL");
diff --git a/drivers/serial/8250_mca.c b/drivers/serial/8250_mca.c
new file mode 100644
index 00000000000..f0c40d68b8c
--- /dev/null
+++ b/drivers/serial/8250_mca.c
@@ -0,0 +1,64 @@
+/*
+ * linux/drivers/serial/8250_mca.c
+ *
+ * Copyright (C) 2005 Russell King.
+ * Data taken from include/asm-i386/serial.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/mca.h>
+#include <linux/serial_8250.h>
+
+/*
+ * FIXME: Should we be doing AUTO_IRQ here?
+ */
+#ifdef CONFIG_SERIAL_8250_DETECT_IRQ
+#define MCA_FLAGS UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ
+#else
+#define MCA_FLAGS UPF_BOOT_AUTOCONF | UPF_SKIP_TEST
+#endif
+
+#define PORT(_base,_irq) \
+ { \
+ .iobase = _base, \
+ .irq = _irq, \
+ .uartclk = 1843200, \
+ .iotype = UPIO_PORT, \
+ .flags = MCA_FLAGS, \
+ }
+
+static struct plat_serial8250_port mca_data[] = {
+ PORT(0x3220, 3),
+ PORT(0x3228, 3),
+ PORT(0x4220, 3),
+ PORT(0x4228, 3),
+ PORT(0x5220, 3),
+ PORT(0x5228, 3),
+ { },
+};
+
+static struct platform_device mca_device = {
+ .name = "serial8250",
+ .id = 5,
+ .dev = {
+ .platform_data = mca_data,
+ },
+};
+
+static int __init mca_init(void)
+{
+ if (!MCA_bus)
+ return -ENODEV;
+ return platform_device_register(&mca_device);
+}
+
+module_init(mca_init);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("8250 serial probe module for MCA ports");
+MODULE_LICENSE("GPL");
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 6e44b46c9e9..e0d0a470ddf 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -86,14 +86,14 @@ config SERIAL_8250_ACPI
namespace, say Y here. If unsure, say N.
config SERIAL_8250_NR_UARTS
- int "Maximum number of non-legacy 8250/16550 serial ports"
+ int "Maximum number of 8250/16550 serial ports"
depends on SERIAL_8250
default "4"
- ---help---
- Set this to the number of non-legacy serial ports you want
- the driver to support. This includes any ports discovered
- via ACPI or PCI enumeration and any ports that may be added
- at run-time via hot-plug.
+ help
+ Set this to the number of serial ports you want the driver
+ to support. This includes any ports discovered via ACPI or
+ PCI enumeration and any ports that may be added at run-time
+ via hot-plug, or any ISA multi-port serial cards.
config SERIAL_8250_EXTENDED
bool "Extended 8250/16550 serial driver options"
@@ -141,31 +141,74 @@ config SERIAL_8250_DETECT_IRQ
If unsure, say N.
-config SERIAL_8250_MULTIPORT
- bool "Support special multiport boards"
- depends on SERIAL_8250_EXTENDED
- help
- Some multiport serial ports have special ports which are used to
- signal when there are any serial ports on the board which need
- servicing. Say Y here to enable the serial driver to take advantage
- of those special I/O ports.
-
config SERIAL_8250_RSA
bool "Support RSA serial ports"
depends on SERIAL_8250_EXTENDED
help
::: To be written :::
-comment "Non-8250 serial port support"
+#
+# Multi-port serial cards
+#
+
+config SERIAL_8250_FOURPORT
+ tristate "Support Fourport cards"
+ depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
+ help
+ Say Y here if you have an AST FourPort serial board.
+
+ To compile this driver as a module, choose M here: the module
+ will be called 8250_fourport.
+
+config SERIAL_8250_ACCENT
+ tristate "Support Accent cards"
+ depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
+ help
+ Say Y here if you have an Accent Async serial board.
+
+ To compile this driver as a module, choose M here: the module
+ will be called 8250_accent.
+
+
+config SERIAL_8250_BOCA
+ tristate "Support Boca cards"
+ depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
+ help
+ Say Y here if you have a Boca serial board. Please read the Boca
+ mini-HOWTO, avaialble from <http://www.tldp.org/docs.html#howto>
+
+ To compile this driver as a module, choose M here: the module
+ will be called 8250_boca.
+
+
+config SERIAL_8250_HUB6
+ tristate "Support Hub6 cards"
+ depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
+ help
+ Say Y here if you have a HUB6 serial board.
+
+ To compile this driver as a module, choose M here: the module
+ will be called 8250_hub6.
+
+config SERIAL_8250_MCA
+ tristate "Support 8250-type ports on MCA buses"
+ depends on SERIAL_8250 != n && MCA
+ help
+ Say Y here if you have a MCA serial ports.
+
+ To compile this driver as a module, choose M here: the module
+ will be called 8250_mca.
config SERIAL_8250_ACORN
tristate "Acorn expansion card serial port support"
- depends on ARM && ARCH_ACORN && SERIAL_8250
+ depends on ARCH_ACORN && SERIAL_8250
help
If you have an Atomwide Serial card or Serial Port card for an Acorn
system, say Y to this option. The driver can handle 1, 2, or 3 port
cards. If unsure, say N.
+comment "Non-8250 serial port support"
+
config SERIAL_AMBA_PL010
tristate "ARM AMBA PL010 serial port support"
depends on ARM_AMBA
@@ -753,7 +796,7 @@ config SERIAL_MPC52xx_CONSOLE_BAUD
config SERIAL_ICOM
tristate "IBM Multiport Serial Adapter"
- depends on PPC_ISERIES || PPC_PSERIES
+ depends on PCI && (PPC_ISERIES || PPC_PSERIES)
select SERIAL_CORE
help
This driver is for a family of multiport serial adapters
@@ -843,4 +886,13 @@ config SERIAL_JSM
To compile this driver as a module, choose M here: the
module will be called jsm.
+config SERIAL_SGI_IOC4
+ tristate "SGI IOC4 controller serial support"
+ depends on (IA64_GENERIC || IA64_SGI_SN2) && SGI_IOC4
+ select SERIAL_CORE
+ help
+ If you have an SGI Altix with an IOC4 based Base IO card
+ and wish to use the serial ports on this card, say Y.
+ Otherwise, say N.
+
endmenu
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 81b77d769b8..65bd4381685 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -17,6 +17,11 @@ obj-$(CONFIG_SERIAL_8250) += 8250.o $(serial-8250-y)
obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o
obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o
obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o
+obj-$(CONFIG_SERIAL_8250_FOURPORT) += 8250_fourport.o
+obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o
+obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
+obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
+obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o
obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o
obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o
obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
@@ -51,4 +56,4 @@ obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o
obj-$(CONFIG_SERIAL_JSM) += jsm/
obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o
obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o
-obj-$(CONFIG_BLK_DEV_SGIIOC4) += ioc4_serial.o
+obj-$(CONFIG_SERIAL_SGI_IOC4) += ioc4_serial.o
diff --git a/drivers/serial/au1x00_uart.c b/drivers/serial/au1x00_uart.c
index b6d3d503494..6104aeef124 100644
--- a/drivers/serial/au1x00_uart.c
+++ b/drivers/serial/au1x00_uart.c
@@ -556,13 +556,10 @@ static unsigned int serial8250_tx_empty(struct uart_port *port)
static unsigned int serial8250_get_mctrl(struct uart_port *port)
{
struct uart_8250_port *up = (struct uart_8250_port *)port;
- unsigned long flags;
unsigned char status;
unsigned int ret;
- spin_lock_irqsave(&up->port.lock, flags);
status = serial_in(up, UART_MSR);
- spin_unlock_irqrestore(&up->port.lock, flags);
ret = 0;
if (status & UART_MSR_DCD)
@@ -773,22 +770,22 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios,
switch (termios->c_cflag & CSIZE) {
case CS5:
- cval = 0x00;
+ cval = UART_LCR_WLEN5;
break;
case CS6:
- cval = 0x01;
+ cval = UART_LCR_WLEN6;
break;
case CS7:
- cval = 0x02;
+ cval = UART_LCR_WLEN7;
break;
default:
case CS8:
- cval = 0x03;
+ cval = UART_LCR_WLEN8;
break;
}
if (termios->c_cflag & CSTOPB)
- cval |= 0x04;
+ cval |= UART_LCR_STOP;
if (termios->c_cflag & PARENB)
cval |= UART_LCR_PARITY;
if (!(termios->c_cflag & PARODD))
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
index de26cf7b003..7911912f50c 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
@@ -94,12 +94,42 @@ void smc1_lineif(struct uart_cpm_port *pinfo)
((immap_t *)IMAP_ADDR)->im_ioport.iop_paodr &= ~iobits;
}
+#ifdef CONFIG_MPC885ADS
+ /* Enable SMC1 transceivers */
+ {
+ volatile uint __iomem *bcsr1 = ioremap(BCSR1, 4);
+ uint tmp;
+
+ tmp = in_be32(bcsr1);
+ tmp &= ~BCSR1_RS232EN_1;
+ out_be32(bcsr1, tmp);
+ iounmap(bcsr1);
+ }
+#endif
+
pinfo->brg = 1;
}
void smc2_lineif(struct uart_cpm_port *pinfo)
{
- /* XXX SMC2: insert port configuration here */
+#ifdef CONFIG_MPC885ADS
+ volatile cpm8xx_t *cp = cpmp;
+ volatile uint __iomem *bcsr1;
+ uint tmp;
+
+ cp->cp_pepar |= 0x00000c00;
+ cp->cp_pedir &= ~0x00000c00;
+ cp->cp_peso &= ~0x00000400;
+ cp->cp_peso |= 0x00000800;
+
+ /* Enable SMC2 transceivers */
+ bcsr1 = ioremap(BCSR1, 4);
+ tmp = in_be32(bcsr1);
+ tmp &= ~BCSR1_RS232EN_2;
+ out_be32(bcsr1, tmp);
+ iounmap(bcsr1);
+#endif
+
pinfo->brg = 2;
}
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
index b422c3abfba..c4c8f4b44f5 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
@@ -134,12 +134,21 @@ void scc1_lineif(struct uart_cpm_port *pinfo)
void scc2_lineif(struct uart_cpm_port *pinfo)
{
+ /*
+ * STx GP3 uses the SCC2 secondary option pin assignment
+ * which this driver doesn't account for in the static
+ * pin assignments. This kind of board specific info
+ * really has to get out of the driver so boards can
+ * be supported in a sane fashion.
+ */
+#ifndef CONFIG_STX_GP3
volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
io->iop_pparb |= 0x008b0000;
io->iop_pdirb |= 0x00880000;
io->iop_psorb |= 0x00880000;
io->iop_pdirb &= ~0x00030000;
io->iop_psorb &= ~0x00030000;
+#endif
cpm2_immr->im_cpmux.cmx_scr &= 0xff00ffff;
cpm2_immr->im_cpmux.cmx_scr |= 0x00090000;
pinfo->brg = 2;
diff --git a/drivers/serial/icom.h b/drivers/serial/icom.h
index 23dc0f7ddf8..798f1ef2371 100644
--- a/drivers/serial/icom.h
+++ b/drivers/serial/icom.h
@@ -286,5 +286,3 @@ struct lookup_int_table {
u32 __iomem *global_int_mask;
unsigned long processor_id;
};
-
-#define MSECS_TO_JIFFIES(ms) (((ms)*HZ+999)/1000)
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c
index ba4e13a22a5..793c3a7cbe4 100644
--- a/drivers/serial/ioc4_serial.c
+++ b/drivers/serial/ioc4_serial.c
@@ -20,7 +20,7 @@
#include <linux/serial_reg.h>
#include <linux/module.h>
#include <linux/pci.h>
-#include <linux/ioc4_common.h>
+#include <linux/ioc4.h>
#include <linux/serial_core.h>
/*
@@ -130,12 +130,19 @@
IOC4_SIO_IR_S3_TX_EXPLICIT)
/* Bitmasks for IOC4_OTHER_IR, IOC4_OTHER_IEC, and IOC4_OTHER_IES */
-#define IOC4_OTHER_IR_ATA_INT 0x00000001 /* ATAPI intr pass-thru */
-#define IOC4_OTHER_IR_ATA_MEMERR 0x00000002 /* ATAPI DMA PCI error */
-#define IOC4_OTHER_IR_S0_MEMERR 0x00000004 /* Port 0 PCI error */
-#define IOC4_OTHER_IR_S1_MEMERR 0x00000008 /* Port 1 PCI error */
-#define IOC4_OTHER_IR_S2_MEMERR 0x00000010 /* Port 2 PCI error */
-#define IOC4_OTHER_IR_S3_MEMERR 0x00000020 /* Port 3 PCI error */
+#define IOC4_OTHER_IR_ATA_INT 0x00000001 /* ATAPI intr pass-thru */
+#define IOC4_OTHER_IR_ATA_MEMERR 0x00000002 /* ATAPI DMA PCI error */
+#define IOC4_OTHER_IR_S0_MEMERR 0x00000004 /* Port 0 PCI error */
+#define IOC4_OTHER_IR_S1_MEMERR 0x00000008 /* Port 1 PCI error */
+#define IOC4_OTHER_IR_S2_MEMERR 0x00000010 /* Port 2 PCI error */
+#define IOC4_OTHER_IR_S3_MEMERR 0x00000020 /* Port 3 PCI error */
+#define IOC4_OTHER_IR_KBD_INT 0x00000040 /* Keyboard/mouse */
+#define IOC4_OTHER_IR_RESERVED 0x007fff80 /* Reserved */
+#define IOC4_OTHER_IR_RT_INT 0x00800000 /* INT_OUT section output */
+#define IOC4_OTHER_IR_GEN_INT 0xff000000 /* Generic pins */
+
+#define IOC4_OTHER_IR_SER_MEMERR (IOC4_OTHER_IR_S0_MEMERR | IOC4_OTHER_IR_S1_MEMERR | \
+ IOC4_OTHER_IR_S2_MEMERR | IOC4_OTHER_IR_S3_MEMERR)
/* Bitmasks for IOC4_SIO_CR */
#define IOC4_SIO_CR_CMD_PULSE_SHIFT 0 /* byte bus strobe shift */
@@ -274,70 +281,24 @@ struct ioc4_uartregs {
#define i4u_dlm u2.dlm
#define i4u_fcr u3.fcr
-/* PCI memory space register map addressed using pci_bar0 */
-struct ioc4_memregs {
- struct ioc4_mem {
- /* Miscellaneous IOC4 registers */
- uint32_t pci_err_addr_l;
- uint32_t pci_err_addr_h;
- uint32_t sio_ir;
- uint32_t other_ir;
-
- /* These registers are read-only for general kernel code. */
- uint32_t sio_ies_ro;
- uint32_t other_ies_ro;
- uint32_t sio_iec_ro;
- uint32_t other_iec_ro;
- uint32_t sio_cr;
- uint32_t misc_fill1;
- uint32_t int_out;
- uint32_t misc_fill2;
- uint32_t gpcr_s;
- uint32_t gpcr_c;
- uint32_t gpdr;
- uint32_t misc_fill3;
- uint32_t gppr_0;
- uint32_t gppr_1;
- uint32_t gppr_2;
- uint32_t gppr_3;
- uint32_t gppr_4;
- uint32_t gppr_5;
- uint32_t gppr_6;
- uint32_t gppr_7;
- } ioc4_mem;
-
- char misc_fill4[0x100 - 0x5C - 4];
-
- /* ATA/ATAP registers */
- uint32_t ata_notused[9];
- char ata_fill1[0x140 - 0x120 - 4];
- uint32_t ata_notused1[8];
- char ata_fill2[0x200 - 0x15C - 4];
-
- /* Keyboard and mouse registers */
- uint32_t km_notused[5];;
- char km_fill1[0x300 - 0x210 - 4];
-
- /* Serial port registers used for DMA serial I/O */
- struct ioc4_serial {
- uint32_t sbbr01_l;
- uint32_t sbbr01_h;
- uint32_t sbbr23_l;
- uint32_t sbbr23_h;
-
- struct ioc4_serialregs port_0;
- struct ioc4_serialregs port_1;
- struct ioc4_serialregs port_2;
- struct ioc4_serialregs port_3;
- struct ioc4_uartregs uart_0;
- struct ioc4_uartregs uart_1;
- struct ioc4_uartregs uart_2;
- struct ioc4_uartregs uart_3;
- } ioc4_serial;
-};
+/* Serial port registers used for DMA serial I/O */
+struct ioc4_serial {
+ uint32_t sbbr01_l;
+ uint32_t sbbr01_h;
+ uint32_t sbbr23_l;
+ uint32_t sbbr23_h;
+
+ struct ioc4_serialregs port_0;
+ struct ioc4_serialregs port_1;
+ struct ioc4_serialregs port_2;
+ struct ioc4_serialregs port_3;
+ struct ioc4_uartregs uart_0;
+ struct ioc4_uartregs uart_1;
+ struct ioc4_uartregs uart_2;
+ struct ioc4_uartregs uart_3;
+} ioc4_serial;
/* UART clock speed */
-#define IOC4_SER_XIN_CLK IOC4_SER_XIN_CLK_66
#define IOC4_SER_XIN_CLK_66 66666667
#define IOC4_SER_XIN_CLK_33 33333333
@@ -412,8 +373,8 @@ enum sio_proto {
| UART_LCR_WLEN7 | UART_LCR_WLEN8)
#define LCR_MASK_STOP_BITS (UART_LCR_STOP)
-#define PENDING(_p) (readl(&(_p)->ip_mem->sio_ir) & _p->ip_ienb)
-#define READ_SIO_IR(_p) readl(&(_p)->ip_mem->sio_ir)
+#define PENDING(_p) (readl(&(_p)->ip_mem->sio_ir.raw) & _p->ip_ienb)
+#define READ_SIO_IR(_p) readl(&(_p)->ip_mem->sio_ir.raw)
/* Default to 4k buffers */
#ifdef IOC4_1K_BUFFERS
@@ -447,7 +408,7 @@ struct ioc4_control {
*/
#define MAX_IOC4_INTR_ENTS (8 * sizeof(uint32_t))
struct ioc4_soft {
- struct ioc4_mem __iomem *is_ioc4_mem_addr;
+ struct ioc4_misc_regs __iomem *is_ioc4_misc_addr;
struct ioc4_serial __iomem *is_ioc4_serial_addr;
/* Each interrupt type has an entry in the array */
@@ -486,7 +447,7 @@ struct ioc4_port {
struct ioc4_soft *ip_ioc4_soft;
/* pci mem addresses */
- struct ioc4_mem __iomem *ip_mem;
+ struct ioc4_misc_regs __iomem *ip_mem;
struct ioc4_serial __iomem *ip_serial;
struct ioc4_serialregs __iomem *ip_serial_regs;
struct ioc4_uartregs __iomem *ip_uart_regs;
@@ -553,7 +514,7 @@ struct hooks {
uint32_t intr_dma_error;
uint32_t intr_clear;
uint32_t intr_all;
- char rs422_select_pin;
+ int rs422_select_pin;
};
static struct hooks hooks_array[IOC4_NUM_SERIAL_PORTS] = {
@@ -669,7 +630,7 @@ static void handle_intr(void *arg, uint32_t sio_ir);
static inline void
write_ireg(struct ioc4_soft *ioc4_soft, uint32_t val, int which, int type)
{
- struct ioc4_mem __iomem *mem = ioc4_soft->is_ioc4_mem_addr;
+ struct ioc4_misc_regs __iomem *mem = ioc4_soft->is_ioc4_misc_addr;
unsigned long flags;
spin_lock_irqsave(&ioc4_soft->is_ir_lock, flags);
@@ -678,11 +639,11 @@ write_ireg(struct ioc4_soft *ioc4_soft, uint32_t val, int which, int type)
case IOC4_SIO_INTR_TYPE:
switch (which) {
case IOC4_W_IES:
- writel(val, &mem->sio_ies_ro);
+ writel(val, &mem->sio_ies.raw);
break;
case IOC4_W_IEC:
- writel(val, &mem->sio_iec_ro);
+ writel(val, &mem->sio_iec.raw);
break;
}
break;
@@ -690,11 +651,11 @@ write_ireg(struct ioc4_soft *ioc4_soft, uint32_t val, int which, int type)
case IOC4_OTHER_INTR_TYPE:
switch (which) {
case IOC4_W_IES:
- writel(val, &mem->other_ies_ro);
+ writel(val, &mem->other_ies.raw);
break;
case IOC4_W_IEC:
- writel(val, &mem->other_iec_ro);
+ writel(val, &mem->other_iec.raw);
break;
}
break;
@@ -747,7 +708,8 @@ static int set_baud(struct ioc4_port *port, int baud)
*/
static struct ioc4_port *get_ioc4_port(struct uart_port *the_port)
{
- struct ioc4_control *control = dev_get_drvdata(the_port->dev);
+ struct ioc4_driver_data *idd = dev_get_drvdata(the_port->dev);
+ struct ioc4_control *control = idd->idd_serial_data;
int ii;
if (control) {
@@ -782,7 +744,7 @@ static struct ioc4_port *get_ioc4_port(struct uart_port *the_port)
static inline uint32_t
pending_intrs(struct ioc4_soft *soft, int type)
{
- struct ioc4_mem __iomem *mem = soft->is_ioc4_mem_addr;
+ struct ioc4_misc_regs __iomem *mem = soft->is_ioc4_misc_addr;
unsigned long flag;
uint32_t intrs = 0;
@@ -793,11 +755,11 @@ pending_intrs(struct ioc4_soft *soft, int type)
switch (type) {
case IOC4_SIO_INTR_TYPE:
- intrs = readl(&mem->sio_ir) & readl(&mem->sio_ies_ro);
+ intrs = readl(&mem->sio_ir.raw) & readl(&mem->sio_ies.raw);
break;
case IOC4_OTHER_INTR_TYPE:
- intrs = readl(&mem->other_ir) & readl(&mem->other_ies_ro);
+ intrs = readl(&mem->other_ir.raw) & readl(&mem->other_ies.raw);
/* Don't process any ATA interrupte */
intrs &= ~(IOC4_OTHER_IR_ATA_INT | IOC4_OTHER_IR_ATA_MEMERR);
@@ -826,7 +788,7 @@ static int inline port_init(struct ioc4_port *port)
/* Wait until any pending bus activity for this port has ceased */
do
- sio_cr = readl(&port->ip_mem->sio_cr);
+ sio_cr = readl(&port->ip_mem->sio_cr.raw);
while (!(sio_cr & IOC4_SIO_CR_SIO_DIAG_IDLE));
/* Finish reset sequence */
@@ -899,7 +861,7 @@ static int inline port_init(struct ioc4_port *port)
write_ireg(port->ip_ioc4_soft, hooks->intr_clear,
IOC4_W_IEC, IOC4_SIO_INTR_TYPE);
port->ip_ienb &= ~hooks->intr_clear;
- writel(hooks->intr_clear, &port->ip_mem->sio_ir);
+ writel(hooks->intr_clear, &port->ip_mem->sio_ir.raw);
return 0;
}
@@ -918,23 +880,23 @@ static void handle_dma_error_intr(void *arg, uint32_t other_ir)
spin_lock_irqsave(&port->ip_lock, flags);
/* ACK the interrupt */
- writel(hooks->intr_dma_error, &port->ip_mem->other_ir);
+ writel(hooks->intr_dma_error, &port->ip_mem->other_ir.raw);
- if (readl(&port->ip_mem->pci_err_addr_l) & IOC4_PCI_ERR_ADDR_VLD) {
+ if (readl(&port->ip_mem->pci_err_addr_l.raw) & IOC4_PCI_ERR_ADDR_VLD) {
printk(KERN_ERR
"PCI error address is 0x%lx, "
"master is serial port %c %s\n",
(((uint64_t)readl(&port->ip_mem->pci_err_addr_h)
<< 32)
- | readl(&port->ip_mem->pci_err_addr_l))
+ | readl(&port->ip_mem->pci_err_addr_l.raw))
& IOC4_PCI_ERR_ADDR_ADDR_MSK, '1' +
- ((char)(readl(&port->ip_mem-> pci_err_addr_l) &
+ ((char)(readl(&port->ip_mem->pci_err_addr_l.raw) &
IOC4_PCI_ERR_ADDR_MST_NUM_MSK) >> 1),
- (readl(&port->ip_mem->pci_err_addr_l)
+ (readl(&port->ip_mem->pci_err_addr_l.raw)
& IOC4_PCI_ERR_ADDR_MST_TYP_MSK)
? "RX" : "TX");
- if (readl(&port->ip_mem->pci_err_addr_l)
+ if (readl(&port->ip_mem->pci_err_addr_l.raw)
& IOC4_PCI_ERR_ADDR_MUL_ERR) {
printk(KERN_ERR
"Multiple errors occurred\n");
@@ -1018,26 +980,26 @@ static irqreturn_t ioc4_intr(int irq, void *arg, struct pt_regs *regs)
"other_ies = 0x%x\n",
(intr_type == IOC4_SIO_INTR_TYPE) ? "sio" :
"other", this_ir,
- readl(&soft->is_ioc4_mem_addr->sio_ir),
- readl(&soft->is_ioc4_mem_addr->sio_ies_ro),
- readl(&soft->is_ioc4_mem_addr->other_ir),
- readl(&soft->is_ioc4_mem_addr->other_ies_ro));
+ readl(&soft->is_ioc4_misc_addr->sio_ir.raw),
+ readl(&soft->is_ioc4_misc_addr->sio_ies.raw),
+ readl(&soft->is_ioc4_misc_addr->other_ir.raw),
+ readl(&soft->is_ioc4_misc_addr->other_ies.raw));
}
}
#ifdef DEBUG_INTERRUPTS
{
- struct ioc4_mem __iomem *mem = soft->is_ioc4_mem_addr;
+ struct ioc4_misc_regs __iomem *mem = soft->is_ioc4_misc_addr;
spinlock_t *lp = &soft->is_ir_lock;
unsigned long flag;
spin_lock_irqsave(&soft->is_ir_lock, flag);
- printk ("%s : %d : mem 0x%p sio_ir 0x%x sio_ies_ro 0x%x "
- "other_ir 0x%x other_ies_ro 0x%x mask 0x%x\n",
+ printk ("%s : %d : mem 0x%p sio_ir 0x%x sio_ies 0x%x "
+ "other_ir 0x%x other_ies 0x%x mask 0x%x\n",
__FUNCTION__, __LINE__,
- (void *)mem, readl(&mem->sio_ir),
- readl(&mem->sio_ies_ro),
- readl(&mem->other_ir),
- readl(&mem->other_ies_ro),
+ (void *)mem, readl(&mem->sio_ir.raw),
+ readl(&mem->sio_ies.raw),
+ readl(&mem->other_ir.raw),
+ readl(&mem->other_ies.raw),
IOC4_OTHER_IR_ATA_INT | IOC4_OTHER_IR_ATA_MEMERR);
spin_unlock_irqrestore(&soft->is_ir_lock, flag);
}
@@ -1049,21 +1011,20 @@ static irqreturn_t ioc4_intr(int irq, void *arg, struct pt_regs *regs)
* ioc4_attach_local - Device initialization.
* Called at *_attach() time for each
* IOC4 with serial ports in the system.
- * @control: ioc4_control ptr
- * @pdev: PCI handle for this device
- * @soft: soft struct for this device
- * @ioc4: ioc4 mem space
+ * @idd: Master module data for this IOC4
*/
-static int inline ioc4_attach_local(struct pci_dev *pdev,
- struct ioc4_control *control,
- struct ioc4_soft *soft, void __iomem *ioc4_mem,
- void __iomem *ioc4_serial)
+static int inline ioc4_attach_local(struct ioc4_driver_data *idd)
{
struct ioc4_port *port;
struct ioc4_port *ports[IOC4_NUM_SERIAL_PORTS];
int port_number;
uint16_t ioc4_revid_min = 62;
uint16_t ioc4_revid;
+ struct pci_dev *pdev = idd->idd_pdev;
+ struct ioc4_control* control = idd->idd_serial_data;
+ struct ioc4_soft *soft = control->ic_soft;
+ void __iomem *ioc4_misc = idd->idd_misc_regs;
+ void __iomem *ioc4_serial = soft->is_ioc4_serial_addr;
/* IOC4 firmware must be at least rev 62 */
pci_read_config_word(pdev, PCI_COMMAND_SPECIAL, &ioc4_revid);
@@ -1076,7 +1037,7 @@ static int inline ioc4_attach_local(struct pci_dev *pdev,
ioc4_revid, ioc4_revid_min);
return -EPERM;
}
- BUG_ON(ioc4_mem == NULL);
+ BUG_ON(ioc4_misc == NULL);
BUG_ON(ioc4_serial == NULL);
/* Create port structures for each port */
@@ -1100,10 +1061,18 @@ static int inline ioc4_attach_local(struct pci_dev *pdev,
port->ip_ioc4_soft = soft;
port->ip_pdev = pdev;
port->ip_ienb = 0;
- port->ip_pci_bus_speed = IOC4_SER_XIN_CLK;
+ /* Use baud rate calculations based on detected PCI
+ * bus speed. Simply test whether the PCI clock is
+ * running closer to 66MHz or 33MHz.
+ */
+ if (idd->count_period/IOC4_EXTINT_COUNT_DIVISOR < 20) {
+ port->ip_pci_bus_speed = IOC4_SER_XIN_CLK_66;
+ } else {
+ port->ip_pci_bus_speed = IOC4_SER_XIN_CLK_33;
+ }
port->ip_baud = 9600;
port->ip_control = control;
- port->ip_mem = ioc4_mem;
+ port->ip_mem = ioc4_misc;
port->ip_serial = ioc4_serial;
/* point to the right hook */
@@ -1604,14 +1573,12 @@ static int ioc4_set_proto(struct ioc4_port *port, enum sio_proto proto)
switch (proto) {
case PROTO_RS232:
/* Clear the appropriate GIO pin */
- writel(0, (&port->ip_mem->gppr_0 +
- hooks->rs422_select_pin));
+ writel(0, (&port->ip_mem->gppr[hooks->rs422_select_pin].raw));
break;
case PROTO_RS422:
/* Set the appropriate GIO pin */
- writel(1, (&port->ip_mem->gppr_0 +
- hooks->rs422_select_pin));
+ writel(1, (&port->ip_mem->gppr[hooks->rs422_select_pin].raw));
break;
default:
@@ -1885,7 +1852,7 @@ static void handle_intr(void *arg, uint32_t sio_ir)
if (sio_ir & hooks->intr_delta_dcd) {
/* ACK the interrupt */
writel(hooks->intr_delta_dcd,
- &port->ip_mem->sio_ir);
+ &port->ip_mem->sio_ir.raw);
shadow = readl(&port->ip_serial_regs->shadow);
@@ -1907,7 +1874,7 @@ static void handle_intr(void *arg, uint32_t sio_ir)
if (sio_ir & hooks->intr_delta_cts) {
/* ACK the interrupt */
writel(hooks->intr_delta_cts,
- &port->ip_mem->sio_ir);
+ &port->ip_mem->sio_ir.raw);
shadow = readl(&port->ip_serial_regs->shadow);
@@ -1928,7 +1895,7 @@ static void handle_intr(void *arg, uint32_t sio_ir)
if (sio_ir & hooks->intr_rx_timer) {
/* ACK the interrupt */
writel(hooks->intr_rx_timer,
- &port->ip_mem->sio_ir);
+ &port->ip_mem->sio_ir.raw);
if ((port->ip_notify & N_DATA_READY)
&& (port->ip_port)) {
@@ -1974,7 +1941,7 @@ static void handle_intr(void *arg, uint32_t sio_ir)
/* ACK the interrupt */
writel(hooks->intr_tx_explicit,
- &port->ip_mem->sio_ir);
+ &port->ip_mem->sio_ir.raw);
if (port->ip_notify & N_OUTPUT_LOWAT)
ioc4_cb_output_lowat(port);
@@ -2634,7 +2601,8 @@ ioc4_serial_core_attach(struct pci_dev *pdev)
{
struct ioc4_port *port;
struct uart_port *the_port;
- struct ioc4_control *control = pci_get_drvdata(pdev);
+ struct ioc4_driver_data *idd = pci_get_drvdata(pdev);
+ struct ioc4_control *control = idd->idd_serial_data;
int ii;
DPRINT_CONFIG(("%s: attach pdev 0x%p - control 0x%p\n",
@@ -2680,55 +2648,29 @@ ioc4_serial_core_attach(struct pci_dev *pdev)
/**
* ioc4_serial_attach_one - register attach function
- * called per card found from ioc4_serial_detect as part
- * of module_init().
- * @pdev: handle for this card
- * @pci_id: pci id for this card
+ * called per card found from IOC4 master module.
+ * @idd: Master module data for this IOC4
*/
int
-ioc4_serial_attach_one(struct pci_dev *pdev, const struct pci_device_id *pci_id)
+ioc4_serial_attach_one(struct ioc4_driver_data *idd)
{
- struct ioc4_mem __iomem *mem;
- unsigned long tmp_addr, tmp_addr1;
+ unsigned long tmp_addr1;
struct ioc4_serial __iomem *serial;
struct ioc4_soft *soft;
struct ioc4_control *control;
- int tmp, ret = 0;
+ int ret = 0;
- DPRINT_CONFIG(("%s (0x%p, 0x%p)\n", __FUNCTION__, pdev, pci_id));
-
- /* Map in the ioc4 memory */
- tmp_addr = pci_resource_start(pdev, 0);
- if (!tmp_addr) {
- printk(KERN_WARNING
- "ioc4 (%p) : unable to get PIO mapping for "
- "MEM space\n", (void *)pdev);
- return -ENODEV;
- }
- if (!request_region(tmp_addr, sizeof(struct ioc4_mem), "sioc4_mem")) {
- printk(KERN_ALERT
- "ioc4 (%p): unable to get request region for "
- "MEM space\n", (void *)pdev);
- return -ENODEV;
- }
- mem = ioremap(tmp_addr, sizeof(struct ioc4_mem));
- if (!mem) {
- printk(KERN_WARNING
- "ioc4 (%p) : unable to remap ioc4 memory\n",
- (void *)pdev);
- ret = -ENODEV;
- goto out1;
- }
+ DPRINT_CONFIG(("%s (0x%p, 0x%p)\n", __FUNCTION__, idd->idd_pdev, idd->idd_pci_id));
/* request serial registers */
- tmp_addr1 = pci_resource_start(pdev, 0) + IOC4_SERIAL_OFFSET;
+ tmp_addr1 = idd->idd_bar0 + IOC4_SERIAL_OFFSET;
if (!request_region(tmp_addr1, sizeof(struct ioc4_serial),
"sioc4_uart")) {
printk(KERN_WARNING
"ioc4 (%p): unable to get request region for "
- "uart space\n", (void *)pdev);
+ "uart space\n", (void *)idd->idd_pdev);
ret = -ENODEV;
goto out1;
}
@@ -2736,12 +2678,12 @@ ioc4_serial_attach_one(struct pci_dev *pdev, const struct pci_device_id *pci_id)
if (!serial) {
printk(KERN_WARNING
"ioc4 (%p) : unable to remap ioc4 serial register\n",
- (void *)pdev);
+ (void *)idd->idd_pdev);
ret = -ENODEV;
goto out2;
}
DPRINT_CONFIG(("%s : mem 0x%p, serial 0x%p\n",
- __FUNCTION__, (void *)mem, (void *)serial));
+ __FUNCTION__, (void *)idd->idd_misc_regs, (void *)serial));
/* Get memory for the new card */
control = kmalloc(sizeof(struct ioc4_control) * IOC4_NUM_SERIAL_PORTS,
@@ -2754,59 +2696,56 @@ ioc4_serial_attach_one(struct pci_dev *pdev, const struct pci_device_id *pci_id)
goto out2;
}
memset(control, 0, sizeof(struct ioc4_control));
- pci_set_drvdata(pdev, control);
+ idd->idd_serial_data = control;
/* Allocate the soft structure */
soft = kmalloc(sizeof(struct ioc4_soft), GFP_KERNEL);
if (!soft) {
printk(KERN_WARNING
"ioc4 (%p): unable to get memory for the soft struct\n",
- (void *)pdev);
+ (void *)idd->idd_pdev);
ret = -ENOMEM;
goto out3;
}
memset(soft, 0, sizeof(struct ioc4_soft));
spin_lock_init(&soft->is_ir_lock);
- soft->is_ioc4_mem_addr = mem;
+ soft->is_ioc4_misc_addr = idd->idd_misc_regs;
soft->is_ioc4_serial_addr = serial;
/* Init the IOC4 */
- pci_read_config_dword(pdev, PCI_COMMAND, &tmp);
- pci_write_config_dword(pdev, PCI_COMMAND,
- tmp | PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
-
- writel(0xf << IOC4_SIO_CR_CMD_PULSE_SHIFT, &mem->sio_cr);
+ writel(0xf << IOC4_SIO_CR_CMD_PULSE_SHIFT,
+ &idd->idd_misc_regs->sio_cr.raw);
/* Enable serial port mode select generic PIO pins as outputs */
writel(IOC4_GPCR_UART0_MODESEL | IOC4_GPCR_UART1_MODESEL
| IOC4_GPCR_UART2_MODESEL | IOC4_GPCR_UART3_MODESEL,
- &mem->gpcr_s);
+ &idd->idd_misc_regs->gpcr_s.raw);
- /* Clear and disable all interrupts */
+ /* Clear and disable all serial interrupts */
write_ireg(soft, ~0, IOC4_W_IEC, IOC4_SIO_INTR_TYPE);
- writel(~0, &mem->sio_ir);
- write_ireg(soft, ~(IOC4_OTHER_IR_ATA_INT | IOC4_OTHER_IR_ATA_MEMERR),
- IOC4_W_IEC, IOC4_OTHER_INTR_TYPE);
- writel(~(IOC4_OTHER_IR_ATA_MEMERR | IOC4_OTHER_IR_ATA_MEMERR),
- &mem->other_ir);
+ writel(~0, &idd->idd_misc_regs->sio_ir.raw);
+ write_ireg(soft, IOC4_OTHER_IR_SER_MEMERR, IOC4_W_IEC,
+ IOC4_OTHER_INTR_TYPE);
+ writel(IOC4_OTHER_IR_SER_MEMERR, &idd->idd_misc_regs->other_ir.raw);
control->ic_soft = soft;
- if (!request_irq(pdev->irq, ioc4_intr, SA_SHIRQ,
+
+ /* Hook up interrupt handler */
+ if (!request_irq(idd->idd_pdev->irq, ioc4_intr, SA_SHIRQ,
"sgi-ioc4serial", (void *)soft)) {
- control->ic_irq = pdev->irq;
+ control->ic_irq = idd->idd_pdev->irq;
} else {
printk(KERN_WARNING
"%s : request_irq fails for IRQ 0x%x\n ",
- __FUNCTION__, pdev->irq);
+ __FUNCTION__, idd->idd_pdev->irq);
}
- if ((ret = ioc4_attach_local(pdev, control, soft,
- soft->is_ioc4_mem_addr,
- soft->is_ioc4_serial_addr)))
+ ret = ioc4_attach_local(idd);
+ if (ret)
goto out4;
/* register port with the serial core */
- if ((ret = ioc4_serial_core_attach(pdev)))
+ if ((ret = ioc4_serial_core_attach(idd->idd_pdev)))
goto out4;
return ret;
@@ -2819,7 +2758,6 @@ out3:
out2:
release_region(tmp_addr1, sizeof(struct ioc4_serial));
out1:
- release_region(tmp_addr, sizeof(struct ioc4_mem));
return ret;
}
@@ -2828,11 +2766,10 @@ out1:
/**
* ioc4_serial_remove_one - detach function
*
- * @pdev: handle for this card
+ * @idd: IOC4 master module data for this IOC4
*/
-#if 0
-void ioc4_serial_remove_one(struct pci_dev *pdev)
+int ioc4_serial_remove_one(struct ioc4_driver_data *idd)
{
int ii;
struct ioc4_control *control;
@@ -2840,7 +2777,7 @@ void ioc4_serial_remove_one(struct pci_dev *pdev)
struct ioc4_port *port;
struct ioc4_soft *soft;
- control = pci_get_drvdata(pdev);
+ control = idd->idd_serial_data;
for (ii = 0; ii < IOC4_NUM_SERIAL_PORTS; ii++) {
the_port = &control->ic_port[ii].icp_uart_port;
@@ -2867,10 +2804,17 @@ void ioc4_serial_remove_one(struct pci_dev *pdev)
kfree(soft);
}
kfree(control);
- pci_set_drvdata(pdev, NULL);
- uart_unregister_driver(&ioc4_uart);
+ idd->idd_serial_data = NULL;
+
+ return 0;
}
-#endif
+
+static struct ioc4_submodule ioc4_serial_submodule = {
+ .is_name = "IOC4_serial",
+ .is_owner = THIS_MODULE,
+ .is_probe = ioc4_serial_attach_one,
+ .is_remove = ioc4_serial_remove_one,
+};
/**
* ioc4_serial_init - module init
@@ -2886,12 +2830,20 @@ int ioc4_serial_init(void)
__FUNCTION__);
return ret;
}
- return 0;
+
+ /* register with IOC4 main module */
+ return ioc4_register_submodule(&ioc4_serial_submodule);
+}
+
+static void __devexit ioc4_serial_exit(void)
+{
+ ioc4_unregister_submodule(&ioc4_serial_submodule);
+ uart_unregister_driver(&ioc4_uart);
}
+module_init(ioc4_serial_init);
+module_exit(ioc4_serial_exit);
+
MODULE_AUTHOR("Pat Gefre - Silicon Graphics Inc. (SGI) <pfg@sgi.com>");
MODULE_DESCRIPTION("Serial PCI driver module for SGI IOC4 Base-IO Card");
MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(ioc4_serial_init);
-EXPORT_SYMBOL(ioc4_serial_attach_one);
diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c
index 3ea46c069f6..ea5bf4d4daa 100644
--- a/drivers/serial/ip22zilog.c
+++ b/drivers/serial/ip22zilog.c
@@ -518,27 +518,28 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id, struct pt_regs *re
static __inline__ unsigned char ip22zilog_read_channel_status(struct uart_port *port)
{
struct zilog_channel *channel;
- unsigned long flags;
unsigned char status;
- spin_lock_irqsave(&port->lock, flags);
-
channel = ZILOG_CHANNEL_FROM_PORT(port);
status = readb(&channel->control);
ZSDELAY();
- spin_unlock_irqrestore(&port->lock, flags);
-
return status;
}
/* The port lock is not held. */
static unsigned int ip22zilog_tx_empty(struct uart_port *port)
{
+ unsigned long flags;
unsigned char status;
unsigned int ret;
+ spin_lock_irqsave(&port->lock, flags);
+
status = ip22zilog_read_channel_status(port);
+
+ spin_unlock_irqrestore(&port->lock, flags);
+
if (status & Tx_BUF_EMP)
ret = TIOCSER_TEMT;
else
@@ -547,7 +548,7 @@ static unsigned int ip22zilog_tx_empty(struct uart_port *port)
return ret;
}
-/* The port lock is not held. */
+/* The port lock is held and interrupts are disabled. */
static unsigned int ip22zilog_get_mctrl(struct uart_port *port)
{
unsigned char status;
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c
index 08d61f13edc..0301feacbde 100644
--- a/drivers/serial/m32r_sio.c
+++ b/drivers/serial/m32r_sio.c
@@ -724,22 +724,22 @@ static void m32r_sio_set_termios(struct uart_port *port,
switch (termios->c_cflag & CSIZE) {
case CS5:
- cval = 0x00;
+ cval = UART_LCR_WLEN5;
break;
case CS6:
- cval = 0x01;
+ cval = UART_LCR_WLEN6;
break;
case CS7:
- cval = 0x02;
+ cval = UART_LCR_WLEN7;
break;
default:
case CS8:
- cval = 0x03;
+ cval = UART_LCR_WLEN8;
break;
}
if (termios->c_cflag & CSTOPB)
- cval |= 0x04;
+ cval |= UART_LCR_STOP;
if (termios->c_cflag & PARENB)
cval |= UART_LCR_PARITY;
if (!(termios->c_cflag & PARODD))
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c
index a8314aee2ab..e43276c6a95 100644
--- a/drivers/serial/mpsc.c
+++ b/drivers/serial/mpsc.c
@@ -67,7 +67,11 @@
static struct mpsc_port_info mpsc_ports[MPSC_NUM_CTLRS];
static struct mpsc_shared_regs mpsc_shared_regs;
+static struct uart_driver mpsc_reg;
+static void mpsc_start_rx(struct mpsc_port_info *pi);
+static void mpsc_free_ring_mem(struct mpsc_port_info *pi);
+static void mpsc_release_port(struct uart_port *port);
/*
******************************************************************************
*
@@ -546,7 +550,6 @@ static int
mpsc_alloc_ring_mem(struct mpsc_port_info *pi)
{
int rc = 0;
- static void mpsc_free_ring_mem(struct mpsc_port_info *pi);
pr_debug("mpsc_alloc_ring_mem[%d]: Allocating ring mem\n",
pi->port.line);
@@ -745,7 +748,6 @@ mpsc_rx_intr(struct mpsc_port_info *pi, struct pt_regs *regs)
int rc = 0;
u8 *bp;
char flag = TTY_NORMAL;
- static void mpsc_start_rx(struct mpsc_port_info *pi);
pr_debug("mpsc_rx_intr[%d]: Handling Rx intr\n", pi->port.line);
@@ -1056,12 +1058,9 @@ mpsc_get_mctrl(struct uart_port *port)
{
struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
u32 mflags, status;
- ulong iflags;
- spin_lock_irqsave(&pi->port.lock, iflags);
status = (pi->mirror_regs) ? pi->MPSC_CHR_10_m :
readl(pi->mpsc_base + MPSC_CHR_10);
- spin_unlock_irqrestore(&pi->port.lock, iflags);
mflags = 0;
if (status & 0x1)
@@ -1178,7 +1177,6 @@ static void
mpsc_shutdown(struct uart_port *port)
{
struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
- static void mpsc_release_port(struct uart_port *port);
pr_debug("mpsc_shutdown[%d]: Shutting down MPSC\n", port->line);
@@ -1448,7 +1446,6 @@ mpsc_console_setup(struct console *co, char *options)
return uart_set_options(&pi->port, co, baud, parity, bits, flow);
}
-extern struct uart_driver mpsc_reg;
static struct console mpsc_console = {
.name = MPSC_DEV_NAME,
.write = mpsc_console_write,
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c
index 85abd8a045e..7db2f37532c 100644
--- a/drivers/serial/pmac_zilog.c
+++ b/drivers/serial/pmac_zilog.c
@@ -604,7 +604,7 @@ static void pmz_set_mctrl(struct uart_port *port, unsigned int mctrl)
/*
* Get Modem Control bits (only the input ones, the core will
* or that with a cached value of the control ones)
- * The port lock is not held.
+ * The port lock is held and interrupts are disabled.
*/
static unsigned int pmz_get_mctrl(struct uart_port *port)
{
@@ -615,7 +615,7 @@ static unsigned int pmz_get_mctrl(struct uart_port *port)
if (ZS_IS_ASLEEP(uap) || uap->node == NULL)
return 0;
- status = pmz_peek_status(to_pmz(port));
+ status = read_zsreg(uap, R0);
ret = 0;
if (status & DCD)
@@ -1545,7 +1545,7 @@ static void pmz_dispose_port(struct uart_pmac_port *uap)
/*
* Called upon match with an escc node in the devive-tree.
*/
-static int pmz_attach(struct macio_dev *mdev, const struct of_match *match)
+static int pmz_attach(struct macio_dev *mdev, const struct of_device_id *match)
{
int i;
@@ -1850,20 +1850,17 @@ err_out:
return rc;
}
-static struct of_match pmz_match[] =
+static struct of_device_id pmz_match[] =
{
{
.name = "ch-a",
- .type = OF_ANY_MATCH,
- .compatible = OF_ANY_MATCH
},
{
.name = "ch-b",
- .type = OF_ANY_MATCH,
- .compatible = OF_ANY_MATCH
},
{},
};
+MODULE_DEVICE_TABLE (of, pmz_match);
static struct macio_driver pmz_driver =
{
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index 9dc151d8fa6..461c81c9320 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -274,14 +274,11 @@ static unsigned int serial_pxa_tx_empty(struct uart_port *port)
static unsigned int serial_pxa_get_mctrl(struct uart_port *port)
{
struct uart_pxa_port *up = (struct uart_pxa_port *)port;
- unsigned long flags;
unsigned char status;
unsigned int ret;
return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
- spin_lock_irqsave(&up->port.lock, flags);
status = serial_in(up, UART_MSR);
- spin_unlock_irqrestore(&up->port.lock, flags);
ret = 0;
if (status & UART_MSR_DCD)
@@ -455,22 +452,22 @@ serial_pxa_set_termios(struct uart_port *port, struct termios *termios,
switch (termios->c_cflag & CSIZE) {
case CS5:
- cval = 0x00;
+ cval = UART_LCR_WLEN5;
break;
case CS6:
- cval = 0x01;
+ cval = UART_LCR_WLEN6;
break;
case CS7:
- cval = 0x02;
+ cval = UART_LCR_WLEN7;
break;
default:
case CS8:
- cval = 0x03;
+ cval = UART_LCR_WLEN8;
break;
}
if (termios->c_cflag & CSTOPB)
- cval |= 0x04;
+ cval |= UART_LCR_STOP;
if (termios->c_cflag & PARENB)
cval |= UART_LCR_PARITY;
if (!(termios->c_cflag & PARODD))
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 2a9f7ade2c9..7365d4b50b9 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -198,7 +198,7 @@ static inline struct s3c24xx_uart_port *to_ourport(struct uart_port *port)
/* translate a port to the device name */
-static inline char *s3c24xx_serial_portname(struct uart_port *port)
+static inline const char *s3c24xx_serial_portname(struct uart_port *port)
{
return to_platform_device(port->dev)->name;
}
@@ -522,14 +522,11 @@ static void s3c24xx_serial_shutdown(struct uart_port *port)
static int s3c24xx_serial_startup(struct uart_port *port)
{
struct s3c24xx_uart_port *ourport = to_ourport(port);
- unsigned long flags;
int ret;
dbg("s3c24xx_serial_startup: port=%p (%08lx,%p)\n",
port->mapbase, port->membase);
- local_irq_save(flags);
-
rx_enabled(port) = 1;
ret = request_irq(RX_IRQ(port),
@@ -563,12 +560,10 @@ static int s3c24xx_serial_startup(struct uart_port *port)
/* the port reset code should have done the correct
* register setup for the port controls */
- local_irq_restore(flags);
return ret;
err:
s3c24xx_serial_shutdown(port);
- local_irq_restore(flags);
return ret;
}
@@ -903,7 +898,7 @@ static void s3c24xx_serial_release_port(struct uart_port *port)
static int s3c24xx_serial_request_port(struct uart_port *port)
{
- char *name = s3c24xx_serial_portname(port);
+ const char *name = s3c24xx_serial_portname(port);
return request_mem_region(port->mapbase, MAP_SIZE, name) ? 0 : -EBUSY;
}
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 36b1ae083fb..54699c3a00a 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -182,6 +182,13 @@ static int uart_startup(struct uart_state *state, int init_hw)
uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR);
}
+ if (info->flags & UIF_CTS_FLOW) {
+ spin_lock_irq(&port->lock);
+ if (!(port->ops->get_mctrl(port) & TIOCM_CTS))
+ info->tty->hw_stopped = 1;
+ spin_unlock_irq(&port->lock);
+ }
+
info->flags |= UIF_INITIALIZED;
clear_bit(TTY_IO_ERROR, &info->tty->flags);
@@ -828,7 +835,10 @@ static int uart_tiocmget(struct tty_struct *tty, struct file *file)
if ((!file || !tty_hung_up_p(file)) &&
!(tty->flags & (1 << TTY_IO_ERROR))) {
result = port->mctrl;
+
+ spin_lock_irq(&port->lock);
result |= port->ops->get_mctrl(port);
+ spin_unlock_irq(&port->lock);
}
up(&state->sem);
@@ -1131,6 +1141,16 @@ static void uart_set_termios(struct tty_struct *tty, struct termios *old_termios
spin_unlock_irqrestore(&state->port->lock, flags);
}
+ /* Handle turning on CRTSCTS */
+ if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) {
+ spin_lock_irqsave(&state->port->lock, flags);
+ if (!(state->port->ops->get_mctrl(state->port) & TIOCM_CTS)) {
+ tty->hw_stopped = 1;
+ state->port->ops->stop_tx(state->port, 0);
+ }
+ spin_unlock_irqrestore(&state->port->lock, flags);
+ }
+
#if 0
/*
* No need to wake up processes in open wait, since they
@@ -1369,6 +1389,7 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
DECLARE_WAITQUEUE(wait, current);
struct uart_info *info = state->info;
struct uart_port *port = state->port;
+ unsigned int mctrl;
info->blocked_open++;
state->count--;
@@ -1416,7 +1437,10 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
* and wait for the carrier to indicate that the
* modem is ready for us.
*/
- if (port->ops->get_mctrl(port) & TIOCM_CAR)
+ spin_lock_irq(&port->lock);
+ mctrl = port->ops->get_mctrl(port);
+ spin_unlock_irq(&port->lock);
+ if (mctrl & TIOCM_CAR)
break;
up(&state->sem);
@@ -1618,7 +1642,9 @@ static int uart_line_info(char *buf, struct uart_driver *drv, int i)
if(capable(CAP_SYS_ADMIN))
{
+ spin_lock_irq(&port->lock);
status = port->ops->get_mctrl(port);
+ spin_unlock_irq(&port->lock);
ret += sprintf(buf + ret, " tx:%d rx:%d",
port->icount.tx, port->icount.rx);
@@ -1782,6 +1808,12 @@ uart_set_options(struct uart_port *port, struct console *co,
struct termios termios;
int i;
+ /*
+ * Ensure that the serial console lock is initialised
+ * early.
+ */
+ spin_lock_init(&port->lock);
+
memset(&termios, 0, sizeof(struct termios));
termios.c_cflag = CREAD | HUPCL | CLOCAL;
@@ -2170,10 +2202,16 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
state->port = port;
- spin_lock_init(&port->lock);
port->cons = drv->cons;
port->info = state->info;
+ /*
+ * If this port is a console, then the spinlock is already
+ * initialised.
+ */
+ if (!uart_console(port))
+ spin_lock_init(&port->lock);
+
uart_configure_port(drv, state, port);
/*
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 0d7b65f93e8..de0136cc593 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -45,7 +45,6 @@
#include <asm/io.h>
#include <asm/system.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
@@ -232,11 +231,6 @@ static dev_link_t *serial_attach(void)
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &serial_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -772,13 +766,120 @@ serial_event(event_t event, int priority, event_callback_args_t * args)
return 0;
}
+static struct pcmcia_device_id serial_ids[] = {
+ PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0057, 0x0021),
+ PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0089, 0x110a),
+ PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0104, 0x000a),
+ PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0xea15),
+ PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0109, 0x0501),
+ PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0138, 0x110a),
+ PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0140, 0x000a),
+ PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0143, 0x3341),
+ PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0143, 0xc0ab),
+ PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x016c, 0x0081),
+ PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x021b, 0x0101),
+ PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x08a1, 0xc0ab),
+ PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0d0a),
+ PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0e0a),
+ PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3288", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x04cd2988, 0x46a52d63),
+ PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3336", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x0143b773, 0x46a52d63),
+ PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "EM1144T", "PCMCIA MODEM", 0xf510db04, 0x856d66c8, 0xbd6c43ef),
+ PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "XJEM1144/CCEM1144", "PCMCIA MODEM", 0xf510db04, 0x52d21e1e, 0xbd6c43ef),
+ PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM28", 0x2e3ee845, 0x0ea978ea),
+ PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM33", 0x2e3ee845, 0x80609023),
+ PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM56", 0x2e3ee845, 0xa650c32a),
+ PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "REM10", 0x2e3ee845, 0x76df1d29),
+ PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "XEM5600", 0x2e3ee845, 0xf1403719),
+ PCMCIA_PFC_DEVICE_PROD_ID12(1, "AnyCom", "Fast Ethernet ", 0x578ba6e7, 0x02d92d1e),
+ PCMCIA_PFC_DEVICE_PROD_ID12(1, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff),
+ PCMCIA_PFC_DEVICE_PROD_ID12(1, "Gateway 2000", "XJEM3336", 0xdd9989be, 0x662c394c),
+ PCMCIA_PFC_DEVICE_PROD_ID12(1, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae),
+ PCMCIA_PFC_DEVICE_PROD_ID12(1, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033),
+ PCMCIA_PFC_DEVICE_PROD_ID12(1, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58),
+ PCMCIA_PFC_DEVICE_PROD_ID12(1, "MEGAHERTZ", "XJEM1144/CCEM1144", 0xf510db04, 0x52d21e1e),
+ PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard", 0x0c2f80cd, 0x0573c29f),
+ PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard", 0x0c2f80cd, 0x0573c29f),
+ PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc),
+ PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f),
+ PCMCIA_PFC_DEVICE_PROD_ID12(1, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed),
+ PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet", 0x2e3ee845, 0xc0e778c2),
+ PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0104, 0x0070),
+ PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0101, 0x0562),
+ PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0104, 0x0070),
+ PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x016c, 0x0020),
+ PCMCIA_MFC_DEVICE_PROD_ID123(1, "APEX DATA", "MULTICARD", "ETHERNET-MODEM", 0x11c2da09, 0x7289dc5d, 0xaad95e1f),
+ PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "Home and Away 28.8 PC Card ", 0xb569a6e5, 0x5bd4ff2c),
+ PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "Home and Away Credit Card Adapter", 0xb569a6e5, 0x4bdf15c3),
+ PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "w95 Home and Away Credit Card ", 0xb569a6e5, 0xae911c15),
+ PCMCIA_MFC_DEVICE_PROD_ID1(1, "Motorola MARQUIS", 0xf03e4e77),
+ PCMCIA_MFC_DEVICE_PROD_ID2(1, "FAX/Modem/Ethernet Combo Card ", 0x1ed59302),
+ PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0301),
+ PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0039),
+ PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0006),
+ PCMCIA_DEVICE_MANF_CARD(0x0105, 0x410a),
+ PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d50),
+ PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d51),
+ PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d52),
+ PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d53),
+ PCMCIA_DEVICE_MANF_CARD(0x010b, 0xd180),
+ PCMCIA_DEVICE_MANF_CARD(0x0137, 0x000e),
+ PCMCIA_DEVICE_MANF_CARD(0x0137, 0x001b),
+ PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0025),
+ PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0045),
+ PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0052),
+ PCMCIA_DEVICE_PROD_ID134("ADV", "TECH", "COMpad-32/85", 0x67459937, 0x916d02ba, 0x8fbe92ae),
+ PCMCIA_DEVICE_PROD_ID124("GATEWAY2000", "CC3144", "PCMCIA MODEM", 0x506bccae, 0xcb3685f1, 0xbd6c43ef),
+ PCMCIA_DEVICE_PROD_ID14("MEGAHERTZ", "PCMCIA MODEM", 0xf510db04, 0xbd6c43ef),
+ PCMCIA_DEVICE_PROD_ID124("TOSHIBA", "T144PF", "PCMCIA MODEM", 0xb4585a1a, 0x7271409c, 0xbd6c43ef),
+ PCMCIA_DEVICE_PROD_ID123("FUJITSU", "FC14F ", "MBH10213", 0x6ee5a3d8, 0x30ead12b, 0xb00f05a0),
+ PCMCIA_DEVICE_PROD_ID13("MEGAHERTZ", "V.34 PCMCIA MODEM", 0xf510db04, 0xbb2cce4a),
+ PCMCIA_DEVICE_PROD_ID12("Brain Boxes", "Bluetooth PC Card", 0xee138382, 0xd4ce9b02),
+ PCMCIA_DEVICE_PROD_ID12("CIRRUS LOGIC", "FAX MODEM", 0xe625f451, 0xcecd6dfa),
+ PCMCIA_DEVICE_PROD_ID12("COMPAQ", "PCMCIA 28800 FAX/DATA MODEM", 0xa3a3062c, 0x8cbd7c76),
+ PCMCIA_DEVICE_PROD_ID12("COMPAQ", "PCMCIA 33600 FAX/DATA MODEM", 0xa3a3062c, 0x5a00ce95),
+ PCMCIA_DEVICE_PROD_ID12("Computerboards, Inc.", "PCM-COM422", 0xd0b78f51, 0x7e2d49ed),
+ PCMCIA_DEVICE_PROD_ID12("Dr. Neuhaus", "FURY CARD 14K4", 0x76942813, 0x8b96ce65),
+ PCMCIA_DEVICE_PROD_ID12("Intelligent", "ANGIA FAX/MODEM", 0xb496e65e, 0xf31602a6),
+ PCMCIA_DEVICE_PROD_ID12("Intel", "MODEM 2400", 0x816cc815, 0x23539b80),
+ PCMCIA_DEVICE_PROD_ID12("IOTech Inc ", "PCMCIA Dual RS-232 Serial Port Card", 0x3bd2d898, 0x92abc92f),
+ PCMCIA_DEVICE_PROD_ID12("MACRONIX", "FAX/MODEM", 0x668388b3, 0x3f9bdf2f),
+ PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT1432LT", 0x5f73be51, 0x0b3e2383),
+ PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT2834LT", 0x5f73be51, 0x4cd7c09e),
+ PCMCIA_DEVICE_PROD_ID12("OEM ", "C288MX ", 0xb572d360, 0xd2385b7a),
+ PCMCIA_DEVICE_PROD_ID12("PCMCIA ", "C336MX ", 0x99bcafe9, 0xaa25bcab),
+ PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "PCMCIA Dual RS-232 Serial Port Card", 0xc4420b35, 0x92abc92f),
+ PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "PCMLM28.cis"),
+ PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "PCMLM28.cis"),
+ PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "PCMLM28.cis"),
+ PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "PCMLM28.cis"),
+ PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "PCMLM28.cis"),
+ PCMCIA_MFC_DEVICE_CIS_PROD_ID12(1, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "DP83903.cis"),
+ PCMCIA_MFC_DEVICE_CIS_PROD_ID4(1, "NSC MF LAN/Modem", 0x58fc6056, "DP83903.cis"),
+ PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0556, "3CCFEM556.cis"),
+ PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "DP83903.cis"),
+ PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "3CXEM556.cis"),
+ PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "3CXEM556.cis"),
+ PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "MT5634ZLX.cis"),
+ PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "COMpad4.cis"),
+ PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "COMpad2.cis"),
+ PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "RS-COM-2P.cis"),
+ /* too generic */
+ /* PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0160, 0x0002), */
+ /* PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0160, 0x0002), */
+ PCMCIA_DEVICE_FUNC_ID(2),
+ PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, serial_ids);
+
static struct pcmcia_driver serial_cs_driver = {
.owner = THIS_MODULE,
.drv = {
.name = "serial_cs",
},
.attach = serial_attach,
+ .event = serial_event,
.detach = serial_detach,
+ .id_table = serial_ids,
};
static int __init init_serial_cs(void)
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index 3f1051a4a13..d085030df70 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -442,13 +442,10 @@ static unsigned int serial_txx9_tx_empty(struct uart_port *port)
static unsigned int serial_txx9_get_mctrl(struct uart_port *port)
{
struct uart_txx9_port *up = (struct uart_txx9_port *)port;
- unsigned long flags;
unsigned int ret;
- spin_lock_irqsave(&up->port.lock, flags);
ret = ((sio_in(up, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS)
| ((sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS);
- spin_unlock_irqrestore(&up->port.lock, flags);
return ret;
}
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c
index fee6418e84c..840815fde49 100644
--- a/drivers/serial/sn_console.c
+++ b/drivers/serial/sn_console.c
@@ -572,6 +572,7 @@ static void sn_transmit_chars(struct sn_cons_port *port, int raw)
if (uart_circ_empty(xmit) || uart_tx_stopped(&port->sc_port)) {
/* Nothing to do. */
+ ia64_sn_console_intr_disable(SAL_CONSOLE_INTR_XMIT);
return;
}
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index 10e2990a40d..8d198880756 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -426,18 +426,15 @@ static void sunsab_set_mctrl(struct uart_port *port, unsigned int mctrl)
sunsab_tx_idle(up);
}
-/* port->lock is not held. */
+/* port->lock is held by caller and interrupts are disabled. */
static unsigned int sunsab_get_mctrl(struct uart_port *port)
{
struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
- unsigned long flags;
unsigned char val;
unsigned int result;
result = 0;
- spin_lock_irqsave(&up->port.lock, flags);
-
val = readb(&up->regs->r.pvr);
result |= (val & up->pvr_dsr_bit) ? 0 : TIOCM_DSR;
@@ -447,8 +444,6 @@ static unsigned int sunsab_get_mctrl(struct uart_port *port)
val = readb(&up->regs->r.star);
result |= (val & SAB82532_STAR_CTS) ? TIOCM_CTS : 0;
- spin_unlock_irqrestore(&up->port.lock, flags);
-
return result;
}
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index ddc97c905e1..d57a3553aea 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -572,13 +572,10 @@ static unsigned int sunsu_tx_empty(struct uart_port *port)
static unsigned int sunsu_get_mctrl(struct uart_port *port)
{
struct uart_sunsu_port *up = (struct uart_sunsu_port *) port;
- unsigned long flags;
unsigned char status;
unsigned int ret;
- spin_lock_irqsave(&up->port.lock, flags);
status = serial_in(up, UART_MSR);
- spin_unlock_irqrestore(&up->port.lock, flags);
ret = 0;
if (status & UART_MSR_DCD)
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index 5c4231ae295..bff42a7b89d 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -610,27 +610,28 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id, struct pt_regs *reg
static __inline__ unsigned char sunzilog_read_channel_status(struct uart_port *port)
{
struct zilog_channel __iomem *channel;
- unsigned long flags;
unsigned char status;
- spin_lock_irqsave(&port->lock, flags);
-
channel = ZILOG_CHANNEL_FROM_PORT(port);
status = sbus_readb(&channel->control);
ZSDELAY();
- spin_unlock_irqrestore(&port->lock, flags);
-
return status;
}
/* The port lock is not held. */
static unsigned int sunzilog_tx_empty(struct uart_port *port)
{
+ unsigned long flags;
unsigned char status;
unsigned int ret;
+ spin_lock_irqsave(&port->lock, flags);
+
status = sunzilog_read_channel_status(port);
+
+ spin_unlock_irqrestore(&port->lock, flags);
+
if (status & Tx_BUF_EMP)
ret = TIOCSER_TEMT;
else
@@ -639,7 +640,7 @@ static unsigned int sunzilog_tx_empty(struct uart_port *port)
return ret;
}
-/* The port lock is not held. */
+/* The port lock is held and interrupts are disabled. */
static unsigned int sunzilog_get_mctrl(struct uart_port *port)
{
unsigned char status;
@@ -1071,7 +1072,7 @@ static void __init sunzilog_alloc_tables(void)
*/
static struct zilog_layout __iomem * __init get_zs_sun4u(int chip, int zsnode)
{
- unsigned long mapped_addr;
+ void __iomem *mapped_addr;
unsigned int sun4u_ino;
struct sbus_bus *sbus = NULL;
struct sbus_dev *sdev = NULL;
@@ -1111,9 +1112,9 @@ static struct zilog_layout __iomem * __init get_zs_sun4u(int chip, int zsnode)
apply_fhc_ranges(central_bus->child,
&zsregs[0], 1);
apply_central_ranges(central_bus, &zsregs[0], 1);
- mapped_addr =
- (((u64)zsregs[0].which_io)<<32UL) |
- ((u64)zsregs[0].phys_addr);
+ mapped_addr = (void __iomem *)
+ ((((u64)zsregs[0].which_io)<<32UL) |
+ ((u64)zsregs[0].phys_addr));
}
if (zilog_irq == -1) {