diff options
Diffstat (limited to 'drivers/serial')
-rw-r--r-- | drivers/serial/21285.c | 4 | ||||
-rw-r--r-- | drivers/serial/8250.c | 7 | ||||
-rw-r--r-- | drivers/serial/8250_pnp.c | 12 | ||||
-rw-r--r-- | drivers/serial/Kconfig | 15 | ||||
-rw-r--r-- | drivers/serial/Makefile | 1 | ||||
-rw-r--r-- | drivers/serial/imx.c | 2 | ||||
-rw-r--r-- | drivers/serial/pmac_zilog.c | 11 | ||||
-rw-r--r-- | drivers/serial/s5pv210.c | 154 | ||||
-rw-r--r-- | drivers/serial/samsung.c | 6 | ||||
-rw-r--r-- | drivers/serial/samsung.h | 19 | ||||
-rw-r--r-- | drivers/serial/serial_core.c | 105 | ||||
-rw-r--r-- | drivers/serial/serial_cs.c | 19 | ||||
-rw-r--r-- | drivers/serial/sh-sci.c | 13 | ||||
-rw-r--r-- | drivers/serial/uartlite.c | 2 |
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"; | |||
58 | static void serial21285_stop_tx(struct uart_port *port) | 58 | static 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) | |||
74 | static void serial21285_stop_rx(struct uart_port *port) | 74 | static 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 | ||
1798 | static unsigned int serial8250_get_mctrl(struct uart_port *port) | 1801 | static 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 | ||
528 | config SERIAL_S3C6400 | 528 | config 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 | ||
536 | config SERIAL_S5PC100 | 536 | config 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 | ||
543 | config 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 | |||
543 | config SERIAL_MAX3100 | 550 | config 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 | |||
45 | obj-$(CONFIG_SERIAL_S3C24A0) += s3c24a0.o | 45 | obj-$(CONFIG_SERIAL_S3C24A0) += s3c24a0.o |
46 | obj-$(CONFIG_SERIAL_S3C6400) += s3c6400.o | 46 | obj-$(CONFIG_SERIAL_S3C6400) += s3c6400.o |
47 | obj-$(CONFIG_SERIAL_S5PC100) += s3c6400.o | 47 | obj-$(CONFIG_SERIAL_S5PC100) += s3c6400.o |
48 | obj-$(CONFIG_SERIAL_S5PV210) += s5pv210.o | ||
48 | obj-$(CONFIG_SERIAL_MAX3100) += max3100.o | 49 | obj-$(CONFIG_SERIAL_MAX3100) += max3100.o |
49 | obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o | 50 | obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o |
50 | obj-$(CONFIG_SERIAL_MUX) += mux.o | 51 | obj-$(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 | |||
28 | static 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 | |||
47 | static 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 | |||
66 | static 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 | |||
97 | static struct s3c24xx_uart_info s5p_port_fifo256 = { | ||
98 | S5PV210_UART_DEFAULT_INFO(256), | ||
99 | }; | ||
100 | |||
101 | static struct s3c24xx_uart_info s5p_port_fifo64 = { | ||
102 | S5PV210_UART_DEFAULT_INFO(64), | ||
103 | }; | ||
104 | |||
105 | static struct s3c24xx_uart_info s5p_port_fifo16 = { | ||
106 | S5PV210_UART_DEFAULT_INFO(16), | ||
107 | }; | ||
108 | |||
109 | static 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 */ | ||
117 | static int s5p_serial_probe(struct platform_device *pdev) | ||
118 | { | ||
119 | return s3c24xx_serial_probe(pdev, s5p_uart_inf[pdev->id]); | ||
120 | } | ||
121 | |||
122 | static 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 | |||
131 | static int __init s5pv210_serial_console_init(void) | ||
132 | { | ||
133 | return s3c24xx_serial_initconsole(&s5p_serial_drv, s5p_uart_inf); | ||
134 | } | ||
135 | |||
136 | console_initcall(s5pv210_serial_console_init); | ||
137 | |||
138 | static int __init s5p_serial_init(void) | ||
139 | { | ||
140 | return s3c24xx_serial_init(&s5p_serial_drv, *s5p_uart_inf); | ||
141 | } | ||
142 | |||
143 | static void __exit s5p_serial_exit(void) | ||
144 | { | ||
145 | platform_driver_unregister(&s5p_serial_drv); | ||
146 | } | ||
147 | |||
148 | module_init(s5p_serial_init); | ||
149 | module_exit(s5p_serial_exit); | ||
150 | |||
151 | MODULE_LICENSE("GPL"); | ||
152 | MODULE_ALIAS("platform:s5pv210-uart"); | ||
153 | MODULE_DESCRIPTION("Samsung S5PV210 UART Driver support"); | ||
154 | MODULE_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 | ||
1377 | static int s3c24xx_serial_init_ports(struct s3c24xx_uart_info *info) | 1377 | static 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 | ||
1453 | int s3c24xx_serial_initconsole(struct platform_driver *drv, | 1453 | int 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, | |||
75 | extern int __devexit s3c24xx_serial_remove(struct platform_device *dev); | 75 | extern int __devexit s3c24xx_serial_remove(struct platform_device *dev); |
76 | 76 | ||
77 | extern int s3c24xx_serial_initconsole(struct platform_driver *drv, | 77 | extern int s3c24xx_serial_initconsole(struct platform_driver *drv, |
78 | struct s3c24xx_uart_info *uart); | 78 | struct s3c24xx_uart_info **uart); |
79 | 79 | ||
80 | extern int s3c24xx_serial_init(struct platform_driver *drv, | 80 | extern 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) \ |
86 | static int __init s3c_serial_console_init(void) \ | 86 | static 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 | \ | ||
91 | console_initcall(s3c_serial_console_init) | 96 | console_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 | }; |
862 | MODULE_DEVICE_TABLE(pcmcia, serial_ids); | 865 | MODULE_DEVICE_TABLE(pcmcia, serial_ids); |
863 | 866 | ||
867 | MODULE_FIRMWARE("cis/PCMLM28.cis"); | ||
868 | MODULE_FIRMWARE("cis/DP83903.cis"); | ||
869 | MODULE_FIRMWARE("cis/3CCFEM556.cis"); | ||
870 | MODULE_FIRMWARE("cis/3CXEM556.cis"); | ||
871 | MODULE_FIRMWARE("cis/SW_8xx_SER.cis"); | ||
872 | MODULE_FIRMWARE("cis/SW_7xx_SER.cis"); | ||
873 | MODULE_FIRMWARE("cis/SW_555_SER.cis"); | ||
874 | MODULE_FIRMWARE("cis/MT5634ZLX.cis"); | ||
875 | MODULE_FIRMWARE("cis/COMpad2.cis"); | ||
876 | MODULE_FIRMWARE("cis/COMpad4.cis"); | ||
877 | MODULE_FIRMWARE("cis/RS-COM-2P.cis"); | ||
878 | |||
864 | static struct pcmcia_driver serial_cs_driver = { | 879 | static 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 | ||
397 | static int __init ulite_console_setup(struct console *co, char *options) | 397 | static 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; |