summaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/68328serial.c17
-rw-r--r--drivers/serial/8250.c61
-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/8250_pci.c51
-rw-r--r--drivers/serial/Kconfig84
-rw-r--r--drivers/serial/Makefile6
-rw-r--r--drivers/serial/au1x00_uart.c3
-rw-r--r--drivers/serial/bast_sio.c80
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm1.c32
-rw-r--r--drivers/serial/crisv10.c2
-rw-r--r--drivers/serial/icom.c1
-rw-r--r--drivers/serial/ip22zilog.c13
-rw-r--r--drivers/serial/jsm/jsm.h1
-rw-r--r--drivers/serial/mpsc.c3
-rw-r--r--drivers/serial/pmac_zilog.c13
-rw-r--r--drivers/serial/pxa.c3
-rw-r--r--drivers/serial/s3c2410.c5
-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/sunsab.c7
-rw-r--r--drivers/serial/sunsu.c3
-rw-r--r--drivers/serial/sunzilog.c13
27 files changed, 605 insertions, 234 deletions
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c
index feb8e73fc1c..d27fb4c881d 100644
--- a/drivers/serial/68328serial.c
+++ b/drivers/serial/68328serial.c
@@ -1497,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/8250.c b/drivers/serial/8250.c
index d8b9d2b8c20..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
@@ -1007,21 +993,24 @@ 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);
}
@@ -1045,10 +1034,11 @@ static void serial8250_start_tx(struct uart_port *port, unsigned int tty_start)
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);
}
@@ -1169,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;
}
@@ -1188,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)
@@ -1390,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)
@@ -2074,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);
@@ -2323,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;
@@ -2335,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_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/8250_pci.c b/drivers/serial/8250_pci.c
index de54bdc5398..356f5556759 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -389,6 +389,9 @@ static void __devexit sbs_exit(struct pci_dev *dev)
* - 10x cards have control registers in IO and/or memory space;
* - 20x cards have control registers in standard PCI configuration space.
*
+ * There are also Quartet Serial cards which use Oxford Semiconductor
+ * 16954 quad UART PCI chip clocked by 18.432 MHz quartz.
+ *
* Note: some SIIG cards are probed by the parport_serial object.
*/
@@ -1026,6 +1029,8 @@ enum pci_board_num_t {
pbn_b0_2_921600,
pbn_b0_4_921600,
+ pbn_b0_4_1152000,
+
pbn_b0_bt_1_115200,
pbn_b0_bt_2_115200,
pbn_b0_bt_8_115200,
@@ -1158,6 +1163,12 @@ static struct pci_board pci_boards[] __devinitdata = {
.base_baud = 921600,
.uart_offset = 8,
},
+ [pbn_b0_4_1152000] = {
+ .flags = FL_BASE0,
+ .num_ports = 4,
+ .base_baud = 1152000,
+ .uart_offset = 8,
+ },
[pbn_b0_bt_1_115200] = {
.flags = FL_BASE0|FL_BASE_BARS,
@@ -1755,33 +1766,30 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
static void __devexit pciserial_remove_one(struct pci_dev *dev)
{
struct serial_private *priv = pci_get_drvdata(dev);
+ struct pci_serial_quirk *quirk;
+ int i;
pci_set_drvdata(dev, NULL);
- if (priv) {
- struct pci_serial_quirk *quirk;
- int i;
-
- for (i = 0; i < priv->nr; i++)
- serial8250_unregister_port(priv->line[i]);
+ for (i = 0; i < priv->nr; i++)
+ serial8250_unregister_port(priv->line[i]);
- for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) {
- if (priv->remapped_bar[i])
- iounmap(priv->remapped_bar[i]);
- priv->remapped_bar[i] = NULL;
- }
+ for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) {
+ if (priv->remapped_bar[i])
+ iounmap(priv->remapped_bar[i]);
+ priv->remapped_bar[i] = NULL;
+ }
- /*
- * Find the exit quirks.
- */
- quirk = find_quirk(dev);
- if (quirk->exit)
- quirk->exit(dev);
+ /*
+ * Find the exit quirks.
+ */
+ quirk = find_quirk(dev);
+ if (quirk->exit)
+ quirk->exit(dev);
- pci_disable_device(dev);
+ pci_disable_device(dev);
- kfree(priv);
- }
+ kfree(priv);
}
static int pciserial_suspend_one(struct pci_dev *dev, pm_message_t state)
@@ -1978,6 +1986,9 @@ static struct pci_device_id serial_pci_tbl[] = {
PCI_VENDOR_ID_SPECIALIX, PCI_SUBDEVICE_ID_SPECIALIX_SPEED4, 0, 0,
pbn_b0_4_921600 },
{ PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
+ PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL, 0, 0,
+ pbn_b0_4_1152000 },
+ { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_b0_4_115200 },
{ PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI952,
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 25fcef2c42d..97034d3937f 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
@@ -263,13 +306,6 @@ config SERIAL_S3C2410_CONSOLE
your boot loader about how to pass options to the kernel at
boot time.)
-config SERIAL_BAST_SIO
- bool "Support for BAST SuperIO serial ports"
- depends on ARCH_BAST && SERIAL_8250=y
- help
- Support for registerin the SuperIO chip on BAST board with
- the 8250/16550 uart code.
-
config SERIAL_DZ
bool "DECstation DZ serial driver"
depends on MACH_DECSTATION && MIPS32
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 8f1cdde7dbe..11c7dc483f9 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
@@ -39,7 +44,6 @@ obj-$(CONFIG_SERIAL_LH7A40X) += serial_lh7a40x.o
obj-$(CONFIG_SERIAL_AU1X00) += au1x00_uart.o
obj-$(CONFIG_SERIAL_DZ) += dz.o
obj-$(CONFIG_SERIAL_SH_SCI) += sh-sci.o
-obj-$(CONFIG_SERIAL_BAST_SIO) += bast_sio.o
obj-$(CONFIG_SERIAL_SGI_L1_CONSOLE) += sn_console.o
obj-$(CONFIG_SERIAL_CPM) += cpm_uart/
obj-$(CONFIG_SERIAL_IMX) += imx.o
diff --git a/drivers/serial/au1x00_uart.c b/drivers/serial/au1x00_uart.c
index 5400dc2c087..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)
diff --git a/drivers/serial/bast_sio.c b/drivers/serial/bast_sio.c
deleted file mode 100644
index 2b48fab6f0c..00000000000
--- a/drivers/serial/bast_sio.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/* linux/drivers/serial/bast_sio.c
- *
- * Copyright (c) 2004 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * http://www.simtec.co.uk/products/EB2410ITX/
- *
- * 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.
- *
- * Modifications:
- * 23-Sep-2004 BJD Added copyright header
- * 23-Sep-2004 BJD Added serial port remove code
-*/
-
-#include <linux/module.h>
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/tty.h>
-#include <linux/serial.h>
-#include <linux/serial_core.h>
-#include <linux/types.h>
-
-#include <asm/io.h>
-#include <asm/serial.h>
-#include <asm/mach-types.h>
-
-#include <asm/arch/map.h>
-#include <asm/arch/irqs.h>
-#include <asm/arch/bast-map.h>
-#include <asm/arch/bast-irq.h>
-
-static int __init serial_bast_register(unsigned long port, unsigned int irq)
-{
- struct serial_struct serial_req;
-
- serial_req.flags = UPF_AUTOPROBE | UPF_SHARE_IRQ;
- serial_req.baud_base = BASE_BAUD;
- serial_req.irq = irq;
- serial_req.io_type = UPIO_MEM;
- serial_req.iomap_base = port;
- serial_req.iomem_base = ioremap(port, 0x10);
- serial_req.iomem_reg_shift = 0;
-
- return register_serial(&serial_req);
-}
-
-#define SERIAL_BASE (S3C2410_CS2 + BAST_PA_SUPERIO)
-
-static int port[2] = { -1, -1 };
-
-static int __init serial_bast_init(void)
-{
- if (machine_is_bast()) {
- port[0] = serial_bast_register(SERIAL_BASE + 0x2f8, IRQ_PCSERIAL1);
- port[1] = serial_bast_register(SERIAL_BASE + 0x3f8, IRQ_PCSERIAL2);
- }
-
- return 0;
-}
-
-static void __exit serial_bast_exit(void)
-{
- if (port[0] != -1)
- unregister_serial(port[0]);
- if (port[1] != -1)
- unregister_serial(port[1]);
-}
-
-
-module_init(serial_bast_init);
-module_exit(serial_bast_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Ben Dooks, ben@simtec.co.uk");
-MODULE_DESCRIPTION("BAST Onboard Serial setup");
-
-
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/crisv10.c b/drivers/serial/crisv10.c
index 3da5494953a..23b8871e74c 100644
--- a/drivers/serial/crisv10.c
+++ b/drivers/serial/crisv10.c
@@ -426,8 +426,6 @@
static char *serial_version = "$Revision: 1.25 $";
#include <linux/config.h>
-#include <linux/version.h>
-
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/signal.h>
diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c
index 546a0bc77e1..c112b32764e 100644
--- a/drivers/serial/icom.c
+++ b/drivers/serial/icom.c
@@ -25,7 +25,6 @@
#define SERIAL_DO_RESTART
#include <linux/module.h>
#include <linux/config.h>
-#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/signal.h>
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/jsm/jsm.h b/drivers/serial/jsm/jsm.h
index 777829fa330..5bf3c45521f 100644
--- a/drivers/serial/jsm/jsm.h
+++ b/drivers/serial/jsm/jsm.h
@@ -28,7 +28,6 @@
#define __JSM_DRIVER_H
#include <linux/kernel.h>
-#include <linux/version.h>
#include <linux/types.h> /* To pick up the varions Linux types */
#include <linux/tty.h>
#include <linux/serial_core.h>
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c
index a2a64331800..e43276c6a95 100644
--- a/drivers/serial/mpsc.c
+++ b/drivers/serial/mpsc.c
@@ -1058,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)
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 08b08d6ae90..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)
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 5c4678478b1..7365d4b50b9 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -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;
}
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/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 8e65206d3d7..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;