diff options
author | Artem B. Bityuckiy <dedekind@infradead.org> | 2005-07-06 10:43:18 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@mtd.linutronix.de> | 2005-07-06 13:40:38 -0400 |
commit | b3539219c9ea20ebf6a5ea3cc534f423a3607c41 (patch) | |
tree | d17c31c0eac0a7290ba5011b59a100fd9e9c9532 /drivers/serial | |
parent | 6430a8def12edebc1c9c7c2621d33ca0e8653c33 (diff) | |
parent | a18bcb7450840f07a772a45229de4811d930f461 (diff) |
Merge with rsync://fileserver/linux
Update to 2.6.12-rc3
Diffstat (limited to 'drivers/serial')
-rw-r--r-- | drivers/serial/68328serial.c | 17 | ||||
-rw-r--r-- | drivers/serial/8250.c | 61 | ||||
-rw-r--r-- | drivers/serial/8250_accent.c | 47 | ||||
-rw-r--r-- | drivers/serial/8250_boca.c | 61 | ||||
-rw-r--r-- | drivers/serial/8250_fourport.c | 53 | ||||
-rw-r--r-- | drivers/serial/8250_hub6.c | 58 | ||||
-rw-r--r-- | drivers/serial/8250_mca.c | 64 | ||||
-rw-r--r-- | drivers/serial/Kconfig | 77 | ||||
-rw-r--r-- | drivers/serial/Makefile | 5 | ||||
-rw-r--r-- | drivers/serial/au1x00_uart.c | 3 | ||||
-rw-r--r-- | drivers/serial/cpm_uart/cpm_uart_cpm1.c | 32 | ||||
-rw-r--r-- | drivers/serial/ip22zilog.c | 13 | ||||
-rw-r--r-- | drivers/serial/mpsc.c | 3 | ||||
-rw-r--r-- | drivers/serial/pmac_zilog.c | 4 | ||||
-rw-r--r-- | drivers/serial/pxa.c | 3 | ||||
-rw-r--r-- | drivers/serial/s3c2410.c | 5 | ||||
-rw-r--r-- | drivers/serial/serial_core.c | 42 | ||||
-rw-r--r-- | drivers/serial/serial_cs.c | 106 | ||||
-rw-r--r-- | drivers/serial/serial_txx9.c | 3 | ||||
-rw-r--r-- | drivers/serial/sunsab.c | 7 | ||||
-rw-r--r-- | drivers/serial/sunsu.c | 3 | ||||
-rw-r--r-- | drivers/serial/sunzilog.c | 13 |
22 files changed, 570 insertions, 110 deletions
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c index feb8e73fc1c9..d27fb4c881d2 100644 --- a/drivers/serial/68328serial.c +++ b/drivers/serial/68328serial.c | |||
@@ -1497,23 +1497,6 @@ rs68328_init(void) | |||
1497 | return 0; | 1497 | return 0; |
1498 | } | 1498 | } |
1499 | 1499 | ||
1500 | |||
1501 | |||
1502 | /* | ||
1503 | * register_serial and unregister_serial allows for serial ports to be | ||
1504 | * configured at run-time, to support PCMCIA modems. | ||
1505 | */ | ||
1506 | /* SPARC: Unused at this time, just here to make things link. */ | ||
1507 | int register_serial(struct serial_struct *req) | ||
1508 | { | ||
1509 | return -1; | ||
1510 | } | ||
1511 | |||
1512 | void unregister_serial(int line) | ||
1513 | { | ||
1514 | return; | ||
1515 | } | ||
1516 | |||
1517 | module_init(rs68328_init); | 1500 | module_init(rs68328_init); |
1518 | 1501 | ||
1519 | 1502 | ||
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index d8b9d2b8c200..7e8fc7c1d4cc 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -77,23 +77,9 @@ static unsigned int share_irqs = SERIAL8250_SHARE_IRQS; | |||
77 | */ | 77 | */ |
78 | #define is_real_interrupt(irq) ((irq) != 0) | 78 | #define is_real_interrupt(irq) ((irq) != 0) |
79 | 79 | ||
80 | /* | ||
81 | * This converts from our new CONFIG_ symbols to the symbols | ||
82 | * that asm/serial.h expects. You _NEED_ to comment out the | ||
83 | * linux/config.h include contained inside asm/serial.h for | ||
84 | * this to work. | ||
85 | */ | ||
86 | #undef CONFIG_SERIAL_MANY_PORTS | ||
87 | #undef CONFIG_SERIAL_DETECT_IRQ | ||
88 | #undef CONFIG_SERIAL_MULTIPORT | ||
89 | #undef CONFIG_HUB6 | ||
90 | |||
91 | #ifdef CONFIG_SERIAL_8250_DETECT_IRQ | 80 | #ifdef CONFIG_SERIAL_8250_DETECT_IRQ |
92 | #define CONFIG_SERIAL_DETECT_IRQ 1 | 81 | #define CONFIG_SERIAL_DETECT_IRQ 1 |
93 | #endif | 82 | #endif |
94 | #ifdef CONFIG_SERIAL_8250_MULTIPORT | ||
95 | #define CONFIG_SERIAL_MULTIPORT 1 | ||
96 | #endif | ||
97 | #ifdef CONFIG_SERIAL_8250_MANY_PORTS | 83 | #ifdef CONFIG_SERIAL_8250_MANY_PORTS |
98 | #define CONFIG_SERIAL_MANY_PORTS 1 | 84 | #define CONFIG_SERIAL_MANY_PORTS 1 |
99 | #endif | 85 | #endif |
@@ -119,7 +105,7 @@ static struct old_serial_port old_serial_port[] = { | |||
119 | SERIAL_PORT_DFNS /* defined in asm/serial.h */ | 105 | SERIAL_PORT_DFNS /* defined in asm/serial.h */ |
120 | }; | 106 | }; |
121 | 107 | ||
122 | #define UART_NR (ARRAY_SIZE(old_serial_port) + CONFIG_SERIAL_8250_NR_UARTS) | 108 | #define UART_NR CONFIG_SERIAL_8250_NR_UARTS |
123 | 109 | ||
124 | #ifdef CONFIG_SERIAL_8250_RSA | 110 | #ifdef CONFIG_SERIAL_8250_RSA |
125 | 111 | ||
@@ -1007,21 +993,24 @@ static void autoconfig_irq(struct uart_8250_port *up) | |||
1007 | up->port.irq = (irq > 0) ? irq : 0; | 993 | up->port.irq = (irq > 0) ? irq : 0; |
1008 | } | 994 | } |
1009 | 995 | ||
996 | static inline void __stop_tx(struct uart_8250_port *p) | ||
997 | { | ||
998 | if (p->ier & UART_IER_THRI) { | ||
999 | p->ier &= ~UART_IER_THRI; | ||
1000 | serial_out(p, UART_IER, p->ier); | ||
1001 | } | ||
1002 | } | ||
1003 | |||
1010 | static void serial8250_stop_tx(struct uart_port *port, unsigned int tty_stop) | 1004 | static void serial8250_stop_tx(struct uart_port *port, unsigned int tty_stop) |
1011 | { | 1005 | { |
1012 | struct uart_8250_port *up = (struct uart_8250_port *)port; | 1006 | struct uart_8250_port *up = (struct uart_8250_port *)port; |
1013 | 1007 | ||
1014 | if (up->ier & UART_IER_THRI) { | 1008 | __stop_tx(up); |
1015 | up->ier &= ~UART_IER_THRI; | ||
1016 | serial_out(up, UART_IER, up->ier); | ||
1017 | } | ||
1018 | 1009 | ||
1019 | /* | 1010 | /* |
1020 | * We only do this from uart_stop - if we run out of | 1011 | * We really want to stop the transmitter from sending. |
1021 | * characters to send, we don't want to prevent the | ||
1022 | * FIFO from emptying. | ||
1023 | */ | 1012 | */ |
1024 | if (up->port.type == PORT_16C950 && tty_stop) { | 1013 | if (up->port.type == PORT_16C950) { |
1025 | up->acr |= UART_ACR_TXDIS; | 1014 | up->acr |= UART_ACR_TXDIS; |
1026 | serial_icr_write(up, UART_ACR, up->acr); | 1015 | serial_icr_write(up, UART_ACR, up->acr); |
1027 | } | 1016 | } |
@@ -1045,10 +1034,11 @@ static void serial8250_start_tx(struct uart_port *port, unsigned int tty_start) | |||
1045 | transmit_chars(up); | 1034 | transmit_chars(up); |
1046 | } | 1035 | } |
1047 | } | 1036 | } |
1037 | |||
1048 | /* | 1038 | /* |
1049 | * We only do this from uart_start | 1039 | * Re-enable the transmitter if we disabled it. |
1050 | */ | 1040 | */ |
1051 | if (tty_start && up->port.type == PORT_16C950) { | 1041 | if (up->port.type == PORT_16C950 && up->acr & UART_ACR_TXDIS) { |
1052 | up->acr &= ~UART_ACR_TXDIS; | 1042 | up->acr &= ~UART_ACR_TXDIS; |
1053 | serial_icr_write(up, UART_ACR, up->acr); | 1043 | serial_icr_write(up, UART_ACR, up->acr); |
1054 | } | 1044 | } |
@@ -1169,7 +1159,7 @@ static _INLINE_ void transmit_chars(struct uart_8250_port *up) | |||
1169 | return; | 1159 | return; |
1170 | } | 1160 | } |
1171 | if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { | 1161 | if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { |
1172 | serial8250_stop_tx(&up->port, 0); | 1162 | __stop_tx(up); |
1173 | return; | 1163 | return; |
1174 | } | 1164 | } |
1175 | 1165 | ||
@@ -1188,7 +1178,7 @@ static _INLINE_ void transmit_chars(struct uart_8250_port *up) | |||
1188 | DEBUG_INTR("THRE..."); | 1178 | DEBUG_INTR("THRE..."); |
1189 | 1179 | ||
1190 | if (uart_circ_empty(xmit)) | 1180 | if (uart_circ_empty(xmit)) |
1191 | serial8250_stop_tx(&up->port, 0); | 1181 | __stop_tx(up); |
1192 | } | 1182 | } |
1193 | 1183 | ||
1194 | static _INLINE_ void check_modem_status(struct uart_8250_port *up) | 1184 | 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) | |||
1390 | static unsigned int serial8250_get_mctrl(struct uart_port *port) | 1380 | static unsigned int serial8250_get_mctrl(struct uart_port *port) |
1391 | { | 1381 | { |
1392 | struct uart_8250_port *up = (struct uart_8250_port *)port; | 1382 | struct uart_8250_port *up = (struct uart_8250_port *)port; |
1393 | unsigned long flags; | ||
1394 | unsigned char status; | 1383 | unsigned char status; |
1395 | unsigned int ret; | 1384 | unsigned int ret; |
1396 | 1385 | ||
1397 | spin_lock_irqsave(&up->port.lock, flags); | ||
1398 | status = serial_in(up, UART_MSR); | 1386 | status = serial_in(up, UART_MSR); |
1399 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
1400 | 1387 | ||
1401 | ret = 0; | 1388 | ret = 0; |
1402 | if (status & UART_MSR_DCD) | 1389 | if (status & UART_MSR_DCD) |
@@ -2074,7 +2061,8 @@ static void __init serial8250_isa_init_ports(void) | |||
2074 | up->port.ops = &serial8250_pops; | 2061 | up->port.ops = &serial8250_pops; |
2075 | } | 2062 | } |
2076 | 2063 | ||
2077 | for (i = 0, up = serial8250_ports; i < ARRAY_SIZE(old_serial_port); | 2064 | for (i = 0, up = serial8250_ports; |
2065 | i < ARRAY_SIZE(old_serial_port) && i < UART_NR; | ||
2078 | i++, up++) { | 2066 | i++, up++) { |
2079 | up->port.iobase = old_serial_port[i].port; | 2067 | up->port.iobase = old_serial_port[i].port; |
2080 | up->port.irq = irq_canonicalize(old_serial_port[i].irq); | 2068 | up->port.irq = irq_canonicalize(old_serial_port[i].irq); |
@@ -2323,10 +2311,11 @@ static int __devinit serial8250_probe(struct device *dev) | |||
2323 | { | 2311 | { |
2324 | struct plat_serial8250_port *p = dev->platform_data; | 2312 | struct plat_serial8250_port *p = dev->platform_data; |
2325 | struct uart_port port; | 2313 | struct uart_port port; |
2314 | int ret, i; | ||
2326 | 2315 | ||
2327 | memset(&port, 0, sizeof(struct uart_port)); | 2316 | memset(&port, 0, sizeof(struct uart_port)); |
2328 | 2317 | ||
2329 | for (; p && p->flags != 0; p++) { | 2318 | for (i = 0; p && p->flags != 0; p++, i++) { |
2330 | port.iobase = p->iobase; | 2319 | port.iobase = p->iobase; |
2331 | port.membase = p->membase; | 2320 | port.membase = p->membase; |
2332 | port.irq = p->irq; | 2321 | port.irq = p->irq; |
@@ -2335,10 +2324,16 @@ static int __devinit serial8250_probe(struct device *dev) | |||
2335 | port.iotype = p->iotype; | 2324 | port.iotype = p->iotype; |
2336 | port.flags = p->flags; | 2325 | port.flags = p->flags; |
2337 | port.mapbase = p->mapbase; | 2326 | port.mapbase = p->mapbase; |
2327 | port.hub6 = p->hub6; | ||
2338 | port.dev = dev; | 2328 | port.dev = dev; |
2339 | if (share_irqs) | 2329 | if (share_irqs) |
2340 | port.flags |= UPF_SHARE_IRQ; | 2330 | port.flags |= UPF_SHARE_IRQ; |
2341 | serial8250_register_port(&port); | 2331 | ret = serial8250_register_port(&port); |
2332 | if (ret < 0) { | ||
2333 | dev_err(dev, "unable to register port at index %d " | ||
2334 | "(IO%lx MEM%lx IRQ%d): %d\n", i, | ||
2335 | p->iobase, p->mapbase, p->irq, ret); | ||
2336 | } | ||
2342 | } | 2337 | } |
2343 | return 0; | 2338 | return 0; |
2344 | } | 2339 | } |
diff --git a/drivers/serial/8250_accent.c b/drivers/serial/8250_accent.c new file mode 100644 index 000000000000..1f2c276063ef --- /dev/null +++ b/drivers/serial/8250_accent.c | |||
@@ -0,0 +1,47 @@ | |||
1 | /* | ||
2 | * linux/drivers/serial/8250_accent.c | ||
3 | * | ||
4 | * Copyright (C) 2005 Russell King. | ||
5 | * Data taken from include/asm-i386/serial.h | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/serial_8250.h> | ||
14 | |||
15 | #define PORT(_base,_irq) \ | ||
16 | { \ | ||
17 | .iobase = _base, \ | ||
18 | .irq = _irq, \ | ||
19 | .uartclk = 1843200, \ | ||
20 | .iotype = UPIO_PORT, \ | ||
21 | .flags = UPF_BOOT_AUTOCONF, \ | ||
22 | } | ||
23 | |||
24 | static struct plat_serial8250_port accent_data[] = { | ||
25 | PORT(0x330, 4), | ||
26 | PORT(0x338, 4), | ||
27 | { }, | ||
28 | }; | ||
29 | |||
30 | static struct platform_device accent_device = { | ||
31 | .name = "serial8250", | ||
32 | .id = 2, | ||
33 | .dev = { | ||
34 | .platform_data = accent_data, | ||
35 | }, | ||
36 | }; | ||
37 | |||
38 | static int __init accent_init(void) | ||
39 | { | ||
40 | return platform_device_register(&accent_device); | ||
41 | } | ||
42 | |||
43 | module_init(accent_init); | ||
44 | |||
45 | MODULE_AUTHOR("Russell King"); | ||
46 | MODULE_DESCRIPTION("8250 serial probe module for Accent Async cards"); | ||
47 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/serial/8250_boca.c b/drivers/serial/8250_boca.c new file mode 100644 index 000000000000..465c9ea1e7a3 --- /dev/null +++ b/drivers/serial/8250_boca.c | |||
@@ -0,0 +1,61 @@ | |||
1 | /* | ||
2 | * linux/drivers/serial/8250_boca.c | ||
3 | * | ||
4 | * Copyright (C) 2005 Russell King. | ||
5 | * Data taken from include/asm-i386/serial.h | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/serial_8250.h> | ||
14 | |||
15 | #define PORT(_base,_irq) \ | ||
16 | { \ | ||
17 | .iobase = _base, \ | ||
18 | .irq = _irq, \ | ||
19 | .uartclk = 1843200, \ | ||
20 | .iotype = UPIO_PORT, \ | ||
21 | .flags = UPF_BOOT_AUTOCONF, \ | ||
22 | } | ||
23 | |||
24 | static struct plat_serial8250_port boca_data[] = { | ||
25 | PORT(0x100, 12), | ||
26 | PORT(0x108, 12), | ||
27 | PORT(0x110, 12), | ||
28 | PORT(0x118, 12), | ||
29 | PORT(0x120, 12), | ||
30 | PORT(0x128, 12), | ||
31 | PORT(0x130, 12), | ||
32 | PORT(0x138, 12), | ||
33 | PORT(0x140, 12), | ||
34 | PORT(0x148, 12), | ||
35 | PORT(0x150, 12), | ||
36 | PORT(0x158, 12), | ||
37 | PORT(0x160, 12), | ||
38 | PORT(0x168, 12), | ||
39 | PORT(0x170, 12), | ||
40 | PORT(0x178, 12), | ||
41 | { }, | ||
42 | }; | ||
43 | |||
44 | static struct platform_device boca_device = { | ||
45 | .name = "serial8250", | ||
46 | .id = 3, | ||
47 | .dev = { | ||
48 | .platform_data = boca_data, | ||
49 | }, | ||
50 | }; | ||
51 | |||
52 | static int __init boca_init(void) | ||
53 | { | ||
54 | return platform_device_register(&boca_device); | ||
55 | } | ||
56 | |||
57 | module_init(boca_init); | ||
58 | |||
59 | MODULE_AUTHOR("Russell King"); | ||
60 | MODULE_DESCRIPTION("8250 serial probe module for Boca cards"); | ||
61 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/serial/8250_fourport.c b/drivers/serial/8250_fourport.c new file mode 100644 index 000000000000..e9b4d908ef42 --- /dev/null +++ b/drivers/serial/8250_fourport.c | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * linux/drivers/serial/8250_fourport.c | ||
3 | * | ||
4 | * Copyright (C) 2005 Russell King. | ||
5 | * Data taken from include/asm-i386/serial.h | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/serial_8250.h> | ||
14 | |||
15 | #define PORT(_base,_irq) \ | ||
16 | { \ | ||
17 | .iobase = _base, \ | ||
18 | .irq = _irq, \ | ||
19 | .uartclk = 1843200, \ | ||
20 | .iotype = UPIO_PORT, \ | ||
21 | .flags = UPF_BOOT_AUTOCONF | UPF_FOURPORT, \ | ||
22 | } | ||
23 | |||
24 | static struct plat_serial8250_port fourport_data[] = { | ||
25 | PORT(0x1a0, 9), | ||
26 | PORT(0x1a8, 9), | ||
27 | PORT(0x1b0, 9), | ||
28 | PORT(0x1b8, 9), | ||
29 | PORT(0x2a0, 5), | ||
30 | PORT(0x2a8, 5), | ||
31 | PORT(0x2b0, 5), | ||
32 | PORT(0x2b8, 5), | ||
33 | { }, | ||
34 | }; | ||
35 | |||
36 | static struct platform_device fourport_device = { | ||
37 | .name = "serial8250", | ||
38 | .id = 1, | ||
39 | .dev = { | ||
40 | .platform_data = fourport_data, | ||
41 | }, | ||
42 | }; | ||
43 | |||
44 | static int __init fourport_init(void) | ||
45 | { | ||
46 | return platform_device_register(&fourport_device); | ||
47 | } | ||
48 | |||
49 | module_init(fourport_init); | ||
50 | |||
51 | MODULE_AUTHOR("Russell King"); | ||
52 | MODULE_DESCRIPTION("8250 serial probe module for AST Fourport cards"); | ||
53 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/serial/8250_hub6.c b/drivers/serial/8250_hub6.c new file mode 100644 index 000000000000..77f396f84b4c --- /dev/null +++ b/drivers/serial/8250_hub6.c | |||
@@ -0,0 +1,58 @@ | |||
1 | /* | ||
2 | * linux/drivers/serial/8250_hub6.c | ||
3 | * | ||
4 | * Copyright (C) 2005 Russell King. | ||
5 | * Data taken from include/asm-i386/serial.h | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/serial_8250.h> | ||
14 | |||
15 | #define HUB6(card,port) \ | ||
16 | { \ | ||
17 | .iobase = 0x302, \ | ||
18 | .irq = 3, \ | ||
19 | .uartclk = 1843200, \ | ||
20 | .iotype = UPIO_HUB6, \ | ||
21 | .flags = UPF_BOOT_AUTOCONF, \ | ||
22 | .hub6 = (card) << 6 | (port) << 3 | 1, \ | ||
23 | } | ||
24 | |||
25 | static struct plat_serial8250_port hub6_data[] = { | ||
26 | HUB6(0,0), | ||
27 | HUB6(0,1), | ||
28 | HUB6(0,2), | ||
29 | HUB6(0,3), | ||
30 | HUB6(0,4), | ||
31 | HUB6(0,5), | ||
32 | HUB6(1,0), | ||
33 | HUB6(1,1), | ||
34 | HUB6(1,2), | ||
35 | HUB6(1,3), | ||
36 | HUB6(1,4), | ||
37 | HUB6(1,5), | ||
38 | { }, | ||
39 | }; | ||
40 | |||
41 | static struct platform_device hub6_device = { | ||
42 | .name = "serial8250", | ||
43 | .id = 4, | ||
44 | .dev = { | ||
45 | .platform_data = hub6_data, | ||
46 | }, | ||
47 | }; | ||
48 | |||
49 | static int __init hub6_init(void) | ||
50 | { | ||
51 | return platform_device_register(&hub6_device); | ||
52 | } | ||
53 | |||
54 | module_init(hub6_init); | ||
55 | |||
56 | MODULE_AUTHOR("Russell King"); | ||
57 | MODULE_DESCRIPTION("8250 serial probe module for Hub6 cards"); | ||
58 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/serial/8250_mca.c b/drivers/serial/8250_mca.c new file mode 100644 index 000000000000..f0c40d68b8c1 --- /dev/null +++ b/drivers/serial/8250_mca.c | |||
@@ -0,0 +1,64 @@ | |||
1 | /* | ||
2 | * linux/drivers/serial/8250_mca.c | ||
3 | * | ||
4 | * Copyright (C) 2005 Russell King. | ||
5 | * Data taken from include/asm-i386/serial.h | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | #include <linux/config.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/mca.h> | ||
15 | #include <linux/serial_8250.h> | ||
16 | |||
17 | /* | ||
18 | * FIXME: Should we be doing AUTO_IRQ here? | ||
19 | */ | ||
20 | #ifdef CONFIG_SERIAL_8250_DETECT_IRQ | ||
21 | #define MCA_FLAGS UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ | ||
22 | #else | ||
23 | #define MCA_FLAGS UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | ||
24 | #endif | ||
25 | |||
26 | #define PORT(_base,_irq) \ | ||
27 | { \ | ||
28 | .iobase = _base, \ | ||
29 | .irq = _irq, \ | ||
30 | .uartclk = 1843200, \ | ||
31 | .iotype = UPIO_PORT, \ | ||
32 | .flags = MCA_FLAGS, \ | ||
33 | } | ||
34 | |||
35 | static struct plat_serial8250_port mca_data[] = { | ||
36 | PORT(0x3220, 3), | ||
37 | PORT(0x3228, 3), | ||
38 | PORT(0x4220, 3), | ||
39 | PORT(0x4228, 3), | ||
40 | PORT(0x5220, 3), | ||
41 | PORT(0x5228, 3), | ||
42 | { }, | ||
43 | }; | ||
44 | |||
45 | static struct platform_device mca_device = { | ||
46 | .name = "serial8250", | ||
47 | .id = 5, | ||
48 | .dev = { | ||
49 | .platform_data = mca_data, | ||
50 | }, | ||
51 | }; | ||
52 | |||
53 | static int __init mca_init(void) | ||
54 | { | ||
55 | if (!MCA_bus) | ||
56 | return -ENODEV; | ||
57 | return platform_device_register(&mca_device); | ||
58 | } | ||
59 | |||
60 | module_init(mca_init); | ||
61 | |||
62 | MODULE_AUTHOR("Russell King"); | ||
63 | MODULE_DESCRIPTION("8250 serial probe module for MCA ports"); | ||
64 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 25fcef2c42de..e0d0a470ddfc 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig | |||
@@ -86,14 +86,14 @@ config SERIAL_8250_ACPI | |||
86 | namespace, say Y here. If unsure, say N. | 86 | namespace, say Y here. If unsure, say N. |
87 | 87 | ||
88 | config SERIAL_8250_NR_UARTS | 88 | config SERIAL_8250_NR_UARTS |
89 | int "Maximum number of non-legacy 8250/16550 serial ports" | 89 | int "Maximum number of 8250/16550 serial ports" |
90 | depends on SERIAL_8250 | 90 | depends on SERIAL_8250 |
91 | default "4" | 91 | default "4" |
92 | ---help--- | 92 | help |
93 | Set this to the number of non-legacy serial ports you want | 93 | Set this to the number of serial ports you want the driver |
94 | the driver to support. This includes any ports discovered | 94 | to support. This includes any ports discovered via ACPI or |
95 | via ACPI or PCI enumeration and any ports that may be added | 95 | PCI enumeration and any ports that may be added at run-time |
96 | at run-time via hot-plug. | 96 | via hot-plug, or any ISA multi-port serial cards. |
97 | 97 | ||
98 | config SERIAL_8250_EXTENDED | 98 | config SERIAL_8250_EXTENDED |
99 | bool "Extended 8250/16550 serial driver options" | 99 | bool "Extended 8250/16550 serial driver options" |
@@ -141,31 +141,74 @@ config SERIAL_8250_DETECT_IRQ | |||
141 | 141 | ||
142 | If unsure, say N. | 142 | If unsure, say N. |
143 | 143 | ||
144 | config SERIAL_8250_MULTIPORT | ||
145 | bool "Support special multiport boards" | ||
146 | depends on SERIAL_8250_EXTENDED | ||
147 | help | ||
148 | Some multiport serial ports have special ports which are used to | ||
149 | signal when there are any serial ports on the board which need | ||
150 | servicing. Say Y here to enable the serial driver to take advantage | ||
151 | of those special I/O ports. | ||
152 | |||
153 | config SERIAL_8250_RSA | 144 | config SERIAL_8250_RSA |
154 | bool "Support RSA serial ports" | 145 | bool "Support RSA serial ports" |
155 | depends on SERIAL_8250_EXTENDED | 146 | depends on SERIAL_8250_EXTENDED |
156 | help | 147 | help |
157 | ::: To be written ::: | 148 | ::: To be written ::: |
158 | 149 | ||
159 | comment "Non-8250 serial port support" | 150 | # |
151 | # Multi-port serial cards | ||
152 | # | ||
153 | |||
154 | config SERIAL_8250_FOURPORT | ||
155 | tristate "Support Fourport cards" | ||
156 | depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS | ||
157 | help | ||
158 | Say Y here if you have an AST FourPort serial board. | ||
159 | |||
160 | To compile this driver as a module, choose M here: the module | ||
161 | will be called 8250_fourport. | ||
162 | |||
163 | config SERIAL_8250_ACCENT | ||
164 | tristate "Support Accent cards" | ||
165 | depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS | ||
166 | help | ||
167 | Say Y here if you have an Accent Async serial board. | ||
168 | |||
169 | To compile this driver as a module, choose M here: the module | ||
170 | will be called 8250_accent. | ||
171 | |||
172 | |||
173 | config SERIAL_8250_BOCA | ||
174 | tristate "Support Boca cards" | ||
175 | depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS | ||
176 | help | ||
177 | Say Y here if you have a Boca serial board. Please read the Boca | ||
178 | mini-HOWTO, avaialble from <http://www.tldp.org/docs.html#howto> | ||
179 | |||
180 | To compile this driver as a module, choose M here: the module | ||
181 | will be called 8250_boca. | ||
182 | |||
183 | |||
184 | config SERIAL_8250_HUB6 | ||
185 | tristate "Support Hub6 cards" | ||
186 | depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS | ||
187 | help | ||
188 | Say Y here if you have a HUB6 serial board. | ||
189 | |||
190 | To compile this driver as a module, choose M here: the module | ||
191 | will be called 8250_hub6. | ||
192 | |||
193 | config SERIAL_8250_MCA | ||
194 | tristate "Support 8250-type ports on MCA buses" | ||
195 | depends on SERIAL_8250 != n && MCA | ||
196 | help | ||
197 | Say Y here if you have a MCA serial ports. | ||
198 | |||
199 | To compile this driver as a module, choose M here: the module | ||
200 | will be called 8250_mca. | ||
160 | 201 | ||
161 | config SERIAL_8250_ACORN | 202 | config SERIAL_8250_ACORN |
162 | tristate "Acorn expansion card serial port support" | 203 | tristate "Acorn expansion card serial port support" |
163 | depends on ARM && ARCH_ACORN && SERIAL_8250 | 204 | depends on ARCH_ACORN && SERIAL_8250 |
164 | help | 205 | help |
165 | If you have an Atomwide Serial card or Serial Port card for an Acorn | 206 | If you have an Atomwide Serial card or Serial Port card for an Acorn |
166 | system, say Y to this option. The driver can handle 1, 2, or 3 port | 207 | system, say Y to this option. The driver can handle 1, 2, or 3 port |
167 | cards. If unsure, say N. | 208 | cards. If unsure, say N. |
168 | 209 | ||
210 | comment "Non-8250 serial port support" | ||
211 | |||
169 | config SERIAL_AMBA_PL010 | 212 | config SERIAL_AMBA_PL010 |
170 | tristate "ARM AMBA PL010 serial port support" | 213 | tristate "ARM AMBA PL010 serial port support" |
171 | depends on ARM_AMBA | 214 | depends on ARM_AMBA |
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 8f1cdde7dbed..65bd4381685e 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile | |||
@@ -17,6 +17,11 @@ obj-$(CONFIG_SERIAL_8250) += 8250.o $(serial-8250-y) | |||
17 | obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o | 17 | obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o |
18 | obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o | 18 | obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o |
19 | obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o | 19 | obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o |
20 | obj-$(CONFIG_SERIAL_8250_FOURPORT) += 8250_fourport.o | ||
21 | obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o | ||
22 | obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o | ||
23 | obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o | ||
24 | obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o | ||
20 | obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o | 25 | obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o |
21 | obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o | 26 | obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o |
22 | obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o | 27 | obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o |
diff --git a/drivers/serial/au1x00_uart.c b/drivers/serial/au1x00_uart.c index 5400dc2c087e..6104aeef1243 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) | |||
556 | static unsigned int serial8250_get_mctrl(struct uart_port *port) | 556 | static unsigned int serial8250_get_mctrl(struct uart_port *port) |
557 | { | 557 | { |
558 | struct uart_8250_port *up = (struct uart_8250_port *)port; | 558 | struct uart_8250_port *up = (struct uart_8250_port *)port; |
559 | unsigned long flags; | ||
560 | unsigned char status; | 559 | unsigned char status; |
561 | unsigned int ret; | 560 | unsigned int ret; |
562 | 561 | ||
563 | spin_lock_irqsave(&up->port.lock, flags); | ||
564 | status = serial_in(up, UART_MSR); | 562 | status = serial_in(up, UART_MSR); |
565 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
566 | 563 | ||
567 | ret = 0; | 564 | ret = 0; |
568 | if (status & UART_MSR_DCD) | 565 | if (status & UART_MSR_DCD) |
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c index de26cf7b003c..7911912f50c7 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) | |||
94 | ((immap_t *)IMAP_ADDR)->im_ioport.iop_paodr &= ~iobits; | 94 | ((immap_t *)IMAP_ADDR)->im_ioport.iop_paodr &= ~iobits; |
95 | } | 95 | } |
96 | 96 | ||
97 | #ifdef CONFIG_MPC885ADS | ||
98 | /* Enable SMC1 transceivers */ | ||
99 | { | ||
100 | volatile uint __iomem *bcsr1 = ioremap(BCSR1, 4); | ||
101 | uint tmp; | ||
102 | |||
103 | tmp = in_be32(bcsr1); | ||
104 | tmp &= ~BCSR1_RS232EN_1; | ||
105 | out_be32(bcsr1, tmp); | ||
106 | iounmap(bcsr1); | ||
107 | } | ||
108 | #endif | ||
109 | |||
97 | pinfo->brg = 1; | 110 | pinfo->brg = 1; |
98 | } | 111 | } |
99 | 112 | ||
100 | void smc2_lineif(struct uart_cpm_port *pinfo) | 113 | void smc2_lineif(struct uart_cpm_port *pinfo) |
101 | { | 114 | { |
102 | /* XXX SMC2: insert port configuration here */ | 115 | #ifdef CONFIG_MPC885ADS |
116 | volatile cpm8xx_t *cp = cpmp; | ||
117 | volatile uint __iomem *bcsr1; | ||
118 | uint tmp; | ||
119 | |||
120 | cp->cp_pepar |= 0x00000c00; | ||
121 | cp->cp_pedir &= ~0x00000c00; | ||
122 | cp->cp_peso &= ~0x00000400; | ||
123 | cp->cp_peso |= 0x00000800; | ||
124 | |||
125 | /* Enable SMC2 transceivers */ | ||
126 | bcsr1 = ioremap(BCSR1, 4); | ||
127 | tmp = in_be32(bcsr1); | ||
128 | tmp &= ~BCSR1_RS232EN_2; | ||
129 | out_be32(bcsr1, tmp); | ||
130 | iounmap(bcsr1); | ||
131 | #endif | ||
132 | |||
103 | pinfo->brg = 2; | 133 | pinfo->brg = 2; |
104 | } | 134 | } |
105 | 135 | ||
diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c index 3ea46c069f6f..ea5bf4d4daa3 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 | |||
518 | static __inline__ unsigned char ip22zilog_read_channel_status(struct uart_port *port) | 518 | static __inline__ unsigned char ip22zilog_read_channel_status(struct uart_port *port) |
519 | { | 519 | { |
520 | struct zilog_channel *channel; | 520 | struct zilog_channel *channel; |
521 | unsigned long flags; | ||
522 | unsigned char status; | 521 | unsigned char status; |
523 | 522 | ||
524 | spin_lock_irqsave(&port->lock, flags); | ||
525 | |||
526 | channel = ZILOG_CHANNEL_FROM_PORT(port); | 523 | channel = ZILOG_CHANNEL_FROM_PORT(port); |
527 | status = readb(&channel->control); | 524 | status = readb(&channel->control); |
528 | ZSDELAY(); | 525 | ZSDELAY(); |
529 | 526 | ||
530 | spin_unlock_irqrestore(&port->lock, flags); | ||
531 | |||
532 | return status; | 527 | return status; |
533 | } | 528 | } |
534 | 529 | ||
535 | /* The port lock is not held. */ | 530 | /* The port lock is not held. */ |
536 | static unsigned int ip22zilog_tx_empty(struct uart_port *port) | 531 | static unsigned int ip22zilog_tx_empty(struct uart_port *port) |
537 | { | 532 | { |
533 | unsigned long flags; | ||
538 | unsigned char status; | 534 | unsigned char status; |
539 | unsigned int ret; | 535 | unsigned int ret; |
540 | 536 | ||
537 | spin_lock_irqsave(&port->lock, flags); | ||
538 | |||
541 | status = ip22zilog_read_channel_status(port); | 539 | status = ip22zilog_read_channel_status(port); |
540 | |||
541 | spin_unlock_irqrestore(&port->lock, flags); | ||
542 | |||
542 | if (status & Tx_BUF_EMP) | 543 | if (status & Tx_BUF_EMP) |
543 | ret = TIOCSER_TEMT; | 544 | ret = TIOCSER_TEMT; |
544 | else | 545 | else |
@@ -547,7 +548,7 @@ static unsigned int ip22zilog_tx_empty(struct uart_port *port) | |||
547 | return ret; | 548 | return ret; |
548 | } | 549 | } |
549 | 550 | ||
550 | /* The port lock is not held. */ | 551 | /* The port lock is held and interrupts are disabled. */ |
551 | static unsigned int ip22zilog_get_mctrl(struct uart_port *port) | 552 | static unsigned int ip22zilog_get_mctrl(struct uart_port *port) |
552 | { | 553 | { |
553 | unsigned char status; | 554 | unsigned char status; |
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c index a2a643318002..e43276c6a954 100644 --- a/drivers/serial/mpsc.c +++ b/drivers/serial/mpsc.c | |||
@@ -1058,12 +1058,9 @@ mpsc_get_mctrl(struct uart_port *port) | |||
1058 | { | 1058 | { |
1059 | struct mpsc_port_info *pi = (struct mpsc_port_info *)port; | 1059 | struct mpsc_port_info *pi = (struct mpsc_port_info *)port; |
1060 | u32 mflags, status; | 1060 | u32 mflags, status; |
1061 | ulong iflags; | ||
1062 | 1061 | ||
1063 | spin_lock_irqsave(&pi->port.lock, iflags); | ||
1064 | status = (pi->mirror_regs) ? pi->MPSC_CHR_10_m : | 1062 | status = (pi->mirror_regs) ? pi->MPSC_CHR_10_m : |
1065 | readl(pi->mpsc_base + MPSC_CHR_10); | 1063 | readl(pi->mpsc_base + MPSC_CHR_10); |
1066 | spin_unlock_irqrestore(&pi->port.lock, iflags); | ||
1067 | 1064 | ||
1068 | mflags = 0; | 1065 | mflags = 0; |
1069 | if (status & 0x1) | 1066 | if (status & 0x1) |
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index 85abd8a045e0..1c9f71617123 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) | |||
604 | /* | 604 | /* |
605 | * Get Modem Control bits (only the input ones, the core will | 605 | * Get Modem Control bits (only the input ones, the core will |
606 | * or that with a cached value of the control ones) | 606 | * or that with a cached value of the control ones) |
607 | * The port lock is not held. | 607 | * The port lock is held and interrupts are disabled. |
608 | */ | 608 | */ |
609 | static unsigned int pmz_get_mctrl(struct uart_port *port) | 609 | static unsigned int pmz_get_mctrl(struct uart_port *port) |
610 | { | 610 | { |
@@ -615,7 +615,7 @@ static unsigned int pmz_get_mctrl(struct uart_port *port) | |||
615 | if (ZS_IS_ASLEEP(uap) || uap->node == NULL) | 615 | if (ZS_IS_ASLEEP(uap) || uap->node == NULL) |
616 | return 0; | 616 | return 0; |
617 | 617 | ||
618 | status = pmz_peek_status(to_pmz(port)); | 618 | status = read_zsreg(uap, R0); |
619 | 619 | ||
620 | ret = 0; | 620 | ret = 0; |
621 | if (status & DCD) | 621 | if (status & DCD) |
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c index 08b08d6ae904..461c81c93207 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) | |||
274 | static unsigned int serial_pxa_get_mctrl(struct uart_port *port) | 274 | static unsigned int serial_pxa_get_mctrl(struct uart_port *port) |
275 | { | 275 | { |
276 | struct uart_pxa_port *up = (struct uart_pxa_port *)port; | 276 | struct uart_pxa_port *up = (struct uart_pxa_port *)port; |
277 | unsigned long flags; | ||
278 | unsigned char status; | 277 | unsigned char status; |
279 | unsigned int ret; | 278 | unsigned int ret; |
280 | 279 | ||
281 | return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; | 280 | return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; |
282 | spin_lock_irqsave(&up->port.lock, flags); | ||
283 | status = serial_in(up, UART_MSR); | 281 | status = serial_in(up, UART_MSR); |
284 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
285 | 282 | ||
286 | ret = 0; | 283 | ret = 0; |
287 | if (status & UART_MSR_DCD) | 284 | if (status & UART_MSR_DCD) |
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c index 5c4678478b1d..7365d4b50b95 100644 --- a/drivers/serial/s3c2410.c +++ b/drivers/serial/s3c2410.c | |||
@@ -522,14 +522,11 @@ static void s3c24xx_serial_shutdown(struct uart_port *port) | |||
522 | static int s3c24xx_serial_startup(struct uart_port *port) | 522 | static int s3c24xx_serial_startup(struct uart_port *port) |
523 | { | 523 | { |
524 | struct s3c24xx_uart_port *ourport = to_ourport(port); | 524 | struct s3c24xx_uart_port *ourport = to_ourport(port); |
525 | unsigned long flags; | ||
526 | int ret; | 525 | int ret; |
527 | 526 | ||
528 | dbg("s3c24xx_serial_startup: port=%p (%08lx,%p)\n", | 527 | dbg("s3c24xx_serial_startup: port=%p (%08lx,%p)\n", |
529 | port->mapbase, port->membase); | 528 | port->mapbase, port->membase); |
530 | 529 | ||
531 | local_irq_save(flags); | ||
532 | |||
533 | rx_enabled(port) = 1; | 530 | rx_enabled(port) = 1; |
534 | 531 | ||
535 | ret = request_irq(RX_IRQ(port), | 532 | ret = request_irq(RX_IRQ(port), |
@@ -563,12 +560,10 @@ static int s3c24xx_serial_startup(struct uart_port *port) | |||
563 | /* the port reset code should have done the correct | 560 | /* the port reset code should have done the correct |
564 | * register setup for the port controls */ | 561 | * register setup for the port controls */ |
565 | 562 | ||
566 | local_irq_restore(flags); | ||
567 | return ret; | 563 | return ret; |
568 | 564 | ||
569 | err: | 565 | err: |
570 | s3c24xx_serial_shutdown(port); | 566 | s3c24xx_serial_shutdown(port); |
571 | local_irq_restore(flags); | ||
572 | return ret; | 567 | return ret; |
573 | } | 568 | } |
574 | 569 | ||
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 36b1ae083fb7..54699c3a00ab 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) | |||
182 | uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR); | 182 | uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR); |
183 | } | 183 | } |
184 | 184 | ||
185 | if (info->flags & UIF_CTS_FLOW) { | ||
186 | spin_lock_irq(&port->lock); | ||
187 | if (!(port->ops->get_mctrl(port) & TIOCM_CTS)) | ||
188 | info->tty->hw_stopped = 1; | ||
189 | spin_unlock_irq(&port->lock); | ||
190 | } | ||
191 | |||
185 | info->flags |= UIF_INITIALIZED; | 192 | info->flags |= UIF_INITIALIZED; |
186 | 193 | ||
187 | clear_bit(TTY_IO_ERROR, &info->tty->flags); | 194 | clear_bit(TTY_IO_ERROR, &info->tty->flags); |
@@ -828,7 +835,10 @@ static int uart_tiocmget(struct tty_struct *tty, struct file *file) | |||
828 | if ((!file || !tty_hung_up_p(file)) && | 835 | if ((!file || !tty_hung_up_p(file)) && |
829 | !(tty->flags & (1 << TTY_IO_ERROR))) { | 836 | !(tty->flags & (1 << TTY_IO_ERROR))) { |
830 | result = port->mctrl; | 837 | result = port->mctrl; |
838 | |||
839 | spin_lock_irq(&port->lock); | ||
831 | result |= port->ops->get_mctrl(port); | 840 | result |= port->ops->get_mctrl(port); |
841 | spin_unlock_irq(&port->lock); | ||
832 | } | 842 | } |
833 | up(&state->sem); | 843 | up(&state->sem); |
834 | 844 | ||
@@ -1131,6 +1141,16 @@ static void uart_set_termios(struct tty_struct *tty, struct termios *old_termios | |||
1131 | spin_unlock_irqrestore(&state->port->lock, flags); | 1141 | spin_unlock_irqrestore(&state->port->lock, flags); |
1132 | } | 1142 | } |
1133 | 1143 | ||
1144 | /* Handle turning on CRTSCTS */ | ||
1145 | if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) { | ||
1146 | spin_lock_irqsave(&state->port->lock, flags); | ||
1147 | if (!(state->port->ops->get_mctrl(state->port) & TIOCM_CTS)) { | ||
1148 | tty->hw_stopped = 1; | ||
1149 | state->port->ops->stop_tx(state->port, 0); | ||
1150 | } | ||
1151 | spin_unlock_irqrestore(&state->port->lock, flags); | ||
1152 | } | ||
1153 | |||
1134 | #if 0 | 1154 | #if 0 |
1135 | /* | 1155 | /* |
1136 | * No need to wake up processes in open wait, since they | 1156 | * 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) | |||
1369 | DECLARE_WAITQUEUE(wait, current); | 1389 | DECLARE_WAITQUEUE(wait, current); |
1370 | struct uart_info *info = state->info; | 1390 | struct uart_info *info = state->info; |
1371 | struct uart_port *port = state->port; | 1391 | struct uart_port *port = state->port; |
1392 | unsigned int mctrl; | ||
1372 | 1393 | ||
1373 | info->blocked_open++; | 1394 | info->blocked_open++; |
1374 | state->count--; | 1395 | state->count--; |
@@ -1416,7 +1437,10 @@ uart_block_til_ready(struct file *filp, struct uart_state *state) | |||
1416 | * and wait for the carrier to indicate that the | 1437 | * and wait for the carrier to indicate that the |
1417 | * modem is ready for us. | 1438 | * modem is ready for us. |
1418 | */ | 1439 | */ |
1419 | if (port->ops->get_mctrl(port) & TIOCM_CAR) | 1440 | spin_lock_irq(&port->lock); |
1441 | mctrl = port->ops->get_mctrl(port); | ||
1442 | spin_unlock_irq(&port->lock); | ||
1443 | if (mctrl & TIOCM_CAR) | ||
1420 | break; | 1444 | break; |
1421 | 1445 | ||
1422 | up(&state->sem); | 1446 | up(&state->sem); |
@@ -1618,7 +1642,9 @@ static int uart_line_info(char *buf, struct uart_driver *drv, int i) | |||
1618 | 1642 | ||
1619 | if(capable(CAP_SYS_ADMIN)) | 1643 | if(capable(CAP_SYS_ADMIN)) |
1620 | { | 1644 | { |
1645 | spin_lock_irq(&port->lock); | ||
1621 | status = port->ops->get_mctrl(port); | 1646 | status = port->ops->get_mctrl(port); |
1647 | spin_unlock_irq(&port->lock); | ||
1622 | 1648 | ||
1623 | ret += sprintf(buf + ret, " tx:%d rx:%d", | 1649 | ret += sprintf(buf + ret, " tx:%d rx:%d", |
1624 | port->icount.tx, port->icount.rx); | 1650 | port->icount.tx, port->icount.rx); |
@@ -1782,6 +1808,12 @@ uart_set_options(struct uart_port *port, struct console *co, | |||
1782 | struct termios termios; | 1808 | struct termios termios; |
1783 | int i; | 1809 | int i; |
1784 | 1810 | ||
1811 | /* | ||
1812 | * Ensure that the serial console lock is initialised | ||
1813 | * early. | ||
1814 | */ | ||
1815 | spin_lock_init(&port->lock); | ||
1816 | |||
1785 | memset(&termios, 0, sizeof(struct termios)); | 1817 | memset(&termios, 0, sizeof(struct termios)); |
1786 | 1818 | ||
1787 | termios.c_cflag = CREAD | HUPCL | CLOCAL; | 1819 | termios.c_cflag = CREAD | HUPCL | CLOCAL; |
@@ -2170,10 +2202,16 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port) | |||
2170 | 2202 | ||
2171 | state->port = port; | 2203 | state->port = port; |
2172 | 2204 | ||
2173 | spin_lock_init(&port->lock); | ||
2174 | port->cons = drv->cons; | 2205 | port->cons = drv->cons; |
2175 | port->info = state->info; | 2206 | port->info = state->info; |
2176 | 2207 | ||
2208 | /* | ||
2209 | * If this port is a console, then the spinlock is already | ||
2210 | * initialised. | ||
2211 | */ | ||
2212 | if (!uart_console(port)) | ||
2213 | spin_lock_init(&port->lock); | ||
2214 | |||
2177 | uart_configure_port(drv, state, port); | 2215 | uart_configure_port(drv, state, port); |
2178 | 2216 | ||
2179 | /* | 2217 | /* |
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index 0d7b65f93e8d..73a34b18866f 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c | |||
@@ -772,6 +772,111 @@ serial_event(event_t event, int priority, event_callback_args_t * args) | |||
772 | return 0; | 772 | return 0; |
773 | } | 773 | } |
774 | 774 | ||
775 | static struct pcmcia_device_id serial_ids[] = { | ||
776 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0057, 0x0021), | ||
777 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0089, 0x110a), | ||
778 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0104, 0x000a), | ||
779 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0xea15), | ||
780 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0109, 0x0501), | ||
781 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0138, 0x110a), | ||
782 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0140, 0x000a), | ||
783 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0143, 0x3341), | ||
784 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0143, 0xc0ab), | ||
785 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x016c, 0x0081), | ||
786 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x021b, 0x0101), | ||
787 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x08a1, 0xc0ab), | ||
788 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0d0a), | ||
789 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0e0a), | ||
790 | PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3288", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x04cd2988, 0x46a52d63), | ||
791 | PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3336", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x0143b773, 0x46a52d63), | ||
792 | PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "EM1144T", "PCMCIA MODEM", 0xf510db04, 0x856d66c8, 0xbd6c43ef), | ||
793 | PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "XJEM1144/CCEM1144", "PCMCIA MODEM", 0xf510db04, 0x52d21e1e, 0xbd6c43ef), | ||
794 | PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM28", 0x2e3ee845, 0x0ea978ea), | ||
795 | PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM33", 0x2e3ee845, 0x80609023), | ||
796 | PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM56", 0x2e3ee845, 0xa650c32a), | ||
797 | PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "REM10", 0x2e3ee845, 0x76df1d29), | ||
798 | PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "XEM5600", 0x2e3ee845, 0xf1403719), | ||
799 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "AnyCom", "Fast Ethernet ", 0x578ba6e7, 0x02d92d1e), | ||
800 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff), | ||
801 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Gateway 2000", "XJEM3336", 0xdd9989be, 0x662c394c), | ||
802 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae), | ||
803 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033), | ||
804 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58), | ||
805 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "MEGAHERTZ", "XJEM1144/CCEM1144", 0xf510db04, 0x52d21e1e), | ||
806 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard", 0x0c2f80cd, 0x0573c29f), | ||
807 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard", 0x0c2f80cd, 0x0573c29f), | ||
808 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc), | ||
809 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f), | ||
810 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed), | ||
811 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet", 0x2e3ee845, 0xc0e778c2), | ||
812 | PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0104, 0x0070), | ||
813 | PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0101, 0x0562), | ||
814 | PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0104, 0x0070), | ||
815 | PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x016c, 0x0020), | ||
816 | PCMCIA_MFC_DEVICE_PROD_ID123(1, "APEX DATA", "MULTICARD", "ETHERNET-MODEM", 0x11c2da09, 0x7289dc5d, 0xaad95e1f), | ||
817 | PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "Home and Away 28.8 PC Card ", 0xb569a6e5, 0x5bd4ff2c), | ||
818 | PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "Home and Away Credit Card Adapter", 0xb569a6e5, 0x4bdf15c3), | ||
819 | PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "w95 Home and Away Credit Card ", 0xb569a6e5, 0xae911c15), | ||
820 | PCMCIA_MFC_DEVICE_PROD_ID1(1, "Motorola MARQUIS", 0xf03e4e77), | ||
821 | PCMCIA_MFC_DEVICE_PROD_ID2(1, "FAX/Modem/Ethernet Combo Card ", 0x1ed59302), | ||
822 | PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0301), | ||
823 | PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0039), | ||
824 | PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0006), | ||
825 | PCMCIA_DEVICE_MANF_CARD(0x0105, 0x410a), | ||
826 | PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d50), | ||
827 | PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d51), | ||
828 | PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d52), | ||
829 | PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d53), | ||
830 | PCMCIA_DEVICE_MANF_CARD(0x010b, 0xd180), | ||
831 | PCMCIA_DEVICE_MANF_CARD(0x0137, 0x000e), | ||
832 | PCMCIA_DEVICE_MANF_CARD(0x0137, 0x001b), | ||
833 | PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0025), | ||
834 | PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0045), | ||
835 | PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0052), | ||
836 | PCMCIA_DEVICE_PROD_ID134("ADV", "TECH", "COMpad-32/85", 0x67459937, 0x916d02ba, 0x8fbe92ae), | ||
837 | PCMCIA_DEVICE_PROD_ID124("GATEWAY2000", "CC3144", "PCMCIA MODEM", 0x506bccae, 0xcb3685f1, 0xbd6c43ef), | ||
838 | PCMCIA_DEVICE_PROD_ID14("MEGAHERTZ", "PCMCIA MODEM", 0xf510db04, 0xbd6c43ef), | ||
839 | PCMCIA_DEVICE_PROD_ID124("TOSHIBA", "T144PF", "PCMCIA MODEM", 0xb4585a1a, 0x7271409c, 0xbd6c43ef), | ||
840 | PCMCIA_DEVICE_PROD_ID123("FUJITSU", "FC14F ", "MBH10213", 0x6ee5a3d8, 0x30ead12b, 0xb00f05a0), | ||
841 | PCMCIA_DEVICE_PROD_ID13("MEGAHERTZ", "V.34 PCMCIA MODEM", 0xf510db04, 0xbb2cce4a), | ||
842 | PCMCIA_DEVICE_PROD_ID12("Brain Boxes", "Bluetooth PC Card", 0xee138382, 0xd4ce9b02), | ||
843 | PCMCIA_DEVICE_PROD_ID12("CIRRUS LOGIC", "FAX MODEM", 0xe625f451, 0xcecd6dfa), | ||
844 | PCMCIA_DEVICE_PROD_ID12("COMPAQ", "PCMCIA 28800 FAX/DATA MODEM", 0xa3a3062c, 0x8cbd7c76), | ||
845 | PCMCIA_DEVICE_PROD_ID12("COMPAQ", "PCMCIA 33600 FAX/DATA MODEM", 0xa3a3062c, 0x5a00ce95), | ||
846 | PCMCIA_DEVICE_PROD_ID12("Computerboards, Inc.", "PCM-COM422", 0xd0b78f51, 0x7e2d49ed), | ||
847 | PCMCIA_DEVICE_PROD_ID12("Dr. Neuhaus", "FURY CARD 14K4", 0x76942813, 0x8b96ce65), | ||
848 | PCMCIA_DEVICE_PROD_ID12("Intelligent", "ANGIA FAX/MODEM", 0xb496e65e, 0xf31602a6), | ||
849 | PCMCIA_DEVICE_PROD_ID12("Intel", "MODEM 2400", 0x816cc815, 0x23539b80), | ||
850 | PCMCIA_DEVICE_PROD_ID12("IOTech Inc ", "PCMCIA Dual RS-232 Serial Port Card", 0x3bd2d898, 0x92abc92f), | ||
851 | PCMCIA_DEVICE_PROD_ID12("MACRONIX", "FAX/MODEM", 0x668388b3, 0x3f9bdf2f), | ||
852 | PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT1432LT", 0x5f73be51, 0x0b3e2383), | ||
853 | PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT2834LT", 0x5f73be51, 0x4cd7c09e), | ||
854 | PCMCIA_DEVICE_PROD_ID12("OEM ", "C288MX ", 0xb572d360, 0xd2385b7a), | ||
855 | PCMCIA_DEVICE_PROD_ID12("PCMCIA ", "C336MX ", 0x99bcafe9, 0xaa25bcab), | ||
856 | PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "PCMCIA Dual RS-232 Serial Port Card", 0xc4420b35, 0x92abc92f), | ||
857 | PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "PCMLM28.cis"), | ||
858 | PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "PCMLM28.cis"), | ||
859 | PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "PCMLM28.cis"), | ||
860 | PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "PCMLM28.cis"), | ||
861 | PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "PCMLM28.cis"), | ||
862 | PCMCIA_MFC_DEVICE_CIS_PROD_ID12(1, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "DP83903.cis"), | ||
863 | PCMCIA_MFC_DEVICE_CIS_PROD_ID4(1, "NSC MF LAN/Modem", 0x58fc6056, "DP83903.cis"), | ||
864 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0556, "3CCFEM556.cis"), | ||
865 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "DP83903.cis"), | ||
866 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "3CXEM556.cis"), | ||
867 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "3CXEM556.cis"), | ||
868 | PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "MT5634ZLX.cis"), | ||
869 | PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "COMpad4.cis"), | ||
870 | PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "COMpad2.cis"), | ||
871 | PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "RS-COM-2P.cis"), | ||
872 | /* too generic */ | ||
873 | /* PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0160, 0x0002), */ | ||
874 | /* PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0160, 0x0002), */ | ||
875 | PCMCIA_DEVICE_FUNC_ID(2), | ||
876 | PCMCIA_DEVICE_NULL, | ||
877 | }; | ||
878 | MODULE_DEVICE_TABLE(pcmcia, serial_ids); | ||
879 | |||
775 | static struct pcmcia_driver serial_cs_driver = { | 880 | static struct pcmcia_driver serial_cs_driver = { |
776 | .owner = THIS_MODULE, | 881 | .owner = THIS_MODULE, |
777 | .drv = { | 882 | .drv = { |
@@ -779,6 +884,7 @@ static struct pcmcia_driver serial_cs_driver = { | |||
779 | }, | 884 | }, |
780 | .attach = serial_attach, | 885 | .attach = serial_attach, |
781 | .detach = serial_detach, | 886 | .detach = serial_detach, |
887 | .id_table = serial_ids, | ||
782 | }; | 888 | }; |
783 | 889 | ||
784 | static int __init init_serial_cs(void) | 890 | static int __init init_serial_cs(void) |
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c index 3f1051a4a13f..d085030df70b 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) | |||
442 | static unsigned int serial_txx9_get_mctrl(struct uart_port *port) | 442 | static unsigned int serial_txx9_get_mctrl(struct uart_port *port) |
443 | { | 443 | { |
444 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 444 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; |
445 | unsigned long flags; | ||
446 | unsigned int ret; | 445 | unsigned int ret; |
447 | 446 | ||
448 | spin_lock_irqsave(&up->port.lock, flags); | ||
449 | ret = ((sio_in(up, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS) | 447 | ret = ((sio_in(up, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS) |
450 | | ((sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS); | 448 | | ((sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS); |
451 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
452 | 449 | ||
453 | return ret; | 450 | return ret; |
454 | } | 451 | } |
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index 10e2990a40d4..8d198880756a 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) | |||
426 | sunsab_tx_idle(up); | 426 | sunsab_tx_idle(up); |
427 | } | 427 | } |
428 | 428 | ||
429 | /* port->lock is not held. */ | 429 | /* port->lock is held by caller and interrupts are disabled. */ |
430 | static unsigned int sunsab_get_mctrl(struct uart_port *port) | 430 | static unsigned int sunsab_get_mctrl(struct uart_port *port) |
431 | { | 431 | { |
432 | struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; | 432 | struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; |
433 | unsigned long flags; | ||
434 | unsigned char val; | 433 | unsigned char val; |
435 | unsigned int result; | 434 | unsigned int result; |
436 | 435 | ||
437 | result = 0; | 436 | result = 0; |
438 | 437 | ||
439 | spin_lock_irqsave(&up->port.lock, flags); | ||
440 | |||
441 | val = readb(&up->regs->r.pvr); | 438 | val = readb(&up->regs->r.pvr); |
442 | result |= (val & up->pvr_dsr_bit) ? 0 : TIOCM_DSR; | 439 | result |= (val & up->pvr_dsr_bit) ? 0 : TIOCM_DSR; |
443 | 440 | ||
@@ -447,8 +444,6 @@ static unsigned int sunsab_get_mctrl(struct uart_port *port) | |||
447 | val = readb(&up->regs->r.star); | 444 | val = readb(&up->regs->r.star); |
448 | result |= (val & SAB82532_STAR_CTS) ? TIOCM_CTS : 0; | 445 | result |= (val & SAB82532_STAR_CTS) ? TIOCM_CTS : 0; |
449 | 446 | ||
450 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
451 | |||
452 | return result; | 447 | return result; |
453 | } | 448 | } |
454 | 449 | ||
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index ddc97c905e14..d57a3553aea3 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) | |||
572 | static unsigned int sunsu_get_mctrl(struct uart_port *port) | 572 | static unsigned int sunsu_get_mctrl(struct uart_port *port) |
573 | { | 573 | { |
574 | struct uart_sunsu_port *up = (struct uart_sunsu_port *) port; | 574 | struct uart_sunsu_port *up = (struct uart_sunsu_port *) port; |
575 | unsigned long flags; | ||
576 | unsigned char status; | 575 | unsigned char status; |
577 | unsigned int ret; | 576 | unsigned int ret; |
578 | 577 | ||
579 | spin_lock_irqsave(&up->port.lock, flags); | ||
580 | status = serial_in(up, UART_MSR); | 578 | status = serial_in(up, UART_MSR); |
581 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
582 | 579 | ||
583 | ret = 0; | 580 | ret = 0; |
584 | if (status & UART_MSR_DCD) | 581 | if (status & UART_MSR_DCD) |
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index 8e65206d3d76..bff42a7b89d0 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 | |||
610 | static __inline__ unsigned char sunzilog_read_channel_status(struct uart_port *port) | 610 | static __inline__ unsigned char sunzilog_read_channel_status(struct uart_port *port) |
611 | { | 611 | { |
612 | struct zilog_channel __iomem *channel; | 612 | struct zilog_channel __iomem *channel; |
613 | unsigned long flags; | ||
614 | unsigned char status; | 613 | unsigned char status; |
615 | 614 | ||
616 | spin_lock_irqsave(&port->lock, flags); | ||
617 | |||
618 | channel = ZILOG_CHANNEL_FROM_PORT(port); | 615 | channel = ZILOG_CHANNEL_FROM_PORT(port); |
619 | status = sbus_readb(&channel->control); | 616 | status = sbus_readb(&channel->control); |
620 | ZSDELAY(); | 617 | ZSDELAY(); |
621 | 618 | ||
622 | spin_unlock_irqrestore(&port->lock, flags); | ||
623 | |||
624 | return status; | 619 | return status; |
625 | } | 620 | } |
626 | 621 | ||
627 | /* The port lock is not held. */ | 622 | /* The port lock is not held. */ |
628 | static unsigned int sunzilog_tx_empty(struct uart_port *port) | 623 | static unsigned int sunzilog_tx_empty(struct uart_port *port) |
629 | { | 624 | { |
625 | unsigned long flags; | ||
630 | unsigned char status; | 626 | unsigned char status; |
631 | unsigned int ret; | 627 | unsigned int ret; |
632 | 628 | ||
629 | spin_lock_irqsave(&port->lock, flags); | ||
630 | |||
633 | status = sunzilog_read_channel_status(port); | 631 | status = sunzilog_read_channel_status(port); |
632 | |||
633 | spin_unlock_irqrestore(&port->lock, flags); | ||
634 | |||
634 | if (status & Tx_BUF_EMP) | 635 | if (status & Tx_BUF_EMP) |
635 | ret = TIOCSER_TEMT; | 636 | ret = TIOCSER_TEMT; |
636 | else | 637 | else |
@@ -639,7 +640,7 @@ static unsigned int sunzilog_tx_empty(struct uart_port *port) | |||
639 | return ret; | 640 | return ret; |
640 | } | 641 | } |
641 | 642 | ||
642 | /* The port lock is not held. */ | 643 | /* The port lock is held and interrupts are disabled. */ |
643 | static unsigned int sunzilog_get_mctrl(struct uart_port *port) | 644 | static unsigned int sunzilog_get_mctrl(struct uart_port *port) |
644 | { | 645 | { |
645 | unsigned char status; | 646 | unsigned char status; |