aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/21285.c4
-rw-r--r--drivers/serial/8250.c7
-rw-r--r--drivers/serial/8250_pnp.c12
-rw-r--r--drivers/serial/Kconfig15
-rw-r--r--drivers/serial/Makefile1
-rw-r--r--drivers/serial/imx.c2
-rw-r--r--drivers/serial/pmac_zilog.c11
-rw-r--r--drivers/serial/s5pv210.c154
-rw-r--r--drivers/serial/samsung.c6
-rw-r--r--drivers/serial/samsung.h19
-rw-r--r--drivers/serial/serial_core.c105
-rw-r--r--drivers/serial/serial_cs.c19
-rw-r--r--drivers/serial/sh-sci.c13
-rw-r--r--drivers/serial/uartlite.c2
14 files changed, 277 insertions, 93 deletions
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c
index 1e3d19397a59..8681f1345056 100644
--- a/drivers/serial/21285.c
+++ b/drivers/serial/21285.c
@@ -58,7 +58,7 @@ static const char serial21285_name[] = "Footbridge UART";
58static void serial21285_stop_tx(struct uart_port *port) 58static void serial21285_stop_tx(struct uart_port *port)
59{ 59{
60 if (tx_enabled(port)) { 60 if (tx_enabled(port)) {
61 disable_irq(IRQ_CONTX); 61 disable_irq_nosync(IRQ_CONTX);
62 tx_enabled(port) = 0; 62 tx_enabled(port) = 0;
63 } 63 }
64} 64}
@@ -74,7 +74,7 @@ static void serial21285_start_tx(struct uart_port *port)
74static void serial21285_stop_rx(struct uart_port *port) 74static void serial21285_stop_rx(struct uart_port *port)
75{ 75{
76 if (rx_enabled(port)) { 76 if (rx_enabled(port)) {
77 disable_irq(IRQ_CONRX); 77 disable_irq_nosync(IRQ_CONRX);
78 rx_enabled(port) = 0; 78 rx_enabled(port) = 0;
79 } 79 }
80} 80}
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index c3e37c8e7e26..e9b15c3746fa 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -83,6 +83,9 @@ static unsigned int skip_txen_test; /* force skip of txen test at init time */
83 83
84#define PASS_LIMIT 256 84#define PASS_LIMIT 256
85 85
86#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
87
88
86/* 89/*
87 * We default to IRQ0 for the "no irq" hack. Some 90 * We default to IRQ0 for the "no irq" hack. Some
88 * machine types want others as well - they're free 91 * machine types want others as well - they're free
@@ -1792,7 +1795,7 @@ static unsigned int serial8250_tx_empty(struct uart_port *port)
1792 up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; 1795 up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
1793 spin_unlock_irqrestore(&up->port.lock, flags); 1796 spin_unlock_irqrestore(&up->port.lock, flags);
1794 1797
1795 return lsr & UART_LSR_TEMT ? TIOCSER_TEMT : 0; 1798 return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0;
1796} 1799}
1797 1800
1798static unsigned int serial8250_get_mctrl(struct uart_port *port) 1801static unsigned int serial8250_get_mctrl(struct uart_port *port)
@@ -1850,8 +1853,6 @@ static void serial8250_break_ctl(struct uart_port *port, int break_state)
1850 spin_unlock_irqrestore(&up->port.lock, flags); 1853 spin_unlock_irqrestore(&up->port.lock, flags);
1851} 1854}
1852 1855
1853#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
1854
1855/* 1856/*
1856 * Wait for transmitter & holding register to empty 1857 * Wait for transmitter & holding register to empty
1857 */ 1858 */
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
index 36ede02ceacf..24485cc62ff8 100644
--- a/drivers/serial/8250_pnp.c
+++ b/drivers/serial/8250_pnp.c
@@ -328,15 +328,7 @@ static const struct pnp_device_id pnp_dev_table[] = {
328 /* U.S. Robotics 56K Voice INT PnP*/ 328 /* U.S. Robotics 56K Voice INT PnP*/
329 { "USR9190", 0 }, 329 { "USR9190", 0 },
330 /* Wacom tablets */ 330 /* Wacom tablets */
331 { "WACF004", 0 }, 331 { "WACFXXX", 0 },
332 { "WACF005", 0 },
333 { "WACF006", 0 },
334 { "WACF007", 0 },
335 { "WACF008", 0 },
336 { "WACF009", 0 },
337 { "WACF00A", 0 },
338 { "WACF00B", 0 },
339 { "WACF00C", 0 },
340 /* Compaq touchscreen */ 332 /* Compaq touchscreen */
341 { "FPI2002", 0 }, 333 { "FPI2002", 0 },
342 /* Fujitsu Stylistic touchscreens */ 334 /* Fujitsu Stylistic touchscreens */
@@ -354,6 +346,8 @@ static const struct pnp_device_id pnp_dev_table[] = {
354 { "FUJ02E5", 0 }, 346 { "FUJ02E5", 0 },
355 /* Fujitsu P-series tablet PC device */ 347 /* Fujitsu P-series tablet PC device */
356 { "FUJ02E6", 0 }, 348 { "FUJ02E6", 0 },
349 /* Fujitsu Wacom 2FGT Tablet PC device */
350 { "FUJ02E7", 0 },
357 /* 351 /*
358 * LG C1 EXPRESS DUAL (C1-PB11A3) touch screen (actually a FUJ02E6 in 352 * LG C1 EXPRESS DUAL (C1-PB11A3) touch screen (actually a FUJ02E6 in
359 * disguise) 353 * disguise)
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 9ff47db0b2ce..ebdd2b984d16 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -459,7 +459,7 @@ config SERIAL_SAMSUNG_UARTS
459 int 459 int
460 depends on ARM && PLAT_S3C 460 depends on ARM && PLAT_S3C
461 default 2 if ARCH_S3C2400 461 default 2 if ARCH_S3C2400
462 default 4 if ARCH_S5PC1XX || ARCH_S3C64XX || CPU_S3C2443 462 default 4 if ARCH_S5P6440 || ARCH_S5PC1XX || ARCH_S5PV210 || ARCH_S3C64XX || CPU_S3C2443
463 default 3 463 default 3
464 help 464 help
465 Select the number of available UART ports for the Samsung S3C 465 Select the number of available UART ports for the Samsung S3C
@@ -526,11 +526,11 @@ config SERIAL_S3C24A0
526 Serial port support for the Samsung S3C24A0 SoC 526 Serial port support for the Samsung S3C24A0 SoC
527 527
528config SERIAL_S3C6400 528config SERIAL_S3C6400
529 tristate "Samsung S3C6400/S3C6410 Serial port support" 529 tristate "Samsung S3C6400/S3C6410/S5P6440 Serial port support"
530 depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410) 530 depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410 || CPU_S5P6440)
531 default y 531 default y
532 help 532 help
533 Serial port support for the Samsung S3C6400 and S3C6410 533 Serial port support for the Samsung S3C6400, S3C6410 and S5P6440
534 SoCs 534 SoCs
535 535
536config SERIAL_S5PC100 536config SERIAL_S5PC100
@@ -540,6 +540,13 @@ config SERIAL_S5PC100
540 help 540 help
541 Serial port support for the Samsung S5PC100 SoCs 541 Serial port support for the Samsung S5PC100 SoCs
542 542
543config SERIAL_S5PV210
544 tristate "Samsung S5PV210 Serial port support"
545 depends on SERIAL_SAMSUNG && CPU_S5PV210
546 default y
547 help
548 Serial port support for Samsung's S5P Family of SoC's
549
543config SERIAL_MAX3100 550config SERIAL_MAX3100
544 tristate "MAX3100 support" 551 tristate "MAX3100 support"
545 depends on SPI 552 depends on SPI
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 5548fe7df61d..6aa4723b74ee 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_SERIAL_S3C2440) += s3c2440.o
45obj-$(CONFIG_SERIAL_S3C24A0) += s3c24a0.o 45obj-$(CONFIG_SERIAL_S3C24A0) += s3c24a0.o
46obj-$(CONFIG_SERIAL_S3C6400) += s3c6400.o 46obj-$(CONFIG_SERIAL_S3C6400) += s3c6400.o
47obj-$(CONFIG_SERIAL_S5PC100) += s3c6400.o 47obj-$(CONFIG_SERIAL_S5PC100) += s3c6400.o
48obj-$(CONFIG_SERIAL_S5PV210) += s5pv210.o
48obj-$(CONFIG_SERIAL_MAX3100) += max3100.o 49obj-$(CONFIG_SERIAL_MAX3100) += max3100.o
49obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o 50obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o
50obj-$(CONFIG_SERIAL_MUX) += mux.o 51obj-$(CONFIG_SERIAL_MUX) += mux.o
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index c5b546a98520..b801f5ab2b7b 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -1088,7 +1088,7 @@ imx_console_get_options(struct imx_port *sport, int *baud,
1088 int *parity, int *bits) 1088 int *parity, int *bits)
1089{ 1089{
1090 1090
1091 if ( readl(sport->port.membase + UCR1) | UCR1_UARTEN ) { 1091 if (readl(sport->port.membase + UCR1) & UCR1_UARTEN) {
1092 /* ok, the port was enabled */ 1092 /* ok, the port was enabled */
1093 unsigned int ucr2, ubir,ubmr, uartclk; 1093 unsigned int ucr2, ubir,ubmr, uartclk;
1094 unsigned int baud_raw; 1094 unsigned int baud_raw;
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c
index 0700cd10b97c..683e66f18e8c 100644
--- a/drivers/serial/pmac_zilog.c
+++ b/drivers/serial/pmac_zilog.c
@@ -411,6 +411,17 @@ static void pmz_transmit_chars(struct uart_pmac_port *uap)
411 goto ack_tx_int; 411 goto ack_tx_int;
412 } 412 }
413 413
414 /* Under some circumstances, we see interrupts reported for
415 * a closed channel. The interrupt mask in R1 is clear, but
416 * R3 still signals the interrupts and we see them when taking
417 * an interrupt for the other channel (this could be a qemu
418 * bug but since the ESCC doc doesn't specify precsiely whether
419 * R3 interrup status bits are masked by R1 interrupt enable
420 * bits, better safe than sorry). --BenH.
421 */
422 if (!ZS_IS_OPEN(uap))
423 goto ack_tx_int;
424
414 if (uap->port.x_char) { 425 if (uap->port.x_char) {
415 uap->flags |= PMACZILOG_FLAG_TX_ACTIVE; 426 uap->flags |= PMACZILOG_FLAG_TX_ACTIVE;
416 write_zsdata(uap, uap->port.x_char); 427 write_zsdata(uap, uap->port.x_char);
diff --git a/drivers/serial/s5pv210.c b/drivers/serial/s5pv210.c
new file mode 100644
index 000000000000..8dc03837617b
--- /dev/null
+++ b/drivers/serial/s5pv210.c
@@ -0,0 +1,154 @@
1/* linux/drivers/serial/s5pv210.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * Based on drivers/serial/s3c6400.c
7 *
8 * Driver for Samsung S5PV210 SoC UARTs.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/module.h>
16#include <linux/ioport.h>
17#include <linux/io.h>
18#include <linux/platform_device.h>
19#include <linux/init.h>
20#include <linux/serial_core.h>
21#include <linux/serial.h>
22
23#include <asm/irq.h>
24#include <mach/hardware.h>
25#include <plat/regs-serial.h>
26#include "samsung.h"
27
28static int s5pv210_serial_setsource(struct uart_port *port,
29 struct s3c24xx_uart_clksrc *clk)
30{
31 unsigned long ucon = rd_regl(port, S3C2410_UCON);
32
33 if (strcmp(clk->name, "pclk") == 0)
34 ucon &= ~S5PV210_UCON_CLKMASK;
35 else if (strcmp(clk->name, "uclk1") == 0)
36 ucon |= S5PV210_UCON_CLKMASK;
37 else {
38 printk(KERN_ERR "unknown clock source %s\n", clk->name);
39 return -EINVAL;
40 }
41
42 wr_regl(port, S3C2410_UCON, ucon);
43 return 0;
44}
45
46
47static int s5pv210_serial_getsource(struct uart_port *port,
48 struct s3c24xx_uart_clksrc *clk)
49{
50 u32 ucon = rd_regl(port, S3C2410_UCON);
51
52 clk->divisor = 1;
53
54 switch (ucon & S5PV210_UCON_CLKMASK) {
55 case S5PV210_UCON_PCLK:
56 clk->name = "pclk";
57 break;
58 case S5PV210_UCON_UCLK:
59 clk->name = "uclk1";
60 break;
61 }
62
63 return 0;
64}
65
66static int s5pv210_serial_resetport(struct uart_port *port,
67 struct s3c2410_uartcfg *cfg)
68{
69 unsigned long ucon = rd_regl(port, S3C2410_UCON);
70
71 ucon &= S5PV210_UCON_CLKMASK;
72 wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
73 wr_regl(port, S3C2410_ULCON, cfg->ulcon);
74
75 /* reset both fifos */
76 wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
77 wr_regl(port, S3C2410_UFCON, cfg->ufcon);
78
79 return 0;
80}
81
82#define S5PV210_UART_DEFAULT_INFO(fifo_size) \
83 .name = "Samsung S5PV210 UART0", \
84 .type = PORT_S3C6400, \
85 .fifosize = fifo_size, \
86 .has_divslot = 1, \
87 .rx_fifomask = S5PV210_UFSTAT_RXMASK, \
88 .rx_fifoshift = S5PV210_UFSTAT_RXSHIFT, \
89 .rx_fifofull = S5PV210_UFSTAT_RXFULL, \
90 .tx_fifofull = S5PV210_UFSTAT_TXFULL, \
91 .tx_fifomask = S5PV210_UFSTAT_TXMASK, \
92 .tx_fifoshift = S5PV210_UFSTAT_TXSHIFT, \
93 .get_clksrc = s5pv210_serial_getsource, \
94 .set_clksrc = s5pv210_serial_setsource, \
95 .reset_port = s5pv210_serial_resetport
96
97static struct s3c24xx_uart_info s5p_port_fifo256 = {
98 S5PV210_UART_DEFAULT_INFO(256),
99};
100
101static struct s3c24xx_uart_info s5p_port_fifo64 = {
102 S5PV210_UART_DEFAULT_INFO(64),
103};
104
105static struct s3c24xx_uart_info s5p_port_fifo16 = {
106 S5PV210_UART_DEFAULT_INFO(16),
107};
108
109static struct s3c24xx_uart_info *s5p_uart_inf[] = {
110 [0] = &s5p_port_fifo256,
111 [1] = &s5p_port_fifo64,
112 [2] = &s5p_port_fifo16,
113 [3] = &s5p_port_fifo16,
114};
115
116/* device management */
117static int s5p_serial_probe(struct platform_device *pdev)
118{
119 return s3c24xx_serial_probe(pdev, s5p_uart_inf[pdev->id]);
120}
121
122static struct platform_driver s5p_serial_drv = {
123 .probe = s5p_serial_probe,
124 .remove = __devexit_p(s3c24xx_serial_remove),
125 .driver = {
126 .name = "s5pv210-uart",
127 .owner = THIS_MODULE,
128 },
129};
130
131static int __init s5pv210_serial_console_init(void)
132{
133 return s3c24xx_serial_initconsole(&s5p_serial_drv, s5p_uart_inf);
134}
135
136console_initcall(s5pv210_serial_console_init);
137
138static int __init s5p_serial_init(void)
139{
140 return s3c24xx_serial_init(&s5p_serial_drv, *s5p_uart_inf);
141}
142
143static void __exit s5p_serial_exit(void)
144{
145 platform_driver_unregister(&s5p_serial_drv);
146}
147
148module_init(s5p_serial_init);
149module_exit(s5p_serial_exit);
150
151MODULE_LICENSE("GPL");
152MODULE_ALIAS("platform:s5pv210-uart");
153MODULE_DESCRIPTION("Samsung S5PV210 UART Driver support");
154MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com>");
diff --git a/drivers/serial/samsung.c b/drivers/serial/samsung.c
index 52e3df113ec0..6982243736d1 100644
--- a/drivers/serial/samsung.c
+++ b/drivers/serial/samsung.c
@@ -1374,7 +1374,7 @@ s3c24xx_serial_get_options(struct uart_port *port, int *baud,
1374 * data. 1374 * data.
1375*/ 1375*/
1376 1376
1377static int s3c24xx_serial_init_ports(struct s3c24xx_uart_info *info) 1377static int s3c24xx_serial_init_ports(struct s3c24xx_uart_info **info)
1378{ 1378{
1379 struct s3c24xx_uart_port *ptr = s3c24xx_serial_ports; 1379 struct s3c24xx_uart_port *ptr = s3c24xx_serial_ports;
1380 struct platform_device **platdev_ptr; 1380 struct platform_device **platdev_ptr;
@@ -1385,7 +1385,7 @@ static int s3c24xx_serial_init_ports(struct s3c24xx_uart_info *info)
1385 platdev_ptr = s3c24xx_uart_devs; 1385 platdev_ptr = s3c24xx_uart_devs;
1386 1386
1387 for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++, ptr++, platdev_ptr++) { 1387 for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++, ptr++, platdev_ptr++) {
1388 s3c24xx_serial_init_port(ptr, info, *platdev_ptr); 1388 s3c24xx_serial_init_port(ptr, info[i], *platdev_ptr);
1389 } 1389 }
1390 1390
1391 return 0; 1391 return 0;
@@ -1451,7 +1451,7 @@ static struct console s3c24xx_serial_console = {
1451}; 1451};
1452 1452
1453int s3c24xx_serial_initconsole(struct platform_driver *drv, 1453int s3c24xx_serial_initconsole(struct platform_driver *drv,
1454 struct s3c24xx_uart_info *info) 1454 struct s3c24xx_uart_info **info)
1455 1455
1456{ 1456{
1457 struct platform_device *dev = s3c24xx_uart_devs[0]; 1457 struct platform_device *dev = s3c24xx_uart_devs[0];
diff --git a/drivers/serial/samsung.h b/drivers/serial/samsung.h
index 1fb22343df42..0ac06a07d25f 100644
--- a/drivers/serial/samsung.h
+++ b/drivers/serial/samsung.h
@@ -75,19 +75,24 @@ extern int s3c24xx_serial_probe(struct platform_device *dev,
75extern int __devexit s3c24xx_serial_remove(struct platform_device *dev); 75extern int __devexit s3c24xx_serial_remove(struct platform_device *dev);
76 76
77extern int s3c24xx_serial_initconsole(struct platform_driver *drv, 77extern int s3c24xx_serial_initconsole(struct platform_driver *drv,
78 struct s3c24xx_uart_info *uart); 78 struct s3c24xx_uart_info **uart);
79 79
80extern int s3c24xx_serial_init(struct platform_driver *drv, 80extern int s3c24xx_serial_init(struct platform_driver *drv,
81 struct s3c24xx_uart_info *info); 81 struct s3c24xx_uart_info *info);
82 82
83#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE 83#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
84 84
85#define s3c24xx_console_init(__drv, __inf) \ 85#define s3c24xx_console_init(__drv, __inf) \
86static int __init s3c_serial_console_init(void) \ 86static int __init s3c_serial_console_init(void) \
87{ \ 87{ \
88 return s3c24xx_serial_initconsole(__drv, __inf); \ 88 struct s3c24xx_uart_info *uinfo[CONFIG_SERIAL_SAMSUNG_UARTS]; \
89} \ 89 int i; \
90 \ 90 \
91 for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++) \
92 uinfo[i] = __inf; \
93 return s3c24xx_serial_initconsole(__drv, uinfo); \
94} \
95 \
91console_initcall(s3c_serial_console_init) 96console_initcall(s3c_serial_console_init)
92 97
93#else 98#else
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 047530b285bb..7f2830709512 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -385,13 +385,20 @@ uart_get_baud_rate(struct uart_port *port, struct ktermios *termios,
385 } 385 }
386 386
387 /* 387 /*
388 * As a last resort, if the quotient is zero, 388 * As a last resort, if the range cannot be met then clip to
389 * default to 9600 bps 389 * the nearest chip supported rate.
390 */ 390 */
391 if (!hung_up) 391 if (!hung_up) {
392 tty_termios_encode_baud_rate(termios, 9600, 9600); 392 if (baud <= min)
393 tty_termios_encode_baud_rate(termios,
394 min + 1, min + 1);
395 else
396 tty_termios_encode_baud_rate(termios,
397 max - 1, max - 1);
398 }
393 } 399 }
394 400 /* Should never happen */
401 WARN_ON(1);
395 return 0; 402 return 0;
396} 403}
397 404
@@ -2006,12 +2013,6 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
2006 2013
2007 mutex_lock(&port->mutex); 2014 mutex_lock(&port->mutex);
2008 2015
2009 if (!console_suspend_enabled && uart_console(uport)) {
2010 /* we're going to avoid suspending serial console */
2011 mutex_unlock(&port->mutex);
2012 return 0;
2013 }
2014
2015 tty_dev = device_find_child(uport->dev, &match, serial_match_port); 2016 tty_dev = device_find_child(uport->dev, &match, serial_match_port);
2016 if (device_may_wakeup(tty_dev)) { 2017 if (device_may_wakeup(tty_dev)) {
2017 enable_irq_wake(uport->irq); 2018 enable_irq_wake(uport->irq);
@@ -2019,20 +2020,23 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
2019 mutex_unlock(&port->mutex); 2020 mutex_unlock(&port->mutex);
2020 return 0; 2021 return 0;
2021 } 2022 }
2022 uport->suspended = 1; 2023 if (console_suspend_enabled || !uart_console(uport))
2024 uport->suspended = 1;
2023 2025
2024 if (port->flags & ASYNC_INITIALIZED) { 2026 if (port->flags & ASYNC_INITIALIZED) {
2025 const struct uart_ops *ops = uport->ops; 2027 const struct uart_ops *ops = uport->ops;
2026 int tries; 2028 int tries;
2027 2029
2028 set_bit(ASYNCB_SUSPENDED, &port->flags); 2030 if (console_suspend_enabled || !uart_console(uport)) {
2029 clear_bit(ASYNCB_INITIALIZED, &port->flags); 2031 set_bit(ASYNCB_SUSPENDED, &port->flags);
2032 clear_bit(ASYNCB_INITIALIZED, &port->flags);
2030 2033
2031 spin_lock_irq(&uport->lock); 2034 spin_lock_irq(&uport->lock);
2032 ops->stop_tx(uport); 2035 ops->stop_tx(uport);
2033 ops->set_mctrl(uport, 0); 2036 ops->set_mctrl(uport, 0);
2034 ops->stop_rx(uport); 2037 ops->stop_rx(uport);
2035 spin_unlock_irq(&uport->lock); 2038 spin_unlock_irq(&uport->lock);
2039 }
2036 2040
2037 /* 2041 /*
2038 * Wait for the transmitter to empty. 2042 * Wait for the transmitter to empty.
@@ -2047,16 +2051,18 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
2047 drv->dev_name, 2051 drv->dev_name,
2048 drv->tty_driver->name_base + uport->line); 2052 drv->tty_driver->name_base + uport->line);
2049 2053
2050 ops->shutdown(uport); 2054 if (console_suspend_enabled || !uart_console(uport))
2055 ops->shutdown(uport);
2051 } 2056 }
2052 2057
2053 /* 2058 /*
2054 * Disable the console device before suspending. 2059 * Disable the console device before suspending.
2055 */ 2060 */
2056 if (uart_console(uport)) 2061 if (console_suspend_enabled && uart_console(uport))
2057 console_stop(uport->cons); 2062 console_stop(uport->cons);
2058 2063
2059 uart_change_pm(state, 3); 2064 if (console_suspend_enabled || !uart_console(uport))
2065 uart_change_pm(state, 3);
2060 2066
2061 mutex_unlock(&port->mutex); 2067 mutex_unlock(&port->mutex);
2062 2068
@@ -2073,29 +2079,6 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
2073 2079
2074 mutex_lock(&port->mutex); 2080 mutex_lock(&port->mutex);
2075 2081
2076 if (!console_suspend_enabled && uart_console(uport)) {
2077 /* no need to resume serial console, it wasn't suspended */
2078 /*
2079 * First try to use the console cflag setting.
2080 */
2081 memset(&termios, 0, sizeof(struct ktermios));
2082 termios.c_cflag = uport->cons->cflag;
2083 /*
2084 * If that's unset, use the tty termios setting.
2085 */
2086 if (termios.c_cflag == 0)
2087 termios = *state->port.tty->termios;
2088 else {
2089 termios.c_ispeed = termios.c_ospeed =
2090 tty_termios_input_baud_rate(&termios);
2091 termios.c_ispeed = termios.c_ospeed =
2092 tty_termios_baud_rate(&termios);
2093 }
2094 uport->ops->set_termios(uport, &termios, NULL);
2095 mutex_unlock(&port->mutex);
2096 return 0;
2097 }
2098
2099 tty_dev = device_find_child(uport->dev, &match, serial_match_port); 2082 tty_dev = device_find_child(uport->dev, &match, serial_match_port);
2100 if (!uport->suspended && device_may_wakeup(tty_dev)) { 2083 if (!uport->suspended && device_may_wakeup(tty_dev)) {
2101 disable_irq_wake(uport->irq); 2084 disable_irq_wake(uport->irq);
@@ -2121,21 +2104,23 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
2121 spin_lock_irq(&uport->lock); 2104 spin_lock_irq(&uport->lock);
2122 ops->set_mctrl(uport, 0); 2105 ops->set_mctrl(uport, 0);
2123 spin_unlock_irq(&uport->lock); 2106 spin_unlock_irq(&uport->lock);
2124 ret = ops->startup(uport); 2107 if (console_suspend_enabled || !uart_console(uport)) {
2125 if (ret == 0) { 2108 ret = ops->startup(uport);
2126 uart_change_speed(state, NULL); 2109 if (ret == 0) {
2127 spin_lock_irq(&uport->lock); 2110 uart_change_speed(state, NULL);
2128 ops->set_mctrl(uport, uport->mctrl); 2111 spin_lock_irq(&uport->lock);
2129 ops->start_tx(uport); 2112 ops->set_mctrl(uport, uport->mctrl);
2130 spin_unlock_irq(&uport->lock); 2113 ops->start_tx(uport);
2131 set_bit(ASYNCB_INITIALIZED, &port->flags); 2114 spin_unlock_irq(&uport->lock);
2132 } else { 2115 set_bit(ASYNCB_INITIALIZED, &port->flags);
2133 /* 2116 } else {
2134 * Failed to resume - maybe hardware went away? 2117 /*
2135 * Clear the "initialized" flag so we won't try 2118 * Failed to resume - maybe hardware went away?
2136 * to call the low level drivers shutdown method. 2119 * Clear the "initialized" flag so we won't try
2137 */ 2120 * to call the low level drivers shutdown method.
2138 uart_shutdown(state); 2121 */
2122 uart_shutdown(state);
2123 }
2139 } 2124 }
2140 2125
2141 clear_bit(ASYNCB_SUSPENDED, &port->flags); 2126 clear_bit(ASYNCB_SUSPENDED, &port->flags);
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index fc413f0f8dd2..95421fa3b304 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -146,7 +146,8 @@ static void quirk_wakeup_oxsemi(struct pcmcia_device *link)
146{ 146{
147 struct serial_info *info = link->priv; 147 struct serial_info *info = link->priv;
148 148
149 outb(12, info->c950ctrl + 1); 149 if (info->c950ctrl)
150 outb(12, info->c950ctrl + 1);
150} 151}
151 152
152/* request_region? oxsemi branch does no request_region too... */ 153/* request_region? oxsemi branch does no request_region too... */
@@ -757,6 +758,7 @@ static struct pcmcia_device_id serial_ids[] = {
757 PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f), 758 PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f),
758 PCMCIA_PFC_DEVICE_PROD_ID12(1, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed), 759 PCMCIA_PFC_DEVICE_PROD_ID12(1, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed),
759 PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet+Modem II", 0x2e3ee845, 0xeca401bf), 760 PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet+Modem II", 0x2e3ee845, 0xeca401bf),
761 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0e01),
760 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0a05), 762 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0a05),
761 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x1101), 763 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x1101),
762 PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0104, 0x0070), 764 PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0104, 0x0070),
@@ -819,6 +821,7 @@ static struct pcmcia_device_id serial_ids[] = {
819 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "cis/3CXEM556.cis"), 821 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "cis/3CXEM556.cis"),
820 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "cis/3CXEM556.cis"), 822 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "cis/3CXEM556.cis"),
821 PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC850", 0xd85f6206, 0x42a2c018, "cis/SW_8xx_SER.cis"), /* Sierra Wireless AC850 3G Network Adapter R1 */ 823 PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC850", 0xd85f6206, 0x42a2c018, "cis/SW_8xx_SER.cis"), /* Sierra Wireless AC850 3G Network Adapter R1 */
824 PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC860", 0xd85f6206, 0x698f93db, "cis/SW_8xx_SER.cis"), /* Sierra Wireless AC860 3G Network Adapter R1 */
822 PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC710/AC750", 0xd85f6206, 0x761b11e0, "cis/SW_7xx_SER.cis"), /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */ 825 PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC710/AC750", 0xd85f6206, 0x761b11e0, "cis/SW_7xx_SER.cis"), /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */
823 PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "cis/SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */ 826 PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "cis/SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */
824 PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "cis/SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */ 827 PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "cis/SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */
@@ -827,7 +830,7 @@ static struct pcmcia_device_id serial_ids[] = {
827 PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "cis/COMpad4.cis"), 830 PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "cis/COMpad4.cis"),
828 PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "cis/COMpad2.cis"), 831 PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "cis/COMpad2.cis"),
829 PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "cis/RS-COM-2P.cis"), 832 PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "cis/RS-COM-2P.cis"),
830 PCMCIA_DEVICE_CIS_MANF_CARD(0x0013, 0x0000, "GLOBETROTTER.cis"), 833 PCMCIA_DEVICE_CIS_MANF_CARD(0x0013, 0x0000, "cis/GLOBETROTTER.cis"),
831 PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100 1.00.",0x19ca78af,0xf964f42b), 834 PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100 1.00.",0x19ca78af,0xf964f42b),
832 PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100",0x19ca78af,0x71d98e83), 835 PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100",0x19ca78af,0x71d98e83),
833 PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL232 1.00.",0x19ca78af,0x69fb7490), 836 PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL232 1.00.",0x19ca78af,0x69fb7490),
@@ -861,6 +864,18 @@ static struct pcmcia_device_id serial_ids[] = {
861}; 864};
862MODULE_DEVICE_TABLE(pcmcia, serial_ids); 865MODULE_DEVICE_TABLE(pcmcia, serial_ids);
863 866
867MODULE_FIRMWARE("cis/PCMLM28.cis");
868MODULE_FIRMWARE("cis/DP83903.cis");
869MODULE_FIRMWARE("cis/3CCFEM556.cis");
870MODULE_FIRMWARE("cis/3CXEM556.cis");
871MODULE_FIRMWARE("cis/SW_8xx_SER.cis");
872MODULE_FIRMWARE("cis/SW_7xx_SER.cis");
873MODULE_FIRMWARE("cis/SW_555_SER.cis");
874MODULE_FIRMWARE("cis/MT5634ZLX.cis");
875MODULE_FIRMWARE("cis/COMpad2.cis");
876MODULE_FIRMWARE("cis/COMpad4.cis");
877MODULE_FIRMWARE("cis/RS-COM-2P.cis");
878
864static struct pcmcia_driver serial_cs_driver = { 879static struct pcmcia_driver serial_cs_driver = {
865 .owner = THIS_MODULE, 880 .owner = THIS_MODULE,
866 .drv = { 881 .drv = {
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index 37f0de9dd9ce..42f3333c4ad0 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -1052,7 +1052,18 @@ static void __devinit sci_init_single(struct platform_device *dev,
1052 sci_port->port.ops = &sci_uart_ops; 1052 sci_port->port.ops = &sci_uart_ops;
1053 sci_port->port.iotype = UPIO_MEM; 1053 sci_port->port.iotype = UPIO_MEM;
1054 sci_port->port.line = index; 1054 sci_port->port.line = index;
1055 sci_port->port.fifosize = 1; 1055
1056 switch (p->type) {
1057 case PORT_SCIFA:
1058 sci_port->port.fifosize = 64;
1059 break;
1060 case PORT_SCIF:
1061 sci_port->port.fifosize = 16;
1062 break;
1063 default:
1064 sci_port->port.fifosize = 1;
1065 break;
1066 }
1056 1067
1057 if (dev) { 1068 if (dev) {
1058 sci_port->iclk = p->clk ? clk_get(&dev->dev, p->clk) : NULL; 1069 sci_port->iclk = p->clk ? clk_get(&dev->dev, p->clk) : NULL;
diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c
index 377f2712289e..ab2ab3c81834 100644
--- a/drivers/serial/uartlite.c
+++ b/drivers/serial/uartlite.c
@@ -394,7 +394,7 @@ static void ulite_console_write(struct console *co, const char *s,
394 spin_unlock_irqrestore(&port->lock, flags); 394 spin_unlock_irqrestore(&port->lock, flags);
395} 395}
396 396
397static int __init ulite_console_setup(struct console *co, char *options) 397static int __devinit ulite_console_setup(struct console *co, char *options)
398{ 398{
399 struct uart_port *port; 399 struct uart_port *port;
400 int baud = 9600; 400 int baud = 9600;