aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-10-03 12:13:29 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-03 12:13:29 -0400
commit6f3a28f7d1f0a65a78443c273b6e8ec01becf301 (patch)
treeea57276725b31ba115f44cb5267a7d85b133e6fb
parent6ebfc0e20b409f13e62bbb84ce70102b49945cfd (diff)
parent75fde2eddcfcd1dcc87a72dc6cd3c859420b6148 (diff)
Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-serial
* 'devel' of master.kernel.org:/home/rmk/linux-2.6-serial: (21 commits) [SERIAL] add PNP IDs for FPI based touchscreens [SERIAL] Magic SysRq SAK does nothing on serial consoles [SERIAL] tickle NMI watchdog on serial output. [SERIAL] Fix oops when removing suspended serial port [SERIAL] Fix resume handling bug [SERIAL] Remove wrong asm/serial.h inclusions [SERIAL] CONFIG_PM=n slim: drivers/serial/8250_pci.c [SERIAL] OMAP1510 serial fix for 115200 baud [SERIAL] returning proper error from serial core driver [SERIAL] Make uart_line_info() correctly tell MMIO from I/O port [SERIAL] suspend/resume handlers don't have level arg anymore [SERIAL] 8250 resourse management fixes [SERIAL] serial_cs: Add quirk for brainboxes 2-port RS232 card [SERIAL] serial_cs: handle Nokia multi->single port bodge via config quirk [SERIAL] serial_cs: add configuration quirk [SERIAL] serial_cs: Convert Oxford 950 / Possio GCC wakeup quirk [SERIAL] serial_cs: convert IBM post-init handling to a quirk [SERIAL] serial_cs: allow wildcarded quirks [SERIAL] serial_cs: convert multi-port table to quirk table [SERIAL] serial_cs: Use clean up multiport card detection ...
-rw-r--r--arch/frv/kernel/setup.c1
-rw-r--r--arch/ia64/kernel/setup.c1
-rw-r--r--arch/mips/cobalt/setup.c1
-rw-r--r--arch/mips/lasat/setup.c1
-rw-r--r--drivers/char/pcmcia/synclink_cs.c1
-rw-r--r--drivers/char/synclink.c1
-rw-r--r--drivers/serial/8250.c35
-rw-r--r--drivers/serial/8250_pci.c4
-rw-r--r--drivers/serial/8250_pnp.c13
-rw-r--r--drivers/serial/m32r_sio.c5
-rw-r--r--drivers/serial/serial_core.c18
-rw-r--r--drivers/serial/serial_cs.c292
-rw-r--r--drivers/serial/serial_txx9.c2
-rw-r--r--include/linux/serial_core.h3
14 files changed, 270 insertions, 108 deletions
diff --git a/arch/frv/kernel/setup.c b/arch/frv/kernel/setup.c
index d96a57e5f030..a8c61dac1cee 100644
--- a/arch/frv/kernel/setup.c
+++ b/arch/frv/kernel/setup.c
@@ -31,7 +31,6 @@
31#include <linux/serial_reg.h> 31#include <linux/serial_reg.h>
32 32
33#include <asm/setup.h> 33#include <asm/setup.h>
34#include <asm/serial.h>
35#include <asm/irq.h> 34#include <asm/irq.h>
36#include <asm/sections.h> 35#include <asm/sections.h>
37#include <asm/pgalloc.h> 36#include <asm/pgalloc.h>
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 84f93c0f2c66..c4caa8003492 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -54,7 +54,6 @@
54#include <asm/processor.h> 54#include <asm/processor.h>
55#include <asm/sal.h> 55#include <asm/sal.h>
56#include <asm/sections.h> 56#include <asm/sections.h>
57#include <asm/serial.h>
58#include <asm/setup.h> 57#include <asm/setup.h>
59#include <asm/smp.h> 58#include <asm/smp.h>
60#include <asm/system.h> 59#include <asm/system.h>
diff --git a/arch/mips/cobalt/setup.c b/arch/mips/cobalt/setup.c
index c01a0170e590..0b347cffc768 100644
--- a/arch/mips/cobalt/setup.c
+++ b/arch/mips/cobalt/setup.c
@@ -23,7 +23,6 @@
23#include <asm/processor.h> 23#include <asm/processor.h>
24#include <asm/reboot.h> 24#include <asm/reboot.h>
25#include <asm/gt64120.h> 25#include <asm/gt64120.h>
26#include <asm/serial.h>
27 26
28#include <asm/mach-cobalt/cobalt.h> 27#include <asm/mach-cobalt/cobalt.h>
29 28
diff --git a/arch/mips/lasat/setup.c b/arch/mips/lasat/setup.c
index 0ffc43c600d9..14c55168f1ff 100644
--- a/arch/mips/lasat/setup.c
+++ b/arch/mips/lasat/setup.c
@@ -34,7 +34,6 @@
34#include <asm/cpu.h> 34#include <asm/cpu.h>
35#include <asm/bootinfo.h> 35#include <asm/bootinfo.h>
36#include <asm/irq.h> 36#include <asm/irq.h>
37#include <asm/serial.h>
38#include <asm/lasat/lasat.h> 37#include <asm/lasat/lasat.h>
39#include <asm/lasat/serial.h> 38#include <asm/lasat/serial.h>
40 39
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index dd845cbefe94..d1ecb2c6de98 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -57,7 +57,6 @@
57#include <linux/netdevice.h> 57#include <linux/netdevice.h>
58#include <linux/vmalloc.h> 58#include <linux/vmalloc.h>
59#include <linux/init.h> 59#include <linux/init.h>
60#include <asm/serial.h>
61#include <linux/delay.h> 60#include <linux/delay.h>
62#include <linux/ioctl.h> 61#include <linux/ioctl.h>
63 62
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index 244dc308c770..38d94987de83 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -87,7 +87,6 @@
87 87
88#include <linux/vmalloc.h> 88#include <linux/vmalloc.h>
89#include <linux/init.h> 89#include <linux/init.h>
90#include <asm/serial.h>
91 90
92#include <linux/delay.h> 91#include <linux/delay.h>
93#include <linux/ioctl.h> 92#include <linux/ioctl.h>
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 10c2daab99ac..cc2a205d4230 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -1896,6 +1896,17 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios,
1896 serial_outp(up, UART_EFR, efr); 1896 serial_outp(up, UART_EFR, efr);
1897 } 1897 }
1898 1898
1899#ifdef CONFIG_ARCH_OMAP15XX
1900 /* Workaround to enable 115200 baud on OMAP1510 internal ports */
1901 if (cpu_is_omap1510() && is_omap_port((unsigned int)up->port.membase)) {
1902 if (baud == 115200) {
1903 quot = 1;
1904 serial_out(up, UART_OMAP_OSC_12M_SEL, 1);
1905 } else
1906 serial_out(up, UART_OMAP_OSC_12M_SEL, 0);
1907 }
1908#endif
1909
1899 if (up->capabilities & UART_NATSEMI) { 1910 if (up->capabilities & UART_NATSEMI) {
1900 /* Switch to bank 2 not bank 1, to avoid resetting EXCR2 */ 1911 /* Switch to bank 2 not bank 1, to avoid resetting EXCR2 */
1901 serial_outp(up, UART_LCR, 0xe0); 1912 serial_outp(up, UART_LCR, 0xe0);
@@ -1949,6 +1960,8 @@ static int serial8250_request_std_resource(struct uart_8250_port *up)
1949 case UPIO_AU: 1960 case UPIO_AU:
1950 size = 0x100000; 1961 size = 0x100000;
1951 /* fall thru */ 1962 /* fall thru */
1963 case UPIO_TSI:
1964 case UPIO_MEM32:
1952 case UPIO_MEM: 1965 case UPIO_MEM:
1953 if (!up->port.mapbase) 1966 if (!up->port.mapbase)
1954 break; 1967 break;
@@ -1984,6 +1997,8 @@ static void serial8250_release_std_resource(struct uart_8250_port *up)
1984 case UPIO_AU: 1997 case UPIO_AU:
1985 size = 0x100000; 1998 size = 0x100000;
1986 /* fall thru */ 1999 /* fall thru */
2000 case UPIO_TSI:
2001 case UPIO_MEM32:
1987 case UPIO_MEM: 2002 case UPIO_MEM:
1988 if (!up->port.mapbase) 2003 if (!up->port.mapbase)
1989 break; 2004 break;
@@ -2007,17 +2022,15 @@ static int serial8250_request_rsa_resource(struct uart_8250_port *up)
2007{ 2022{
2008 unsigned long start = UART_RSA_BASE << up->port.regshift; 2023 unsigned long start = UART_RSA_BASE << up->port.regshift;
2009 unsigned int size = 8 << up->port.regshift; 2024 unsigned int size = 8 << up->port.regshift;
2010 int ret = 0; 2025 int ret = -EINVAL;
2011 2026
2012 switch (up->port.iotype) { 2027 switch (up->port.iotype) {
2013 case UPIO_MEM:
2014 ret = -EINVAL;
2015 break;
2016
2017 case UPIO_HUB6: 2028 case UPIO_HUB6:
2018 case UPIO_PORT: 2029 case UPIO_PORT:
2019 start += up->port.iobase; 2030 start += up->port.iobase;
2020 if (!request_region(start, size, "serial-rsa")) 2031 if (request_region(start, size, "serial-rsa"))
2032 ret = 0;
2033 else
2021 ret = -EBUSY; 2034 ret = -EBUSY;
2022 break; 2035 break;
2023 } 2036 }
@@ -2031,9 +2044,6 @@ static void serial8250_release_rsa_resource(struct uart_8250_port *up)
2031 unsigned int size = 8 << up->port.regshift; 2044 unsigned int size = 8 << up->port.regshift;
2032 2045
2033 switch (up->port.iotype) { 2046 switch (up->port.iotype) {
2034 case UPIO_MEM:
2035 break;
2036
2037 case UPIO_HUB6: 2047 case UPIO_HUB6:
2038 case UPIO_PORT: 2048 case UPIO_PORT:
2039 release_region(up->port.iobase + offset, size); 2049 release_region(up->port.iobase + offset, size);
@@ -2222,9 +2232,10 @@ static inline void wait_for_xmitr(struct uart_8250_port *up, int bits)
2222 /* Wait up to 1s for flow control if necessary */ 2232 /* Wait up to 1s for flow control if necessary */
2223 if (up->port.flags & UPF_CONS_FLOW) { 2233 if (up->port.flags & UPF_CONS_FLOW) {
2224 tmout = 1000000; 2234 tmout = 1000000;
2225 while (--tmout && 2235 while (!(serial_in(up, UART_MSR) & UART_MSR_CTS) && --tmout) {
2226 ((serial_in(up, UART_MSR) & UART_MSR_CTS) == 0))
2227 udelay(1); 2236 udelay(1);
2237 touch_nmi_watchdog();
2238 }
2228 } 2239 }
2229} 2240}
2230 2241
@@ -2397,7 +2408,6 @@ int __init early_serial_setup(struct uart_port *port)
2397/** 2408/**
2398 * serial8250_suspend_port - suspend one serial port 2409 * serial8250_suspend_port - suspend one serial port
2399 * @line: serial line number 2410 * @line: serial line number
2400 * @level: the level of port suspension, as per uart_suspend_port
2401 * 2411 *
2402 * Suspend one serial port. 2412 * Suspend one serial port.
2403 */ 2413 */
@@ -2409,7 +2419,6 @@ void serial8250_suspend_port(int line)
2409/** 2419/**
2410 * serial8250_resume_port - resume one serial port 2420 * serial8250_resume_port - resume one serial port
2411 * @line: serial line number 2421 * @line: serial line number
2412 * @level: the level of port resumption, as per uart_resume_port
2413 * 2422 *
2414 * Resume one serial port. 2423 * Resume one serial port.
2415 */ 2424 */
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 851e4839d6d9..4d0ff8f4a01b 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -1789,6 +1789,7 @@ static void __devexit pciserial_remove_one(struct pci_dev *dev)
1789 pci_disable_device(dev); 1789 pci_disable_device(dev);
1790} 1790}
1791 1791
1792#ifdef CONFIG_PM
1792static int pciserial_suspend_one(struct pci_dev *dev, pm_message_t state) 1793static int pciserial_suspend_one(struct pci_dev *dev, pm_message_t state)
1793{ 1794{
1794 struct serial_private *priv = pci_get_drvdata(dev); 1795 struct serial_private *priv = pci_get_drvdata(dev);
@@ -1818,6 +1819,7 @@ static int pciserial_resume_one(struct pci_dev *dev)
1818 } 1819 }
1819 return 0; 1820 return 0;
1820} 1821}
1822#endif
1821 1823
1822static struct pci_device_id serial_pci_tbl[] = { 1824static struct pci_device_id serial_pci_tbl[] = {
1823 { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960, 1825 { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
@@ -2375,8 +2377,10 @@ static struct pci_driver serial_pci_driver = {
2375 .name = "serial", 2377 .name = "serial",
2376 .probe = pciserial_init_one, 2378 .probe = pciserial_init_one,
2377 .remove = __devexit_p(pciserial_remove_one), 2379 .remove = __devexit_p(pciserial_remove_one),
2380#ifdef CONFIG_PM
2378 .suspend = pciserial_suspend_one, 2381 .suspend = pciserial_suspend_one,
2379 .resume = pciserial_resume_one, 2382 .resume = pciserial_resume_one,
2383#endif
2380 .id_table = serial_pci_tbl, 2384 .id_table = serial_pci_tbl,
2381}; 2385};
2382 2386
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
index 632f62d6ec7e..71d907c8288b 100644
--- a/drivers/serial/8250_pnp.c
+++ b/drivers/serial/8250_pnp.c
@@ -327,6 +327,19 @@ static const struct pnp_device_id pnp_dev_table[] = {
327 { "WACF004", 0 }, 327 { "WACF004", 0 },
328 { "WACF005", 0 }, 328 { "WACF005", 0 },
329 { "WACF006", 0 }, 329 { "WACF006", 0 },
330 /* Compaq touchscreen */
331 { "FPI2002", 0 },
332 /* Fujitsu Stylistic touchscreens */
333 { "FUJ02B2", 0 },
334 { "FUJ02B3", 0 },
335 /* Fujitsu Stylistic LT touchscreens */
336 { "FUJ02B4", 0 },
337 /* Passive Fujitsu Stylistic touchscreens */
338 { "FUJ02B6", 0 },
339 { "FUJ02B7", 0 },
340 { "FUJ02B8", 0 },
341 { "FUJ02B9", 0 },
342 { "FUJ02BC", 0 },
330 /* Rockwell's (PORALiNK) 33600 INT PNP */ 343 /* Rockwell's (PORALiNK) 33600 INT PNP */
331 { "WCI0003", 0 }, 344 { "WCI0003", 0 },
332 /* Unkown PnP modems */ 345 /* Unkown PnP modems */
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c
index e7fe4bb46eca..28c9ce6f0bdc 100644
--- a/drivers/serial/m32r_sio.c
+++ b/drivers/serial/m32r_sio.c
@@ -76,7 +76,7 @@
76 */ 76 */
77#define is_real_interrupt(irq) ((irq) != 0) 77#define is_real_interrupt(irq) ((irq) != 0)
78 78
79#include <asm/serial.h> 79#define BASE_BAUD 115200
80 80
81/* Standard COM flags */ 81/* Standard COM flags */
82#define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST) 82#define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST)
@@ -86,7 +86,6 @@
86 * standard enumeration mechanism. Platforms that can find all 86 * standard enumeration mechanism. Platforms that can find all
87 * serial ports via mechanisms like ACPI or PCI need not supply it. 87 * serial ports via mechanisms like ACPI or PCI need not supply it.
88 */ 88 */
89#undef SERIAL_PORT_DFNS
90#if defined(CONFIG_PLAT_USRV) 89#if defined(CONFIG_PLAT_USRV)
91 90
92#define SERIAL_PORT_DFNS \ 91#define SERIAL_PORT_DFNS \
@@ -109,7 +108,7 @@
109#endif /* !CONFIG_PLAT_USRV */ 108#endif /* !CONFIG_PLAT_USRV */
110 109
111static struct old_serial_port old_serial_port[] = { 110static struct old_serial_port old_serial_port[] = {
112 SERIAL_PORT_DFNS /* defined in asm/serial.h */ 111 SERIAL_PORT_DFNS
113}; 112};
114 113
115#define UART_NR ARRAY_SIZE(old_serial_port) 114#define UART_NR ARRAY_SIZE(old_serial_port)
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index de5e8930a6fd..c67b05e9a451 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -792,6 +792,7 @@ static int uart_set_info(struct uart_state *state,
792 * We failed anyway. 792 * We failed anyway.
793 */ 793 */
794 retval = -EBUSY; 794 retval = -EBUSY;
795 goto exit; // Added to return the correct error -Ram Gupta
795 } 796 }
796 } 797 }
797 798
@@ -1662,16 +1663,16 @@ static int uart_line_info(char *buf, struct uart_driver *drv, int i)
1662 struct uart_port *port = state->port; 1663 struct uart_port *port = state->port;
1663 char stat_buf[32]; 1664 char stat_buf[32];
1664 unsigned int status; 1665 unsigned int status;
1665 int ret; 1666 int mmio, ret;
1666 1667
1667 if (!port) 1668 if (!port)
1668 return 0; 1669 return 0;
1669 1670
1671 mmio = port->iotype >= UPIO_MEM;
1670 ret = sprintf(buf, "%d: uart:%s %s%08lX irq:%d", 1672 ret = sprintf(buf, "%d: uart:%s %s%08lX irq:%d",
1671 port->line, uart_type(port), 1673 port->line, uart_type(port),
1672 port->iotype == UPIO_MEM ? "mmio:0x" : "port:", 1674 mmio ? "mmio:0x" : "port:",
1673 port->iotype == UPIO_MEM ? port->mapbase : 1675 mmio ? port->mapbase : (unsigned long) port->iobase,
1674 (unsigned long) port->iobase,
1675 port->irq); 1676 port->irq);
1676 1677
1677 if (port->type == PORT_UNKNOWN) { 1678 if (port->type == PORT_UNKNOWN) {
@@ -1939,6 +1940,9 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
1939 if (state->info && state->info->flags & UIF_INITIALIZED) { 1940 if (state->info && state->info->flags & UIF_INITIALIZED) {
1940 const struct uart_ops *ops = port->ops; 1941 const struct uart_ops *ops = port->ops;
1941 1942
1943 state->info->flags = (state->info->flags & ~UIF_INITIALIZED)
1944 | UIF_SUSPENDED;
1945
1942 spin_lock_irq(&port->lock); 1946 spin_lock_irq(&port->lock);
1943 ops->stop_tx(port); 1947 ops->stop_tx(port);
1944 ops->set_mctrl(port, 0); 1948 ops->set_mctrl(port, 0);
@@ -2005,7 +2009,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
2005 console_start(port->cons); 2009 console_start(port->cons);
2006 } 2010 }
2007 2011
2008 if (state->info && state->info->flags & UIF_INITIALIZED) { 2012 if (state->info && state->info->flags & UIF_SUSPENDED) {
2009 const struct uart_ops *ops = port->ops; 2013 const struct uart_ops *ops = port->ops;
2010 int ret; 2014 int ret;
2011 2015
@@ -2017,15 +2021,17 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
2017 ops->set_mctrl(port, port->mctrl); 2021 ops->set_mctrl(port, port->mctrl);
2018 ops->start_tx(port); 2022 ops->start_tx(port);
2019 spin_unlock_irq(&port->lock); 2023 spin_unlock_irq(&port->lock);
2024 state->info->flags |= UIF_INITIALIZED;
2020 } else { 2025 } else {
2021 /* 2026 /*
2022 * Failed to resume - maybe hardware went away? 2027 * Failed to resume - maybe hardware went away?
2023 * Clear the "initialized" flag so we won't try 2028 * Clear the "initialized" flag so we won't try
2024 * to call the low level drivers shutdown method. 2029 * to call the low level drivers shutdown method.
2025 */ 2030 */
2026 state->info->flags &= ~UIF_INITIALIZED;
2027 uart_shutdown(state); 2031 uart_shutdown(state);
2028 } 2032 }
2033
2034 state->info->flags &= ~UIF_SUSPENDED;
2029 } 2035 }
2030 2036
2031 mutex_unlock(&state->mutex); 2037 mutex_unlock(&state->mutex);
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index cbf260bc225d..00f9ffd69489 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -80,23 +80,16 @@ module_param(buggy_uart, int, 0444);
80 80
81/* Table of multi-port card ID's */ 81/* Table of multi-port card ID's */
82 82
83struct multi_id { 83struct serial_quirk {
84 u_short manfid; 84 unsigned int manfid;
85 u_short prodid; 85 unsigned int prodid;
86 int multi; /* 1 = multifunction, > 1 = # ports */ 86 int multi; /* 1 = multifunction, > 1 = # ports */
87 void (*config)(struct pcmcia_device *);
88 void (*setup)(struct pcmcia_device *, struct uart_port *);
89 void (*wakeup)(struct pcmcia_device *);
90 int (*post)(struct pcmcia_device *);
87}; 91};
88 92
89static const struct multi_id multi_id[] = {
90 { MANFID_OMEGA, PRODID_OMEGA_QSP_100, 4 },
91 { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232, 2 },
92 { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232_D1, 2 },
93 { MANFID_QUATECH, PRODID_QUATECH_QUAD_RS232, 4 },
94 { MANFID_SOCKET, PRODID_SOCKET_DUAL_RS232, 2 },
95 { MANFID_INTEL, PRODID_INTEL_DUAL_RS232, 2 },
96 { MANFID_NATINST, PRODID_NATINST_QUAD_RS232, 4 }
97};
98#define MULTI_COUNT (sizeof(multi_id)/sizeof(struct multi_id))
99
100struct serial_info { 93struct serial_info {
101 struct pcmcia_device *p_dev; 94 struct pcmcia_device *p_dev;
102 int ndev; 95 int ndev;
@@ -107,6 +100,7 @@ struct serial_info {
107 int c950ctrl; 100 int c950ctrl;
108 dev_node_t node[4]; 101 dev_node_t node[4];
109 int line[4]; 102 int line[4];
103 const struct serial_quirk *quirk;
110}; 104};
111 105
112struct serial_cfg_mem { 106struct serial_cfg_mem {
@@ -115,37 +109,165 @@ struct serial_cfg_mem {
115 u_char buf[256]; 109 u_char buf[256];
116}; 110};
117 111
112/*
113 * vers_1 5.0, "Brain Boxes", "2-Port RS232 card", "r6"
114 * manfid 0x0160, 0x0104
115 * This card appears to have a 14.7456MHz clock.
116 */
117static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_port *port)
118{
119 port->uartclk = 14745600;
120}
118 121
119static int serial_config(struct pcmcia_device * link); 122static int quirk_post_ibm(struct pcmcia_device *link)
123{
124 conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
125 int last_ret, last_fn;
120 126
127 last_ret = pcmcia_access_configuration_register(link, &reg);
128 if (last_ret) {
129 last_fn = AccessConfigurationRegister;
130 goto cs_failed;
131 }
132 reg.Action = CS_WRITE;
133 reg.Value = reg.Value | 1;
134 last_ret = pcmcia_access_configuration_register(link, &reg);
135 if (last_ret) {
136 last_fn = AccessConfigurationRegister;
137 goto cs_failed;
138 }
139 return 0;
121 140
122static void wakeup_card(struct serial_info *info) 141 cs_failed:
142 cs_error(link, last_fn, last_ret);
143 return -ENODEV;
144}
145
146/*
147 * Nokia cards are not really multiport cards. Shouldn't this
148 * be handled by setting the quirk entry .multi = 0 | 1 ?
149 */
150static void quirk_config_nokia(struct pcmcia_device *link)
123{ 151{
124 int ctrl = info->c950ctrl; 152 struct serial_info *info = link->priv;
125 153
126 if (info->manfid == MANFID_OXSEMI) { 154 if (info->multi > 1)
127 outb(12, ctrl + 1); 155 info->multi = 1;
128 } else if (info->manfid == MANFID_POSSIO && info->prodid == PRODID_POSSIO_GCC) { 156}
129 /* request_region? oxsemi branch does no request_region too... */ 157
130 /* This sequence is needed to properly initialize MC45 attached to OXCF950. 158static void quirk_wakeup_oxsemi(struct pcmcia_device *link)
131 * I tried decreasing these msleep()s, but it worked properly (survived 159{
132 * 1000 stop/start operations) with these timeouts (or bigger). */ 160 struct serial_info *info = link->priv;
133 outb(0xA, ctrl + 1); 161
134 msleep(100); 162 outb(12, info->c950ctrl + 1);
135 outb(0xE, ctrl + 1); 163}
136 msleep(300); 164
137 outb(0xC, ctrl + 1); 165/* request_region? oxsemi branch does no request_region too... */
138 msleep(100); 166/*
139 outb(0xE, ctrl + 1); 167 * This sequence is needed to properly initialize MC45 attached to OXCF950.
140 msleep(200); 168 * I tried decreasing these msleep()s, but it worked properly (survived
141 outb(0xF, ctrl + 1); 169 * 1000 stop/start operations) with these timeouts (or bigger).
142 msleep(100); 170 */
143 outb(0xE, ctrl + 1); 171static void quirk_wakeup_possio_gcc(struct pcmcia_device *link)
144 msleep(100); 172{
145 outb(0xC, ctrl + 1); 173 struct serial_info *info = link->priv;
174 unsigned int ctrl = info->c950ctrl;
175
176 outb(0xA, ctrl + 1);
177 msleep(100);
178 outb(0xE, ctrl + 1);
179 msleep(300);
180 outb(0xC, ctrl + 1);
181 msleep(100);
182 outb(0xE, ctrl + 1);
183 msleep(200);
184 outb(0xF, ctrl + 1);
185 msleep(100);
186 outb(0xE, ctrl + 1);
187 msleep(100);
188 outb(0xC, ctrl + 1);
189}
190
191/*
192 * Socket Dual IO: this enables irq's for second port
193 */
194static void quirk_config_socket(struct pcmcia_device *link)
195{
196 struct serial_info *info = link->priv;
197
198 if (info->multi) {
199 link->conf.Present |= PRESENT_EXT_STATUS;
200 link->conf.ExtStatus = ESR_REQ_ATTN_ENA;
146 } 201 }
147} 202}
148 203
204static const struct serial_quirk quirks[] = {
205 {
206 .manfid = 0x0160,
207 .prodid = 0x0104,
208 .multi = -1,
209 .setup = quirk_setup_brainboxes_0104,
210 }, {
211 .manfid = MANFID_IBM,
212 .prodid = ~0,
213 .multi = -1,
214 .post = quirk_post_ibm,
215 }, {
216 .manfid = MANFID_INTEL,
217 .prodid = PRODID_INTEL_DUAL_RS232,
218 .multi = 2,
219 }, {
220 .manfid = MANFID_NATINST,
221 .prodid = PRODID_NATINST_QUAD_RS232,
222 .multi = 4,
223 }, {
224 .manfid = MANFID_NOKIA,
225 .prodid = ~0,
226 .multi = -1,
227 .config = quirk_config_nokia,
228 }, {
229 .manfid = MANFID_OMEGA,
230 .prodid = PRODID_OMEGA_QSP_100,
231 .multi = 4,
232 }, {
233 .manfid = MANFID_OXSEMI,
234 .prodid = ~0,
235 .multi = -1,
236 .wakeup = quirk_wakeup_oxsemi,
237 }, {
238 .manfid = MANFID_POSSIO,
239 .prodid = PRODID_POSSIO_GCC,
240 .multi = -1,
241 .wakeup = quirk_wakeup_possio_gcc,
242 }, {
243 .manfid = MANFID_QUATECH,
244 .prodid = PRODID_QUATECH_DUAL_RS232,
245 .multi = 2,
246 }, {
247 .manfid = MANFID_QUATECH,
248 .prodid = PRODID_QUATECH_DUAL_RS232_D1,
249 .multi = 2,
250 }, {
251 .manfid = MANFID_QUATECH,
252 .prodid = PRODID_QUATECH_QUAD_RS232,
253 .multi = 4,
254 }, {
255 .manfid = MANFID_SOCKET,
256 .prodid = PRODID_SOCKET_DUAL_RS232,
257 .multi = 2,
258 .config = quirk_config_socket,
259 }, {
260 .manfid = MANFID_SOCKET,
261 .prodid = ~0,
262 .multi = -1,
263 .config = quirk_config_socket,
264 }
265};
266
267
268static int serial_config(struct pcmcia_device * link);
269
270
149/*====================================================================== 271/*======================================================================
150 272
151 After a card is removed, serial_remove() will unregister 273 After a card is removed, serial_remove() will unregister
@@ -185,14 +307,14 @@ static int serial_suspend(struct pcmcia_device *link)
185 307
186static int serial_resume(struct pcmcia_device *link) 308static int serial_resume(struct pcmcia_device *link)
187{ 309{
188 if (pcmcia_dev_present(link)) { 310 struct serial_info *info = link->priv;
189 struct serial_info *info = link->priv; 311 int i;
190 int i;
191 312
192 for (i = 0; i < info->ndev; i++) 313 for (i = 0; i < info->ndev; i++)
193 serial8250_resume_port(info->line[i]); 314 serial8250_resume_port(info->line[i]);
194 wakeup_card(info); 315
195 } 316 if (info->quirk && info->quirk->wakeup)
317 info->quirk->wakeup(link);
196 318
197 return 0; 319 return 0;
198} 320}
@@ -278,6 +400,10 @@ static int setup_serial(struct pcmcia_device *handle, struct serial_info * info,
278 port.dev = &handle_to_dev(handle); 400 port.dev = &handle_to_dev(handle);
279 if (buggy_uart) 401 if (buggy_uart)
280 port.flags |= UPF_BUGGY_UART; 402 port.flags |= UPF_BUGGY_UART;
403
404 if (info->quirk && info->quirk->setup)
405 info->quirk->setup(handle, &port);
406
281 line = serial8250_register_port(&port); 407 line = serial8250_register_port(&port);
282 if (line < 0) { 408 if (line < 0) {
283 printk(KERN_NOTICE "serial_cs: serial8250_register_port() at " 409 printk(KERN_NOTICE "serial_cs: serial8250_register_port() at "
@@ -433,6 +559,13 @@ next_entry:
433 } 559 }
434 if (info->multi && (info->manfid == MANFID_3COM)) 560 if (info->multi && (info->manfid == MANFID_3COM))
435 link->conf.ConfigIndex &= ~(0x08); 561 link->conf.ConfigIndex &= ~(0x08);
562
563 /*
564 * Apply any configuration quirks.
565 */
566 if (info->quirk && info->quirk->config)
567 info->quirk->config(link);
568
436 i = pcmcia_request_configuration(link, &link->conf); 569 i = pcmcia_request_configuration(link, &link->conf);
437 if (i != CS_SUCCESS) { 570 if (i != CS_SUCCESS) {
438 cs_error(link, RequestConfiguration, i); 571 cs_error(link, RequestConfiguration, i);
@@ -521,11 +654,13 @@ static int multi_config(struct pcmcia_device * link)
521 cs_error(link, RequestIRQ, i); 654 cs_error(link, RequestIRQ, i);
522 link->irq.AssignedIRQ = 0; 655 link->irq.AssignedIRQ = 0;
523 } 656 }
524 /* Socket Dual IO: this enables irq's for second port */ 657
525 if (info->multi && (info->manfid == MANFID_SOCKET)) { 658 /*
526 link->conf.Present |= PRESENT_EXT_STATUS; 659 * Apply any configuration quirks.
527 link->conf.ExtStatus = ESR_REQ_ATTN_ENA; 660 */
528 } 661 if (info->quirk && info->quirk->config)
662 info->quirk->config(link);
663
529 i = pcmcia_request_configuration(link, &link->conf); 664 i = pcmcia_request_configuration(link, &link->conf);
530 if (i != CS_SUCCESS) { 665 if (i != CS_SUCCESS) {
531 cs_error(link, RequestConfiguration, i); 666 cs_error(link, RequestConfiguration, i);
@@ -550,17 +685,19 @@ static int multi_config(struct pcmcia_device * link)
550 link->irq.AssignedIRQ); 685 link->irq.AssignedIRQ);
551 } 686 }
552 info->c950ctrl = base2; 687 info->c950ctrl = base2;
553 wakeup_card(info); 688
689 /*
690 * FIXME: We really should wake up the port prior to
691 * handing it over to the serial layer.
692 */
693 if (info->quirk && info->quirk->wakeup)
694 info->quirk->wakeup(link);
695
554 rc = 0; 696 rc = 0;
555 goto free_cfg_mem; 697 goto free_cfg_mem;
556 } 698 }
557 699
558 setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ); 700 setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ);
559 /* The Nokia cards are not really multiport cards */
560 if (info->manfid == MANFID_NOKIA) {
561 rc = 0;
562 goto free_cfg_mem;
563 }
564 for (i = 0; i < info->multi - 1; i++) 701 for (i = 0; i < info->multi - 1; i++)
565 setup_serial(link, info, base2 + (8 * i), 702 setup_serial(link, info, base2 + (8 * i),
566 link->irq.AssignedIRQ); 703 link->irq.AssignedIRQ);
@@ -622,13 +759,16 @@ static int serial_config(struct pcmcia_device * link)
622 tuple->DesiredTuple = CISTPL_MANFID; 759 tuple->DesiredTuple = CISTPL_MANFID;
623 if (first_tuple(link, tuple, parse) == CS_SUCCESS) { 760 if (first_tuple(link, tuple, parse) == CS_SUCCESS) {
624 info->manfid = parse->manfid.manf; 761 info->manfid = parse->manfid.manf;
625 info->prodid = le16_to_cpu(buf[1]); 762 info->prodid = parse->manfid.card;
626 for (i = 0; i < MULTI_COUNT; i++) 763
627 if ((info->manfid == multi_id[i].manfid) && 764 for (i = 0; i < ARRAY_SIZE(quirks); i++)
628 (parse->manfid.card == multi_id[i].prodid)) 765 if ((quirks[i].manfid == ~0 ||
766 quirks[i].manfid == info->manfid) &&
767 (quirks[i].prodid == ~0 ||
768 quirks[i].prodid == info->prodid)) {
769 info->quirk = &quirks[i];
629 break; 770 break;
630 if (i < MULTI_COUNT) 771 }
631 info->multi = multi_id[i].multi;
632 } 772 }
633 773
634 /* Another check for dual-serial cards: look for either serial or 774 /* Another check for dual-serial cards: look for either serial or
@@ -648,6 +788,12 @@ static int serial_config(struct pcmcia_device * link)
648 } 788 }
649 } 789 }
650 790
791 /*
792 * Apply any multi-port quirk.
793 */
794 if (info->quirk && info->quirk->multi != -1)
795 info->multi = info->quirk->multi;
796
651 if (info->multi > 1) 797 if (info->multi > 1)
652 multi_config(link); 798 multi_config(link);
653 else 799 else
@@ -656,21 +802,13 @@ static int serial_config(struct pcmcia_device * link)
656 if (info->ndev == 0) 802 if (info->ndev == 0)
657 goto failed; 803 goto failed;
658 804
659 if (info->manfid == MANFID_IBM) { 805 /*
660 conf_reg_t reg = { 0, CS_READ, 0x800, 0 }; 806 * Apply any post-init quirk. FIXME: This should really happen
661 last_ret = pcmcia_access_configuration_register(link, &reg); 807 * before we register the port, since it might already be in use.
662 if (last_ret) { 808 */
663 last_fn = AccessConfigurationRegister; 809 if (info->quirk && info->quirk->post)
664 goto cs_failed; 810 if (info->quirk->post(link))
665 } 811 goto failed;
666 reg.Action = CS_WRITE;
667 reg.Value = reg.Value | 1;
668 last_ret = pcmcia_access_configuration_register(link, &reg);
669 if (last_ret) {
670 last_fn = AccessConfigurationRegister;
671 goto cs_failed;
672 }
673 }
674 812
675 link->dev_node = &info->node[0]; 813 link->dev_node = &info->node[0];
676 kfree(cfg_mem); 814 kfree(cfg_mem);
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index b361669f85a1..ebd8d2bb17fd 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -990,7 +990,6 @@ int __init early_serial_txx9_setup(struct uart_port *port)
990/** 990/**
991 * serial_txx9_suspend_port - suspend one serial port 991 * serial_txx9_suspend_port - suspend one serial port
992 * @line: serial line number 992 * @line: serial line number
993 * @level: the level of port suspension, as per uart_suspend_port
994 * 993 *
995 * Suspend one serial port. 994 * Suspend one serial port.
996 */ 995 */
@@ -1002,7 +1001,6 @@ static void serial_txx9_suspend_port(int line)
1002/** 1001/**
1003 * serial_txx9_resume_port - resume one serial port 1002 * serial_txx9_resume_port - resume one serial port
1004 * @line: serial line number 1003 * @line: serial line number
1005 * @level: the level of port resumption, as per uart_resume_port
1006 * 1004 *
1007 * Resume one serial port. 1005 * Resume one serial port.
1008 */ 1006 */
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 86501a3de2ac..de2e68159d96 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -319,6 +319,7 @@ struct uart_info {
319#define UIF_CTS_FLOW ((__force uif_t) (1 << 26)) 319#define UIF_CTS_FLOW ((__force uif_t) (1 << 26))
320#define UIF_NORMAL_ACTIVE ((__force uif_t) (1 << 29)) 320#define UIF_NORMAL_ACTIVE ((__force uif_t) (1 << 29))
321#define UIF_INITIALIZED ((__force uif_t) (1 << 31)) 321#define UIF_INITIALIZED ((__force uif_t) (1 << 31))
322#define UIF_SUSPENDED ((__force uif_t) (1 << 30))
322 323
323 int blocked_open; 324 int blocked_open;
324 325
@@ -414,7 +415,7 @@ uart_handle_sysrq_char(struct uart_port *port, unsigned int ch,
414#ifdef SUPPORT_SYSRQ 415#ifdef SUPPORT_SYSRQ
415 if (port->sysrq) { 416 if (port->sysrq) {
416 if (ch && time_before(jiffies, port->sysrq)) { 417 if (ch && time_before(jiffies, port->sysrq)) {
417 handle_sysrq(ch, regs, NULL); 418 handle_sysrq(ch, regs, port->info->tty);
418 port->sysrq = 0; 419 port->sysrq = 0;
419 return 1; 420 return 1;
420 } 421 }