diff options
139 files changed, 3447 insertions, 3701 deletions
diff --git a/Documentation/devicetree/bindings/goldfish/tty.txt b/Documentation/devicetree/bindings/goldfish/tty.txt new file mode 100644 index 000000000000..82648278da77 --- /dev/null +++ b/Documentation/devicetree/bindings/goldfish/tty.txt | |||
@@ -0,0 +1,17 @@ | |||
1 | Android Goldfish TTY | ||
2 | |||
3 | Android goldfish tty device generated by android emulator. | ||
4 | |||
5 | Required properties: | ||
6 | |||
7 | - compatible : should contain "google,goldfish-tty" to match emulator | ||
8 | - reg : <registers mapping> | ||
9 | - interrupts : <interrupt mapping> | ||
10 | |||
11 | Example: | ||
12 | |||
13 | goldfish_tty@1f004000 { | ||
14 | compatible = "google,goldfish-tty"; | ||
15 | reg = <0x1f004000 0x1000>; | ||
16 | interrupts = <0xc>; | ||
17 | }; | ||
diff --git a/Documentation/devicetree/bindings/serial/brcm,bcm2835-aux-uart.txt b/Documentation/devicetree/bindings/serial/brcm,bcm2835-aux-uart.txt new file mode 100644 index 000000000000..b5cc6297cd1b --- /dev/null +++ b/Documentation/devicetree/bindings/serial/brcm,bcm2835-aux-uart.txt | |||
@@ -0,0 +1,18 @@ | |||
1 | * BCM2835 AUXILIAR UART | ||
2 | |||
3 | Required properties: | ||
4 | |||
5 | - compatible: "brcm,bcm2835-aux-uart" | ||
6 | - reg: The base address of the UART register bank. | ||
7 | - interrupts: A single interrupt specifier. | ||
8 | - clocks: Clock driving the hardware; used to figure out the baud rate | ||
9 | divisor. | ||
10 | |||
11 | Example: | ||
12 | |||
13 | uart1: serial@7e215040 { | ||
14 | compatible = "brcm,bcm2835-aux-uart"; | ||
15 | reg = <0x7e215040 0x40>; | ||
16 | interrupts = <1 29>; | ||
17 | clocks = <&aux BCM2835_AUX_CLOCK_UART>; | ||
18 | }; | ||
diff --git a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt index 401b1b33c2c4..528c3b90f23c 100644 --- a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt +++ b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt | |||
@@ -19,6 +19,8 @@ Required properties: | |||
19 | - "renesas,scifa-r8a7791" for R8A7791 (R-Car M2-W) SCIFA compatible UART. | 19 | - "renesas,scifa-r8a7791" for R8A7791 (R-Car M2-W) SCIFA compatible UART. |
20 | - "renesas,scifb-r8a7791" for R8A7791 (R-Car M2-W) SCIFB compatible UART. | 20 | - "renesas,scifb-r8a7791" for R8A7791 (R-Car M2-W) SCIFB compatible UART. |
21 | - "renesas,hscif-r8a7791" for R8A7791 (R-Car M2-W) HSCIF compatible UART. | 21 | - "renesas,hscif-r8a7791" for R8A7791 (R-Car M2-W) HSCIF compatible UART. |
22 | - "renesas,scif-r8a7792" for R8A7792 (R-Car V2H) SCIF compatible UART. | ||
23 | - "renesas,hscif-r8a7792" for R8A7792 (R-Car V2H) HSCIF compatible UART. | ||
22 | - "renesas,scif-r8a7793" for R8A7793 (R-Car M2-N) SCIF compatible UART. | 24 | - "renesas,scif-r8a7793" for R8A7793 (R-Car M2-N) SCIF compatible UART. |
23 | - "renesas,scifa-r8a7793" for R8A7793 (R-Car M2-N) SCIFA compatible UART. | 25 | - "renesas,scifa-r8a7793" for R8A7793 (R-Car M2-N) SCIFA compatible UART. |
24 | - "renesas,scifb-r8a7793" for R8A7793 (R-Car M2-N) SCIFB compatible UART. | 26 | - "renesas,scifb-r8a7793" for R8A7793 (R-Car M2-N) SCIFB compatible UART. |
diff --git a/Documentation/devicetree/bindings/tty/serial/mvebu-uart.txt b/Documentation/devicetree/bindings/tty/serial/mvebu-uart.txt new file mode 100644 index 000000000000..6087defd9f93 --- /dev/null +++ b/Documentation/devicetree/bindings/tty/serial/mvebu-uart.txt | |||
@@ -0,0 +1,13 @@ | |||
1 | * Marvell UART : Non standard UART used in some of Marvell EBU SoCs (e.g., Armada-3700) | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: "marvell,armada-3700-uart" | ||
5 | - reg: offset and length of the register set for the device. | ||
6 | - interrupts: device interrupt | ||
7 | |||
8 | Example: | ||
9 | serial@12000 { | ||
10 | compatible = "marvell,armada-3700-uart"; | ||
11 | reg = <0x12000 0x400>; | ||
12 | interrupts = <43>; | ||
13 | }; | ||
diff --git a/Documentation/filesystems/devpts.txt b/Documentation/filesystems/devpts.txt index 68dffd87f9b7..30d2fcb32f72 100644 --- a/Documentation/filesystems/devpts.txt +++ b/Documentation/filesystems/devpts.txt | |||
@@ -51,6 +51,15 @@ where 'ns_exec -cm /bin/bash' calls clone() with CLONE_NEWNS flag and execs | |||
51 | /bin/bash in the child process. A pty created by the sshd is not visible in | 51 | /bin/bash in the child process. A pty created by the sshd is not visible in |
52 | the original mount of /dev/pts. | 52 | the original mount of /dev/pts. |
53 | 53 | ||
54 | Total count of pty pairs in all instances is limited by sysctls: | ||
55 | kernel.pty.max = 4096 - global limit | ||
56 | kernel.pty.reserve = 1024 - reserve for initial instance | ||
57 | kernel.pty.nr - current count of ptys | ||
58 | |||
59 | Per-instance limit could be set by adding mount option "max=<count>". | ||
60 | This feature was added in kernel 3.4 together with sysctl kernel.pty.reserve. | ||
61 | In kernels older than 3.4 sysctl kernel.pty.max works as per-instance limit. | ||
62 | |||
54 | User-space changes | 63 | User-space changes |
55 | ------------------ | 64 | ------------------ |
56 | 65 | ||
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index def479154d59..85b280de7aa8 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1064,6 +1064,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
1064 | A valid base address must be provided, and the serial | 1064 | A valid base address must be provided, and the serial |
1065 | port must already be setup and configured. | 1065 | port must already be setup and configured. |
1066 | 1066 | ||
1067 | armada3700_uart,<addr> | ||
1068 | Start an early, polled-mode console on the | ||
1069 | Armada 3700 serial port at the specified | ||
1070 | address. The serial port must already be setup | ||
1071 | and configured. Options are not yet supported. | ||
1072 | |||
1067 | earlyprintk= [X86,SH,BLACKFIN,ARM,M68k] | 1073 | earlyprintk= [X86,SH,BLACKFIN,ARM,M68k] |
1068 | earlyprintk=vga | 1074 | earlyprintk=vga |
1069 | earlyprintk=efi | 1075 | earlyprintk=efi |
diff --git a/Documentation/serial/tty.txt b/Documentation/serial/tty.txt index bc3842dc323a..798cba82c762 100644 --- a/Documentation/serial/tty.txt +++ b/Documentation/serial/tty.txt | |||
@@ -72,9 +72,6 @@ flush_buffer() - (optional) May be called at any point between | |||
72 | open and close, and instructs the line discipline | 72 | open and close, and instructs the line discipline |
73 | to empty its input buffer. | 73 | to empty its input buffer. |
74 | 74 | ||
75 | chars_in_buffer() - (optional) Report the number of bytes in the input | ||
76 | buffer. | ||
77 | |||
78 | set_termios() - (optional) Called on termios structure changes. | 75 | set_termios() - (optional) Called on termios structure changes. |
79 | The caller passes the old termios data and the | 76 | The caller passes the old termios data and the |
80 | current data is in the tty. Called under the | 77 | current data is in the tty. Called under the |
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index f4444c94ff28..57653a44b128 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt | |||
@@ -66,6 +66,7 @@ show up in /proc/sys/kernel: | |||
66 | - printk_delay | 66 | - printk_delay |
67 | - printk_ratelimit | 67 | - printk_ratelimit |
68 | - printk_ratelimit_burst | 68 | - printk_ratelimit_burst |
69 | - pty ==> Documentation/filesystems/devpts.txt | ||
69 | - randomize_va_space | 70 | - randomize_va_space |
70 | - real-root-dev ==> Documentation/initrd.txt | 71 | - real-root-dev ==> Documentation/initrd.txt |
71 | - reboot-cmd [ SPARC only ] | 72 | - reboot-cmd [ SPARC only ] |
diff --git a/MAINTAINERS b/MAINTAINERS index 543dd219de80..5dc9d90c4048 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -6068,7 +6068,7 @@ S: Maintained | |||
6068 | F: drivers/media/platform/rcar_jpu.c | 6068 | F: drivers/media/platform/rcar_jpu.c |
6069 | 6069 | ||
6070 | JSM Neo PCI based serial card | 6070 | JSM Neo PCI based serial card |
6071 | M: Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com> | 6071 | M: Gabriel Krisman Bertazi <krisman@linux.vnet.ibm.com> |
6072 | L: linux-serial@vger.kernel.org | 6072 | L: linux-serial@vger.kernel.org |
6073 | S: Maintained | 6073 | S: Maintained |
6074 | F: drivers/tty/serial/jsm/ | 6074 | F: drivers/tty/serial/jsm/ |
diff --git a/arch/alpha/include/asm/serial.h b/arch/alpha/include/asm/serial.h index 22909b83f473..e31557fc06cc 100644 --- a/arch/alpha/include/asm/serial.h +++ b/arch/alpha/include/asm/serial.h | |||
@@ -14,11 +14,11 @@ | |||
14 | 14 | ||
15 | /* Standard COM flags (except for COM4, because of the 8514 problem) */ | 15 | /* Standard COM flags (except for COM4, because of the 8514 problem) */ |
16 | #ifdef CONFIG_SERIAL_8250_DETECT_IRQ | 16 | #ifdef CONFIG_SERIAL_8250_DETECT_IRQ |
17 | #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ) | 17 | #define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ) |
18 | #define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ) | 18 | #define STD_COM4_FLAGS (UPF_BOOT_AUTOCONF | UPF_AUTO_IRQ) |
19 | #else | 19 | #else |
20 | #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) | 20 | #define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST) |
21 | #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF | 21 | #define STD_COM4_FLAGS UPF_BOOT_AUTOCONF |
22 | #endif | 22 | #endif |
23 | 23 | ||
24 | #define SERIAL_PORT_DFNS \ | 24 | #define SERIAL_PORT_DFNS \ |
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index f164c6b32ce2..8e072de89fed 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c | |||
@@ -252,7 +252,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata, | |||
252 | info = omap_serial_default_info; | 252 | info = omap_serial_default_info; |
253 | 253 | ||
254 | oh = uart->oh; | 254 | oh = uart->oh; |
255 | name = DRIVER_NAME; | 255 | name = OMAP_SERIAL_DRIVER_NAME; |
256 | 256 | ||
257 | omap_up.dma_enabled = info->dma_enabled; | 257 | omap_up.dma_enabled = info->dma_enabled; |
258 | omap_up.uartclk = OMAP24XX_BASE_BAUD * 16; | 258 | omap_up.uartclk = OMAP24XX_BASE_BAUD * 16; |
diff --git a/arch/frv/include/asm/serial.h b/arch/frv/include/asm/serial.h index dbb825998689..bce0d0d07e60 100644 --- a/arch/frv/include/asm/serial.h +++ b/arch/frv/include/asm/serial.h | |||
@@ -13,6 +13,6 @@ | |||
13 | */ | 13 | */ |
14 | #define BASE_BAUD 0 | 14 | #define BASE_BAUD 0 |
15 | 15 | ||
16 | #define STD_COM_FLAGS ASYNC_BOOT_AUTOCONF | 16 | #define STD_COM_FLAGS UPF_BOOT_AUTOCONF |
17 | 17 | ||
18 | #define SERIAL_PORT_DFNS | 18 | #define SERIAL_PORT_DFNS |
diff --git a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c index 622772b7fb6c..e7ae6088350a 100644 --- a/arch/ia64/kernel/unaligned.c +++ b/arch/ia64/kernel/unaligned.c | |||
@@ -1336,8 +1336,11 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs) | |||
1336 | * Don't call tty_write_message() if we're in the kernel; we might | 1336 | * Don't call tty_write_message() if we're in the kernel; we might |
1337 | * be holding locks... | 1337 | * be holding locks... |
1338 | */ | 1338 | */ |
1339 | if (user_mode(regs)) | 1339 | if (user_mode(regs)) { |
1340 | tty_write_message(current->signal->tty, buf); | 1340 | struct tty_struct *tty = get_current_tty(); |
1341 | tty_write_message(tty, buf); | ||
1342 | tty_kref_put(tty); | ||
1343 | } | ||
1341 | buf[len-1] = '\0'; /* drop '\r' */ | 1344 | buf[len-1] = '\0'; /* drop '\r' */ |
1342 | /* watch for command names containing %s */ | 1345 | /* watch for command names containing %s */ |
1343 | printk(KERN_WARNING "%s", buf); | 1346 | printk(KERN_WARNING "%s", buf); |
diff --git a/arch/m68k/include/asm/serial.h b/arch/m68k/include/asm/serial.h index 06d0cb19b4e1..6d4497049b4b 100644 --- a/arch/m68k/include/asm/serial.h +++ b/arch/m68k/include/asm/serial.h | |||
@@ -18,11 +18,11 @@ | |||
18 | 18 | ||
19 | /* Standard COM flags (except for COM4, because of the 8514 problem) */ | 19 | /* Standard COM flags (except for COM4, because of the 8514 problem) */ |
20 | #ifdef CONFIG_SERIAL_8250_DETECT_IRQ | 20 | #ifdef CONFIG_SERIAL_8250_DETECT_IRQ |
21 | #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ) | 21 | #define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ) |
22 | #define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ) | 22 | #define STD_COM4_FLAGS (UPF_BOOT_AUTOCONF | UPF_AUTO_IRQ) |
23 | #else | 23 | #else |
24 | #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) | 24 | #define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST) |
25 | #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF | 25 | #define STD_COM4_FLAGS UPF_BOOT_AUTOCONF |
26 | #endif | 26 | #endif |
27 | 27 | ||
28 | #ifdef CONFIG_ISA | 28 | #ifdef CONFIG_ISA |
diff --git a/arch/mips/pmcs-msp71xx/msp_serial.c b/arch/mips/pmcs-msp71xx/msp_serial.c index d304be22b963..8e6e8db8dd5f 100644 --- a/arch/mips/pmcs-msp71xx/msp_serial.c +++ b/arch/mips/pmcs-msp71xx/msp_serial.c | |||
@@ -110,7 +110,7 @@ void __init msp_serial_setup(void) | |||
110 | up.uartclk = uartclk; | 110 | up.uartclk = uartclk; |
111 | up.regshift = 2; | 111 | up.regshift = 2; |
112 | up.iotype = UPIO_MEM; | 112 | up.iotype = UPIO_MEM; |
113 | up.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; | 113 | up.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; |
114 | up.type = PORT_16550A; | 114 | up.type = PORT_16550A; |
115 | up.line = 0; | 115 | up.line = 0; |
116 | up.serial_out = msp_serial_out; | 116 | up.serial_out = msp_serial_out; |
diff --git a/arch/mn10300/include/asm/serial.h b/arch/mn10300/include/asm/serial.h index c1990218f18c..594ebff15d3f 100644 --- a/arch/mn10300/include/asm/serial.h +++ b/arch/mn10300/include/asm/serial.h | |||
@@ -14,15 +14,15 @@ | |||
14 | 14 | ||
15 | /* Standard COM flags (except for COM4, because of the 8514 problem) */ | 15 | /* Standard COM flags (except for COM4, because of the 8514 problem) */ |
16 | #ifdef CONFIG_SERIAL_8250_DETECT_IRQ | 16 | #ifdef CONFIG_SERIAL_8250_DETECT_IRQ |
17 | #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ) | 17 | #define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ) |
18 | #define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ) | 18 | #define STD_COM4_FLAGS (UPF_BOOT_AUTOCONF | UPF_AUTO_IRQ) |
19 | #else | 19 | #else |
20 | #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) | 20 | #define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST) |
21 | #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF | 21 | #define STD_COM4_FLAGS UPF_BOOT_AUTOCONF |
22 | #endif | 22 | #endif |
23 | 23 | ||
24 | #ifdef CONFIG_SERIAL_8250_MANY_PORTS | 24 | #ifdef CONFIG_SERIAL_8250_MANY_PORTS |
25 | #define FOURPORT_FLAGS ASYNC_FOURPORT | 25 | #define FOURPORT_FLAGS UPF_FOURPORT |
26 | #define ACCENT_FLAGS 0 | 26 | #define ACCENT_FLAGS 0 |
27 | #define BOCA_FLAGS 0 | 27 | #define BOCA_FLAGS 0 |
28 | #define HUB6_FLAGS 0 | 28 | #define HUB6_FLAGS 0 |
diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c index 70cb408bc20d..c54505dcf4db 100644 --- a/arch/xtensa/platforms/iss/console.c +++ b/arch/xtensa/platforms/iss/console.c | |||
@@ -28,10 +28,6 @@ | |||
28 | #include <linux/tty.h> | 28 | #include <linux/tty.h> |
29 | #include <linux/tty_flip.h> | 29 | #include <linux/tty_flip.h> |
30 | 30 | ||
31 | #ifdef SERIAL_INLINE | ||
32 | #define _INLINE_ inline | ||
33 | #endif | ||
34 | |||
35 | #define SERIAL_MAX_NUM_LINES 1 | 31 | #define SERIAL_MAX_NUM_LINES 1 |
36 | #define SERIAL_TIMER_VALUE (HZ / 10) | 32 | #define SERIAL_TIMER_VALUE (HZ / 10) |
37 | 33 | ||
diff --git a/arch/xtensa/platforms/xt2000/setup.c b/arch/xtensa/platforms/xt2000/setup.c index 87678961a8c8..5f4bd71971d6 100644 --- a/arch/xtensa/platforms/xt2000/setup.c +++ b/arch/xtensa/platforms/xt2000/setup.c | |||
@@ -113,7 +113,7 @@ void platform_heartbeat(void) | |||
113 | } | 113 | } |
114 | 114 | ||
115 | //#define RS_TABLE_SIZE 2 | 115 | //#define RS_TABLE_SIZE 2 |
116 | //#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST) | 116 | //#define STD_COM_FLAGS (UPF_BOOT_AUTOCONF|UPF_SKIP_TEST) |
117 | 117 | ||
118 | #define _SERIAL_PORT(_base,_irq) \ | 118 | #define _SERIAL_PORT(_base,_irq) \ |
119 | { \ | 119 | { \ |
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 45df4bf914f8..22c27652e46a 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c | |||
@@ -1349,7 +1349,7 @@ static void shutdown(MGSLPC_INFO * info, struct tty_struct *tty) | |||
1349 | /* TODO:disable interrupts instead of reset to preserve signal states */ | 1349 | /* TODO:disable interrupts instead of reset to preserve signal states */ |
1350 | reset_device(info); | 1350 | reset_device(info); |
1351 | 1351 | ||
1352 | if (!tty || tty->termios.c_cflag & HUPCL) { | 1352 | if (!tty || C_HUPCL(tty)) { |
1353 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); | 1353 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
1354 | set_signals(info); | 1354 | set_signals(info); |
1355 | } | 1355 | } |
@@ -1390,7 +1390,7 @@ static void mgslpc_program_hw(MGSLPC_INFO *info, struct tty_struct *tty) | |||
1390 | port_irq_enable(info, (unsigned char) PVR_DSR | PVR_RI); | 1390 | port_irq_enable(info, (unsigned char) PVR_DSR | PVR_RI); |
1391 | get_signals(info); | 1391 | get_signals(info); |
1392 | 1392 | ||
1393 | if (info->netcount || (tty && (tty->termios.c_cflag & CREAD))) | 1393 | if (info->netcount || (tty && C_CREAD(tty))) |
1394 | rx_start(info); | 1394 | rx_start(info); |
1395 | 1395 | ||
1396 | spin_unlock_irqrestore(&info->lock, flags); | 1396 | spin_unlock_irqrestore(&info->lock, flags); |
@@ -1733,7 +1733,7 @@ static void mgslpc_throttle(struct tty_struct * tty) | |||
1733 | if (I_IXOFF(tty)) | 1733 | if (I_IXOFF(tty)) |
1734 | mgslpc_send_xchar(tty, STOP_CHAR(tty)); | 1734 | mgslpc_send_xchar(tty, STOP_CHAR(tty)); |
1735 | 1735 | ||
1736 | if (tty->termios.c_cflag & CRTSCTS) { | 1736 | if (C_CRTSCTS(tty)) { |
1737 | spin_lock_irqsave(&info->lock, flags); | 1737 | spin_lock_irqsave(&info->lock, flags); |
1738 | info->serial_signals &= ~SerialSignal_RTS; | 1738 | info->serial_signals &= ~SerialSignal_RTS; |
1739 | set_signals(info); | 1739 | set_signals(info); |
@@ -1762,7 +1762,7 @@ static void mgslpc_unthrottle(struct tty_struct * tty) | |||
1762 | mgslpc_send_xchar(tty, START_CHAR(tty)); | 1762 | mgslpc_send_xchar(tty, START_CHAR(tty)); |
1763 | } | 1763 | } |
1764 | 1764 | ||
1765 | if (tty->termios.c_cflag & CRTSCTS) { | 1765 | if (C_CRTSCTS(tty)) { |
1766 | spin_lock_irqsave(&info->lock, flags); | 1766 | spin_lock_irqsave(&info->lock, flags); |
1767 | info->serial_signals |= SerialSignal_RTS; | 1767 | info->serial_signals |= SerialSignal_RTS; |
1768 | set_signals(info); | 1768 | set_signals(info); |
@@ -2306,8 +2306,7 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term | |||
2306 | mgslpc_change_params(info, tty); | 2306 | mgslpc_change_params(info, tty); |
2307 | 2307 | ||
2308 | /* Handle transition to B0 status */ | 2308 | /* Handle transition to B0 status */ |
2309 | if (old_termios->c_cflag & CBAUD && | 2309 | if ((old_termios->c_cflag & CBAUD) && !C_BAUD(tty)) { |
2310 | !(tty->termios.c_cflag & CBAUD)) { | ||
2311 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); | 2310 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
2312 | spin_lock_irqsave(&info->lock, flags); | 2311 | spin_lock_irqsave(&info->lock, flags); |
2313 | set_signals(info); | 2312 | set_signals(info); |
@@ -2315,21 +2314,17 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term | |||
2315 | } | 2314 | } |
2316 | 2315 | ||
2317 | /* Handle transition away from B0 status */ | 2316 | /* Handle transition away from B0 status */ |
2318 | if (!(old_termios->c_cflag & CBAUD) && | 2317 | if (!(old_termios->c_cflag & CBAUD) && C_BAUD(tty)) { |
2319 | tty->termios.c_cflag & CBAUD) { | ||
2320 | info->serial_signals |= SerialSignal_DTR; | 2318 | info->serial_signals |= SerialSignal_DTR; |
2321 | if (!(tty->termios.c_cflag & CRTSCTS) || | 2319 | if (!C_CRTSCTS(tty) || !test_bit(TTY_THROTTLED, &tty->flags)) |
2322 | !test_bit(TTY_THROTTLED, &tty->flags)) { | ||
2323 | info->serial_signals |= SerialSignal_RTS; | 2320 | info->serial_signals |= SerialSignal_RTS; |
2324 | } | ||
2325 | spin_lock_irqsave(&info->lock, flags); | 2321 | spin_lock_irqsave(&info->lock, flags); |
2326 | set_signals(info); | 2322 | set_signals(info); |
2327 | spin_unlock_irqrestore(&info->lock, flags); | 2323 | spin_unlock_irqrestore(&info->lock, flags); |
2328 | } | 2324 | } |
2329 | 2325 | ||
2330 | /* Handle turning off CRTSCTS */ | 2326 | /* Handle turning off CRTSCTS */ |
2331 | if (old_termios->c_cflag & CRTSCTS && | 2327 | if (old_termios->c_cflag & CRTSCTS && !C_CRTSCTS(tty)) { |
2332 | !(tty->termios.c_cflag & CRTSCTS)) { | ||
2333 | tty->hw_stopped = 0; | 2328 | tty->hw_stopped = 0; |
2334 | tx_release(tty); | 2329 | tx_release(tty); |
2335 | } | 2330 | } |
diff --git a/drivers/char/ttyprintk.c b/drivers/char/ttyprintk.c index a15ce4ef39cd..b098d2d0b7c4 100644 --- a/drivers/char/ttyprintk.c +++ b/drivers/char/ttyprintk.c | |||
@@ -171,7 +171,7 @@ static const struct tty_operations ttyprintk_ops = { | |||
171 | .ioctl = tpk_ioctl, | 171 | .ioctl = tpk_ioctl, |
172 | }; | 172 | }; |
173 | 173 | ||
174 | static struct tty_port_operations null_ops = { }; | 174 | static const struct tty_port_operations null_ops = { }; |
175 | 175 | ||
176 | static struct tty_driver *ttyprintk_driver; | 176 | static struct tty_driver *ttyprintk_driver; |
177 | 177 | ||
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 2175225af742..947d5c978b8f 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c | |||
@@ -1572,7 +1572,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp) | |||
1572 | #endif | 1572 | #endif |
1573 | return; | 1573 | return; |
1574 | } | 1574 | } |
1575 | port->flags |= ASYNC_CLOSING; | 1575 | info->closing = 1; |
1576 | 1576 | ||
1577 | tty->closing = 1; | 1577 | tty->closing = 1; |
1578 | /* | 1578 | /* |
@@ -1603,6 +1603,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp) | |||
1603 | info->ncarrier = 0; | 1603 | info->ncarrier = 0; |
1604 | 1604 | ||
1605 | tty_port_close_end(port, tty); | 1605 | tty_port_close_end(port, tty); |
1606 | info->closing = 0; | ||
1606 | #ifdef ISDN_DEBUG_MODEM_OPEN | 1607 | #ifdef ISDN_DEBUG_MODEM_OPEN |
1607 | printk(KERN_DEBUG "isdn_tty_close normal exit\n"); | 1608 | printk(KERN_DEBUG "isdn_tty_close normal exit\n"); |
1608 | #endif | 1609 | #endif |
@@ -2236,7 +2237,7 @@ isdn_tty_at_cout(char *msg, modem_info *info) | |||
2236 | l = strlen(msg); | 2237 | l = strlen(msg); |
2237 | 2238 | ||
2238 | spin_lock_irqsave(&info->readlock, flags); | 2239 | spin_lock_irqsave(&info->readlock, flags); |
2239 | if (port->flags & ASYNC_CLOSING) { | 2240 | if (info->closing) { |
2240 | spin_unlock_irqrestore(&info->readlock, flags); | 2241 | spin_unlock_irqrestore(&info->readlock, flags); |
2241 | return; | 2242 | return; |
2242 | } | 2243 | } |
@@ -2386,13 +2387,12 @@ isdn_tty_modem_result(int code, modem_info *info) | |||
2386 | case RESULT_NO_CARRIER: | 2387 | case RESULT_NO_CARRIER: |
2387 | #ifdef ISDN_DEBUG_MODEM_HUP | 2388 | #ifdef ISDN_DEBUG_MODEM_HUP |
2388 | printk(KERN_DEBUG "modem_result: NO CARRIER %d %d\n", | 2389 | printk(KERN_DEBUG "modem_result: NO CARRIER %d %d\n", |
2389 | (info->port.flags & ASYNC_CLOSING), | 2390 | info->closing, !info->port.tty); |
2390 | (!info->port.tty)); | ||
2391 | #endif | 2391 | #endif |
2392 | m->mdmreg[REG_RINGCNT] = 0; | 2392 | m->mdmreg[REG_RINGCNT] = 0; |
2393 | del_timer(&info->nc_timer); | 2393 | del_timer(&info->nc_timer); |
2394 | info->ncarrier = 0; | 2394 | info->ncarrier = 0; |
2395 | if ((info->port.flags & ASYNC_CLOSING) || (!info->port.tty)) | 2395 | if (info->closing || !info->port.tty) |
2396 | return; | 2396 | return; |
2397 | 2397 | ||
2398 | #ifdef CONFIG_ISDN_AUDIO | 2398 | #ifdef CONFIG_ISDN_AUDIO |
@@ -2525,7 +2525,7 @@ isdn_tty_modem_result(int code, modem_info *info) | |||
2525 | } | 2525 | } |
2526 | } | 2526 | } |
2527 | if (code == RESULT_NO_CARRIER) { | 2527 | if (code == RESULT_NO_CARRIER) { |
2528 | if ((info->port.flags & ASYNC_CLOSING) || (!info->port.tty)) | 2528 | if (info->closing || (!info->port.tty)) |
2529 | return; | 2529 | return; |
2530 | 2530 | ||
2531 | if (info->port.flags & ASYNC_CHECK_CD) | 2531 | if (info->port.flags & ASYNC_CHECK_CD) |
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c index d2de5925b73e..5415056f9aa5 100644 --- a/drivers/mmc/card/sdio_uart.c +++ b/drivers/mmc/card/sdio_uart.c | |||
@@ -493,7 +493,7 @@ static void sdio_uart_check_modem_status(struct sdio_uart_port *port) | |||
493 | if (status & UART_MSR_DCTS) { | 493 | if (status & UART_MSR_DCTS) { |
494 | port->icount.cts++; | 494 | port->icount.cts++; |
495 | tty = tty_port_tty_get(&port->port); | 495 | tty = tty_port_tty_get(&port->port); |
496 | if (tty && (tty->termios.c_cflag & CRTSCTS)) { | 496 | if (tty && C_CRTSCTS(tty)) { |
497 | int cts = (status & UART_MSR_CTS); | 497 | int cts = (status & UART_MSR_CTS); |
498 | if (tty->hw_stopped) { | 498 | if (tty->hw_stopped) { |
499 | if (cts) { | 499 | if (cts) { |
@@ -648,10 +648,10 @@ static int sdio_uart_activate(struct tty_port *tport, struct tty_struct *tty) | |||
648 | 648 | ||
649 | sdio_uart_change_speed(port, &tty->termios, NULL); | 649 | sdio_uart_change_speed(port, &tty->termios, NULL); |
650 | 650 | ||
651 | if (tty->termios.c_cflag & CBAUD) | 651 | if (C_BAUD(tty)) |
652 | sdio_uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR); | 652 | sdio_uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR); |
653 | 653 | ||
654 | if (tty->termios.c_cflag & CRTSCTS) | 654 | if (C_CRTSCTS(tty)) |
655 | if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS)) | 655 | if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS)) |
656 | tty->hw_stopped = 1; | 656 | tty->hw_stopped = 1; |
657 | 657 | ||
@@ -833,7 +833,7 @@ static void sdio_uart_throttle(struct tty_struct *tty) | |||
833 | { | 833 | { |
834 | struct sdio_uart_port *port = tty->driver_data; | 834 | struct sdio_uart_port *port = tty->driver_data; |
835 | 835 | ||
836 | if (!I_IXOFF(tty) && !(tty->termios.c_cflag & CRTSCTS)) | 836 | if (!I_IXOFF(tty) && !C_CRTSCTS(tty)) |
837 | return; | 837 | return; |
838 | 838 | ||
839 | if (sdio_uart_claim_func(port) != 0) | 839 | if (sdio_uart_claim_func(port) != 0) |
@@ -844,7 +844,7 @@ static void sdio_uart_throttle(struct tty_struct *tty) | |||
844 | sdio_uart_start_tx(port); | 844 | sdio_uart_start_tx(port); |
845 | } | 845 | } |
846 | 846 | ||
847 | if (tty->termios.c_cflag & CRTSCTS) | 847 | if (C_CRTSCTS(tty)) |
848 | sdio_uart_clear_mctrl(port, TIOCM_RTS); | 848 | sdio_uart_clear_mctrl(port, TIOCM_RTS); |
849 | 849 | ||
850 | sdio_uart_irq(port->func); | 850 | sdio_uart_irq(port->func); |
@@ -855,7 +855,7 @@ static void sdio_uart_unthrottle(struct tty_struct *tty) | |||
855 | { | 855 | { |
856 | struct sdio_uart_port *port = tty->driver_data; | 856 | struct sdio_uart_port *port = tty->driver_data; |
857 | 857 | ||
858 | if (!I_IXOFF(tty) && !(tty->termios.c_cflag & CRTSCTS)) | 858 | if (!I_IXOFF(tty) && !C_CRTSCTS(tty)) |
859 | return; | 859 | return; |
860 | 860 | ||
861 | if (sdio_uart_claim_func(port) != 0) | 861 | if (sdio_uart_claim_func(port) != 0) |
@@ -870,7 +870,7 @@ static void sdio_uart_unthrottle(struct tty_struct *tty) | |||
870 | } | 870 | } |
871 | } | 871 | } |
872 | 872 | ||
873 | if (tty->termios.c_cflag & CRTSCTS) | 873 | if (C_CRTSCTS(tty)) |
874 | sdio_uart_set_mctrl(port, TIOCM_RTS); | 874 | sdio_uart_set_mctrl(port, TIOCM_RTS); |
875 | 875 | ||
876 | sdio_uart_irq(port->func); | 876 | sdio_uart_irq(port->func); |
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c index 696852eb23c3..7a3f990c1935 100644 --- a/drivers/net/irda/irtty-sir.c +++ b/drivers/net/irda/irtty-sir.c | |||
@@ -430,16 +430,6 @@ static int irtty_open(struct tty_struct *tty) | |||
430 | 430 | ||
431 | /* Module stuff handled via irda_ldisc.owner - Jean II */ | 431 | /* Module stuff handled via irda_ldisc.owner - Jean II */ |
432 | 432 | ||
433 | /* First make sure we're not already connected. */ | ||
434 | if (tty->disc_data != NULL) { | ||
435 | priv = tty->disc_data; | ||
436 | if (priv && priv->magic == IRTTY_MAGIC) { | ||
437 | ret = -EEXIST; | ||
438 | goto out; | ||
439 | } | ||
440 | tty->disc_data = NULL; /* ### */ | ||
441 | } | ||
442 | |||
443 | /* stop the underlying driver */ | 433 | /* stop the underlying driver */ |
444 | irtty_stop_receiver(tty, TRUE); | 434 | irtty_stop_receiver(tty, TRUE); |
445 | if (tty->ops->stop) | 435 | if (tty->ops->stop) |
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 655f79db7899..e2295b2c9836 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c | |||
@@ -796,14 +796,13 @@ static inline void early_init_dt_check_for_initrd(unsigned long node) | |||
796 | #endif /* CONFIG_BLK_DEV_INITRD */ | 796 | #endif /* CONFIG_BLK_DEV_INITRD */ |
797 | 797 | ||
798 | #ifdef CONFIG_SERIAL_EARLYCON | 798 | #ifdef CONFIG_SERIAL_EARLYCON |
799 | extern struct of_device_id __earlycon_of_table[]; | ||
800 | 799 | ||
801 | static int __init early_init_dt_scan_chosen_serial(void) | 800 | static int __init early_init_dt_scan_chosen_serial(void) |
802 | { | 801 | { |
803 | int offset; | 802 | int offset; |
804 | const char *p; | 803 | const char *p, *q, *options = NULL; |
805 | int l; | 804 | int l; |
806 | const struct of_device_id *match = __earlycon_of_table; | 805 | const struct earlycon_id *match; |
807 | const void *fdt = initial_boot_params; | 806 | const void *fdt = initial_boot_params; |
808 | 807 | ||
809 | offset = fdt_path_offset(fdt, "/chosen"); | 808 | offset = fdt_path_offset(fdt, "/chosen"); |
@@ -818,27 +817,26 @@ static int __init early_init_dt_scan_chosen_serial(void) | |||
818 | if (!p || !l) | 817 | if (!p || !l) |
819 | return -ENOENT; | 818 | return -ENOENT; |
820 | 819 | ||
821 | /* Remove console options if present */ | 820 | q = strchrnul(p, ':'); |
822 | l = strchrnul(p, ':') - p; | 821 | if (*q != '\0') |
822 | options = q + 1; | ||
823 | l = q - p; | ||
823 | 824 | ||
824 | /* Get the node specified by stdout-path */ | 825 | /* Get the node specified by stdout-path */ |
825 | offset = fdt_path_offset_namelen(fdt, p, l); | 826 | offset = fdt_path_offset_namelen(fdt, p, l); |
826 | if (offset < 0) | 827 | if (offset < 0) { |
827 | return -ENODEV; | 828 | pr_warn("earlycon: stdout-path %.*s not found\n", l, p); |
828 | 829 | return 0; | |
829 | while (match->compatible[0]) { | 830 | } |
830 | u64 addr; | ||
831 | 831 | ||
832 | if (fdt_node_check_compatible(fdt, offset, match->compatible)) { | 832 | for (match = __earlycon_table; match < __earlycon_table_end; match++) { |
833 | match++; | 833 | if (!match->compatible[0]) |
834 | continue; | 834 | continue; |
835 | } | ||
836 | 835 | ||
837 | addr = fdt_translate_address(fdt, offset); | 836 | if (fdt_node_check_compatible(fdt, offset, match->compatible)) |
838 | if (addr == OF_BAD_ADDR) | 837 | continue; |
839 | return -ENXIO; | ||
840 | 838 | ||
841 | of_setup_earlycon(addr, match->data); | 839 | of_setup_earlycon(match, offset, options); |
842 | return 0; | 840 | return 0; |
843 | } | 841 | } |
844 | return -ENODEV; | 842 | return -ENODEV; |
diff --git a/drivers/of/fdt_address.c b/drivers/of/fdt_address.c index 8d3dc6fbdb7a..dca8f9b93745 100644 --- a/drivers/of/fdt_address.c +++ b/drivers/of/fdt_address.c | |||
@@ -161,7 +161,7 @@ static int __init fdt_translate_one(const void *blob, int parent, | |||
161 | * that can be mapped to a cpu physical address). This is not really specified | 161 | * that can be mapped to a cpu physical address). This is not really specified |
162 | * that way, but this is traditionally the way IBM at least do things | 162 | * that way, but this is traditionally the way IBM at least do things |
163 | */ | 163 | */ |
164 | u64 __init fdt_translate_address(const void *blob, int node_offset) | 164 | static u64 __init fdt_translate_address(const void *blob, int node_offset) |
165 | { | 165 | { |
166 | int parent, len; | 166 | int parent, len; |
167 | const struct of_bus *bus, *pbus; | 167 | const struct of_bus *bus, *pbus; |
@@ -239,3 +239,12 @@ u64 __init fdt_translate_address(const void *blob, int node_offset) | |||
239 | bail: | 239 | bail: |
240 | return result; | 240 | return result; |
241 | } | 241 | } |
242 | |||
243 | /** | ||
244 | * of_flat_dt_translate_address - translate DT addr into CPU phys addr | ||
245 | * @node: node in the flat blob | ||
246 | */ | ||
247 | u64 __init of_flat_dt_translate_address(unsigned long node) | ||
248 | { | ||
249 | return fdt_translate_address(initial_boot_params, node); | ||
250 | } | ||
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 7d82bbcb12df..e7e078b3c7e6 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c | |||
@@ -643,7 +643,6 @@ static void raw3215_shutdown(struct raw3215_info *raw) | |||
643 | if ((raw->flags & RAW3215_WORKING) || | 643 | if ((raw->flags & RAW3215_WORKING) || |
644 | raw->queued_write != NULL || | 644 | raw->queued_write != NULL || |
645 | raw->queued_read != NULL) { | 645 | raw->queued_read != NULL) { |
646 | raw->port.flags |= ASYNC_CLOSING; | ||
647 | add_wait_queue(&raw->empty_wait, &wait); | 646 | add_wait_queue(&raw->empty_wait, &wait); |
648 | set_current_state(TASK_INTERRUPTIBLE); | 647 | set_current_state(TASK_INTERRUPTIBLE); |
649 | spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); | 648 | spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); |
@@ -651,7 +650,7 @@ static void raw3215_shutdown(struct raw3215_info *raw) | |||
651 | spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); | 650 | spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); |
652 | remove_wait_queue(&raw->empty_wait, &wait); | 651 | remove_wait_queue(&raw->empty_wait, &wait); |
653 | set_current_state(TASK_RUNNING); | 652 | set_current_state(TASK_RUNNING); |
654 | raw->port.flags &= ~(ASYNC_INITIALIZED | ASYNC_CLOSING); | 653 | raw->port.flags &= ~ASYNC_INITIALIZED; |
655 | } | 654 | } |
656 | spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); | 655 | spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); |
657 | } | 656 | } |
diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c index bad355100825..294c1c83aa4d 100644 --- a/drivers/staging/dgap/dgap.c +++ b/drivers/staging/dgap/dgap.c | |||
@@ -1530,7 +1530,7 @@ static void dgap_input(struct channel_t *ch) | |||
1530 | if ((bd->state != BOARD_READY) || !tp || | 1530 | if ((bd->state != BOARD_READY) || !tp || |
1531 | (tp->magic != TTY_MAGIC) || | 1531 | (tp->magic != TTY_MAGIC) || |
1532 | !(ch->ch_tun.un_flags & UN_ISOPEN) || | 1532 | !(ch->ch_tun.un_flags & UN_ISOPEN) || |
1533 | !(tp->termios.c_cflag & CREAD) || | 1533 | !C_CREAD(tp) || |
1534 | (ch->ch_tun.un_flags & UN_CLOSING)) { | 1534 | (ch->ch_tun.un_flags & UN_CLOSING)) { |
1535 | writew(head, &bs->rx_tail); | 1535 | writew(head, &bs->rx_tail); |
1536 | writeb(1, &bs->idata); | 1536 | writeb(1, &bs->idata); |
@@ -1665,9 +1665,7 @@ static void dgap_input(struct channel_t *ch) | |||
1665 | } | 1665 | } |
1666 | 1666 | ||
1667 | static void dgap_write_wakeup(struct board_t *bd, struct channel_t *ch, | 1667 | static void dgap_write_wakeup(struct board_t *bd, struct channel_t *ch, |
1668 | struct un_t *un, u32 mask, | 1668 | struct un_t *un, u32 mask) |
1669 | unsigned long *irq_flags1, | ||
1670 | unsigned long *irq_flags2) | ||
1671 | { | 1669 | { |
1672 | if (!(un->un_flags & mask)) | 1670 | if (!(un->un_flags & mask)) |
1673 | return; | 1671 | return; |
@@ -1677,17 +1675,7 @@ static void dgap_write_wakeup(struct board_t *bd, struct channel_t *ch, | |||
1677 | if (!(un->un_flags & UN_ISOPEN)) | 1675 | if (!(un->un_flags & UN_ISOPEN)) |
1678 | return; | 1676 | return; |
1679 | 1677 | ||
1680 | if ((un->un_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && | 1678 | tty_wakeup(un->un_tty); |
1681 | un->un_tty->ldisc->ops->write_wakeup) { | ||
1682 | spin_unlock_irqrestore(&ch->ch_lock, *irq_flags2); | ||
1683 | spin_unlock_irqrestore(&bd->bd_lock, *irq_flags1); | ||
1684 | |||
1685 | (un->un_tty->ldisc->ops->write_wakeup)(un->un_tty); | ||
1686 | |||
1687 | spin_lock_irqsave(&bd->bd_lock, *irq_flags1); | ||
1688 | spin_lock_irqsave(&ch->ch_lock, *irq_flags2); | ||
1689 | } | ||
1690 | wake_up_interruptible(&un->un_tty->write_wait); | ||
1691 | wake_up_interruptible(&un->un_flags_wait); | 1679 | wake_up_interruptible(&un->un_flags_wait); |
1692 | } | 1680 | } |
1693 | 1681 | ||
@@ -1952,10 +1940,8 @@ static int dgap_event(struct board_t *bd) | |||
1952 | * Process Transmit low. | 1940 | * Process Transmit low. |
1953 | */ | 1941 | */ |
1954 | if (reason & IFTLW) { | 1942 | if (reason & IFTLW) { |
1955 | dgap_write_wakeup(bd, ch, &ch->ch_tun, UN_LOW, | 1943 | dgap_write_wakeup(bd, ch, &ch->ch_tun, UN_LOW); |
1956 | &lock_flags, &lock_flags2); | 1944 | dgap_write_wakeup(bd, ch, &ch->ch_pun, UN_LOW); |
1957 | dgap_write_wakeup(bd, ch, &ch->ch_pun, UN_LOW, | ||
1958 | &lock_flags, &lock_flags2); | ||
1959 | if (ch->ch_flags & CH_WLOW) { | 1945 | if (ch->ch_flags & CH_WLOW) { |
1960 | ch->ch_flags &= ~CH_WLOW; | 1946 | ch->ch_flags &= ~CH_WLOW; |
1961 | wake_up_interruptible(&ch->ch_flags_wait); | 1947 | wake_up_interruptible(&ch->ch_flags_wait); |
@@ -1966,10 +1952,8 @@ static int dgap_event(struct board_t *bd) | |||
1966 | * Process Transmit empty. | 1952 | * Process Transmit empty. |
1967 | */ | 1953 | */ |
1968 | if (reason & IFTEM) { | 1954 | if (reason & IFTEM) { |
1969 | dgap_write_wakeup(bd, ch, &ch->ch_tun, UN_EMPTY, | 1955 | dgap_write_wakeup(bd, ch, &ch->ch_tun, UN_EMPTY); |
1970 | &lock_flags, &lock_flags2); | 1956 | dgap_write_wakeup(bd, ch, &ch->ch_pun, UN_EMPTY); |
1971 | dgap_write_wakeup(bd, ch, &ch->ch_pun, UN_EMPTY, | ||
1972 | &lock_flags, &lock_flags2); | ||
1973 | if (ch->ch_flags & CH_WEMPTY) { | 1957 | if (ch->ch_flags & CH_WEMPTY) { |
1974 | ch->ch_flags &= ~CH_WEMPTY; | 1958 | ch->ch_flags &= ~CH_WEMPTY; |
1975 | wake_up_interruptible(&ch->ch_flags_wait); | 1959 | wake_up_interruptible(&ch->ch_flags_wait); |
@@ -3171,8 +3155,6 @@ static void dgap_tty_flush_buffer(struct tty_struct *tty) | |||
3171 | 3155 | ||
3172 | spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); | 3156 | spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); |
3173 | spin_unlock_irqrestore(&bd->bd_lock, lock_flags); | 3157 | spin_unlock_irqrestore(&bd->bd_lock, lock_flags); |
3174 | if (waitqueue_active(&tty->write_wait)) | ||
3175 | wake_up_interruptible(&tty->write_wait); | ||
3176 | tty_wakeup(tty); | 3158 | tty_wakeup(tty); |
3177 | } | 3159 | } |
3178 | 3160 | ||
@@ -4969,10 +4951,6 @@ static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd, | |||
4969 | ch->ch_pun.un_flags &= ~(UN_LOW | UN_EMPTY); | 4951 | ch->ch_pun.un_flags &= ~(UN_LOW | UN_EMPTY); |
4970 | wake_up_interruptible(&ch->ch_pun.un_flags_wait); | 4952 | wake_up_interruptible(&ch->ch_pun.un_flags_wait); |
4971 | } | 4953 | } |
4972 | if (waitqueue_active(&tty->write_wait)) | ||
4973 | wake_up_interruptible(&tty->write_wait); | ||
4974 | |||
4975 | /* Can't hold any locks when calling tty_wakeup! */ | ||
4976 | spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); | 4954 | spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); |
4977 | spin_unlock_irqrestore(&bd->bd_lock, lock_flags); | 4955 | spin_unlock_irqrestore(&bd->bd_lock, lock_flags); |
4978 | tty_wakeup(tty); | 4956 | tty_wakeup(tty); |
diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index b79eab084c02..8b1ba65a6984 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c | |||
@@ -541,7 +541,7 @@ void dgnc_input(struct channel_t *ch) | |||
541 | */ | 541 | */ |
542 | if (!tp || (tp->magic != TTY_MAGIC) || | 542 | if (!tp || (tp->magic != TTY_MAGIC) || |
543 | !(ch->ch_tun.un_flags & UN_ISOPEN) || | 543 | !(ch->ch_tun.un_flags & UN_ISOPEN) || |
544 | !(tp->termios.c_cflag & CREAD) || | 544 | !C_CREAD(tp) || |
545 | (ch->ch_tun.un_flags & UN_CLOSING)) { | 545 | (ch->ch_tun.un_flags & UN_CLOSING)) { |
546 | ch->ch_r_head = tail; | 546 | ch->ch_r_head = tail; |
547 | 547 | ||
@@ -933,14 +933,7 @@ void dgnc_wakeup_writes(struct channel_t *ch) | |||
933 | } | 933 | } |
934 | 934 | ||
935 | if (ch->ch_tun.un_flags & UN_ISOPEN) { | 935 | if (ch->ch_tun.un_flags & UN_ISOPEN) { |
936 | if ((ch->ch_tun.un_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && | 936 | tty_wakeup(ch->ch_tun.un_tty); |
937 | ch->ch_tun.un_tty->ldisc->ops->write_wakeup) { | ||
938 | spin_unlock_irqrestore(&ch->ch_lock, flags); | ||
939 | ch->ch_tun.un_tty->ldisc->ops->write_wakeup(ch->ch_tun.un_tty); | ||
940 | spin_lock_irqsave(&ch->ch_lock, flags); | ||
941 | } | ||
942 | |||
943 | wake_up_interruptible(&ch->ch_tun.un_tty->write_wait); | ||
944 | 937 | ||
945 | /* | 938 | /* |
946 | * If unit is set to wait until empty, check to make sure | 939 | * If unit is set to wait until empty, check to make sure |
@@ -975,14 +968,7 @@ void dgnc_wakeup_writes(struct channel_t *ch) | |||
975 | } | 968 | } |
976 | 969 | ||
977 | if (ch->ch_pun.un_flags & UN_ISOPEN) { | 970 | if (ch->ch_pun.un_flags & UN_ISOPEN) { |
978 | if ((ch->ch_pun.un_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && | 971 | tty_wakeup(ch->ch_pun.un_tty); |
979 | ch->ch_pun.un_tty->ldisc->ops->write_wakeup) { | ||
980 | spin_unlock_irqrestore(&ch->ch_lock, flags); | ||
981 | ch->ch_pun.un_tty->ldisc->ops->write_wakeup(ch->ch_pun.un_tty); | ||
982 | spin_lock_irqsave(&ch->ch_lock, flags); | ||
983 | } | ||
984 | |||
985 | wake_up_interruptible(&ch->ch_pun.un_tty->write_wait); | ||
986 | 972 | ||
987 | /* | 973 | /* |
988 | * If unit is set to wait until empty, check to make sure | 974 | * If unit is set to wait until empty, check to make sure |
diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig index c01f45095877..82c4d2e45319 100644 --- a/drivers/tty/Kconfig +++ b/drivers/tty/Kconfig | |||
@@ -226,7 +226,7 @@ config CYCLADES | |||
226 | 226 | ||
227 | config CYZ_INTR | 227 | config CYZ_INTR |
228 | bool "Cyclades-Z interrupt mode operation" | 228 | bool "Cyclades-Z interrupt mode operation" |
229 | depends on CYCLADES | 229 | depends on CYCLADES && PCI |
230 | help | 230 | help |
231 | The Cyclades-Z family of multiport cards allows 2 (two) driver op | 231 | The Cyclades-Z family of multiport cards allows 2 (two) driver op |
232 | modes: polling and interrupt. In polling mode, the driver will check | 232 | modes: polling and interrupt. In polling mode, the driver will check |
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 2caaf5a2516d..eacf4c9f3b29 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c | |||
@@ -639,7 +639,7 @@ static void shutdown(struct tty_struct *tty, struct serial_state *info) | |||
639 | custom.adkcon = AC_UARTBRK; | 639 | custom.adkcon = AC_UARTBRK; |
640 | mb(); | 640 | mb(); |
641 | 641 | ||
642 | if (tty->termios.c_cflag & HUPCL) | 642 | if (C_HUPCL(tty)) |
643 | info->MCR &= ~(SER_DTR|SER_RTS); | 643 | info->MCR &= ~(SER_DTR|SER_RTS); |
644 | rtsdtr_ctrl(info->MCR); | 644 | rtsdtr_ctrl(info->MCR); |
645 | 645 | ||
@@ -965,8 +965,7 @@ static void rs_throttle(struct tty_struct * tty) | |||
965 | struct serial_state *info = tty->driver_data; | 965 | struct serial_state *info = tty->driver_data; |
966 | unsigned long flags; | 966 | unsigned long flags; |
967 | #ifdef SERIAL_DEBUG_THROTTLE | 967 | #ifdef SERIAL_DEBUG_THROTTLE |
968 | printk("throttle %s: %d....\n", tty_name(tty), | 968 | printk("throttle %s ....\n", tty_name(tty)); |
969 | tty->ldisc.chars_in_buffer(tty)); | ||
970 | #endif | 969 | #endif |
971 | 970 | ||
972 | if (serial_paranoia_check(info, tty->name, "rs_throttle")) | 971 | if (serial_paranoia_check(info, tty->name, "rs_throttle")) |
@@ -975,7 +974,7 @@ static void rs_throttle(struct tty_struct * tty) | |||
975 | if (I_IXOFF(tty)) | 974 | if (I_IXOFF(tty)) |
976 | rs_send_xchar(tty, STOP_CHAR(tty)); | 975 | rs_send_xchar(tty, STOP_CHAR(tty)); |
977 | 976 | ||
978 | if (tty->termios.c_cflag & CRTSCTS) | 977 | if (C_CRTSCTS(tty)) |
979 | info->MCR &= ~SER_RTS; | 978 | info->MCR &= ~SER_RTS; |
980 | 979 | ||
981 | local_irq_save(flags); | 980 | local_irq_save(flags); |
@@ -988,8 +987,7 @@ static void rs_unthrottle(struct tty_struct * tty) | |||
988 | struct serial_state *info = tty->driver_data; | 987 | struct serial_state *info = tty->driver_data; |
989 | unsigned long flags; | 988 | unsigned long flags; |
990 | #ifdef SERIAL_DEBUG_THROTTLE | 989 | #ifdef SERIAL_DEBUG_THROTTLE |
991 | printk("unthrottle %s: %d....\n", tty_name(tty), | 990 | printk("unthrottle %s ....\n", tty_name(tty)); |
992 | tty->ldisc.chars_in_buffer(tty)); | ||
993 | #endif | 991 | #endif |
994 | 992 | ||
995 | if (serial_paranoia_check(info, tty->name, "rs_unthrottle")) | 993 | if (serial_paranoia_check(info, tty->name, "rs_unthrottle")) |
@@ -1001,7 +999,7 @@ static void rs_unthrottle(struct tty_struct * tty) | |||
1001 | else | 999 | else |
1002 | rs_send_xchar(tty, START_CHAR(tty)); | 1000 | rs_send_xchar(tty, START_CHAR(tty)); |
1003 | } | 1001 | } |
1004 | if (tty->termios.c_cflag & CRTSCTS) | 1002 | if (C_CRTSCTS(tty)) |
1005 | info->MCR |= SER_RTS; | 1003 | info->MCR |= SER_RTS; |
1006 | local_irq_save(flags); | 1004 | local_irq_save(flags); |
1007 | rtsdtr_ctrl(info->MCR); | 1005 | rtsdtr_ctrl(info->MCR); |
@@ -1334,8 +1332,7 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
1334 | change_speed(tty, info, old_termios); | 1332 | change_speed(tty, info, old_termios); |
1335 | 1333 | ||
1336 | /* Handle transition to B0 status */ | 1334 | /* Handle transition to B0 status */ |
1337 | if ((old_termios->c_cflag & CBAUD) && | 1335 | if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD)) { |
1338 | !(cflag & CBAUD)) { | ||
1339 | info->MCR &= ~(SER_DTR|SER_RTS); | 1336 | info->MCR &= ~(SER_DTR|SER_RTS); |
1340 | local_irq_save(flags); | 1337 | local_irq_save(flags); |
1341 | rtsdtr_ctrl(info->MCR); | 1338 | rtsdtr_ctrl(info->MCR); |
@@ -1343,21 +1340,17 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
1343 | } | 1340 | } |
1344 | 1341 | ||
1345 | /* Handle transition away from B0 status */ | 1342 | /* Handle transition away from B0 status */ |
1346 | if (!(old_termios->c_cflag & CBAUD) && | 1343 | if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { |
1347 | (cflag & CBAUD)) { | ||
1348 | info->MCR |= SER_DTR; | 1344 | info->MCR |= SER_DTR; |
1349 | if (!(tty->termios.c_cflag & CRTSCTS) || | 1345 | if (!C_CRTSCTS(tty) || !test_bit(TTY_THROTTLED, &tty->flags)) |
1350 | !test_bit(TTY_THROTTLED, &tty->flags)) { | ||
1351 | info->MCR |= SER_RTS; | 1346 | info->MCR |= SER_RTS; |
1352 | } | ||
1353 | local_irq_save(flags); | 1347 | local_irq_save(flags); |
1354 | rtsdtr_ctrl(info->MCR); | 1348 | rtsdtr_ctrl(info->MCR); |
1355 | local_irq_restore(flags); | 1349 | local_irq_restore(flags); |
1356 | } | 1350 | } |
1357 | 1351 | ||
1358 | /* Handle turning off CRTSCTS */ | 1352 | /* Handle turning off CRTSCTS */ |
1359 | if ((old_termios->c_cflag & CRTSCTS) && | 1353 | if ((old_termios->c_cflag & CRTSCTS) && !C_CRTSCTS(tty)) { |
1360 | !(tty->termios.c_cflag & CRTSCTS)) { | ||
1361 | tty->hw_stopped = 0; | 1354 | tty->hw_stopped = 0; |
1362 | rs_start(tty); | 1355 | rs_start(tty); |
1363 | } | 1356 | } |
@@ -1369,8 +1362,7 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
1369 | * XXX It's not clear whether the current behavior is correct | 1362 | * XXX It's not clear whether the current behavior is correct |
1370 | * or not. Hence, this may change..... | 1363 | * or not. Hence, this may change..... |
1371 | */ | 1364 | */ |
1372 | if (!(old_termios->c_cflag & CLOCAL) && | 1365 | if (!(old_termios->c_cflag & CLOCAL) && C_CLOCAL(tty)) |
1373 | (tty->termios.c_cflag & CLOCAL)) | ||
1374 | wake_up_interruptible(&info->open_wait); | 1366 | wake_up_interruptible(&info->open_wait); |
1375 | #endif | 1367 | #endif |
1376 | } | 1368 | } |
diff --git a/drivers/tty/cyclades.c b/drivers/tty/cyclades.c index abbed201dc74..d67e542bab1c 100644 --- a/drivers/tty/cyclades.c +++ b/drivers/tty/cyclades.c | |||
@@ -1440,7 +1440,7 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty) | |||
1440 | info->port.xmit_buf = NULL; | 1440 | info->port.xmit_buf = NULL; |
1441 | free_page((unsigned long)temp); | 1441 | free_page((unsigned long)temp); |
1442 | } | 1442 | } |
1443 | if (tty->termios.c_cflag & HUPCL) | 1443 | if (C_HUPCL(tty)) |
1444 | cyy_change_rts_dtr(info, 0, TIOCM_RTS | TIOCM_DTR); | 1444 | cyy_change_rts_dtr(info, 0, TIOCM_RTS | TIOCM_DTR); |
1445 | 1445 | ||
1446 | cyy_issue_cmd(info, CyCHAN_CTL | CyDIS_RCVR); | 1446 | cyy_issue_cmd(info, CyCHAN_CTL | CyDIS_RCVR); |
@@ -1469,7 +1469,7 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty) | |||
1469 | free_page((unsigned long)temp); | 1469 | free_page((unsigned long)temp); |
1470 | } | 1470 | } |
1471 | 1471 | ||
1472 | if (tty->termios.c_cflag & HUPCL) | 1472 | if (C_HUPCL(tty)) |
1473 | tty_port_lower_dtr_rts(&info->port); | 1473 | tty_port_lower_dtr_rts(&info->port); |
1474 | 1474 | ||
1475 | set_bit(TTY_IO_ERROR, &tty->flags); | 1475 | set_bit(TTY_IO_ERROR, &tty->flags); |
@@ -2795,8 +2795,7 @@ static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
2795 | 2795 | ||
2796 | cy_set_line_char(info, tty); | 2796 | cy_set_line_char(info, tty); |
2797 | 2797 | ||
2798 | if ((old_termios->c_cflag & CRTSCTS) && | 2798 | if ((old_termios->c_cflag & CRTSCTS) && !C_CRTSCTS(tty)) { |
2799 | !(tty->termios.c_cflag & CRTSCTS)) { | ||
2800 | tty->hw_stopped = 0; | 2799 | tty->hw_stopped = 0; |
2801 | cy_start(tty); | 2800 | cy_start(tty); |
2802 | } | 2801 | } |
@@ -2807,8 +2806,7 @@ static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
2807 | * XXX It's not clear whether the current behavior is correct | 2806 | * XXX It's not clear whether the current behavior is correct |
2808 | * or not. Hence, this may change..... | 2807 | * or not. Hence, this may change..... |
2809 | */ | 2808 | */ |
2810 | if (!(old_termios->c_cflag & CLOCAL) && | 2809 | if (!(old_termios->c_cflag & CLOCAL) && C_CLOCAL(tty)) |
2811 | (tty->termios.c_cflag & CLOCAL)) | ||
2812 | wake_up_interruptible(&info->port.open_wait); | 2810 | wake_up_interruptible(&info->port.open_wait); |
2813 | #endif | 2811 | #endif |
2814 | } /* cy_set_termios */ | 2812 | } /* cy_set_termios */ |
@@ -2852,8 +2850,8 @@ static void cy_throttle(struct tty_struct *tty) | |||
2852 | unsigned long flags; | 2850 | unsigned long flags; |
2853 | 2851 | ||
2854 | #ifdef CY_DEBUG_THROTTLE | 2852 | #ifdef CY_DEBUG_THROTTLE |
2855 | printk(KERN_DEBUG "cyc:throttle %s: %ld...ttyC%d\n", tty_name(tty), | 2853 | printk(KERN_DEBUG "cyc:throttle %s ...ttyC%d\n", tty_name(tty), |
2856 | tty->ldisc.chars_in_buffer(tty), info->line); | 2854 | info->line); |
2857 | #endif | 2855 | #endif |
2858 | 2856 | ||
2859 | if (serial_paranoia_check(info, tty->name, "cy_throttle")) | 2857 | if (serial_paranoia_check(info, tty->name, "cy_throttle")) |
@@ -2868,7 +2866,7 @@ static void cy_throttle(struct tty_struct *tty) | |||
2868 | info->throttle = 1; | 2866 | info->throttle = 1; |
2869 | } | 2867 | } |
2870 | 2868 | ||
2871 | if (tty->termios.c_cflag & CRTSCTS) { | 2869 | if (C_CRTSCTS(tty)) { |
2872 | if (!cy_is_Z(card)) { | 2870 | if (!cy_is_Z(card)) { |
2873 | spin_lock_irqsave(&card->card_lock, flags); | 2871 | spin_lock_irqsave(&card->card_lock, flags); |
2874 | cyy_change_rts_dtr(info, 0, TIOCM_RTS); | 2872 | cyy_change_rts_dtr(info, 0, TIOCM_RTS); |
@@ -2891,8 +2889,8 @@ static void cy_unthrottle(struct tty_struct *tty) | |||
2891 | unsigned long flags; | 2889 | unsigned long flags; |
2892 | 2890 | ||
2893 | #ifdef CY_DEBUG_THROTTLE | 2891 | #ifdef CY_DEBUG_THROTTLE |
2894 | printk(KERN_DEBUG "cyc:unthrottle %s: %ld...ttyC%d\n", | 2892 | printk(KERN_DEBUG "cyc:unthrottle %s ...ttyC%d\n", |
2895 | tty_name(tty), tty_chars_in_buffer(tty), info->line); | 2893 | tty_name(tty), info->line); |
2896 | #endif | 2894 | #endif |
2897 | 2895 | ||
2898 | if (serial_paranoia_check(info, tty->name, "cy_unthrottle")) | 2896 | if (serial_paranoia_check(info, tty->name, "cy_unthrottle")) |
@@ -2905,7 +2903,7 @@ static void cy_unthrottle(struct tty_struct *tty) | |||
2905 | cy_send_xchar(tty, START_CHAR(tty)); | 2903 | cy_send_xchar(tty, START_CHAR(tty)); |
2906 | } | 2904 | } |
2907 | 2905 | ||
2908 | if (tty->termios.c_cflag & CRTSCTS) { | 2906 | if (C_CRTSCTS(tty)) { |
2909 | card = info->card; | 2907 | card = info->card; |
2910 | if (!cy_is_Z(card)) { | 2908 | if (!cy_is_Z(card)) { |
2911 | spin_lock_irqsave(&card->card_lock, flags); | 2909 | spin_lock_irqsave(&card->card_lock, flags); |
diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c index 342b36b9ad35..7ac9bcdf1e61 100644 --- a/drivers/tty/ehv_bytechan.c +++ b/drivers/tty/ehv_bytechan.c | |||
@@ -23,7 +23,6 @@ | |||
23 | * byte channel used for the console is designated as the default tty. | 23 | * byte channel used for the console is designated as the default tty. |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/init.h> | 26 | #include <linux/init.h> |
28 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
29 | #include <linux/err.h> | 28 | #include <linux/err.h> |
@@ -719,19 +718,6 @@ error: | |||
719 | return ret; | 718 | return ret; |
720 | } | 719 | } |
721 | 720 | ||
722 | static int ehv_bc_tty_remove(struct platform_device *pdev) | ||
723 | { | ||
724 | struct ehv_bc_data *bc = dev_get_drvdata(&pdev->dev); | ||
725 | |||
726 | tty_unregister_device(ehv_bc_driver, bc - bcs); | ||
727 | |||
728 | tty_port_destroy(&bc->port); | ||
729 | irq_dispose_mapping(bc->tx_irq); | ||
730 | irq_dispose_mapping(bc->rx_irq); | ||
731 | |||
732 | return 0; | ||
733 | } | ||
734 | |||
735 | static const struct of_device_id ehv_bc_tty_of_ids[] = { | 721 | static const struct of_device_id ehv_bc_tty_of_ids[] = { |
736 | { .compatible = "epapr,hv-byte-channel" }, | 722 | { .compatible = "epapr,hv-byte-channel" }, |
737 | {} | 723 | {} |
@@ -741,15 +727,15 @@ static struct platform_driver ehv_bc_tty_driver = { | |||
741 | .driver = { | 727 | .driver = { |
742 | .name = "ehv-bc", | 728 | .name = "ehv-bc", |
743 | .of_match_table = ehv_bc_tty_of_ids, | 729 | .of_match_table = ehv_bc_tty_of_ids, |
730 | .suppress_bind_attrs = true, | ||
744 | }, | 731 | }, |
745 | .probe = ehv_bc_tty_probe, | 732 | .probe = ehv_bc_tty_probe, |
746 | .remove = ehv_bc_tty_remove, | ||
747 | }; | 733 | }; |
748 | 734 | ||
749 | /** | 735 | /** |
750 | * ehv_bc_init - ePAPR hypervisor byte channel driver initialization | 736 | * ehv_bc_init - ePAPR hypervisor byte channel driver initialization |
751 | * | 737 | * |
752 | * This function is called when this module is loaded. | 738 | * This function is called when this driver is loaded. |
753 | */ | 739 | */ |
754 | static int __init ehv_bc_init(void) | 740 | static int __init ehv_bc_init(void) |
755 | { | 741 | { |
@@ -814,24 +800,4 @@ error: | |||
814 | 800 | ||
815 | return ret; | 801 | return ret; |
816 | } | 802 | } |
817 | 803 | device_initcall(ehv_bc_init); | |
818 | |||
819 | /** | ||
820 | * ehv_bc_exit - ePAPR hypervisor byte channel driver termination | ||
821 | * | ||
822 | * This function is called when this driver is unloaded. | ||
823 | */ | ||
824 | static void __exit ehv_bc_exit(void) | ||
825 | { | ||
826 | platform_driver_unregister(&ehv_bc_tty_driver); | ||
827 | tty_unregister_driver(ehv_bc_driver); | ||
828 | put_tty_driver(ehv_bc_driver); | ||
829 | kfree(bcs); | ||
830 | } | ||
831 | |||
832 | module_init(ehv_bc_init); | ||
833 | module_exit(ehv_bc_exit); | ||
834 | |||
835 | MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); | ||
836 | MODULE_DESCRIPTION("ePAPR hypervisor byte channel driver"); | ||
837 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/tty/goldfish.c b/drivers/tty/goldfish.c index 0f82c0b146f6..3fc912373adf 100644 --- a/drivers/tty/goldfish.c +++ b/drivers/tty/goldfish.c | |||
@@ -68,8 +68,7 @@ static void goldfish_tty_do_write(int line, const char *buf, unsigned count) | |||
68 | 68 | ||
69 | static irqreturn_t goldfish_tty_interrupt(int irq, void *dev_id) | 69 | static irqreturn_t goldfish_tty_interrupt(int irq, void *dev_id) |
70 | { | 70 | { |
71 | struct platform_device *pdev = dev_id; | 71 | struct goldfish_tty *qtty = dev_id; |
72 | struct goldfish_tty *qtty = &goldfish_ttys[pdev->id]; | ||
73 | void __iomem *base = qtty->base; | 72 | void __iomem *base = qtty->base; |
74 | unsigned long irq_flags; | 73 | unsigned long irq_flags; |
75 | unsigned char *buf; | 74 | unsigned char *buf; |
@@ -162,7 +161,7 @@ static int goldfish_tty_console_setup(struct console *co, char *options) | |||
162 | return 0; | 161 | return 0; |
163 | } | 162 | } |
164 | 163 | ||
165 | static struct tty_port_operations goldfish_port_ops = { | 164 | static const struct tty_port_operations goldfish_port_ops = { |
166 | .activate = goldfish_tty_activate, | 165 | .activate = goldfish_tty_activate, |
167 | .shutdown = goldfish_tty_shutdown | 166 | .shutdown = goldfish_tty_shutdown |
168 | }; | 167 | }; |
@@ -233,6 +232,7 @@ static int goldfish_tty_probe(struct platform_device *pdev) | |||
233 | struct device *ttydev; | 232 | struct device *ttydev; |
234 | void __iomem *base; | 233 | void __iomem *base; |
235 | u32 irq; | 234 | u32 irq; |
235 | unsigned int line; | ||
236 | 236 | ||
237 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 237 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
238 | if (r == NULL) | 238 | if (r == NULL) |
@@ -248,10 +248,16 @@ static int goldfish_tty_probe(struct platform_device *pdev) | |||
248 | 248 | ||
249 | irq = r->start; | 249 | irq = r->start; |
250 | 250 | ||
251 | if (pdev->id >= goldfish_tty_line_count) | ||
252 | goto err_unmap; | ||
253 | |||
254 | mutex_lock(&goldfish_tty_lock); | 251 | mutex_lock(&goldfish_tty_lock); |
252 | |||
253 | if (pdev->id == PLATFORM_DEVID_NONE) | ||
254 | line = goldfish_tty_current_line_count; | ||
255 | else | ||
256 | line = pdev->id; | ||
257 | |||
258 | if (line >= goldfish_tty_line_count) | ||
259 | goto err_create_driver_failed; | ||
260 | |||
255 | if (goldfish_tty_current_line_count == 0) { | 261 | if (goldfish_tty_current_line_count == 0) { |
256 | ret = goldfish_tty_create_driver(); | 262 | ret = goldfish_tty_create_driver(); |
257 | if (ret) | 263 | if (ret) |
@@ -259,7 +265,7 @@ static int goldfish_tty_probe(struct platform_device *pdev) | |||
259 | } | 265 | } |
260 | goldfish_tty_current_line_count++; | 266 | goldfish_tty_current_line_count++; |
261 | 267 | ||
262 | qtty = &goldfish_ttys[pdev->id]; | 268 | qtty = &goldfish_ttys[line]; |
263 | spin_lock_init(&qtty->lock); | 269 | spin_lock_init(&qtty->lock); |
264 | tty_port_init(&qtty->port); | 270 | tty_port_init(&qtty->port); |
265 | qtty->port.ops = &goldfish_port_ops; | 271 | qtty->port.ops = &goldfish_port_ops; |
@@ -269,13 +275,13 @@ static int goldfish_tty_probe(struct platform_device *pdev) | |||
269 | writel(GOLDFISH_TTY_CMD_INT_DISABLE, base + GOLDFISH_TTY_CMD); | 275 | writel(GOLDFISH_TTY_CMD_INT_DISABLE, base + GOLDFISH_TTY_CMD); |
270 | 276 | ||
271 | ret = request_irq(irq, goldfish_tty_interrupt, IRQF_SHARED, | 277 | ret = request_irq(irq, goldfish_tty_interrupt, IRQF_SHARED, |
272 | "goldfish_tty", pdev); | 278 | "goldfish_tty", qtty); |
273 | if (ret) | 279 | if (ret) |
274 | goto err_request_irq_failed; | 280 | goto err_request_irq_failed; |
275 | 281 | ||
276 | 282 | ||
277 | ttydev = tty_port_register_device(&qtty->port, goldfish_tty_driver, | 283 | ttydev = tty_port_register_device(&qtty->port, goldfish_tty_driver, |
278 | pdev->id, &pdev->dev); | 284 | line, &pdev->dev); |
279 | if (IS_ERR(ttydev)) { | 285 | if (IS_ERR(ttydev)) { |
280 | ret = PTR_ERR(ttydev); | 286 | ret = PTR_ERR(ttydev); |
281 | goto err_tty_register_device_failed; | 287 | goto err_tty_register_device_failed; |
@@ -286,8 +292,9 @@ static int goldfish_tty_probe(struct platform_device *pdev) | |||
286 | qtty->console.device = goldfish_tty_console_device; | 292 | qtty->console.device = goldfish_tty_console_device; |
287 | qtty->console.setup = goldfish_tty_console_setup; | 293 | qtty->console.setup = goldfish_tty_console_setup; |
288 | qtty->console.flags = CON_PRINTBUFFER; | 294 | qtty->console.flags = CON_PRINTBUFFER; |
289 | qtty->console.index = pdev->id; | 295 | qtty->console.index = line; |
290 | register_console(&qtty->console); | 296 | register_console(&qtty->console); |
297 | platform_set_drvdata(pdev, qtty); | ||
291 | 298 | ||
292 | mutex_unlock(&goldfish_tty_lock); | 299 | mutex_unlock(&goldfish_tty_lock); |
293 | return 0; | 300 | return 0; |
@@ -307,13 +314,12 @@ err_unmap: | |||
307 | 314 | ||
308 | static int goldfish_tty_remove(struct platform_device *pdev) | 315 | static int goldfish_tty_remove(struct platform_device *pdev) |
309 | { | 316 | { |
310 | struct goldfish_tty *qtty; | 317 | struct goldfish_tty *qtty = platform_get_drvdata(pdev); |
311 | 318 | ||
312 | mutex_lock(&goldfish_tty_lock); | 319 | mutex_lock(&goldfish_tty_lock); |
313 | 320 | ||
314 | qtty = &goldfish_ttys[pdev->id]; | ||
315 | unregister_console(&qtty->console); | 321 | unregister_console(&qtty->console); |
316 | tty_unregister_device(goldfish_tty_driver, pdev->id); | 322 | tty_unregister_device(goldfish_tty_driver, qtty->console.index); |
317 | iounmap(qtty->base); | 323 | iounmap(qtty->base); |
318 | qtty->base = NULL; | 324 | qtty->base = NULL; |
319 | free_irq(qtty->irq, pdev); | 325 | free_irq(qtty->irq, pdev); |
@@ -324,11 +330,19 @@ static int goldfish_tty_remove(struct platform_device *pdev) | |||
324 | return 0; | 330 | return 0; |
325 | } | 331 | } |
326 | 332 | ||
333 | static const struct of_device_id goldfish_tty_of_match[] = { | ||
334 | { .compatible = "google,goldfish-tty", }, | ||
335 | {}, | ||
336 | }; | ||
337 | |||
338 | MODULE_DEVICE_TABLE(of, goldfish_tty_of_match); | ||
339 | |||
327 | static struct platform_driver goldfish_tty_platform_driver = { | 340 | static struct platform_driver goldfish_tty_platform_driver = { |
328 | .probe = goldfish_tty_probe, | 341 | .probe = goldfish_tty_probe, |
329 | .remove = goldfish_tty_remove, | 342 | .remove = goldfish_tty_remove, |
330 | .driver = { | 343 | .driver = { |
331 | .name = "goldfish_tty" | 344 | .name = "goldfish_tty", |
345 | .of_match_table = goldfish_tty_of_match, | ||
332 | } | 346 | } |
333 | }; | 347 | }; |
334 | 348 | ||
diff --git a/drivers/tty/hvc/hvc_vio.c b/drivers/tty/hvc/hvc_vio.c index f575a9b5ede7..b05dc5086627 100644 --- a/drivers/tty/hvc/hvc_vio.c +++ b/drivers/tty/hvc/hvc_vio.c | |||
@@ -41,7 +41,6 @@ | |||
41 | #include <linux/delay.h> | 41 | #include <linux/delay.h> |
42 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
43 | #include <linux/console.h> | 43 | #include <linux/console.h> |
44 | #include <linux/module.h> | ||
45 | 44 | ||
46 | #include <asm/hvconsole.h> | 45 | #include <asm/hvconsole.h> |
47 | #include <asm/vio.h> | 46 | #include <asm/vio.h> |
@@ -61,7 +60,6 @@ static struct vio_device_id hvc_driver_table[] = { | |||
61 | #endif | 60 | #endif |
62 | { "", "" } | 61 | { "", "" } |
63 | }; | 62 | }; |
64 | MODULE_DEVICE_TABLE(vio, hvc_driver_table); | ||
65 | 63 | ||
66 | typedef enum hv_protocol { | 64 | typedef enum hv_protocol { |
67 | HV_PROTOCOL_RAW, | 65 | HV_PROTOCOL_RAW, |
@@ -363,26 +361,13 @@ static int hvc_vio_probe(struct vio_dev *vdev, | |||
363 | return 0; | 361 | return 0; |
364 | } | 362 | } |
365 | 363 | ||
366 | static int hvc_vio_remove(struct vio_dev *vdev) | ||
367 | { | ||
368 | struct hvc_struct *hp = dev_get_drvdata(&vdev->dev); | ||
369 | int rc, termno; | ||
370 | |||
371 | termno = hp->vtermno; | ||
372 | rc = hvc_remove(hp); | ||
373 | if (rc == 0) { | ||
374 | if (hvterm_privs[termno] != &hvterm_priv0) | ||
375 | kfree(hvterm_privs[termno]); | ||
376 | hvterm_privs[termno] = NULL; | ||
377 | } | ||
378 | return rc; | ||
379 | } | ||
380 | |||
381 | static struct vio_driver hvc_vio_driver = { | 364 | static struct vio_driver hvc_vio_driver = { |
382 | .id_table = hvc_driver_table, | 365 | .id_table = hvc_driver_table, |
383 | .probe = hvc_vio_probe, | 366 | .probe = hvc_vio_probe, |
384 | .remove = hvc_vio_remove, | ||
385 | .name = hvc_driver_name, | 367 | .name = hvc_driver_name, |
368 | .driver = { | ||
369 | .suppress_bind_attrs = true, | ||
370 | }, | ||
386 | }; | 371 | }; |
387 | 372 | ||
388 | static int __init hvc_vio_init(void) | 373 | static int __init hvc_vio_init(void) |
@@ -394,13 +379,7 @@ static int __init hvc_vio_init(void) | |||
394 | 379 | ||
395 | return rc; | 380 | return rc; |
396 | } | 381 | } |
397 | module_init(hvc_vio_init); /* after drivers/char/hvc_console.c */ | 382 | device_initcall(hvc_vio_init); /* after drivers/tty/hvc/hvc_console.c */ |
398 | |||
399 | static void __exit hvc_vio_exit(void) | ||
400 | { | ||
401 | vio_unregister_driver(&hvc_vio_driver); | ||
402 | } | ||
403 | module_exit(hvc_vio_exit); | ||
404 | 383 | ||
405 | void __init hvc_vio_init_early(void) | 384 | void __init hvc_vio_init_early(void) |
406 | { | 385 | { |
diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c index fa816b7193b6..f417fa1ee47c 100644 --- a/drivers/tty/hvc/hvc_xen.c +++ b/drivers/tty/hvc/hvc_xen.c | |||
@@ -162,7 +162,7 @@ static int domU_read_console(uint32_t vtermno, char *buf, int len) | |||
162 | return recv; | 162 | return recv; |
163 | } | 163 | } |
164 | 164 | ||
165 | static struct hv_ops domU_hvc_ops = { | 165 | static const struct hv_ops domU_hvc_ops = { |
166 | .get_chars = domU_read_console, | 166 | .get_chars = domU_read_console, |
167 | .put_chars = domU_write_console, | 167 | .put_chars = domU_write_console, |
168 | .notifier_add = notifier_add_irq, | 168 | .notifier_add = notifier_add_irq, |
@@ -188,7 +188,7 @@ static int dom0_write_console(uint32_t vtermno, const char *str, int len) | |||
188 | return len; | 188 | return len; |
189 | } | 189 | } |
190 | 190 | ||
191 | static struct hv_ops dom0_hvc_ops = { | 191 | static const struct hv_ops dom0_hvc_ops = { |
192 | .get_chars = dom0_read_console, | 192 | .get_chars = dom0_read_console, |
193 | .put_chars = dom0_write_console, | 193 | .put_chars = dom0_write_console, |
194 | .notifier_add = notifier_add_irq, | 194 | .notifier_add = notifier_add_irq, |
@@ -323,6 +323,7 @@ void xen_console_resume(void) | |||
323 | } | 323 | } |
324 | } | 324 | } |
325 | 325 | ||
326 | #ifdef CONFIG_HVC_XEN_FRONTEND | ||
326 | static void xencons_disconnect_backend(struct xencons_info *info) | 327 | static void xencons_disconnect_backend(struct xencons_info *info) |
327 | { | 328 | { |
328 | if (info->irq > 0) | 329 | if (info->irq > 0) |
@@ -363,7 +364,6 @@ static int xen_console_remove(struct xencons_info *info) | |||
363 | return 0; | 364 | return 0; |
364 | } | 365 | } |
365 | 366 | ||
366 | #ifdef CONFIG_HVC_XEN_FRONTEND | ||
367 | static int xencons_remove(struct xenbus_device *dev) | 367 | static int xencons_remove(struct xenbus_device *dev) |
368 | { | 368 | { |
369 | return xen_console_remove(dev_get_drvdata(&dev->dev)); | 369 | return xen_console_remove(dev_get_drvdata(&dev->dev)); |
diff --git a/drivers/tty/isicom.c b/drivers/tty/isicom.c index 99875949bfb7..8bf67630018b 100644 --- a/drivers/tty/isicom.c +++ b/drivers/tty/isicom.c | |||
@@ -1204,8 +1204,7 @@ static void isicom_set_termios(struct tty_struct *tty, | |||
1204 | isicom_config_port(tty); | 1204 | isicom_config_port(tty); |
1205 | spin_unlock_irqrestore(&port->card->card_lock, flags); | 1205 | spin_unlock_irqrestore(&port->card->card_lock, flags); |
1206 | 1206 | ||
1207 | if ((old_termios->c_cflag & CRTSCTS) && | 1207 | if ((old_termios->c_cflag & CRTSCTS) && !C_CRTSCTS(tty)) { |
1208 | !(tty->termios.c_cflag & CRTSCTS)) { | ||
1209 | tty->hw_stopped = 0; | 1208 | tty->hw_stopped = 0; |
1210 | isicom_start(tty); | 1209 | isicom_start(tty); |
1211 | } | 1210 | } |
diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 4c4a23674569..2f12bb9f4336 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c | |||
@@ -254,6 +254,7 @@ struct mxser_port { | |||
254 | int xmit_head; | 254 | int xmit_head; |
255 | int xmit_tail; | 255 | int xmit_tail; |
256 | int xmit_cnt; | 256 | int xmit_cnt; |
257 | int closing; | ||
257 | 258 | ||
258 | struct ktermios normal_termios; | 259 | struct ktermios normal_termios; |
259 | 260 | ||
@@ -1081,6 +1082,7 @@ static void mxser_close(struct tty_struct *tty, struct file *filp) | |||
1081 | return; | 1082 | return; |
1082 | if (tty_port_close_start(port, tty, filp) == 0) | 1083 | if (tty_port_close_start(port, tty, filp) == 0) |
1083 | return; | 1084 | return; |
1085 | info->closing = 1; | ||
1084 | mutex_lock(&port->mutex); | 1086 | mutex_lock(&port->mutex); |
1085 | mxser_close_port(port); | 1087 | mxser_close_port(port); |
1086 | mxser_flush_buffer(tty); | 1088 | mxser_flush_buffer(tty); |
@@ -1091,6 +1093,7 @@ static void mxser_close(struct tty_struct *tty, struct file *filp) | |||
1091 | mxser_shutdown_port(port); | 1093 | mxser_shutdown_port(port); |
1092 | clear_bit(ASYNCB_INITIALIZED, &port->flags); | 1094 | clear_bit(ASYNCB_INITIALIZED, &port->flags); |
1093 | mutex_unlock(&port->mutex); | 1095 | mutex_unlock(&port->mutex); |
1096 | info->closing = 0; | ||
1094 | /* Right now the tty_port set is done outside of the close_end helper | 1097 | /* Right now the tty_port set is done outside of the close_end helper |
1095 | as we don't yet have everyone using refcounts */ | 1098 | as we don't yet have everyone using refcounts */ |
1096 | tty_port_close_end(port, tty); | 1099 | tty_port_close_end(port, tty); |
@@ -1864,7 +1867,7 @@ static void mxser_stoprx(struct tty_struct *tty) | |||
1864 | } | 1867 | } |
1865 | } | 1868 | } |
1866 | 1869 | ||
1867 | if (tty->termios.c_cflag & CRTSCTS) { | 1870 | if (C_CRTSCTS(tty)) { |
1868 | info->MCR &= ~UART_MCR_RTS; | 1871 | info->MCR &= ~UART_MCR_RTS; |
1869 | outb(info->MCR, info->ioaddr + UART_MCR); | 1872 | outb(info->MCR, info->ioaddr + UART_MCR); |
1870 | } | 1873 | } |
@@ -1901,7 +1904,7 @@ static void mxser_unthrottle(struct tty_struct *tty) | |||
1901 | } | 1904 | } |
1902 | } | 1905 | } |
1903 | 1906 | ||
1904 | if (tty->termios.c_cflag & CRTSCTS) { | 1907 | if (C_CRTSCTS(tty)) { |
1905 | info->MCR |= UART_MCR_RTS; | 1908 | info->MCR |= UART_MCR_RTS; |
1906 | outb(info->MCR, info->ioaddr + UART_MCR); | 1909 | outb(info->MCR, info->ioaddr + UART_MCR); |
1907 | } | 1910 | } |
@@ -1949,15 +1952,13 @@ static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termi | |||
1949 | mxser_change_speed(tty, old_termios); | 1952 | mxser_change_speed(tty, old_termios); |
1950 | spin_unlock_irqrestore(&info->slock, flags); | 1953 | spin_unlock_irqrestore(&info->slock, flags); |
1951 | 1954 | ||
1952 | if ((old_termios->c_cflag & CRTSCTS) && | 1955 | if ((old_termios->c_cflag & CRTSCTS) && !C_CRTSCTS(tty)) { |
1953 | !(tty->termios.c_cflag & CRTSCTS)) { | ||
1954 | tty->hw_stopped = 0; | 1956 | tty->hw_stopped = 0; |
1955 | mxser_start(tty); | 1957 | mxser_start(tty); |
1956 | } | 1958 | } |
1957 | 1959 | ||
1958 | /* Handle sw stopped */ | 1960 | /* Handle sw stopped */ |
1959 | if ((old_termios->c_iflag & IXON) && | 1961 | if ((old_termios->c_iflag & IXON) && !I_IXON(tty)) { |
1960 | !(tty->termios.c_iflag & IXON)) { | ||
1961 | tty->stopped = 0; | 1962 | tty->stopped = 0; |
1962 | 1963 | ||
1963 | if (info->board->chip_flag) { | 1964 | if (info->board->chip_flag) { |
@@ -2255,10 +2256,8 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) | |||
2255 | break; | 2256 | break; |
2256 | iir &= MOXA_MUST_IIR_MASK; | 2257 | iir &= MOXA_MUST_IIR_MASK; |
2257 | tty = tty_port_tty_get(&port->port); | 2258 | tty = tty_port_tty_get(&port->port); |
2258 | if (!tty || | 2259 | if (!tty || port->closing || |
2259 | (port->port.flags & ASYNC_CLOSING) || | 2260 | !(port->port.flags & ASYNC_INITIALIZED)) { |
2260 | !(port->port.flags & | ||
2261 | ASYNC_INITIALIZED)) { | ||
2262 | status = inb(port->ioaddr + UART_LSR); | 2261 | status = inb(port->ioaddr + UART_LSR); |
2263 | outb(0x27, port->ioaddr + UART_FCR); | 2262 | outb(0x27, port->ioaddr + UART_FCR); |
2264 | inb(port->ioaddr + UART_MSR); | 2263 | inb(port->ioaddr + UART_MSR); |
@@ -2337,7 +2336,7 @@ static const struct tty_operations mxser_ops = { | |||
2337 | .get_icount = mxser_get_icount, | 2336 | .get_icount = mxser_get_icount, |
2338 | }; | 2337 | }; |
2339 | 2338 | ||
2340 | static struct tty_port_operations mxser_port_ops = { | 2339 | static const struct tty_port_operations mxser_port_ops = { |
2341 | .carrier_raised = mxser_carrier_raised, | 2340 | .carrier_raised = mxser_carrier_raised, |
2342 | .dtr_rts = mxser_dtr_rts, | 2341 | .dtr_rts = mxser_dtr_rts, |
2343 | .activate = mxser_activate, | 2342 | .activate = mxser_activate, |
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index c3fe026d3168..c01620780f5b 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c | |||
@@ -1066,7 +1066,7 @@ static void gsm_process_modem(struct tty_struct *tty, struct gsm_dlci *dlci, | |||
1066 | /* Carrier drop -> hangup */ | 1066 | /* Carrier drop -> hangup */ |
1067 | if (tty) { | 1067 | if (tty) { |
1068 | if ((mlines & TIOCM_CD) == 0 && (dlci->modem_rx & TIOCM_CD)) | 1068 | if ((mlines & TIOCM_CD) == 0 && (dlci->modem_rx & TIOCM_CD)) |
1069 | if (!(tty->termios.c_cflag & CLOCAL)) | 1069 | if (!C_CLOCAL(tty)) |
1070 | tty_hangup(tty); | 1070 | tty_hangup(tty); |
1071 | } | 1071 | } |
1072 | if (brk & 0x01) | 1072 | if (brk & 0x01) |
@@ -2304,21 +2304,6 @@ static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
2304 | } | 2304 | } |
2305 | 2305 | ||
2306 | /** | 2306 | /** |
2307 | * gsmld_chars_in_buffer - report available bytes | ||
2308 | * @tty: tty device | ||
2309 | * | ||
2310 | * Report the number of characters buffered to be delivered to user | ||
2311 | * at this instant in time. | ||
2312 | * | ||
2313 | * Locking: gsm lock | ||
2314 | */ | ||
2315 | |||
2316 | static ssize_t gsmld_chars_in_buffer(struct tty_struct *tty) | ||
2317 | { | ||
2318 | return 0; | ||
2319 | } | ||
2320 | |||
2321 | /** | ||
2322 | * gsmld_flush_buffer - clean input queue | 2307 | * gsmld_flush_buffer - clean input queue |
2323 | * @tty: terminal device | 2308 | * @tty: terminal device |
2324 | * | 2309 | * |
@@ -2830,7 +2815,6 @@ static struct tty_ldisc_ops tty_ldisc_packet = { | |||
2830 | .open = gsmld_open, | 2815 | .open = gsmld_open, |
2831 | .close = gsmld_close, | 2816 | .close = gsmld_close, |
2832 | .flush_buffer = gsmld_flush_buffer, | 2817 | .flush_buffer = gsmld_flush_buffer, |
2833 | .chars_in_buffer = gsmld_chars_in_buffer, | ||
2834 | .read = gsmld_read, | 2818 | .read = gsmld_read, |
2835 | .write = gsmld_write, | 2819 | .write = gsmld_write, |
2836 | .ioctl = gsmld_ioctl, | 2820 | .ioctl = gsmld_ioctl, |
@@ -3132,7 +3116,7 @@ static void gsmtty_throttle(struct tty_struct *tty) | |||
3132 | struct gsm_dlci *dlci = tty->driver_data; | 3116 | struct gsm_dlci *dlci = tty->driver_data; |
3133 | if (dlci->state == DLCI_CLOSED) | 3117 | if (dlci->state == DLCI_CLOSED) |
3134 | return; | 3118 | return; |
3135 | if (tty->termios.c_cflag & CRTSCTS) | 3119 | if (C_CRTSCTS(tty)) |
3136 | dlci->modem_tx &= ~TIOCM_DTR; | 3120 | dlci->modem_tx &= ~TIOCM_DTR; |
3137 | dlci->throttled = 1; | 3121 | dlci->throttled = 1; |
3138 | /* Send an MSC with DTR cleared */ | 3122 | /* Send an MSC with DTR cleared */ |
@@ -3144,7 +3128,7 @@ static void gsmtty_unthrottle(struct tty_struct *tty) | |||
3144 | struct gsm_dlci *dlci = tty->driver_data; | 3128 | struct gsm_dlci *dlci = tty->driver_data; |
3145 | if (dlci->state == DLCI_CLOSED) | 3129 | if (dlci->state == DLCI_CLOSED) |
3146 | return; | 3130 | return; |
3147 | if (tty->termios.c_cflag & CRTSCTS) | 3131 | if (C_CRTSCTS(tty)) |
3148 | dlci->modem_tx |= TIOCM_DTR; | 3132 | dlci->modem_tx |= TIOCM_DTR; |
3149 | dlci->throttled = 0; | 3133 | dlci->throttled = 0; |
3150 | /* Send an MSC with DTR set */ | 3134 | /* Send an MSC with DTR set */ |
diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c index bbc4ce66c2c1..bcaba17688f6 100644 --- a/drivers/tty/n_hdlc.c +++ b/drivers/tty/n_hdlc.c | |||
@@ -159,7 +159,6 @@ struct n_hdlc { | |||
159 | /* | 159 | /* |
160 | * HDLC buffer list manipulation functions | 160 | * HDLC buffer list manipulation functions |
161 | */ | 161 | */ |
162 | static void n_hdlc_buf_list_init(struct n_hdlc_buf_list *list); | ||
163 | static void n_hdlc_buf_put(struct n_hdlc_buf_list *list, | 162 | static void n_hdlc_buf_put(struct n_hdlc_buf_list *list, |
164 | struct n_hdlc_buf *buf); | 163 | struct n_hdlc_buf *buf); |
165 | static struct n_hdlc_buf *n_hdlc_buf_get(struct n_hdlc_buf_list *list); | 164 | static struct n_hdlc_buf *n_hdlc_buf_get(struct n_hdlc_buf_list *list); |
@@ -853,10 +852,10 @@ static struct n_hdlc *n_hdlc_alloc(void) | |||
853 | if (!n_hdlc) | 852 | if (!n_hdlc) |
854 | return NULL; | 853 | return NULL; |
855 | 854 | ||
856 | n_hdlc_buf_list_init(&n_hdlc->rx_free_buf_list); | 855 | spin_lock_init(&n_hdlc->rx_free_buf_list.spinlock); |
857 | n_hdlc_buf_list_init(&n_hdlc->tx_free_buf_list); | 856 | spin_lock_init(&n_hdlc->tx_free_buf_list.spinlock); |
858 | n_hdlc_buf_list_init(&n_hdlc->rx_buf_list); | 857 | spin_lock_init(&n_hdlc->rx_buf_list.spinlock); |
859 | n_hdlc_buf_list_init(&n_hdlc->tx_buf_list); | 858 | spin_lock_init(&n_hdlc->tx_buf_list.spinlock); |
860 | 859 | ||
861 | /* allocate free rx buffer list */ | 860 | /* allocate free rx buffer list */ |
862 | for(i=0;i<DEFAULT_RX_BUF_COUNT;i++) { | 861 | for(i=0;i<DEFAULT_RX_BUF_COUNT;i++) { |
@@ -885,16 +884,6 @@ static struct n_hdlc *n_hdlc_alloc(void) | |||
885 | } /* end of n_hdlc_alloc() */ | 884 | } /* end of n_hdlc_alloc() */ |
886 | 885 | ||
887 | /** | 886 | /** |
888 | * n_hdlc_buf_list_init - initialize specified HDLC buffer list | ||
889 | * @list - pointer to buffer list | ||
890 | */ | ||
891 | static void n_hdlc_buf_list_init(struct n_hdlc_buf_list *list) | ||
892 | { | ||
893 | memset(list, 0, sizeof(*list)); | ||
894 | spin_lock_init(&list->spinlock); | ||
895 | } /* end of n_hdlc_buf_list_init() */ | ||
896 | |||
897 | /** | ||
898 | * n_hdlc_buf_put - add specified HDLC buffer to tail of specified list | 887 | * n_hdlc_buf_put - add specified HDLC buffer to tail of specified list |
899 | * @list - pointer to buffer list | 888 | * @list - pointer to buffer list |
900 | * @buf - pointer to buffer | 889 | * @buf - pointer to buffer |
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index b280abaad91b..fb76a7d80e7e 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c | |||
@@ -113,8 +113,6 @@ struct n_tty_data { | |||
113 | DECLARE_BITMAP(read_flags, N_TTY_BUF_SIZE); | 113 | DECLARE_BITMAP(read_flags, N_TTY_BUF_SIZE); |
114 | unsigned char echo_buf[N_TTY_BUF_SIZE]; | 114 | unsigned char echo_buf[N_TTY_BUF_SIZE]; |
115 | 115 | ||
116 | int minimum_to_wake; | ||
117 | |||
118 | /* consumer-published */ | 116 | /* consumer-published */ |
119 | size_t read_tail; | 117 | size_t read_tail; |
120 | size_t line_start; | 118 | size_t line_start; |
@@ -153,15 +151,6 @@ static inline unsigned char *echo_buf_addr(struct n_tty_data *ldata, size_t i) | |||
153 | return &ldata->echo_buf[i & (N_TTY_BUF_SIZE - 1)]; | 151 | return &ldata->echo_buf[i & (N_TTY_BUF_SIZE - 1)]; |
154 | } | 152 | } |
155 | 153 | ||
156 | static inline int tty_put_user(struct tty_struct *tty, unsigned char x, | ||
157 | unsigned char __user *ptr) | ||
158 | { | ||
159 | struct n_tty_data *ldata = tty->disc_data; | ||
160 | |||
161 | tty_audit_add_data(tty, &x, 1, ldata->icanon); | ||
162 | return put_user(x, ptr); | ||
163 | } | ||
164 | |||
165 | static int tty_copy_to_user(struct tty_struct *tty, void __user *to, | 154 | static int tty_copy_to_user(struct tty_struct *tty, void __user *to, |
166 | size_t tail, size_t n) | 155 | size_t tail, size_t n) |
167 | { | 156 | { |
@@ -171,7 +160,7 @@ static int tty_copy_to_user(struct tty_struct *tty, void __user *to, | |||
171 | int uncopied; | 160 | int uncopied; |
172 | 161 | ||
173 | if (n > size) { | 162 | if (n > size) { |
174 | tty_audit_add_data(tty, from, size, ldata->icanon); | 163 | tty_audit_add_data(tty, from, size); |
175 | uncopied = copy_to_user(to, from, size); | 164 | uncopied = copy_to_user(to, from, size); |
176 | if (uncopied) | 165 | if (uncopied) |
177 | return uncopied; | 166 | return uncopied; |
@@ -180,7 +169,7 @@ static int tty_copy_to_user(struct tty_struct *tty, void __user *to, | |||
180 | from = ldata->read_buf; | 169 | from = ldata->read_buf; |
181 | } | 170 | } |
182 | 171 | ||
183 | tty_audit_add_data(tty, from, n, ldata->icanon); | 172 | tty_audit_add_data(tty, from, n); |
184 | return copy_to_user(to, from, n); | 173 | return copy_to_user(to, from, n); |
185 | } | 174 | } |
186 | 175 | ||
@@ -239,8 +228,8 @@ static ssize_t chars_in_buffer(struct tty_struct *tty) | |||
239 | 228 | ||
240 | static void n_tty_write_wakeup(struct tty_struct *tty) | 229 | static void n_tty_write_wakeup(struct tty_struct *tty) |
241 | { | 230 | { |
242 | if (tty->fasync && test_and_clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) | 231 | clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); |
243 | kill_fasync(&tty->fasync, SIGIO, POLL_OUT); | 232 | kill_fasync(&tty->fasync, SIGIO, POLL_OUT); |
244 | } | 233 | } |
245 | 234 | ||
246 | static void n_tty_check_throttle(struct tty_struct *tty) | 235 | static void n_tty_check_throttle(struct tty_struct *tty) |
@@ -272,8 +261,6 @@ static void n_tty_check_unthrottle(struct tty_struct *tty) | |||
272 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY) { | 261 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY) { |
273 | if (chars_in_buffer(tty) > TTY_THRESHOLD_UNTHROTTLE) | 262 | if (chars_in_buffer(tty) > TTY_THRESHOLD_UNTHROTTLE) |
274 | return; | 263 | return; |
275 | if (!tty->count) | ||
276 | return; | ||
277 | n_tty_kick_worker(tty); | 264 | n_tty_kick_worker(tty); |
278 | tty_wakeup(tty->link); | 265 | tty_wakeup(tty->link); |
279 | return; | 266 | return; |
@@ -292,8 +279,6 @@ static void n_tty_check_unthrottle(struct tty_struct *tty) | |||
292 | tty_set_flow_change(tty, TTY_UNTHROTTLE_SAFE); | 279 | tty_set_flow_change(tty, TTY_UNTHROTTLE_SAFE); |
293 | if (chars_in_buffer(tty) > TTY_THRESHOLD_UNTHROTTLE) | 280 | if (chars_in_buffer(tty) > TTY_THRESHOLD_UNTHROTTLE) |
294 | break; | 281 | break; |
295 | if (!tty->count) | ||
296 | break; | ||
297 | n_tty_kick_worker(tty); | 282 | n_tty_kick_worker(tty); |
298 | unthrottled = tty_unthrottle_safe(tty); | 283 | unthrottled = tty_unthrottle_safe(tty); |
299 | if (!unthrottled) | 284 | if (!unthrottled) |
@@ -381,28 +366,6 @@ static void n_tty_flush_buffer(struct tty_struct *tty) | |||
381 | } | 366 | } |
382 | 367 | ||
383 | /** | 368 | /** |
384 | * n_tty_chars_in_buffer - report available bytes | ||
385 | * @tty: tty device | ||
386 | * | ||
387 | * Report the number of characters buffered to be delivered to user | ||
388 | * at this instant in time. | ||
389 | * | ||
390 | * Locking: exclusive termios_rwsem | ||
391 | */ | ||
392 | |||
393 | static ssize_t n_tty_chars_in_buffer(struct tty_struct *tty) | ||
394 | { | ||
395 | ssize_t n; | ||
396 | |||
397 | WARN_ONCE(1, "%s is deprecated and scheduled for removal.", __func__); | ||
398 | |||
399 | down_write(&tty->termios_rwsem); | ||
400 | n = chars_in_buffer(tty); | ||
401 | up_write(&tty->termios_rwsem); | ||
402 | return n; | ||
403 | } | ||
404 | |||
405 | /** | ||
406 | * is_utf8_continuation - utf8 multibyte check | 369 | * is_utf8_continuation - utf8 multibyte check |
407 | * @c: byte to check | 370 | * @c: byte to check |
408 | * | 371 | * |
@@ -1561,8 +1524,6 @@ n_tty_receive_buf_closing(struct tty_struct *tty, const unsigned char *cp, | |||
1561 | flag = *fp++; | 1524 | flag = *fp++; |
1562 | if (likely(flag == TTY_NORMAL)) | 1525 | if (likely(flag == TTY_NORMAL)) |
1563 | n_tty_receive_char_closing(tty, *cp++); | 1526 | n_tty_receive_char_closing(tty, *cp++); |
1564 | else | ||
1565 | n_tty_receive_char_flagged(tty, *cp++, flag); | ||
1566 | } | 1527 | } |
1567 | } | 1528 | } |
1568 | 1529 | ||
@@ -1664,7 +1625,7 @@ static void __receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
1664 | /* publish read_head to consumer */ | 1625 | /* publish read_head to consumer */ |
1665 | smp_store_release(&ldata->commit_head, ldata->read_head); | 1626 | smp_store_release(&ldata->commit_head, ldata->read_head); |
1666 | 1627 | ||
1667 | if ((read_cnt(ldata) >= ldata->minimum_to_wake) || L_EXTPROC(tty)) { | 1628 | if (read_cnt(ldata)) { |
1668 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); | 1629 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); |
1669 | wake_up_interruptible_poll(&tty->read_wait, POLLIN); | 1630 | wake_up_interruptible_poll(&tty->read_wait, POLLIN); |
1670 | } | 1631 | } |
@@ -1785,12 +1746,6 @@ static int n_tty_receive_buf2(struct tty_struct *tty, const unsigned char *cp, | |||
1785 | return n_tty_receive_buf_common(tty, cp, fp, count, 1); | 1746 | return n_tty_receive_buf_common(tty, cp, fp, count, 1); |
1786 | } | 1747 | } |
1787 | 1748 | ||
1788 | int is_ignored(int sig) | ||
1789 | { | ||
1790 | return (sigismember(¤t->blocked, sig) || | ||
1791 | current->sighand->action[sig-1].sa.sa_handler == SIG_IGN); | ||
1792 | } | ||
1793 | |||
1794 | /** | 1749 | /** |
1795 | * n_tty_set_termios - termios data changed | 1750 | * n_tty_set_termios - termios data changed |
1796 | * @tty: terminal | 1751 | * @tty: terminal |
@@ -1937,7 +1892,6 @@ static int n_tty_open(struct tty_struct *tty) | |||
1937 | reset_buffer_flags(tty->disc_data); | 1892 | reset_buffer_flags(tty->disc_data); |
1938 | ldata->column = 0; | 1893 | ldata->column = 0; |
1939 | ldata->canon_column = 0; | 1894 | ldata->canon_column = 0; |
1940 | ldata->minimum_to_wake = 1; | ||
1941 | ldata->num_overrun = 0; | 1895 | ldata->num_overrun = 0; |
1942 | ldata->no_room = 0; | 1896 | ldata->no_room = 0; |
1943 | ldata->lnext = 0; | 1897 | ldata->lnext = 0; |
@@ -2015,7 +1969,7 @@ static int copy_from_read_buf(struct tty_struct *tty, | |||
2015 | retval = copy_to_user(*b, from, n); | 1969 | retval = copy_to_user(*b, from, n); |
2016 | n -= retval; | 1970 | n -= retval; |
2017 | is_eof = n == 1 && *from == EOF_CHAR(tty); | 1971 | is_eof = n == 1 && *from == EOF_CHAR(tty); |
2018 | tty_audit_add_data(tty, from, n, ldata->icanon); | 1972 | tty_audit_add_data(tty, from, n); |
2019 | smp_store_release(&ldata->read_tail, ldata->read_tail + n); | 1973 | smp_store_release(&ldata->read_tail, ldata->read_tail + n); |
2020 | /* Turn single EOF into zero-length read */ | 1974 | /* Turn single EOF into zero-length read */ |
2021 | if (L_EXTPROC(tty) && ldata->icanon && is_eof && | 1975 | if (L_EXTPROC(tty) && ldata->icanon && is_eof && |
@@ -2109,7 +2063,7 @@ static int canon_copy_from_read_buf(struct tty_struct *tty, | |||
2109 | ldata->line_start = ldata->read_tail; | 2063 | ldata->line_start = ldata->read_tail; |
2110 | else | 2064 | else |
2111 | ldata->push = 0; | 2065 | ldata->push = 0; |
2112 | tty_audit_push(tty); | 2066 | tty_audit_push(); |
2113 | } | 2067 | } |
2114 | return 0; | 2068 | return 0; |
2115 | } | 2069 | } |
@@ -2200,14 +2154,9 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, | |||
2200 | minimum = MIN_CHAR(tty); | 2154 | minimum = MIN_CHAR(tty); |
2201 | if (minimum) { | 2155 | if (minimum) { |
2202 | time = (HZ / 10) * TIME_CHAR(tty); | 2156 | time = (HZ / 10) * TIME_CHAR(tty); |
2203 | if (time) | ||
2204 | ldata->minimum_to_wake = 1; | ||
2205 | else if (!waitqueue_active(&tty->read_wait) || | ||
2206 | (ldata->minimum_to_wake > minimum)) | ||
2207 | ldata->minimum_to_wake = minimum; | ||
2208 | } else { | 2157 | } else { |
2209 | timeout = (HZ / 10) * TIME_CHAR(tty); | 2158 | timeout = (HZ / 10) * TIME_CHAR(tty); |
2210 | ldata->minimum_to_wake = minimum = 1; | 2159 | minimum = 1; |
2211 | } | 2160 | } |
2212 | } | 2161 | } |
2213 | 2162 | ||
@@ -2225,19 +2174,15 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, | |||
2225 | cs = tty->link->ctrl_status; | 2174 | cs = tty->link->ctrl_status; |
2226 | tty->link->ctrl_status = 0; | 2175 | tty->link->ctrl_status = 0; |
2227 | spin_unlock_irq(&tty->link->ctrl_lock); | 2176 | spin_unlock_irq(&tty->link->ctrl_lock); |
2228 | if (tty_put_user(tty, cs, b++)) { | 2177 | if (put_user(cs, b)) { |
2229 | retval = -EFAULT; | 2178 | retval = -EFAULT; |
2230 | b--; | ||
2231 | break; | 2179 | break; |
2232 | } | 2180 | } |
2181 | b++; | ||
2233 | nr--; | 2182 | nr--; |
2234 | break; | 2183 | break; |
2235 | } | 2184 | } |
2236 | 2185 | ||
2237 | if (((minimum - (b - buf)) < ldata->minimum_to_wake) && | ||
2238 | ((minimum - (b - buf)) >= 1)) | ||
2239 | ldata->minimum_to_wake = (minimum - (b - buf)); | ||
2240 | |||
2241 | done = check_other_done(tty); | 2186 | done = check_other_done(tty); |
2242 | 2187 | ||
2243 | if (!input_available_p(tty, 0)) { | 2188 | if (!input_available_p(tty, 0)) { |
@@ -2275,11 +2220,11 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, | |||
2275 | 2220 | ||
2276 | /* Deal with packet mode. */ | 2221 | /* Deal with packet mode. */ |
2277 | if (packet && b == buf) { | 2222 | if (packet && b == buf) { |
2278 | if (tty_put_user(tty, TIOCPKT_DATA, b++)) { | 2223 | if (put_user(TIOCPKT_DATA, b)) { |
2279 | retval = -EFAULT; | 2224 | retval = -EFAULT; |
2280 | b--; | ||
2281 | break; | 2225 | break; |
2282 | } | 2226 | } |
2227 | b++; | ||
2283 | nr--; | 2228 | nr--; |
2284 | } | 2229 | } |
2285 | 2230 | ||
@@ -2303,9 +2248,6 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, | |||
2303 | up_read(&tty->termios_rwsem); | 2248 | up_read(&tty->termios_rwsem); |
2304 | 2249 | ||
2305 | remove_wait_queue(&tty->read_wait, &wait); | 2250 | remove_wait_queue(&tty->read_wait, &wait); |
2306 | if (!waitqueue_active(&tty->read_wait)) | ||
2307 | ldata->minimum_to_wake = minimum; | ||
2308 | |||
2309 | mutex_unlock(&ldata->atomic_read_lock); | 2251 | mutex_unlock(&ldata->atomic_read_lock); |
2310 | 2252 | ||
2311 | if (b - buf) | 2253 | if (b - buf) |
@@ -2417,7 +2359,7 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, | |||
2417 | } | 2359 | } |
2418 | break_out: | 2360 | break_out: |
2419 | remove_wait_queue(&tty->write_wait, &wait); | 2361 | remove_wait_queue(&tty->write_wait, &wait); |
2420 | if (b - buf != nr && tty->fasync) | 2362 | if (nr && tty->fasync) |
2421 | set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); | 2363 | set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); |
2422 | up_read(&tty->termios_rwsem); | 2364 | up_read(&tty->termios_rwsem); |
2423 | return (b - buf) ? b - buf : retval; | 2365 | return (b - buf) ? b - buf : retval; |
@@ -2440,7 +2382,6 @@ break_out: | |||
2440 | static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file, | 2382 | static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file, |
2441 | poll_table *wait) | 2383 | poll_table *wait) |
2442 | { | 2384 | { |
2443 | struct n_tty_data *ldata = tty->disc_data; | ||
2444 | unsigned int mask = 0; | 2385 | unsigned int mask = 0; |
2445 | 2386 | ||
2446 | poll_wait(file, &tty->read_wait, wait); | 2387 | poll_wait(file, &tty->read_wait, wait); |
@@ -2453,12 +2394,6 @@ static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file, | |||
2453 | mask |= POLLPRI | POLLIN | POLLRDNORM; | 2394 | mask |= POLLPRI | POLLIN | POLLRDNORM; |
2454 | if (tty_hung_up_p(file)) | 2395 | if (tty_hung_up_p(file)) |
2455 | mask |= POLLHUP; | 2396 | mask |= POLLHUP; |
2456 | if (!(mask & (POLLHUP | POLLIN | POLLRDNORM))) { | ||
2457 | if (MIN_CHAR(tty) && !TIME_CHAR(tty)) | ||
2458 | ldata->minimum_to_wake = MIN_CHAR(tty); | ||
2459 | else | ||
2460 | ldata->minimum_to_wake = 1; | ||
2461 | } | ||
2462 | if (tty->ops->write && !tty_is_writelocked(tty) && | 2397 | if (tty->ops->write && !tty_is_writelocked(tty) && |
2463 | tty_chars_in_buffer(tty) < WAKEUP_CHARS && | 2398 | tty_chars_in_buffer(tty) < WAKEUP_CHARS && |
2464 | tty_write_room(tty) > 0) | 2399 | tty_write_room(tty) > 0) |
@@ -2507,25 +2442,12 @@ static int n_tty_ioctl(struct tty_struct *tty, struct file *file, | |||
2507 | } | 2442 | } |
2508 | } | 2443 | } |
2509 | 2444 | ||
2510 | static void n_tty_fasync(struct tty_struct *tty, int on) | 2445 | static struct tty_ldisc_ops n_tty_ops = { |
2511 | { | ||
2512 | struct n_tty_data *ldata = tty->disc_data; | ||
2513 | |||
2514 | if (!waitqueue_active(&tty->read_wait)) { | ||
2515 | if (on) | ||
2516 | ldata->minimum_to_wake = 1; | ||
2517 | else if (!tty->fasync) | ||
2518 | ldata->minimum_to_wake = N_TTY_BUF_SIZE; | ||
2519 | } | ||
2520 | } | ||
2521 | |||
2522 | struct tty_ldisc_ops tty_ldisc_N_TTY = { | ||
2523 | .magic = TTY_LDISC_MAGIC, | 2446 | .magic = TTY_LDISC_MAGIC, |
2524 | .name = "n_tty", | 2447 | .name = "n_tty", |
2525 | .open = n_tty_open, | 2448 | .open = n_tty_open, |
2526 | .close = n_tty_close, | 2449 | .close = n_tty_close, |
2527 | .flush_buffer = n_tty_flush_buffer, | 2450 | .flush_buffer = n_tty_flush_buffer, |
2528 | .chars_in_buffer = n_tty_chars_in_buffer, | ||
2529 | .read = n_tty_read, | 2451 | .read = n_tty_read, |
2530 | .write = n_tty_write, | 2452 | .write = n_tty_write, |
2531 | .ioctl = n_tty_ioctl, | 2453 | .ioctl = n_tty_ioctl, |
@@ -2533,7 +2455,6 @@ struct tty_ldisc_ops tty_ldisc_N_TTY = { | |||
2533 | .poll = n_tty_poll, | 2455 | .poll = n_tty_poll, |
2534 | .receive_buf = n_tty_receive_buf, | 2456 | .receive_buf = n_tty_receive_buf, |
2535 | .write_wakeup = n_tty_write_wakeup, | 2457 | .write_wakeup = n_tty_write_wakeup, |
2536 | .fasync = n_tty_fasync, | ||
2537 | .receive_buf2 = n_tty_receive_buf2, | 2458 | .receive_buf2 = n_tty_receive_buf2, |
2538 | }; | 2459 | }; |
2539 | 2460 | ||
@@ -2541,14 +2462,18 @@ struct tty_ldisc_ops tty_ldisc_N_TTY = { | |||
2541 | * n_tty_inherit_ops - inherit N_TTY methods | 2462 | * n_tty_inherit_ops - inherit N_TTY methods |
2542 | * @ops: struct tty_ldisc_ops where to save N_TTY methods | 2463 | * @ops: struct tty_ldisc_ops where to save N_TTY methods |
2543 | * | 2464 | * |
2544 | * Enables a 'subclass' line discipline to 'inherit' N_TTY | 2465 | * Enables a 'subclass' line discipline to 'inherit' N_TTY methods. |
2545 | * methods. | ||
2546 | */ | 2466 | */ |
2547 | 2467 | ||
2548 | void n_tty_inherit_ops(struct tty_ldisc_ops *ops) | 2468 | void n_tty_inherit_ops(struct tty_ldisc_ops *ops) |
2549 | { | 2469 | { |
2550 | *ops = tty_ldisc_N_TTY; | 2470 | *ops = n_tty_ops; |
2551 | ops->owner = NULL; | 2471 | ops->owner = NULL; |
2552 | ops->refcount = ops->flags = 0; | 2472 | ops->refcount = ops->flags = 0; |
2553 | } | 2473 | } |
2554 | EXPORT_SYMBOL_GPL(n_tty_inherit_ops); | 2474 | EXPORT_SYMBOL_GPL(n_tty_inherit_ops); |
2475 | |||
2476 | void __init n_tty_init(void) | ||
2477 | { | ||
2478 | tty_register_ldisc(N_TTY, &n_tty_ops); | ||
2479 | } | ||
diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index 80f9de907563..5cc80b80c82b 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c | |||
@@ -823,7 +823,7 @@ static int receive_data(enum port_type index, struct nozomi *dc) | |||
823 | struct tty_struct *tty = tty_port_tty_get(&port->port); | 823 | struct tty_struct *tty = tty_port_tty_get(&port->port); |
824 | int i, ret; | 824 | int i, ret; |
825 | 825 | ||
826 | read_mem32((u32 *) &size, addr, 4); | 826 | size = __le32_to_cpu(readl(addr)); |
827 | /* DBG1( "%d bytes port: %d", size, index); */ | 827 | /* DBG1( "%d bytes port: %d", size, index); */ |
828 | 828 | ||
829 | if (tty && test_bit(TTY_THROTTLED, &tty->flags)) { | 829 | if (tty && test_bit(TTY_THROTTLED, &tty->flags)) { |
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 2348fa613707..e16a49b507ef 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c | |||
@@ -263,8 +263,7 @@ static void pty_set_termios(struct tty_struct *tty, | |||
263 | { | 263 | { |
264 | /* See if packet mode change of state. */ | 264 | /* See if packet mode change of state. */ |
265 | if (tty->link && tty->link->packet) { | 265 | if (tty->link && tty->link->packet) { |
266 | int extproc = (old_termios->c_lflag & EXTPROC) | | 266 | int extproc = (old_termios->c_lflag & EXTPROC) | L_EXTPROC(tty); |
267 | (tty->termios.c_lflag & EXTPROC); | ||
268 | int old_flow = ((old_termios->c_iflag & IXON) && | 267 | int old_flow = ((old_termios->c_iflag & IXON) && |
269 | (old_termios->c_cc[VSTOP] == '\023') && | 268 | (old_termios->c_cc[VSTOP] == '\023') && |
270 | (old_termios->c_cc[VSTART] == '\021')); | 269 | (old_termios->c_cc[VSTART] == '\021')); |
@@ -406,13 +405,8 @@ static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty, | |||
406 | if (legacy) { | 405 | if (legacy) { |
407 | /* We always use new tty termios data so we can do this | 406 | /* We always use new tty termios data so we can do this |
408 | the easy way .. */ | 407 | the easy way .. */ |
409 | retval = tty_init_termios(tty); | 408 | tty_init_termios(tty); |
410 | if (retval) | 409 | tty_init_termios(o_tty); |
411 | goto err_deinit_tty; | ||
412 | |||
413 | retval = tty_init_termios(o_tty); | ||
414 | if (retval) | ||
415 | goto err_free_termios; | ||
416 | 410 | ||
417 | driver->other->ttys[idx] = o_tty; | 411 | driver->other->ttys[idx] = o_tty; |
418 | driver->ttys[idx] = tty; | 412 | driver->ttys[idx] = tty; |
@@ -444,12 +438,7 @@ static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty, | |||
444 | tty->count++; | 438 | tty->count++; |
445 | o_tty->count++; | 439 | o_tty->count++; |
446 | return 0; | 440 | return 0; |
447 | err_free_termios: | 441 | |
448 | if (legacy) | ||
449 | tty_free_termios(tty); | ||
450 | err_deinit_tty: | ||
451 | deinitialize_tty_struct(o_tty); | ||
452 | free_tty_struct(o_tty); | ||
453 | err_put_module: | 442 | err_put_module: |
454 | module_put(driver->other->owner); | 443 | module_put(driver->other->owner); |
455 | err: | 444 | err: |
@@ -666,20 +655,13 @@ static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver, | |||
666 | return tty; | 655 | return tty; |
667 | } | 656 | } |
668 | 657 | ||
669 | /* We have no need to install and remove our tty objects as devpts does all | ||
670 | the work for us */ | ||
671 | |||
672 | static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty) | 658 | static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty) |
673 | { | 659 | { |
674 | return pty_common_install(driver, tty, false); | 660 | return pty_common_install(driver, tty, false); |
675 | } | 661 | } |
676 | 662 | ||
677 | static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) | ||
678 | { | ||
679 | } | ||
680 | |||
681 | /* this is called once with whichever end is closed last */ | 663 | /* this is called once with whichever end is closed last */ |
682 | static void pty_unix98_shutdown(struct tty_struct *tty) | 664 | static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) |
683 | { | 665 | { |
684 | struct inode *ptmx_inode; | 666 | struct inode *ptmx_inode; |
685 | 667 | ||
@@ -704,7 +686,6 @@ static const struct tty_operations ptm_unix98_ops = { | |||
704 | .unthrottle = pty_unthrottle, | 686 | .unthrottle = pty_unthrottle, |
705 | .ioctl = pty_unix98_ioctl, | 687 | .ioctl = pty_unix98_ioctl, |
706 | .resize = pty_resize, | 688 | .resize = pty_resize, |
707 | .shutdown = pty_unix98_shutdown, | ||
708 | .cleanup = pty_cleanup | 689 | .cleanup = pty_cleanup |
709 | }; | 690 | }; |
710 | 691 | ||
@@ -722,7 +703,6 @@ static const struct tty_operations pty_unix98_ops = { | |||
722 | .set_termios = pty_set_termios, | 703 | .set_termios = pty_set_termios, |
723 | .start = pty_start, | 704 | .start = pty_start, |
724 | .stop = pty_stop, | 705 | .stop = pty_stop, |
725 | .shutdown = pty_unix98_shutdown, | ||
726 | .cleanup = pty_cleanup, | 706 | .cleanup = pty_cleanup, |
727 | }; | 707 | }; |
728 | 708 | ||
diff --git a/drivers/tty/rocket.c b/drivers/tty/rocket.c index 802eac7e561b..0b802cdd70d0 100644 --- a/drivers/tty/rocket.c +++ b/drivers/tty/rocket.c | |||
@@ -643,7 +643,6 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev) | |||
643 | info->chan = chan; | 643 | info->chan = chan; |
644 | tty_port_init(&info->port); | 644 | tty_port_init(&info->port); |
645 | info->port.ops = &rocket_port_ops; | 645 | info->port.ops = &rocket_port_ops; |
646 | init_completion(&info->close_wait); | ||
647 | info->flags &= ~ROCKET_MODE_MASK; | 646 | info->flags &= ~ROCKET_MODE_MASK; |
648 | switch (pc104[board][line]) { | 647 | switch (pc104[board][line]) { |
649 | case 422: | 648 | case 422: |
@@ -960,7 +959,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp) | |||
960 | tty->alt_speed = 460800; | 959 | tty->alt_speed = 460800; |
961 | 960 | ||
962 | configure_r_port(tty, info, NULL); | 961 | configure_r_port(tty, info, NULL); |
963 | if (tty->termios.c_cflag & CBAUD) { | 962 | if (C_BAUD(tty)) { |
964 | sSetDTR(cp); | 963 | sSetDTR(cp); |
965 | sSetRTS(cp); | 964 | sSetRTS(cp); |
966 | } | 965 | } |
@@ -1043,13 +1042,12 @@ static void rp_close(struct tty_struct *tty, struct file *filp) | |||
1043 | } | 1042 | } |
1044 | } | 1043 | } |
1045 | spin_lock_irq(&port->lock); | 1044 | spin_lock_irq(&port->lock); |
1046 | info->port.flags &= ~(ASYNC_INITIALIZED | ASYNC_CLOSING | ASYNC_NORMAL_ACTIVE); | 1045 | info->port.flags &= ~(ASYNC_INITIALIZED | ASYNC_NORMAL_ACTIVE); |
1047 | tty->closing = 0; | 1046 | tty->closing = 0; |
1048 | spin_unlock_irq(&port->lock); | 1047 | spin_unlock_irq(&port->lock); |
1049 | mutex_unlock(&port->mutex); | 1048 | mutex_unlock(&port->mutex); |
1050 | tty_port_tty_set(port, NULL); | 1049 | tty_port_tty_set(port, NULL); |
1051 | 1050 | ||
1052 | complete_all(&info->close_wait); | ||
1053 | atomic_dec(&rp_num_ports_open); | 1051 | atomic_dec(&rp_num_ports_open); |
1054 | 1052 | ||
1055 | #ifdef ROCKET_DEBUG_OPEN | 1053 | #ifdef ROCKET_DEBUG_OPEN |
@@ -1086,18 +1084,18 @@ static void rp_set_termios(struct tty_struct *tty, | |||
1086 | cp = &info->channel; | 1084 | cp = &info->channel; |
1087 | 1085 | ||
1088 | /* Handle transition to B0 status */ | 1086 | /* Handle transition to B0 status */ |
1089 | if ((old_termios->c_cflag & CBAUD) && !(tty->termios.c_cflag & CBAUD)) { | 1087 | if ((old_termios->c_cflag & CBAUD) && !C_BAUD(tty)) { |
1090 | sClrDTR(cp); | 1088 | sClrDTR(cp); |
1091 | sClrRTS(cp); | 1089 | sClrRTS(cp); |
1092 | } | 1090 | } |
1093 | 1091 | ||
1094 | /* Handle transition away from B0 status */ | 1092 | /* Handle transition away from B0 status */ |
1095 | if (!(old_termios->c_cflag & CBAUD) && (tty->termios.c_cflag & CBAUD)) { | 1093 | if (!(old_termios->c_cflag & CBAUD) && C_BAUD(tty)) { |
1096 | sSetRTS(cp); | 1094 | sSetRTS(cp); |
1097 | sSetDTR(cp); | 1095 | sSetDTR(cp); |
1098 | } | 1096 | } |
1099 | 1097 | ||
1100 | if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios.c_cflag & CRTSCTS)) | 1098 | if ((old_termios->c_cflag & CRTSCTS) && !C_CRTSCTS(tty)) |
1101 | rp_start(tty); | 1099 | rp_start(tty); |
1102 | } | 1100 | } |
1103 | 1101 | ||
@@ -1360,8 +1358,7 @@ static void rp_throttle(struct tty_struct *tty) | |||
1360 | struct r_port *info = tty->driver_data; | 1358 | struct r_port *info = tty->driver_data; |
1361 | 1359 | ||
1362 | #ifdef ROCKET_DEBUG_THROTTLE | 1360 | #ifdef ROCKET_DEBUG_THROTTLE |
1363 | printk(KERN_INFO "throttle %s: %d....\n", tty->name, | 1361 | printk(KERN_INFO "throttle %s ....\n", tty->name); |
1364 | tty->ldisc.chars_in_buffer(tty)); | ||
1365 | #endif | 1362 | #endif |
1366 | 1363 | ||
1367 | if (rocket_paranoia_check(info, "rp_throttle")) | 1364 | if (rocket_paranoia_check(info, "rp_throttle")) |
@@ -1377,8 +1374,7 @@ static void rp_unthrottle(struct tty_struct *tty) | |||
1377 | { | 1374 | { |
1378 | struct r_port *info = tty->driver_data; | 1375 | struct r_port *info = tty->driver_data; |
1379 | #ifdef ROCKET_DEBUG_THROTTLE | 1376 | #ifdef ROCKET_DEBUG_THROTTLE |
1380 | printk(KERN_INFO "unthrottle %s: %d....\n", tty->name, | 1377 | printk(KERN_INFO "unthrottle %s ....\n", tty->name); |
1381 | tty->ldisc.chars_in_buffer(tty)); | ||
1382 | #endif | 1378 | #endif |
1383 | 1379 | ||
1384 | if (rocket_paranoia_check(info, "rp_unthrottle")) | 1380 | if (rocket_paranoia_check(info, "rp_unthrottle")) |
diff --git a/drivers/tty/rocket_int.h b/drivers/tty/rocket_int.h index 67e0f1e778a2..ef1e1be6b26d 100644 --- a/drivers/tty/rocket_int.h +++ b/drivers/tty/rocket_int.h | |||
@@ -1144,7 +1144,6 @@ struct r_port { | |||
1144 | int read_status_mask; | 1144 | int read_status_mask; |
1145 | int cps; | 1145 | int cps; |
1146 | 1146 | ||
1147 | struct completion close_wait; /* Not yet matching the core */ | ||
1148 | spinlock_t slock; | 1147 | spinlock_t slock; |
1149 | struct mutex write_mtx; | 1148 | struct mutex write_mtx; |
1150 | }; | 1149 | }; |
diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c deleted file mode 100644 index 0982c1a44187..000000000000 --- a/drivers/tty/serial/68328serial.c +++ /dev/null | |||
@@ -1,1322 +0,0 @@ | |||
1 | /* 68328serial.c: Serial port driver for 68328 microcontroller | ||
2 | * | ||
3 | * Copyright (C) 1995 David S. Miller <davem@caip.rutgers.edu> | ||
4 | * Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com> | ||
5 | * Copyright (C) 1998, 1999 D. Jeff Dionne <jeff@uclinux.org> | ||
6 | * Copyright (C) 1999 Vladimir Gurevich <vgurevic@cisco.com> | ||
7 | * Copyright (C) 2002-2003 David McCullough <davidm@snapgear.com> | ||
8 | * Copyright (C) 2002 Greg Ungerer <gerg@snapgear.com> | ||
9 | * | ||
10 | * VZ Support/Fixes Evan Stawnyczy <e@lineo.ca> | ||
11 | * Multiple UART support Daniel Potts <danielp@cse.unsw.edu.au> | ||
12 | * Power management support Daniel Potts <danielp@cse.unsw.edu.au> | ||
13 | * VZ Second Serial Port enable Phil Wilshire | ||
14 | * 2.4/2.5 port David McCullough | ||
15 | */ | ||
16 | |||
17 | #include <linux/module.h> | ||
18 | #include <linux/errno.h> | ||
19 | #include <linux/serial.h> | ||
20 | #include <linux/signal.h> | ||
21 | #include <linux/sched.h> | ||
22 | #include <linux/timer.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/tty.h> | ||
25 | #include <linux/tty_flip.h> | ||
26 | #include <linux/major.h> | ||
27 | #include <linux/string.h> | ||
28 | #include <linux/fcntl.h> | ||
29 | #include <linux/mm.h> | ||
30 | #include <linux/kernel.h> | ||
31 | #include <linux/console.h> | ||
32 | #include <linux/reboot.h> | ||
33 | #include <linux/keyboard.h> | ||
34 | #include <linux/init.h> | ||
35 | #include <linux/pm.h> | ||
36 | #include <linux/bitops.h> | ||
37 | #include <linux/delay.h> | ||
38 | #include <linux/gfp.h> | ||
39 | |||
40 | #include <asm/io.h> | ||
41 | #include <asm/irq.h> | ||
42 | #include <asm/delay.h> | ||
43 | #include <asm/uaccess.h> | ||
44 | |||
45 | /* (es) */ | ||
46 | /* note: perhaps we can murge these files, so that you can just | ||
47 | * define 1 of them, and they can sort that out for themselves | ||
48 | */ | ||
49 | #if defined(CONFIG_M68EZ328) | ||
50 | #include <asm/MC68EZ328.h> | ||
51 | #else | ||
52 | #if defined(CONFIG_M68VZ328) | ||
53 | #include <asm/MC68VZ328.h> | ||
54 | #else | ||
55 | #include <asm/MC68328.h> | ||
56 | #endif /* CONFIG_M68VZ328 */ | ||
57 | #endif /* CONFIG_M68EZ328 */ | ||
58 | |||
59 | /* Turn off usage of real serial interrupt code, to "support" Copilot */ | ||
60 | #ifdef CONFIG_XCOPILOT_BUGS | ||
61 | #undef USE_INTS | ||
62 | #else | ||
63 | #define USE_INTS | ||
64 | #endif | ||
65 | |||
66 | /* | ||
67 | * I believe this is the optimal setting that reduces the number of interrupts. | ||
68 | * At high speeds the output might become a little "bursted" (use USTCNT_TXHE | ||
69 | * if that bothers you), but in most cases it will not, since we try to | ||
70 | * transmit characters every time rs_interrupt is called. Thus, quite often | ||
71 | * you'll see that a receive interrupt occures before the transmit one. | ||
72 | * -- Vladimir Gurevich | ||
73 | */ | ||
74 | #define USTCNT_TX_INTR_MASK (USTCNT_TXEE) | ||
75 | |||
76 | /* | ||
77 | * 68328 and 68EZ328 UARTS are a little bit different. EZ328 has special | ||
78 | * "Old data interrupt" which occures whenever the data stay in the FIFO | ||
79 | * longer than 30 bits time. This allows us to use FIFO without compromising | ||
80 | * latency. '328 does not have this feature and without the real 328-based | ||
81 | * board I would assume that RXRE is the safest setting. | ||
82 | * | ||
83 | * For EZ328 I use RXHE (Half empty) interrupt to reduce the number of | ||
84 | * interrupts. RXFE (receive queue full) causes the system to lose data | ||
85 | * at least at 115200 baud | ||
86 | * | ||
87 | * If your board is busy doing other stuff, you might consider to use | ||
88 | * RXRE (data ready intrrupt) instead. | ||
89 | * | ||
90 | * The other option is to make these INTR masks run-time configurable, so | ||
91 | * that people can dynamically adapt them according to the current usage. | ||
92 | * -- Vladimir Gurevich | ||
93 | */ | ||
94 | |||
95 | /* (es) */ | ||
96 | #if defined(CONFIG_M68EZ328) || defined(CONFIG_M68VZ328) | ||
97 | #define USTCNT_RX_INTR_MASK (USTCNT_RXHE | USTCNT_ODEN) | ||
98 | #elif defined(CONFIG_M68328) | ||
99 | #define USTCNT_RX_INTR_MASK (USTCNT_RXRE) | ||
100 | #else | ||
101 | #error Please, define the Rx interrupt events for your CPU | ||
102 | #endif | ||
103 | /* (/es) */ | ||
104 | |||
105 | /* | ||
106 | * This is our internal structure for each serial port's state. | ||
107 | */ | ||
108 | struct m68k_serial { | ||
109 | struct tty_port tport; | ||
110 | char is_cons; /* Is this our console. */ | ||
111 | int magic; | ||
112 | int baud_base; | ||
113 | int port; | ||
114 | int irq; | ||
115 | int type; /* UART type */ | ||
116 | int custom_divisor; | ||
117 | int x_char; /* xon/xoff character */ | ||
118 | int line; | ||
119 | unsigned char *xmit_buf; | ||
120 | int xmit_head; | ||
121 | int xmit_tail; | ||
122 | int xmit_cnt; | ||
123 | }; | ||
124 | |||
125 | #define SERIAL_MAGIC 0x5301 | ||
126 | |||
127 | /* | ||
128 | * Define the number of ports supported and their irqs. | ||
129 | */ | ||
130 | #define NR_PORTS 1 | ||
131 | |||
132 | static struct m68k_serial m68k_soft[NR_PORTS]; | ||
133 | |||
134 | static unsigned int uart_irqs[NR_PORTS] = { UART_IRQ_NUM }; | ||
135 | |||
136 | /* multiple ports are contiguous in memory */ | ||
137 | m68328_uart *uart_addr = (m68328_uart *)USTCNT_ADDR; | ||
138 | |||
139 | struct tty_driver *serial_driver; | ||
140 | |||
141 | static void change_speed(struct m68k_serial *info, struct tty_struct *tty); | ||
142 | |||
143 | /* | ||
144 | * Setup for console. Argument comes from the boot command line. | ||
145 | */ | ||
146 | |||
147 | /* note: this is messy, but it works, again, perhaps defined somewhere else?*/ | ||
148 | #ifdef CONFIG_M68VZ328 | ||
149 | #define CONSOLE_BAUD_RATE 19200 | ||
150 | #define DEFAULT_CBAUD B19200 | ||
151 | #endif | ||
152 | |||
153 | |||
154 | #ifndef CONSOLE_BAUD_RATE | ||
155 | #define CONSOLE_BAUD_RATE 9600 | ||
156 | #define DEFAULT_CBAUD B9600 | ||
157 | #endif | ||
158 | |||
159 | |||
160 | static int m68328_console_initted; | ||
161 | static int m68328_console_baud = CONSOLE_BAUD_RATE; | ||
162 | static int m68328_console_cbaud = DEFAULT_CBAUD; | ||
163 | |||
164 | |||
165 | static inline int serial_paranoia_check(struct m68k_serial *info, | ||
166 | char *name, const char *routine) | ||
167 | { | ||
168 | #ifdef SERIAL_PARANOIA_CHECK | ||
169 | static const char *badmagic = | ||
170 | "Warning: bad magic number for serial struct %s in %s\n"; | ||
171 | static const char *badinfo = | ||
172 | "Warning: null m68k_serial for %s in %s\n"; | ||
173 | |||
174 | if (!info) { | ||
175 | printk(badinfo, name, routine); | ||
176 | return 1; | ||
177 | } | ||
178 | if (info->magic != SERIAL_MAGIC) { | ||
179 | printk(badmagic, name, routine); | ||
180 | return 1; | ||
181 | } | ||
182 | #endif | ||
183 | return 0; | ||
184 | } | ||
185 | |||
186 | /* | ||
187 | * This is used to figure out the divisor speeds and the timeouts | ||
188 | */ | ||
189 | static int baud_table[] = { | ||
190 | 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, | ||
191 | 9600, 19200, 38400, 57600, 115200, 0 }; | ||
192 | |||
193 | /* Utility routines */ | ||
194 | static inline int get_baud(struct m68k_serial *ss) | ||
195 | { | ||
196 | unsigned long result = 115200; | ||
197 | unsigned short int baud = uart_addr[ss->line].ubaud; | ||
198 | if (GET_FIELD(baud, UBAUD_PRESCALER) == 0x38) result = 38400; | ||
199 | result >>= GET_FIELD(baud, UBAUD_DIVIDE); | ||
200 | |||
201 | return result; | ||
202 | } | ||
203 | |||
204 | /* | ||
205 | * ------------------------------------------------------------ | ||
206 | * rs_stop() and rs_start() | ||
207 | * | ||
208 | * This routines are called before setting or resetting tty->stopped. | ||
209 | * They enable or disable transmitter interrupts, as necessary. | ||
210 | * ------------------------------------------------------------ | ||
211 | */ | ||
212 | static void rs_stop(struct tty_struct *tty) | ||
213 | { | ||
214 | struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; | ||
215 | m68328_uart *uart = &uart_addr[info->line]; | ||
216 | unsigned long flags; | ||
217 | |||
218 | if (serial_paranoia_check(info, tty->name, "rs_stop")) | ||
219 | return; | ||
220 | |||
221 | local_irq_save(flags); | ||
222 | uart->ustcnt &= ~USTCNT_TXEN; | ||
223 | local_irq_restore(flags); | ||
224 | } | ||
225 | |||
226 | static int rs_put_char(char ch) | ||
227 | { | ||
228 | unsigned long flags; | ||
229 | int loops = 0; | ||
230 | |||
231 | local_irq_save(flags); | ||
232 | |||
233 | while (!(UTX & UTX_TX_AVAIL) && (loops < 1000)) { | ||
234 | loops++; | ||
235 | udelay(5); | ||
236 | } | ||
237 | |||
238 | UTX_TXDATA = ch; | ||
239 | udelay(5); | ||
240 | local_irq_restore(flags); | ||
241 | return 1; | ||
242 | } | ||
243 | |||
244 | static void rs_start(struct tty_struct *tty) | ||
245 | { | ||
246 | struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; | ||
247 | m68328_uart *uart = &uart_addr[info->line]; | ||
248 | unsigned long flags; | ||
249 | |||
250 | if (serial_paranoia_check(info, tty->name, "rs_start")) | ||
251 | return; | ||
252 | |||
253 | local_irq_save(flags); | ||
254 | if (info->xmit_cnt && info->xmit_buf && !(uart->ustcnt & USTCNT_TXEN)) { | ||
255 | #ifdef USE_INTS | ||
256 | uart->ustcnt |= USTCNT_TXEN | USTCNT_TX_INTR_MASK; | ||
257 | #else | ||
258 | uart->ustcnt |= USTCNT_TXEN; | ||
259 | #endif | ||
260 | } | ||
261 | local_irq_restore(flags); | ||
262 | } | ||
263 | |||
264 | static void receive_chars(struct m68k_serial *info, unsigned short rx) | ||
265 | { | ||
266 | m68328_uart *uart = &uart_addr[info->line]; | ||
267 | unsigned char ch, flag; | ||
268 | |||
269 | /* | ||
270 | * This do { } while() loop will get ALL chars out of Rx FIFO | ||
271 | */ | ||
272 | #ifndef CONFIG_XCOPILOT_BUGS | ||
273 | do { | ||
274 | #endif | ||
275 | ch = GET_FIELD(rx, URX_RXDATA); | ||
276 | |||
277 | if (info->is_cons) { | ||
278 | if (URX_BREAK & rx) { /* whee, break received */ | ||
279 | return; | ||
280 | #ifdef CONFIG_MAGIC_SYSRQ | ||
281 | } else if (ch == 0x10) { /* ^P */ | ||
282 | show_state(); | ||
283 | show_free_areas(0); | ||
284 | show_buffers(); | ||
285 | /* show_net_buffers(); */ | ||
286 | return; | ||
287 | } else if (ch == 0x12) { /* ^R */ | ||
288 | emergency_restart(); | ||
289 | return; | ||
290 | #endif /* CONFIG_MAGIC_SYSRQ */ | ||
291 | } | ||
292 | } | ||
293 | |||
294 | flag = TTY_NORMAL; | ||
295 | |||
296 | if (rx & URX_PARITY_ERROR) | ||
297 | flag = TTY_PARITY; | ||
298 | else if (rx & URX_OVRUN) | ||
299 | flag = TTY_OVERRUN; | ||
300 | else if (rx & URX_FRAME_ERROR) | ||
301 | flag = TTY_FRAME; | ||
302 | |||
303 | tty_insert_flip_char(&info->tport, ch, flag); | ||
304 | #ifndef CONFIG_XCOPILOT_BUGS | ||
305 | } while ((rx = uart->urx.w) & URX_DATA_READY); | ||
306 | #endif | ||
307 | |||
308 | tty_schedule_flip(&info->tport); | ||
309 | } | ||
310 | |||
311 | static void transmit_chars(struct m68k_serial *info, struct tty_struct *tty) | ||
312 | { | ||
313 | m68328_uart *uart = &uart_addr[info->line]; | ||
314 | |||
315 | if (info->x_char) { | ||
316 | /* Send next char */ | ||
317 | uart->utx.b.txdata = info->x_char; | ||
318 | info->x_char = 0; | ||
319 | goto clear_and_return; | ||
320 | } | ||
321 | |||
322 | if ((info->xmit_cnt <= 0) || !tty || tty->stopped) { | ||
323 | /* That's peculiar... TX ints off */ | ||
324 | uart->ustcnt &= ~USTCNT_TX_INTR_MASK; | ||
325 | goto clear_and_return; | ||
326 | } | ||
327 | |||
328 | /* Send char */ | ||
329 | uart->utx.b.txdata = info->xmit_buf[info->xmit_tail++]; | ||
330 | info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); | ||
331 | info->xmit_cnt--; | ||
332 | |||
333 | if (info->xmit_cnt <= 0) { | ||
334 | /* All done for now... TX ints off */ | ||
335 | uart->ustcnt &= ~USTCNT_TX_INTR_MASK; | ||
336 | goto clear_and_return; | ||
337 | } | ||
338 | |||
339 | clear_and_return: | ||
340 | /* Clear interrupt (should be auto)*/ | ||
341 | return; | ||
342 | } | ||
343 | |||
344 | /* | ||
345 | * This is the serial driver's generic interrupt routine | ||
346 | */ | ||
347 | irqreturn_t rs_interrupt(int irq, void *dev_id) | ||
348 | { | ||
349 | struct m68k_serial *info = dev_id; | ||
350 | struct tty_struct *tty = tty_port_tty_get(&info->tport); | ||
351 | m68328_uart *uart; | ||
352 | unsigned short rx; | ||
353 | unsigned short tx; | ||
354 | |||
355 | uart = &uart_addr[info->line]; | ||
356 | rx = uart->urx.w; | ||
357 | |||
358 | #ifdef USE_INTS | ||
359 | tx = uart->utx.w; | ||
360 | |||
361 | if (rx & URX_DATA_READY) | ||
362 | receive_chars(info, rx); | ||
363 | if (tx & UTX_TX_AVAIL) | ||
364 | transmit_chars(info, tty); | ||
365 | #else | ||
366 | receive_chars(info, rx); | ||
367 | #endif | ||
368 | tty_kref_put(tty); | ||
369 | |||
370 | return IRQ_HANDLED; | ||
371 | } | ||
372 | |||
373 | static int startup(struct m68k_serial *info, struct tty_struct *tty) | ||
374 | { | ||
375 | m68328_uart *uart = &uart_addr[info->line]; | ||
376 | unsigned long flags; | ||
377 | |||
378 | if (info->tport.flags & ASYNC_INITIALIZED) | ||
379 | return 0; | ||
380 | |||
381 | if (!info->xmit_buf) { | ||
382 | info->xmit_buf = (unsigned char *) __get_free_page(GFP_KERNEL); | ||
383 | if (!info->xmit_buf) | ||
384 | return -ENOMEM; | ||
385 | } | ||
386 | |||
387 | local_irq_save(flags); | ||
388 | |||
389 | /* | ||
390 | * Clear the FIFO buffers and disable them | ||
391 | * (they will be reenabled in change_speed()) | ||
392 | */ | ||
393 | |||
394 | uart->ustcnt = USTCNT_UEN; | ||
395 | uart->ustcnt = USTCNT_UEN | USTCNT_RXEN | USTCNT_TXEN; | ||
396 | (void)uart->urx.w; | ||
397 | |||
398 | /* | ||
399 | * Finally, enable sequencing and interrupts | ||
400 | */ | ||
401 | #ifdef USE_INTS | ||
402 | uart->ustcnt = USTCNT_UEN | USTCNT_RXEN | | ||
403 | USTCNT_RX_INTR_MASK | USTCNT_TX_INTR_MASK; | ||
404 | #else | ||
405 | uart->ustcnt = USTCNT_UEN | USTCNT_RXEN | USTCNT_RX_INTR_MASK; | ||
406 | #endif | ||
407 | |||
408 | if (tty) | ||
409 | clear_bit(TTY_IO_ERROR, &tty->flags); | ||
410 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | ||
411 | |||
412 | /* | ||
413 | * and set the speed of the serial port | ||
414 | */ | ||
415 | |||
416 | change_speed(info, tty); | ||
417 | |||
418 | info->tport.flags |= ASYNC_INITIALIZED; | ||
419 | local_irq_restore(flags); | ||
420 | return 0; | ||
421 | } | ||
422 | |||
423 | /* | ||
424 | * This routine will shutdown a serial port; interrupts are disabled, and | ||
425 | * DTR is dropped if the hangup on close termio flag is on. | ||
426 | */ | ||
427 | static void shutdown(struct m68k_serial *info, struct tty_struct *tty) | ||
428 | { | ||
429 | m68328_uart *uart = &uart_addr[info->line]; | ||
430 | unsigned long flags; | ||
431 | |||
432 | uart->ustcnt = 0; /* All off! */ | ||
433 | if (!(info->tport.flags & ASYNC_INITIALIZED)) | ||
434 | return; | ||
435 | |||
436 | local_irq_save(flags); | ||
437 | |||
438 | if (info->xmit_buf) { | ||
439 | free_page((unsigned long) info->xmit_buf); | ||
440 | info->xmit_buf = 0; | ||
441 | } | ||
442 | |||
443 | if (tty) | ||
444 | set_bit(TTY_IO_ERROR, &tty->flags); | ||
445 | |||
446 | info->tport.flags &= ~ASYNC_INITIALIZED; | ||
447 | local_irq_restore(flags); | ||
448 | } | ||
449 | |||
450 | struct { | ||
451 | int divisor, prescale; | ||
452 | } | ||
453 | #ifndef CONFIG_M68VZ328 | ||
454 | hw_baud_table[18] = { | ||
455 | {0, 0}, /* 0 */ | ||
456 | {0, 0}, /* 50 */ | ||
457 | {0, 0}, /* 75 */ | ||
458 | {0, 0}, /* 110 */ | ||
459 | {0, 0}, /* 134 */ | ||
460 | {0, 0}, /* 150 */ | ||
461 | {0, 0}, /* 200 */ | ||
462 | {7, 0x26}, /* 300 */ | ||
463 | {6, 0x26}, /* 600 */ | ||
464 | {5, 0x26}, /* 1200 */ | ||
465 | {0, 0}, /* 1800 */ | ||
466 | {4, 0x26}, /* 2400 */ | ||
467 | {3, 0x26}, /* 4800 */ | ||
468 | {2, 0x26}, /* 9600 */ | ||
469 | {1, 0x26}, /* 19200 */ | ||
470 | {0, 0x26}, /* 38400 */ | ||
471 | {1, 0x38}, /* 57600 */ | ||
472 | {0, 0x38}, /* 115200 */ | ||
473 | }; | ||
474 | #else | ||
475 | hw_baud_table[18] = { | ||
476 | {0, 0}, /* 0 */ | ||
477 | {0, 0}, /* 50 */ | ||
478 | {0, 0}, /* 75 */ | ||
479 | {0, 0}, /* 110 */ | ||
480 | {0, 0}, /* 134 */ | ||
481 | {0, 0}, /* 150 */ | ||
482 | {0, 0}, /* 200 */ | ||
483 | {0, 0}, /* 300 */ | ||
484 | {7, 0x26}, /* 600 */ | ||
485 | {6, 0x26}, /* 1200 */ | ||
486 | {0, 0}, /* 1800 */ | ||
487 | {5, 0x26}, /* 2400 */ | ||
488 | {4, 0x26}, /* 4800 */ | ||
489 | {3, 0x26}, /* 9600 */ | ||
490 | {2, 0x26}, /* 19200 */ | ||
491 | {1, 0x26}, /* 38400 */ | ||
492 | {0, 0x26}, /* 57600 */ | ||
493 | {1, 0x38}, /* 115200 */ | ||
494 | }; | ||
495 | #endif | ||
496 | /* rate = 1036800 / ((65 - prescale) * (1<<divider)) */ | ||
497 | |||
498 | /* | ||
499 | * This routine is called to set the UART divisor registers to match | ||
500 | * the specified baud rate for a serial port. | ||
501 | */ | ||
502 | static void change_speed(struct m68k_serial *info, struct tty_struct *tty) | ||
503 | { | ||
504 | m68328_uart *uart = &uart_addr[info->line]; | ||
505 | unsigned short port; | ||
506 | unsigned short ustcnt; | ||
507 | unsigned cflag; | ||
508 | int i; | ||
509 | |||
510 | cflag = tty->termios.c_cflag; | ||
511 | port = info->port; | ||
512 | if (!port) | ||
513 | return; | ||
514 | |||
515 | ustcnt = uart->ustcnt; | ||
516 | uart->ustcnt = ustcnt & ~USTCNT_TXEN; | ||
517 | |||
518 | i = cflag & CBAUD; | ||
519 | if (i & CBAUDEX) { | ||
520 | i = (i & ~CBAUDEX) + B38400; | ||
521 | } | ||
522 | |||
523 | uart->ubaud = PUT_FIELD(UBAUD_DIVIDE, hw_baud_table[i].divisor) | | ||
524 | PUT_FIELD(UBAUD_PRESCALER, hw_baud_table[i].prescale); | ||
525 | |||
526 | ustcnt &= ~(USTCNT_PARITYEN | USTCNT_ODD_EVEN | USTCNT_STOP | USTCNT_8_7); | ||
527 | |||
528 | if ((cflag & CSIZE) == CS8) | ||
529 | ustcnt |= USTCNT_8_7; | ||
530 | |||
531 | if (cflag & CSTOPB) | ||
532 | ustcnt |= USTCNT_STOP; | ||
533 | |||
534 | if (cflag & PARENB) | ||
535 | ustcnt |= USTCNT_PARITYEN; | ||
536 | if (cflag & PARODD) | ||
537 | ustcnt |= USTCNT_ODD_EVEN; | ||
538 | |||
539 | #ifdef CONFIG_SERIAL_68328_RTS_CTS | ||
540 | if (cflag & CRTSCTS) { | ||
541 | uart->utx.w &= ~UTX_NOCTS; | ||
542 | } else { | ||
543 | uart->utx.w |= UTX_NOCTS; | ||
544 | } | ||
545 | #endif | ||
546 | |||
547 | ustcnt |= USTCNT_TXEN; | ||
548 | |||
549 | uart->ustcnt = ustcnt; | ||
550 | return; | ||
551 | } | ||
552 | |||
553 | /* | ||
554 | * Fair output driver allows a process to speak. | ||
555 | */ | ||
556 | static void rs_fair_output(void) | ||
557 | { | ||
558 | int left; /* Output no more than that */ | ||
559 | unsigned long flags; | ||
560 | struct m68k_serial *info = &m68k_soft[0]; | ||
561 | char c; | ||
562 | |||
563 | if (info == NULL) return; | ||
564 | if (info->xmit_buf == NULL) return; | ||
565 | |||
566 | local_irq_save(flags); | ||
567 | left = info->xmit_cnt; | ||
568 | while (left != 0) { | ||
569 | c = info->xmit_buf[info->xmit_tail]; | ||
570 | info->xmit_tail = (info->xmit_tail+1) & (SERIAL_XMIT_SIZE-1); | ||
571 | info->xmit_cnt--; | ||
572 | local_irq_restore(flags); | ||
573 | |||
574 | rs_put_char(c); | ||
575 | |||
576 | local_irq_save(flags); | ||
577 | left = min(info->xmit_cnt, left-1); | ||
578 | } | ||
579 | |||
580 | /* Last character is being transmitted now (hopefully). */ | ||
581 | udelay(5); | ||
582 | |||
583 | local_irq_restore(flags); | ||
584 | return; | ||
585 | } | ||
586 | |||
587 | /* | ||
588 | * m68k_console_print is registered for printk. | ||
589 | */ | ||
590 | void console_print_68328(const char *p) | ||
591 | { | ||
592 | char c; | ||
593 | |||
594 | while ((c = *(p++)) != 0) { | ||
595 | if (c == '\n') | ||
596 | rs_put_char('\r'); | ||
597 | rs_put_char(c); | ||
598 | } | ||
599 | |||
600 | /* Comment this if you want to have a strict interrupt-driven output */ | ||
601 | rs_fair_output(); | ||
602 | |||
603 | return; | ||
604 | } | ||
605 | |||
606 | static void rs_set_ldisc(struct tty_struct *tty) | ||
607 | { | ||
608 | struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; | ||
609 | |||
610 | if (serial_paranoia_check(info, tty->name, "rs_set_ldisc")) | ||
611 | return; | ||
612 | |||
613 | info->is_cons = (tty->termios.c_line == N_TTY); | ||
614 | |||
615 | printk("ttyS%d console mode %s\n", info->line, info->is_cons ? "on" : "off"); | ||
616 | } | ||
617 | |||
618 | static void rs_flush_chars(struct tty_struct *tty) | ||
619 | { | ||
620 | struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; | ||
621 | m68328_uart *uart = &uart_addr[info->line]; | ||
622 | unsigned long flags; | ||
623 | |||
624 | if (serial_paranoia_check(info, tty->name, "rs_flush_chars")) | ||
625 | return; | ||
626 | #ifndef USE_INTS | ||
627 | for (;;) { | ||
628 | #endif | ||
629 | |||
630 | /* Enable transmitter */ | ||
631 | local_irq_save(flags); | ||
632 | |||
633 | if (info->xmit_cnt <= 0 || tty->stopped || !info->xmit_buf) { | ||
634 | local_irq_restore(flags); | ||
635 | return; | ||
636 | } | ||
637 | |||
638 | #ifdef USE_INTS | ||
639 | uart->ustcnt |= USTCNT_TXEN | USTCNT_TX_INTR_MASK; | ||
640 | #else | ||
641 | uart->ustcnt |= USTCNT_TXEN; | ||
642 | #endif | ||
643 | |||
644 | #ifdef USE_INTS | ||
645 | if (uart->utx.w & UTX_TX_AVAIL) { | ||
646 | #else | ||
647 | if (1) { | ||
648 | #endif | ||
649 | /* Send char */ | ||
650 | uart->utx.b.txdata = info->xmit_buf[info->xmit_tail++]; | ||
651 | info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); | ||
652 | info->xmit_cnt--; | ||
653 | } | ||
654 | |||
655 | #ifndef USE_INTS | ||
656 | while (!(uart->utx.w & UTX_TX_AVAIL)) udelay(5); | ||
657 | } | ||
658 | #endif | ||
659 | local_irq_restore(flags); | ||
660 | } | ||
661 | |||
662 | extern void console_printn(const char *b, int count); | ||
663 | |||
664 | static int rs_write(struct tty_struct *tty, | ||
665 | const unsigned char *buf, int count) | ||
666 | { | ||
667 | int c, total = 0; | ||
668 | struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; | ||
669 | m68328_uart *uart = &uart_addr[info->line]; | ||
670 | unsigned long flags; | ||
671 | |||
672 | if (serial_paranoia_check(info, tty->name, "rs_write")) | ||
673 | return 0; | ||
674 | |||
675 | if (!tty || !info->xmit_buf) | ||
676 | return 0; | ||
677 | |||
678 | local_save_flags(flags); | ||
679 | while (1) { | ||
680 | local_irq_disable(); | ||
681 | c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, | ||
682 | SERIAL_XMIT_SIZE - info->xmit_head)); | ||
683 | local_irq_restore(flags); | ||
684 | |||
685 | if (c <= 0) | ||
686 | break; | ||
687 | |||
688 | memcpy(info->xmit_buf + info->xmit_head, buf, c); | ||
689 | |||
690 | local_irq_disable(); | ||
691 | info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1); | ||
692 | info->xmit_cnt += c; | ||
693 | local_irq_restore(flags); | ||
694 | buf += c; | ||
695 | count -= c; | ||
696 | total += c; | ||
697 | } | ||
698 | |||
699 | if (info->xmit_cnt && !tty->stopped) { | ||
700 | /* Enable transmitter */ | ||
701 | local_irq_disable(); | ||
702 | #ifndef USE_INTS | ||
703 | while (info->xmit_cnt) { | ||
704 | #endif | ||
705 | |||
706 | uart->ustcnt |= USTCNT_TXEN; | ||
707 | #ifdef USE_INTS | ||
708 | uart->ustcnt |= USTCNT_TX_INTR_MASK; | ||
709 | #else | ||
710 | while (!(uart->utx.w & UTX_TX_AVAIL)) udelay(5); | ||
711 | #endif | ||
712 | if (uart->utx.w & UTX_TX_AVAIL) { | ||
713 | uart->utx.b.txdata = info->xmit_buf[info->xmit_tail++]; | ||
714 | info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); | ||
715 | info->xmit_cnt--; | ||
716 | } | ||
717 | |||
718 | #ifndef USE_INTS | ||
719 | } | ||
720 | #endif | ||
721 | local_irq_restore(flags); | ||
722 | } | ||
723 | |||
724 | return total; | ||
725 | } | ||
726 | |||
727 | static int rs_write_room(struct tty_struct *tty) | ||
728 | { | ||
729 | struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; | ||
730 | int ret; | ||
731 | |||
732 | if (serial_paranoia_check(info, tty->name, "rs_write_room")) | ||
733 | return 0; | ||
734 | ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1; | ||
735 | if (ret < 0) | ||
736 | ret = 0; | ||
737 | return ret; | ||
738 | } | ||
739 | |||
740 | static int rs_chars_in_buffer(struct tty_struct *tty) | ||
741 | { | ||
742 | struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; | ||
743 | |||
744 | if (serial_paranoia_check(info, tty->name, "rs_chars_in_buffer")) | ||
745 | return 0; | ||
746 | return info->xmit_cnt; | ||
747 | } | ||
748 | |||
749 | static void rs_flush_buffer(struct tty_struct *tty) | ||
750 | { | ||
751 | struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; | ||
752 | unsigned long flags; | ||
753 | |||
754 | if (serial_paranoia_check(info, tty->name, "rs_flush_buffer")) | ||
755 | return; | ||
756 | local_irq_save(flags); | ||
757 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | ||
758 | local_irq_restore(flags); | ||
759 | tty_wakeup(tty); | ||
760 | } | ||
761 | |||
762 | /* | ||
763 | * ------------------------------------------------------------ | ||
764 | * rs_throttle() | ||
765 | * | ||
766 | * This routine is called by the upper-layer tty layer to signal that | ||
767 | * incoming characters should be throttled. | ||
768 | * ------------------------------------------------------------ | ||
769 | */ | ||
770 | static void rs_throttle(struct tty_struct *tty) | ||
771 | { | ||
772 | struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; | ||
773 | |||
774 | if (serial_paranoia_check(info, tty->name, "rs_throttle")) | ||
775 | return; | ||
776 | |||
777 | if (I_IXOFF(tty)) | ||
778 | info->x_char = STOP_CHAR(tty); | ||
779 | |||
780 | /* Turn off RTS line (do this atomic) */ | ||
781 | } | ||
782 | |||
783 | static void rs_unthrottle(struct tty_struct *tty) | ||
784 | { | ||
785 | struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; | ||
786 | |||
787 | if (serial_paranoia_check(info, tty->name, "rs_unthrottle")) | ||
788 | return; | ||
789 | |||
790 | if (I_IXOFF(tty)) { | ||
791 | if (info->x_char) | ||
792 | info->x_char = 0; | ||
793 | else | ||
794 | info->x_char = START_CHAR(tty); | ||
795 | } | ||
796 | |||
797 | /* Assert RTS line (do this atomic) */ | ||
798 | } | ||
799 | |||
800 | /* | ||
801 | * ------------------------------------------------------------ | ||
802 | * rs_ioctl() and friends | ||
803 | * ------------------------------------------------------------ | ||
804 | */ | ||
805 | |||
806 | static int get_serial_info(struct m68k_serial *info, | ||
807 | struct serial_struct *retinfo) | ||
808 | { | ||
809 | struct serial_struct tmp; | ||
810 | |||
811 | if (!retinfo) | ||
812 | return -EFAULT; | ||
813 | memset(&tmp, 0, sizeof(tmp)); | ||
814 | tmp.type = info->type; | ||
815 | tmp.line = info->line; | ||
816 | tmp.port = info->port; | ||
817 | tmp.irq = info->irq; | ||
818 | tmp.flags = info->tport.flags; | ||
819 | tmp.baud_base = info->baud_base; | ||
820 | tmp.close_delay = info->tport.close_delay; | ||
821 | tmp.closing_wait = info->tport.closing_wait; | ||
822 | tmp.custom_divisor = info->custom_divisor; | ||
823 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) | ||
824 | return -EFAULT; | ||
825 | |||
826 | return 0; | ||
827 | } | ||
828 | |||
829 | static int set_serial_info(struct m68k_serial *info, struct tty_struct *tty, | ||
830 | struct serial_struct *new_info) | ||
831 | { | ||
832 | struct tty_port *port = &info->tport; | ||
833 | struct serial_struct new_serial; | ||
834 | struct m68k_serial old_info; | ||
835 | int retval = 0; | ||
836 | |||
837 | if (!new_info) | ||
838 | return -EFAULT; | ||
839 | if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) | ||
840 | return -EFAULT; | ||
841 | old_info = *info; | ||
842 | |||
843 | if (!capable(CAP_SYS_ADMIN)) { | ||
844 | if ((new_serial.baud_base != info->baud_base) || | ||
845 | (new_serial.type != info->type) || | ||
846 | (new_serial.close_delay != port->close_delay) || | ||
847 | ((new_serial.flags & ~ASYNC_USR_MASK) != | ||
848 | (port->flags & ~ASYNC_USR_MASK))) | ||
849 | return -EPERM; | ||
850 | port->flags = ((port->flags & ~ASYNC_USR_MASK) | | ||
851 | (new_serial.flags & ASYNC_USR_MASK)); | ||
852 | info->custom_divisor = new_serial.custom_divisor; | ||
853 | goto check_and_exit; | ||
854 | } | ||
855 | |||
856 | if (port->count > 1) | ||
857 | return -EBUSY; | ||
858 | |||
859 | /* | ||
860 | * OK, past this point, all the error checking has been done. | ||
861 | * At this point, we start making changes..... | ||
862 | */ | ||
863 | |||
864 | info->baud_base = new_serial.baud_base; | ||
865 | port->flags = ((port->flags & ~ASYNC_FLAGS) | | ||
866 | (new_serial.flags & ASYNC_FLAGS)); | ||
867 | info->type = new_serial.type; | ||
868 | port->close_delay = new_serial.close_delay; | ||
869 | port->closing_wait = new_serial.closing_wait; | ||
870 | |||
871 | check_and_exit: | ||
872 | retval = startup(info, tty); | ||
873 | return retval; | ||
874 | } | ||
875 | |||
876 | /* | ||
877 | * get_lsr_info - get line status register info | ||
878 | * | ||
879 | * Purpose: Let user call ioctl() to get info when the UART physically | ||
880 | * is emptied. On bus types like RS485, the transmitter must | ||
881 | * release the bus after transmitting. This must be done when | ||
882 | * the transmit shift register is empty, not be done when the | ||
883 | * transmit holding register is empty. This functionality | ||
884 | * allows an RS485 driver to be written in user space. | ||
885 | */ | ||
886 | static int get_lsr_info(struct m68k_serial *info, unsigned int *value) | ||
887 | { | ||
888 | #ifdef CONFIG_SERIAL_68328_RTS_CTS | ||
889 | m68328_uart *uart = &uart_addr[info->line]; | ||
890 | #endif | ||
891 | unsigned char status; | ||
892 | unsigned long flags; | ||
893 | |||
894 | local_irq_save(flags); | ||
895 | #ifdef CONFIG_SERIAL_68328_RTS_CTS | ||
896 | status = (uart->utx.w & UTX_CTS_STAT) ? 1 : 0; | ||
897 | #else | ||
898 | status = 0; | ||
899 | #endif | ||
900 | local_irq_restore(flags); | ||
901 | return put_user(status, value); | ||
902 | } | ||
903 | |||
904 | /* | ||
905 | * This routine sends a break character out the serial port. | ||
906 | */ | ||
907 | static void send_break(struct m68k_serial *info, unsigned int duration) | ||
908 | { | ||
909 | m68328_uart *uart = &uart_addr[info->line]; | ||
910 | unsigned long flags; | ||
911 | if (!info->port) | ||
912 | return; | ||
913 | local_irq_save(flags); | ||
914 | #ifdef USE_INTS | ||
915 | uart->utx.w |= UTX_SEND_BREAK; | ||
916 | msleep_interruptible(duration); | ||
917 | uart->utx.w &= ~UTX_SEND_BREAK; | ||
918 | #endif | ||
919 | local_irq_restore(flags); | ||
920 | } | ||
921 | |||
922 | static int rs_ioctl(struct tty_struct *tty, | ||
923 | unsigned int cmd, unsigned long arg) | ||
924 | { | ||
925 | struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; | ||
926 | int retval; | ||
927 | |||
928 | if (serial_paranoia_check(info, tty->name, "rs_ioctl")) | ||
929 | return -ENODEV; | ||
930 | |||
931 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && | ||
932 | (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) && | ||
933 | (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) { | ||
934 | if (tty->flags & (1 << TTY_IO_ERROR)) | ||
935 | return -EIO; | ||
936 | } | ||
937 | |||
938 | switch (cmd) { | ||
939 | case TCSBRK: /* SVID version: non-zero arg --> no break */ | ||
940 | retval = tty_check_change(tty); | ||
941 | if (retval) | ||
942 | return retval; | ||
943 | tty_wait_until_sent(tty, 0); | ||
944 | if (!arg) | ||
945 | send_break(info, 250); /* 1/4 second */ | ||
946 | return 0; | ||
947 | case TCSBRKP: /* support for POSIX tcsendbreak() */ | ||
948 | retval = tty_check_change(tty); | ||
949 | if (retval) | ||
950 | return retval; | ||
951 | tty_wait_until_sent(tty, 0); | ||
952 | send_break(info, arg ? arg*(100) : 250); | ||
953 | return 0; | ||
954 | case TIOCGSERIAL: | ||
955 | return get_serial_info(info, | ||
956 | (struct serial_struct *) arg); | ||
957 | case TIOCSSERIAL: | ||
958 | return set_serial_info(info, tty, | ||
959 | (struct serial_struct *) arg); | ||
960 | case TIOCSERGETLSR: /* Get line status register */ | ||
961 | return get_lsr_info(info, (unsigned int *) arg); | ||
962 | case TIOCSERGSTRUCT: | ||
963 | if (copy_to_user((struct m68k_serial *) arg, | ||
964 | info, sizeof(struct m68k_serial))) | ||
965 | return -EFAULT; | ||
966 | return 0; | ||
967 | default: | ||
968 | return -ENOIOCTLCMD; | ||
969 | } | ||
970 | return 0; | ||
971 | } | ||
972 | |||
973 | static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | ||
974 | { | ||
975 | struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; | ||
976 | |||
977 | change_speed(info, tty); | ||
978 | |||
979 | if ((old_termios->c_cflag & CRTSCTS) && | ||
980 | !(tty->termios.c_cflag & CRTSCTS)) | ||
981 | rs_start(tty); | ||
982 | |||
983 | } | ||
984 | |||
985 | /* | ||
986 | * ------------------------------------------------------------ | ||
987 | * rs_close() | ||
988 | * | ||
989 | * This routine is called when the serial port gets closed. First, we | ||
990 | * wait for the last remaining data to be sent. Then, we unlink its | ||
991 | * S structure from the interrupt chain if necessary, and we free | ||
992 | * that IRQ if nothing is left in the chain. | ||
993 | * ------------------------------------------------------------ | ||
994 | */ | ||
995 | static void rs_close(struct tty_struct *tty, struct file *filp) | ||
996 | { | ||
997 | struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; | ||
998 | struct tty_port *port = &info->tport; | ||
999 | m68328_uart *uart = &uart_addr[info->line]; | ||
1000 | unsigned long flags; | ||
1001 | |||
1002 | if (serial_paranoia_check(info, tty->name, "rs_close")) | ||
1003 | return; | ||
1004 | |||
1005 | local_irq_save(flags); | ||
1006 | |||
1007 | if (tty_hung_up_p(filp)) { | ||
1008 | local_irq_restore(flags); | ||
1009 | return; | ||
1010 | } | ||
1011 | |||
1012 | if ((tty->count == 1) && (port->count != 1)) { | ||
1013 | /* | ||
1014 | * Uh, oh. tty->count is 1, which means that the tty | ||
1015 | * structure will be freed. Info->count should always | ||
1016 | * be one in these conditions. If it's greater than | ||
1017 | * one, we've got real problems, since it means the | ||
1018 | * serial port won't be shutdown. | ||
1019 | */ | ||
1020 | printk("rs_close: bad serial port count; tty->count is 1, " | ||
1021 | "port->count is %d\n", port->count); | ||
1022 | port->count = 1; | ||
1023 | } | ||
1024 | if (--port->count < 0) { | ||
1025 | printk("rs_close: bad serial port count for ttyS%d: %d\n", | ||
1026 | info->line, port->count); | ||
1027 | port->count = 0; | ||
1028 | } | ||
1029 | if (port->count) { | ||
1030 | local_irq_restore(flags); | ||
1031 | return; | ||
1032 | } | ||
1033 | port->flags |= ASYNC_CLOSING; | ||
1034 | /* | ||
1035 | * Now we wait for the transmit buffer to clear; and we notify | ||
1036 | * the line discipline to only process XON/XOFF characters. | ||
1037 | */ | ||
1038 | tty->closing = 1; | ||
1039 | if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) | ||
1040 | tty_wait_until_sent(tty, port->closing_wait); | ||
1041 | /* | ||
1042 | * At this point we stop accepting input. To do this, we | ||
1043 | * disable the receive line status interrupts, and tell the | ||
1044 | * interrupt driver to stop checking the data ready bit in the | ||
1045 | * line status register. | ||
1046 | */ | ||
1047 | |||
1048 | uart->ustcnt &= ~USTCNT_RXEN; | ||
1049 | uart->ustcnt &= ~(USTCNT_RXEN | USTCNT_RX_INTR_MASK); | ||
1050 | |||
1051 | shutdown(info, tty); | ||
1052 | rs_flush_buffer(tty); | ||
1053 | |||
1054 | tty_ldisc_flush(tty); | ||
1055 | tty->closing = 0; | ||
1056 | tty_port_tty_set(&info->tport, NULL); | ||
1057 | #warning "This is not and has never been valid so fix it" | ||
1058 | #if 0 | ||
1059 | if (tty->ldisc.num != ldiscs[N_TTY].num) { | ||
1060 | if (tty->ldisc.close) | ||
1061 | (tty->ldisc.close)(tty); | ||
1062 | tty->ldisc = ldiscs[N_TTY]; | ||
1063 | tty->termios.c_line = N_TTY; | ||
1064 | if (tty->ldisc.open) | ||
1065 | (tty->ldisc.open)(tty); | ||
1066 | } | ||
1067 | #endif | ||
1068 | if (port->blocked_open) { | ||
1069 | if (port->close_delay) | ||
1070 | msleep_interruptible(jiffies_to_msecs(port->close_delay)); | ||
1071 | wake_up_interruptible(&port->open_wait); | ||
1072 | } | ||
1073 | port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); | ||
1074 | local_irq_restore(flags); | ||
1075 | } | ||
1076 | |||
1077 | /* | ||
1078 | * rs_hangup() --- called by tty_hangup() when a hangup is signaled. | ||
1079 | */ | ||
1080 | void rs_hangup(struct tty_struct *tty) | ||
1081 | { | ||
1082 | struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; | ||
1083 | |||
1084 | if (serial_paranoia_check(info, tty->name, "rs_hangup")) | ||
1085 | return; | ||
1086 | |||
1087 | rs_flush_buffer(tty); | ||
1088 | shutdown(info, tty); | ||
1089 | info->tport.count = 0; | ||
1090 | info->tport.flags &= ~ASYNC_NORMAL_ACTIVE; | ||
1091 | tty_port_tty_set(&info->tport, NULL); | ||
1092 | wake_up_interruptible(&info->tport.open_wait); | ||
1093 | } | ||
1094 | |||
1095 | /* | ||
1096 | * This routine is called whenever a serial port is opened. It | ||
1097 | * enables interrupts for a serial port, linking in its S structure into | ||
1098 | * the IRQ chain. It also performs the serial-specific | ||
1099 | * initialization for the tty structure. | ||
1100 | */ | ||
1101 | int rs_open(struct tty_struct *tty, struct file *filp) | ||
1102 | { | ||
1103 | struct m68k_serial *info; | ||
1104 | int retval; | ||
1105 | |||
1106 | info = &m68k_soft[tty->index]; | ||
1107 | |||
1108 | if (serial_paranoia_check(info, tty->name, "rs_open")) | ||
1109 | return -ENODEV; | ||
1110 | |||
1111 | info->tport.count++; | ||
1112 | tty->driver_data = info; | ||
1113 | tty_port_tty_set(&info->tport, tty); | ||
1114 | |||
1115 | /* | ||
1116 | * Start up serial port | ||
1117 | */ | ||
1118 | retval = startup(info, tty); | ||
1119 | if (retval) | ||
1120 | return retval; | ||
1121 | |||
1122 | return tty_port_block_til_ready(&info->tport, tty, filp); | ||
1123 | } | ||
1124 | |||
1125 | /* Finally, routines used to initialize the serial driver. */ | ||
1126 | |||
1127 | static void show_serial_version(void) | ||
1128 | { | ||
1129 | printk("MC68328 serial driver version 1.00\n"); | ||
1130 | } | ||
1131 | |||
1132 | static const struct tty_operations rs_ops = { | ||
1133 | .open = rs_open, | ||
1134 | .close = rs_close, | ||
1135 | .write = rs_write, | ||
1136 | .flush_chars = rs_flush_chars, | ||
1137 | .write_room = rs_write_room, | ||
1138 | .chars_in_buffer = rs_chars_in_buffer, | ||
1139 | .flush_buffer = rs_flush_buffer, | ||
1140 | .ioctl = rs_ioctl, | ||
1141 | .throttle = rs_throttle, | ||
1142 | .unthrottle = rs_unthrottle, | ||
1143 | .set_termios = rs_set_termios, | ||
1144 | .stop = rs_stop, | ||
1145 | .start = rs_start, | ||
1146 | .hangup = rs_hangup, | ||
1147 | .set_ldisc = rs_set_ldisc, | ||
1148 | }; | ||
1149 | |||
1150 | static const struct tty_port_operations rs_port_ops = { | ||
1151 | }; | ||
1152 | |||
1153 | /* rs_init inits the driver */ | ||
1154 | static int __init | ||
1155 | rs68328_init(void) | ||
1156 | { | ||
1157 | unsigned long flags; | ||
1158 | int i; | ||
1159 | struct m68k_serial *info; | ||
1160 | |||
1161 | serial_driver = alloc_tty_driver(NR_PORTS); | ||
1162 | if (!serial_driver) | ||
1163 | return -ENOMEM; | ||
1164 | |||
1165 | show_serial_version(); | ||
1166 | |||
1167 | /* Initialize the tty_driver structure */ | ||
1168 | /* SPARC: Not all of this is exactly right for us. */ | ||
1169 | |||
1170 | serial_driver->name = "ttyS"; | ||
1171 | serial_driver->major = TTY_MAJOR; | ||
1172 | serial_driver->minor_start = 64; | ||
1173 | serial_driver->type = TTY_DRIVER_TYPE_SERIAL; | ||
1174 | serial_driver->subtype = SERIAL_TYPE_NORMAL; | ||
1175 | serial_driver->init_termios = tty_std_termios; | ||
1176 | serial_driver->init_termios.c_cflag = | ||
1177 | m68328_console_cbaud | CS8 | CREAD | HUPCL | CLOCAL; | ||
1178 | serial_driver->flags = TTY_DRIVER_REAL_RAW; | ||
1179 | tty_set_operations(serial_driver, &rs_ops); | ||
1180 | |||
1181 | local_irq_save(flags); | ||
1182 | |||
1183 | for (i = 0; i < NR_PORTS; i++) { | ||
1184 | |||
1185 | info = &m68k_soft[i]; | ||
1186 | tty_port_init(&info->tport); | ||
1187 | info->tport.ops = &rs_port_ops; | ||
1188 | info->magic = SERIAL_MAGIC; | ||
1189 | info->port = (int) &uart_addr[i]; | ||
1190 | info->irq = uart_irqs[i]; | ||
1191 | info->custom_divisor = 16; | ||
1192 | info->x_char = 0; | ||
1193 | info->line = i; | ||
1194 | info->is_cons = 1; /* Means shortcuts work */ | ||
1195 | |||
1196 | printk("%s%d at 0x%08x (irq = %d)", serial_driver->name, info->line, | ||
1197 | info->port, info->irq); | ||
1198 | printk(" is a builtin MC68328 UART\n"); | ||
1199 | |||
1200 | #ifdef CONFIG_M68VZ328 | ||
1201 | if (i > 0) | ||
1202 | PJSEL &= 0xCF; /* PSW enable second port output */ | ||
1203 | #endif | ||
1204 | |||
1205 | if (request_irq(uart_irqs[i], | ||
1206 | rs_interrupt, | ||
1207 | 0, | ||
1208 | "M68328_UART", info)) | ||
1209 | panic("Unable to attach 68328 serial interrupt\n"); | ||
1210 | |||
1211 | tty_port_link_device(&info->tport, serial_driver, i); | ||
1212 | } | ||
1213 | local_irq_restore(flags); | ||
1214 | |||
1215 | if (tty_register_driver(serial_driver)) { | ||
1216 | put_tty_driver(serial_driver); | ||
1217 | for (i = 0; i < NR_PORTS; i++) | ||
1218 | tty_port_destroy(&m68k_soft[i].tport); | ||
1219 | printk(KERN_ERR "Couldn't register serial driver\n"); | ||
1220 | return -ENOMEM; | ||
1221 | } | ||
1222 | |||
1223 | return 0; | ||
1224 | } | ||
1225 | |||
1226 | module_init(rs68328_init); | ||
1227 | |||
1228 | |||
1229 | |||
1230 | static void m68328_set_baud(void) | ||
1231 | { | ||
1232 | unsigned short ustcnt; | ||
1233 | int i; | ||
1234 | |||
1235 | ustcnt = USTCNT; | ||
1236 | USTCNT = ustcnt & ~USTCNT_TXEN; | ||
1237 | |||
1238 | again: | ||
1239 | for (i = 0; i < ARRAY_SIZE(baud_table); i++) | ||
1240 | if (baud_table[i] == m68328_console_baud) | ||
1241 | break; | ||
1242 | if (i >= ARRAY_SIZE(baud_table)) { | ||
1243 | m68328_console_baud = 9600; | ||
1244 | goto again; | ||
1245 | } | ||
1246 | |||
1247 | UBAUD = PUT_FIELD(UBAUD_DIVIDE, hw_baud_table[i].divisor) | | ||
1248 | PUT_FIELD(UBAUD_PRESCALER, hw_baud_table[i].prescale); | ||
1249 | ustcnt &= ~(USTCNT_PARITYEN | USTCNT_ODD_EVEN | USTCNT_STOP | USTCNT_8_7); | ||
1250 | ustcnt |= USTCNT_8_7; | ||
1251 | ustcnt |= USTCNT_TXEN; | ||
1252 | USTCNT = ustcnt; | ||
1253 | m68328_console_initted = 1; | ||
1254 | return; | ||
1255 | } | ||
1256 | |||
1257 | |||
1258 | int m68328_console_setup(struct console *cp, char *arg) | ||
1259 | { | ||
1260 | int i, n = CONSOLE_BAUD_RATE; | ||
1261 | |||
1262 | if (!cp) | ||
1263 | return(-1); | ||
1264 | |||
1265 | if (arg) | ||
1266 | n = simple_strtoul(arg, NULL, 0); | ||
1267 | |||
1268 | for (i = 0; i < ARRAY_SIZE(baud_table); i++) | ||
1269 | if (baud_table[i] == n) | ||
1270 | break; | ||
1271 | if (i < ARRAY_SIZE(baud_table)) { | ||
1272 | m68328_console_baud = n; | ||
1273 | m68328_console_cbaud = 0; | ||
1274 | if (i > 15) { | ||
1275 | m68328_console_cbaud |= CBAUDEX; | ||
1276 | i -= 15; | ||
1277 | } | ||
1278 | m68328_console_cbaud |= i; | ||
1279 | } | ||
1280 | |||
1281 | m68328_set_baud(); /* make sure baud rate changes */ | ||
1282 | return 0; | ||
1283 | } | ||
1284 | |||
1285 | |||
1286 | static struct tty_driver *m68328_console_device(struct console *c, int *index) | ||
1287 | { | ||
1288 | *index = c->index; | ||
1289 | return serial_driver; | ||
1290 | } | ||
1291 | |||
1292 | |||
1293 | void m68328_console_write (struct console *co, const char *str, | ||
1294 | unsigned int count) | ||
1295 | { | ||
1296 | if (!m68328_console_initted) | ||
1297 | m68328_set_baud(); | ||
1298 | while (count--) { | ||
1299 | if (*str == '\n') | ||
1300 | rs_put_char('\r'); | ||
1301 | rs_put_char(*str++); | ||
1302 | } | ||
1303 | } | ||
1304 | |||
1305 | |||
1306 | static struct console m68328_driver = { | ||
1307 | .name = "ttyS", | ||
1308 | .write = m68328_console_write, | ||
1309 | .device = m68328_console_device, | ||
1310 | .setup = m68328_console_setup, | ||
1311 | .flags = CON_PRINTBUFFER, | ||
1312 | .index = -1, | ||
1313 | }; | ||
1314 | |||
1315 | |||
1316 | static int __init m68328_console_init(void) | ||
1317 | { | ||
1318 | register_console(&m68328_driver); | ||
1319 | return 0; | ||
1320 | } | ||
1321 | |||
1322 | console_initcall(m68328_console_init); | ||
diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h index d54dcd87c67e..047a7ba6796a 100644 --- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h | |||
@@ -92,6 +92,18 @@ struct serial8250_config { | |||
92 | #define SERIAL8250_SHARE_IRQS 0 | 92 | #define SERIAL8250_SHARE_IRQS 0 |
93 | #endif | 93 | #endif |
94 | 94 | ||
95 | #define SERIAL8250_PORT_FLAGS(_base, _irq, _flags) \ | ||
96 | { \ | ||
97 | .iobase = _base, \ | ||
98 | .irq = _irq, \ | ||
99 | .uartclk = 1843200, \ | ||
100 | .iotype = UPIO_PORT, \ | ||
101 | .flags = UPF_BOOT_AUTOCONF | (_flags), \ | ||
102 | } | ||
103 | |||
104 | #define SERIAL8250_PORT(_base, _irq) SERIAL8250_PORT_FLAGS(_base, _irq, 0) | ||
105 | |||
106 | |||
95 | static inline int serial_in(struct uart_8250_port *up, int offset) | 107 | static inline int serial_in(struct uart_8250_port *up, int offset) |
96 | { | 108 | { |
97 | return up->port.serial_in(&up->port, offset); | 109 | return up->port.serial_in(&up->port, offset); |
@@ -117,6 +129,8 @@ static inline void serial_dl_write(struct uart_8250_port *up, int value) | |||
117 | struct uart_8250_port *serial8250_get_port(int line); | 129 | struct uart_8250_port *serial8250_get_port(int line); |
118 | void serial8250_rpm_get(struct uart_8250_port *p); | 130 | void serial8250_rpm_get(struct uart_8250_port *p); |
119 | void serial8250_rpm_put(struct uart_8250_port *p); | 131 | void serial8250_rpm_put(struct uart_8250_port *p); |
132 | int serial8250_em485_init(struct uart_8250_port *p); | ||
133 | void serial8250_em485_destroy(struct uart_8250_port *p); | ||
120 | 134 | ||
121 | #if defined(__alpha__) && !defined(CONFIG_PCI) | 135 | #if defined(__alpha__) && !defined(CONFIG_PCI) |
122 | /* | 136 | /* |
diff --git a/drivers/tty/serial/8250/8250_accent.c b/drivers/tty/serial/8250/8250_accent.c index 34b51c651192..522aeae05192 100644 --- a/drivers/tty/serial/8250/8250_accent.c +++ b/drivers/tty/serial/8250/8250_accent.c | |||
@@ -10,18 +10,11 @@ | |||
10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
11 | #include <linux/serial_8250.h> | 11 | #include <linux/serial_8250.h> |
12 | 12 | ||
13 | #define PORT(_base,_irq) \ | 13 | #include "8250.h" |
14 | { \ | ||
15 | .iobase = _base, \ | ||
16 | .irq = _irq, \ | ||
17 | .uartclk = 1843200, \ | ||
18 | .iotype = UPIO_PORT, \ | ||
19 | .flags = UPF_BOOT_AUTOCONF, \ | ||
20 | } | ||
21 | 14 | ||
22 | static struct plat_serial8250_port accent_data[] = { | 15 | static struct plat_serial8250_port accent_data[] = { |
23 | PORT(0x330, 4), | 16 | SERIAL8250_PORT(0x330, 4), |
24 | PORT(0x338, 4), | 17 | SERIAL8250_PORT(0x338, 4), |
25 | { }, | 18 | { }, |
26 | }; | 19 | }; |
27 | 20 | ||
diff --git a/drivers/tty/serial/8250/8250_acorn.c b/drivers/tty/serial/8250/8250_acorn.c index 549aa07c0d27..402dfdd4940e 100644 --- a/drivers/tty/serial/8250/8250_acorn.c +++ b/drivers/tty/serial/8250/8250_acorn.c | |||
@@ -70,7 +70,7 @@ serial_card_probe(struct expansion_card *ec, const struct ecard_id *id) | |||
70 | uart.port.regshift = 2; | 70 | uart.port.regshift = 2; |
71 | uart.port.dev = &ec->dev; | 71 | uart.port.dev = &ec->dev; |
72 | 72 | ||
73 | for (i = 0; i < info->num_ports; i ++) { | 73 | for (i = 0; i < info->num_ports; i++) { |
74 | uart.port.membase = info->vaddr + type->offset[i]; | 74 | uart.port.membase = info->vaddr + type->offset[i]; |
75 | uart.port.mapbase = bus_addr + type->offset[i]; | 75 | uart.port.mapbase = bus_addr + type->offset[i]; |
76 | 76 | ||
diff --git a/drivers/tty/serial/8250/8250_bcm2835aux.c b/drivers/tty/serial/8250/8250_bcm2835aux.c new file mode 100644 index 000000000000..e10f1244409b --- /dev/null +++ b/drivers/tty/serial/8250/8250_bcm2835aux.c | |||
@@ -0,0 +1,146 @@ | |||
1 | /* | ||
2 | * Serial port driver for BCM2835AUX UART | ||
3 | * | ||
4 | * Copyright (C) 2016 Martin Sperl <kernel@martin.sperl.org> | ||
5 | * | ||
6 | * Based on 8250_lpc18xx.c: | ||
7 | * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include <linux/clk.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/of.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | |||
21 | #include "8250.h" | ||
22 | |||
23 | struct bcm2835aux_data { | ||
24 | struct uart_8250_port uart; | ||
25 | struct clk *clk; | ||
26 | int line; | ||
27 | }; | ||
28 | |||
29 | static int bcm2835aux_serial_probe(struct platform_device *pdev) | ||
30 | { | ||
31 | struct bcm2835aux_data *data; | ||
32 | struct resource *res; | ||
33 | int ret; | ||
34 | |||
35 | /* allocate the custom structure */ | ||
36 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); | ||
37 | if (!data) | ||
38 | return -ENOMEM; | ||
39 | |||
40 | /* initialize data */ | ||
41 | spin_lock_init(&data->uart.port.lock); | ||
42 | data->uart.capabilities = UART_CAP_FIFO; | ||
43 | data->uart.port.dev = &pdev->dev; | ||
44 | data->uart.port.regshift = 2; | ||
45 | data->uart.port.type = PORT_16550; | ||
46 | data->uart.port.iotype = UPIO_MEM; | ||
47 | data->uart.port.fifosize = 8; | ||
48 | data->uart.port.flags = UPF_SHARE_IRQ | | ||
49 | UPF_FIXED_PORT | | ||
50 | UPF_FIXED_TYPE | | ||
51 | UPF_SKIP_TEST; | ||
52 | |||
53 | /* get the clock - this also enables the HW */ | ||
54 | data->clk = devm_clk_get(&pdev->dev, NULL); | ||
55 | ret = PTR_ERR_OR_ZERO(data->clk); | ||
56 | if (ret) { | ||
57 | dev_err(&pdev->dev, "could not get clk: %d\n", ret); | ||
58 | return ret; | ||
59 | } | ||
60 | |||
61 | /* get the interrupt */ | ||
62 | ret = platform_get_irq(pdev, 0); | ||
63 | if (ret < 0) { | ||
64 | dev_err(&pdev->dev, "irq not found - %i", ret); | ||
65 | return ret; | ||
66 | } | ||
67 | data->uart.port.irq = ret; | ||
68 | |||
69 | /* map the main registers */ | ||
70 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
71 | if (!res) { | ||
72 | dev_err(&pdev->dev, "memory resource not found"); | ||
73 | return -EINVAL; | ||
74 | } | ||
75 | data->uart.port.membase = devm_ioremap_resource(&pdev->dev, res); | ||
76 | ret = PTR_ERR_OR_ZERO(data->uart.port.membase); | ||
77 | if (ret) | ||
78 | return ret; | ||
79 | |||
80 | /* Check for a fixed line number */ | ||
81 | ret = of_alias_get_id(pdev->dev.of_node, "serial"); | ||
82 | if (ret >= 0) | ||
83 | data->uart.port.line = ret; | ||
84 | |||
85 | /* enable the clock as a last step */ | ||
86 | ret = clk_prepare_enable(data->clk); | ||
87 | if (ret) { | ||
88 | dev_err(&pdev->dev, "unable to enable uart clock - %d\n", | ||
89 | ret); | ||
90 | return ret; | ||
91 | } | ||
92 | |||
93 | /* the HW-clock divider for bcm2835aux is 8, | ||
94 | * but 8250 expects a divider of 16, | ||
95 | * so we have to multiply the actual clock by 2 | ||
96 | * to get identical baudrates. | ||
97 | */ | ||
98 | data->uart.port.uartclk = clk_get_rate(data->clk) * 2; | ||
99 | |||
100 | /* register the port */ | ||
101 | ret = serial8250_register_8250_port(&data->uart); | ||
102 | if (ret < 0) { | ||
103 | dev_err(&pdev->dev, "unable to register 8250 port - %d\n", | ||
104 | ret); | ||
105 | goto dis_clk; | ||
106 | } | ||
107 | data->line = ret; | ||
108 | |||
109 | platform_set_drvdata(pdev, data); | ||
110 | |||
111 | return 0; | ||
112 | |||
113 | dis_clk: | ||
114 | clk_disable_unprepare(data->clk); | ||
115 | return ret; | ||
116 | } | ||
117 | |||
118 | static int bcm2835aux_serial_remove(struct platform_device *pdev) | ||
119 | { | ||
120 | struct bcm2835aux_data *data = platform_get_drvdata(pdev); | ||
121 | |||
122 | serial8250_unregister_port(data->uart.port.line); | ||
123 | clk_disable_unprepare(data->clk); | ||
124 | |||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | static const struct of_device_id bcm2835aux_serial_match[] = { | ||
129 | { .compatible = "brcm,bcm2835-aux-uart" }, | ||
130 | { }, | ||
131 | }; | ||
132 | MODULE_DEVICE_TABLE(of, bcm2835aux_serial_match); | ||
133 | |||
134 | static struct platform_driver bcm2835aux_serial_driver = { | ||
135 | .driver = { | ||
136 | .name = "bcm2835-aux-uart", | ||
137 | .of_match_table = bcm2835aux_serial_match, | ||
138 | }, | ||
139 | .probe = bcm2835aux_serial_probe, | ||
140 | .remove = bcm2835aux_serial_remove, | ||
141 | }; | ||
142 | module_platform_driver(bcm2835aux_serial_driver); | ||
143 | |||
144 | MODULE_DESCRIPTION("BCM2835 auxiliar UART driver"); | ||
145 | MODULE_AUTHOR("Martin Sperl <kernel@martin.sperl.org>"); | ||
146 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/tty/serial/8250/8250_boca.c b/drivers/tty/serial/8250/8250_boca.c index d125dc107985..a63b5998e383 100644 --- a/drivers/tty/serial/8250/8250_boca.c +++ b/drivers/tty/serial/8250/8250_boca.c | |||
@@ -10,32 +10,25 @@ | |||
10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
11 | #include <linux/serial_8250.h> | 11 | #include <linux/serial_8250.h> |
12 | 12 | ||
13 | #define PORT(_base,_irq) \ | 13 | #include "8250.h" |
14 | { \ | ||
15 | .iobase = _base, \ | ||
16 | .irq = _irq, \ | ||
17 | .uartclk = 1843200, \ | ||
18 | .iotype = UPIO_PORT, \ | ||
19 | .flags = UPF_BOOT_AUTOCONF, \ | ||
20 | } | ||
21 | 14 | ||
22 | static struct plat_serial8250_port boca_data[] = { | 15 | static struct plat_serial8250_port boca_data[] = { |
23 | PORT(0x100, 12), | 16 | SERIAL8250_PORT(0x100, 12), |
24 | PORT(0x108, 12), | 17 | SERIAL8250_PORT(0x108, 12), |
25 | PORT(0x110, 12), | 18 | SERIAL8250_PORT(0x110, 12), |
26 | PORT(0x118, 12), | 19 | SERIAL8250_PORT(0x118, 12), |
27 | PORT(0x120, 12), | 20 | SERIAL8250_PORT(0x120, 12), |
28 | PORT(0x128, 12), | 21 | SERIAL8250_PORT(0x128, 12), |
29 | PORT(0x130, 12), | 22 | SERIAL8250_PORT(0x130, 12), |
30 | PORT(0x138, 12), | 23 | SERIAL8250_PORT(0x138, 12), |
31 | PORT(0x140, 12), | 24 | SERIAL8250_PORT(0x140, 12), |
32 | PORT(0x148, 12), | 25 | SERIAL8250_PORT(0x148, 12), |
33 | PORT(0x150, 12), | 26 | SERIAL8250_PORT(0x150, 12), |
34 | PORT(0x158, 12), | 27 | SERIAL8250_PORT(0x158, 12), |
35 | PORT(0x160, 12), | 28 | SERIAL8250_PORT(0x160, 12), |
36 | PORT(0x168, 12), | 29 | SERIAL8250_PORT(0x168, 12), |
37 | PORT(0x170, 12), | 30 | SERIAL8250_PORT(0x170, 12), |
38 | PORT(0x178, 12), | 31 | SERIAL8250_PORT(0x178, 12), |
39 | { }, | 32 | { }, |
40 | }; | 33 | }; |
41 | 34 | ||
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index c9720a97a977..2f4f5ee651db 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c | |||
@@ -597,6 +597,7 @@ static void univ8250_console_write(struct console *co, const char *s, | |||
597 | static int univ8250_console_setup(struct console *co, char *options) | 597 | static int univ8250_console_setup(struct console *co, char *options) |
598 | { | 598 | { |
599 | struct uart_port *port; | 599 | struct uart_port *port; |
600 | int retval; | ||
600 | 601 | ||
601 | /* | 602 | /* |
602 | * Check whether an invalid uart number has been specified, and | 603 | * Check whether an invalid uart number has been specified, and |
@@ -609,7 +610,10 @@ static int univ8250_console_setup(struct console *co, char *options) | |||
609 | /* link port to console */ | 610 | /* link port to console */ |
610 | port->cons = co; | 611 | port->cons = co; |
611 | 612 | ||
612 | return serial8250_console_setup(port, options, false); | 613 | retval = serial8250_console_setup(port, options, false); |
614 | if (retval != 0) | ||
615 | port->cons = NULL; | ||
616 | return retval; | ||
613 | } | 617 | } |
614 | 618 | ||
615 | /** | 619 | /** |
@@ -687,7 +691,7 @@ static int __init univ8250_console_init(void) | |||
687 | } | 691 | } |
688 | console_initcall(univ8250_console_init); | 692 | console_initcall(univ8250_console_init); |
689 | 693 | ||
690 | #define SERIAL8250_CONSOLE &univ8250_console | 694 | #define SERIAL8250_CONSOLE (&univ8250_console) |
691 | #else | 695 | #else |
692 | #define SERIAL8250_CONSOLE NULL | 696 | #define SERIAL8250_CONSOLE NULL |
693 | #endif | 697 | #endif |
@@ -764,6 +768,7 @@ void serial8250_suspend_port(int line) | |||
764 | 768 | ||
765 | uart_suspend_port(&serial8250_reg, port); | 769 | uart_suspend_port(&serial8250_reg, port); |
766 | } | 770 | } |
771 | EXPORT_SYMBOL(serial8250_suspend_port); | ||
767 | 772 | ||
768 | /** | 773 | /** |
769 | * serial8250_resume_port - resume one serial port | 774 | * serial8250_resume_port - resume one serial port |
@@ -789,6 +794,7 @@ void serial8250_resume_port(int line) | |||
789 | } | 794 | } |
790 | uart_resume_port(&serial8250_reg, port); | 795 | uart_resume_port(&serial8250_reg, port); |
791 | } | 796 | } |
797 | EXPORT_SYMBOL(serial8250_resume_port); | ||
792 | 798 | ||
793 | /* | 799 | /* |
794 | * Register a set of serial devices attached to a platform device. The | 800 | * Register a set of serial devices attached to a platform device. The |
@@ -1068,6 +1074,15 @@ void serial8250_unregister_port(int line) | |||
1068 | struct uart_8250_port *uart = &serial8250_ports[line]; | 1074 | struct uart_8250_port *uart = &serial8250_ports[line]; |
1069 | 1075 | ||
1070 | mutex_lock(&serial_mutex); | 1076 | mutex_lock(&serial_mutex); |
1077 | |||
1078 | if (uart->em485) { | ||
1079 | unsigned long flags; | ||
1080 | |||
1081 | spin_lock_irqsave(&uart->port.lock, flags); | ||
1082 | serial8250_em485_destroy(uart); | ||
1083 | spin_unlock_irqrestore(&uart->port.lock, flags); | ||
1084 | } | ||
1085 | |||
1071 | uart_remove_one_port(&serial8250_reg, &uart->port); | 1086 | uart_remove_one_port(&serial8250_reg, &uart->port); |
1072 | if (serial8250_isa_devs) { | 1087 | if (serial8250_isa_devs) { |
1073 | uart->port.flags &= ~UPF_BOOT_AUTOCONF; | 1088 | uart->port.flags &= ~UPF_BOOT_AUTOCONF; |
@@ -1093,9 +1108,8 @@ static int __init serial8250_init(void) | |||
1093 | 1108 | ||
1094 | serial8250_isa_init_ports(); | 1109 | serial8250_isa_init_ports(); |
1095 | 1110 | ||
1096 | printk(KERN_INFO "Serial: 8250/16550 driver, " | 1111 | pr_info("Serial: 8250/16550 driver, %d ports, IRQ sharing %sabled\n", |
1097 | "%d ports, IRQ sharing %sabled\n", nr_uarts, | 1112 | nr_uarts, share_irqs ? "en" : "dis"); |
1098 | share_irqs ? "en" : "dis"); | ||
1099 | 1113 | ||
1100 | #ifdef CONFIG_SPARC | 1114 | #ifdef CONFIG_SPARC |
1101 | ret = sunserial_register_minors(&serial8250_reg, UART_NR); | 1115 | ret = sunserial_register_minors(&serial8250_reg, UART_NR); |
@@ -1168,15 +1182,11 @@ static void __exit serial8250_exit(void) | |||
1168 | module_init(serial8250_init); | 1182 | module_init(serial8250_init); |
1169 | module_exit(serial8250_exit); | 1183 | module_exit(serial8250_exit); |
1170 | 1184 | ||
1171 | EXPORT_SYMBOL(serial8250_suspend_port); | ||
1172 | EXPORT_SYMBOL(serial8250_resume_port); | ||
1173 | |||
1174 | MODULE_LICENSE("GPL"); | 1185 | MODULE_LICENSE("GPL"); |
1175 | MODULE_DESCRIPTION("Generic 8250/16x50 serial driver"); | 1186 | MODULE_DESCRIPTION("Generic 8250/16x50 serial driver"); |
1176 | 1187 | ||
1177 | module_param(share_irqs, uint, 0644); | 1188 | module_param(share_irqs, uint, 0644); |
1178 | MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices" | 1189 | MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices (unsafe)"); |
1179 | " (unsafe)"); | ||
1180 | 1190 | ||
1181 | module_param(nr_uarts, uint, 0644); | 1191 | module_param(nr_uarts, uint, 0644); |
1182 | MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")"); | 1192 | MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")"); |
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index a5d319e4aae6..a3fb95d85d7c 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c | |||
@@ -68,12 +68,6 @@ struct dw8250_data { | |||
68 | unsigned int uart_16550_compatible:1; | 68 | unsigned int uart_16550_compatible:1; |
69 | }; | 69 | }; |
70 | 70 | ||
71 | #define BYT_PRV_CLK 0x800 | ||
72 | #define BYT_PRV_CLK_EN (1 << 0) | ||
73 | #define BYT_PRV_CLK_M_VAL_SHIFT 1 | ||
74 | #define BYT_PRV_CLK_N_VAL_SHIFT 16 | ||
75 | #define BYT_PRV_CLK_UPDATE (1 << 31) | ||
76 | |||
77 | static inline int dw8250_modify_msr(struct uart_port *p, int offset, int value) | 71 | static inline int dw8250_modify_msr(struct uart_port *p, int offset, int value) |
78 | { | 72 | { |
79 | struct dw8250_data *d = p->private_data; | 73 | struct dw8250_data *d = p->private_data; |
@@ -95,25 +89,45 @@ static void dw8250_force_idle(struct uart_port *p) | |||
95 | (void)p->serial_in(p, UART_RX); | 89 | (void)p->serial_in(p, UART_RX); |
96 | } | 90 | } |
97 | 91 | ||
98 | static void dw8250_serial_out(struct uart_port *p, int offset, int value) | 92 | static void dw8250_check_lcr(struct uart_port *p, int value) |
99 | { | 93 | { |
100 | writeb(value, p->membase + (offset << p->regshift)); | 94 | void __iomem *offset = p->membase + (UART_LCR << p->regshift); |
95 | int tries = 1000; | ||
101 | 96 | ||
102 | /* Make sure LCR write wasn't ignored */ | 97 | /* Make sure LCR write wasn't ignored */ |
103 | if (offset == UART_LCR) { | 98 | while (tries--) { |
104 | int tries = 1000; | 99 | unsigned int lcr = p->serial_in(p, UART_LCR); |
105 | while (tries--) { | 100 | |
106 | unsigned int lcr = p->serial_in(p, UART_LCR); | 101 | if ((value & ~UART_LCR_SPAR) == (lcr & ~UART_LCR_SPAR)) |
107 | if ((value & ~UART_LCR_SPAR) == (lcr & ~UART_LCR_SPAR)) | 102 | return; |
108 | return; | 103 | |
109 | dw8250_force_idle(p); | 104 | dw8250_force_idle(p); |
110 | writeb(value, p->membase + (UART_LCR << p->regshift)); | 105 | |
111 | } | 106 | #ifdef CONFIG_64BIT |
112 | /* | 107 | __raw_writeq(value & 0xff, offset); |
113 | * FIXME: this deadlocks if port->lock is already held | 108 | #else |
114 | * dev_err(p->dev, "Couldn't set LCR to %d\n", value); | 109 | if (p->iotype == UPIO_MEM32) |
115 | */ | 110 | writel(value, offset); |
111 | else if (p->iotype == UPIO_MEM32BE) | ||
112 | iowrite32be(value, offset); | ||
113 | else | ||
114 | writeb(value, offset); | ||
115 | #endif | ||
116 | } | 116 | } |
117 | /* | ||
118 | * FIXME: this deadlocks if port->lock is already held | ||
119 | * dev_err(p->dev, "Couldn't set LCR to %d\n", value); | ||
120 | */ | ||
121 | } | ||
122 | |||
123 | static void dw8250_serial_out(struct uart_port *p, int offset, int value) | ||
124 | { | ||
125 | struct dw8250_data *d = p->private_data; | ||
126 | |||
127 | writeb(value, p->membase + (offset << p->regshift)); | ||
128 | |||
129 | if (offset == UART_LCR && !d->uart_16550_compatible) | ||
130 | dw8250_check_lcr(p, value); | ||
117 | } | 131 | } |
118 | 132 | ||
119 | static unsigned int dw8250_serial_in(struct uart_port *p, int offset) | 133 | static unsigned int dw8250_serial_in(struct uart_port *p, int offset) |
@@ -135,49 +149,26 @@ static unsigned int dw8250_serial_inq(struct uart_port *p, int offset) | |||
135 | 149 | ||
136 | static void dw8250_serial_outq(struct uart_port *p, int offset, int value) | 150 | static void dw8250_serial_outq(struct uart_port *p, int offset, int value) |
137 | { | 151 | { |
152 | struct dw8250_data *d = p->private_data; | ||
153 | |||
138 | value &= 0xff; | 154 | value &= 0xff; |
139 | __raw_writeq(value, p->membase + (offset << p->regshift)); | 155 | __raw_writeq(value, p->membase + (offset << p->regshift)); |
140 | /* Read back to ensure register write ordering. */ | 156 | /* Read back to ensure register write ordering. */ |
141 | __raw_readq(p->membase + (UART_LCR << p->regshift)); | 157 | __raw_readq(p->membase + (UART_LCR << p->regshift)); |
142 | 158 | ||
143 | /* Make sure LCR write wasn't ignored */ | 159 | if (offset == UART_LCR && !d->uart_16550_compatible) |
144 | if (offset == UART_LCR) { | 160 | dw8250_check_lcr(p, value); |
145 | int tries = 1000; | ||
146 | while (tries--) { | ||
147 | unsigned int lcr = p->serial_in(p, UART_LCR); | ||
148 | if ((value & ~UART_LCR_SPAR) == (lcr & ~UART_LCR_SPAR)) | ||
149 | return; | ||
150 | dw8250_force_idle(p); | ||
151 | __raw_writeq(value & 0xff, | ||
152 | p->membase + (UART_LCR << p->regshift)); | ||
153 | } | ||
154 | /* | ||
155 | * FIXME: this deadlocks if port->lock is already held | ||
156 | * dev_err(p->dev, "Couldn't set LCR to %d\n", value); | ||
157 | */ | ||
158 | } | ||
159 | } | 161 | } |
160 | #endif /* CONFIG_64BIT */ | 162 | #endif /* CONFIG_64BIT */ |
161 | 163 | ||
162 | static void dw8250_serial_out32(struct uart_port *p, int offset, int value) | 164 | static void dw8250_serial_out32(struct uart_port *p, int offset, int value) |
163 | { | 165 | { |
166 | struct dw8250_data *d = p->private_data; | ||
167 | |||
164 | writel(value, p->membase + (offset << p->regshift)); | 168 | writel(value, p->membase + (offset << p->regshift)); |
165 | 169 | ||
166 | /* Make sure LCR write wasn't ignored */ | 170 | if (offset == UART_LCR && !d->uart_16550_compatible) |
167 | if (offset == UART_LCR) { | 171 | dw8250_check_lcr(p, value); |
168 | int tries = 1000; | ||
169 | while (tries--) { | ||
170 | unsigned int lcr = p->serial_in(p, UART_LCR); | ||
171 | if ((value & ~UART_LCR_SPAR) == (lcr & ~UART_LCR_SPAR)) | ||
172 | return; | ||
173 | dw8250_force_idle(p); | ||
174 | writel(value, p->membase + (UART_LCR << p->regshift)); | ||
175 | } | ||
176 | /* | ||
177 | * FIXME: this deadlocks if port->lock is already held | ||
178 | * dev_err(p->dev, "Couldn't set LCR to %d\n", value); | ||
179 | */ | ||
180 | } | ||
181 | } | 172 | } |
182 | 173 | ||
183 | static unsigned int dw8250_serial_in32(struct uart_port *p, int offset) | 174 | static unsigned int dw8250_serial_in32(struct uart_port *p, int offset) |
@@ -187,14 +178,33 @@ static unsigned int dw8250_serial_in32(struct uart_port *p, int offset) | |||
187 | return dw8250_modify_msr(p, offset, value); | 178 | return dw8250_modify_msr(p, offset, value); |
188 | } | 179 | } |
189 | 180 | ||
181 | static void dw8250_serial_out32be(struct uart_port *p, int offset, int value) | ||
182 | { | ||
183 | struct dw8250_data *d = p->private_data; | ||
184 | |||
185 | iowrite32be(value, p->membase + (offset << p->regshift)); | ||
186 | |||
187 | if (offset == UART_LCR && !d->uart_16550_compatible) | ||
188 | dw8250_check_lcr(p, value); | ||
189 | } | ||
190 | |||
191 | static unsigned int dw8250_serial_in32be(struct uart_port *p, int offset) | ||
192 | { | ||
193 | unsigned int value = ioread32be(p->membase + (offset << p->regshift)); | ||
194 | |||
195 | return dw8250_modify_msr(p, offset, value); | ||
196 | } | ||
197 | |||
198 | |||
190 | static int dw8250_handle_irq(struct uart_port *p) | 199 | static int dw8250_handle_irq(struct uart_port *p) |
191 | { | 200 | { |
192 | struct dw8250_data *d = p->private_data; | 201 | struct dw8250_data *d = p->private_data; |
193 | unsigned int iir = p->serial_in(p, UART_IIR); | 202 | unsigned int iir = p->serial_in(p, UART_IIR); |
194 | 203 | ||
195 | if (serial8250_handle_irq(p, iir)) { | 204 | if (serial8250_handle_irq(p, iir)) |
196 | return 1; | 205 | return 1; |
197 | } else if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) { | 206 | |
207 | if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) { | ||
198 | /* Clear the USR */ | 208 | /* Clear the USR */ |
199 | (void)p->serial_in(p, d->usr_reg); | 209 | (void)p->serial_in(p, d->usr_reg); |
200 | 210 | ||
@@ -281,6 +291,11 @@ static void dw8250_quirks(struct uart_port *p, struct dw8250_data *data) | |||
281 | data->skip_autocfg = true; | 291 | data->skip_autocfg = true; |
282 | } | 292 | } |
283 | #endif | 293 | #endif |
294 | if (of_device_is_big_endian(p->dev->of_node)) { | ||
295 | p->iotype = UPIO_MEM32BE; | ||
296 | p->serial_in = dw8250_serial_in32be; | ||
297 | p->serial_out = dw8250_serial_out32be; | ||
298 | } | ||
284 | } else if (has_acpi_companion(p->dev)) { | 299 | } else if (has_acpi_companion(p->dev)) { |
285 | p->iotype = UPIO_MEM32; | 300 | p->iotype = UPIO_MEM32; |
286 | p->regshift = 2; | 301 | p->regshift = 2; |
@@ -309,14 +324,20 @@ static void dw8250_setup_port(struct uart_port *p) | |||
309 | * If the Component Version Register returns zero, we know that | 324 | * If the Component Version Register returns zero, we know that |
310 | * ADDITIONAL_FEATURES are not enabled. No need to go any further. | 325 | * ADDITIONAL_FEATURES are not enabled. No need to go any further. |
311 | */ | 326 | */ |
312 | reg = readl(p->membase + DW_UART_UCV); | 327 | if (p->iotype == UPIO_MEM32BE) |
328 | reg = ioread32be(p->membase + DW_UART_UCV); | ||
329 | else | ||
330 | reg = readl(p->membase + DW_UART_UCV); | ||
313 | if (!reg) | 331 | if (!reg) |
314 | return; | 332 | return; |
315 | 333 | ||
316 | dev_dbg(p->dev, "Designware UART version %c.%c%c\n", | 334 | dev_dbg(p->dev, "Designware UART version %c.%c%c\n", |
317 | (reg >> 24) & 0xff, (reg >> 16) & 0xff, (reg >> 8) & 0xff); | 335 | (reg >> 24) & 0xff, (reg >> 16) & 0xff, (reg >> 8) & 0xff); |
318 | 336 | ||
319 | reg = readl(p->membase + DW_UART_CPR); | 337 | if (p->iotype == UPIO_MEM32BE) |
338 | reg = ioread32be(p->membase + DW_UART_CPR); | ||
339 | else | ||
340 | reg = readl(p->membase + DW_UART_CPR); | ||
320 | if (!reg) | 341 | if (!reg) |
321 | return; | 342 | return; |
322 | 343 | ||
@@ -463,10 +484,8 @@ static int dw8250_probe(struct platform_device *pdev) | |||
463 | dw8250_quirks(p, data); | 484 | dw8250_quirks(p, data); |
464 | 485 | ||
465 | /* If the Busy Functionality is not implemented, don't handle it */ | 486 | /* If the Busy Functionality is not implemented, don't handle it */ |
466 | if (data->uart_16550_compatible) { | 487 | if (data->uart_16550_compatible) |
467 | p->serial_out = NULL; | ||
468 | p->handle_irq = NULL; | 488 | p->handle_irq = NULL; |
469 | } | ||
470 | 489 | ||
471 | if (!data->skip_autocfg) | 490 | if (!data->skip_autocfg) |
472 | dw8250_setup_port(p); | 491 | dw8250_setup_port(p); |
diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c index af62131af21e..8d08ff5c4e34 100644 --- a/drivers/tty/serial/8250/8250_early.c +++ b/drivers/tty/serial/8250/8250_early.c | |||
@@ -39,15 +39,17 @@ | |||
39 | 39 | ||
40 | static unsigned int __init serial8250_early_in(struct uart_port *port, int offset) | 40 | static unsigned int __init serial8250_early_in(struct uart_port *port, int offset) |
41 | { | 41 | { |
42 | offset <<= port->regshift; | ||
43 | |||
42 | switch (port->iotype) { | 44 | switch (port->iotype) { |
43 | case UPIO_MEM: | 45 | case UPIO_MEM: |
44 | return readb(port->membase + offset); | 46 | return readb(port->membase + offset); |
45 | case UPIO_MEM16: | 47 | case UPIO_MEM16: |
46 | return readw(port->membase + (offset << 1)); | 48 | return readw(port->membase + offset); |
47 | case UPIO_MEM32: | 49 | case UPIO_MEM32: |
48 | return readl(port->membase + (offset << 2)); | 50 | return readl(port->membase + offset); |
49 | case UPIO_MEM32BE: | 51 | case UPIO_MEM32BE: |
50 | return ioread32be(port->membase + (offset << 2)); | 52 | return ioread32be(port->membase + offset); |
51 | case UPIO_PORT: | 53 | case UPIO_PORT: |
52 | return inb(port->iobase + offset); | 54 | return inb(port->iobase + offset); |
53 | default: | 55 | default: |
@@ -57,18 +59,20 @@ static unsigned int __init serial8250_early_in(struct uart_port *port, int offse | |||
57 | 59 | ||
58 | static void __init serial8250_early_out(struct uart_port *port, int offset, int value) | 60 | static void __init serial8250_early_out(struct uart_port *port, int offset, int value) |
59 | { | 61 | { |
62 | offset <<= port->regshift; | ||
63 | |||
60 | switch (port->iotype) { | 64 | switch (port->iotype) { |
61 | case UPIO_MEM: | 65 | case UPIO_MEM: |
62 | writeb(value, port->membase + offset); | 66 | writeb(value, port->membase + offset); |
63 | break; | 67 | break; |
64 | case UPIO_MEM16: | 68 | case UPIO_MEM16: |
65 | writew(value, port->membase + (offset << 1)); | 69 | writew(value, port->membase + offset); |
66 | break; | 70 | break; |
67 | case UPIO_MEM32: | 71 | case UPIO_MEM32: |
68 | writel(value, port->membase + (offset << 2)); | 72 | writel(value, port->membase + offset); |
69 | break; | 73 | break; |
70 | case UPIO_MEM32BE: | 74 | case UPIO_MEM32BE: |
71 | iowrite32be(value, port->membase + (offset << 2)); | 75 | iowrite32be(value, port->membase + offset); |
72 | break; | 76 | break; |
73 | case UPIO_PORT: | 77 | case UPIO_PORT: |
74 | outb(value, port->iobase + offset); | 78 | outb(value, port->iobase + offset); |
@@ -145,3 +149,25 @@ EARLYCON_DECLARE(uart8250, early_serial8250_setup); | |||
145 | EARLYCON_DECLARE(uart, early_serial8250_setup); | 149 | EARLYCON_DECLARE(uart, early_serial8250_setup); |
146 | OF_EARLYCON_DECLARE(ns16550, "ns16550", early_serial8250_setup); | 150 | OF_EARLYCON_DECLARE(ns16550, "ns16550", early_serial8250_setup); |
147 | OF_EARLYCON_DECLARE(ns16550a, "ns16550a", early_serial8250_setup); | 151 | OF_EARLYCON_DECLARE(ns16550a, "ns16550a", early_serial8250_setup); |
152 | OF_EARLYCON_DECLARE(uart, "nvidia,tegra20-uart", early_serial8250_setup); | ||
153 | |||
154 | #ifdef CONFIG_SERIAL_8250_OMAP | ||
155 | |||
156 | static int __init early_omap8250_setup(struct earlycon_device *device, | ||
157 | const char *options) | ||
158 | { | ||
159 | struct uart_port *port = &device->port; | ||
160 | |||
161 | if (!(device->port.membase || device->port.iobase)) | ||
162 | return -ENODEV; | ||
163 | |||
164 | port->regshift = 2; | ||
165 | device->con->write = early_serial8250_write; | ||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | OF_EARLYCON_DECLARE(omap8250, "ti,omap2-uart", early_omap8250_setup); | ||
170 | OF_EARLYCON_DECLARE(omap8250, "ti,omap3-uart", early_omap8250_setup); | ||
171 | OF_EARLYCON_DECLARE(omap8250, "ti,omap4-uart", early_omap8250_setup); | ||
172 | |||
173 | #endif | ||
diff --git a/drivers/tty/serial/8250/8250_exar_st16c554.c b/drivers/tty/serial/8250/8250_exar_st16c554.c index bf53aabf9b5e..3a7cb8262bb9 100644 --- a/drivers/tty/serial/8250/8250_exar_st16c554.c +++ b/drivers/tty/serial/8250/8250_exar_st16c554.c | |||
@@ -13,20 +13,13 @@ | |||
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/serial_8250.h> | 14 | #include <linux/serial_8250.h> |
15 | 15 | ||
16 | #define PORT(_base,_irq) \ | 16 | #include "8250.h" |
17 | { \ | ||
18 | .iobase = _base, \ | ||
19 | .irq = _irq, \ | ||
20 | .uartclk = 1843200, \ | ||
21 | .iotype = UPIO_PORT, \ | ||
22 | .flags = UPF_BOOT_AUTOCONF, \ | ||
23 | } | ||
24 | 17 | ||
25 | static struct plat_serial8250_port exar_data[] = { | 18 | static struct plat_serial8250_port exar_data[] = { |
26 | PORT(0x100, 5), | 19 | SERIAL8250_PORT(0x100, 5), |
27 | PORT(0x108, 5), | 20 | SERIAL8250_PORT(0x108, 5), |
28 | PORT(0x110, 5), | 21 | SERIAL8250_PORT(0x110, 5), |
29 | PORT(0x118, 5), | 22 | SERIAL8250_PORT(0x118, 5), |
30 | { }, | 23 | { }, |
31 | }; | 24 | }; |
32 | 25 | ||
diff --git a/drivers/tty/serial/8250/8250_fourport.c b/drivers/tty/serial/8250/8250_fourport.c index be1582609626..4045180a8cfc 100644 --- a/drivers/tty/serial/8250/8250_fourport.c +++ b/drivers/tty/serial/8250/8250_fourport.c | |||
@@ -10,24 +10,20 @@ | |||
10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
11 | #include <linux/serial_8250.h> | 11 | #include <linux/serial_8250.h> |
12 | 12 | ||
13 | #define PORT(_base,_irq) \ | 13 | #include "8250.h" |
14 | { \ | 14 | |
15 | .iobase = _base, \ | 15 | #define SERIAL8250_FOURPORT(_base, _irq) \ |
16 | .irq = _irq, \ | 16 | SERIAL8250_PORT_FLAGS(_base, _irq, UPF_FOURPORT) |
17 | .uartclk = 1843200, \ | ||
18 | .iotype = UPIO_PORT, \ | ||
19 | .flags = UPF_BOOT_AUTOCONF | UPF_FOURPORT, \ | ||
20 | } | ||
21 | 17 | ||
22 | static struct plat_serial8250_port fourport_data[] = { | 18 | static struct plat_serial8250_port fourport_data[] = { |
23 | PORT(0x1a0, 9), | 19 | SERIAL8250_FOURPORT(0x1a0, 9), |
24 | PORT(0x1a8, 9), | 20 | SERIAL8250_FOURPORT(0x1a8, 9), |
25 | PORT(0x1b0, 9), | 21 | SERIAL8250_FOURPORT(0x1b0, 9), |
26 | PORT(0x1b8, 9), | 22 | SERIAL8250_FOURPORT(0x1b8, 9), |
27 | PORT(0x2a0, 5), | 23 | SERIAL8250_FOURPORT(0x2a0, 5), |
28 | PORT(0x2a8, 5), | 24 | SERIAL8250_FOURPORT(0x2a8, 5), |
29 | PORT(0x2b0, 5), | 25 | SERIAL8250_FOURPORT(0x2b0, 5), |
30 | PORT(0x2b8, 5), | 26 | SERIAL8250_FOURPORT(0x2b8, 5), |
31 | { }, | 27 | { }, |
32 | }; | 28 | }; |
33 | 29 | ||
diff --git a/drivers/tty/serial/8250/8250_gsc.c b/drivers/tty/serial/8250/8250_gsc.c index 2e3ea1a70d7b..b1e6ae9f1ff9 100644 --- a/drivers/tty/serial/8250/8250_gsc.c +++ b/drivers/tty/serial/8250/8250_gsc.c | |||
@@ -42,7 +42,7 @@ static int __init serial_init_chip(struct parisc_device *dev) | |||
42 | * the user what they're missing. | 42 | * the user what they're missing. |
43 | */ | 43 | */ |
44 | if (parisc_parent(dev)->id.hw_type != HPHW_IOA) | 44 | if (parisc_parent(dev)->id.hw_type != HPHW_IOA) |
45 | printk(KERN_INFO | 45 | dev_info(&dev->dev, |
46 | "Serial: device 0x%llx not configured.\n" | 46 | "Serial: device 0x%llx not configured.\n" |
47 | "Enable support for Wax, Lasi, Asp or Dino.\n", | 47 | "Enable support for Wax, Lasi, Asp or Dino.\n", |
48 | (unsigned long long)dev->hpa.start); | 48 | (unsigned long long)dev->hpa.start); |
@@ -66,8 +66,9 @@ static int __init serial_init_chip(struct parisc_device *dev) | |||
66 | 66 | ||
67 | err = serial8250_register_8250_port(&uart); | 67 | err = serial8250_register_8250_port(&uart); |
68 | if (err < 0) { | 68 | if (err < 0) { |
69 | printk(KERN_WARNING | 69 | dev_warn(&dev->dev, |
70 | "serial8250_register_8250_port returned error %d\n", err); | 70 | "serial8250_register_8250_port returned error %d\n", |
71 | err); | ||
71 | iounmap(uart.port.membase); | 72 | iounmap(uart.port.membase); |
72 | return err; | 73 | return err; |
73 | } | 74 | } |
diff --git a/drivers/tty/serial/8250/8250_hp300.c b/drivers/tty/serial/8250/8250_hp300.c index 2891958cd842..38166db2b824 100644 --- a/drivers/tty/serial/8250/8250_hp300.c +++ b/drivers/tty/serial/8250/8250_hp300.c | |||
@@ -24,8 +24,7 @@ | |||
24 | #endif | 24 | #endif |
25 | 25 | ||
26 | #ifdef CONFIG_HPAPCI | 26 | #ifdef CONFIG_HPAPCI |
27 | struct hp300_port | 27 | struct hp300_port { |
28 | { | ||
29 | struct hp300_port *next; /* next port */ | 28 | struct hp300_port *next; /* next port */ |
30 | int line; /* line (tty) number */ | 29 | int line; /* line (tty) number */ |
31 | }; | 30 | }; |
@@ -111,7 +110,7 @@ int __init hp300_setup_serial_console(void) | |||
111 | /* Check for APCI console */ | 110 | /* Check for APCI console */ |
112 | if (scode == 256) { | 111 | if (scode == 256) { |
113 | #ifdef CONFIG_HPAPCI | 112 | #ifdef CONFIG_HPAPCI |
114 | printk(KERN_INFO "Serial console is HP APCI 1\n"); | 113 | pr_info("Serial console is HP APCI 1\n"); |
115 | 114 | ||
116 | port.uartclk = HPAPCI_BAUD_BASE * 16; | 115 | port.uartclk = HPAPCI_BAUD_BASE * 16; |
117 | port.mapbase = (FRODO_BASE + FRODO_APCI_OFFSET(1)); | 116 | port.mapbase = (FRODO_BASE + FRODO_APCI_OFFSET(1)); |
@@ -119,7 +118,7 @@ int __init hp300_setup_serial_console(void) | |||
119 | port.regshift = 2; | 118 | port.regshift = 2; |
120 | add_preferred_console("ttyS", port.line, "9600n8"); | 119 | add_preferred_console("ttyS", port.line, "9600n8"); |
121 | #else | 120 | #else |
122 | printk(KERN_WARNING "Serial console is APCI but support is disabled (CONFIG_HPAPCI)!\n"); | 121 | pr_warn("Serial console is APCI but support is disabled (CONFIG_HPAPCI)!\n"); |
123 | return 0; | 122 | return 0; |
124 | #endif | 123 | #endif |
125 | } else { | 124 | } else { |
@@ -128,7 +127,7 @@ int __init hp300_setup_serial_console(void) | |||
128 | if (!pa) | 127 | if (!pa) |
129 | return 0; | 128 | return 0; |
130 | 129 | ||
131 | printk(KERN_INFO "Serial console is HP DCA at select code %d\n", scode); | 130 | pr_info("Serial console is HP DCA at select code %d\n", scode); |
132 | 131 | ||
133 | port.uartclk = HPDCA_BAUD_BASE * 16; | 132 | port.uartclk = HPDCA_BAUD_BASE * 16; |
134 | port.mapbase = (pa + UART_OFFSET); | 133 | port.mapbase = (pa + UART_OFFSET); |
@@ -142,13 +141,13 @@ int __init hp300_setup_serial_console(void) | |||
142 | if (DIO_ID(pa + DIO_VIRADDRBASE) & 0x80) | 141 | if (DIO_ID(pa + DIO_VIRADDRBASE) & 0x80) |
143 | add_preferred_console("ttyS", port.line, "9600n8"); | 142 | add_preferred_console("ttyS", port.line, "9600n8"); |
144 | #else | 143 | #else |
145 | printk(KERN_WARNING "Serial console is DCA but support is disabled (CONFIG_HPDCA)!\n"); | 144 | pr_warn("Serial console is DCA but support is disabled (CONFIG_HPDCA)!\n"); |
146 | return 0; | 145 | return 0; |
147 | #endif | 146 | #endif |
148 | } | 147 | } |
149 | 148 | ||
150 | if (early_serial_setup(&port) < 0) | 149 | if (early_serial_setup(&port) < 0) |
151 | printk(KERN_WARNING "hp300_setup_serial_console(): early_serial_setup() failed.\n"); | 150 | pr_warn("%s: early_serial_setup() failed.\n", __func__); |
152 | return 0; | 151 | return 0; |
153 | } | 152 | } |
154 | #endif /* CONFIG_SERIAL_8250_CONSOLE */ | 153 | #endif /* CONFIG_SERIAL_8250_CONSOLE */ |
@@ -180,8 +179,9 @@ static int hpdca_init_one(struct dio_dev *d, | |||
180 | line = serial8250_register_8250_port(&uart); | 179 | line = serial8250_register_8250_port(&uart); |
181 | 180 | ||
182 | if (line < 0) { | 181 | if (line < 0) { |
183 | printk(KERN_NOTICE "8250_hp300: register_serial() DCA scode %d" | 182 | dev_notice(&d->dev, |
184 | " irq %d failed\n", d->scode, uart.port.irq); | 183 | "8250_hp300: register_serial() DCA scode %d irq %d failed\n", |
184 | d->scode, uart.port.irq); | ||
185 | return -ENOMEM; | 185 | return -ENOMEM; |
186 | } | 186 | } |
187 | 187 | ||
@@ -249,8 +249,8 @@ static int __init hp300_8250_init(void) | |||
249 | 249 | ||
250 | /* Memory mapped I/O */ | 250 | /* Memory mapped I/O */ |
251 | uart.port.iotype = UPIO_MEM; | 251 | uart.port.iotype = UPIO_MEM; |
252 | uart.port.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ \ | 252 | uart.port.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ |
253 | | UPF_BOOT_AUTOCONF; | 253 | | UPF_BOOT_AUTOCONF; |
254 | /* XXX - no interrupt support yet */ | 254 | /* XXX - no interrupt support yet */ |
255 | uart.port.irq = 0; | 255 | uart.port.irq = 0; |
256 | uart.port.uartclk = HPAPCI_BAUD_BASE * 16; | 256 | uart.port.uartclk = HPAPCI_BAUD_BASE * 16; |
@@ -261,8 +261,9 @@ static int __init hp300_8250_init(void) | |||
261 | line = serial8250_register_8250_port(&uart); | 261 | line = serial8250_register_8250_port(&uart); |
262 | 262 | ||
263 | if (line < 0) { | 263 | if (line < 0) { |
264 | printk(KERN_NOTICE "8250_hp300: register_serial() APCI" | 264 | dev_notice(uart.port.dev, |
265 | " %d irq %d failed\n", i, uart.port.irq); | 265 | "8250_hp300: register_serial() APCI %d irq %d failed\n", |
266 | i, uart.port.irq); | ||
266 | kfree(port); | 267 | kfree(port); |
267 | continue; | 268 | continue; |
268 | } | 269 | } |
diff --git a/drivers/tty/serial/8250/8250_hub6.c b/drivers/tty/serial/8250/8250_hub6.c index a5c778e83de0..27124e21eb96 100644 --- a/drivers/tty/serial/8250/8250_hub6.c +++ b/drivers/tty/serial/8250/8250_hub6.c | |||
@@ -10,7 +10,7 @@ | |||
10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
11 | #include <linux/serial_8250.h> | 11 | #include <linux/serial_8250.h> |
12 | 12 | ||
13 | #define HUB6(card,port) \ | 13 | #define HUB6(card, port) \ |
14 | { \ | 14 | { \ |
15 | .iobase = 0x302, \ | 15 | .iobase = 0x302, \ |
16 | .irq = 3, \ | 16 | .irq = 3, \ |
diff --git a/drivers/tty/serial/8250/8250_ingenic.c b/drivers/tty/serial/8250/8250_ingenic.c index d6e1ec9b4fde..b0677f610863 100644 --- a/drivers/tty/serial/8250/8250_ingenic.c +++ b/drivers/tty/serial/8250/8250_ingenic.c | |||
@@ -48,7 +48,7 @@ static const struct of_device_id of_match[]; | |||
48 | #define UART_MCR_MDCE BIT(7) | 48 | #define UART_MCR_MDCE BIT(7) |
49 | #define UART_MCR_FCM BIT(6) | 49 | #define UART_MCR_FCM BIT(6) |
50 | 50 | ||
51 | #ifdef CONFIG_SERIAL_EARLYCON | 51 | #if defined(CONFIG_SERIAL_EARLYCON) && !defined(MODULE) |
52 | static struct earlycon_device *early_device; | 52 | static struct earlycon_device *early_device; |
53 | 53 | ||
54 | static uint8_t __init early_in(struct uart_port *port, int offset) | 54 | static uint8_t __init early_in(struct uart_port *port, int offset) |
@@ -154,14 +154,18 @@ static void ingenic_uart_serial_out(struct uart_port *p, int offset, int value) | |||
154 | break; | 154 | break; |
155 | 155 | ||
156 | case UART_IER: | 156 | case UART_IER: |
157 | /* Enable receive timeout interrupt with the | 157 | /* |
158 | * receive line status interrupt */ | 158 | * Enable receive timeout interrupt with the receive line |
159 | * status interrupt. | ||
160 | */ | ||
159 | value |= (value & 0x4) << 2; | 161 | value |= (value & 0x4) << 2; |
160 | break; | 162 | break; |
161 | 163 | ||
162 | case UART_MCR: | 164 | case UART_MCR: |
163 | /* If we have enabled modem status IRQs we should enable modem | 165 | /* |
164 | * mode. */ | 166 | * If we have enabled modem status IRQs we should enable |
167 | * modem mode. | ||
168 | */ | ||
165 | ier = p->serial_in(p, UART_IER); | 169 | ier = p->serial_in(p, UART_IER); |
166 | 170 | ||
167 | if (ier & UART_IER_MSI) | 171 | if (ier & UART_IER_MSI) |
diff --git a/drivers/tty/serial/8250/8250_moxa.c b/drivers/tty/serial/8250/8250_moxa.c new file mode 100644 index 000000000000..26eb5393a263 --- /dev/null +++ b/drivers/tty/serial/8250/8250_moxa.c | |||
@@ -0,0 +1,157 @@ | |||
1 | /* | ||
2 | * 8250_moxa.c - MOXA Smartio/Industio MUE multiport serial driver. | ||
3 | * | ||
4 | * Author: Mathieu OTHACEHE <m.othacehe@gmail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/pci.h> | ||
13 | |||
14 | #include "8250.h" | ||
15 | |||
16 | #define PCI_DEVICE_ID_MOXA_CP102E 0x1024 | ||
17 | #define PCI_DEVICE_ID_MOXA_CP102EL 0x1025 | ||
18 | #define PCI_DEVICE_ID_MOXA_CP104EL_A 0x1045 | ||
19 | #define PCI_DEVICE_ID_MOXA_CP114EL 0x1144 | ||
20 | #define PCI_DEVICE_ID_MOXA_CP116E_A_A 0x1160 | ||
21 | #define PCI_DEVICE_ID_MOXA_CP116E_A_B 0x1161 | ||
22 | #define PCI_DEVICE_ID_MOXA_CP118EL_A 0x1182 | ||
23 | #define PCI_DEVICE_ID_MOXA_CP118E_A_I 0x1183 | ||
24 | #define PCI_DEVICE_ID_MOXA_CP132EL 0x1322 | ||
25 | #define PCI_DEVICE_ID_MOXA_CP134EL_A 0x1342 | ||
26 | #define PCI_DEVICE_ID_MOXA_CP138E_A 0x1381 | ||
27 | #define PCI_DEVICE_ID_MOXA_CP168EL_A 0x1683 | ||
28 | |||
29 | #define MOXA_BASE_BAUD 921600 | ||
30 | #define MOXA_UART_OFFSET 0x200 | ||
31 | #define MOXA_BASE_BAR 1 | ||
32 | |||
33 | struct moxa8250_board { | ||
34 | unsigned int num_ports; | ||
35 | int line[0]; | ||
36 | }; | ||
37 | |||
38 | enum { | ||
39 | moxa8250_2p = 0, | ||
40 | moxa8250_4p, | ||
41 | moxa8250_8p | ||
42 | }; | ||
43 | |||
44 | static struct moxa8250_board moxa8250_boards[] = { | ||
45 | [moxa8250_2p] = { .num_ports = 2}, | ||
46 | [moxa8250_4p] = { .num_ports = 4}, | ||
47 | [moxa8250_8p] = { .num_ports = 8}, | ||
48 | }; | ||
49 | |||
50 | static int moxa8250_probe(struct pci_dev *pdev, const struct pci_device_id *id) | ||
51 | { | ||
52 | struct uart_8250_port uart; | ||
53 | struct moxa8250_board *brd; | ||
54 | void __iomem *ioaddr; | ||
55 | resource_size_t baseaddr; | ||
56 | unsigned int i, nr_ports; | ||
57 | unsigned int offset; | ||
58 | int ret; | ||
59 | |||
60 | brd = &moxa8250_boards[id->driver_data]; | ||
61 | nr_ports = brd->num_ports; | ||
62 | |||
63 | ret = pcim_enable_device(pdev); | ||
64 | if (ret) | ||
65 | return ret; | ||
66 | |||
67 | brd = devm_kzalloc(&pdev->dev, sizeof(struct moxa8250_board) + | ||
68 | sizeof(unsigned int) * nr_ports, GFP_KERNEL); | ||
69 | if (!brd) | ||
70 | return -ENOMEM; | ||
71 | |||
72 | memset(&uart, 0, sizeof(struct uart_8250_port)); | ||
73 | |||
74 | uart.port.dev = &pdev->dev; | ||
75 | uart.port.irq = pdev->irq; | ||
76 | uart.port.uartclk = MOXA_BASE_BAUD * 16; | ||
77 | uart.port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ; | ||
78 | |||
79 | baseaddr = pci_resource_start(pdev, MOXA_BASE_BAR); | ||
80 | ioaddr = pcim_iomap(pdev, MOXA_BASE_BAR, 0); | ||
81 | if (!ioaddr) | ||
82 | return -ENOMEM; | ||
83 | |||
84 | for (i = 0; i < nr_ports; i++) { | ||
85 | |||
86 | /* | ||
87 | * MOXA Smartio MUE boards with 4 ports have | ||
88 | * a different offset for port #3 | ||
89 | */ | ||
90 | if (nr_ports == 4 && i == 3) | ||
91 | offset = 7 * MOXA_UART_OFFSET; | ||
92 | else | ||
93 | offset = i * MOXA_UART_OFFSET; | ||
94 | |||
95 | uart.port.iotype = UPIO_MEM; | ||
96 | uart.port.iobase = 0; | ||
97 | uart.port.mapbase = baseaddr + offset; | ||
98 | uart.port.membase = ioaddr + offset; | ||
99 | uart.port.regshift = 0; | ||
100 | |||
101 | dev_dbg(&pdev->dev, "Setup PCI port: port %lx, irq %d, type %d\n", | ||
102 | uart.port.iobase, uart.port.irq, uart.port.iotype); | ||
103 | |||
104 | brd->line[i] = serial8250_register_8250_port(&uart); | ||
105 | if (brd->line[i] < 0) { | ||
106 | dev_err(&pdev->dev, | ||
107 | "Couldn't register serial port %lx, irq %d, type %d, error %d\n", | ||
108 | uart.port.iobase, uart.port.irq, | ||
109 | uart.port.iotype, brd->line[i]); | ||
110 | break; | ||
111 | } | ||
112 | } | ||
113 | |||
114 | pci_set_drvdata(pdev, brd); | ||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | static void moxa8250_remove(struct pci_dev *pdev) | ||
119 | { | ||
120 | struct moxa8250_board *brd = pci_get_drvdata(pdev); | ||
121 | unsigned int i; | ||
122 | |||
123 | for (i = 0; i < brd->num_ports; i++) | ||
124 | serial8250_unregister_port(brd->line[i]); | ||
125 | } | ||
126 | |||
127 | #define MOXA_DEVICE(id, data) { PCI_VDEVICE(MOXA, id), (kernel_ulong_t)data } | ||
128 | |||
129 | static const struct pci_device_id pci_ids[] = { | ||
130 | MOXA_DEVICE(PCI_DEVICE_ID_MOXA_CP102E, moxa8250_2p), | ||
131 | MOXA_DEVICE(PCI_DEVICE_ID_MOXA_CP102EL, moxa8250_2p), | ||
132 | MOXA_DEVICE(PCI_DEVICE_ID_MOXA_CP104EL_A, moxa8250_4p), | ||
133 | MOXA_DEVICE(PCI_DEVICE_ID_MOXA_CP114EL, moxa8250_4p), | ||
134 | MOXA_DEVICE(PCI_DEVICE_ID_MOXA_CP116E_A_A, moxa8250_8p), | ||
135 | MOXA_DEVICE(PCI_DEVICE_ID_MOXA_CP116E_A_B, moxa8250_8p), | ||
136 | MOXA_DEVICE(PCI_DEVICE_ID_MOXA_CP118EL_A, moxa8250_8p), | ||
137 | MOXA_DEVICE(PCI_DEVICE_ID_MOXA_CP118E_A_I, moxa8250_8p), | ||
138 | MOXA_DEVICE(PCI_DEVICE_ID_MOXA_CP132EL, moxa8250_2p), | ||
139 | MOXA_DEVICE(PCI_DEVICE_ID_MOXA_CP134EL_A, moxa8250_4p), | ||
140 | MOXA_DEVICE(PCI_DEVICE_ID_MOXA_CP138E_A, moxa8250_8p), | ||
141 | MOXA_DEVICE(PCI_DEVICE_ID_MOXA_CP168EL_A, moxa8250_8p), | ||
142 | {0} | ||
143 | }; | ||
144 | MODULE_DEVICE_TABLE(pci, pci_ids); | ||
145 | |||
146 | static struct pci_driver moxa8250_pci_driver = { | ||
147 | .name = "8250_moxa", | ||
148 | .id_table = pci_ids, | ||
149 | .probe = moxa8250_probe, | ||
150 | .remove = moxa8250_remove, | ||
151 | }; | ||
152 | |||
153 | module_pci_driver(moxa8250_pci_driver); | ||
154 | |||
155 | MODULE_AUTHOR("Mathieu OTHACEHE"); | ||
156 | MODULE_DESCRIPTION("MOXA SmartIO MUE driver"); | ||
157 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c index 0e590b233f03..3489fbcb7313 100644 --- a/drivers/tty/serial/8250/8250_mtk.c +++ b/drivers/tty/serial/8250/8250_mtk.c | |||
@@ -16,7 +16,7 @@ | |||
16 | */ | 16 | */ |
17 | #include <linux/clk.h> | 17 | #include <linux/clk.h> |
18 | #include <linux/io.h> | 18 | #include <linux/io.h> |
19 | #include <linux/init.h> | 19 | #include <linux/module.h> |
20 | #include <linux/of_irq.h> | 20 | #include <linux/of_irq.h> |
21 | #include <linux/of_platform.h> | 21 | #include <linux/of_platform.h> |
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
@@ -41,12 +41,10 @@ static void | |||
41 | mtk8250_set_termios(struct uart_port *port, struct ktermios *termios, | 41 | mtk8250_set_termios(struct uart_port *port, struct ktermios *termios, |
42 | struct ktermios *old) | 42 | struct ktermios *old) |
43 | { | 43 | { |
44 | struct uart_8250_port *up = up_to_u8250p(port); | ||
44 | unsigned long flags; | 45 | unsigned long flags; |
45 | unsigned int baud, quot; | 46 | unsigned int baud, quot; |
46 | 47 | ||
47 | struct uart_8250_port *up = | ||
48 | container_of(port, struct uart_8250_port, port); | ||
49 | |||
50 | serial8250_do_set_termios(port, termios, old); | 48 | serial8250_do_set_termios(port, termios, old); |
51 | 49 | ||
52 | /* | 50 | /* |
@@ -116,7 +114,7 @@ mtk8250_set_termios(struct uart_port *port, struct ktermios *termios, | |||
116 | tty_termios_encode_baud_rate(termios, baud, baud); | 114 | tty_termios_encode_baud_rate(termios, baud, baud); |
117 | } | 115 | } |
118 | 116 | ||
119 | static int mtk8250_runtime_suspend(struct device *dev) | 117 | static int __maybe_unused mtk8250_runtime_suspend(struct device *dev) |
120 | { | 118 | { |
121 | struct mtk8250_data *data = dev_get_drvdata(dev); | 119 | struct mtk8250_data *data = dev_get_drvdata(dev); |
122 | 120 | ||
@@ -126,7 +124,7 @@ static int mtk8250_runtime_suspend(struct device *dev) | |||
126 | return 0; | 124 | return 0; |
127 | } | 125 | } |
128 | 126 | ||
129 | static int mtk8250_runtime_resume(struct device *dev) | 127 | static int __maybe_unused mtk8250_runtime_resume(struct device *dev) |
130 | { | 128 | { |
131 | struct mtk8250_data *data = dev_get_drvdata(dev); | 129 | struct mtk8250_data *data = dev_get_drvdata(dev); |
132 | int err; | 130 | int err; |
@@ -245,8 +243,24 @@ static int mtk8250_probe(struct platform_device *pdev) | |||
245 | return 0; | 243 | return 0; |
246 | } | 244 | } |
247 | 245 | ||
248 | #ifdef CONFIG_PM_SLEEP | 246 | static int mtk8250_remove(struct platform_device *pdev) |
249 | static int mtk8250_suspend(struct device *dev) | 247 | { |
248 | struct mtk8250_data *data = platform_get_drvdata(pdev); | ||
249 | |||
250 | pm_runtime_get_sync(&pdev->dev); | ||
251 | |||
252 | serial8250_unregister_port(data->line); | ||
253 | |||
254 | pm_runtime_disable(&pdev->dev); | ||
255 | pm_runtime_put_noidle(&pdev->dev); | ||
256 | |||
257 | if (!pm_runtime_status_suspended(&pdev->dev)) | ||
258 | mtk8250_runtime_suspend(&pdev->dev); | ||
259 | |||
260 | return 0; | ||
261 | } | ||
262 | |||
263 | static int __maybe_unused mtk8250_suspend(struct device *dev) | ||
250 | { | 264 | { |
251 | struct mtk8250_data *data = dev_get_drvdata(dev); | 265 | struct mtk8250_data *data = dev_get_drvdata(dev); |
252 | 266 | ||
@@ -255,7 +269,7 @@ static int mtk8250_suspend(struct device *dev) | |||
255 | return 0; | 269 | return 0; |
256 | } | 270 | } |
257 | 271 | ||
258 | static int mtk8250_resume(struct device *dev) | 272 | static int __maybe_unused mtk8250_resume(struct device *dev) |
259 | { | 273 | { |
260 | struct mtk8250_data *data = dev_get_drvdata(dev); | 274 | struct mtk8250_data *data = dev_get_drvdata(dev); |
261 | 275 | ||
@@ -263,7 +277,6 @@ static int mtk8250_resume(struct device *dev) | |||
263 | 277 | ||
264 | return 0; | 278 | return 0; |
265 | } | 279 | } |
266 | #endif /* CONFIG_PM_SLEEP */ | ||
267 | 280 | ||
268 | static const struct dev_pm_ops mtk8250_pm_ops = { | 281 | static const struct dev_pm_ops mtk8250_pm_ops = { |
269 | SET_SYSTEM_SLEEP_PM_OPS(mtk8250_suspend, mtk8250_resume) | 282 | SET_SYSTEM_SLEEP_PM_OPS(mtk8250_suspend, mtk8250_resume) |
@@ -275,20 +288,20 @@ static const struct of_device_id mtk8250_of_match[] = { | |||
275 | { .compatible = "mediatek,mt6577-uart" }, | 288 | { .compatible = "mediatek,mt6577-uart" }, |
276 | { /* Sentinel */ } | 289 | { /* Sentinel */ } |
277 | }; | 290 | }; |
291 | MODULE_DEVICE_TABLE(of, mtk8250_of_match); | ||
278 | 292 | ||
279 | static struct platform_driver mtk8250_platform_driver = { | 293 | static struct platform_driver mtk8250_platform_driver = { |
280 | .driver = { | 294 | .driver = { |
281 | .name = "mt6577-uart", | 295 | .name = "mt6577-uart", |
282 | .pm = &mtk8250_pm_ops, | 296 | .pm = &mtk8250_pm_ops, |
283 | .of_match_table = mtk8250_of_match, | 297 | .of_match_table = mtk8250_of_match, |
284 | .suppress_bind_attrs = true, | ||
285 | |||
286 | }, | 298 | }, |
287 | .probe = mtk8250_probe, | 299 | .probe = mtk8250_probe, |
300 | .remove = mtk8250_remove, | ||
288 | }; | 301 | }; |
289 | builtin_platform_driver(mtk8250_platform_driver); | 302 | module_platform_driver(mtk8250_platform_driver); |
290 | 303 | ||
291 | #ifdef CONFIG_SERIAL_8250_CONSOLE | 304 | #if defined(CONFIG_SERIAL_8250_CONSOLE) && !defined(MODULE) |
292 | static int __init early_mtk8250_setup(struct earlycon_device *device, | 305 | static int __init early_mtk8250_setup(struct earlycon_device *device, |
293 | const char *options) | 306 | const char *options) |
294 | { | 307 | { |
@@ -302,3 +315,7 @@ static int __init early_mtk8250_setup(struct earlycon_device *device, | |||
302 | 315 | ||
303 | OF_EARLYCON_DECLARE(mtk8250, "mediatek,mt6577-uart", early_mtk8250_setup); | 316 | OF_EARLYCON_DECLARE(mtk8250, "mediatek,mt6577-uart", early_mtk8250_setup); |
304 | #endif | 317 | #endif |
318 | |||
319 | MODULE_AUTHOR("Matthias Brugger"); | ||
320 | MODULE_LICENSE("GPL"); | ||
321 | MODULE_DESCRIPTION("Mediatek 8250 serial port driver"); | ||
diff --git a/drivers/tty/serial/8250/8250_of.c b/drivers/tty/serial/8250/8250_of.c index 33021c1f7d55..c7ed3d2bc8b2 100644 --- a/drivers/tty/serial/8250/8250_of.c +++ b/drivers/tty/serial/8250/8250_of.c | |||
@@ -335,6 +335,7 @@ static struct platform_driver of_platform_serial_driver = { | |||
335 | .driver = { | 335 | .driver = { |
336 | .name = "of_serial", | 336 | .name = "of_serial", |
337 | .of_match_table = of_platform_serial_table, | 337 | .of_match_table = of_platform_serial_table, |
338 | .pm = &of_serial_pm_ops, | ||
338 | }, | 339 | }, |
339 | .probe = of_platform_serial_probe, | 340 | .probe = of_platform_serial_probe, |
340 | .remove = of_platform_serial_remove, | 341 | .remove = of_platform_serial_remove, |
diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index a2c0734c76e2..6f760510e46d 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c | |||
@@ -318,8 +318,7 @@ static void omap_8250_set_termios(struct uart_port *port, | |||
318 | struct ktermios *termios, | 318 | struct ktermios *termios, |
319 | struct ktermios *old) | 319 | struct ktermios *old) |
320 | { | 320 | { |
321 | struct uart_8250_port *up = | 321 | struct uart_8250_port *up = up_to_u8250p(port); |
322 | container_of(port, struct uart_8250_port, port); | ||
323 | struct omap8250_priv *priv = up->port.private_data; | 322 | struct omap8250_priv *priv = up->port.private_data; |
324 | unsigned char cval = 0; | 323 | unsigned char cval = 0; |
325 | unsigned int baud; | 324 | unsigned int baud; |
@@ -682,9 +681,8 @@ static void omap_8250_shutdown(struct uart_port *port) | |||
682 | 681 | ||
683 | static void omap_8250_throttle(struct uart_port *port) | 682 | static void omap_8250_throttle(struct uart_port *port) |
684 | { | 683 | { |
684 | struct uart_8250_port *up = up_to_u8250p(port); | ||
685 | unsigned long flags; | 685 | unsigned long flags; |
686 | struct uart_8250_port *up = | ||
687 | container_of(port, struct uart_8250_port, port); | ||
688 | 686 | ||
689 | pm_runtime_get_sync(port->dev); | 687 | pm_runtime_get_sync(port->dev); |
690 | 688 | ||
@@ -697,11 +695,40 @@ static void omap_8250_throttle(struct uart_port *port) | |||
697 | pm_runtime_put_autosuspend(port->dev); | 695 | pm_runtime_put_autosuspend(port->dev); |
698 | } | 696 | } |
699 | 697 | ||
698 | static int omap_8250_rs485_config(struct uart_port *port, | ||
699 | struct serial_rs485 *rs485) | ||
700 | { | ||
701 | struct uart_8250_port *up = up_to_u8250p(port); | ||
702 | |||
703 | /* Clamp the delays to [0, 100ms] */ | ||
704 | rs485->delay_rts_before_send = min(rs485->delay_rts_before_send, 100U); | ||
705 | rs485->delay_rts_after_send = min(rs485->delay_rts_after_send, 100U); | ||
706 | |||
707 | port->rs485 = *rs485; | ||
708 | |||
709 | /* | ||
710 | * Both serial8250_em485_init and serial8250_em485_destroy | ||
711 | * are idempotent | ||
712 | */ | ||
713 | if (rs485->flags & SER_RS485_ENABLED) { | ||
714 | int ret = serial8250_em485_init(up); | ||
715 | |||
716 | if (ret) { | ||
717 | rs485->flags &= ~SER_RS485_ENABLED; | ||
718 | port->rs485.flags &= ~SER_RS485_ENABLED; | ||
719 | } | ||
720 | return ret; | ||
721 | } | ||
722 | |||
723 | serial8250_em485_destroy(up); | ||
724 | |||
725 | return 0; | ||
726 | } | ||
727 | |||
700 | static void omap_8250_unthrottle(struct uart_port *port) | 728 | static void omap_8250_unthrottle(struct uart_port *port) |
701 | { | 729 | { |
730 | struct uart_8250_port *up = up_to_u8250p(port); | ||
702 | unsigned long flags; | 731 | unsigned long flags; |
703 | struct uart_8250_port *up = | ||
704 | container_of(port, struct uart_8250_port, port); | ||
705 | 732 | ||
706 | pm_runtime_get_sync(port->dev); | 733 | pm_runtime_get_sync(port->dev); |
707 | 734 | ||
@@ -1146,6 +1173,7 @@ static int omap8250_probe(struct platform_device *pdev) | |||
1146 | up.port.shutdown = omap_8250_shutdown; | 1173 | up.port.shutdown = omap_8250_shutdown; |
1147 | up.port.throttle = omap_8250_throttle; | 1174 | up.port.throttle = omap_8250_throttle; |
1148 | up.port.unthrottle = omap_8250_unthrottle; | 1175 | up.port.unthrottle = omap_8250_unthrottle; |
1176 | up.port.rs485_config = omap_8250_rs485_config; | ||
1149 | 1177 | ||
1150 | if (pdev->dev.of_node) { | 1178 | if (pdev->dev.of_node) { |
1151 | const struct of_device_id *id; | 1179 | const struct of_device_id *id; |
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 7cd6f9a90542..98862aa5bb58 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c | |||
@@ -55,7 +55,6 @@ struct pci_serial_quirk { | |||
55 | struct serial_private { | 55 | struct serial_private { |
56 | struct pci_dev *dev; | 56 | struct pci_dev *dev; |
57 | unsigned int nr; | 57 | unsigned int nr; |
58 | void __iomem *remapped_bar[PCI_NUM_BAR_RESOURCES]; | ||
59 | struct pci_serial_quirk *quirk; | 58 | struct pci_serial_quirk *quirk; |
60 | int line[0]; | 59 | int line[0]; |
61 | }; | 60 | }; |
@@ -85,15 +84,13 @@ setup_port(struct serial_private *priv, struct uart_8250_port *port, | |||
85 | return -EINVAL; | 84 | return -EINVAL; |
86 | 85 | ||
87 | if (pci_resource_flags(dev, bar) & IORESOURCE_MEM) { | 86 | if (pci_resource_flags(dev, bar) & IORESOURCE_MEM) { |
88 | if (!priv->remapped_bar[bar]) | 87 | if (!pcim_iomap(dev, bar, 0) && !pcim_iomap_table(dev)) |
89 | priv->remapped_bar[bar] = pci_ioremap_bar(dev, bar); | ||
90 | if (!priv->remapped_bar[bar]) | ||
91 | return -ENOMEM; | 88 | return -ENOMEM; |
92 | 89 | ||
93 | port->port.iotype = UPIO_MEM; | 90 | port->port.iotype = UPIO_MEM; |
94 | port->port.iobase = 0; | 91 | port->port.iobase = 0; |
95 | port->port.mapbase = pci_resource_start(dev, bar) + offset; | 92 | port->port.mapbase = pci_resource_start(dev, bar) + offset; |
96 | port->port.membase = priv->remapped_bar[bar] + offset; | 93 | port->port.membase = pcim_iomap_table(dev)[bar] + offset; |
97 | port->port.regshift = regshift; | 94 | port->port.regshift = regshift; |
98 | } else { | 95 | } else { |
99 | port->port.iotype = UPIO_PORT; | 96 | port->port.iotype = UPIO_PORT; |
@@ -721,7 +718,7 @@ static int pci_ni8430_init(struct pci_dev *dev) | |||
721 | */ | 718 | */ |
722 | pcibios_resource_to_bus(dev->bus, ®ion, &dev->resource[bar]); | 719 | pcibios_resource_to_bus(dev->bus, ®ion, &dev->resource[bar]); |
723 | device_window = ((region.start + MITE_IOWBSR1_WIN_OFFSET) & 0xffffff00) | 720 | device_window = ((region.start + MITE_IOWBSR1_WIN_OFFSET) & 0xffffff00) |
724 | | MITE_IOWBSR1_WENAB | MITE_IOWBSR1_WSIZE; | 721 | | MITE_IOWBSR1_WENAB | MITE_IOWBSR1_WSIZE; |
725 | writel(device_window, p + MITE_IOWBSR1); | 722 | writel(device_window, p + MITE_IOWBSR1); |
726 | 723 | ||
727 | /* Set window access to go to RAMSEL IO address space */ | 724 | /* Set window access to go to RAMSEL IO address space */ |
@@ -803,12 +800,12 @@ static int pci_netmos_9900_numports(struct pci_dev *dev) | |||
803 | unsigned int pi; | 800 | unsigned int pi; |
804 | unsigned short sub_serports; | 801 | unsigned short sub_serports; |
805 | 802 | ||
806 | pi = (c & 0xff); | 803 | pi = c & 0xff; |
807 | 804 | ||
808 | if (pi == 2) { | 805 | if (pi == 2) |
809 | return 1; | 806 | return 1; |
810 | } else if ((pi == 0) && | 807 | |
811 | (dev->device == PCI_DEVICE_ID_NETMOS_9900)) { | 808 | if ((pi == 0) && (dev->device == PCI_DEVICE_ID_NETMOS_9900)) { |
812 | /* two possibilities: 0x30ps encodes number of parallel and | 809 | /* two possibilities: 0x30ps encodes number of parallel and |
813 | * serial ports, or 0x1000 indicates *something*. This is not | 810 | * serial ports, or 0x1000 indicates *something*. This is not |
814 | * immediately obvious, since the 2s1p+4s configuration seems | 811 | * immediately obvious, since the 2s1p+4s configuration seems |
@@ -816,12 +813,12 @@ static int pci_netmos_9900_numports(struct pci_dev *dev) | |||
816 | * advertising the same function 3 as the 4s+2s1p config. | 813 | * advertising the same function 3 as the 4s+2s1p config. |
817 | */ | 814 | */ |
818 | sub_serports = dev->subsystem_device & 0xf; | 815 | sub_serports = dev->subsystem_device & 0xf; |
819 | if (sub_serports > 0) { | 816 | if (sub_serports > 0) |
820 | return sub_serports; | 817 | return sub_serports; |
821 | } else { | 818 | |
822 | dev_err(&dev->dev, "NetMos/Mostech serial driver ignoring port on ambiguous config.\n"); | 819 | dev_err(&dev->dev, |
823 | return 0; | 820 | "NetMos/Mostech serial driver ignoring port on ambiguous config.\n"); |
824 | } | 821 | return 0; |
825 | } | 822 | } |
826 | 823 | ||
827 | moan_device("unknown NetMos/Mostech program interface", dev); | 824 | moan_device("unknown NetMos/Mostech program interface", dev); |
@@ -842,21 +839,21 @@ static int pci_netmos_init(struct pci_dev *dev) | |||
842 | return 0; | 839 | return 0; |
843 | 840 | ||
844 | switch (dev->device) { /* FALLTHROUGH on all */ | 841 | switch (dev->device) { /* FALLTHROUGH on all */ |
845 | case PCI_DEVICE_ID_NETMOS_9904: | 842 | case PCI_DEVICE_ID_NETMOS_9904: |
846 | case PCI_DEVICE_ID_NETMOS_9912: | 843 | case PCI_DEVICE_ID_NETMOS_9912: |
847 | case PCI_DEVICE_ID_NETMOS_9922: | 844 | case PCI_DEVICE_ID_NETMOS_9922: |
848 | case PCI_DEVICE_ID_NETMOS_9900: | 845 | case PCI_DEVICE_ID_NETMOS_9900: |
849 | num_serial = pci_netmos_9900_numports(dev); | 846 | num_serial = pci_netmos_9900_numports(dev); |
850 | break; | 847 | break; |
851 | 848 | ||
852 | default: | 849 | default: |
853 | if (num_serial == 0 ) { | 850 | break; |
854 | moan_device("unknown NetMos/Mostech device", dev); | ||
855 | } | ||
856 | } | 851 | } |
857 | 852 | ||
858 | if (num_serial == 0) | 853 | if (num_serial == 0) { |
854 | moan_device("unknown NetMos/Mostech device", dev); | ||
859 | return -ENODEV; | 855 | return -ENODEV; |
856 | } | ||
860 | 857 | ||
861 | return num_serial; | 858 | return num_serial; |
862 | } | 859 | } |
@@ -1198,8 +1195,9 @@ static int pci_quatech_has_qmcr(struct uart_8250_port *port) | |||
1198 | 1195 | ||
1199 | static int pci_quatech_test(struct uart_8250_port *port) | 1196 | static int pci_quatech_test(struct uart_8250_port *port) |
1200 | { | 1197 | { |
1201 | u8 reg; | 1198 | u8 reg, qopr; |
1202 | u8 qopr = pci_quatech_rqopr(port); | 1199 | |
1200 | qopr = pci_quatech_rqopr(port); | ||
1203 | pci_quatech_wqopr(port, qopr & QPCR_TEST_FOR1); | 1201 | pci_quatech_wqopr(port, qopr & QPCR_TEST_FOR1); |
1204 | reg = pci_quatech_rqopr(port) & 0xC0; | 1202 | reg = pci_quatech_rqopr(port) & 0xC0; |
1205 | if (reg != QPCR_TEST_GET1) | 1203 | if (reg != QPCR_TEST_GET1) |
@@ -1286,6 +1284,7 @@ static int pci_quatech_init(struct pci_dev *dev) | |||
1286 | unsigned long base = pci_resource_start(dev, 0); | 1284 | unsigned long base = pci_resource_start(dev, 0); |
1287 | if (base) { | 1285 | if (base) { |
1288 | u32 tmp; | 1286 | u32 tmp; |
1287 | |||
1289 | outl(inl(base + 0x38) | 0x00002000, base + 0x38); | 1288 | outl(inl(base + 0x38) | 0x00002000, base + 0x38); |
1290 | tmp = inl(base + 0x3c); | 1289 | tmp = inl(base + 0x3c); |
1291 | outl(tmp | 0x01000000, base + 0x3c); | 1290 | outl(tmp | 0x01000000, base + 0x3c); |
@@ -1334,29 +1333,6 @@ static int pci_default_setup(struct serial_private *priv, | |||
1334 | return setup_port(priv, port, bar, offset, board->reg_shift); | 1333 | return setup_port(priv, port, bar, offset, board->reg_shift); |
1335 | } | 1334 | } |
1336 | 1335 | ||
1337 | static int pci_pericom_setup(struct serial_private *priv, | ||
1338 | const struct pciserial_board *board, | ||
1339 | struct uart_8250_port *port, int idx) | ||
1340 | { | ||
1341 | unsigned int bar, offset = board->first_offset, maxnr; | ||
1342 | |||
1343 | bar = FL_GET_BASE(board->flags); | ||
1344 | if (board->flags & FL_BASE_BARS) | ||
1345 | bar += idx; | ||
1346 | else | ||
1347 | offset += idx * board->uart_offset; | ||
1348 | |||
1349 | maxnr = (pci_resource_len(priv->dev, bar) - board->first_offset) >> | ||
1350 | (board->reg_shift + 3); | ||
1351 | |||
1352 | if (board->flags & FL_REGION_SZ_CAP && idx >= maxnr) | ||
1353 | return 1; | ||
1354 | |||
1355 | port->port.uartclk = 14745600; | ||
1356 | |||
1357 | return setup_port(priv, port, bar, offset, board->reg_shift); | ||
1358 | } | ||
1359 | |||
1360 | static int | 1336 | static int |
1361 | ce4100_serial_setup(struct serial_private *priv, | 1337 | ce4100_serial_setup(struct serial_private *priv, |
1362 | const struct pciserial_board *board, | 1338 | const struct pciserial_board *board, |
@@ -1541,10 +1517,9 @@ pci_brcm_trumanage_setup(struct serial_private *priv, | |||
1541 | static int pci_fintek_rs485_config(struct uart_port *port, | 1517 | static int pci_fintek_rs485_config(struct uart_port *port, |
1542 | struct serial_rs485 *rs485) | 1518 | struct serial_rs485 *rs485) |
1543 | { | 1519 | { |
1520 | struct pci_dev *pci_dev = to_pci_dev(port->dev); | ||
1544 | u8 setting; | 1521 | u8 setting; |
1545 | u8 *index = (u8 *) port->private_data; | 1522 | u8 *index = (u8 *) port->private_data; |
1546 | struct pci_dev *pci_dev = container_of(port->dev, struct pci_dev, | ||
1547 | dev); | ||
1548 | 1523 | ||
1549 | pci_read_config_byte(pci_dev, 0x40 + 8 * *index + 7, &setting); | 1524 | pci_read_config_byte(pci_dev, 0x40 + 8 * *index + 7, &setting); |
1550 | 1525 | ||
@@ -1766,7 +1741,7 @@ xr17v35x_has_slave(struct serial_private *priv) | |||
1766 | const int dev_id = priv->dev->device; | 1741 | const int dev_id = priv->dev->device; |
1767 | 1742 | ||
1768 | return ((dev_id == PCI_DEVICE_ID_EXAR_XR17V4358) || | 1743 | return ((dev_id == PCI_DEVICE_ID_EXAR_XR17V4358) || |
1769 | (dev_id == PCI_DEVICE_ID_EXAR_XR17V8358)); | 1744 | (dev_id == PCI_DEVICE_ID_EXAR_XR17V8358)); |
1770 | } | 1745 | } |
1771 | 1746 | ||
1772 | static int | 1747 | static int |
@@ -1866,8 +1841,8 @@ pci_fastcom335_setup(struct serial_private *priv, | |||
1866 | 1841 | ||
1867 | static int | 1842 | static int |
1868 | pci_wch_ch353_setup(struct serial_private *priv, | 1843 | pci_wch_ch353_setup(struct serial_private *priv, |
1869 | const struct pciserial_board *board, | 1844 | const struct pciserial_board *board, |
1870 | struct uart_8250_port *port, int idx) | 1845 | struct uart_8250_port *port, int idx) |
1871 | { | 1846 | { |
1872 | port->port.flags |= UPF_FIXED_TYPE; | 1847 | port->port.flags |= UPF_FIXED_TYPE; |
1873 | port->port.type = PORT_16550A; | 1848 | port->port.type = PORT_16550A; |
@@ -1876,8 +1851,8 @@ pci_wch_ch353_setup(struct serial_private *priv, | |||
1876 | 1851 | ||
1877 | static int | 1852 | static int |
1878 | pci_wch_ch38x_setup(struct serial_private *priv, | 1853 | pci_wch_ch38x_setup(struct serial_private *priv, |
1879 | const struct pciserial_board *board, | 1854 | const struct pciserial_board *board, |
1880 | struct uart_8250_port *port, int idx) | 1855 | struct uart_8250_port *port, int idx) |
1881 | { | 1856 | { |
1882 | port->port.flags |= UPF_FIXED_TYPE; | 1857 | port->port.flags |= UPF_FIXED_TYPE; |
1883 | port->port.type = PORT_16850; | 1858 | port->port.type = PORT_16850; |
@@ -2246,16 +2221,6 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
2246 | .exit = pci_plx9050_exit, | 2221 | .exit = pci_plx9050_exit, |
2247 | }, | 2222 | }, |
2248 | /* | 2223 | /* |
2249 | * Pericom | ||
2250 | */ | ||
2251 | { | ||
2252 | .vendor = PCI_VENDOR_ID_PERICOM, | ||
2253 | .device = PCI_ANY_ID, | ||
2254 | .subvendor = PCI_ANY_ID, | ||
2255 | .subdevice = PCI_ANY_ID, | ||
2256 | .setup = pci_pericom_setup, | ||
2257 | }, | ||
2258 | /* | ||
2259 | * PLX | 2224 | * PLX |
2260 | */ | 2225 | */ |
2261 | { | 2226 | { |
@@ -3733,15 +3698,10 @@ static struct pciserial_board pci_boards[] = { | |||
3733 | .base_baud = 921600, | 3698 | .base_baud = 921600, |
3734 | .reg_shift = 2, | 3699 | .reg_shift = 2, |
3735 | }, | 3700 | }, |
3736 | /* | ||
3737 | * Intel BayTrail HSUART reference clock is 44.2368 MHz at power-on, | ||
3738 | * but is overridden by byt_set_termios. | ||
3739 | */ | ||
3740 | [pbn_byt] = { | 3701 | [pbn_byt] = { |
3741 | .flags = FL_BASE0, | 3702 | .flags = FL_BASE0, |
3742 | .num_ports = 1, | 3703 | .num_ports = 1, |
3743 | .base_baud = 2764800, | 3704 | .base_baud = 2764800, |
3744 | .uart_offset = 0x80, | ||
3745 | .reg_shift = 2, | 3705 | .reg_shift = 2, |
3746 | }, | 3706 | }, |
3747 | [pbn_qrk] = { | 3707 | [pbn_qrk] = { |
@@ -3840,6 +3800,20 @@ static const struct pci_device_id blacklist[] = { | |||
3840 | { PCI_DEVICE(0x1c00, 0x3250), }, /* WCH CH382 2S1P */ | 3800 | { PCI_DEVICE(0x1c00, 0x3250), }, /* WCH CH382 2S1P */ |
3841 | { PCI_DEVICE(0x1c00, 0x3470), }, /* WCH CH384 4S */ | 3801 | { PCI_DEVICE(0x1c00, 0x3470), }, /* WCH CH384 4S */ |
3842 | 3802 | ||
3803 | /* Moxa Smartio MUE boards handled by 8250_moxa */ | ||
3804 | { PCI_VDEVICE(MOXA, 0x1024), }, | ||
3805 | { PCI_VDEVICE(MOXA, 0x1025), }, | ||
3806 | { PCI_VDEVICE(MOXA, 0x1045), }, | ||
3807 | { PCI_VDEVICE(MOXA, 0x1144), }, | ||
3808 | { PCI_VDEVICE(MOXA, 0x1160), }, | ||
3809 | { PCI_VDEVICE(MOXA, 0x1161), }, | ||
3810 | { PCI_VDEVICE(MOXA, 0x1182), }, | ||
3811 | { PCI_VDEVICE(MOXA, 0x1183), }, | ||
3812 | { PCI_VDEVICE(MOXA, 0x1322), }, | ||
3813 | { PCI_VDEVICE(MOXA, 0x1342), }, | ||
3814 | { PCI_VDEVICE(MOXA, 0x1381), }, | ||
3815 | { PCI_VDEVICE(MOXA, 0x1683), }, | ||
3816 | |||
3843 | /* Intel platforms with MID UART */ | 3817 | /* Intel platforms with MID UART */ |
3844 | { PCI_VDEVICE(INTEL, 0x081b), }, | 3818 | { PCI_VDEVICE(INTEL, 0x081b), }, |
3845 | { PCI_VDEVICE(INTEL, 0x081c), }, | 3819 | { PCI_VDEVICE(INTEL, 0x081c), }, |
@@ -4027,12 +4001,6 @@ void pciserial_remove_ports(struct serial_private *priv) | |||
4027 | for (i = 0; i < priv->nr; i++) | 4001 | for (i = 0; i < priv->nr; i++) |
4028 | serial8250_unregister_port(priv->line[i]); | 4002 | serial8250_unregister_port(priv->line[i]); |
4029 | 4003 | ||
4030 | for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) { | ||
4031 | if (priv->remapped_bar[i]) | ||
4032 | iounmap(priv->remapped_bar[i]); | ||
4033 | priv->remapped_bar[i] = NULL; | ||
4034 | } | ||
4035 | |||
4036 | /* | 4004 | /* |
4037 | * Find the exit quirks. | 4005 | * Find the exit quirks. |
4038 | */ | 4006 | */ |
@@ -4104,7 +4072,7 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent) | |||
4104 | 4072 | ||
4105 | board = &pci_boards[ent->driver_data]; | 4073 | board = &pci_boards[ent->driver_data]; |
4106 | 4074 | ||
4107 | rc = pci_enable_device(dev); | 4075 | rc = pcim_enable_device(dev); |
4108 | pci_save_state(dev); | 4076 | pci_save_state(dev); |
4109 | if (rc) | 4077 | if (rc) |
4110 | return rc; | 4078 | return rc; |
@@ -4123,7 +4091,7 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent) | |||
4123 | */ | 4091 | */ |
4124 | rc = serial_pci_guess_board(dev, &tmp); | 4092 | rc = serial_pci_guess_board(dev, &tmp); |
4125 | if (rc) | 4093 | if (rc) |
4126 | goto disable; | 4094 | return rc; |
4127 | } else { | 4095 | } else { |
4128 | /* | 4096 | /* |
4129 | * We matched an explicit entry. If we are able to | 4097 | * We matched an explicit entry. If we are able to |
@@ -4139,16 +4107,11 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent) | |||
4139 | } | 4107 | } |
4140 | 4108 | ||
4141 | priv = pciserial_init_ports(dev, board); | 4109 | priv = pciserial_init_ports(dev, board); |
4142 | if (!IS_ERR(priv)) { | 4110 | if (IS_ERR(priv)) |
4143 | pci_set_drvdata(dev, priv); | 4111 | return PTR_ERR(priv); |
4144 | return 0; | ||
4145 | } | ||
4146 | 4112 | ||
4147 | rc = PTR_ERR(priv); | 4113 | pci_set_drvdata(dev, priv); |
4148 | 4114 | return 0; | |
4149 | disable: | ||
4150 | pci_disable_device(dev); | ||
4151 | return rc; | ||
4152 | } | 4115 | } |
4153 | 4116 | ||
4154 | static void pciserial_remove_one(struct pci_dev *dev) | 4117 | static void pciserial_remove_one(struct pci_dev *dev) |
@@ -4156,8 +4119,6 @@ static void pciserial_remove_one(struct pci_dev *dev) | |||
4156 | struct serial_private *priv = pci_get_drvdata(dev); | 4119 | struct serial_private *priv = pci_get_drvdata(dev); |
4157 | 4120 | ||
4158 | pciserial_remove_ports(priv); | 4121 | pciserial_remove_ports(priv); |
4159 | |||
4160 | pci_disable_device(dev); | ||
4161 | } | 4122 | } |
4162 | 4123 | ||
4163 | #ifdef CONFIG_PM_SLEEP | 4124 | #ifdef CONFIG_PM_SLEEP |
@@ -4538,7 +4499,7 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
4538 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4499 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4539 | pbn_b0_bt_2_921600 }, | 4500 | pbn_b0_bt_2_921600 }, |
4540 | { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI958, | 4501 | { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI958, |
4541 | PCI_ANY_ID , PCI_ANY_ID, 0, 0, | 4502 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4542 | pbn_b2_8_1152000 }, | 4503 | pbn_b2_8_1152000 }, |
4543 | 4504 | ||
4544 | /* | 4505 | /* |
diff --git a/drivers/tty/serial/8250/8250_pnp.c b/drivers/tty/serial/8250/8250_pnp.c index 658b392d1170..34f05ed78b68 100644 --- a/drivers/tty/serial/8250/8250_pnp.c +++ b/drivers/tty/serial/8250/8250_pnp.c | |||
@@ -357,8 +357,8 @@ static const struct pnp_device_id pnp_dev_table[] = { | |||
357 | /* Fujitsu Wacom 1FGT Tablet PC device */ | 357 | /* Fujitsu Wacom 1FGT Tablet PC device */ |
358 | { "FUJ02E9", 0 }, | 358 | { "FUJ02E9", 0 }, |
359 | /* | 359 | /* |
360 | * LG C1 EXPRESS DUAL (C1-PB11A3) touch screen (actually a FUJ02E6 in | 360 | * LG C1 EXPRESS DUAL (C1-PB11A3) touch screen (actually a FUJ02E6 |
361 | * disguise) | 361 | * in disguise). |
362 | */ | 362 | */ |
363 | { "LTS0001", 0 }, | 363 | { "LTS0001", 0 }, |
364 | /* Rockwell's (PORALiNK) 33600 INT PNP */ | 364 | /* Rockwell's (PORALiNK) 33600 INT PNP */ |
@@ -367,12 +367,14 @@ static const struct pnp_device_id pnp_dev_table[] = { | |||
367 | { "PNPCXXX", UNKNOWN_DEV }, | 367 | { "PNPCXXX", UNKNOWN_DEV }, |
368 | /* More unknown PnP modems */ | 368 | /* More unknown PnP modems */ |
369 | { "PNPDXXX", UNKNOWN_DEV }, | 369 | { "PNPDXXX", UNKNOWN_DEV }, |
370 | /* Winbond CIR port, should not be probed. We should keep track | 370 | /* |
371 | of it to prevent the legacy serial driver from probing it */ | 371 | * Winbond CIR port, should not be probed. We should keep track of |
372 | * it to prevent the legacy serial driver from probing it. | ||
373 | */ | ||
372 | { "WEC1022", CIR_PORT }, | 374 | { "WEC1022", CIR_PORT }, |
373 | /* | 375 | /* |
374 | * SMSC IrCC SIR/FIR port, should not be probed by serial driver | 376 | * SMSC IrCC SIR/FIR port, should not be probed by serial driver as |
375 | * as well so its own driver can bind to it. | 377 | * well so its own driver can bind to it. |
376 | */ | 378 | */ |
377 | { "SMCF010", CIR_PORT }, | 379 | { "SMCF010", CIR_PORT }, |
378 | { "", 0 } | 380 | { "", 0 } |
@@ -380,35 +382,35 @@ static const struct pnp_device_id pnp_dev_table[] = { | |||
380 | 382 | ||
381 | MODULE_DEVICE_TABLE(pnp, pnp_dev_table); | 383 | MODULE_DEVICE_TABLE(pnp, pnp_dev_table); |
382 | 384 | ||
383 | static char *modem_names[] = { | 385 | static const char *modem_names[] = { |
384 | "MODEM", "Modem", "modem", "FAX", "Fax", "fax", | 386 | "MODEM", "Modem", "modem", "FAX", "Fax", "fax", |
385 | "56K", "56k", "K56", "33.6", "28.8", "14.4", | 387 | "56K", "56k", "K56", "33.6", "28.8", "14.4", |
386 | "33,600", "28,800", "14,400", "33.600", "28.800", "14.400", | 388 | "33,600", "28,800", "14,400", "33.600", "28.800", "14.400", |
387 | "33600", "28800", "14400", "V.90", "V.34", "V.32", NULL | 389 | "33600", "28800", "14400", "V.90", "V.34", "V.32", NULL |
388 | }; | 390 | }; |
389 | 391 | ||
390 | static int check_name(char *name) | 392 | static bool check_name(const char *name) |
391 | { | 393 | { |
392 | char **tmp; | 394 | const char **tmp; |
393 | 395 | ||
394 | for (tmp = modem_names; *tmp; tmp++) | 396 | for (tmp = modem_names; *tmp; tmp++) |
395 | if (strstr(name, *tmp)) | 397 | if (strstr(name, *tmp)) |
396 | return 1; | 398 | return true; |
397 | 399 | ||
398 | return 0; | 400 | return false; |
399 | } | 401 | } |
400 | 402 | ||
401 | static int check_resources(struct pnp_dev *dev) | 403 | static bool check_resources(struct pnp_dev *dev) |
402 | { | 404 | { |
403 | resource_size_t base[] = {0x2f8, 0x3f8, 0x2e8, 0x3e8}; | 405 | static const resource_size_t base[] = {0x2f8, 0x3f8, 0x2e8, 0x3e8}; |
404 | int i; | 406 | unsigned int i; |
405 | 407 | ||
406 | for (i = 0; i < ARRAY_SIZE(base); i++) { | 408 | for (i = 0; i < ARRAY_SIZE(base); i++) { |
407 | if (pnp_possible_config(dev, IORESOURCE_IO, base[i], 8)) | 409 | if (pnp_possible_config(dev, IORESOURCE_IO, base[i], 8)) |
408 | return 1; | 410 | return true; |
409 | } | 411 | } |
410 | 412 | ||
411 | return 0; | 413 | return false; |
412 | } | 414 | } |
413 | 415 | ||
414 | /* | 416 | /* |
@@ -425,8 +427,8 @@ static int check_resources(struct pnp_dev *dev) | |||
425 | static int serial_pnp_guess_board(struct pnp_dev *dev) | 427 | static int serial_pnp_guess_board(struct pnp_dev *dev) |
426 | { | 428 | { |
427 | if (!(check_name(pnp_dev_name(dev)) || | 429 | if (!(check_name(pnp_dev_name(dev)) || |
428 | (dev->card && check_name(dev->card->name)))) | 430 | (dev->card && check_name(dev->card->name)))) |
429 | return -ENODEV; | 431 | return -ENODEV; |
430 | 432 | ||
431 | if (check_resources(dev)) | 433 | if (check_resources(dev)) |
432 | return 0; | 434 | return 0; |
@@ -462,11 +464,11 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) | |||
462 | } else | 464 | } else |
463 | return -ENODEV; | 465 | return -ENODEV; |
464 | 466 | ||
465 | #ifdef SERIAL_DEBUG_PNP | 467 | dev_dbg(&dev->dev, |
466 | printk(KERN_DEBUG | 468 | "Setup PNP port: port %lx, mem %pa, irq %d, type %d\n", |
467 | "Setup PNP port: port %x, mem 0x%lx, irq %d, type %d\n", | 469 | uart.port.iobase, &uart.port.mapbase, |
468 | uart.port.iobase, uart.port.mapbase, uart.port.irq, uart.port.iotype); | 470 | uart.port.irq, uart.port.iotype); |
469 | #endif | 471 | |
470 | if (flags & CIR_PORT) { | 472 | if (flags & CIR_PORT) { |
471 | uart.port.flags |= UPF_FIXED_PORT | UPF_FIXED_TYPE; | 473 | uart.port.flags |= UPF_FIXED_PORT | UPF_FIXED_TYPE; |
472 | uart.port.type = PORT_8250_CIR; | 474 | uart.port.type = PORT_8250_CIR; |
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 8d262bce97e4..e213da01a3d7 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
38 | #include <linux/uaccess.h> | 38 | #include <linux/uaccess.h> |
39 | #include <linux/pm_runtime.h> | 39 | #include <linux/pm_runtime.h> |
40 | #include <linux/timer.h> | ||
40 | 41 | ||
41 | #include <asm/io.h> | 42 | #include <asm/io.h> |
42 | #include <asm/irq.h> | 43 | #include <asm/irq.h> |
@@ -52,7 +53,7 @@ | |||
52 | #define DEBUG_AUTOCONF(fmt...) do { } while (0) | 53 | #define DEBUG_AUTOCONF(fmt...) do { } while (0) |
53 | #endif | 54 | #endif |
54 | 55 | ||
55 | #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) | 56 | #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) |
56 | 57 | ||
57 | /* | 58 | /* |
58 | * Here we define the default xmit fifo size used for each type of UART. | 59 | * Here we define the default xmit fifo size used for each type of UART. |
@@ -250,9 +251,11 @@ static const struct serial8250_config uart_config[] = { | |||
250 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | 251 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, |
251 | .flags = UART_CAP_FIFO | UART_CAP_AFE, | 252 | .flags = UART_CAP_FIFO | UART_CAP_AFE, |
252 | }, | 253 | }, |
253 | /* tx_loadsz is set to 63-bytes instead of 64-bytes to implement | 254 | /* |
254 | workaround of errata A-008006 which states that tx_loadsz should be | 255 | * tx_loadsz is set to 63-bytes instead of 64-bytes to implement |
255 | configured less than Maximum supported fifo bytes */ | 256 | * workaround of errata A-008006 which states that tx_loadsz should |
257 | * be configured less than Maximum supported fifo bytes. | ||
258 | */ | ||
256 | [PORT_16550A_FSL64] = { | 259 | [PORT_16550A_FSL64] = { |
257 | .name = "16550A_FSL64", | 260 | .name = "16550A_FSL64", |
258 | .fifo_size = 64, | 261 | .fifo_size = 64, |
@@ -522,6 +525,20 @@ static void serial8250_clear_fifos(struct uart_8250_port *p) | |||
522 | } | 525 | } |
523 | } | 526 | } |
524 | 527 | ||
528 | static inline void serial8250_em485_rts_after_send(struct uart_8250_port *p) | ||
529 | { | ||
530 | unsigned char mcr = serial_in(p, UART_MCR); | ||
531 | |||
532 | if (p->port.rs485.flags & SER_RS485_RTS_AFTER_SEND) | ||
533 | mcr |= UART_MCR_RTS; | ||
534 | else | ||
535 | mcr &= ~UART_MCR_RTS; | ||
536 | serial_out(p, UART_MCR, mcr); | ||
537 | } | ||
538 | |||
539 | static void serial8250_em485_handle_start_tx(unsigned long arg); | ||
540 | static void serial8250_em485_handle_stop_tx(unsigned long arg); | ||
541 | |||
525 | void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p) | 542 | void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p) |
526 | { | 543 | { |
527 | serial8250_clear_fifos(p); | 544 | serial8250_clear_fifos(p); |
@@ -546,6 +563,73 @@ void serial8250_rpm_put(struct uart_8250_port *p) | |||
546 | } | 563 | } |
547 | EXPORT_SYMBOL_GPL(serial8250_rpm_put); | 564 | EXPORT_SYMBOL_GPL(serial8250_rpm_put); |
548 | 565 | ||
566 | /** | ||
567 | * serial8250_em485_init() - put uart_8250_port into rs485 emulating | ||
568 | * @p: uart_8250_port port instance | ||
569 | * | ||
570 | * The function is used to start rs485 software emulating on the | ||
571 | * &struct uart_8250_port* @p. Namely, RTS is switched before/after | ||
572 | * transmission. The function is idempotent, so it is safe to call it | ||
573 | * multiple times. | ||
574 | * | ||
575 | * The caller MUST enable interrupt on empty shift register before | ||
576 | * calling serial8250_em485_init(). This interrupt is not a part of | ||
577 | * 8250 standard, but implementation defined. | ||
578 | * | ||
579 | * The function is supposed to be called from .rs485_config callback | ||
580 | * or from any other callback protected with p->port.lock spinlock. | ||
581 | * | ||
582 | * See also serial8250_em485_destroy() | ||
583 | * | ||
584 | * Return 0 - success, -errno - otherwise | ||
585 | */ | ||
586 | int serial8250_em485_init(struct uart_8250_port *p) | ||
587 | { | ||
588 | if (p->em485 != NULL) | ||
589 | return 0; | ||
590 | |||
591 | p->em485 = kmalloc(sizeof(struct uart_8250_em485), GFP_ATOMIC); | ||
592 | if (p->em485 == NULL) | ||
593 | return -ENOMEM; | ||
594 | |||
595 | setup_timer(&p->em485->stop_tx_timer, | ||
596 | serial8250_em485_handle_stop_tx, (unsigned long)p); | ||
597 | setup_timer(&p->em485->start_tx_timer, | ||
598 | serial8250_em485_handle_start_tx, (unsigned long)p); | ||
599 | p->em485->active_timer = NULL; | ||
600 | |||
601 | serial8250_em485_rts_after_send(p); | ||
602 | |||
603 | return 0; | ||
604 | } | ||
605 | EXPORT_SYMBOL_GPL(serial8250_em485_init); | ||
606 | |||
607 | /** | ||
608 | * serial8250_em485_destroy() - put uart_8250_port into normal state | ||
609 | * @p: uart_8250_port port instance | ||
610 | * | ||
611 | * The function is used to stop rs485 software emulating on the | ||
612 | * &struct uart_8250_port* @p. The function is idempotent, so it is safe to | ||
613 | * call it multiple times. | ||
614 | * | ||
615 | * The function is supposed to be called from .rs485_config callback | ||
616 | * or from any other callback protected with p->port.lock spinlock. | ||
617 | * | ||
618 | * See also serial8250_em485_init() | ||
619 | */ | ||
620 | void serial8250_em485_destroy(struct uart_8250_port *p) | ||
621 | { | ||
622 | if (p->em485 == NULL) | ||
623 | return; | ||
624 | |||
625 | del_timer(&p->em485->start_tx_timer); | ||
626 | del_timer(&p->em485->stop_tx_timer); | ||
627 | |||
628 | kfree(p->em485); | ||
629 | p->em485 = NULL; | ||
630 | } | ||
631 | EXPORT_SYMBOL_GPL(serial8250_em485_destroy); | ||
632 | |||
549 | /* | 633 | /* |
550 | * These two wrappers ensure that enable_runtime_pm_tx() can be called more than | 634 | * These two wrappers ensure that enable_runtime_pm_tx() can be called more than |
551 | * once and disable_runtime_pm_tx() will still disable RPM because the fifo is | 635 | * once and disable_runtime_pm_tx() will still disable RPM because the fifo is |
@@ -731,22 +815,16 @@ static int size_fifo(struct uart_8250_port *up) | |||
731 | */ | 815 | */ |
732 | static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p) | 816 | static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p) |
733 | { | 817 | { |
734 | unsigned char old_dll, old_dlm, old_lcr; | 818 | unsigned char old_lcr; |
735 | unsigned int id; | 819 | unsigned int id, old_dl; |
736 | 820 | ||
737 | old_lcr = serial_in(p, UART_LCR); | 821 | old_lcr = serial_in(p, UART_LCR); |
738 | serial_out(p, UART_LCR, UART_LCR_CONF_MODE_A); | 822 | serial_out(p, UART_LCR, UART_LCR_CONF_MODE_A); |
823 | old_dl = serial_dl_read(p); | ||
824 | serial_dl_write(p, 0); | ||
825 | id = serial_dl_read(p); | ||
826 | serial_dl_write(p, old_dl); | ||
739 | 827 | ||
740 | old_dll = serial_in(p, UART_DLL); | ||
741 | old_dlm = serial_in(p, UART_DLM); | ||
742 | |||
743 | serial_out(p, UART_DLL, 0); | ||
744 | serial_out(p, UART_DLM, 0); | ||
745 | |||
746 | id = serial_in(p, UART_DLL) | serial_in(p, UART_DLM) << 8; | ||
747 | |||
748 | serial_out(p, UART_DLL, old_dll); | ||
749 | serial_out(p, UART_DLM, old_dlm); | ||
750 | serial_out(p, UART_LCR, old_lcr); | 828 | serial_out(p, UART_LCR, old_lcr); |
751 | 829 | ||
752 | return id; | 830 | return id; |
@@ -1238,8 +1316,7 @@ static void autoconfig(struct uart_8250_port *up) | |||
1238 | out_lock: | 1316 | out_lock: |
1239 | spin_unlock_irqrestore(&port->lock, flags); | 1317 | spin_unlock_irqrestore(&port->lock, flags); |
1240 | if (up->capabilities != old_capabilities) { | 1318 | if (up->capabilities != old_capabilities) { |
1241 | printk(KERN_WARNING | 1319 | pr_warn("ttyS%d: detected caps %08x should be %08x\n", |
1242 | "ttyS%d: detected caps %08x should be %08x\n", | ||
1243 | serial_index(port), old_capabilities, | 1320 | serial_index(port), old_capabilities, |
1244 | up->capabilities); | 1321 | up->capabilities); |
1245 | } | 1322 | } |
@@ -1304,7 +1381,69 @@ static void autoconfig_irq(struct uart_8250_port *up) | |||
1304 | port->irq = (irq > 0) ? irq : 0; | 1381 | port->irq = (irq > 0) ? irq : 0; |
1305 | } | 1382 | } |
1306 | 1383 | ||
1307 | static inline void __stop_tx(struct uart_8250_port *p) | 1384 | static void serial8250_stop_rx(struct uart_port *port) |
1385 | { | ||
1386 | struct uart_8250_port *up = up_to_u8250p(port); | ||
1387 | |||
1388 | serial8250_rpm_get(up); | ||
1389 | |||
1390 | up->ier &= ~(UART_IER_RLSI | UART_IER_RDI); | ||
1391 | up->port.read_status_mask &= ~UART_LSR_DR; | ||
1392 | serial_port_out(port, UART_IER, up->ier); | ||
1393 | |||
1394 | serial8250_rpm_put(up); | ||
1395 | } | ||
1396 | |||
1397 | static void __do_stop_tx_rs485(struct uart_8250_port *p) | ||
1398 | { | ||
1399 | if (!p->em485) | ||
1400 | return; | ||
1401 | |||
1402 | serial8250_em485_rts_after_send(p); | ||
1403 | /* | ||
1404 | * Empty the RX FIFO, we are not interested in anything | ||
1405 | * received during the half-duplex transmission. | ||
1406 | */ | ||
1407 | if (!(p->port.rs485.flags & SER_RS485_RX_DURING_TX)) | ||
1408 | serial8250_clear_fifos(p); | ||
1409 | } | ||
1410 | |||
1411 | static void serial8250_em485_handle_stop_tx(unsigned long arg) | ||
1412 | { | ||
1413 | struct uart_8250_port *p = (struct uart_8250_port *)arg; | ||
1414 | struct uart_8250_em485 *em485 = p->em485; | ||
1415 | unsigned long flags; | ||
1416 | |||
1417 | spin_lock_irqsave(&p->port.lock, flags); | ||
1418 | if (em485 && | ||
1419 | em485->active_timer == &em485->stop_tx_timer) { | ||
1420 | __do_stop_tx_rs485(p); | ||
1421 | em485->active_timer = NULL; | ||
1422 | } | ||
1423 | spin_unlock_irqrestore(&p->port.lock, flags); | ||
1424 | } | ||
1425 | |||
1426 | static void __stop_tx_rs485(struct uart_8250_port *p) | ||
1427 | { | ||
1428 | struct uart_8250_em485 *em485 = p->em485; | ||
1429 | |||
1430 | if (!em485) | ||
1431 | return; | ||
1432 | |||
1433 | /* | ||
1434 | * __do_stop_tx_rs485 is going to set RTS according to config | ||
1435 | * AND flush RX FIFO if required. | ||
1436 | */ | ||
1437 | if (p->port.rs485.delay_rts_after_send > 0) { | ||
1438 | em485->active_timer = &em485->stop_tx_timer; | ||
1439 | mod_timer(&em485->stop_tx_timer, jiffies + | ||
1440 | p->port.rs485.delay_rts_after_send * HZ / 1000); | ||
1441 | } else { | ||
1442 | __do_stop_tx_rs485(p); | ||
1443 | } | ||
1444 | } | ||
1445 | |||
1446 | static inline void __do_stop_tx(struct uart_8250_port *p) | ||
1308 | { | 1447 | { |
1309 | if (p->ier & UART_IER_THRI) { | 1448 | if (p->ier & UART_IER_THRI) { |
1310 | p->ier &= ~UART_IER_THRI; | 1449 | p->ier &= ~UART_IER_THRI; |
@@ -1313,6 +1452,28 @@ static inline void __stop_tx(struct uart_8250_port *p) | |||
1313 | } | 1452 | } |
1314 | } | 1453 | } |
1315 | 1454 | ||
1455 | static inline void __stop_tx(struct uart_8250_port *p) | ||
1456 | { | ||
1457 | struct uart_8250_em485 *em485 = p->em485; | ||
1458 | |||
1459 | if (em485) { | ||
1460 | unsigned char lsr = serial_in(p, UART_LSR); | ||
1461 | /* | ||
1462 | * To provide required timeing and allow FIFO transfer, | ||
1463 | * __stop_tx_rs485 must be called only when both FIFO and | ||
1464 | * shift register are empty. It is for device driver to enable | ||
1465 | * interrupt on TEMT. | ||
1466 | */ | ||
1467 | if ((lsr & BOTH_EMPTY) != BOTH_EMPTY) | ||
1468 | return; | ||
1469 | |||
1470 | del_timer(&em485->start_tx_timer); | ||
1471 | em485->active_timer = NULL; | ||
1472 | } | ||
1473 | __do_stop_tx(p); | ||
1474 | __stop_tx_rs485(p); | ||
1475 | } | ||
1476 | |||
1316 | static void serial8250_stop_tx(struct uart_port *port) | 1477 | static void serial8250_stop_tx(struct uart_port *port) |
1317 | { | 1478 | { |
1318 | struct uart_8250_port *up = up_to_u8250p(port); | 1479 | struct uart_8250_port *up = up_to_u8250p(port); |
@@ -1330,12 +1491,10 @@ static void serial8250_stop_tx(struct uart_port *port) | |||
1330 | serial8250_rpm_put(up); | 1491 | serial8250_rpm_put(up); |
1331 | } | 1492 | } |
1332 | 1493 | ||
1333 | static void serial8250_start_tx(struct uart_port *port) | 1494 | static inline void __start_tx(struct uart_port *port) |
1334 | { | 1495 | { |
1335 | struct uart_8250_port *up = up_to_u8250p(port); | 1496 | struct uart_8250_port *up = up_to_u8250p(port); |
1336 | 1497 | ||
1337 | serial8250_rpm_get_tx(up); | ||
1338 | |||
1339 | if (up->dma && !up->dma->tx_dma(up)) | 1498 | if (up->dma && !up->dma->tx_dma(up)) |
1340 | return; | 1499 | return; |
1341 | 1500 | ||
@@ -1345,6 +1504,7 @@ static void serial8250_start_tx(struct uart_port *port) | |||
1345 | 1504 | ||
1346 | if (up->bugs & UART_BUG_TXEN) { | 1505 | if (up->bugs & UART_BUG_TXEN) { |
1347 | unsigned char lsr; | 1506 | unsigned char lsr; |
1507 | |||
1348 | lsr = serial_in(up, UART_LSR); | 1508 | lsr = serial_in(up, UART_LSR); |
1349 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; | 1509 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; |
1350 | if (lsr & UART_LSR_THRE) | 1510 | if (lsr & UART_LSR_THRE) |
@@ -1361,33 +1521,83 @@ static void serial8250_start_tx(struct uart_port *port) | |||
1361 | } | 1521 | } |
1362 | } | 1522 | } |
1363 | 1523 | ||
1364 | static void serial8250_throttle(struct uart_port *port) | 1524 | static inline void start_tx_rs485(struct uart_port *port) |
1365 | { | 1525 | { |
1366 | port->throttle(port); | 1526 | struct uart_8250_port *up = up_to_u8250p(port); |
1527 | struct uart_8250_em485 *em485 = up->em485; | ||
1528 | unsigned char mcr; | ||
1529 | |||
1530 | if (!(up->port.rs485.flags & SER_RS485_RX_DURING_TX)) | ||
1531 | serial8250_stop_rx(&up->port); | ||
1532 | |||
1533 | del_timer(&em485->stop_tx_timer); | ||
1534 | em485->active_timer = NULL; | ||
1535 | |||
1536 | mcr = serial_in(up, UART_MCR); | ||
1537 | if (!!(up->port.rs485.flags & SER_RS485_RTS_ON_SEND) != | ||
1538 | !!(mcr & UART_MCR_RTS)) { | ||
1539 | if (up->port.rs485.flags & SER_RS485_RTS_ON_SEND) | ||
1540 | mcr |= UART_MCR_RTS; | ||
1541 | else | ||
1542 | mcr &= ~UART_MCR_RTS; | ||
1543 | serial_out(up, UART_MCR, mcr); | ||
1544 | |||
1545 | if (up->port.rs485.delay_rts_before_send > 0) { | ||
1546 | em485->active_timer = &em485->start_tx_timer; | ||
1547 | mod_timer(&em485->start_tx_timer, jiffies + | ||
1548 | up->port.rs485.delay_rts_before_send * HZ / 1000); | ||
1549 | return; | ||
1550 | } | ||
1551 | } | ||
1552 | |||
1553 | __start_tx(port); | ||
1367 | } | 1554 | } |
1368 | 1555 | ||
1369 | static void serial8250_unthrottle(struct uart_port *port) | 1556 | static void serial8250_em485_handle_start_tx(unsigned long arg) |
1370 | { | 1557 | { |
1371 | port->unthrottle(port); | 1558 | struct uart_8250_port *p = (struct uart_8250_port *)arg; |
1559 | struct uart_8250_em485 *em485 = p->em485; | ||
1560 | unsigned long flags; | ||
1561 | |||
1562 | spin_lock_irqsave(&p->port.lock, flags); | ||
1563 | if (em485 && | ||
1564 | em485->active_timer == &em485->start_tx_timer) { | ||
1565 | __start_tx(&p->port); | ||
1566 | em485->active_timer = NULL; | ||
1567 | } | ||
1568 | spin_unlock_irqrestore(&p->port.lock, flags); | ||
1372 | } | 1569 | } |
1373 | 1570 | ||
1374 | static void serial8250_stop_rx(struct uart_port *port) | 1571 | static void serial8250_start_tx(struct uart_port *port) |
1375 | { | 1572 | { |
1376 | struct uart_8250_port *up = up_to_u8250p(port); | 1573 | struct uart_8250_port *up = up_to_u8250p(port); |
1574 | struct uart_8250_em485 *em485 = up->em485; | ||
1377 | 1575 | ||
1378 | serial8250_rpm_get(up); | 1576 | serial8250_rpm_get_tx(up); |
1379 | 1577 | ||
1380 | up->ier &= ~(UART_IER_RLSI | UART_IER_RDI); | 1578 | if (em485 && |
1381 | up->port.read_status_mask &= ~UART_LSR_DR; | 1579 | em485->active_timer == &em485->start_tx_timer) |
1382 | serial_port_out(port, UART_IER, up->ier); | 1580 | return; |
1383 | 1581 | ||
1384 | serial8250_rpm_put(up); | 1582 | if (em485) |
1583 | start_tx_rs485(port); | ||
1584 | else | ||
1585 | __start_tx(port); | ||
1586 | } | ||
1587 | |||
1588 | static void serial8250_throttle(struct uart_port *port) | ||
1589 | { | ||
1590 | port->throttle(port); | ||
1591 | } | ||
1592 | |||
1593 | static void serial8250_unthrottle(struct uart_port *port) | ||
1594 | { | ||
1595 | port->unthrottle(port); | ||
1385 | } | 1596 | } |
1386 | 1597 | ||
1387 | static void serial8250_disable_ms(struct uart_port *port) | 1598 | static void serial8250_disable_ms(struct uart_port *port) |
1388 | { | 1599 | { |
1389 | struct uart_8250_port *up = | 1600 | struct uart_8250_port *up = up_to_u8250p(port); |
1390 | container_of(port, struct uart_8250_port, port); | ||
1391 | 1601 | ||
1392 | /* no MSR capabilities */ | 1602 | /* no MSR capabilities */ |
1393 | if (up->bugs & UART_BUG_NOMSR) | 1603 | if (up->bugs & UART_BUG_NOMSR) |
@@ -1412,81 +1622,85 @@ static void serial8250_enable_ms(struct uart_port *port) | |||
1412 | serial8250_rpm_put(up); | 1622 | serial8250_rpm_put(up); |
1413 | } | 1623 | } |
1414 | 1624 | ||
1625 | static void serial8250_read_char(struct uart_8250_port *up, unsigned char lsr) | ||
1626 | { | ||
1627 | struct uart_port *port = &up->port; | ||
1628 | unsigned char ch; | ||
1629 | char flag = TTY_NORMAL; | ||
1630 | |||
1631 | if (likely(lsr & UART_LSR_DR)) | ||
1632 | ch = serial_in(up, UART_RX); | ||
1633 | else | ||
1634 | /* | ||
1635 | * Intel 82571 has a Serial Over Lan device that will | ||
1636 | * set UART_LSR_BI without setting UART_LSR_DR when | ||
1637 | * it receives a break. To avoid reading from the | ||
1638 | * receive buffer without UART_LSR_DR bit set, we | ||
1639 | * just force the read character to be 0 | ||
1640 | */ | ||
1641 | ch = 0; | ||
1642 | |||
1643 | port->icount.rx++; | ||
1644 | |||
1645 | lsr |= up->lsr_saved_flags; | ||
1646 | up->lsr_saved_flags = 0; | ||
1647 | |||
1648 | if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) { | ||
1649 | if (lsr & UART_LSR_BI) { | ||
1650 | lsr &= ~(UART_LSR_FE | UART_LSR_PE); | ||
1651 | port->icount.brk++; | ||
1652 | /* | ||
1653 | * We do the SysRQ and SAK checking | ||
1654 | * here because otherwise the break | ||
1655 | * may get masked by ignore_status_mask | ||
1656 | * or read_status_mask. | ||
1657 | */ | ||
1658 | if (uart_handle_break(port)) | ||
1659 | return; | ||
1660 | } else if (lsr & UART_LSR_PE) | ||
1661 | port->icount.parity++; | ||
1662 | else if (lsr & UART_LSR_FE) | ||
1663 | port->icount.frame++; | ||
1664 | if (lsr & UART_LSR_OE) | ||
1665 | port->icount.overrun++; | ||
1666 | |||
1667 | /* | ||
1668 | * Mask off conditions which should be ignored. | ||
1669 | */ | ||
1670 | lsr &= port->read_status_mask; | ||
1671 | |||
1672 | if (lsr & UART_LSR_BI) { | ||
1673 | DEBUG_INTR("handling break...."); | ||
1674 | flag = TTY_BREAK; | ||
1675 | } else if (lsr & UART_LSR_PE) | ||
1676 | flag = TTY_PARITY; | ||
1677 | else if (lsr & UART_LSR_FE) | ||
1678 | flag = TTY_FRAME; | ||
1679 | } | ||
1680 | if (uart_handle_sysrq_char(port, ch)) | ||
1681 | return; | ||
1682 | |||
1683 | uart_insert_char(port, lsr, UART_LSR_OE, ch, flag); | ||
1684 | } | ||
1685 | |||
1415 | /* | 1686 | /* |
1416 | * serial8250_rx_chars: processes according to the passed in LSR | 1687 | * serial8250_rx_chars: processes according to the passed in LSR |
1417 | * value, and returns the remaining LSR bits not handled | 1688 | * value, and returns the remaining LSR bits not handled |
1418 | * by this Rx routine. | 1689 | * by this Rx routine. |
1419 | */ | 1690 | */ |
1420 | unsigned char | 1691 | unsigned char serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) |
1421 | serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) | ||
1422 | { | 1692 | { |
1423 | struct uart_port *port = &up->port; | 1693 | struct uart_port *port = &up->port; |
1424 | unsigned char ch; | ||
1425 | int max_count = 256; | 1694 | int max_count = 256; |
1426 | char flag; | ||
1427 | 1695 | ||
1428 | do { | 1696 | do { |
1429 | if (likely(lsr & UART_LSR_DR)) | 1697 | serial8250_read_char(up, lsr); |
1430 | ch = serial_in(up, UART_RX); | 1698 | if (--max_count == 0) |
1431 | else | 1699 | break; |
1432 | /* | ||
1433 | * Intel 82571 has a Serial Over Lan device that will | ||
1434 | * set UART_LSR_BI without setting UART_LSR_DR when | ||
1435 | * it receives a break. To avoid reading from the | ||
1436 | * receive buffer without UART_LSR_DR bit set, we | ||
1437 | * just force the read character to be 0 | ||
1438 | */ | ||
1439 | ch = 0; | ||
1440 | |||
1441 | flag = TTY_NORMAL; | ||
1442 | port->icount.rx++; | ||
1443 | |||
1444 | lsr |= up->lsr_saved_flags; | ||
1445 | up->lsr_saved_flags = 0; | ||
1446 | |||
1447 | if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) { | ||
1448 | if (lsr & UART_LSR_BI) { | ||
1449 | lsr &= ~(UART_LSR_FE | UART_LSR_PE); | ||
1450 | port->icount.brk++; | ||
1451 | /* | ||
1452 | * We do the SysRQ and SAK checking | ||
1453 | * here because otherwise the break | ||
1454 | * may get masked by ignore_status_mask | ||
1455 | * or read_status_mask. | ||
1456 | */ | ||
1457 | if (uart_handle_break(port)) | ||
1458 | goto ignore_char; | ||
1459 | } else if (lsr & UART_LSR_PE) | ||
1460 | port->icount.parity++; | ||
1461 | else if (lsr & UART_LSR_FE) | ||
1462 | port->icount.frame++; | ||
1463 | if (lsr & UART_LSR_OE) | ||
1464 | port->icount.overrun++; | ||
1465 | |||
1466 | /* | ||
1467 | * Mask off conditions which should be ignored. | ||
1468 | */ | ||
1469 | lsr &= port->read_status_mask; | ||
1470 | |||
1471 | if (lsr & UART_LSR_BI) { | ||
1472 | DEBUG_INTR("handling break...."); | ||
1473 | flag = TTY_BREAK; | ||
1474 | } else if (lsr & UART_LSR_PE) | ||
1475 | flag = TTY_PARITY; | ||
1476 | else if (lsr & UART_LSR_FE) | ||
1477 | flag = TTY_FRAME; | ||
1478 | } | ||
1479 | if (uart_handle_sysrq_char(port, ch)) | ||
1480 | goto ignore_char; | ||
1481 | |||
1482 | uart_insert_char(port, lsr, UART_LSR_OE, ch, flag); | ||
1483 | |||
1484 | ignore_char: | ||
1485 | lsr = serial_in(up, UART_LSR); | 1700 | lsr = serial_in(up, UART_LSR); |
1486 | } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (--max_count > 0)); | 1701 | } while (lsr & (UART_LSR_DR | UART_LSR_BI)); |
1487 | spin_unlock(&port->lock); | 1702 | |
1488 | tty_flip_buffer_push(&port->state->port); | 1703 | tty_flip_buffer_push(&port->state->port); |
1489 | spin_lock(&port->lock); | ||
1490 | return lsr; | 1704 | return lsr; |
1491 | } | 1705 | } |
1492 | EXPORT_SYMBOL_GPL(serial8250_rx_chars); | 1706 | EXPORT_SYMBOL_GPL(serial8250_rx_chars); |
@@ -1519,11 +1733,9 @@ void serial8250_tx_chars(struct uart_8250_port *up) | |||
1519 | port->icount.tx++; | 1733 | port->icount.tx++; |
1520 | if (uart_circ_empty(xmit)) | 1734 | if (uart_circ_empty(xmit)) |
1521 | break; | 1735 | break; |
1522 | if (up->capabilities & UART_CAP_HFIFO) { | 1736 | if ((up->capabilities & UART_CAP_HFIFO) && |
1523 | if ((serial_port_in(port, UART_LSR) & BOTH_EMPTY) != | 1737 | (serial_in(up, UART_LSR) & BOTH_EMPTY) != BOTH_EMPTY) |
1524 | BOTH_EMPTY) | 1738 | break; |
1525 | break; | ||
1526 | } | ||
1527 | } while (--count > 0); | 1739 | } while (--count > 0); |
1528 | 1740 | ||
1529 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 1741 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
@@ -1752,6 +1964,7 @@ static void wait_for_xmitr(struct uart_8250_port *up, int bits) | |||
1752 | /* Wait up to 1s for flow control if necessary */ | 1964 | /* Wait up to 1s for flow control if necessary */ |
1753 | if (up->port.flags & UPF_CONS_FLOW) { | 1965 | if (up->port.flags & UPF_CONS_FLOW) { |
1754 | unsigned int tmout; | 1966 | unsigned int tmout; |
1967 | |||
1755 | for (tmout = 1000000; tmout; tmout--) { | 1968 | for (tmout = 1000000; tmout; tmout--) { |
1756 | unsigned int msr = serial_in(up, UART_MSR); | 1969 | unsigned int msr = serial_in(up, UART_MSR); |
1757 | up->msr_saved_flags |= msr & MSR_SAVE_FLAGS; | 1970 | up->msr_saved_flags |= msr & MSR_SAVE_FLAGS; |
@@ -1985,23 +2198,23 @@ int serial8250_do_startup(struct uart_port *port) | |||
1985 | 2198 | ||
1986 | serial8250_set_mctrl(port, port->mctrl); | 2199 | serial8250_set_mctrl(port, port->mctrl); |
1987 | 2200 | ||
1988 | /* Serial over Lan (SoL) hack: | 2201 | /* |
1989 | Intel 8257x Gigabit ethernet chips have a | 2202 | * Serial over Lan (SoL) hack: |
1990 | 16550 emulation, to be used for Serial Over Lan. | 2203 | * Intel 8257x Gigabit ethernet chips have a 16550 emulation, to be |
1991 | Those chips take a longer time than a normal | 2204 | * used for Serial Over Lan. Those chips take a longer time than a |
1992 | serial device to signalize that a transmission | 2205 | * normal serial device to signalize that a transmission data was |
1993 | data was queued. Due to that, the above test generally | 2206 | * queued. Due to that, the above test generally fails. One solution |
1994 | fails. One solution would be to delay the reading of | 2207 | * would be to delay the reading of iir. However, this is not |
1995 | iir. However, this is not reliable, since the timeout | 2208 | * reliable, since the timeout is variable. So, let's just don't |
1996 | is variable. So, let's just don't test if we receive | 2209 | * test if we receive TX irq. This way, we'll never enable |
1997 | TX irq. This way, we'll never enable UART_BUG_TXEN. | 2210 | * UART_BUG_TXEN. |
1998 | */ | 2211 | */ |
1999 | if (up->port.flags & UPF_NO_TXEN_TEST) | 2212 | if (up->port.flags & UPF_NO_TXEN_TEST) |
2000 | goto dont_test_tx_en; | 2213 | goto dont_test_tx_en; |
2001 | 2214 | ||
2002 | /* | 2215 | /* |
2003 | * Do a quick test to see if we receive an | 2216 | * Do a quick test to see if we receive an interrupt when we enable |
2004 | * interrupt when we enable the TX irq. | 2217 | * the TX irq. |
2005 | */ | 2218 | */ |
2006 | serial_port_out(port, UART_IER, UART_IER_THRI); | 2219 | serial_port_out(port, UART_IER, UART_IER_THRI); |
2007 | lsr = serial_port_in(port, UART_LSR); | 2220 | lsr = serial_port_in(port, UART_LSR); |
@@ -2084,8 +2297,12 @@ void serial8250_do_shutdown(struct uart_port *port) | |||
2084 | /* | 2297 | /* |
2085 | * Disable interrupts from this port | 2298 | * Disable interrupts from this port |
2086 | */ | 2299 | */ |
2300 | spin_lock_irqsave(&port->lock, flags); | ||
2087 | up->ier = 0; | 2301 | up->ier = 0; |
2088 | serial_port_out(port, UART_IER, 0); | 2302 | serial_port_out(port, UART_IER, 0); |
2303 | spin_unlock_irqrestore(&port->lock, flags); | ||
2304 | |||
2305 | synchronize_irq(port->irq); | ||
2089 | 2306 | ||
2090 | if (up->dma) | 2307 | if (up->dma) |
2091 | serial8250_release_dma(up); | 2308 | serial8250_release_dma(up); |
@@ -2251,9 +2468,9 @@ static void serial8250_set_divisor(struct uart_port *port, unsigned int baud, | |||
2251 | serial_port_out(port, 0x2, quot_frac); | 2468 | serial_port_out(port, 0x2, quot_frac); |
2252 | } | 2469 | } |
2253 | 2470 | ||
2254 | static unsigned int | 2471 | static unsigned int serial8250_get_baud_rate(struct uart_port *port, |
2255 | serial8250_get_baud_rate(struct uart_port *port, struct ktermios *termios, | 2472 | struct ktermios *termios, |
2256 | struct ktermios *old) | 2473 | struct ktermios *old) |
2257 | { | 2474 | { |
2258 | unsigned int tolerance = port->uartclk / 100; | 2475 | unsigned int tolerance = port->uartclk / 100; |
2259 | 2476 | ||
@@ -2270,7 +2487,7 @@ serial8250_get_baud_rate(struct uart_port *port, struct ktermios *termios, | |||
2270 | 2487 | ||
2271 | void | 2488 | void |
2272 | serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | 2489 | serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, |
2273 | struct ktermios *old) | 2490 | struct ktermios *old) |
2274 | { | 2491 | { |
2275 | struct uart_8250_port *up = up_to_u8250p(port); | 2492 | struct uart_8250_port *up = up_to_u8250p(port); |
2276 | unsigned char cval; | 2493 | unsigned char cval; |
@@ -2583,8 +2800,7 @@ static int do_get_rxtrig(struct tty_port *port) | |||
2583 | { | 2800 | { |
2584 | struct uart_state *state = container_of(port, struct uart_state, port); | 2801 | struct uart_state *state = container_of(port, struct uart_state, port); |
2585 | struct uart_port *uport = state->uart_port; | 2802 | struct uart_port *uport = state->uart_port; |
2586 | struct uart_8250_port *up = | 2803 | struct uart_8250_port *up = up_to_u8250p(uport); |
2587 | container_of(uport, struct uart_8250_port, port); | ||
2588 | 2804 | ||
2589 | if (!(up->capabilities & UART_CAP_FIFO) || uport->fifosize <= 1) | 2805 | if (!(up->capabilities & UART_CAP_FIFO) || uport->fifosize <= 1) |
2590 | return -EINVAL; | 2806 | return -EINVAL; |
@@ -2620,8 +2836,7 @@ static int do_set_rxtrig(struct tty_port *port, unsigned char bytes) | |||
2620 | { | 2836 | { |
2621 | struct uart_state *state = container_of(port, struct uart_state, port); | 2837 | struct uart_state *state = container_of(port, struct uart_state, port); |
2622 | struct uart_port *uport = state->uart_port; | 2838 | struct uart_port *uport = state->uart_port; |
2623 | struct uart_8250_port *up = | 2839 | struct uart_8250_port *up = up_to_u8250p(uport); |
2624 | container_of(uport, struct uart_8250_port, port); | ||
2625 | int rxtrig; | 2840 | int rxtrig; |
2626 | 2841 | ||
2627 | if (!(up->capabilities & UART_CAP_FIFO) || uport->fifosize <= 1 || | 2842 | if (!(up->capabilities & UART_CAP_FIFO) || uport->fifosize <= 1 || |
@@ -2745,8 +2960,7 @@ serial8250_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
2745 | return 0; | 2960 | return 0; |
2746 | } | 2961 | } |
2747 | 2962 | ||
2748 | static const char * | 2963 | static const char *serial8250_type(struct uart_port *port) |
2749 | serial8250_type(struct uart_port *port) | ||
2750 | { | 2964 | { |
2751 | int type = port->type; | 2965 | int type = port->type; |
2752 | 2966 | ||
diff --git a/drivers/tty/serial/8250/8250_uniphier.c b/drivers/tty/serial/8250/8250_uniphier.c index bab6b3ae2540..1b7bd26555b7 100644 --- a/drivers/tty/serial/8250/8250_uniphier.c +++ b/drivers/tty/serial/8250/8250_uniphier.c | |||
@@ -35,7 +35,7 @@ struct uniphier8250_priv { | |||
35 | spinlock_t atomic_write_lock; | 35 | spinlock_t atomic_write_lock; |
36 | }; | 36 | }; |
37 | 37 | ||
38 | #ifdef CONFIG_SERIAL_8250_CONSOLE | 38 | #if defined(CONFIG_SERIAL_8250_CONSOLE) && !defined(MODULE) |
39 | static int __init uniphier_early_console_setup(struct earlycon_device *device, | 39 | static int __init uniphier_early_console_setup(struct earlycon_device *device, |
40 | const char *options) | 40 | const char *options) |
41 | { | 41 | { |
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index b03cb5175113..64742a086ae3 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig | |||
@@ -262,7 +262,12 @@ config SERIAL_8250_RSA | |||
262 | bool "Support RSA serial ports" | 262 | bool "Support RSA serial ports" |
263 | depends on SERIAL_8250_EXTENDED | 263 | depends on SERIAL_8250_EXTENDED |
264 | help | 264 | help |
265 | ::: To be written ::: | 265 | Say Y here if you have a IODATA RSA-DV II/S ISA card and |
266 | would like to use its >115kbps speeds. | ||
267 | You will need to provide module parameter "probe_rsa", or boot-time | ||
268 | parameter 8250.probe_rsa with I/O addresses of this card then. | ||
269 | |||
270 | If you don't have such card, or if unsure, say N. | ||
266 | 271 | ||
267 | config SERIAL_8250_ACORN | 272 | config SERIAL_8250_ACORN |
268 | tristate "Acorn expansion card serial port support" | 273 | tristate "Acorn expansion card serial port support" |
@@ -272,6 +277,30 @@ config SERIAL_8250_ACORN | |||
272 | system, say Y to this option. The driver can handle 1, 2, or 3 port | 277 | system, say Y to this option. The driver can handle 1, 2, or 3 port |
273 | cards. If unsure, say N. | 278 | cards. If unsure, say N. |
274 | 279 | ||
280 | config SERIAL_8250_BCM2835AUX | ||
281 | tristate "BCM2835 auxiliar mini UART support" | ||
282 | depends on ARCH_BCM2835 || COMPILE_TEST | ||
283 | depends on SERIAL_8250 && SERIAL_8250_SHARE_IRQ | ||
284 | help | ||
285 | Support for the BCM2835 auxiliar mini UART. | ||
286 | |||
287 | Features and limitations of the UART are | ||
288 | Registers are similar to 16650 registers, | ||
289 | set bits in the control registers that are unsupported | ||
290 | are ignored and read back as 0 | ||
291 | 7/8 bit operation with 1 start and 1 stop bit | ||
292 | 8 symbols deep fifo for rx and tx | ||
293 | SW controlled RTS and SW readable CTS | ||
294 | Clock rate derived from system clock | ||
295 | Uses 8 times oversampling (compared to 16 times for 16650) | ||
296 | Missing break detection (but break generation) | ||
297 | Missing framing error detection | ||
298 | Missing parity bit | ||
299 | Missing receive time-out interrupt | ||
300 | Missing DCD, DSR, DTR and RI signals | ||
301 | |||
302 | If unsure, say N. | ||
303 | |||
275 | config SERIAL_8250_FSL | 304 | config SERIAL_8250_FSL |
276 | bool | 305 | bool |
277 | depends on SERIAL_8250_CONSOLE | 306 | depends on SERIAL_8250_CONSOLE |
@@ -295,6 +324,7 @@ config SERIAL_8250_EM | |||
295 | config SERIAL_8250_RT288X | 324 | config SERIAL_8250_RT288X |
296 | bool "Ralink RT288x/RT305x/RT3662/RT3883 serial port support" | 325 | bool "Ralink RT288x/RT305x/RT3662/RT3883 serial port support" |
297 | depends on SERIAL_8250 | 326 | depends on SERIAL_8250 |
327 | depends on MIPS || COMPILE_TEST | ||
298 | default y if MIPS_ALCHEMY || SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620 | 328 | default y if MIPS_ALCHEMY || SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620 |
299 | help | 329 | help |
300 | Selecting this option will add support for the alternate register | 330 | Selecting this option will add support for the alternate register |
@@ -346,7 +376,7 @@ config SERIAL_8250_LPC18XX | |||
346 | serial port, say Y to this option. If unsure, say Y. | 376 | serial port, say Y to this option. If unsure, say Y. |
347 | 377 | ||
348 | config SERIAL_8250_MT6577 | 378 | config SERIAL_8250_MT6577 |
349 | bool "Mediatek serial port support" | 379 | tristate "Mediatek serial port support" |
350 | depends on SERIAL_8250 && ARCH_MEDIATEK | 380 | depends on SERIAL_8250 && ARCH_MEDIATEK |
351 | help | 381 | help |
352 | If you have a Mediatek based board and want to use the | 382 | If you have a Mediatek based board and want to use the |
@@ -360,9 +390,10 @@ config SERIAL_8250_UNIPHIER | |||
360 | serial ports, say Y to this option. If unsure, say N. | 390 | serial ports, say Y to this option. If unsure, say N. |
361 | 391 | ||
362 | config SERIAL_8250_INGENIC | 392 | config SERIAL_8250_INGENIC |
363 | bool "Support for Ingenic SoC serial ports" | 393 | tristate "Support for Ingenic SoC serial ports" |
364 | depends on OF_FLATTREE | 394 | depends on SERIAL_8250 |
365 | select LIBFDT | 395 | depends on (OF_FLATTREE && SERIAL_8250_CONSOLE) || !SERIAL_EARLYCON |
396 | depends on MIPS || COMPILE_TEST | ||
366 | help | 397 | help |
367 | If you have a system using an Ingenic SoC and wish to make use of | 398 | If you have a system using an Ingenic SoC and wish to make use of |
368 | its UARTs, say Y to this option. If unsure, say N. | 399 | its UARTs, say Y to this option. If unsure, say N. |
@@ -378,6 +409,16 @@ config SERIAL_8250_MID | |||
378 | present on the UART found on Intel Medfield SOC and various other | 409 | present on the UART found on Intel Medfield SOC and various other |
379 | Intel platforms. | 410 | Intel platforms. |
380 | 411 | ||
412 | config SERIAL_8250_MOXA | ||
413 | tristate "MOXA SmartIO MUE support" | ||
414 | depends on SERIAL_8250 && PCI | ||
415 | help | ||
416 | Say Y here if you have a Moxa SmartIO MUE multiport serial card. | ||
417 | If unsure, say N. | ||
418 | |||
419 | This driver can also be built as a module. The module will be called | ||
420 | 8250_moxa. If you want to do that, say M here. | ||
421 | |||
381 | config SERIAL_OF_PLATFORM | 422 | config SERIAL_OF_PLATFORM |
382 | tristate "Devicetree based probing for 8250 ports" | 423 | tristate "Devicetree based probing for 8250 ports" |
383 | depends on SERIAL_8250 && OF | 424 | depends on SERIAL_8250 && OF |
diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile index b9b9bca5b6c3..c9a2d6ed87e9 100644 --- a/drivers/tty/serial/8250/Makefile +++ b/drivers/tty/serial/8250/Makefile | |||
@@ -12,6 +12,7 @@ obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o | |||
12 | obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o | 12 | obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o |
13 | obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o | 13 | obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o |
14 | obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o | 14 | obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o |
15 | obj-$(CONFIG_SERIAL_8250_BCM2835AUX) += 8250_bcm2835aux.o | ||
15 | obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o | 16 | obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o |
16 | obj-$(CONFIG_SERIAL_8250_FOURPORT) += 8250_fourport.o | 17 | obj-$(CONFIG_SERIAL_8250_FOURPORT) += 8250_fourport.o |
17 | obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o | 18 | obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o |
@@ -28,6 +29,7 @@ obj-$(CONFIG_SERIAL_8250_MT6577) += 8250_mtk.o | |||
28 | obj-$(CONFIG_SERIAL_8250_UNIPHIER) += 8250_uniphier.o | 29 | obj-$(CONFIG_SERIAL_8250_UNIPHIER) += 8250_uniphier.o |
29 | obj-$(CONFIG_SERIAL_8250_INGENIC) += 8250_ingenic.o | 30 | obj-$(CONFIG_SERIAL_8250_INGENIC) += 8250_ingenic.o |
30 | obj-$(CONFIG_SERIAL_8250_MID) += 8250_mid.o | 31 | obj-$(CONFIG_SERIAL_8250_MID) += 8250_mid.o |
32 | obj-$(CONFIG_SERIAL_8250_MOXA) += 8250_moxa.o | ||
31 | obj-$(CONFIG_SERIAL_OF_PLATFORM) += 8250_of.o | 33 | obj-$(CONFIG_SERIAL_OF_PLATFORM) += 8250_of.o |
32 | 34 | ||
33 | CFLAGS_8250_ingenic.o += -I$(srctree)/scripts/dtc/libfdt | 35 | CFLAGS_8250_ingenic.o += -I$(srctree)/scripts/dtc/libfdt |
diff --git a/drivers/tty/serial/8250/serial_cs.c b/drivers/tty/serial/8250/serial_cs.c index 4d180c9423ef..933c2688dd7e 100644 --- a/drivers/tty/serial/8250/serial_cs.c +++ b/drivers/tty/serial/8250/serial_cs.c | |||
@@ -28,7 +28,7 @@ | |||
28 | and other provisions required by the GPL. If you do not delete | 28 | and other provisions required by the GPL. If you do not delete |
29 | the provisions above, a recipient may use your version of this | 29 | the provisions above, a recipient may use your version of this |
30 | file under either the MPL or the GPL. | 30 | file under either the MPL or the GPL. |
31 | 31 | ||
32 | ======================================================================*/ | 32 | ======================================================================*/ |
33 | 33 | ||
34 | #include <linux/module.h> | 34 | #include <linux/module.h> |
@@ -257,7 +257,7 @@ static const struct serial_quirk quirks[] = { | |||
257 | }; | 257 | }; |
258 | 258 | ||
259 | 259 | ||
260 | static int serial_config(struct pcmcia_device * link); | 260 | static int serial_config(struct pcmcia_device *link); |
261 | 261 | ||
262 | 262 | ||
263 | static void serial_remove(struct pcmcia_device *link) | 263 | static void serial_remove(struct pcmcia_device *link) |
@@ -309,7 +309,7 @@ static int serial_probe(struct pcmcia_device *link) | |||
309 | dev_dbg(&link->dev, "serial_attach()\n"); | 309 | dev_dbg(&link->dev, "serial_attach()\n"); |
310 | 310 | ||
311 | /* Create new serial device */ | 311 | /* Create new serial device */ |
312 | info = kzalloc(sizeof (*info), GFP_KERNEL); | 312 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
313 | if (!info) | 313 | if (!info) |
314 | return -ENOMEM; | 314 | return -ENOMEM; |
315 | info->p_dev = link; | 315 | info->p_dev = link; |
@@ -339,7 +339,7 @@ static void serial_detach(struct pcmcia_device *link) | |||
339 | 339 | ||
340 | /*====================================================================*/ | 340 | /*====================================================================*/ |
341 | 341 | ||
342 | static int setup_serial(struct pcmcia_device *handle, struct serial_info * info, | 342 | static int setup_serial(struct pcmcia_device *handle, struct serial_info *info, |
343 | unsigned int iobase, int irq) | 343 | unsigned int iobase, int irq) |
344 | { | 344 | { |
345 | struct uart_8250_port uart; | 345 | struct uart_8250_port uart; |
@@ -441,16 +441,20 @@ static int simple_config(struct pcmcia_device *link) | |||
441 | struct serial_info *info = link->priv; | 441 | struct serial_info *info = link->priv; |
442 | int i = -ENODEV, try; | 442 | int i = -ENODEV, try; |
443 | 443 | ||
444 | /* First pass: look for a config entry that looks normal. | 444 | /* |
445 | * Two tries: without IO aliases, then with aliases */ | 445 | * First pass: look for a config entry that looks normal. |
446 | * Two tries: without IO aliases, then with aliases. | ||
447 | */ | ||
446 | link->config_flags |= CONF_AUTO_SET_VPP; | 448 | link->config_flags |= CONF_AUTO_SET_VPP; |
447 | for (try = 0; try < 4; try++) | 449 | for (try = 0; try < 4; try++) |
448 | if (!pcmcia_loop_config(link, simple_config_check, &try)) | 450 | if (!pcmcia_loop_config(link, simple_config_check, &try)) |
449 | goto found_port; | 451 | goto found_port; |
450 | 452 | ||
451 | /* Second pass: try to find an entry that isn't picky about | 453 | /* |
452 | its base address, then try to grab any standard serial port | 454 | * Second pass: try to find an entry that isn't picky about |
453 | address, and finally try to get any free port. */ | 455 | * its base address, then try to grab any standard serial port |
456 | * address, and finally try to get any free port. | ||
457 | */ | ||
454 | if (!pcmcia_loop_config(link, simple_config_check_notpicky, NULL)) | 458 | if (!pcmcia_loop_config(link, simple_config_check_notpicky, NULL)) |
455 | goto found_port; | 459 | goto found_port; |
456 | 460 | ||
@@ -480,8 +484,10 @@ static int multi_config_check(struct pcmcia_device *p_dev, void *priv_data) | |||
480 | if (p_dev->resource[1]->end) | 484 | if (p_dev->resource[1]->end) |
481 | return -EINVAL; | 485 | return -EINVAL; |
482 | 486 | ||
483 | /* The quad port cards have bad CIS's, so just look for a | 487 | /* |
484 | window larger than 8 ports and assume it will be right */ | 488 | * The quad port cards have bad CIS's, so just look for a |
489 | * window larger than 8 ports and assume it will be right. | ||
490 | */ | ||
485 | if (p_dev->resource[0]->end <= 8) | 491 | if (p_dev->resource[0]->end <= 8) |
486 | return -EINVAL; | 492 | return -EINVAL; |
487 | 493 | ||
@@ -527,8 +533,8 @@ static int multi_config(struct pcmcia_device *link) | |||
527 | info->multi = 2; | 533 | info->multi = 2; |
528 | if (pcmcia_loop_config(link, multi_config_check_notpicky, | 534 | if (pcmcia_loop_config(link, multi_config_check_notpicky, |
529 | &base2)) { | 535 | &base2)) { |
530 | dev_warn(&link->dev, "no usable port range " | 536 | dev_warn(&link->dev, |
531 | "found, giving up\n"); | 537 | "no usable port range found, giving up\n"); |
532 | return -ENODEV; | 538 | return -ENODEV; |
533 | } | 539 | } |
534 | } | 540 | } |
@@ -600,7 +606,7 @@ static int serial_check_for_multi(struct pcmcia_device *p_dev, void *priv_data) | |||
600 | } | 606 | } |
601 | 607 | ||
602 | 608 | ||
603 | static int serial_config(struct pcmcia_device * link) | 609 | static int serial_config(struct pcmcia_device *link) |
604 | { | 610 | { |
605 | struct serial_info *info = link->priv; | 611 | struct serial_info *info = link->priv; |
606 | int i; | 612 | int i; |
@@ -623,8 +629,10 @@ static int serial_config(struct pcmcia_device * link) | |||
623 | break; | 629 | break; |
624 | } | 630 | } |
625 | 631 | ||
626 | /* Another check for dual-serial cards: look for either serial or | 632 | /* |
627 | multifunction cards that ask for appropriate IO port ranges */ | 633 | * Another check for dual-serial cards: look for either serial or |
634 | * multifunction cards that ask for appropriate IO port ranges. | ||
635 | */ | ||
628 | if ((info->multi == 0) && | 636 | if ((info->multi == 0) && |
629 | (link->has_func_id) && | 637 | (link->has_func_id) && |
630 | (link->socket->pcmcia_pfc == 0) && | 638 | (link->socket->pcmcia_pfc == 0) && |
@@ -701,7 +709,7 @@ static const struct pcmcia_device_id serial_ids[] = { | |||
701 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58), | 709 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58), |
702 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "MEGAHERTZ", "XJEM1144/CCEM1144", 0xf510db04, 0x52d21e1e), | 710 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "MEGAHERTZ", "XJEM1144/CCEM1144", 0xf510db04, 0x52d21e1e), |
703 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "MICRO RESEARCH", "COMBO-L/M-336", 0xb2ced065, 0x3ced0555), | 711 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "MICRO RESEARCH", "COMBO-L/M-336", 0xb2ced065, 0x3ced0555), |
704 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "NEC", "PK-UG-J001" ,0x18df0ba0 ,0x831b1064), | 712 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "NEC", "PK-UG-J001", 0x18df0ba0, 0x831b1064), |
705 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Diamonds Modem+Ethernet", 0xc2f80cd, 0x656947b9), | 713 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Diamonds Modem+Ethernet", 0xc2f80cd, 0x656947b9), |
706 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Hearts Modem+Ethernet", 0xc2f80cd, 0xdc9ba5ed), | 714 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Hearts Modem+Ethernet", 0xc2f80cd, 0xdc9ba5ed), |
707 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc), | 715 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc), |
@@ -797,30 +805,30 @@ static const struct pcmcia_device_id serial_ids[] = { | |||
797 | PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "cis/COMpad2.cis"), | 805 | PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "cis/COMpad2.cis"), |
798 | PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "cis/RS-COM-2P.cis"), | 806 | PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "cis/RS-COM-2P.cis"), |
799 | PCMCIA_DEVICE_CIS_MANF_CARD(0x0013, 0x0000, "cis/GLOBETROTTER.cis"), | 807 | PCMCIA_DEVICE_CIS_MANF_CARD(0x0013, 0x0000, "cis/GLOBETROTTER.cis"), |
800 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100 1.00.",0x19ca78af,0xf964f42b), | 808 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.", "SERIAL CARD: SL100 1.00.", 0x19ca78af, 0xf964f42b), |
801 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100",0x19ca78af,0x71d98e83), | 809 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.", "SERIAL CARD: SL100", 0x19ca78af, 0x71d98e83), |
802 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL232 1.00.",0x19ca78af,0x69fb7490), | 810 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.", "SERIAL CARD: SL232 1.00.", 0x19ca78af, 0x69fb7490), |
803 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL232",0x19ca78af,0xb6bc0235), | 811 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.", "SERIAL CARD: SL232", 0x19ca78af, 0xb6bc0235), |
804 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c2000.","SERIAL CARD: CF232",0x63f2e0bd,0xb9e175d3), | 812 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c2000.", "SERIAL CARD: CF232", 0x63f2e0bd, 0xb9e175d3), |
805 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c2000.","SERIAL CARD: CF232-5",0x63f2e0bd,0xfce33442), | 813 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c2000.", "SERIAL CARD: CF232-5", 0x63f2e0bd, 0xfce33442), |
806 | PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF232",0x3beb8cf2,0x171e7190), | 814 | PCMCIA_DEVICE_PROD_ID12("Elan", "Serial Port: CF232", 0x3beb8cf2, 0x171e7190), |
807 | PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF232-5",0x3beb8cf2,0x20da4262), | 815 | PCMCIA_DEVICE_PROD_ID12("Elan", "Serial Port: CF232-5", 0x3beb8cf2, 0x20da4262), |
808 | PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF428",0x3beb8cf2,0xea5dd57d), | 816 | PCMCIA_DEVICE_PROD_ID12("Elan", "Serial Port: CF428", 0x3beb8cf2, 0xea5dd57d), |
809 | PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF500",0x3beb8cf2,0xd77255fa), | 817 | PCMCIA_DEVICE_PROD_ID12("Elan", "Serial Port: CF500", 0x3beb8cf2, 0xd77255fa), |
810 | PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: IC232",0x3beb8cf2,0x6a709903), | 818 | PCMCIA_DEVICE_PROD_ID12("Elan", "Serial Port: IC232", 0x3beb8cf2, 0x6a709903), |
811 | PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: SL232",0x3beb8cf2,0x18430676), | 819 | PCMCIA_DEVICE_PROD_ID12("Elan", "Serial Port: SL232", 0x3beb8cf2, 0x18430676), |
812 | PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: XL232",0x3beb8cf2,0x6f933767), | 820 | PCMCIA_DEVICE_PROD_ID12("Elan", "Serial Port: XL232", 0x3beb8cf2, 0x6f933767), |
813 | PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: CF332",0x3beb8cf2,0x16dc1ba7), | 821 | PCMCIA_MFC_DEVICE_PROD_ID12(0, "Elan", "Serial Port: CF332", 0x3beb8cf2, 0x16dc1ba7), |
814 | PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: SL332",0x3beb8cf2,0x19816c41), | 822 | PCMCIA_MFC_DEVICE_PROD_ID12(0, "Elan", "Serial Port: SL332", 0x3beb8cf2, 0x19816c41), |
815 | PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: SL385",0x3beb8cf2,0x64112029), | 823 | PCMCIA_MFC_DEVICE_PROD_ID12(0, "Elan", "Serial Port: SL385", 0x3beb8cf2, 0x64112029), |
816 | PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4), | 824 | PCMCIA_MFC_DEVICE_PROD_ID12(0, "Elan", "Serial Port: SL432", 0x3beb8cf2, 0x1cce7ac4), |
817 | PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial+Parallel Port: SP230",0x3beb8cf2,0xdb9e58bc), | 825 | PCMCIA_MFC_DEVICE_PROD_ID12(0, "Elan", "Serial+Parallel Port: SP230", 0x3beb8cf2, 0xdb9e58bc), |
818 | PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: CF332",0x3beb8cf2,0x16dc1ba7), | 826 | PCMCIA_MFC_DEVICE_PROD_ID12(1, "Elan", "Serial Port: CF332", 0x3beb8cf2, 0x16dc1ba7), |
819 | PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: SL332",0x3beb8cf2,0x19816c41), | 827 | PCMCIA_MFC_DEVICE_PROD_ID12(1, "Elan", "Serial Port: SL332", 0x3beb8cf2, 0x19816c41), |
820 | PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: SL385",0x3beb8cf2,0x64112029), | 828 | PCMCIA_MFC_DEVICE_PROD_ID12(1, "Elan", "Serial Port: SL385", 0x3beb8cf2, 0x64112029), |
821 | PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4), | 829 | PCMCIA_MFC_DEVICE_PROD_ID12(1, "Elan", "Serial Port: SL432", 0x3beb8cf2, 0x1cce7ac4), |
822 | PCMCIA_MFC_DEVICE_PROD_ID12(2,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4), | 830 | PCMCIA_MFC_DEVICE_PROD_ID12(2, "Elan", "Serial Port: SL432", 0x3beb8cf2, 0x1cce7ac4), |
823 | PCMCIA_MFC_DEVICE_PROD_ID12(3,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4), | 831 | PCMCIA_MFC_DEVICE_PROD_ID12(3, "Elan", "Serial Port: SL432", 0x3beb8cf2, 0x1cce7ac4), |
824 | PCMCIA_DEVICE_MANF_CARD(0x0279, 0x950b), | 832 | PCMCIA_DEVICE_MANF_CARD(0x0279, 0x950b), |
825 | /* too generic */ | 833 | /* too generic */ |
826 | /* PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0160, 0x0002), */ | 834 | /* PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0160, 0x0002), */ |
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 39721ec4f415..13d4ed6caac4 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig | |||
@@ -610,6 +610,7 @@ config SERIAL_UARTLITE_CONSOLE | |||
610 | bool "Support for console on Xilinx uartlite serial port" | 610 | bool "Support for console on Xilinx uartlite serial port" |
611 | depends on SERIAL_UARTLITE=y | 611 | depends on SERIAL_UARTLITE=y |
612 | select SERIAL_CORE_CONSOLE | 612 | select SERIAL_CORE_CONSOLE |
613 | select SERIAL_EARLYCON | ||
613 | help | 614 | help |
614 | Say Y here if you wish to use a Xilinx uartlite as the system | 615 | Say Y here if you wish to use a Xilinx uartlite as the system |
615 | console (the system console is the device which receives all kernel | 616 | console (the system console is the device which receives all kernel |
@@ -732,7 +733,7 @@ config SERIAL_IP22_ZILOG_CONSOLE | |||
732 | 733 | ||
733 | config SERIAL_SH_SCI | 734 | config SERIAL_SH_SCI |
734 | tristate "SuperH SCI(F) serial port support" | 735 | tristate "SuperH SCI(F) serial port support" |
735 | depends on SUPERH || ARCH_SHMOBILE || H8300 || COMPILE_TEST | 736 | depends on SUPERH || ARCH_RENESAS || H8300 || COMPILE_TEST |
736 | select SERIAL_CORE | 737 | select SERIAL_CORE |
737 | 738 | ||
738 | config SERIAL_SH_SCI_NR_UARTS | 739 | config SERIAL_SH_SCI_NR_UARTS |
@@ -745,6 +746,12 @@ config SERIAL_SH_SCI_CONSOLE | |||
745 | depends on SERIAL_SH_SCI=y | 746 | depends on SERIAL_SH_SCI=y |
746 | select SERIAL_CORE_CONSOLE | 747 | select SERIAL_CORE_CONSOLE |
747 | 748 | ||
749 | config SERIAL_SH_SCI_EARLYCON | ||
750 | bool "Support for early console on SuperH SCI(F)" | ||
751 | depends on SERIAL_SH_SCI=y | ||
752 | select SERIAL_CORE_CONSOLE | ||
753 | select SERIAL_EARLYCON | ||
754 | |||
748 | config SERIAL_SH_SCI_DMA | 755 | config SERIAL_SH_SCI_DMA |
749 | bool "DMA support" | 756 | bool "DMA support" |
750 | depends on SERIAL_SH_SCI && DMA_ENGINE | 757 | depends on SERIAL_SH_SCI && DMA_ENGINE |
@@ -793,17 +800,6 @@ config SERIAL_CORE_CONSOLE | |||
793 | config CONSOLE_POLL | 800 | config CONSOLE_POLL |
794 | bool | 801 | bool |
795 | 802 | ||
796 | config SERIAL_68328 | ||
797 | bool "68328 serial support" | ||
798 | depends on M68328 || M68EZ328 || M68VZ328 | ||
799 | help | ||
800 | This driver supports the built-in serial port of the Motorola 68328 | ||
801 | (standard, EZ and VZ varieties). | ||
802 | |||
803 | config SERIAL_68328_RTS_CTS | ||
804 | bool "Support RTS/CTS on 68328 serial port" | ||
805 | depends on SERIAL_68328 | ||
806 | |||
807 | config SERIAL_MCF | 803 | config SERIAL_MCF |
808 | bool "Coldfire serial support" | 804 | bool "Coldfire serial support" |
809 | depends on COLDFIRE | 805 | depends on COLDFIRE |
@@ -1606,6 +1602,28 @@ config SERIAL_STM32_CONSOLE | |||
1606 | depends on SERIAL_STM32=y | 1602 | depends on SERIAL_STM32=y |
1607 | select SERIAL_CORE_CONSOLE | 1603 | select SERIAL_CORE_CONSOLE |
1608 | 1604 | ||
1605 | config SERIAL_MVEBU_UART | ||
1606 | bool "Marvell EBU serial port support" | ||
1607 | select SERIAL_CORE | ||
1608 | help | ||
1609 | This driver is for Marvell EBU SoC's UART. If you have a machine | ||
1610 | based on the Armada-3700 SoC and wish to use the on-board serial | ||
1611 | port, | ||
1612 | say 'Y' here. | ||
1613 | Otherwise, say 'N'. | ||
1614 | |||
1615 | config SERIAL_MVEBU_CONSOLE | ||
1616 | bool "Console on Marvell EBU serial port" | ||
1617 | depends on SERIAL_MVEBU_UART | ||
1618 | select SERIAL_CORE_CONSOLE | ||
1619 | select SERIAL_EARLYCON | ||
1620 | default y | ||
1621 | help | ||
1622 | Say 'Y' here if you wish to use Armada-3700 UART as the system console. | ||
1623 | (the system console is the device which receives all kernel messages | ||
1624 | and warnings and which allows logins in single user mode) | ||
1625 | Otherwise, say 'N'. | ||
1626 | |||
1609 | endmenu | 1627 | endmenu |
1610 | 1628 | ||
1611 | config SERIAL_MCTRL_GPIO | 1629 | config SERIAL_MCTRL_GPIO |
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index b391c9b31960..8c261adac04e 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile | |||
@@ -34,7 +34,6 @@ obj-$(CONFIG_SERIAL_MAX3100) += max3100.o | |||
34 | obj-$(CONFIG_SERIAL_MAX310X) += max310x.o | 34 | obj-$(CONFIG_SERIAL_MAX310X) += max310x.o |
35 | obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o | 35 | obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o |
36 | obj-$(CONFIG_SERIAL_MUX) += mux.o | 36 | obj-$(CONFIG_SERIAL_MUX) += mux.o |
37 | obj-$(CONFIG_SERIAL_68328) += 68328serial.o | ||
38 | obj-$(CONFIG_SERIAL_MCF) += mcf.o | 37 | obj-$(CONFIG_SERIAL_MCF) += mcf.o |
39 | obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o | 38 | obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o |
40 | obj-$(CONFIG_SERIAL_HS_LPC32XX) += lpc32xx_hs.o | 39 | obj-$(CONFIG_SERIAL_HS_LPC32XX) += lpc32xx_hs.o |
@@ -91,6 +90,7 @@ obj-$(CONFIG_SERIAL_CONEXANT_DIGICOLOR) += digicolor-usart.o | |||
91 | obj-$(CONFIG_SERIAL_MEN_Z135) += men_z135_uart.o | 90 | obj-$(CONFIG_SERIAL_MEN_Z135) += men_z135_uart.o |
92 | obj-$(CONFIG_SERIAL_SPRD) += sprd_serial.o | 91 | obj-$(CONFIG_SERIAL_SPRD) += sprd_serial.o |
93 | obj-$(CONFIG_SERIAL_STM32) += stm32-usart.o | 92 | obj-$(CONFIG_SERIAL_STM32) += stm32-usart.o |
93 | obj-$(CONFIG_SERIAL_MVEBU_UART) += mvebu-uart.o | ||
94 | 94 | ||
95 | # GPIOLIB helpers for modem control lines | 95 | # GPIOLIB helpers for modem control lines |
96 | obj-$(CONFIG_SERIAL_MCTRL_GPIO) += serial_mctrl_gpio.o | 96 | obj-$(CONFIG_SERIAL_MCTRL_GPIO) += serial_mctrl_gpio.o |
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index c0da0ccbbcf5..7c198e0a3178 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c | |||
@@ -187,7 +187,7 @@ static const u16 pl011_zte_offsets[REG_ARRAY_SIZE] = { | |||
187 | [REG_DMACR] = ZX_UART011_DMACR, | 187 | [REG_DMACR] = ZX_UART011_DMACR, |
188 | }; | 188 | }; |
189 | 189 | ||
190 | static struct vendor_data vendor_zte = { | 190 | static struct vendor_data vendor_zte __maybe_unused = { |
191 | .reg_offset = pl011_zte_offsets, | 191 | .reg_offset = pl011_zte_offsets, |
192 | .access_32b = true, | 192 | .access_32b = true, |
193 | .ifls = UART011_IFLS_RX4_8|UART011_IFLS_TX4_8, | 193 | .ifls = UART011_IFLS_RX4_8|UART011_IFLS_TX4_8, |
@@ -420,7 +420,7 @@ static void pl011_dma_probe(struct uart_amba_port *uap) | |||
420 | /* Optionally make use of an RX channel as well */ | 420 | /* Optionally make use of an RX channel as well */ |
421 | chan = dma_request_slave_channel(dev, "rx"); | 421 | chan = dma_request_slave_channel(dev, "rx"); |
422 | 422 | ||
423 | if (!chan && plat->dma_rx_param) { | 423 | if (!chan && plat && plat->dma_rx_param) { |
424 | chan = dma_request_channel(mask, plat->dma_filter, plat->dma_rx_param); | 424 | chan = dma_request_channel(mask, plat->dma_filter, plat->dma_rx_param); |
425 | 425 | ||
426 | if (!chan) { | 426 | if (!chan) { |
@@ -1167,7 +1167,7 @@ static void pl011_dma_shutdown(struct uart_amba_port *uap) | |||
1167 | 1167 | ||
1168 | /* Disable RX and TX DMA */ | 1168 | /* Disable RX and TX DMA */ |
1169 | while (pl011_read(uap, REG_FR) & UART01x_FR_BUSY) | 1169 | while (pl011_read(uap, REG_FR) & UART01x_FR_BUSY) |
1170 | barrier(); | 1170 | cpu_relax(); |
1171 | 1171 | ||
1172 | spin_lock_irq(&uap->port.lock); | 1172 | spin_lock_irq(&uap->port.lock); |
1173 | uap->dmacr &= ~(UART011_DMAONERR | UART011_RXDMAE | UART011_TXDMAE); | 1173 | uap->dmacr &= ~(UART011_DMAONERR | UART011_RXDMAE | UART011_TXDMAE); |
@@ -1611,7 +1611,7 @@ static void pl011_put_poll_char(struct uart_port *port, | |||
1611 | container_of(port, struct uart_amba_port, port); | 1611 | container_of(port, struct uart_amba_port, port); |
1612 | 1612 | ||
1613 | while (pl011_read(uap, REG_FR) & UART01x_FR_TXFF) | 1613 | while (pl011_read(uap, REG_FR) & UART01x_FR_TXFF) |
1614 | barrier(); | 1614 | cpu_relax(); |
1615 | 1615 | ||
1616 | pl011_write(ch, uap, REG_DR); | 1616 | pl011_write(ch, uap, REG_DR); |
1617 | } | 1617 | } |
@@ -1947,6 +1947,8 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1947 | lcr_h |= UART01x_LCRH_PEN; | 1947 | lcr_h |= UART01x_LCRH_PEN; |
1948 | if (!(termios->c_cflag & PARODD)) | 1948 | if (!(termios->c_cflag & PARODD)) |
1949 | lcr_h |= UART01x_LCRH_EPS; | 1949 | lcr_h |= UART01x_LCRH_EPS; |
1950 | if (termios->c_cflag & CMSPAR) | ||
1951 | lcr_h |= UART011_LCRH_SPS; | ||
1950 | } | 1952 | } |
1951 | if (uap->fifosize > 1) | 1953 | if (uap->fifosize > 1) |
1952 | lcr_h |= UART01x_LCRH_FEN; | 1954 | lcr_h |= UART01x_LCRH_FEN; |
@@ -2150,7 +2152,7 @@ static void pl011_console_putchar(struct uart_port *port, int ch) | |||
2150 | container_of(port, struct uart_amba_port, port); | 2152 | container_of(port, struct uart_amba_port, port); |
2151 | 2153 | ||
2152 | while (pl011_read(uap, REG_FR) & UART01x_FR_TXFF) | 2154 | while (pl011_read(uap, REG_FR) & UART01x_FR_TXFF) |
2153 | barrier(); | 2155 | cpu_relax(); |
2154 | pl011_write(ch, uap, REG_DR); | 2156 | pl011_write(ch, uap, REG_DR); |
2155 | } | 2157 | } |
2156 | 2158 | ||
@@ -2158,7 +2160,7 @@ static void | |||
2158 | pl011_console_write(struct console *co, const char *s, unsigned int count) | 2160 | pl011_console_write(struct console *co, const char *s, unsigned int count) |
2159 | { | 2161 | { |
2160 | struct uart_amba_port *uap = amba_ports[co->index]; | 2162 | struct uart_amba_port *uap = amba_ports[co->index]; |
2161 | unsigned int status, old_cr = 0, new_cr; | 2163 | unsigned int old_cr = 0, new_cr; |
2162 | unsigned long flags; | 2164 | unsigned long flags; |
2163 | int locked = 1; | 2165 | int locked = 1; |
2164 | 2166 | ||
@@ -2188,9 +2190,8 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) | |||
2188 | * Finally, wait for transmitter to become empty | 2190 | * Finally, wait for transmitter to become empty |
2189 | * and restore the TCR | 2191 | * and restore the TCR |
2190 | */ | 2192 | */ |
2191 | do { | 2193 | while (pl011_read(uap, REG_FR) & UART01x_FR_BUSY) |
2192 | status = pl011_read(uap, REG_FR); | 2194 | cpu_relax(); |
2193 | } while (status & UART01x_FR_BUSY); | ||
2194 | if (!uap->vendor->always_enabled) | 2195 | if (!uap->vendor->always_enabled) |
2195 | pl011_write(old_cr, uap, REG_CR); | 2196 | pl011_write(old_cr, uap, REG_CR); |
2196 | 2197 | ||
@@ -2302,13 +2303,13 @@ static struct console amba_console = { | |||
2302 | static void pl011_putc(struct uart_port *port, int c) | 2303 | static void pl011_putc(struct uart_port *port, int c) |
2303 | { | 2304 | { |
2304 | while (readl(port->membase + UART01x_FR) & UART01x_FR_TXFF) | 2305 | while (readl(port->membase + UART01x_FR) & UART01x_FR_TXFF) |
2305 | ; | 2306 | cpu_relax(); |
2306 | if (port->iotype == UPIO_MEM32) | 2307 | if (port->iotype == UPIO_MEM32) |
2307 | writel(c, port->membase + UART01x_DR); | 2308 | writel(c, port->membase + UART01x_DR); |
2308 | else | 2309 | else |
2309 | writeb(c, port->membase + UART01x_DR); | 2310 | writeb(c, port->membase + UART01x_DR); |
2310 | while (readl(port->membase + UART01x_FR) & UART01x_FR_BUSY) | 2311 | while (readl(port->membase + UART01x_FR) & UART01x_FR_BUSY) |
2311 | ; | 2312 | cpu_relax(); |
2312 | } | 2313 | } |
2313 | 2314 | ||
2314 | static void pl011_early_write(struct console *con, const char *s, unsigned n) | 2315 | static void pl011_early_write(struct console *con, const char *s, unsigned n) |
@@ -2327,7 +2328,6 @@ static int __init pl011_early_console_setup(struct earlycon_device *device, | |||
2327 | device->con->write = pl011_early_write; | 2328 | device->con->write = pl011_early_write; |
2328 | return 0; | 2329 | return 0; |
2329 | } | 2330 | } |
2330 | EARLYCON_DECLARE(pl011, pl011_early_console_setup); | ||
2331 | OF_EARLYCON_DECLARE(pl011, "arm,pl011", pl011_early_console_setup); | 2331 | OF_EARLYCON_DECLARE(pl011, "arm,pl011", pl011_early_console_setup); |
2332 | 2332 | ||
2333 | #else | 2333 | #else |
diff --git a/drivers/tty/serial/arc_uart.c b/drivers/tty/serial/arc_uart.c index 03ebe401fff7..3a1de5c87cb4 100644 --- a/drivers/tty/serial/arc_uart.c +++ b/drivers/tty/serial/arc_uart.c | |||
@@ -576,7 +576,6 @@ static int __init arc_early_console_setup(struct earlycon_device *dev, | |||
576 | dev->con->write = arc_early_serial_write; | 576 | dev->con->write = arc_early_serial_write; |
577 | return 0; | 577 | return 0; |
578 | } | 578 | } |
579 | EARLYCON_DECLARE(arc_uart, arc_early_console_setup); | ||
580 | OF_EARLYCON_DECLARE(arc_uart, "snps,arc-uart", arc_early_console_setup); | 579 | OF_EARLYCON_DECLARE(arc_uart, "snps,arc-uart", arc_early_console_setup); |
581 | 580 | ||
582 | #endif /* CONFIG_SERIAL_ARC_CONSOLE */ | 581 | #endif /* CONFIG_SERIAL_ARC_CONSOLE */ |
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 1c0884d8ef32..d9439e6ab719 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c | |||
@@ -159,8 +159,9 @@ struct atmel_uart_port { | |||
159 | u32 rts_high; | 159 | u32 rts_high; |
160 | u32 rts_low; | 160 | u32 rts_low; |
161 | bool ms_irq_enabled; | 161 | bool ms_irq_enabled; |
162 | bool is_usart; /* usart or uart */ | 162 | u32 rtor; /* address of receiver timeout register if it exists */ |
163 | struct timer_list uart_timer; /* uart timer */ | 163 | bool has_hw_timer; |
164 | struct timer_list uart_timer; | ||
164 | 165 | ||
165 | bool suspended; | 166 | bool suspended; |
166 | unsigned int pending; | 167 | unsigned int pending; |
@@ -1710,19 +1711,24 @@ static void atmel_get_ip_name(struct uart_port *port) | |||
1710 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | 1711 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
1711 | int name = atmel_uart_readl(port, ATMEL_US_NAME); | 1712 | int name = atmel_uart_readl(port, ATMEL_US_NAME); |
1712 | u32 version; | 1713 | u32 version; |
1713 | int usart, uart; | 1714 | u32 usart, dbgu_uart, new_uart; |
1714 | /* usart and uart ascii */ | 1715 | /* ASCII decoding for IP version */ |
1715 | usart = 0x55534152; | 1716 | usart = 0x55534152; /* USAR(T) */ |
1716 | uart = 0x44424755; | 1717 | dbgu_uart = 0x44424755; /* DBGU */ |
1717 | 1718 | new_uart = 0x55415254; /* UART */ | |
1718 | atmel_port->is_usart = false; | 1719 | |
1719 | 1720 | atmel_port->has_hw_timer = false; | |
1720 | if (name == usart) { | 1721 | |
1721 | dev_dbg(port->dev, "This is usart\n"); | 1722 | if (name == new_uart) { |
1722 | atmel_port->is_usart = true; | 1723 | dev_dbg(port->dev, "Uart with hw timer"); |
1723 | } else if (name == uart) { | 1724 | atmel_port->has_hw_timer = true; |
1724 | dev_dbg(port->dev, "This is uart\n"); | 1725 | atmel_port->rtor = ATMEL_UA_RTOR; |
1725 | atmel_port->is_usart = false; | 1726 | } else if (name == usart) { |
1727 | dev_dbg(port->dev, "Usart\n"); | ||
1728 | atmel_port->has_hw_timer = true; | ||
1729 | atmel_port->rtor = ATMEL_US_RTOR; | ||
1730 | } else if (name == dbgu_uart) { | ||
1731 | dev_dbg(port->dev, "Dbgu or uart without hw timer\n"); | ||
1726 | } else { | 1732 | } else { |
1727 | /* fallback for older SoCs: use version field */ | 1733 | /* fallback for older SoCs: use version field */ |
1728 | version = atmel_uart_readl(port, ATMEL_US_VERSION); | 1734 | version = atmel_uart_readl(port, ATMEL_US_VERSION); |
@@ -1730,12 +1736,12 @@ static void atmel_get_ip_name(struct uart_port *port) | |||
1730 | case 0x302: | 1736 | case 0x302: |
1731 | case 0x10213: | 1737 | case 0x10213: |
1732 | dev_dbg(port->dev, "This version is usart\n"); | 1738 | dev_dbg(port->dev, "This version is usart\n"); |
1733 | atmel_port->is_usart = true; | 1739 | atmel_port->has_hw_timer = true; |
1740 | atmel_port->rtor = ATMEL_US_RTOR; | ||
1734 | break; | 1741 | break; |
1735 | case 0x203: | 1742 | case 0x203: |
1736 | case 0x10202: | 1743 | case 0x10202: |
1737 | dev_dbg(port->dev, "This version is uart\n"); | 1744 | dev_dbg(port->dev, "This version is uart\n"); |
1738 | atmel_port->is_usart = false; | ||
1739 | break; | 1745 | break; |
1740 | default: | 1746 | default: |
1741 | dev_err(port->dev, "Not supported ip name nor version, set to uart\n"); | 1747 | dev_err(port->dev, "Not supported ip name nor version, set to uart\n"); |
@@ -1835,12 +1841,13 @@ static int atmel_startup(struct uart_port *port) | |||
1835 | 1841 | ||
1836 | if (atmel_use_pdc_rx(port)) { | 1842 | if (atmel_use_pdc_rx(port)) { |
1837 | /* set UART timeout */ | 1843 | /* set UART timeout */ |
1838 | if (!atmel_port->is_usart) { | 1844 | if (!atmel_port->has_hw_timer) { |
1839 | mod_timer(&atmel_port->uart_timer, | 1845 | mod_timer(&atmel_port->uart_timer, |
1840 | jiffies + uart_poll_timeout(port)); | 1846 | jiffies + uart_poll_timeout(port)); |
1841 | /* set USART timeout */ | 1847 | /* set USART timeout */ |
1842 | } else { | 1848 | } else { |
1843 | atmel_uart_writel(port, ATMEL_US_RTOR, PDC_RX_TIMEOUT); | 1849 | atmel_uart_writel(port, atmel_port->rtor, |
1850 | PDC_RX_TIMEOUT); | ||
1844 | atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_STTTO); | 1851 | atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_STTTO); |
1845 | 1852 | ||
1846 | atmel_uart_writel(port, ATMEL_US_IER, | 1853 | atmel_uart_writel(port, ATMEL_US_IER, |
@@ -1850,12 +1857,13 @@ static int atmel_startup(struct uart_port *port) | |||
1850 | atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_RXTEN); | 1857 | atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_RXTEN); |
1851 | } else if (atmel_use_dma_rx(port)) { | 1858 | } else if (atmel_use_dma_rx(port)) { |
1852 | /* set UART timeout */ | 1859 | /* set UART timeout */ |
1853 | if (!atmel_port->is_usart) { | 1860 | if (!atmel_port->has_hw_timer) { |
1854 | mod_timer(&atmel_port->uart_timer, | 1861 | mod_timer(&atmel_port->uart_timer, |
1855 | jiffies + uart_poll_timeout(port)); | 1862 | jiffies + uart_poll_timeout(port)); |
1856 | /* set USART timeout */ | 1863 | /* set USART timeout */ |
1857 | } else { | 1864 | } else { |
1858 | atmel_uart_writel(port, ATMEL_US_RTOR, PDC_RX_TIMEOUT); | 1865 | atmel_uart_writel(port, atmel_port->rtor, |
1866 | PDC_RX_TIMEOUT); | ||
1859 | atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_STTTO); | 1867 | atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_STTTO); |
1860 | 1868 | ||
1861 | atmel_uart_writel(port, ATMEL_US_IER, | 1869 | atmel_uart_writel(port, ATMEL_US_IER, |
@@ -2478,13 +2486,13 @@ static int __init atmel_console_init(void) | |||
2478 | struct atmel_uart_data *pdata = | 2486 | struct atmel_uart_data *pdata = |
2479 | dev_get_platdata(&atmel_default_console_device->dev); | 2487 | dev_get_platdata(&atmel_default_console_device->dev); |
2480 | int id = pdata->num; | 2488 | int id = pdata->num; |
2481 | struct atmel_uart_port *port = &atmel_ports[id]; | 2489 | struct atmel_uart_port *atmel_port = &atmel_ports[id]; |
2482 | 2490 | ||
2483 | port->backup_imr = 0; | 2491 | atmel_port->backup_imr = 0; |
2484 | port->uart.line = id; | 2492 | atmel_port->uart.line = id; |
2485 | 2493 | ||
2486 | add_preferred_console(ATMEL_DEVICENAME, id, NULL); | 2494 | add_preferred_console(ATMEL_DEVICENAME, id, NULL); |
2487 | ret = atmel_init_port(port, atmel_default_console_device); | 2495 | ret = atmel_init_port(atmel_port, atmel_default_console_device); |
2488 | if (ret) | 2496 | if (ret) |
2489 | return ret; | 2497 | return ret; |
2490 | register_console(&atmel_console); | 2498 | register_console(&atmel_console); |
@@ -2599,23 +2607,23 @@ static int atmel_serial_resume(struct platform_device *pdev) | |||
2599 | #define atmel_serial_resume NULL | 2607 | #define atmel_serial_resume NULL |
2600 | #endif | 2608 | #endif |
2601 | 2609 | ||
2602 | static void atmel_serial_probe_fifos(struct atmel_uart_port *port, | 2610 | static void atmel_serial_probe_fifos(struct atmel_uart_port *atmel_port, |
2603 | struct platform_device *pdev) | 2611 | struct platform_device *pdev) |
2604 | { | 2612 | { |
2605 | port->fifo_size = 0; | 2613 | atmel_port->fifo_size = 0; |
2606 | port->rts_low = 0; | 2614 | atmel_port->rts_low = 0; |
2607 | port->rts_high = 0; | 2615 | atmel_port->rts_high = 0; |
2608 | 2616 | ||
2609 | if (of_property_read_u32(pdev->dev.of_node, | 2617 | if (of_property_read_u32(pdev->dev.of_node, |
2610 | "atmel,fifo-size", | 2618 | "atmel,fifo-size", |
2611 | &port->fifo_size)) | 2619 | &atmel_port->fifo_size)) |
2612 | return; | 2620 | return; |
2613 | 2621 | ||
2614 | if (!port->fifo_size) | 2622 | if (!atmel_port->fifo_size) |
2615 | return; | 2623 | return; |
2616 | 2624 | ||
2617 | if (port->fifo_size < ATMEL_MIN_FIFO_SIZE) { | 2625 | if (atmel_port->fifo_size < ATMEL_MIN_FIFO_SIZE) { |
2618 | port->fifo_size = 0; | 2626 | atmel_port->fifo_size = 0; |
2619 | dev_err(&pdev->dev, "Invalid FIFO size\n"); | 2627 | dev_err(&pdev->dev, "Invalid FIFO size\n"); |
2620 | return; | 2628 | return; |
2621 | } | 2629 | } |
@@ -2628,22 +2636,22 @@ static void atmel_serial_probe_fifos(struct atmel_uart_port *port, | |||
2628 | * Threshold to a reasonably high value respecting this 16 data | 2636 | * Threshold to a reasonably high value respecting this 16 data |
2629 | * empirical rule when possible. | 2637 | * empirical rule when possible. |
2630 | */ | 2638 | */ |
2631 | port->rts_high = max_t(int, port->fifo_size >> 1, | 2639 | atmel_port->rts_high = max_t(int, atmel_port->fifo_size >> 1, |
2632 | port->fifo_size - ATMEL_RTS_HIGH_OFFSET); | 2640 | atmel_port->fifo_size - ATMEL_RTS_HIGH_OFFSET); |
2633 | port->rts_low = max_t(int, port->fifo_size >> 2, | 2641 | atmel_port->rts_low = max_t(int, atmel_port->fifo_size >> 2, |
2634 | port->fifo_size - ATMEL_RTS_LOW_OFFSET); | 2642 | atmel_port->fifo_size - ATMEL_RTS_LOW_OFFSET); |
2635 | 2643 | ||
2636 | dev_info(&pdev->dev, "Using FIFO (%u data)\n", | 2644 | dev_info(&pdev->dev, "Using FIFO (%u data)\n", |
2637 | port->fifo_size); | 2645 | atmel_port->fifo_size); |
2638 | dev_dbg(&pdev->dev, "RTS High Threshold : %2u data\n", | 2646 | dev_dbg(&pdev->dev, "RTS High Threshold : %2u data\n", |
2639 | port->rts_high); | 2647 | atmel_port->rts_high); |
2640 | dev_dbg(&pdev->dev, "RTS Low Threshold : %2u data\n", | 2648 | dev_dbg(&pdev->dev, "RTS Low Threshold : %2u data\n", |
2641 | port->rts_low); | 2649 | atmel_port->rts_low); |
2642 | } | 2650 | } |
2643 | 2651 | ||
2644 | static int atmel_serial_probe(struct platform_device *pdev) | 2652 | static int atmel_serial_probe(struct platform_device *pdev) |
2645 | { | 2653 | { |
2646 | struct atmel_uart_port *port; | 2654 | struct atmel_uart_port *atmel_port; |
2647 | struct device_node *np = pdev->dev.of_node; | 2655 | struct device_node *np = pdev->dev.of_node; |
2648 | struct atmel_uart_data *pdata = dev_get_platdata(&pdev->dev); | 2656 | struct atmel_uart_data *pdata = dev_get_platdata(&pdev->dev); |
2649 | void *data; | 2657 | void *data; |
@@ -2674,99 +2682,133 @@ static int atmel_serial_probe(struct platform_device *pdev) | |||
2674 | goto err; | 2682 | goto err; |
2675 | } | 2683 | } |
2676 | 2684 | ||
2677 | port = &atmel_ports[ret]; | 2685 | atmel_port = &atmel_ports[ret]; |
2678 | port->backup_imr = 0; | 2686 | atmel_port->backup_imr = 0; |
2679 | port->uart.line = ret; | 2687 | atmel_port->uart.line = ret; |
2680 | atmel_serial_probe_fifos(port, pdev); | 2688 | atmel_serial_probe_fifos(atmel_port, pdev); |
2681 | 2689 | ||
2682 | spin_lock_init(&port->lock_suspended); | 2690 | spin_lock_init(&atmel_port->lock_suspended); |
2683 | 2691 | ||
2684 | ret = atmel_init_port(port, pdev); | 2692 | ret = atmel_init_port(atmel_port, pdev); |
2685 | if (ret) | 2693 | if (ret) |
2686 | goto err_clear_bit; | 2694 | goto err_clear_bit; |
2687 | 2695 | ||
2688 | port->gpios = mctrl_gpio_init(&port->uart, 0); | 2696 | atmel_port->gpios = mctrl_gpio_init(&atmel_port->uart, 0); |
2689 | if (IS_ERR(port->gpios)) { | 2697 | if (IS_ERR(atmel_port->gpios)) { |
2690 | ret = PTR_ERR(port->gpios); | 2698 | ret = PTR_ERR(atmel_port->gpios); |
2691 | goto err_clear_bit; | 2699 | goto err_clear_bit; |
2692 | } | 2700 | } |
2693 | 2701 | ||
2694 | if (!atmel_use_pdc_rx(&port->uart)) { | 2702 | if (!atmel_use_pdc_rx(&atmel_port->uart)) { |
2695 | ret = -ENOMEM; | 2703 | ret = -ENOMEM; |
2696 | data = kmalloc(sizeof(struct atmel_uart_char) | 2704 | data = kmalloc(sizeof(struct atmel_uart_char) |
2697 | * ATMEL_SERIAL_RINGSIZE, GFP_KERNEL); | 2705 | * ATMEL_SERIAL_RINGSIZE, GFP_KERNEL); |
2698 | if (!data) | 2706 | if (!data) |
2699 | goto err_alloc_ring; | 2707 | goto err_alloc_ring; |
2700 | port->rx_ring.buf = data; | 2708 | atmel_port->rx_ring.buf = data; |
2701 | } | 2709 | } |
2702 | 2710 | ||
2703 | rs485_enabled = port->uart.rs485.flags & SER_RS485_ENABLED; | 2711 | rs485_enabled = atmel_port->uart.rs485.flags & SER_RS485_ENABLED; |
2704 | 2712 | ||
2705 | ret = uart_add_one_port(&atmel_uart, &port->uart); | 2713 | ret = uart_add_one_port(&atmel_uart, &atmel_port->uart); |
2706 | if (ret) | 2714 | if (ret) |
2707 | goto err_add_port; | 2715 | goto err_add_port; |
2708 | 2716 | ||
2709 | #ifdef CONFIG_SERIAL_ATMEL_CONSOLE | 2717 | #ifdef CONFIG_SERIAL_ATMEL_CONSOLE |
2710 | if (atmel_is_console_port(&port->uart) | 2718 | if (atmel_is_console_port(&atmel_port->uart) |
2711 | && ATMEL_CONSOLE_DEVICE->flags & CON_ENABLED) { | 2719 | && ATMEL_CONSOLE_DEVICE->flags & CON_ENABLED) { |
2712 | /* | 2720 | /* |
2713 | * The serial core enabled the clock for us, so undo | 2721 | * The serial core enabled the clock for us, so undo |
2714 | * the clk_prepare_enable() in atmel_console_setup() | 2722 | * the clk_prepare_enable() in atmel_console_setup() |
2715 | */ | 2723 | */ |
2716 | clk_disable_unprepare(port->clk); | 2724 | clk_disable_unprepare(atmel_port->clk); |
2717 | } | 2725 | } |
2718 | #endif | 2726 | #endif |
2719 | 2727 | ||
2720 | device_init_wakeup(&pdev->dev, 1); | 2728 | device_init_wakeup(&pdev->dev, 1); |
2721 | platform_set_drvdata(pdev, port); | 2729 | platform_set_drvdata(pdev, atmel_port); |
2722 | 2730 | ||
2723 | /* | 2731 | /* |
2724 | * The peripheral clock has been disabled by atmel_init_port(): | 2732 | * The peripheral clock has been disabled by atmel_init_port(): |
2725 | * enable it before accessing I/O registers | 2733 | * enable it before accessing I/O registers |
2726 | */ | 2734 | */ |
2727 | clk_prepare_enable(port->clk); | 2735 | clk_prepare_enable(atmel_port->clk); |
2728 | 2736 | ||
2729 | if (rs485_enabled) { | 2737 | if (rs485_enabled) { |
2730 | atmel_uart_writel(&port->uart, ATMEL_US_MR, | 2738 | atmel_uart_writel(&atmel_port->uart, ATMEL_US_MR, |
2731 | ATMEL_US_USMODE_NORMAL); | 2739 | ATMEL_US_USMODE_NORMAL); |
2732 | atmel_uart_writel(&port->uart, ATMEL_US_CR, ATMEL_US_RTSEN); | 2740 | atmel_uart_writel(&atmel_port->uart, ATMEL_US_CR, |
2741 | ATMEL_US_RTSEN); | ||
2733 | } | 2742 | } |
2734 | 2743 | ||
2735 | /* | 2744 | /* |
2736 | * Get port name of usart or uart | 2745 | * Get port name of usart or uart |
2737 | */ | 2746 | */ |
2738 | atmel_get_ip_name(&port->uart); | 2747 | atmel_get_ip_name(&atmel_port->uart); |
2739 | 2748 | ||
2740 | /* | 2749 | /* |
2741 | * The peripheral clock can now safely be disabled till the port | 2750 | * The peripheral clock can now safely be disabled till the port |
2742 | * is used | 2751 | * is used |
2743 | */ | 2752 | */ |
2744 | clk_disable_unprepare(port->clk); | 2753 | clk_disable_unprepare(atmel_port->clk); |
2745 | 2754 | ||
2746 | return 0; | 2755 | return 0; |
2747 | 2756 | ||
2748 | err_add_port: | 2757 | err_add_port: |
2749 | kfree(port->rx_ring.buf); | 2758 | kfree(atmel_port->rx_ring.buf); |
2750 | port->rx_ring.buf = NULL; | 2759 | atmel_port->rx_ring.buf = NULL; |
2751 | err_alloc_ring: | 2760 | err_alloc_ring: |
2752 | if (!atmel_is_console_port(&port->uart)) { | 2761 | if (!atmel_is_console_port(&atmel_port->uart)) { |
2753 | clk_put(port->clk); | 2762 | clk_put(atmel_port->clk); |
2754 | port->clk = NULL; | 2763 | atmel_port->clk = NULL; |
2755 | } | 2764 | } |
2756 | err_clear_bit: | 2765 | err_clear_bit: |
2757 | clear_bit(port->uart.line, atmel_ports_in_use); | 2766 | clear_bit(atmel_port->uart.line, atmel_ports_in_use); |
2758 | err: | 2767 | err: |
2759 | return ret; | 2768 | return ret; |
2760 | } | 2769 | } |
2761 | 2770 | ||
2771 | /* | ||
2772 | * Even if the driver is not modular, it makes sense to be able to | ||
2773 | * unbind a device: there can be many bound devices, and there are | ||
2774 | * situations where dynamic binding and unbinding can be useful. | ||
2775 | * | ||
2776 | * For example, a connected device can require a specific firmware update | ||
2777 | * protocol that needs bitbanging on IO lines, but use the regular serial | ||
2778 | * port in the normal case. | ||
2779 | */ | ||
2780 | static int atmel_serial_remove(struct platform_device *pdev) | ||
2781 | { | ||
2782 | struct uart_port *port = platform_get_drvdata(pdev); | ||
2783 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | ||
2784 | int ret = 0; | ||
2785 | |||
2786 | tasklet_kill(&atmel_port->tasklet); | ||
2787 | |||
2788 | device_init_wakeup(&pdev->dev, 0); | ||
2789 | |||
2790 | ret = uart_remove_one_port(&atmel_uart, port); | ||
2791 | |||
2792 | kfree(atmel_port->rx_ring.buf); | ||
2793 | |||
2794 | /* "port" is allocated statically, so we shouldn't free it */ | ||
2795 | |||
2796 | clear_bit(port->line, atmel_ports_in_use); | ||
2797 | |||
2798 | clk_put(atmel_port->clk); | ||
2799 | atmel_port->clk = NULL; | ||
2800 | |||
2801 | return ret; | ||
2802 | } | ||
2803 | |||
2762 | static struct platform_driver atmel_serial_driver = { | 2804 | static struct platform_driver atmel_serial_driver = { |
2763 | .probe = atmel_serial_probe, | 2805 | .probe = atmel_serial_probe, |
2806 | .remove = atmel_serial_remove, | ||
2764 | .suspend = atmel_serial_suspend, | 2807 | .suspend = atmel_serial_suspend, |
2765 | .resume = atmel_serial_resume, | 2808 | .resume = atmel_serial_resume, |
2766 | .driver = { | 2809 | .driver = { |
2767 | .name = "atmel_usart", | 2810 | .name = "atmel_usart", |
2768 | .of_match_table = of_match_ptr(atmel_serial_dt_ids), | 2811 | .of_match_table = of_match_ptr(atmel_serial_dt_ids), |
2769 | .suppress_bind_attrs = true, | ||
2770 | }, | 2812 | }, |
2771 | }; | 2813 | }; |
2772 | 2814 | ||
diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index b3a4e0cdddaa..5beafd2d2218 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c | |||
@@ -450,6 +450,7 @@ static int uart_clps711x_probe(struct platform_device *pdev) | |||
450 | struct clps711x_port *s; | 450 | struct clps711x_port *s; |
451 | struct resource *res; | 451 | struct resource *res; |
452 | struct clk *uart_clk; | 452 | struct clk *uart_clk; |
453 | int irq; | ||
453 | 454 | ||
454 | if (index < 0 || index >= UART_CLPS711X_NR) | 455 | if (index < 0 || index >= UART_CLPS711X_NR) |
455 | return -EINVAL; | 456 | return -EINVAL; |
@@ -467,12 +468,13 @@ static int uart_clps711x_probe(struct platform_device *pdev) | |||
467 | if (IS_ERR(s->port.membase)) | 468 | if (IS_ERR(s->port.membase)) |
468 | return PTR_ERR(s->port.membase); | 469 | return PTR_ERR(s->port.membase); |
469 | 470 | ||
470 | s->port.irq = platform_get_irq(pdev, 0); | 471 | irq = platform_get_irq(pdev, 0); |
471 | if (IS_ERR_VALUE(s->port.irq)) | 472 | if (irq < 0) |
472 | return s->port.irq; | 473 | return irq; |
474 | s->port.irq = irq; | ||
473 | 475 | ||
474 | s->rx_irq = platform_get_irq(pdev, 1); | 476 | s->rx_irq = platform_get_irq(pdev, 1); |
475 | if (IS_ERR_VALUE(s->rx_irq)) | 477 | if (s->rx_irq < 0) |
476 | return s->rx_irq; | 478 | return s->rx_irq; |
477 | 479 | ||
478 | if (!np) { | 480 | if (!np) { |
diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c index f13f2ebd215b..c0172bf54a9b 100644 --- a/drivers/tty/serial/crisv10.c +++ b/drivers/tty/serial/crisv10.c | |||
@@ -1413,9 +1413,8 @@ rs_stop(struct tty_struct *tty) | |||
1413 | xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, | 1413 | xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, |
1414 | STOP_CHAR(info->port.tty)); | 1414 | STOP_CHAR(info->port.tty)); |
1415 | xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, stop); | 1415 | xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, stop); |
1416 | if (tty->termios.c_iflag & IXON ) { | 1416 | if (I_IXON(tty)) |
1417 | xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable); | 1417 | xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable); |
1418 | } | ||
1419 | 1418 | ||
1420 | *((unsigned long *)&info->ioport[REG_XOFF]) = xoff; | 1419 | *((unsigned long *)&info->ioport[REG_XOFF]) = xoff; |
1421 | local_irq_restore(flags); | 1420 | local_irq_restore(flags); |
@@ -1436,9 +1435,8 @@ rs_start(struct tty_struct *tty) | |||
1436 | info->xmit.tail,SERIAL_XMIT_SIZE))); | 1435 | info->xmit.tail,SERIAL_XMIT_SIZE))); |
1437 | xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(tty)); | 1436 | xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(tty)); |
1438 | xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, enable); | 1437 | xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, enable); |
1439 | if (tty->termios.c_iflag & IXON ) { | 1438 | if (I_IXON(tty)) |
1440 | xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable); | 1439 | xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable); |
1441 | } | ||
1442 | 1440 | ||
1443 | *((unsigned long *)&info->ioport[REG_XOFF]) = xoff; | 1441 | *((unsigned long *)&info->ioport[REG_XOFF]) = xoff; |
1444 | if (!info->uses_dma_out && | 1442 | if (!info->uses_dma_out && |
@@ -2968,7 +2966,7 @@ static int rs_raw_write(struct tty_struct *tty, | |||
2968 | 2966 | ||
2969 | local_save_flags(flags); | 2967 | local_save_flags(flags); |
2970 | DFLOW(DEBUG_LOG(info->line, "write count %i ", count)); | 2968 | DFLOW(DEBUG_LOG(info->line, "write count %i ", count)); |
2971 | DFLOW(DEBUG_LOG(info->line, "ldisc %i\n", tty->ldisc.chars_in_buffer(tty))); | 2969 | DFLOW(DEBUG_LOG(info->line, "ldisc\n")); |
2972 | 2970 | ||
2973 | 2971 | ||
2974 | /* The local_irq_disable/restore_flags pairs below are needed | 2972 | /* The local_irq_disable/restore_flags pairs below are needed |
@@ -3161,13 +3159,12 @@ rs_throttle(struct tty_struct * tty) | |||
3161 | { | 3159 | { |
3162 | struct e100_serial *info = (struct e100_serial *)tty->driver_data; | 3160 | struct e100_serial *info = (struct e100_serial *)tty->driver_data; |
3163 | #ifdef SERIAL_DEBUG_THROTTLE | 3161 | #ifdef SERIAL_DEBUG_THROTTLE |
3164 | printk("throttle %s: %lu....\n", tty_name(tty), | 3162 | printk("throttle %s ....\n", tty_name(tty)); |
3165 | (unsigned long)tty->ldisc.chars_in_buffer(tty)); | ||
3166 | #endif | 3163 | #endif |
3167 | DFLOW(DEBUG_LOG(info->line,"rs_throttle %lu\n", tty->ldisc.chars_in_buffer(tty))); | 3164 | DFLOW(DEBUG_LOG(info->line,"rs_throttle\n")); |
3168 | 3165 | ||
3169 | /* Do RTS before XOFF since XOFF might take some time */ | 3166 | /* Do RTS before XOFF since XOFF might take some time */ |
3170 | if (tty->termios.c_cflag & CRTSCTS) { | 3167 | if (C_CRTSCTS(tty)) { |
3171 | /* Turn off RTS line */ | 3168 | /* Turn off RTS line */ |
3172 | e100_rts(info, 0); | 3169 | e100_rts(info, 0); |
3173 | } | 3170 | } |
@@ -3181,13 +3178,12 @@ rs_unthrottle(struct tty_struct * tty) | |||
3181 | { | 3178 | { |
3182 | struct e100_serial *info = (struct e100_serial *)tty->driver_data; | 3179 | struct e100_serial *info = (struct e100_serial *)tty->driver_data; |
3183 | #ifdef SERIAL_DEBUG_THROTTLE | 3180 | #ifdef SERIAL_DEBUG_THROTTLE |
3184 | printk("unthrottle %s: %lu....\n", tty_name(tty), | 3181 | printk("unthrottle %s ....\n", tty_name(tty)); |
3185 | (unsigned long)tty->ldisc.chars_in_buffer(tty)); | ||
3186 | #endif | 3182 | #endif |
3187 | DFLOW(DEBUG_LOG(info->line,"rs_unthrottle ldisc %d\n", tty->ldisc.chars_in_buffer(tty))); | 3183 | DFLOW(DEBUG_LOG(info->line,"rs_unthrottle ldisc\n")); |
3188 | DFLOW(DEBUG_LOG(info->line,"rs_unthrottle flip.count: %i\n", tty->flip.count)); | 3184 | DFLOW(DEBUG_LOG(info->line,"rs_unthrottle flip.count: %i\n", tty->flip.count)); |
3189 | /* Do RTS before XOFF since XOFF might take some time */ | 3185 | /* Do RTS before XOFF since XOFF might take some time */ |
3190 | if (tty->termios.c_cflag & CRTSCTS) { | 3186 | if (C_CRTSCTS(tty)) { |
3191 | /* Assert RTS line */ | 3187 | /* Assert RTS line */ |
3192 | e100_rts(info, 1); | 3188 | e100_rts(info, 1); |
3193 | } | 3189 | } |
@@ -3555,8 +3551,7 @@ rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
3555 | change_speed(info); | 3551 | change_speed(info); |
3556 | 3552 | ||
3557 | /* Handle turning off CRTSCTS */ | 3553 | /* Handle turning off CRTSCTS */ |
3558 | if ((old_termios->c_cflag & CRTSCTS) && | 3554 | if ((old_termios->c_cflag & CRTSCTS) && !C_CRTSCTS(tty)) |
3559 | !(tty->termios.c_cflag & CRTSCTS)) | ||
3560 | rs_start(tty); | 3555 | rs_start(tty); |
3561 | 3556 | ||
3562 | } | 3557 | } |
@@ -3615,7 +3610,6 @@ rs_close(struct tty_struct *tty, struct file * filp) | |||
3615 | local_irq_restore(flags); | 3610 | local_irq_restore(flags); |
3616 | return; | 3611 | return; |
3617 | } | 3612 | } |
3618 | info->port.flags |= ASYNC_CLOSING; | ||
3619 | /* | 3613 | /* |
3620 | * Now we wait for the transmit buffer to clear; and we notify | 3614 | * Now we wait for the transmit buffer to clear; and we notify |
3621 | * the line discipline to only process XON/XOFF characters. | 3615 | * the line discipline to only process XON/XOFF characters. |
@@ -3654,7 +3648,7 @@ rs_close(struct tty_struct *tty, struct file * filp) | |||
3654 | schedule_timeout_interruptible(info->port.close_delay); | 3648 | schedule_timeout_interruptible(info->port.close_delay); |
3655 | wake_up_interruptible(&info->port.open_wait); | 3649 | wake_up_interruptible(&info->port.open_wait); |
3656 | } | 3650 | } |
3657 | info->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); | 3651 | info->port.flags &= ~ASYNC_NORMAL_ACTIVE; |
3658 | local_irq_restore(flags); | 3652 | local_irq_restore(flags); |
3659 | 3653 | ||
3660 | /* port closed */ | 3654 | /* port closed */ |
@@ -3767,9 +3761,8 @@ block_til_ready(struct tty_struct *tty, struct file * filp, | |||
3767 | return 0; | 3761 | return 0; |
3768 | } | 3762 | } |
3769 | 3763 | ||
3770 | if (tty->termios.c_cflag & CLOCAL) { | 3764 | if (C_CLOCAL(tty)) |
3771 | do_clocal = 1; | 3765 | do_clocal = 1; |
3772 | } | ||
3773 | 3766 | ||
3774 | /* | 3767 | /* |
3775 | * Block waiting for the carrier detect and the line to become | 3768 | * Block waiting for the carrier detect and the line to become |
diff --git a/drivers/tty/serial/digicolor-usart.c b/drivers/tty/serial/digicolor-usart.c index a80cdad114f3..02ad6953b167 100644 --- a/drivers/tty/serial/digicolor-usart.c +++ b/drivers/tty/serial/digicolor-usart.c | |||
@@ -453,7 +453,7 @@ static struct uart_driver digicolor_uart = { | |||
453 | static int digicolor_uart_probe(struct platform_device *pdev) | 453 | static int digicolor_uart_probe(struct platform_device *pdev) |
454 | { | 454 | { |
455 | struct device_node *np = pdev->dev.of_node; | 455 | struct device_node *np = pdev->dev.of_node; |
456 | int ret, index; | 456 | int irq, ret, index; |
457 | struct digicolor_port *dp; | 457 | struct digicolor_port *dp; |
458 | struct resource *res; | 458 | struct resource *res; |
459 | struct clk *uart_clk; | 459 | struct clk *uart_clk; |
@@ -481,9 +481,10 @@ static int digicolor_uart_probe(struct platform_device *pdev) | |||
481 | if (IS_ERR(dp->port.membase)) | 481 | if (IS_ERR(dp->port.membase)) |
482 | return PTR_ERR(dp->port.membase); | 482 | return PTR_ERR(dp->port.membase); |
483 | 483 | ||
484 | dp->port.irq = platform_get_irq(pdev, 0); | 484 | irq = platform_get_irq(pdev, 0); |
485 | if (IS_ERR_VALUE(dp->port.irq)) | 485 | if (irq < 0) |
486 | return dp->port.irq; | 486 | return irq; |
487 | dp->port.irq = irq; | ||
487 | 488 | ||
488 | dp->port.iotype = UPIO_MEM; | 489 | dp->port.iotype = UPIO_MEM; |
489 | dp->port.uartclk = clk_get_rate(uart_clk); | 490 | dp->port.uartclk = clk_get_rate(uart_clk); |
diff --git a/drivers/tty/serial/earlycon.c b/drivers/tty/serial/earlycon.c index 3f2423690d01..067783f0523c 100644 --- a/drivers/tty/serial/earlycon.c +++ b/drivers/tty/serial/earlycon.c | |||
@@ -19,7 +19,8 @@ | |||
19 | #include <linux/io.h> | 19 | #include <linux/io.h> |
20 | #include <linux/serial_core.h> | 20 | #include <linux/serial_core.h> |
21 | #include <linux/sizes.h> | 21 | #include <linux/sizes.h> |
22 | #include <linux/mod_devicetable.h> | 22 | #include <linux/of.h> |
23 | #include <linux/of_fdt.h> | ||
23 | 24 | ||
24 | #ifdef CONFIG_FIX_EARLYCON_MEM | 25 | #ifdef CONFIG_FIX_EARLYCON_MEM |
25 | #include <asm/fixmap.h> | 26 | #include <asm/fixmap.h> |
@@ -28,22 +29,15 @@ | |||
28 | #include <asm/serial.h> | 29 | #include <asm/serial.h> |
29 | 30 | ||
30 | static struct console early_con = { | 31 | static struct console early_con = { |
31 | .name = "uart", /* 8250 console switch requires this name */ | 32 | .name = "uart", /* fixed up at earlycon registration */ |
32 | .flags = CON_PRINTBUFFER | CON_BOOT, | 33 | .flags = CON_PRINTBUFFER | CON_BOOT, |
33 | .index = -1, | 34 | .index = 0, |
34 | }; | 35 | }; |
35 | 36 | ||
36 | static struct earlycon_device early_console_dev = { | 37 | static struct earlycon_device early_console_dev = { |
37 | .con = &early_con, | 38 | .con = &early_con, |
38 | }; | 39 | }; |
39 | 40 | ||
40 | extern struct earlycon_id __earlycon_table[]; | ||
41 | static const struct earlycon_id __earlycon_table_sentinel | ||
42 | __used __section(__earlycon_table_end); | ||
43 | |||
44 | static const struct of_device_id __earlycon_of_table_sentinel | ||
45 | __used __section(__earlycon_of_table_end); | ||
46 | |||
47 | static void __iomem * __init earlycon_map(unsigned long paddr, size_t size) | 41 | static void __iomem * __init earlycon_map(unsigned long paddr, size_t size) |
48 | { | 42 | { |
49 | void __iomem *base; | 43 | void __iomem *base; |
@@ -61,6 +55,39 @@ static void __iomem * __init earlycon_map(unsigned long paddr, size_t size) | |||
61 | return base; | 55 | return base; |
62 | } | 56 | } |
63 | 57 | ||
58 | static void __init earlycon_init(struct earlycon_device *device, | ||
59 | const char *name) | ||
60 | { | ||
61 | struct console *earlycon = device->con; | ||
62 | struct uart_port *port = &device->port; | ||
63 | const char *s; | ||
64 | size_t len; | ||
65 | |||
66 | /* scan backwards from end of string for first non-numeral */ | ||
67 | for (s = name + strlen(name); | ||
68 | s > name && s[-1] >= '0' && s[-1] <= '9'; | ||
69 | s--) | ||
70 | ; | ||
71 | if (*s) | ||
72 | earlycon->index = simple_strtoul(s, NULL, 10); | ||
73 | len = s - name; | ||
74 | strlcpy(earlycon->name, name, min(len + 1, sizeof(earlycon->name))); | ||
75 | earlycon->data = &early_console_dev; | ||
76 | |||
77 | if (port->iotype == UPIO_MEM || port->iotype == UPIO_MEM16 || | ||
78 | port->iotype == UPIO_MEM32 || port->iotype == UPIO_MEM32BE) | ||
79 | pr_info("%s%d at MMIO%s %pa (options '%s')\n", | ||
80 | earlycon->name, earlycon->index, | ||
81 | (port->iotype == UPIO_MEM) ? "" : | ||
82 | (port->iotype == UPIO_MEM16) ? "16" : | ||
83 | (port->iotype == UPIO_MEM32) ? "32" : "32be", | ||
84 | &port->mapbase, device->options); | ||
85 | else | ||
86 | pr_info("%s%d at I/O port 0x%lx (options '%s')\n", | ||
87 | earlycon->name, earlycon->index, | ||
88 | port->iobase, device->options); | ||
89 | } | ||
90 | |||
64 | static int __init parse_options(struct earlycon_device *device, char *options) | 91 | static int __init parse_options(struct earlycon_device *device, char *options) |
65 | { | 92 | { |
66 | struct uart_port *port = &device->port; | 93 | struct uart_port *port = &device->port; |
@@ -97,19 +124,6 @@ static int __init parse_options(struct earlycon_device *device, char *options) | |||
97 | strlcpy(device->options, options, length); | 124 | strlcpy(device->options, options, length); |
98 | } | 125 | } |
99 | 126 | ||
100 | if (port->iotype == UPIO_MEM || port->iotype == UPIO_MEM16 || | ||
101 | port->iotype == UPIO_MEM32 || port->iotype == UPIO_MEM32BE) | ||
102 | pr_info("Early serial console at MMIO%s 0x%llx (options '%s')\n", | ||
103 | (port->iotype == UPIO_MEM) ? "" : | ||
104 | (port->iotype == UPIO_MEM16) ? "16" : | ||
105 | (port->iotype == UPIO_MEM32) ? "32" : "32be", | ||
106 | (unsigned long long)port->mapbase, | ||
107 | device->options); | ||
108 | else | ||
109 | pr_info("Early serial console at I/O port 0x%lx (options '%s')\n", | ||
110 | port->iobase, | ||
111 | device->options); | ||
112 | |||
113 | return 0; | 127 | return 0; |
114 | } | 128 | } |
115 | 129 | ||
@@ -127,7 +141,7 @@ static int __init register_earlycon(char *buf, const struct earlycon_id *match) | |||
127 | if (port->mapbase) | 141 | if (port->mapbase) |
128 | port->membase = earlycon_map(port->mapbase, 64); | 142 | port->membase = earlycon_map(port->mapbase, 64); |
129 | 143 | ||
130 | early_console_dev.con->data = &early_console_dev; | 144 | earlycon_init(&early_console_dev, match->name); |
131 | err = match->setup(&early_console_dev, buf); | 145 | err = match->setup(&early_console_dev, buf); |
132 | if (err < 0) | 146 | if (err < 0) |
133 | return err; | 147 | return err; |
@@ -166,7 +180,7 @@ int __init setup_earlycon(char *buf) | |||
166 | if (early_con.flags & CON_ENABLED) | 180 | if (early_con.flags & CON_ENABLED) |
167 | return -EALREADY; | 181 | return -EALREADY; |
168 | 182 | ||
169 | for (match = __earlycon_table; match->name[0]; match++) { | 183 | for (match = __earlycon_table; match < __earlycon_table_end; match++) { |
170 | size_t len = strlen(match->name); | 184 | size_t len = strlen(match->name); |
171 | 185 | ||
172 | if (strncmp(buf, match->name, len)) | 186 | if (strncmp(buf, match->name, len)) |
@@ -204,20 +218,62 @@ static int __init param_setup_earlycon(char *buf) | |||
204 | } | 218 | } |
205 | early_param("earlycon", param_setup_earlycon); | 219 | early_param("earlycon", param_setup_earlycon); |
206 | 220 | ||
207 | int __init of_setup_earlycon(unsigned long addr, | 221 | #ifdef CONFIG_OF_EARLY_FLATTREE |
208 | int (*setup)(struct earlycon_device *, const char *)) | 222 | |
223 | int __init of_setup_earlycon(const struct earlycon_id *match, | ||
224 | unsigned long node, | ||
225 | const char *options) | ||
209 | { | 226 | { |
210 | int err; | 227 | int err; |
211 | struct uart_port *port = &early_console_dev.port; | 228 | struct uart_port *port = &early_console_dev.port; |
229 | const __be32 *val; | ||
230 | bool big_endian; | ||
231 | u64 addr; | ||
212 | 232 | ||
213 | spin_lock_init(&port->lock); | 233 | spin_lock_init(&port->lock); |
214 | port->iotype = UPIO_MEM; | 234 | port->iotype = UPIO_MEM; |
235 | addr = of_flat_dt_translate_address(node); | ||
236 | if (addr == OF_BAD_ADDR) { | ||
237 | pr_warn("[%s] bad address\n", match->name); | ||
238 | return -ENXIO; | ||
239 | } | ||
215 | port->mapbase = addr; | 240 | port->mapbase = addr; |
216 | port->uartclk = BASE_BAUD * 16; | 241 | port->uartclk = BASE_BAUD * 16; |
217 | port->membase = earlycon_map(addr, SZ_4K); | 242 | port->membase = earlycon_map(port->mapbase, SZ_4K); |
243 | |||
244 | val = of_get_flat_dt_prop(node, "reg-offset", NULL); | ||
245 | if (val) | ||
246 | port->mapbase += be32_to_cpu(*val); | ||
247 | val = of_get_flat_dt_prop(node, "reg-shift", NULL); | ||
248 | if (val) | ||
249 | port->regshift = be32_to_cpu(*val); | ||
250 | big_endian = of_get_flat_dt_prop(node, "big-endian", NULL) != NULL || | ||
251 | (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN) && | ||
252 | of_get_flat_dt_prop(node, "native-endian", NULL) != NULL); | ||
253 | val = of_get_flat_dt_prop(node, "reg-io-width", NULL); | ||
254 | if (val) { | ||
255 | switch (be32_to_cpu(*val)) { | ||
256 | case 1: | ||
257 | port->iotype = UPIO_MEM; | ||
258 | break; | ||
259 | case 2: | ||
260 | port->iotype = UPIO_MEM16; | ||
261 | break; | ||
262 | case 4: | ||
263 | port->iotype = (big_endian) ? UPIO_MEM32BE : UPIO_MEM32; | ||
264 | break; | ||
265 | default: | ||
266 | pr_warn("[%s] unsupported reg-io-width\n", match->name); | ||
267 | return -EINVAL; | ||
268 | } | ||
269 | } | ||
218 | 270 | ||
219 | early_console_dev.con->data = &early_console_dev; | 271 | if (options) { |
220 | err = setup(&early_console_dev, NULL); | 272 | strlcpy(early_console_dev.options, options, |
273 | sizeof(early_console_dev.options)); | ||
274 | } | ||
275 | earlycon_init(&early_console_dev, match->name); | ||
276 | err = match->setup(&early_console_dev, options); | ||
221 | if (err < 0) | 277 | if (err < 0) |
222 | return err; | 278 | return err; |
223 | if (!early_console_dev.con->write) | 279 | if (!early_console_dev.con->write) |
@@ -227,3 +283,5 @@ int __init of_setup_earlycon(unsigned long addr, | |||
227 | register_console(early_console_dev.con); | 283 | register_console(early_console_dev.con); |
228 | return 0; | 284 | return 0; |
229 | } | 285 | } |
286 | |||
287 | #endif /* CONFIG_OF_EARLY_FLATTREE */ | ||
diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 88246f7e435a..2085a6cfa44b 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c | |||
@@ -395,8 +395,10 @@ static int ifx_spi_decode_spi_header(unsigned char *buffer, int *length, | |||
395 | 395 | ||
396 | if (h1 == 0 && h2 == 0) { | 396 | if (h1 == 0 && h2 == 0) { |
397 | *received_cts = 0; | 397 | *received_cts = 0; |
398 | *more = 0; | ||
398 | return IFX_SPI_HEADER_0; | 399 | return IFX_SPI_HEADER_0; |
399 | } else if (h1 == 0xffff && h2 == 0xffff) { | 400 | } else if (h1 == 0xffff && h2 == 0xffff) { |
401 | *more = 0; | ||
400 | /* spi_slave_cts remains as it was */ | 402 | /* spi_slave_cts remains as it was */ |
401 | return IFX_SPI_HEADER_F; | 403 | return IFX_SPI_HEADER_F; |
402 | } | 404 | } |
@@ -688,6 +690,7 @@ static void ifx_spi_complete(void *ctx) | |||
688 | ifx_dev->rx_buffer + IFX_SPI_HEADER_OVERHEAD, | 690 | ifx_dev->rx_buffer + IFX_SPI_HEADER_OVERHEAD, |
689 | (size_t)actual_length); | 691 | (size_t)actual_length); |
690 | } else { | 692 | } else { |
693 | more = 0; | ||
691 | dev_dbg(&ifx_dev->spi_dev->dev, "SPI transfer error %d", | 694 | dev_dbg(&ifx_dev->spi_dev->dev, "SPI transfer error %d", |
692 | ifx_dev->spi_msg.status); | 695 | ifx_dev->spi_msg.status); |
693 | } | 696 | } |
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 9362f54c816c..231e7d5caf6c 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c | |||
@@ -2166,7 +2166,8 @@ static int imx_serial_port_suspend(struct device *dev) | |||
2166 | 2166 | ||
2167 | uart_suspend_port(&imx_reg, &sport->port); | 2167 | uart_suspend_port(&imx_reg, &sport->port); |
2168 | 2168 | ||
2169 | return 0; | 2169 | /* Needed to enable clock in suspend_noirq */ |
2170 | return clk_prepare(sport->clk_ipg); | ||
2170 | } | 2171 | } |
2171 | 2172 | ||
2172 | static int imx_serial_port_resume(struct device *dev) | 2173 | static int imx_serial_port_resume(struct device *dev) |
@@ -2179,6 +2180,8 @@ static int imx_serial_port_resume(struct device *dev) | |||
2179 | 2180 | ||
2180 | uart_resume_port(&imx_reg, &sport->port); | 2181 | uart_resume_port(&imx_reg, &sport->port); |
2181 | 2182 | ||
2183 | clk_unprepare(sport->clk_ipg); | ||
2184 | |||
2182 | return 0; | 2185 | return 0; |
2183 | } | 2186 | } |
2184 | 2187 | ||
diff --git a/drivers/tty/serial/jsm/jsm_tty.c b/drivers/tty/serial/jsm/jsm_tty.c index 524e86ab3cae..c5ddfe542451 100644 --- a/drivers/tty/serial/jsm/jsm_tty.c +++ b/drivers/tty/serial/jsm/jsm_tty.c | |||
@@ -529,7 +529,6 @@ void jsm_input(struct jsm_channel *ch) | |||
529 | int data_len; | 529 | int data_len; |
530 | unsigned long lock_flags; | 530 | unsigned long lock_flags; |
531 | int len = 0; | 531 | int len = 0; |
532 | int n = 0; | ||
533 | int s = 0; | 532 | int s = 0; |
534 | int i = 0; | 533 | int i = 0; |
535 | 534 | ||
@@ -569,8 +568,7 @@ void jsm_input(struct jsm_channel *ch) | |||
569 | *If the device is not open, or CREAD is off, flush | 568 | *If the device is not open, or CREAD is off, flush |
570 | *input data and return immediately. | 569 | *input data and return immediately. |
571 | */ | 570 | */ |
572 | if (!tp || | 571 | if (!tp || !C_CREAD(tp)) { |
573 | !(tp->termios.c_cflag & CREAD) ) { | ||
574 | 572 | ||
575 | jsm_dbg(READ, &ch->ch_bd->pci_dev, | 573 | jsm_dbg(READ, &ch->ch_bd->pci_dev, |
576 | "input. dropping %d bytes on port %d...\n", | 574 | "input. dropping %d bytes on port %d...\n", |
@@ -598,16 +596,15 @@ void jsm_input(struct jsm_channel *ch) | |||
598 | jsm_dbg(READ, &ch->ch_bd->pci_dev, "start 2\n"); | 596 | jsm_dbg(READ, &ch->ch_bd->pci_dev, "start 2\n"); |
599 | 597 | ||
600 | len = tty_buffer_request_room(port, data_len); | 598 | len = tty_buffer_request_room(port, data_len); |
601 | n = len; | ||
602 | 599 | ||
603 | /* | 600 | /* |
604 | * n now contains the most amount of data we can copy, | 601 | * len now contains the most amount of data we can copy, |
605 | * bounded either by the flip buffer size or the amount | 602 | * bounded either by the flip buffer size or the amount |
606 | * of data the card actually has pending... | 603 | * of data the card actually has pending... |
607 | */ | 604 | */ |
608 | while (n) { | 605 | while (len) { |
609 | s = ((head >= tail) ? head : RQUEUESIZE) - tail; | 606 | s = ((head >= tail) ? head : RQUEUESIZE) - tail; |
610 | s = min(s, n); | 607 | s = min(s, len); |
611 | 608 | ||
612 | if (s <= 0) | 609 | if (s <= 0) |
613 | break; | 610 | break; |
@@ -638,7 +635,7 @@ void jsm_input(struct jsm_channel *ch) | |||
638 | tty_insert_flip_string(port, ch->ch_rqueue + tail, s); | 635 | tty_insert_flip_string(port, ch->ch_rqueue + tail, s); |
639 | } | 636 | } |
640 | tail += s; | 637 | tail += s; |
641 | n -= s; | 638 | len -= s; |
642 | /* Flip queue if needed */ | 639 | /* Flip queue if needed */ |
643 | tail &= rmask; | 640 | tail &= rmask; |
644 | } | 641 | } |
diff --git a/drivers/tty/serial/m32r_sio.c b/drivers/tty/serial/m32r_sio.c index 0eeb64f2499c..68765f7c2645 100644 --- a/drivers/tty/serial/m32r_sio.c +++ b/drivers/tty/serial/m32r_sio.c | |||
@@ -47,59 +47,26 @@ | |||
47 | #define BAUD_RATE 115200 | 47 | #define BAUD_RATE 115200 |
48 | 48 | ||
49 | #include <linux/serial_core.h> | 49 | #include <linux/serial_core.h> |
50 | #include "m32r_sio.h" | ||
51 | #include "m32r_sio_reg.h" | 50 | #include "m32r_sio_reg.h" |
52 | 51 | ||
53 | /* | ||
54 | * Debugging. | ||
55 | */ | ||
56 | #if 0 | ||
57 | #define DEBUG_AUTOCONF(fmt...) printk(fmt) | ||
58 | #else | ||
59 | #define DEBUG_AUTOCONF(fmt...) do { } while (0) | ||
60 | #endif | ||
61 | |||
62 | #if 0 | ||
63 | #define DEBUG_INTR(fmt...) printk(fmt) | ||
64 | #else | ||
65 | #define DEBUG_INTR(fmt...) do { } while (0) | ||
66 | #endif | ||
67 | |||
68 | #define PASS_LIMIT 256 | 52 | #define PASS_LIMIT 256 |
69 | 53 | ||
70 | #define BASE_BAUD 115200 | ||
71 | |||
72 | /* Standard COM flags */ | 54 | /* Standard COM flags */ |
73 | #define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST) | 55 | #define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST) |
74 | 56 | ||
75 | /* | 57 | static const struct { |
76 | * SERIAL_PORT_DFNS tells us about built-in ports that have no | 58 | unsigned int port; |
77 | * standard enumeration mechanism. Platforms that can find all | 59 | unsigned int irq; |
78 | * serial ports via mechanisms like ACPI or PCI need not supply it. | 60 | } old_serial_port[] = { |
79 | */ | ||
80 | #if defined(CONFIG_PLAT_USRV) | 61 | #if defined(CONFIG_PLAT_USRV) |
81 | 62 | /* PORT IRQ FLAGS */ | |
82 | #define SERIAL_PORT_DFNS \ | 63 | { 0x3F8, PLD_IRQ_UART0 }, /* ttyS0 */ |
83 | /* UART CLK PORT IRQ FLAGS */ \ | 64 | { 0x2F8, PLD_IRQ_UART1 }, /* ttyS1 */ |
84 | { 0, BASE_BAUD, 0x3F8, PLD_IRQ_UART0, STD_COM_FLAGS }, /* ttyS0 */ \ | 65 | #elif defined(CONFIG_SERIAL_M32R_PLDSIO) |
85 | { 0, BASE_BAUD, 0x2F8, PLD_IRQ_UART1, STD_COM_FLAGS }, /* ttyS1 */ | 66 | { ((unsigned long)PLD_ESIO0CR), PLD_IRQ_SIO0_RCV }, /* ttyS0 */ |
86 | |||
87 | #else /* !CONFIG_PLAT_USRV */ | ||
88 | |||
89 | #if defined(CONFIG_SERIAL_M32R_PLDSIO) | ||
90 | #define SERIAL_PORT_DFNS \ | ||
91 | { 0, BASE_BAUD, ((unsigned long)PLD_ESIO0CR), PLD_IRQ_SIO0_RCV, \ | ||
92 | STD_COM_FLAGS }, /* ttyS0 */ | ||
93 | #else | 67 | #else |
94 | #define SERIAL_PORT_DFNS \ | 68 | { M32R_SIO_OFFSET, M32R_IRQ_SIO0_R }, /* ttyS0 */ |
95 | { 0, BASE_BAUD, M32R_SIO_OFFSET, M32R_IRQ_SIO0_R, \ | ||
96 | STD_COM_FLAGS }, /* ttyS0 */ | ||
97 | #endif | 69 | #endif |
98 | |||
99 | #endif /* !CONFIG_PLAT_USRV */ | ||
100 | |||
101 | static struct old_serial_port old_serial_port[] = { | ||
102 | SERIAL_PORT_DFNS | ||
103 | }; | 70 | }; |
104 | 71 | ||
105 | #define UART_NR ARRAY_SIZE(old_serial_port) | 72 | #define UART_NR ARRAY_SIZE(old_serial_port) |
@@ -108,19 +75,7 @@ struct uart_sio_port { | |||
108 | struct uart_port port; | 75 | struct uart_port port; |
109 | struct timer_list timer; /* "no irq" timer */ | 76 | struct timer_list timer; /* "no irq" timer */ |
110 | struct list_head list; /* ports on this IRQ */ | 77 | struct list_head list; /* ports on this IRQ */ |
111 | unsigned short rev; | ||
112 | unsigned char acr; | ||
113 | unsigned char ier; | 78 | unsigned char ier; |
114 | unsigned char lcr; | ||
115 | unsigned char mcr_mask; /* mask of user bits */ | ||
116 | unsigned char mcr_force; /* mask of forced bits */ | ||
117 | unsigned char lsr_break_flag; | ||
118 | |||
119 | /* | ||
120 | * We provide a per-port pm hook. | ||
121 | */ | ||
122 | void (*pm)(struct uart_port *port, | ||
123 | unsigned int state, unsigned int old); | ||
124 | }; | 79 | }; |
125 | 80 | ||
126 | struct irq_info { | 81 | struct irq_info { |
@@ -345,14 +300,8 @@ static void receive_chars(struct uart_sio_port *up, int *status) | |||
345 | */ | 300 | */ |
346 | *status &= up->port.read_status_mask; | 301 | *status &= up->port.read_status_mask; |
347 | 302 | ||
348 | if (up->port.line == up->port.cons->index) { | ||
349 | /* Recover the break flag from console xmit */ | ||
350 | *status |= up->lsr_break_flag; | ||
351 | up->lsr_break_flag = 0; | ||
352 | } | ||
353 | |||
354 | if (*status & UART_LSR_BI) { | 303 | if (*status & UART_LSR_BI) { |
355 | DEBUG_INTR("handling break...."); | 304 | pr_debug("handling break....\n"); |
356 | flag = TTY_BREAK; | 305 | flag = TTY_BREAK; |
357 | } else if (*status & UART_LSR_PE) | 306 | } else if (*status & UART_LSR_PE) |
358 | flag = TTY_PARITY; | 307 | flag = TTY_PARITY; |
@@ -413,7 +362,7 @@ static void transmit_chars(struct uart_sio_port *up) | |||
413 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 362 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
414 | uart_write_wakeup(&up->port); | 363 | uart_write_wakeup(&up->port); |
415 | 364 | ||
416 | DEBUG_INTR("THRE..."); | 365 | pr_debug("THRE...\n"); |
417 | 366 | ||
418 | if (uart_circ_empty(xmit)) | 367 | if (uart_circ_empty(xmit)) |
419 | m32r_sio_stop_tx(&up->port); | 368 | m32r_sio_stop_tx(&up->port); |
@@ -425,7 +374,7 @@ static void transmit_chars(struct uart_sio_port *up) | |||
425 | static inline void m32r_sio_handle_port(struct uart_sio_port *up, | 374 | static inline void m32r_sio_handle_port(struct uart_sio_port *up, |
426 | unsigned int status) | 375 | unsigned int status) |
427 | { | 376 | { |
428 | DEBUG_INTR("status = %x...", status); | 377 | pr_debug("status = %x...\n", status); |
429 | 378 | ||
430 | if (status & 0x04) | 379 | if (status & 0x04) |
431 | receive_chars(up, &status); | 380 | receive_chars(up, &status); |
@@ -453,7 +402,7 @@ static irqreturn_t m32r_sio_interrupt(int irq, void *dev_id) | |||
453 | struct list_head *l, *end = NULL; | 402 | struct list_head *l, *end = NULL; |
454 | int pass_counter = 0; | 403 | int pass_counter = 0; |
455 | 404 | ||
456 | DEBUG_INTR("m32r_sio_interrupt(%d)...", irq); | 405 | pr_debug("m32r_sio_interrupt(%d)...\n", irq); |
457 | 406 | ||
458 | #ifdef CONFIG_SERIAL_M32R_PLDSIO | 407 | #ifdef CONFIG_SERIAL_M32R_PLDSIO |
459 | // if (irq == PLD_IRQ_SIO0_SND) | 408 | // if (irq == PLD_IRQ_SIO0_SND) |
@@ -493,7 +442,7 @@ static irqreturn_t m32r_sio_interrupt(int irq, void *dev_id) | |||
493 | 442 | ||
494 | spin_unlock(&i->lock); | 443 | spin_unlock(&i->lock); |
495 | 444 | ||
496 | DEBUG_INTR("end.\n"); | 445 | pr_debug("end.\n"); |
497 | 446 | ||
498 | return IRQ_HANDLED; | 447 | return IRQ_HANDLED; |
499 | } | 448 | } |
@@ -782,20 +731,9 @@ static void m32r_sio_set_termios(struct uart_port *port, | |||
782 | 731 | ||
783 | serial_out(up, UART_IER, up->ier); | 732 | serial_out(up, UART_IER, up->ier); |
784 | 733 | ||
785 | up->lcr = cval; /* Save LCR */ | ||
786 | spin_unlock_irqrestore(&up->port.lock, flags); | 734 | spin_unlock_irqrestore(&up->port.lock, flags); |
787 | } | 735 | } |
788 | 736 | ||
789 | static void m32r_sio_pm(struct uart_port *port, unsigned int state, | ||
790 | unsigned int oldstate) | ||
791 | { | ||
792 | struct uart_sio_port *up = | ||
793 | container_of(port, struct uart_sio_port, port); | ||
794 | |||
795 | if (up->pm) | ||
796 | up->pm(port, state, oldstate); | ||
797 | } | ||
798 | |||
799 | /* | 737 | /* |
800 | * Resource handling. This is complicated by the fact that resources | 738 | * Resource handling. This is complicated by the fact that resources |
801 | * depend on the port type. Maybe we should be claiming the standard | 739 | * depend on the port type. Maybe we should be claiming the standard |
@@ -932,7 +870,6 @@ static struct uart_ops m32r_sio_pops = { | |||
932 | .startup = m32r_sio_startup, | 870 | .startup = m32r_sio_startup, |
933 | .shutdown = m32r_sio_shutdown, | 871 | .shutdown = m32r_sio_shutdown, |
934 | .set_termios = m32r_sio_set_termios, | 872 | .set_termios = m32r_sio_set_termios, |
935 | .pm = m32r_sio_pm, | ||
936 | .release_port = m32r_sio_release_port, | 873 | .release_port = m32r_sio_release_port, |
937 | .request_port = m32r_sio_request_port, | 874 | .request_port = m32r_sio_request_port, |
938 | .config_port = m32r_sio_config_port, | 875 | .config_port = m32r_sio_config_port, |
@@ -951,15 +888,14 @@ static void __init m32r_sio_init_ports(void) | |||
951 | return; | 888 | return; |
952 | first = 0; | 889 | first = 0; |
953 | 890 | ||
954 | for (i = 0, up = m32r_sio_ports; i < ARRAY_SIZE(old_serial_port); | 891 | for (i = 0, up = m32r_sio_ports; i < UART_NR; i++, up++) { |
955 | i++, up++) { | ||
956 | up->port.iobase = old_serial_port[i].port; | 892 | up->port.iobase = old_serial_port[i].port; |
957 | up->port.irq = irq_canonicalize(old_serial_port[i].irq); | 893 | up->port.irq = irq_canonicalize(old_serial_port[i].irq); |
958 | up->port.uartclk = old_serial_port[i].baud_base * 16; | 894 | up->port.uartclk = BAUD_RATE * 16; |
959 | up->port.flags = old_serial_port[i].flags; | 895 | up->port.flags = STD_COM_FLAGS; |
960 | up->port.membase = old_serial_port[i].iomem_base; | 896 | up->port.membase = 0; |
961 | up->port.iotype = old_serial_port[i].io_type; | 897 | up->port.iotype = 0; |
962 | up->port.regshift = old_serial_port[i].iomem_reg_shift; | 898 | up->port.regshift = 0; |
963 | up->port.ops = &m32r_sio_pops; | 899 | up->port.ops = &m32r_sio_pops; |
964 | } | 900 | } |
965 | } | 901 | } |
@@ -978,9 +914,6 @@ static void __init m32r_sio_register_ports(struct uart_driver *drv) | |||
978 | init_timer(&up->timer); | 914 | init_timer(&up->timer); |
979 | up->timer.function = m32r_sio_timeout; | 915 | up->timer.function = m32r_sio_timeout; |
980 | 916 | ||
981 | up->mcr_mask = ~0; | ||
982 | up->mcr_force = 0; | ||
983 | |||
984 | uart_add_one_port(drv, &up->port); | 917 | uart_add_one_port(drv, &up->port); |
985 | } | 918 | } |
986 | } | 919 | } |
@@ -1112,28 +1045,6 @@ static struct uart_driver m32r_sio_reg = { | |||
1112 | .cons = M32R_SIO_CONSOLE, | 1045 | .cons = M32R_SIO_CONSOLE, |
1113 | }; | 1046 | }; |
1114 | 1047 | ||
1115 | /** | ||
1116 | * m32r_sio_suspend_port - suspend one serial port | ||
1117 | * @line: serial line number | ||
1118 | * | ||
1119 | * Suspend one serial port. | ||
1120 | */ | ||
1121 | void m32r_sio_suspend_port(int line) | ||
1122 | { | ||
1123 | uart_suspend_port(&m32r_sio_reg, &m32r_sio_ports[line].port); | ||
1124 | } | ||
1125 | |||
1126 | /** | ||
1127 | * m32r_sio_resume_port - resume one serial port | ||
1128 | * @line: serial line number | ||
1129 | * | ||
1130 | * Resume one serial port. | ||
1131 | */ | ||
1132 | void m32r_sio_resume_port(int line) | ||
1133 | { | ||
1134 | uart_resume_port(&m32r_sio_reg, &m32r_sio_ports[line].port); | ||
1135 | } | ||
1136 | |||
1137 | static int __init m32r_sio_init(void) | 1048 | static int __init m32r_sio_init(void) |
1138 | { | 1049 | { |
1139 | int ret, i; | 1050 | int ret, i; |
@@ -1163,8 +1074,5 @@ static void __exit m32r_sio_exit(void) | |||
1163 | module_init(m32r_sio_init); | 1074 | module_init(m32r_sio_init); |
1164 | module_exit(m32r_sio_exit); | 1075 | module_exit(m32r_sio_exit); |
1165 | 1076 | ||
1166 | EXPORT_SYMBOL(m32r_sio_suspend_port); | ||
1167 | EXPORT_SYMBOL(m32r_sio_resume_port); | ||
1168 | |||
1169 | MODULE_LICENSE("GPL"); | 1077 | MODULE_LICENSE("GPL"); |
1170 | MODULE_DESCRIPTION("Generic M32R SIO serial driver"); | 1078 | MODULE_DESCRIPTION("Generic M32R SIO serial driver"); |
diff --git a/drivers/tty/serial/m32r_sio.h b/drivers/tty/serial/m32r_sio.h deleted file mode 100644 index 8129824496c6..000000000000 --- a/drivers/tty/serial/m32r_sio.h +++ /dev/null | |||
@@ -1,49 +0,0 @@ | |||
1 | /* | ||
2 | * m32r_sio.h | ||
3 | * | ||
4 | * Driver for M32R serial ports | ||
5 | * | ||
6 | * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. | ||
7 | * Based on drivers/serial/8250.h. | ||
8 | * | ||
9 | * Copyright (C) 2001 Russell King. | ||
10 | * Copyright (C) 2004 Hirokazu Takata <takata at linux-m32r.org> | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License as published by | ||
14 | * the Free Software Foundation; either version 2 of the License, or | ||
15 | * (at your option) any later version. | ||
16 | */ | ||
17 | |||
18 | #include <linux/pci.h> | ||
19 | |||
20 | struct m32r_sio_probe { | ||
21 | struct module *owner; | ||
22 | int (*pci_init_one)(struct pci_dev *dev); | ||
23 | void (*pci_remove_one)(struct pci_dev *dev); | ||
24 | void (*pnp_init)(void); | ||
25 | }; | ||
26 | |||
27 | int m32r_sio_register_probe(struct m32r_sio_probe *probe); | ||
28 | void m32r_sio_unregister_probe(struct m32r_sio_probe *probe); | ||
29 | void m32r_sio_get_irq_map(unsigned int *map); | ||
30 | void m32r_sio_suspend_port(int line); | ||
31 | void m32r_sio_resume_port(int line); | ||
32 | |||
33 | struct old_serial_port { | ||
34 | unsigned int uart; | ||
35 | unsigned int baud_base; | ||
36 | unsigned int port; | ||
37 | unsigned int irq; | ||
38 | unsigned int flags; | ||
39 | unsigned char io_type; | ||
40 | unsigned char __iomem *iomem_base; | ||
41 | unsigned short iomem_reg_shift; | ||
42 | }; | ||
43 | |||
44 | #define _INLINE_ inline | ||
45 | |||
46 | #define PROBE_RSA (1 << 0) | ||
47 | #define PROBE_ANY (~0) | ||
48 | |||
49 | #define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) | ||
diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index b12a37bd37b6..024445aa0521 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c | |||
@@ -78,6 +78,7 @@ | |||
78 | /* AML_UART_REG5 bits */ | 78 | /* AML_UART_REG5 bits */ |
79 | #define AML_UART_BAUD_MASK 0x7fffff | 79 | #define AML_UART_BAUD_MASK 0x7fffff |
80 | #define AML_UART_BAUD_USE BIT(23) | 80 | #define AML_UART_BAUD_USE BIT(23) |
81 | #define AML_UART_BAUD_XTAL BIT(24) | ||
81 | 82 | ||
82 | #define AML_UART_PORT_NUM 6 | 83 | #define AML_UART_PORT_NUM 6 |
83 | #define AML_UART_DEV_NAME "ttyAML" | 84 | #define AML_UART_DEV_NAME "ttyAML" |
@@ -299,7 +300,12 @@ static void meson_uart_change_speed(struct uart_port *port, unsigned long baud) | |||
299 | 300 | ||
300 | val = readl(port->membase + AML_UART_REG5); | 301 | val = readl(port->membase + AML_UART_REG5); |
301 | val &= ~AML_UART_BAUD_MASK; | 302 | val &= ~AML_UART_BAUD_MASK; |
302 | val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1; | 303 | if (port->uartclk == 24000000) { |
304 | val = ((port->uartclk / 3) / baud) - 1; | ||
305 | val |= AML_UART_BAUD_XTAL; | ||
306 | } else { | ||
307 | val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1; | ||
308 | } | ||
303 | val |= AML_UART_BAUD_USE; | 309 | val |= AML_UART_BAUD_USE; |
304 | writel(val, port->membase + AML_UART_REG5); | 310 | writel(val, port->membase + AML_UART_REG5); |
305 | } | 311 | } |
diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index 8c3e51314470..3970d6a9aaca 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c | |||
@@ -346,7 +346,7 @@ static irqreturn_t mpc52xx_psc_handle_irq(struct uart_port *port) | |||
346 | return mpc5xxx_uart_process_int(port); | 346 | return mpc5xxx_uart_process_int(port); |
347 | } | 347 | } |
348 | 348 | ||
349 | static struct psc_ops mpc52xx_psc_ops = { | 349 | static const struct psc_ops mpc52xx_psc_ops = { |
350 | .fifo_init = mpc52xx_psc_fifo_init, | 350 | .fifo_init = mpc52xx_psc_fifo_init, |
351 | .raw_rx_rdy = mpc52xx_psc_raw_rx_rdy, | 351 | .raw_rx_rdy = mpc52xx_psc_raw_rx_rdy, |
352 | .raw_tx_rdy = mpc52xx_psc_raw_tx_rdy, | 352 | .raw_tx_rdy = mpc52xx_psc_raw_tx_rdy, |
@@ -376,7 +376,7 @@ static struct psc_ops mpc52xx_psc_ops = { | |||
376 | .get_mr1 = mpc52xx_psc_get_mr1, | 376 | .get_mr1 = mpc52xx_psc_get_mr1, |
377 | }; | 377 | }; |
378 | 378 | ||
379 | static struct psc_ops mpc5200b_psc_ops = { | 379 | static const struct psc_ops mpc5200b_psc_ops = { |
380 | .fifo_init = mpc52xx_psc_fifo_init, | 380 | .fifo_init = mpc52xx_psc_fifo_init, |
381 | .raw_rx_rdy = mpc52xx_psc_raw_rx_rdy, | 381 | .raw_rx_rdy = mpc52xx_psc_raw_rx_rdy, |
382 | .raw_tx_rdy = mpc52xx_psc_raw_tx_rdy, | 382 | .raw_tx_rdy = mpc52xx_psc_raw_tx_rdy, |
@@ -969,7 +969,7 @@ static u8 mpc5125_psc_get_mr1(struct uart_port *port) | |||
969 | return in_8(&PSC_5125(port)->mr1); | 969 | return in_8(&PSC_5125(port)->mr1); |
970 | } | 970 | } |
971 | 971 | ||
972 | static struct psc_ops mpc5125_psc_ops = { | 972 | static const struct psc_ops mpc5125_psc_ops = { |
973 | .fifo_init = mpc5125_psc_fifo_init, | 973 | .fifo_init = mpc5125_psc_fifo_init, |
974 | .raw_rx_rdy = mpc5125_psc_raw_rx_rdy, | 974 | .raw_rx_rdy = mpc5125_psc_raw_rx_rdy, |
975 | .raw_tx_rdy = mpc5125_psc_raw_tx_rdy, | 975 | .raw_tx_rdy = mpc5125_psc_raw_tx_rdy, |
@@ -1004,7 +1004,7 @@ static struct psc_ops mpc5125_psc_ops = { | |||
1004 | .get_mr1 = mpc5125_psc_get_mr1, | 1004 | .get_mr1 = mpc5125_psc_get_mr1, |
1005 | }; | 1005 | }; |
1006 | 1006 | ||
1007 | static struct psc_ops mpc512x_psc_ops = { | 1007 | static const struct psc_ops mpc512x_psc_ops = { |
1008 | .fifo_init = mpc512x_psc_fifo_init, | 1008 | .fifo_init = mpc512x_psc_fifo_init, |
1009 | .raw_rx_rdy = mpc512x_psc_raw_rx_rdy, | 1009 | .raw_rx_rdy = mpc512x_psc_raw_rx_rdy, |
1010 | .raw_tx_rdy = mpc512x_psc_raw_tx_rdy, | 1010 | .raw_tx_rdy = mpc512x_psc_raw_tx_rdy, |
diff --git a/drivers/tty/serial/mpsc.c b/drivers/tty/serial/mpsc.c index cadfd1cfae2b..4a3021bcc859 100644 --- a/drivers/tty/serial/mpsc.c +++ b/drivers/tty/serial/mpsc.c | |||
@@ -137,8 +137,6 @@ struct mpsc_port_info { | |||
137 | /* Internal driver state for this ctlr */ | 137 | /* Internal driver state for this ctlr */ |
138 | u8 ready; | 138 | u8 ready; |
139 | u8 rcv_data; | 139 | u8 rcv_data; |
140 | tcflag_t c_iflag; /* save termios->c_iflag */ | ||
141 | tcflag_t c_cflag; /* save termios->c_cflag */ | ||
142 | 140 | ||
143 | /* Info passed in from platform */ | 141 | /* Info passed in from platform */ |
144 | u8 mirror_regs; /* Need to mirror regs? */ | 142 | u8 mirror_regs; /* Need to mirror regs? */ |
@@ -1407,9 +1405,6 @@ static void mpsc_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1407 | ulong flags; | 1405 | ulong flags; |
1408 | u32 chr_bits, stop_bits, par; | 1406 | u32 chr_bits, stop_bits, par; |
1409 | 1407 | ||
1410 | pi->c_iflag = termios->c_iflag; | ||
1411 | pi->c_cflag = termios->c_cflag; | ||
1412 | |||
1413 | switch (termios->c_cflag & CSIZE) { | 1408 | switch (termios->c_cflag & CSIZE) { |
1414 | case CS5: | 1409 | case CS5: |
1415 | chr_bits = MPSC_MPCR_CL_5; | 1410 | chr_bits = MPSC_MPCR_CL_5; |
@@ -1870,12 +1865,12 @@ static int mpsc_shared_map_regs(struct platform_device *pd) | |||
1870 | 1865 | ||
1871 | static void mpsc_shared_unmap_regs(void) | 1866 | static void mpsc_shared_unmap_regs(void) |
1872 | { | 1867 | { |
1873 | if (!mpsc_shared_regs.mpsc_routing_base) { | 1868 | if (mpsc_shared_regs.mpsc_routing_base) { |
1874 | iounmap(mpsc_shared_regs.mpsc_routing_base); | 1869 | iounmap(mpsc_shared_regs.mpsc_routing_base); |
1875 | release_mem_region(mpsc_shared_regs.mpsc_routing_base_p, | 1870 | release_mem_region(mpsc_shared_regs.mpsc_routing_base_p, |
1876 | MPSC_ROUTING_REG_BLOCK_SIZE); | 1871 | MPSC_ROUTING_REG_BLOCK_SIZE); |
1877 | } | 1872 | } |
1878 | if (!mpsc_shared_regs.sdma_intr_base) { | 1873 | if (mpsc_shared_regs.sdma_intr_base) { |
1879 | iounmap(mpsc_shared_regs.sdma_intr_base); | 1874 | iounmap(mpsc_shared_regs.sdma_intr_base); |
1880 | release_mem_region(mpsc_shared_regs.sdma_intr_base_p, | 1875 | release_mem_region(mpsc_shared_regs.sdma_intr_base_p, |
1881 | MPSC_SDMA_INTR_REG_BLOCK_SIZE); | 1876 | MPSC_SDMA_INTR_REG_BLOCK_SIZE); |
@@ -1891,44 +1886,39 @@ static void mpsc_shared_unmap_regs(void) | |||
1891 | static int mpsc_shared_drv_probe(struct platform_device *dev) | 1886 | static int mpsc_shared_drv_probe(struct platform_device *dev) |
1892 | { | 1887 | { |
1893 | struct mpsc_shared_pdata *pdata; | 1888 | struct mpsc_shared_pdata *pdata; |
1894 | int rc = -ENODEV; | 1889 | int rc; |
1895 | |||
1896 | if (dev->id == 0) { | ||
1897 | rc = mpsc_shared_map_regs(dev); | ||
1898 | if (!rc) { | ||
1899 | pdata = (struct mpsc_shared_pdata *) | ||
1900 | dev_get_platdata(&dev->dev); | ||
1901 | |||
1902 | mpsc_shared_regs.MPSC_MRR_m = pdata->mrr_val; | ||
1903 | mpsc_shared_regs.MPSC_RCRR_m= pdata->rcrr_val; | ||
1904 | mpsc_shared_regs.MPSC_TCRR_m= pdata->tcrr_val; | ||
1905 | mpsc_shared_regs.SDMA_INTR_CAUSE_m = | ||
1906 | pdata->intr_cause_val; | ||
1907 | mpsc_shared_regs.SDMA_INTR_MASK_m = | ||
1908 | pdata->intr_mask_val; | ||
1909 | |||
1910 | rc = 0; | ||
1911 | } | ||
1912 | } | ||
1913 | 1890 | ||
1914 | return rc; | 1891 | if (dev->id != 0) |
1892 | return -ENODEV; | ||
1893 | |||
1894 | rc = mpsc_shared_map_regs(dev); | ||
1895 | if (rc) | ||
1896 | return rc; | ||
1897 | |||
1898 | pdata = dev_get_platdata(&dev->dev); | ||
1899 | |||
1900 | mpsc_shared_regs.MPSC_MRR_m = pdata->mrr_val; | ||
1901 | mpsc_shared_regs.MPSC_RCRR_m= pdata->rcrr_val; | ||
1902 | mpsc_shared_regs.MPSC_TCRR_m= pdata->tcrr_val; | ||
1903 | mpsc_shared_regs.SDMA_INTR_CAUSE_m = pdata->intr_cause_val; | ||
1904 | mpsc_shared_regs.SDMA_INTR_MASK_m = pdata->intr_mask_val; | ||
1905 | |||
1906 | return 0; | ||
1915 | } | 1907 | } |
1916 | 1908 | ||
1917 | static int mpsc_shared_drv_remove(struct platform_device *dev) | 1909 | static int mpsc_shared_drv_remove(struct platform_device *dev) |
1918 | { | 1910 | { |
1919 | int rc = -ENODEV; | 1911 | if (dev->id != 0) |
1912 | return -ENODEV; | ||
1920 | 1913 | ||
1921 | if (dev->id == 0) { | 1914 | mpsc_shared_unmap_regs(); |
1922 | mpsc_shared_unmap_regs(); | 1915 | mpsc_shared_regs.MPSC_MRR_m = 0; |
1923 | mpsc_shared_regs.MPSC_MRR_m = 0; | 1916 | mpsc_shared_regs.MPSC_RCRR_m = 0; |
1924 | mpsc_shared_regs.MPSC_RCRR_m = 0; | 1917 | mpsc_shared_regs.MPSC_TCRR_m = 0; |
1925 | mpsc_shared_regs.MPSC_TCRR_m = 0; | 1918 | mpsc_shared_regs.SDMA_INTR_CAUSE_m = 0; |
1926 | mpsc_shared_regs.SDMA_INTR_CAUSE_m = 0; | 1919 | mpsc_shared_regs.SDMA_INTR_MASK_m = 0; |
1927 | mpsc_shared_regs.SDMA_INTR_MASK_m = 0; | ||
1928 | rc = 0; | ||
1929 | } | ||
1930 | 1920 | ||
1931 | return rc; | 1921 | return 0; |
1932 | } | 1922 | } |
1933 | 1923 | ||
1934 | static struct platform_driver mpsc_shared_driver = { | 1924 | static struct platform_driver mpsc_shared_driver = { |
@@ -1979,10 +1969,6 @@ static int mpsc_drv_map_regs(struct mpsc_port_info *pi, | |||
1979 | pi->sdma_base_p = r->start; | 1969 | pi->sdma_base_p = r->start; |
1980 | } else { | 1970 | } else { |
1981 | mpsc_resource_err("SDMA base"); | 1971 | mpsc_resource_err("SDMA base"); |
1982 | if (pi->mpsc_base) { | ||
1983 | iounmap(pi->mpsc_base); | ||
1984 | pi->mpsc_base = NULL; | ||
1985 | } | ||
1986 | goto err; | 1972 | goto err; |
1987 | } | 1973 | } |
1988 | 1974 | ||
@@ -1993,33 +1979,33 @@ static int mpsc_drv_map_regs(struct mpsc_port_info *pi, | |||
1993 | pi->brg_base_p = r->start; | 1979 | pi->brg_base_p = r->start; |
1994 | } else { | 1980 | } else { |
1995 | mpsc_resource_err("BRG base"); | 1981 | mpsc_resource_err("BRG base"); |
1996 | if (pi->mpsc_base) { | ||
1997 | iounmap(pi->mpsc_base); | ||
1998 | pi->mpsc_base = NULL; | ||
1999 | } | ||
2000 | if (pi->sdma_base) { | ||
2001 | iounmap(pi->sdma_base); | ||
2002 | pi->sdma_base = NULL; | ||
2003 | } | ||
2004 | goto err; | 1982 | goto err; |
2005 | } | 1983 | } |
2006 | return 0; | 1984 | return 0; |
2007 | 1985 | ||
2008 | err: | 1986 | err: |
1987 | if (pi->sdma_base) { | ||
1988 | iounmap(pi->sdma_base); | ||
1989 | pi->sdma_base = NULL; | ||
1990 | } | ||
1991 | if (pi->mpsc_base) { | ||
1992 | iounmap(pi->mpsc_base); | ||
1993 | pi->mpsc_base = NULL; | ||
1994 | } | ||
2009 | return -ENOMEM; | 1995 | return -ENOMEM; |
2010 | } | 1996 | } |
2011 | 1997 | ||
2012 | static void mpsc_drv_unmap_regs(struct mpsc_port_info *pi) | 1998 | static void mpsc_drv_unmap_regs(struct mpsc_port_info *pi) |
2013 | { | 1999 | { |
2014 | if (!pi->mpsc_base) { | 2000 | if (pi->mpsc_base) { |
2015 | iounmap(pi->mpsc_base); | 2001 | iounmap(pi->mpsc_base); |
2016 | release_mem_region(pi->mpsc_base_p, MPSC_REG_BLOCK_SIZE); | 2002 | release_mem_region(pi->mpsc_base_p, MPSC_REG_BLOCK_SIZE); |
2017 | } | 2003 | } |
2018 | if (!pi->sdma_base) { | 2004 | if (pi->sdma_base) { |
2019 | iounmap(pi->sdma_base); | 2005 | iounmap(pi->sdma_base); |
2020 | release_mem_region(pi->sdma_base_p, MPSC_SDMA_REG_BLOCK_SIZE); | 2006 | release_mem_region(pi->sdma_base_p, MPSC_SDMA_REG_BLOCK_SIZE); |
2021 | } | 2007 | } |
2022 | if (!pi->brg_base) { | 2008 | if (pi->brg_base) { |
2023 | iounmap(pi->brg_base); | 2009 | iounmap(pi->brg_base); |
2024 | release_mem_region(pi->brg_base_p, MPSC_BRG_REG_BLOCK_SIZE); | 2010 | release_mem_region(pi->brg_base_p, MPSC_BRG_REG_BLOCK_SIZE); |
2025 | } | 2011 | } |
@@ -2073,36 +2059,37 @@ static void mpsc_drv_get_platform_data(struct mpsc_port_info *pi, | |||
2073 | 2059 | ||
2074 | static int mpsc_drv_probe(struct platform_device *dev) | 2060 | static int mpsc_drv_probe(struct platform_device *dev) |
2075 | { | 2061 | { |
2076 | struct mpsc_port_info *pi; | 2062 | struct mpsc_port_info *pi; |
2077 | int rc = -ENODEV; | 2063 | int rc; |
2078 | 2064 | ||
2079 | pr_debug("mpsc_drv_probe: Adding MPSC %d\n", dev->id); | 2065 | dev_dbg(&dev->dev, "mpsc_drv_probe: Adding MPSC %d\n", dev->id); |
2080 | 2066 | ||
2081 | if (dev->id < MPSC_NUM_CTLRS) { | 2067 | if (dev->id >= MPSC_NUM_CTLRS) |
2082 | pi = &mpsc_ports[dev->id]; | 2068 | return -ENODEV; |
2083 | 2069 | ||
2084 | rc = mpsc_drv_map_regs(pi, dev); | 2070 | pi = &mpsc_ports[dev->id]; |
2085 | if (!rc) { | 2071 | |
2086 | mpsc_drv_get_platform_data(pi, dev, dev->id); | 2072 | rc = mpsc_drv_map_regs(pi, dev); |
2087 | pi->port.dev = &dev->dev; | 2073 | if (rc) |
2088 | 2074 | return rc; | |
2089 | rc = mpsc_make_ready(pi); | ||
2090 | if (!rc) { | ||
2091 | spin_lock_init(&pi->tx_lock); | ||
2092 | rc = uart_add_one_port(&mpsc_reg, &pi->port); | ||
2093 | if (!rc) { | ||
2094 | rc = 0; | ||
2095 | } else { | ||
2096 | mpsc_release_port((struct uart_port *) | ||
2097 | pi); | ||
2098 | mpsc_drv_unmap_regs(pi); | ||
2099 | } | ||
2100 | } else { | ||
2101 | mpsc_drv_unmap_regs(pi); | ||
2102 | } | ||
2103 | } | ||
2104 | } | ||
2105 | 2075 | ||
2076 | mpsc_drv_get_platform_data(pi, dev, dev->id); | ||
2077 | pi->port.dev = &dev->dev; | ||
2078 | |||
2079 | rc = mpsc_make_ready(pi); | ||
2080 | if (rc) | ||
2081 | goto err_unmap; | ||
2082 | |||
2083 | spin_lock_init(&pi->tx_lock); | ||
2084 | rc = uart_add_one_port(&mpsc_reg, &pi->port); | ||
2085 | if (rc) | ||
2086 | goto err_relport; | ||
2087 | |||
2088 | return 0; | ||
2089 | err_relport: | ||
2090 | mpsc_release_port(&pi->port); | ||
2091 | err_unmap: | ||
2092 | mpsc_drv_unmap_regs(pi); | ||
2106 | return rc; | 2093 | return rc; |
2107 | } | 2094 | } |
2108 | 2095 | ||
@@ -2124,19 +2111,22 @@ static int __init mpsc_drv_init(void) | |||
2124 | memset(&mpsc_shared_regs, 0, sizeof(mpsc_shared_regs)); | 2111 | memset(&mpsc_shared_regs, 0, sizeof(mpsc_shared_regs)); |
2125 | 2112 | ||
2126 | rc = uart_register_driver(&mpsc_reg); | 2113 | rc = uart_register_driver(&mpsc_reg); |
2127 | if (!rc) { | 2114 | if (rc) |
2128 | rc = platform_driver_register(&mpsc_shared_driver); | 2115 | return rc; |
2129 | if (!rc) { | 2116 | |
2130 | rc = platform_driver_register(&mpsc_driver); | 2117 | rc = platform_driver_register(&mpsc_shared_driver); |
2131 | if (rc) { | 2118 | if (rc) |
2132 | platform_driver_unregister(&mpsc_shared_driver); | 2119 | goto err_unreg_uart; |
2133 | uart_unregister_driver(&mpsc_reg); | ||
2134 | } | ||
2135 | } else { | ||
2136 | uart_unregister_driver(&mpsc_reg); | ||
2137 | } | ||
2138 | } | ||
2139 | 2120 | ||
2121 | rc = platform_driver_register(&mpsc_driver); | ||
2122 | if (rc) | ||
2123 | goto err_unreg_plat; | ||
2124 | |||
2125 | return 0; | ||
2126 | err_unreg_plat: | ||
2127 | platform_driver_unregister(&mpsc_shared_driver); | ||
2128 | err_unreg_uart: | ||
2129 | uart_unregister_driver(&mpsc_reg); | ||
2140 | return rc; | 2130 | return rc; |
2141 | } | 2131 | } |
2142 | device_initcall(mpsc_drv_init); | 2132 | device_initcall(mpsc_drv_init); |
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index dcde955475dc..96d3ce8dc2dc 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c | |||
@@ -1478,7 +1478,6 @@ msm_serial_early_console_setup(struct earlycon_device *device, const char *opt) | |||
1478 | device->con->write = msm_serial_early_write; | 1478 | device->con->write = msm_serial_early_write; |
1479 | return 0; | 1479 | return 0; |
1480 | } | 1480 | } |
1481 | EARLYCON_DECLARE(msm_serial, msm_serial_early_console_setup); | ||
1482 | OF_EARLYCON_DECLARE(msm_serial, "qcom,msm-uart", | 1481 | OF_EARLYCON_DECLARE(msm_serial, "qcom,msm-uart", |
1483 | msm_serial_early_console_setup); | 1482 | msm_serial_early_console_setup); |
1484 | 1483 | ||
@@ -1500,7 +1499,6 @@ msm_serial_early_console_setup_dm(struct earlycon_device *device, | |||
1500 | device->con->write = msm_serial_early_write_dm; | 1499 | device->con->write = msm_serial_early_write_dm; |
1501 | return 0; | 1500 | return 0; |
1502 | } | 1501 | } |
1503 | EARLYCON_DECLARE(msm_serial_dm, msm_serial_early_console_setup_dm); | ||
1504 | OF_EARLYCON_DECLARE(msm_serial_dm, "qcom,msm-uartdm", | 1502 | OF_EARLYCON_DECLARE(msm_serial_dm, "qcom,msm-uartdm", |
1505 | msm_serial_early_console_setup_dm); | 1503 | msm_serial_early_console_setup_dm); |
1506 | 1504 | ||
diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c new file mode 100644 index 000000000000..0ff27818bb87 --- /dev/null +++ b/drivers/tty/serial/mvebu-uart.c | |||
@@ -0,0 +1,650 @@ | |||
1 | /* | ||
2 | * *************************************************************************** | ||
3 | * Copyright (C) 2015 Marvell International Ltd. | ||
4 | * *************************************************************************** | ||
5 | * This program is free software: you can redistribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License as published by the Free | ||
7 | * Software Foundation, either version 2 of the License, or any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | * *************************************************************************** | ||
17 | */ | ||
18 | |||
19 | #include <linux/clk.h> | ||
20 | #include <linux/console.h> | ||
21 | #include <linux/delay.h> | ||
22 | #include <linux/device.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/io.h> | ||
25 | #include <linux/iopoll.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/of.h> | ||
28 | #include <linux/of_address.h> | ||
29 | #include <linux/of_device.h> | ||
30 | #include <linux/of_irq.h> | ||
31 | #include <linux/of_platform.h> | ||
32 | #include <linux/platform_device.h> | ||
33 | #include <linux/serial.h> | ||
34 | #include <linux/serial_core.h> | ||
35 | #include <linux/slab.h> | ||
36 | #include <linux/tty.h> | ||
37 | #include <linux/tty_flip.h> | ||
38 | |||
39 | /* Register Map */ | ||
40 | #define UART_RBR 0x00 | ||
41 | #define RBR_BRK_DET BIT(15) | ||
42 | #define RBR_FRM_ERR_DET BIT(14) | ||
43 | #define RBR_PAR_ERR_DET BIT(13) | ||
44 | #define RBR_OVR_ERR_DET BIT(12) | ||
45 | |||
46 | #define UART_TSH 0x04 | ||
47 | |||
48 | #define UART_CTRL 0x08 | ||
49 | #define CTRL_SOFT_RST BIT(31) | ||
50 | #define CTRL_TXFIFO_RST BIT(15) | ||
51 | #define CTRL_RXFIFO_RST BIT(14) | ||
52 | #define CTRL_ST_MIRR_EN BIT(13) | ||
53 | #define CTRL_LPBK_EN BIT(12) | ||
54 | #define CTRL_SND_BRK_SEQ BIT(11) | ||
55 | #define CTRL_PAR_EN BIT(10) | ||
56 | #define CTRL_TWO_STOP BIT(9) | ||
57 | #define CTRL_TX_HFL_INT BIT(8) | ||
58 | #define CTRL_RX_HFL_INT BIT(7) | ||
59 | #define CTRL_TX_EMP_INT BIT(6) | ||
60 | #define CTRL_TX_RDY_INT BIT(5) | ||
61 | #define CTRL_RX_RDY_INT BIT(4) | ||
62 | #define CTRL_BRK_DET_INT BIT(3) | ||
63 | #define CTRL_FRM_ERR_INT BIT(2) | ||
64 | #define CTRL_PAR_ERR_INT BIT(1) | ||
65 | #define CTRL_OVR_ERR_INT BIT(0) | ||
66 | #define CTRL_RX_INT (CTRL_RX_RDY_INT | CTRL_BRK_DET_INT |\ | ||
67 | CTRL_FRM_ERR_INT | CTRL_PAR_ERR_INT | CTRL_OVR_ERR_INT) | ||
68 | |||
69 | #define UART_STAT 0x0c | ||
70 | #define STAT_TX_FIFO_EMP BIT(13) | ||
71 | #define STAT_RX_FIFO_EMP BIT(12) | ||
72 | #define STAT_TX_FIFO_FUL BIT(11) | ||
73 | #define STAT_TX_FIFO_HFL BIT(10) | ||
74 | #define STAT_RX_TOGL BIT(9) | ||
75 | #define STAT_RX_FIFO_FUL BIT(8) | ||
76 | #define STAT_RX_FIFO_HFL BIT(7) | ||
77 | #define STAT_TX_EMP BIT(6) | ||
78 | #define STAT_TX_RDY BIT(5) | ||
79 | #define STAT_RX_RDY BIT(4) | ||
80 | #define STAT_BRK_DET BIT(3) | ||
81 | #define STAT_FRM_ERR BIT(2) | ||
82 | #define STAT_PAR_ERR BIT(1) | ||
83 | #define STAT_OVR_ERR BIT(0) | ||
84 | #define STAT_BRK_ERR (STAT_BRK_DET | STAT_FRM_ERR | STAT_FRM_ERR\ | ||
85 | | STAT_PAR_ERR | STAT_OVR_ERR) | ||
86 | |||
87 | #define UART_BRDV 0x10 | ||
88 | |||
89 | #define MVEBU_NR_UARTS 1 | ||
90 | |||
91 | #define MVEBU_UART_TYPE "mvebu-uart" | ||
92 | |||
93 | static struct uart_port mvebu_uart_ports[MVEBU_NR_UARTS]; | ||
94 | |||
95 | struct mvebu_uart_data { | ||
96 | struct uart_port *port; | ||
97 | struct clk *clk; | ||
98 | }; | ||
99 | |||
100 | /* Core UART Driver Operations */ | ||
101 | static unsigned int mvebu_uart_tx_empty(struct uart_port *port) | ||
102 | { | ||
103 | unsigned long flags; | ||
104 | unsigned int st; | ||
105 | |||
106 | spin_lock_irqsave(&port->lock, flags); | ||
107 | st = readl(port->membase + UART_STAT); | ||
108 | spin_unlock_irqrestore(&port->lock, flags); | ||
109 | |||
110 | return (st & STAT_TX_FIFO_EMP) ? TIOCSER_TEMT : 0; | ||
111 | } | ||
112 | |||
113 | static unsigned int mvebu_uart_get_mctrl(struct uart_port *port) | ||
114 | { | ||
115 | return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; | ||
116 | } | ||
117 | |||
118 | static void mvebu_uart_set_mctrl(struct uart_port *port, | ||
119 | unsigned int mctrl) | ||
120 | { | ||
121 | /* | ||
122 | * Even if we do not support configuring the modem control lines, this | ||
123 | * function must be proided to the serial core | ||
124 | */ | ||
125 | } | ||
126 | |||
127 | static void mvebu_uart_stop_tx(struct uart_port *port) | ||
128 | { | ||
129 | unsigned int ctl = readl(port->membase + UART_CTRL); | ||
130 | |||
131 | ctl &= ~CTRL_TX_RDY_INT; | ||
132 | writel(ctl, port->membase + UART_CTRL); | ||
133 | } | ||
134 | |||
135 | static void mvebu_uart_start_tx(struct uart_port *port) | ||
136 | { | ||
137 | unsigned int ctl = readl(port->membase + UART_CTRL); | ||
138 | |||
139 | ctl |= CTRL_TX_RDY_INT; | ||
140 | writel(ctl, port->membase + UART_CTRL); | ||
141 | } | ||
142 | |||
143 | static void mvebu_uart_stop_rx(struct uart_port *port) | ||
144 | { | ||
145 | unsigned int ctl = readl(port->membase + UART_CTRL); | ||
146 | |||
147 | ctl &= ~CTRL_RX_INT; | ||
148 | writel(ctl, port->membase + UART_CTRL); | ||
149 | } | ||
150 | |||
151 | static void mvebu_uart_break_ctl(struct uart_port *port, int brk) | ||
152 | { | ||
153 | unsigned int ctl; | ||
154 | unsigned long flags; | ||
155 | |||
156 | spin_lock_irqsave(&port->lock, flags); | ||
157 | ctl = readl(port->membase + UART_CTRL); | ||
158 | if (brk == -1) | ||
159 | ctl |= CTRL_SND_BRK_SEQ; | ||
160 | else | ||
161 | ctl &= ~CTRL_SND_BRK_SEQ; | ||
162 | writel(ctl, port->membase + UART_CTRL); | ||
163 | spin_unlock_irqrestore(&port->lock, flags); | ||
164 | } | ||
165 | |||
166 | static void mvebu_uart_rx_chars(struct uart_port *port, unsigned int status) | ||
167 | { | ||
168 | struct tty_port *tport = &port->state->port; | ||
169 | unsigned char ch = 0; | ||
170 | char flag = 0; | ||
171 | |||
172 | do { | ||
173 | if (status & STAT_RX_RDY) { | ||
174 | ch = readl(port->membase + UART_RBR); | ||
175 | ch &= 0xff; | ||
176 | flag = TTY_NORMAL; | ||
177 | port->icount.rx++; | ||
178 | |||
179 | if (status & STAT_PAR_ERR) | ||
180 | port->icount.parity++; | ||
181 | } | ||
182 | |||
183 | if (status & STAT_BRK_DET) { | ||
184 | port->icount.brk++; | ||
185 | status &= ~(STAT_FRM_ERR | STAT_PAR_ERR); | ||
186 | if (uart_handle_break(port)) | ||
187 | goto ignore_char; | ||
188 | } | ||
189 | |||
190 | if (status & STAT_OVR_ERR) | ||
191 | port->icount.overrun++; | ||
192 | |||
193 | if (status & STAT_FRM_ERR) | ||
194 | port->icount.frame++; | ||
195 | |||
196 | if (uart_handle_sysrq_char(port, ch)) | ||
197 | goto ignore_char; | ||
198 | |||
199 | if (status & port->ignore_status_mask & STAT_PAR_ERR) | ||
200 | status &= ~STAT_RX_RDY; | ||
201 | |||
202 | status &= port->read_status_mask; | ||
203 | |||
204 | if (status & STAT_PAR_ERR) | ||
205 | flag = TTY_PARITY; | ||
206 | |||
207 | status &= ~port->ignore_status_mask; | ||
208 | |||
209 | if (status & STAT_RX_RDY) | ||
210 | tty_insert_flip_char(tport, ch, flag); | ||
211 | |||
212 | if (status & STAT_BRK_DET) | ||
213 | tty_insert_flip_char(tport, 0, TTY_BREAK); | ||
214 | |||
215 | if (status & STAT_FRM_ERR) | ||
216 | tty_insert_flip_char(tport, 0, TTY_FRAME); | ||
217 | |||
218 | if (status & STAT_OVR_ERR) | ||
219 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); | ||
220 | |||
221 | ignore_char: | ||
222 | status = readl(port->membase + UART_STAT); | ||
223 | } while (status & (STAT_RX_RDY | STAT_BRK_DET)); | ||
224 | |||
225 | tty_flip_buffer_push(tport); | ||
226 | } | ||
227 | |||
228 | static void mvebu_uart_tx_chars(struct uart_port *port, unsigned int status) | ||
229 | { | ||
230 | struct circ_buf *xmit = &port->state->xmit; | ||
231 | unsigned int count; | ||
232 | unsigned int st; | ||
233 | |||
234 | if (port->x_char) { | ||
235 | writel(port->x_char, port->membase + UART_TSH); | ||
236 | port->icount.tx++; | ||
237 | port->x_char = 0; | ||
238 | return; | ||
239 | } | ||
240 | |||
241 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { | ||
242 | mvebu_uart_stop_tx(port); | ||
243 | return; | ||
244 | } | ||
245 | |||
246 | for (count = 0; count < port->fifosize; count++) { | ||
247 | writel(xmit->buf[xmit->tail], port->membase + UART_TSH); | ||
248 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
249 | port->icount.tx++; | ||
250 | |||
251 | if (uart_circ_empty(xmit)) | ||
252 | break; | ||
253 | |||
254 | st = readl(port->membase + UART_STAT); | ||
255 | if (st & STAT_TX_FIFO_FUL) | ||
256 | break; | ||
257 | } | ||
258 | |||
259 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
260 | uart_write_wakeup(port); | ||
261 | |||
262 | if (uart_circ_empty(xmit)) | ||
263 | mvebu_uart_stop_tx(port); | ||
264 | } | ||
265 | |||
266 | static irqreturn_t mvebu_uart_isr(int irq, void *dev_id) | ||
267 | { | ||
268 | struct uart_port *port = (struct uart_port *)dev_id; | ||
269 | unsigned int st = readl(port->membase + UART_STAT); | ||
270 | |||
271 | if (st & (STAT_RX_RDY | STAT_OVR_ERR | STAT_FRM_ERR | STAT_BRK_DET)) | ||
272 | mvebu_uart_rx_chars(port, st); | ||
273 | |||
274 | if (st & STAT_TX_RDY) | ||
275 | mvebu_uart_tx_chars(port, st); | ||
276 | |||
277 | return IRQ_HANDLED; | ||
278 | } | ||
279 | |||
280 | static int mvebu_uart_startup(struct uart_port *port) | ||
281 | { | ||
282 | int ret; | ||
283 | |||
284 | writel(CTRL_TXFIFO_RST | CTRL_RXFIFO_RST, | ||
285 | port->membase + UART_CTRL); | ||
286 | udelay(1); | ||
287 | writel(CTRL_RX_INT, port->membase + UART_CTRL); | ||
288 | |||
289 | ret = request_irq(port->irq, mvebu_uart_isr, port->irqflags, "serial", | ||
290 | port); | ||
291 | if (ret) { | ||
292 | dev_err(port->dev, "failed to request irq\n"); | ||
293 | return ret; | ||
294 | } | ||
295 | |||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | static void mvebu_uart_shutdown(struct uart_port *port) | ||
300 | { | ||
301 | writel(0, port->membase + UART_CTRL); | ||
302 | } | ||
303 | |||
304 | static void mvebu_uart_set_termios(struct uart_port *port, | ||
305 | struct ktermios *termios, | ||
306 | struct ktermios *old) | ||
307 | { | ||
308 | unsigned long flags; | ||
309 | unsigned int baud; | ||
310 | |||
311 | spin_lock_irqsave(&port->lock, flags); | ||
312 | |||
313 | port->read_status_mask = STAT_RX_RDY | STAT_OVR_ERR | | ||
314 | STAT_TX_RDY | STAT_TX_FIFO_FUL; | ||
315 | |||
316 | if (termios->c_iflag & INPCK) | ||
317 | port->read_status_mask |= STAT_FRM_ERR | STAT_PAR_ERR; | ||
318 | |||
319 | port->ignore_status_mask = 0; | ||
320 | if (termios->c_iflag & IGNPAR) | ||
321 | port->ignore_status_mask |= | ||
322 | STAT_FRM_ERR | STAT_PAR_ERR | STAT_OVR_ERR; | ||
323 | |||
324 | if ((termios->c_cflag & CREAD) == 0) | ||
325 | port->ignore_status_mask |= STAT_RX_RDY | STAT_BRK_ERR; | ||
326 | |||
327 | if (old) | ||
328 | tty_termios_copy_hw(termios, old); | ||
329 | |||
330 | baud = uart_get_baud_rate(port, termios, old, 0, 460800); | ||
331 | uart_update_timeout(port, termios->c_cflag, baud); | ||
332 | |||
333 | spin_unlock_irqrestore(&port->lock, flags); | ||
334 | } | ||
335 | |||
336 | static const char *mvebu_uart_type(struct uart_port *port) | ||
337 | { | ||
338 | return MVEBU_UART_TYPE; | ||
339 | } | ||
340 | |||
341 | static void mvebu_uart_release_port(struct uart_port *port) | ||
342 | { | ||
343 | /* Nothing to do here */ | ||
344 | } | ||
345 | |||
346 | static int mvebu_uart_request_port(struct uart_port *port) | ||
347 | { | ||
348 | return 0; | ||
349 | } | ||
350 | |||
351 | #ifdef CONFIG_CONSOLE_POLL | ||
352 | static int mvebu_uart_get_poll_char(struct uart_port *port) | ||
353 | { | ||
354 | unsigned int st = readl(port->membase + UART_STAT); | ||
355 | |||
356 | if (!(st & STAT_RX_RDY)) | ||
357 | return NO_POLL_CHAR; | ||
358 | |||
359 | return readl(port->membase + UART_RBR); | ||
360 | } | ||
361 | |||
362 | static void mvebu_uart_put_poll_char(struct uart_port *port, unsigned char c) | ||
363 | { | ||
364 | unsigned int st; | ||
365 | |||
366 | for (;;) { | ||
367 | st = readl(port->membase + UART_STAT); | ||
368 | |||
369 | if (!(st & STAT_TX_FIFO_FUL)) | ||
370 | break; | ||
371 | |||
372 | udelay(1); | ||
373 | } | ||
374 | |||
375 | writel(c, port->membase + UART_TSH); | ||
376 | } | ||
377 | #endif | ||
378 | |||
379 | static const struct uart_ops mvebu_uart_ops = { | ||
380 | .tx_empty = mvebu_uart_tx_empty, | ||
381 | .set_mctrl = mvebu_uart_set_mctrl, | ||
382 | .get_mctrl = mvebu_uart_get_mctrl, | ||
383 | .stop_tx = mvebu_uart_stop_tx, | ||
384 | .start_tx = mvebu_uart_start_tx, | ||
385 | .stop_rx = mvebu_uart_stop_rx, | ||
386 | .break_ctl = mvebu_uart_break_ctl, | ||
387 | .startup = mvebu_uart_startup, | ||
388 | .shutdown = mvebu_uart_shutdown, | ||
389 | .set_termios = mvebu_uart_set_termios, | ||
390 | .type = mvebu_uart_type, | ||
391 | .release_port = mvebu_uart_release_port, | ||
392 | .request_port = mvebu_uart_request_port, | ||
393 | #ifdef CONFIG_CONSOLE_POLL | ||
394 | .poll_get_char = mvebu_uart_get_poll_char, | ||
395 | .poll_put_char = mvebu_uart_put_poll_char, | ||
396 | #endif | ||
397 | }; | ||
398 | |||
399 | /* Console Driver Operations */ | ||
400 | |||
401 | #ifdef CONFIG_SERIAL_MVEBU_CONSOLE | ||
402 | /* Early Console */ | ||
403 | static void mvebu_uart_putc(struct uart_port *port, int c) | ||
404 | { | ||
405 | unsigned int st; | ||
406 | |||
407 | for (;;) { | ||
408 | st = readl(port->membase + UART_STAT); | ||
409 | if (!(st & STAT_TX_FIFO_FUL)) | ||
410 | break; | ||
411 | } | ||
412 | |||
413 | writel(c, port->membase + UART_TSH); | ||
414 | |||
415 | for (;;) { | ||
416 | st = readl(port->membase + UART_STAT); | ||
417 | if (st & STAT_TX_FIFO_EMP) | ||
418 | break; | ||
419 | } | ||
420 | } | ||
421 | |||
422 | static void mvebu_uart_putc_early_write(struct console *con, | ||
423 | const char *s, | ||
424 | unsigned n) | ||
425 | { | ||
426 | struct earlycon_device *dev = con->data; | ||
427 | |||
428 | uart_console_write(&dev->port, s, n, mvebu_uart_putc); | ||
429 | } | ||
430 | |||
431 | static int __init | ||
432 | mvebu_uart_early_console_setup(struct earlycon_device *device, | ||
433 | const char *opt) | ||
434 | { | ||
435 | if (!device->port.membase) | ||
436 | return -ENODEV; | ||
437 | |||
438 | device->con->write = mvebu_uart_putc_early_write; | ||
439 | |||
440 | return 0; | ||
441 | } | ||
442 | |||
443 | EARLYCON_DECLARE(ar3700_uart, mvebu_uart_early_console_setup); | ||
444 | OF_EARLYCON_DECLARE(ar3700_uart, "marvell,armada-3700-uart", | ||
445 | mvebu_uart_early_console_setup); | ||
446 | |||
447 | static void wait_for_xmitr(struct uart_port *port) | ||
448 | { | ||
449 | u32 val; | ||
450 | |||
451 | readl_poll_timeout_atomic(port->membase + UART_STAT, val, | ||
452 | (val & STAT_TX_EMP), 1, 10000); | ||
453 | } | ||
454 | |||
455 | static void mvebu_uart_console_putchar(struct uart_port *port, int ch) | ||
456 | { | ||
457 | wait_for_xmitr(port); | ||
458 | writel(ch, port->membase + UART_TSH); | ||
459 | } | ||
460 | |||
461 | static void mvebu_uart_console_write(struct console *co, const char *s, | ||
462 | unsigned int count) | ||
463 | { | ||
464 | struct uart_port *port = &mvebu_uart_ports[co->index]; | ||
465 | unsigned long flags; | ||
466 | unsigned int ier; | ||
467 | int locked = 1; | ||
468 | |||
469 | if (oops_in_progress) | ||
470 | locked = spin_trylock_irqsave(&port->lock, flags); | ||
471 | else | ||
472 | spin_lock_irqsave(&port->lock, flags); | ||
473 | |||
474 | ier = readl(port->membase + UART_CTRL) & | ||
475 | (CTRL_RX_INT | CTRL_TX_RDY_INT); | ||
476 | writel(0, port->membase + UART_CTRL); | ||
477 | |||
478 | uart_console_write(port, s, count, mvebu_uart_console_putchar); | ||
479 | |||
480 | wait_for_xmitr(port); | ||
481 | |||
482 | if (ier) | ||
483 | writel(ier, port->membase + UART_CTRL); | ||
484 | |||
485 | if (locked) | ||
486 | spin_unlock_irqrestore(&port->lock, flags); | ||
487 | } | ||
488 | |||
489 | static int mvebu_uart_console_setup(struct console *co, char *options) | ||
490 | { | ||
491 | struct uart_port *port; | ||
492 | int baud = 9600; | ||
493 | int bits = 8; | ||
494 | int parity = 'n'; | ||
495 | int flow = 'n'; | ||
496 | |||
497 | if (co->index < 0 || co->index >= MVEBU_NR_UARTS) | ||
498 | return -EINVAL; | ||
499 | |||
500 | port = &mvebu_uart_ports[co->index]; | ||
501 | |||
502 | if (!port->mapbase || !port->membase) { | ||
503 | pr_debug("console on ttyMV%i not present\n", co->index); | ||
504 | return -ENODEV; | ||
505 | } | ||
506 | |||
507 | if (options) | ||
508 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
509 | |||
510 | return uart_set_options(port, co, baud, parity, bits, flow); | ||
511 | } | ||
512 | |||
513 | static struct uart_driver mvebu_uart_driver; | ||
514 | |||
515 | static struct console mvebu_uart_console = { | ||
516 | .name = "ttyMV", | ||
517 | .write = mvebu_uart_console_write, | ||
518 | .device = uart_console_device, | ||
519 | .setup = mvebu_uart_console_setup, | ||
520 | .flags = CON_PRINTBUFFER, | ||
521 | .index = -1, | ||
522 | .data = &mvebu_uart_driver, | ||
523 | }; | ||
524 | |||
525 | static int __init mvebu_uart_console_init(void) | ||
526 | { | ||
527 | register_console(&mvebu_uart_console); | ||
528 | return 0; | ||
529 | } | ||
530 | |||
531 | console_initcall(mvebu_uart_console_init); | ||
532 | |||
533 | |||
534 | #endif /* CONFIG_SERIAL_MVEBU_CONSOLE */ | ||
535 | |||
536 | static struct uart_driver mvebu_uart_driver = { | ||
537 | .owner = THIS_MODULE, | ||
538 | .driver_name = "mvebu_serial", | ||
539 | .dev_name = "ttyMV", | ||
540 | .nr = MVEBU_NR_UARTS, | ||
541 | #ifdef CONFIG_SERIAL_MVEBU_CONSOLE | ||
542 | .cons = &mvebu_uart_console, | ||
543 | #endif | ||
544 | }; | ||
545 | |||
546 | static int mvebu_uart_probe(struct platform_device *pdev) | ||
547 | { | ||
548 | struct resource *reg = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
549 | struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
550 | struct uart_port *port; | ||
551 | struct mvebu_uart_data *data; | ||
552 | int ret; | ||
553 | |||
554 | if (!reg || !irq) { | ||
555 | dev_err(&pdev->dev, "no registers/irq defined\n"); | ||
556 | return -EINVAL; | ||
557 | } | ||
558 | |||
559 | port = &mvebu_uart_ports[0]; | ||
560 | |||
561 | spin_lock_init(&port->lock); | ||
562 | |||
563 | port->dev = &pdev->dev; | ||
564 | port->type = PORT_MVEBU; | ||
565 | port->ops = &mvebu_uart_ops; | ||
566 | port->regshift = 0; | ||
567 | |||
568 | port->fifosize = 32; | ||
569 | port->iotype = UPIO_MEM32; | ||
570 | port->flags = UPF_FIXED_PORT; | ||
571 | port->line = 0; /* single port: force line number to 0 */ | ||
572 | |||
573 | port->irq = irq->start; | ||
574 | port->irqflags = 0; | ||
575 | port->mapbase = reg->start; | ||
576 | |||
577 | port->membase = devm_ioremap_resource(&pdev->dev, reg); | ||
578 | if (IS_ERR(port->membase)) | ||
579 | return -PTR_ERR(port->membase); | ||
580 | |||
581 | data = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_uart_data), | ||
582 | GFP_KERNEL); | ||
583 | if (!data) | ||
584 | return -ENOMEM; | ||
585 | |||
586 | data->port = port; | ||
587 | |||
588 | port->private_data = data; | ||
589 | platform_set_drvdata(pdev, data); | ||
590 | |||
591 | ret = uart_add_one_port(&mvebu_uart_driver, port); | ||
592 | if (ret) | ||
593 | return ret; | ||
594 | return 0; | ||
595 | } | ||
596 | |||
597 | static int mvebu_uart_remove(struct platform_device *pdev) | ||
598 | { | ||
599 | struct mvebu_uart_data *data = platform_get_drvdata(pdev); | ||
600 | |||
601 | uart_remove_one_port(&mvebu_uart_driver, data->port); | ||
602 | data->port->private_data = NULL; | ||
603 | data->port->mapbase = 0; | ||
604 | return 0; | ||
605 | } | ||
606 | |||
607 | /* Match table for of_platform binding */ | ||
608 | static const struct of_device_id mvebu_uart_of_match[] = { | ||
609 | { .compatible = "marvell,armada-3700-uart", }, | ||
610 | {} | ||
611 | }; | ||
612 | MODULE_DEVICE_TABLE(of, mvebu_uart_of_match); | ||
613 | |||
614 | static struct platform_driver mvebu_uart_platform_driver = { | ||
615 | .probe = mvebu_uart_probe, | ||
616 | .remove = mvebu_uart_remove, | ||
617 | .driver = { | ||
618 | .owner = THIS_MODULE, | ||
619 | .name = "mvebu-uart", | ||
620 | .of_match_table = of_match_ptr(mvebu_uart_of_match), | ||
621 | }, | ||
622 | }; | ||
623 | |||
624 | static int __init mvebu_uart_init(void) | ||
625 | { | ||
626 | int ret; | ||
627 | |||
628 | ret = uart_register_driver(&mvebu_uart_driver); | ||
629 | if (ret) | ||
630 | return ret; | ||
631 | |||
632 | ret = platform_driver_register(&mvebu_uart_platform_driver); | ||
633 | if (ret) | ||
634 | uart_unregister_driver(&mvebu_uart_driver); | ||
635 | |||
636 | return ret; | ||
637 | } | ||
638 | |||
639 | static void __exit mvebu_uart_exit(void) | ||
640 | { | ||
641 | platform_driver_unregister(&mvebu_uart_platform_driver); | ||
642 | uart_unregister_driver(&mvebu_uart_driver); | ||
643 | } | ||
644 | |||
645 | arch_initcall(mvebu_uart_init); | ||
646 | module_exit(mvebu_uart_exit); | ||
647 | |||
648 | MODULE_AUTHOR("Wilson Ding <dingwei@marvell.com>"); | ||
649 | MODULE_DESCRIPTION("Marvell Armada-3700 Serial Driver"); | ||
650 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index fa49eb1e2fa2..a2a529994ba5 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c | |||
@@ -1870,7 +1870,7 @@ static struct platform_driver serial_omap_driver = { | |||
1870 | .probe = serial_omap_probe, | 1870 | .probe = serial_omap_probe, |
1871 | .remove = serial_omap_remove, | 1871 | .remove = serial_omap_remove, |
1872 | .driver = { | 1872 | .driver = { |
1873 | .name = DRIVER_NAME, | 1873 | .name = OMAP_SERIAL_DRIVER_NAME, |
1874 | .pm = &serial_omap_dev_pm_ops, | 1874 | .pm = &serial_omap_dev_pm_ops, |
1875 | .of_match_table = of_match_ptr(omap_serial_of_match), | 1875 | .of_match_table = of_match_ptr(omap_serial_of_match), |
1876 | }, | 1876 | }, |
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index d72cd736bdc6..ac7f8df54406 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c | |||
@@ -601,14 +601,21 @@ static void s3c24xx_serial_rx_drain_fifo(struct s3c24xx_uart_port *ourport) | |||
601 | { | 601 | { |
602 | struct uart_port *port = &ourport->port; | 602 | struct uart_port *port = &ourport->port; |
603 | unsigned int ufcon, ch, flag, ufstat, uerstat; | 603 | unsigned int ufcon, ch, flag, ufstat, uerstat; |
604 | unsigned int fifocnt = 0; | ||
604 | int max_count = port->fifosize; | 605 | int max_count = port->fifosize; |
605 | 606 | ||
606 | while (max_count-- > 0) { | 607 | while (max_count-- > 0) { |
607 | ufcon = rd_regl(port, S3C2410_UFCON); | 608 | /* |
608 | ufstat = rd_regl(port, S3C2410_UFSTAT); | 609 | * Receive all characters known to be in FIFO |
609 | 610 | * before reading FIFO level again | |
610 | if (s3c24xx_serial_rx_fifocnt(ourport, ufstat) == 0) | 611 | */ |
611 | break; | 612 | if (fifocnt == 0) { |
613 | ufstat = rd_regl(port, S3C2410_UFSTAT); | ||
614 | fifocnt = s3c24xx_serial_rx_fifocnt(ourport, ufstat); | ||
615 | if (fifocnt == 0) | ||
616 | break; | ||
617 | } | ||
618 | fifocnt--; | ||
612 | 619 | ||
613 | uerstat = rd_regl(port, S3C2410_UERSTAT); | 620 | uerstat = rd_regl(port, S3C2410_UERSTAT); |
614 | ch = rd_regb(port, S3C2410_URXH); | 621 | ch = rd_regb(port, S3C2410_URXH); |
@@ -623,6 +630,7 @@ static void s3c24xx_serial_rx_drain_fifo(struct s3c24xx_uart_port *ourport) | |||
623 | } | 630 | } |
624 | } else { | 631 | } else { |
625 | if (txe) { | 632 | if (txe) { |
633 | ufcon = rd_regl(port, S3C2410_UFCON); | ||
626 | ufcon |= S3C2410_UFCON_RESETRX; | 634 | ufcon |= S3C2410_UFCON_RESETRX; |
627 | wr_regl(port, S3C2410_UFCON, ufcon); | 635 | wr_regl(port, S3C2410_UFCON, ufcon); |
628 | rx_enabled(port) = 1; | 636 | rx_enabled(port) = 1; |
@@ -2451,7 +2459,6 @@ static int __init s3c2410_early_console_setup(struct earlycon_device *device, | |||
2451 | } | 2459 | } |
2452 | OF_EARLYCON_DECLARE(s3c2410, "samsung,s3c2410-uart", | 2460 | OF_EARLYCON_DECLARE(s3c2410, "samsung,s3c2410-uart", |
2453 | s3c2410_early_console_setup); | 2461 | s3c2410_early_console_setup); |
2454 | EARLYCON_DECLARE(s3c2410, s3c2410_early_console_setup); | ||
2455 | 2462 | ||
2456 | /* S3C2412, S3C2440, S3C64xx */ | 2463 | /* S3C2412, S3C2440, S3C64xx */ |
2457 | static struct samsung_early_console_data s3c2440_early_console_data = { | 2464 | static struct samsung_early_console_data s3c2440_early_console_data = { |
@@ -2470,9 +2477,6 @@ OF_EARLYCON_DECLARE(s3c2440, "samsung,s3c2440-uart", | |||
2470 | s3c2440_early_console_setup); | 2477 | s3c2440_early_console_setup); |
2471 | OF_EARLYCON_DECLARE(s3c6400, "samsung,s3c6400-uart", | 2478 | OF_EARLYCON_DECLARE(s3c6400, "samsung,s3c6400-uart", |
2472 | s3c2440_early_console_setup); | 2479 | s3c2440_early_console_setup); |
2473 | EARLYCON_DECLARE(s3c2412, s3c2440_early_console_setup); | ||
2474 | EARLYCON_DECLARE(s3c2440, s3c2440_early_console_setup); | ||
2475 | EARLYCON_DECLARE(s3c6400, s3c2440_early_console_setup); | ||
2476 | 2480 | ||
2477 | /* S5PV210, EXYNOS */ | 2481 | /* S5PV210, EXYNOS */ |
2478 | static struct samsung_early_console_data s5pv210_early_console_data = { | 2482 | static struct samsung_early_console_data s5pv210_early_console_data = { |
@@ -2489,8 +2493,6 @@ OF_EARLYCON_DECLARE(s5pv210, "samsung,s5pv210-uart", | |||
2489 | s5pv210_early_console_setup); | 2493 | s5pv210_early_console_setup); |
2490 | OF_EARLYCON_DECLARE(exynos4210, "samsung,exynos4210-uart", | 2494 | OF_EARLYCON_DECLARE(exynos4210, "samsung,exynos4210-uart", |
2491 | s5pv210_early_console_setup); | 2495 | s5pv210_early_console_setup); |
2492 | EARLYCON_DECLARE(s5pv210, s5pv210_early_console_setup); | ||
2493 | EARLYCON_DECLARE(exynos4210, s5pv210_early_console_setup); | ||
2494 | #endif | 2496 | #endif |
2495 | 2497 | ||
2496 | MODULE_ALIAS("platform:samsung-uart"); | 2498 | MODULE_ALIAS("platform:samsung-uart"); |
diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c index 13f8d5f70272..025a4264430e 100644 --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c | |||
@@ -196,14 +196,14 @@ | |||
196 | * or (IO6) | 196 | * or (IO6) |
197 | * - only on 75x/76x | 197 | * - only on 75x/76x |
198 | */ | 198 | */ |
199 | #define SC16IS7XX_MSR_CTS_BIT (1 << 0) /* CTS */ | 199 | #define SC16IS7XX_MSR_CTS_BIT (1 << 4) /* CTS */ |
200 | #define SC16IS7XX_MSR_DSR_BIT (1 << 1) /* DSR (IO4) | 200 | #define SC16IS7XX_MSR_DSR_BIT (1 << 5) /* DSR (IO4) |
201 | * - only on 75x/76x | 201 | * - only on 75x/76x |
202 | */ | 202 | */ |
203 | #define SC16IS7XX_MSR_RI_BIT (1 << 2) /* RI (IO7) | 203 | #define SC16IS7XX_MSR_RI_BIT (1 << 6) /* RI (IO7) |
204 | * - only on 75x/76x | 204 | * - only on 75x/76x |
205 | */ | 205 | */ |
206 | #define SC16IS7XX_MSR_CD_BIT (1 << 3) /* CD (IO6) | 206 | #define SC16IS7XX_MSR_CD_BIT (1 << 7) /* CD (IO6) |
207 | * - only on 75x/76x | 207 | * - only on 75x/76x |
208 | */ | 208 | */ |
209 | #define SC16IS7XX_MSR_DELTA_MASK 0x0F /* Any of the delta bits! */ | 209 | #define SC16IS7XX_MSR_DELTA_MASK 0x0F /* Any of the delta bits! */ |
@@ -240,7 +240,7 @@ | |||
240 | 240 | ||
241 | /* IOControl register bits (Only 750/760) */ | 241 | /* IOControl register bits (Only 750/760) */ |
242 | #define SC16IS7XX_IOCONTROL_LATCH_BIT (1 << 0) /* Enable input latching */ | 242 | #define SC16IS7XX_IOCONTROL_LATCH_BIT (1 << 0) /* Enable input latching */ |
243 | #define SC16IS7XX_IOCONTROL_GPIO_BIT (1 << 1) /* Enable GPIO[7:4] */ | 243 | #define SC16IS7XX_IOCONTROL_MODEM_BIT (1 << 1) /* Enable GPIO[7:4] as modem pins */ |
244 | #define SC16IS7XX_IOCONTROL_SRESET_BIT (1 << 3) /* Software Reset */ | 244 | #define SC16IS7XX_IOCONTROL_SRESET_BIT (1 << 3) /* Software Reset */ |
245 | 245 | ||
246 | /* EFCR register bits */ | 246 | /* EFCR register bits */ |
@@ -687,7 +687,7 @@ static void sc16is7xx_port_irq(struct sc16is7xx_port *s, int portno) | |||
687 | case SC16IS7XX_IIR_CTSRTS_SRC: | 687 | case SC16IS7XX_IIR_CTSRTS_SRC: |
688 | msr = sc16is7xx_port_read(port, SC16IS7XX_MSR_REG); | 688 | msr = sc16is7xx_port_read(port, SC16IS7XX_MSR_REG); |
689 | uart_handle_cts_change(port, | 689 | uart_handle_cts_change(port, |
690 | !!(msr & SC16IS7XX_MSR_CTS_BIT)); | 690 | !!(msr & SC16IS7XX_MSR_DCTS_BIT)); |
691 | break; | 691 | break; |
692 | case SC16IS7XX_IIR_THRI_SRC: | 692 | case SC16IS7XX_IIR_THRI_SRC: |
693 | sc16is7xx_handle_tx(port); | 693 | sc16is7xx_handle_tx(port); |
@@ -761,12 +761,20 @@ static void sc16is7xx_reg_proc(struct kthread_work *ws) | |||
761 | memset(&one->config, 0, sizeof(one->config)); | 761 | memset(&one->config, 0, sizeof(one->config)); |
762 | spin_unlock_irqrestore(&one->port.lock, irqflags); | 762 | spin_unlock_irqrestore(&one->port.lock, irqflags); |
763 | 763 | ||
764 | if (config.flags & SC16IS7XX_RECONF_MD) | 764 | if (config.flags & SC16IS7XX_RECONF_MD) { |
765 | sc16is7xx_port_update(&one->port, SC16IS7XX_MCR_REG, | 765 | sc16is7xx_port_update(&one->port, SC16IS7XX_MCR_REG, |
766 | SC16IS7XX_MCR_LOOP_BIT, | 766 | SC16IS7XX_MCR_LOOP_BIT, |
767 | (one->port.mctrl & TIOCM_LOOP) ? | 767 | (one->port.mctrl & TIOCM_LOOP) ? |
768 | SC16IS7XX_MCR_LOOP_BIT : 0); | 768 | SC16IS7XX_MCR_LOOP_BIT : 0); |
769 | 769 | sc16is7xx_port_update(&one->port, SC16IS7XX_MCR_REG, | |
770 | SC16IS7XX_MCR_RTS_BIT, | ||
771 | (one->port.mctrl & TIOCM_RTS) ? | ||
772 | SC16IS7XX_MCR_RTS_BIT : 0); | ||
773 | sc16is7xx_port_update(&one->port, SC16IS7XX_MCR_REG, | ||
774 | SC16IS7XX_MCR_DTR_BIT, | ||
775 | (one->port.mctrl & TIOCM_DTR) ? | ||
776 | SC16IS7XX_MCR_DTR_BIT : 0); | ||
777 | } | ||
770 | if (config.flags & SC16IS7XX_RECONF_IER) | 778 | if (config.flags & SC16IS7XX_RECONF_IER) |
771 | sc16is7xx_port_update(&one->port, SC16IS7XX_IER_REG, | 779 | sc16is7xx_port_update(&one->port, SC16IS7XX_IER_REG, |
772 | config.ier_clear, 0); | 780 | config.ier_clear, 0); |
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index b1f54ab1818c..a126a603b083 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c | |||
@@ -171,14 +171,12 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state, | |||
171 | */ | 171 | */ |
172 | uart_change_speed(tty, state, NULL); | 172 | uart_change_speed(tty, state, NULL); |
173 | 173 | ||
174 | if (init_hw) { | 174 | /* |
175 | /* | 175 | * Setup the RTS and DTR signals once the |
176 | * Setup the RTS and DTR signals once the | 176 | * port is open and ready to respond. |
177 | * port is open and ready to respond. | 177 | */ |
178 | */ | 178 | if (init_hw && C_BAUD(tty)) |
179 | if (tty->termios.c_cflag & CBAUD) | 179 | uart_set_mctrl(uport, TIOCM_RTS | TIOCM_DTR); |
180 | uart_set_mctrl(uport, TIOCM_RTS | TIOCM_DTR); | ||
181 | } | ||
182 | } | 180 | } |
183 | 181 | ||
184 | /* | 182 | /* |
@@ -240,7 +238,7 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state) | |||
240 | if (uart_console(uport) && tty) | 238 | if (uart_console(uport) && tty) |
241 | uport->cons->cflag = tty->termios.c_cflag; | 239 | uport->cons->cflag = tty->termios.c_cflag; |
242 | 240 | ||
243 | if (!tty || (tty->termios.c_cflag & HUPCL)) | 241 | if (!tty || C_HUPCL(tty)) |
244 | uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS); | 242 | uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS); |
245 | 243 | ||
246 | uart_port_shutdown(port); | 244 | uart_port_shutdown(port); |
@@ -485,12 +483,15 @@ static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, | |||
485 | spin_unlock_irq(&uport->lock); | 483 | spin_unlock_irq(&uport->lock); |
486 | } | 484 | } |
487 | 485 | ||
488 | static inline int __uart_put_char(struct uart_port *port, | 486 | static int uart_put_char(struct tty_struct *tty, unsigned char c) |
489 | struct circ_buf *circ, unsigned char c) | ||
490 | { | 487 | { |
488 | struct uart_state *state = tty->driver_data; | ||
489 | struct uart_port *port = state->uart_port; | ||
490 | struct circ_buf *circ; | ||
491 | unsigned long flags; | 491 | unsigned long flags; |
492 | int ret = 0; | 492 | int ret = 0; |
493 | 493 | ||
494 | circ = &state->xmit; | ||
494 | if (!circ->buf) | 495 | if (!circ->buf) |
495 | return 0; | 496 | return 0; |
496 | 497 | ||
@@ -504,13 +505,6 @@ static inline int __uart_put_char(struct uart_port *port, | |||
504 | return ret; | 505 | return ret; |
505 | } | 506 | } |
506 | 507 | ||
507 | static int uart_put_char(struct tty_struct *tty, unsigned char ch) | ||
508 | { | ||
509 | struct uart_state *state = tty->driver_data; | ||
510 | |||
511 | return __uart_put_char(state->uart_port, &state->xmit, ch); | ||
512 | } | ||
513 | |||
514 | static void uart_flush_chars(struct tty_struct *tty) | 508 | static void uart_flush_chars(struct tty_struct *tty) |
515 | { | 509 | { |
516 | uart_start(tty); | 510 | uart_start(tty); |
@@ -639,7 +633,7 @@ static void uart_throttle(struct tty_struct *tty) | |||
639 | 633 | ||
640 | if (I_IXOFF(tty)) | 634 | if (I_IXOFF(tty)) |
641 | mask |= UPSTAT_AUTOXOFF; | 635 | mask |= UPSTAT_AUTOXOFF; |
642 | if (tty->termios.c_cflag & CRTSCTS) | 636 | if (C_CRTSCTS(tty)) |
643 | mask |= UPSTAT_AUTORTS; | 637 | mask |= UPSTAT_AUTORTS; |
644 | 638 | ||
645 | if (port->status & mask) { | 639 | if (port->status & mask) { |
@@ -647,11 +641,11 @@ static void uart_throttle(struct tty_struct *tty) | |||
647 | mask &= ~port->status; | 641 | mask &= ~port->status; |
648 | } | 642 | } |
649 | 643 | ||
650 | if (mask & UPSTAT_AUTOXOFF) | ||
651 | uart_send_xchar(tty, STOP_CHAR(tty)); | ||
652 | |||
653 | if (mask & UPSTAT_AUTORTS) | 644 | if (mask & UPSTAT_AUTORTS) |
654 | uart_clear_mctrl(port, TIOCM_RTS); | 645 | uart_clear_mctrl(port, TIOCM_RTS); |
646 | |||
647 | if (mask & UPSTAT_AUTOXOFF) | ||
648 | uart_send_xchar(tty, STOP_CHAR(tty)); | ||
655 | } | 649 | } |
656 | 650 | ||
657 | static void uart_unthrottle(struct tty_struct *tty) | 651 | static void uart_unthrottle(struct tty_struct *tty) |
@@ -662,7 +656,7 @@ static void uart_unthrottle(struct tty_struct *tty) | |||
662 | 656 | ||
663 | if (I_IXOFF(tty)) | 657 | if (I_IXOFF(tty)) |
664 | mask |= UPSTAT_AUTOXOFF; | 658 | mask |= UPSTAT_AUTOXOFF; |
665 | if (tty->termios.c_cflag & CRTSCTS) | 659 | if (C_CRTSCTS(tty)) |
666 | mask |= UPSTAT_AUTORTS; | 660 | mask |= UPSTAT_AUTORTS; |
667 | 661 | ||
668 | if (port->status & mask) { | 662 | if (port->status & mask) { |
@@ -670,21 +664,25 @@ static void uart_unthrottle(struct tty_struct *tty) | |||
670 | mask &= ~port->status; | 664 | mask &= ~port->status; |
671 | } | 665 | } |
672 | 666 | ||
673 | if (mask & UPSTAT_AUTOXOFF) | ||
674 | uart_send_xchar(tty, START_CHAR(tty)); | ||
675 | |||
676 | if (mask & UPSTAT_AUTORTS) | 667 | if (mask & UPSTAT_AUTORTS) |
677 | uart_set_mctrl(port, TIOCM_RTS); | 668 | uart_set_mctrl(port, TIOCM_RTS); |
669 | |||
670 | if (mask & UPSTAT_AUTOXOFF) | ||
671 | uart_send_xchar(tty, START_CHAR(tty)); | ||
678 | } | 672 | } |
679 | 673 | ||
680 | static void do_uart_get_info(struct tty_port *port, | 674 | static void uart_get_info(struct tty_port *port, struct serial_struct *retinfo) |
681 | struct serial_struct *retinfo) | ||
682 | { | 675 | { |
683 | struct uart_state *state = container_of(port, struct uart_state, port); | 676 | struct uart_state *state = container_of(port, struct uart_state, port); |
684 | struct uart_port *uport = state->uart_port; | 677 | struct uart_port *uport = state->uart_port; |
685 | 678 | ||
686 | memset(retinfo, 0, sizeof(*retinfo)); | 679 | memset(retinfo, 0, sizeof(*retinfo)); |
687 | 680 | ||
681 | /* | ||
682 | * Ensure the state we copy is consistent and no hardware changes | ||
683 | * occur as we go | ||
684 | */ | ||
685 | mutex_lock(&port->mutex); | ||
688 | retinfo->type = uport->type; | 686 | retinfo->type = uport->type; |
689 | retinfo->line = uport->line; | 687 | retinfo->line = uport->line; |
690 | retinfo->port = uport->iobase; | 688 | retinfo->port = uport->iobase; |
@@ -703,15 +701,6 @@ static void do_uart_get_info(struct tty_port *port, | |||
703 | retinfo->io_type = uport->iotype; | 701 | retinfo->io_type = uport->iotype; |
704 | retinfo->iomem_reg_shift = uport->regshift; | 702 | retinfo->iomem_reg_shift = uport->regshift; |
705 | retinfo->iomem_base = (void *)(unsigned long)uport->mapbase; | 703 | retinfo->iomem_base = (void *)(unsigned long)uport->mapbase; |
706 | } | ||
707 | |||
708 | static void uart_get_info(struct tty_port *port, | ||
709 | struct serial_struct *retinfo) | ||
710 | { | ||
711 | /* Ensure the state we copy is consistent and no hardware changes | ||
712 | occur as we go */ | ||
713 | mutex_lock(&port->mutex); | ||
714 | do_uart_get_info(port, retinfo); | ||
715 | mutex_unlock(&port->mutex); | 704 | mutex_unlock(&port->mutex); |
716 | } | 705 | } |
717 | 706 | ||
@@ -719,6 +708,7 @@ static int uart_get_info_user(struct tty_port *port, | |||
719 | struct serial_struct __user *retinfo) | 708 | struct serial_struct __user *retinfo) |
720 | { | 709 | { |
721 | struct serial_struct tmp; | 710 | struct serial_struct tmp; |
711 | |||
722 | uart_get_info(port, &tmp); | 712 | uart_get_info(port, &tmp); |
723 | 713 | ||
724 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) | 714 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) |
@@ -1391,8 +1381,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp) | |||
1391 | 1381 | ||
1392 | uport = state->uart_port; | 1382 | uport = state->uart_port; |
1393 | port = &state->port; | 1383 | port = &state->port; |
1394 | 1384 | pr_debug("uart_close(%d) called\n", tty->index); | |
1395 | pr_debug("uart_close(%d) called\n", uport ? uport->line : -1); | ||
1396 | 1385 | ||
1397 | if (!port->count || tty_port_close_start(port, tty, filp) == 0) | 1386 | if (!port->count || tty_port_close_start(port, tty, filp) == 0) |
1398 | return; | 1387 | return; |
@@ -1434,7 +1423,6 @@ static void uart_close(struct tty_struct *tty, struct file *filp) | |||
1434 | * Wake up anyone trying to open this port. | 1423 | * Wake up anyone trying to open this port. |
1435 | */ | 1424 | */ |
1436 | clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags); | 1425 | clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags); |
1437 | clear_bit(ASYNCB_CLOSING, &port->flags); | ||
1438 | spin_unlock_irq(&port->lock); | 1426 | spin_unlock_irq(&port->lock); |
1439 | wake_up_interruptible(&port->open_wait); | 1427 | wake_up_interruptible(&port->open_wait); |
1440 | 1428 | ||
@@ -1510,7 +1498,7 @@ static void uart_hangup(struct tty_struct *tty) | |||
1510 | struct tty_port *port = &state->port; | 1498 | struct tty_port *port = &state->port; |
1511 | unsigned long flags; | 1499 | unsigned long flags; |
1512 | 1500 | ||
1513 | pr_debug("uart_hangup(%d)\n", state->uart_port->line); | 1501 | pr_debug("uart_hangup(%d)\n", tty->index); |
1514 | 1502 | ||
1515 | mutex_lock(&port->mutex); | 1503 | mutex_lock(&port->mutex); |
1516 | if (port->flags & ASYNC_NORMAL_ACTIVE) { | 1504 | if (port->flags & ASYNC_NORMAL_ACTIVE) { |
@@ -1591,7 +1579,7 @@ static void uart_dtr_rts(struct tty_port *port, int onoff) | |||
1591 | */ | 1579 | */ |
1592 | static int uart_open(struct tty_struct *tty, struct file *filp) | 1580 | static int uart_open(struct tty_struct *tty, struct file *filp) |
1593 | { | 1581 | { |
1594 | struct uart_driver *drv = (struct uart_driver *)tty->driver->driver_state; | 1582 | struct uart_driver *drv = tty->driver->driver_state; |
1595 | int retval, line = tty->index; | 1583 | int retval, line = tty->index; |
1596 | struct uart_state *state = drv->state + line; | 1584 | struct uart_state *state = drv->state + line; |
1597 | struct tty_port *port = &state->port; | 1585 | struct tty_port *port = &state->port; |
@@ -1633,15 +1621,12 @@ static int uart_open(struct tty_struct *tty, struct file *filp) | |||
1633 | /* | 1621 | /* |
1634 | * If we succeeded, wait until the port is ready. | 1622 | * If we succeeded, wait until the port is ready. |
1635 | */ | 1623 | */ |
1624 | err_unlock: | ||
1636 | mutex_unlock(&port->mutex); | 1625 | mutex_unlock(&port->mutex); |
1637 | if (retval == 0) | 1626 | if (retval == 0) |
1638 | retval = tty_port_block_til_ready(port, tty, filp); | 1627 | retval = tty_port_block_til_ready(port, tty, filp); |
1639 | |||
1640 | end: | 1628 | end: |
1641 | return retval; | 1629 | return retval; |
1642 | err_unlock: | ||
1643 | mutex_unlock(&port->mutex); | ||
1644 | goto end; | ||
1645 | } | 1630 | } |
1646 | 1631 | ||
1647 | static const char *uart_type(struct uart_port *port) | 1632 | static const char *uart_type(struct uart_port *port) |
@@ -1700,17 +1685,13 @@ static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i) | |||
1700 | seq_printf(m, " tx:%d rx:%d", | 1685 | seq_printf(m, " tx:%d rx:%d", |
1701 | uport->icount.tx, uport->icount.rx); | 1686 | uport->icount.tx, uport->icount.rx); |
1702 | if (uport->icount.frame) | 1687 | if (uport->icount.frame) |
1703 | seq_printf(m, " fe:%d", | 1688 | seq_printf(m, " fe:%d", uport->icount.frame); |
1704 | uport->icount.frame); | ||
1705 | if (uport->icount.parity) | 1689 | if (uport->icount.parity) |
1706 | seq_printf(m, " pe:%d", | 1690 | seq_printf(m, " pe:%d", uport->icount.parity); |
1707 | uport->icount.parity); | ||
1708 | if (uport->icount.brk) | 1691 | if (uport->icount.brk) |
1709 | seq_printf(m, " brk:%d", | 1692 | seq_printf(m, " brk:%d", uport->icount.brk); |
1710 | uport->icount.brk); | ||
1711 | if (uport->icount.overrun) | 1693 | if (uport->icount.overrun) |
1712 | seq_printf(m, " oe:%d", | 1694 | seq_printf(m, " oe:%d", uport->icount.overrun); |
1713 | uport->icount.overrun); | ||
1714 | 1695 | ||
1715 | #define INFOBIT(bit, str) \ | 1696 | #define INFOBIT(bit, str) \ |
1716 | if (uport->mctrl & (bit)) \ | 1697 | if (uport->mctrl & (bit)) \ |
@@ -1745,8 +1726,7 @@ static int uart_proc_show(struct seq_file *m, void *v) | |||
1745 | struct uart_driver *drv = ttydrv->driver_state; | 1726 | struct uart_driver *drv = ttydrv->driver_state; |
1746 | int i; | 1727 | int i; |
1747 | 1728 | ||
1748 | seq_printf(m, "serinfo:1.0 driver%s%s revision:%s\n", | 1729 | seq_printf(m, "serinfo:1.0 driver%s%s revision:%s\n", "", "", ""); |
1749 | "", "", ""); | ||
1750 | for (i = 0; i < drv->nr; i++) | 1730 | for (i = 0; i < drv->nr; i++) |
1751 | uart_line_info(m, drv, i); | 1731 | uart_line_info(m, drv, i); |
1752 | return 0; | 1732 | return 0; |
@@ -1895,26 +1875,6 @@ uart_parse_options(char *options, int *baud, int *parity, int *bits, int *flow) | |||
1895 | } | 1875 | } |
1896 | EXPORT_SYMBOL_GPL(uart_parse_options); | 1876 | EXPORT_SYMBOL_GPL(uart_parse_options); |
1897 | 1877 | ||
1898 | struct baud_rates { | ||
1899 | unsigned int rate; | ||
1900 | unsigned int cflag; | ||
1901 | }; | ||
1902 | |||
1903 | static const struct baud_rates baud_rates[] = { | ||
1904 | { 921600, B921600 }, | ||
1905 | { 460800, B460800 }, | ||
1906 | { 230400, B230400 }, | ||
1907 | { 115200, B115200 }, | ||
1908 | { 57600, B57600 }, | ||
1909 | { 38400, B38400 }, | ||
1910 | { 19200, B19200 }, | ||
1911 | { 9600, B9600 }, | ||
1912 | { 4800, B4800 }, | ||
1913 | { 2400, B2400 }, | ||
1914 | { 1200, B1200 }, | ||
1915 | { 0, B38400 } | ||
1916 | }; | ||
1917 | |||
1918 | /** | 1878 | /** |
1919 | * uart_set_options - setup the serial console parameters | 1879 | * uart_set_options - setup the serial console parameters |
1920 | * @port: pointer to the serial ports uart_port structure | 1880 | * @port: pointer to the serial ports uart_port structure |
@@ -1930,7 +1890,6 @@ uart_set_options(struct uart_port *port, struct console *co, | |||
1930 | { | 1890 | { |
1931 | struct ktermios termios; | 1891 | struct ktermios termios; |
1932 | static struct ktermios dummy; | 1892 | static struct ktermios dummy; |
1933 | int i; | ||
1934 | 1893 | ||
1935 | /* | 1894 | /* |
1936 | * Ensure that the serial console lock is initialised | 1895 | * Ensure that the serial console lock is initialised |
@@ -1945,16 +1904,8 @@ uart_set_options(struct uart_port *port, struct console *co, | |||
1945 | 1904 | ||
1946 | memset(&termios, 0, sizeof(struct ktermios)); | 1905 | memset(&termios, 0, sizeof(struct ktermios)); |
1947 | 1906 | ||
1948 | termios.c_cflag = CREAD | HUPCL | CLOCAL; | 1907 | termios.c_cflag |= CREAD | HUPCL | CLOCAL; |
1949 | 1908 | tty_termios_encode_baud_rate(&termios, baud, baud); | |
1950 | /* | ||
1951 | * Construct a cflag setting. | ||
1952 | */ | ||
1953 | for (i = 0; baud_rates[i].rate; i++) | ||
1954 | if (baud_rates[i].rate <= baud) | ||
1955 | break; | ||
1956 | |||
1957 | termios.c_cflag |= baud_rates[i].cflag; | ||
1958 | 1909 | ||
1959 | if (bits == 7) | 1910 | if (bits == 7) |
1960 | termios.c_cflag |= CS7; | 1911 | termios.c_cflag |= CS7; |
diff --git a/drivers/tty/serial/serial_ks8695.c b/drivers/tty/serial/serial_ks8695.c index b4decf8787de..57f152394af5 100644 --- a/drivers/tty/serial/serial_ks8695.c +++ b/drivers/tty/serial/serial_ks8695.c | |||
@@ -554,7 +554,7 @@ static struct uart_port ks8695uart_ports[SERIAL_KS8695_NR] = { | |||
554 | .uartclk = KS8695_CLOCK_RATE * 16, | 554 | .uartclk = KS8695_CLOCK_RATE * 16, |
555 | .fifosize = 16, | 555 | .fifosize = 16, |
556 | .ops = &ks8695uart_pops, | 556 | .ops = &ks8695uart_pops, |
557 | .flags = ASYNC_BOOT_AUTOCONF, | 557 | .flags = UPF_BOOT_AUTOCONF, |
558 | .line = 0, | 558 | .line = 0, |
559 | } | 559 | } |
560 | }; | 560 | }; |
diff --git a/drivers/tty/serial/serial_mctrl_gpio.c b/drivers/tty/serial/serial_mctrl_gpio.c index 226ad23b136c..02147361eaa9 100644 --- a/drivers/tty/serial/serial_mctrl_gpio.c +++ b/drivers/tty/serial/serial_mctrl_gpio.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/gpio/consumer.h> | 20 | #include <linux/gpio/consumer.h> |
21 | #include <linux/termios.h> | 21 | #include <linux/termios.h> |
22 | #include <linux/serial_core.h> | 22 | #include <linux/serial_core.h> |
23 | #include <linux/module.h> | ||
23 | 24 | ||
24 | #include "serial_mctrl_gpio.h" | 25 | #include "serial_mctrl_gpio.h" |
25 | 26 | ||
@@ -249,3 +250,5 @@ void mctrl_gpio_disable_ms(struct mctrl_gpios *gpios) | |||
249 | } | 250 | } |
250 | } | 251 | } |
251 | EXPORT_SYMBOL_GPL(mctrl_gpio_disable_ms); | 252 | EXPORT_SYMBOL_GPL(mctrl_gpio_disable_ms); |
253 | |||
254 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 4646a9f531ad..0130feb069ae 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c | |||
@@ -84,6 +84,22 @@ enum SCI_CLKS { | |||
84 | SCI_NUM_CLKS | 84 | SCI_NUM_CLKS |
85 | }; | 85 | }; |
86 | 86 | ||
87 | /* Bit x set means sampling rate x + 1 is supported */ | ||
88 | #define SCI_SR(x) BIT((x) - 1) | ||
89 | #define SCI_SR_RANGE(x, y) GENMASK((y) - 1, (x) - 1) | ||
90 | |||
91 | #define SCI_SR_SCIFAB SCI_SR(5) | SCI_SR(7) | SCI_SR(11) | \ | ||
92 | SCI_SR(13) | SCI_SR(16) | SCI_SR(17) | \ | ||
93 | SCI_SR(19) | SCI_SR(27) | ||
94 | |||
95 | #define min_sr(_port) ffs((_port)->sampling_rate_mask) | ||
96 | #define max_sr(_port) fls((_port)->sampling_rate_mask) | ||
97 | |||
98 | /* Iterate over all supported sampling rates, from high to low */ | ||
99 | #define for_each_sr(_sr, _port) \ | ||
100 | for ((_sr) = max_sr(_port); (_sr) >= min_sr(_port); (_sr)--) \ | ||
101 | if ((_port)->sampling_rate_mask & SCI_SR((_sr))) | ||
102 | |||
87 | struct sci_port { | 103 | struct sci_port { |
88 | struct uart_port port; | 104 | struct uart_port port; |
89 | 105 | ||
@@ -93,7 +109,7 @@ struct sci_port { | |||
93 | unsigned int overrun_mask; | 109 | unsigned int overrun_mask; |
94 | unsigned int error_mask; | 110 | unsigned int error_mask; |
95 | unsigned int error_clear; | 111 | unsigned int error_clear; |
96 | unsigned int sampling_rate; | 112 | unsigned int sampling_rate_mask; |
97 | resource_size_t reg_size; | 113 | resource_size_t reg_size; |
98 | 114 | ||
99 | /* Break timer */ | 115 | /* Break timer */ |
@@ -637,7 +653,8 @@ static void sci_clear_SCxSR(struct uart_port *port, unsigned int mask) | |||
637 | } | 653 | } |
638 | } | 654 | } |
639 | 655 | ||
640 | #if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_SH_SCI_CONSOLE) | 656 | #if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_SH_SCI_CONSOLE) || \ |
657 | defined(CONFIG_SERIAL_SH_SCI_EARLYCON) | ||
641 | 658 | ||
642 | #ifdef CONFIG_CONSOLE_POLL | 659 | #ifdef CONFIG_CONSOLE_POLL |
643 | static int sci_poll_get_char(struct uart_port *port) | 660 | static int sci_poll_get_char(struct uart_port *port) |
@@ -678,7 +695,8 @@ static void sci_poll_put_char(struct uart_port *port, unsigned char c) | |||
678 | serial_port_out(port, SCxTDR, c); | 695 | serial_port_out(port, SCxTDR, c); |
679 | sci_clear_SCxSR(port, SCxSR_TDxE_CLEAR(port) & ~SCxSR_TEND(port)); | 696 | sci_clear_SCxSR(port, SCxSR_TDxE_CLEAR(port) & ~SCxSR_TEND(port)); |
680 | } | 697 | } |
681 | #endif /* CONFIG_CONSOLE_POLL || CONFIG_SERIAL_SH_SCI_CONSOLE */ | 698 | #endif /* CONFIG_CONSOLE_POLL || CONFIG_SERIAL_SH_SCI_CONSOLE || |
699 | CONFIG_SERIAL_SH_SCI_EARLYCON */ | ||
682 | 700 | ||
683 | static void sci_init_pins(struct uart_port *port, unsigned int cflag) | 701 | static void sci_init_pins(struct uart_port *port, unsigned int cflag) |
684 | { | 702 | { |
@@ -1902,19 +1920,13 @@ static int sci_sck_calc(struct sci_port *s, unsigned int bps, | |||
1902 | unsigned int *srr) | 1920 | unsigned int *srr) |
1903 | { | 1921 | { |
1904 | unsigned long freq = s->clk_rates[SCI_SCK]; | 1922 | unsigned long freq = s->clk_rates[SCI_SCK]; |
1905 | unsigned int min_sr, max_sr, sr; | ||
1906 | int err, min_err = INT_MAX; | 1923 | int err, min_err = INT_MAX; |
1924 | unsigned int sr; | ||
1907 | 1925 | ||
1908 | if (s->sampling_rate) { | 1926 | if (s->port.type != PORT_HSCIF) |
1909 | /* SCI(F) has a fixed sampling rate */ | 1927 | freq *= 2; |
1910 | min_sr = max_sr = s->sampling_rate / 2; | ||
1911 | } else { | ||
1912 | /* HSCIF has a variable 1/(8..32) sampling rate */ | ||
1913 | min_sr = 8; | ||
1914 | max_sr = 32; | ||
1915 | } | ||
1916 | 1928 | ||
1917 | for (sr = max_sr; sr >= min_sr; sr--) { | 1929 | for_each_sr(sr, s) { |
1918 | err = DIV_ROUND_CLOSEST(freq, sr) - bps; | 1930 | err = DIV_ROUND_CLOSEST(freq, sr) - bps; |
1919 | if (abs(err) >= abs(min_err)) | 1931 | if (abs(err) >= abs(min_err)) |
1920 | continue; | 1932 | continue; |
@@ -1935,19 +1947,13 @@ static int sci_brg_calc(struct sci_port *s, unsigned int bps, | |||
1935 | unsigned long freq, unsigned int *dlr, | 1947 | unsigned long freq, unsigned int *dlr, |
1936 | unsigned int *srr) | 1948 | unsigned int *srr) |
1937 | { | 1949 | { |
1938 | unsigned int min_sr, max_sr, sr, dl; | ||
1939 | int err, min_err = INT_MAX; | 1950 | int err, min_err = INT_MAX; |
1951 | unsigned int sr, dl; | ||
1940 | 1952 | ||
1941 | if (s->sampling_rate) { | 1953 | if (s->port.type != PORT_HSCIF) |
1942 | /* SCIF has a fixed sampling rate */ | 1954 | freq *= 2; |
1943 | min_sr = max_sr = s->sampling_rate / 2; | ||
1944 | } else { | ||
1945 | /* HSCIF has a variable 1/(8..32) sampling rate */ | ||
1946 | min_sr = 8; | ||
1947 | max_sr = 32; | ||
1948 | } | ||
1949 | 1955 | ||
1950 | for (sr = max_sr; sr >= min_sr; sr--) { | 1956 | for_each_sr(sr, s) { |
1951 | dl = DIV_ROUND_CLOSEST(freq, sr * bps); | 1957 | dl = DIV_ROUND_CLOSEST(freq, sr * bps); |
1952 | dl = clamp(dl, 1U, 65535U); | 1958 | dl = clamp(dl, 1U, 65535U); |
1953 | 1959 | ||
@@ -1973,19 +1979,12 @@ static int sci_scbrr_calc(struct sci_port *s, unsigned int bps, | |||
1973 | unsigned int *brr, unsigned int *srr, | 1979 | unsigned int *brr, unsigned int *srr, |
1974 | unsigned int *cks) | 1980 | unsigned int *cks) |
1975 | { | 1981 | { |
1976 | unsigned int min_sr, max_sr, shift, sr, br, prediv, scrate, c; | ||
1977 | unsigned long freq = s->clk_rates[SCI_FCK]; | 1982 | unsigned long freq = s->clk_rates[SCI_FCK]; |
1983 | unsigned int sr, br, prediv, scrate, c; | ||
1978 | int err, min_err = INT_MAX; | 1984 | int err, min_err = INT_MAX; |
1979 | 1985 | ||
1980 | if (s->sampling_rate) { | 1986 | if (s->port.type != PORT_HSCIF) |
1981 | min_sr = max_sr = s->sampling_rate; | 1987 | freq *= 2; |
1982 | shift = 0; | ||
1983 | } else { | ||
1984 | /* HSCIF has a variable sample rate */ | ||
1985 | min_sr = 8; | ||
1986 | max_sr = 32; | ||
1987 | shift = 1; | ||
1988 | } | ||
1989 | 1988 | ||
1990 | /* | 1989 | /* |
1991 | * Find the combination of sample rate and clock select with the | 1990 | * Find the combination of sample rate and clock select with the |
@@ -2002,10 +2001,10 @@ static int sci_scbrr_calc(struct sci_port *s, unsigned int bps, | |||
2002 | * (|D - 0.5| / N * (1 + F))| | 2001 | * (|D - 0.5| / N * (1 + F))| |
2003 | * NOTE: Usually, treat D for 0.5, F is 0 by this calculation. | 2002 | * NOTE: Usually, treat D for 0.5, F is 0 by this calculation. |
2004 | */ | 2003 | */ |
2005 | for (sr = max_sr; sr >= min_sr; sr--) { | 2004 | for_each_sr(sr, s) { |
2006 | for (c = 0; c <= 3; c++) { | 2005 | for (c = 0; c <= 3; c++) { |
2007 | /* integerized formulas from HSCIF documentation */ | 2006 | /* integerized formulas from HSCIF documentation */ |
2008 | prediv = sr * (1 << (2 * c + shift)); | 2007 | prediv = sr * (1 << (2 * c + 1)); |
2009 | 2008 | ||
2010 | /* | 2009 | /* |
2011 | * We need to calculate: | 2010 | * We need to calculate: |
@@ -2062,7 +2061,7 @@ static void sci_reset(struct uart_port *port) | |||
2062 | static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | 2061 | static void sci_set_termios(struct uart_port *port, struct ktermios *termios, |
2063 | struct ktermios *old) | 2062 | struct ktermios *old) |
2064 | { | 2063 | { |
2065 | unsigned int baud, smr_val = 0, scr_val = 0, i; | 2064 | unsigned int baud, smr_val = SCSMR_ASYNC, scr_val = 0, i; |
2066 | unsigned int brr = 255, cks = 0, srr = 15, dl = 0, sccks = 0; | 2065 | unsigned int brr = 255, cks = 0, srr = 15, dl = 0, sccks = 0; |
2067 | unsigned int brr1 = 255, cks1 = 0, srr1 = 15, dl1 = 0; | 2066 | unsigned int brr1 = 255, cks1 = 0, srr1 = 15, dl1 = 0; |
2068 | struct sci_port *s = to_sci_port(port); | 2067 | struct sci_port *s = to_sci_port(port); |
@@ -2096,8 +2095,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
2096 | for (i = 0; i < SCI_NUM_CLKS; i++) | 2095 | for (i = 0; i < SCI_NUM_CLKS; i++) |
2097 | max_freq = max(max_freq, s->clk_rates[i]); | 2096 | max_freq = max(max_freq, s->clk_rates[i]); |
2098 | 2097 | ||
2099 | baud = uart_get_baud_rate(port, termios, old, 0, | 2098 | baud = uart_get_baud_rate(port, termios, old, 0, max_freq / min_sr(s)); |
2100 | max_freq / max(s->sampling_rate, 8U)); | ||
2101 | if (!baud) | 2099 | if (!baud) |
2102 | goto done; | 2100 | goto done; |
2103 | 2101 | ||
@@ -2185,6 +2183,17 @@ done: | |||
2185 | uart_update_timeout(port, termios->c_cflag, baud); | 2183 | uart_update_timeout(port, termios->c_cflag, baud); |
2186 | 2184 | ||
2187 | if (best_clk >= 0) { | 2185 | if (best_clk >= 0) { |
2186 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) | ||
2187 | switch (srr + 1) { | ||
2188 | case 5: smr_val |= SCSMR_SRC_5; break; | ||
2189 | case 7: smr_val |= SCSMR_SRC_7; break; | ||
2190 | case 11: smr_val |= SCSMR_SRC_11; break; | ||
2191 | case 13: smr_val |= SCSMR_SRC_13; break; | ||
2192 | case 16: smr_val |= SCSMR_SRC_16; break; | ||
2193 | case 17: smr_val |= SCSMR_SRC_17; break; | ||
2194 | case 19: smr_val |= SCSMR_SRC_19; break; | ||
2195 | case 27: smr_val |= SCSMR_SRC_27; break; | ||
2196 | } | ||
2188 | smr_val |= cks; | 2197 | smr_val |= cks; |
2189 | dev_dbg(port->dev, | 2198 | dev_dbg(port->dev, |
2190 | "SCR 0x%x SMR 0x%x BRR %u CKS 0x%x DL %u SRR %u\n", | 2199 | "SCR 0x%x SMR 0x%x BRR %u CKS 0x%x DL %u SRR %u\n", |
@@ -2200,7 +2209,8 @@ done: | |||
2200 | } else { | 2209 | } else { |
2201 | /* Don't touch the bit rate configuration */ | 2210 | /* Don't touch the bit rate configuration */ |
2202 | scr_val = s->cfg->scscr & (SCSCR_CKE1 | SCSCR_CKE0); | 2211 | scr_val = s->cfg->scscr & (SCSCR_CKE1 | SCSCR_CKE0); |
2203 | smr_val |= serial_port_in(port, SCSMR) & SCSMR_CKS; | 2212 | smr_val |= serial_port_in(port, SCSMR) & |
2213 | (SCSMR_CKEDG | SCSMR_SRC_MASK | SCSMR_CKS); | ||
2204 | dev_dbg(port->dev, "SCR 0x%x SMR 0x%x\n", scr_val, smr_val); | 2214 | dev_dbg(port->dev, "SCR 0x%x SMR 0x%x\n", scr_val, smr_val); |
2205 | serial_port_out(port, SCSCR, scr_val); | 2215 | serial_port_out(port, SCSCR, scr_val); |
2206 | serial_port_out(port, SCSMR, smr_val); | 2216 | serial_port_out(port, SCSMR, smr_val); |
@@ -2232,6 +2242,16 @@ done: | |||
2232 | scr_val |= s->cfg->scscr & ~(SCSCR_CKE1 | SCSCR_CKE0); | 2242 | scr_val |= s->cfg->scscr & ~(SCSCR_CKE1 | SCSCR_CKE0); |
2233 | dev_dbg(port->dev, "SCSCR 0x%x\n", scr_val); | 2243 | dev_dbg(port->dev, "SCSCR 0x%x\n", scr_val); |
2234 | serial_port_out(port, SCSCR, scr_val); | 2244 | serial_port_out(port, SCSCR, scr_val); |
2245 | if ((srr + 1 == 5) && | ||
2246 | (port->type == PORT_SCIFA || port->type == PORT_SCIFB)) { | ||
2247 | /* | ||
2248 | * In asynchronous mode, when the sampling rate is 1/5, first | ||
2249 | * received data may become invalid on some SCIFA and SCIFB. | ||
2250 | * To avoid this problem wait more than 1 serial data time (1 | ||
2251 | * bit time x serial data number) after setting SCSCR.RE = 1. | ||
2252 | */ | ||
2253 | udelay(DIV_ROUND_UP(10 * 1000000, baud)); | ||
2254 | } | ||
2235 | 2255 | ||
2236 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | 2256 | #ifdef CONFIG_SERIAL_SH_SCI_DMA |
2237 | /* | 2257 | /* |
@@ -2528,37 +2548,37 @@ static int sci_init_single(struct platform_device *dev, | |||
2528 | port->fifosize = 256; | 2548 | port->fifosize = 256; |
2529 | sci_port->overrun_reg = SCxSR; | 2549 | sci_port->overrun_reg = SCxSR; |
2530 | sci_port->overrun_mask = SCIFA_ORER; | 2550 | sci_port->overrun_mask = SCIFA_ORER; |
2531 | sci_port->sampling_rate = 16; | 2551 | sci_port->sampling_rate_mask = SCI_SR_SCIFAB; |
2532 | break; | 2552 | break; |
2533 | case PORT_HSCIF: | 2553 | case PORT_HSCIF: |
2534 | port->fifosize = 128; | 2554 | port->fifosize = 128; |
2535 | sci_port->overrun_reg = SCLSR; | 2555 | sci_port->overrun_reg = SCLSR; |
2536 | sci_port->overrun_mask = SCLSR_ORER; | 2556 | sci_port->overrun_mask = SCLSR_ORER; |
2537 | sci_port->sampling_rate = 0; | 2557 | sci_port->sampling_rate_mask = SCI_SR_RANGE(8, 32); |
2538 | break; | 2558 | break; |
2539 | case PORT_SCIFA: | 2559 | case PORT_SCIFA: |
2540 | port->fifosize = 64; | 2560 | port->fifosize = 64; |
2541 | sci_port->overrun_reg = SCxSR; | 2561 | sci_port->overrun_reg = SCxSR; |
2542 | sci_port->overrun_mask = SCIFA_ORER; | 2562 | sci_port->overrun_mask = SCIFA_ORER; |
2543 | sci_port->sampling_rate = 16; | 2563 | sci_port->sampling_rate_mask = SCI_SR_SCIFAB; |
2544 | break; | 2564 | break; |
2545 | case PORT_SCIF: | 2565 | case PORT_SCIF: |
2546 | port->fifosize = 16; | 2566 | port->fifosize = 16; |
2547 | if (p->regtype == SCIx_SH7705_SCIF_REGTYPE) { | 2567 | if (p->regtype == SCIx_SH7705_SCIF_REGTYPE) { |
2548 | sci_port->overrun_reg = SCxSR; | 2568 | sci_port->overrun_reg = SCxSR; |
2549 | sci_port->overrun_mask = SCIFA_ORER; | 2569 | sci_port->overrun_mask = SCIFA_ORER; |
2550 | sci_port->sampling_rate = 16; | 2570 | sci_port->sampling_rate_mask = SCI_SR(16); |
2551 | } else { | 2571 | } else { |
2552 | sci_port->overrun_reg = SCLSR; | 2572 | sci_port->overrun_reg = SCLSR; |
2553 | sci_port->overrun_mask = SCLSR_ORER; | 2573 | sci_port->overrun_mask = SCLSR_ORER; |
2554 | sci_port->sampling_rate = 32; | 2574 | sci_port->sampling_rate_mask = SCI_SR(32); |
2555 | } | 2575 | } |
2556 | break; | 2576 | break; |
2557 | default: | 2577 | default: |
2558 | port->fifosize = 1; | 2578 | port->fifosize = 1; |
2559 | sci_port->overrun_reg = SCxSR; | 2579 | sci_port->overrun_reg = SCxSR; |
2560 | sci_port->overrun_mask = SCI_ORER; | 2580 | sci_port->overrun_mask = SCI_ORER; |
2561 | sci_port->sampling_rate = 32; | 2581 | sci_port->sampling_rate_mask = SCI_SR(32); |
2562 | break; | 2582 | break; |
2563 | } | 2583 | } |
2564 | 2584 | ||
@@ -2567,7 +2587,7 @@ static int sci_init_single(struct platform_device *dev, | |||
2567 | * data override the sampling rate for now. | 2587 | * data override the sampling rate for now. |
2568 | */ | 2588 | */ |
2569 | if (p->sampling_rate) | 2589 | if (p->sampling_rate) |
2570 | sci_port->sampling_rate = p->sampling_rate; | 2590 | sci_port->sampling_rate_mask = SCI_SR(p->sampling_rate); |
2571 | 2591 | ||
2572 | if (!early) { | 2592 | if (!early) { |
2573 | ret = sci_init_clocks(sci_port, &dev->dev); | 2593 | ret = sci_init_clocks(sci_port, &dev->dev); |
@@ -2632,7 +2652,8 @@ static void sci_cleanup_single(struct sci_port *port) | |||
2632 | pm_runtime_disable(port->port.dev); | 2652 | pm_runtime_disable(port->port.dev); |
2633 | } | 2653 | } |
2634 | 2654 | ||
2635 | #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE | 2655 | #if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) || \ |
2656 | defined(CONFIG_SERIAL_SH_SCI_EARLYCON) | ||
2636 | static void serial_console_putchar(struct uart_port *port, int ch) | 2657 | static void serial_console_putchar(struct uart_port *port, int ch) |
2637 | { | 2658 | { |
2638 | sci_poll_put_char(port, ch); | 2659 | sci_poll_put_char(port, ch); |
@@ -2652,9 +2673,12 @@ static void serial_console_write(struct console *co, const char *s, | |||
2652 | int locked = 1; | 2673 | int locked = 1; |
2653 | 2674 | ||
2654 | local_irq_save(flags); | 2675 | local_irq_save(flags); |
2676 | #if defined(SUPPORT_SYSRQ) | ||
2655 | if (port->sysrq) | 2677 | if (port->sysrq) |
2656 | locked = 0; | 2678 | locked = 0; |
2657 | else if (oops_in_progress) | 2679 | else |
2680 | #endif | ||
2681 | if (oops_in_progress) | ||
2658 | locked = spin_trylock(&port->lock); | 2682 | locked = spin_trylock(&port->lock); |
2659 | else | 2683 | else |
2660 | spin_lock(&port->lock); | 2684 | spin_lock(&port->lock); |
@@ -2764,7 +2788,7 @@ static inline int sci_probe_earlyprintk(struct platform_device *pdev) | |||
2764 | 2788 | ||
2765 | #define SCI_CONSOLE NULL | 2789 | #define SCI_CONSOLE NULL |
2766 | 2790 | ||
2767 | #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ | 2791 | #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE || CONFIG_SERIAL_SH_SCI_EARLYCON */ |
2768 | 2792 | ||
2769 | static const char banner[] __initconst = "SuperH (H)SCI(F) driver initialized"; | 2793 | static const char banner[] __initconst = "SuperH (H)SCI(F) driver initialized"; |
2770 | 2794 | ||
@@ -2998,6 +3022,62 @@ static void __exit sci_exit(void) | |||
2998 | early_platform_init_buffer("earlyprintk", &sci_driver, | 3022 | early_platform_init_buffer("earlyprintk", &sci_driver, |
2999 | early_serial_buf, ARRAY_SIZE(early_serial_buf)); | 3023 | early_serial_buf, ARRAY_SIZE(early_serial_buf)); |
3000 | #endif | 3024 | #endif |
3025 | #ifdef CONFIG_SERIAL_SH_SCI_EARLYCON | ||
3026 | static struct __init plat_sci_port port_cfg; | ||
3027 | |||
3028 | static int __init early_console_setup(struct earlycon_device *device, | ||
3029 | int type) | ||
3030 | { | ||
3031 | if (!device->port.membase) | ||
3032 | return -ENODEV; | ||
3033 | |||
3034 | device->port.serial_in = sci_serial_in; | ||
3035 | device->port.serial_out = sci_serial_out; | ||
3036 | device->port.type = type; | ||
3037 | memcpy(&sci_ports[0].port, &device->port, sizeof(struct uart_port)); | ||
3038 | sci_ports[0].cfg = &port_cfg; | ||
3039 | sci_ports[0].cfg->type = type; | ||
3040 | sci_probe_regmap(sci_ports[0].cfg); | ||
3041 | port_cfg.scscr = sci_serial_in(&sci_ports[0].port, SCSCR) | | ||
3042 | SCSCR_RE | SCSCR_TE; | ||
3043 | sci_serial_out(&sci_ports[0].port, SCSCR, port_cfg.scscr); | ||
3044 | |||
3045 | device->con->write = serial_console_write; | ||
3046 | return 0; | ||
3047 | } | ||
3048 | static int __init sci_early_console_setup(struct earlycon_device *device, | ||
3049 | const char *opt) | ||
3050 | { | ||
3051 | return early_console_setup(device, PORT_SCI); | ||
3052 | } | ||
3053 | static int __init scif_early_console_setup(struct earlycon_device *device, | ||
3054 | const char *opt) | ||
3055 | { | ||
3056 | return early_console_setup(device, PORT_SCIF); | ||
3057 | } | ||
3058 | static int __init scifa_early_console_setup(struct earlycon_device *device, | ||
3059 | const char *opt) | ||
3060 | { | ||
3061 | return early_console_setup(device, PORT_SCIFA); | ||
3062 | } | ||
3063 | static int __init scifb_early_console_setup(struct earlycon_device *device, | ||
3064 | const char *opt) | ||
3065 | { | ||
3066 | return early_console_setup(device, PORT_SCIFB); | ||
3067 | } | ||
3068 | static int __init hscif_early_console_setup(struct earlycon_device *device, | ||
3069 | const char *opt) | ||
3070 | { | ||
3071 | return early_console_setup(device, PORT_HSCIF); | ||
3072 | } | ||
3073 | |||
3074 | OF_EARLYCON_DECLARE(sci, "renesas,sci", sci_early_console_setup); | ||
3075 | OF_EARLYCON_DECLARE(scif, "renesas,scif", scif_early_console_setup); | ||
3076 | OF_EARLYCON_DECLARE(scifa, "renesas,scifa", scifa_early_console_setup); | ||
3077 | OF_EARLYCON_DECLARE(scifb, "renesas,scifb", scifb_early_console_setup); | ||
3078 | OF_EARLYCON_DECLARE(hscif, "renesas,hscif", hscif_early_console_setup); | ||
3079 | #endif /* CONFIG_SERIAL_SH_SCI_EARLYCON */ | ||
3080 | |||
3001 | module_init(sci_init); | 3081 | module_init(sci_init); |
3002 | module_exit(sci_exit); | 3082 | module_exit(sci_exit); |
3003 | 3083 | ||
diff --git a/drivers/tty/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h index fb1760250421..7a4fa185b93e 100644 --- a/drivers/tty/serial/sh-sci.h +++ b/drivers/tty/serial/sh-sci.h | |||
@@ -35,12 +35,27 @@ enum { | |||
35 | 35 | ||
36 | 36 | ||
37 | /* SCSMR (Serial Mode Register) */ | 37 | /* SCSMR (Serial Mode Register) */ |
38 | #define SCSMR_C_A BIT(7) /* Communication Mode */ | ||
39 | #define SCSMR_CSYNC BIT(7) /* - Clocked synchronous mode */ | ||
40 | #define SCSMR_ASYNC 0 /* - Asynchronous mode */ | ||
38 | #define SCSMR_CHR BIT(6) /* 7-bit Character Length */ | 41 | #define SCSMR_CHR BIT(6) /* 7-bit Character Length */ |
39 | #define SCSMR_PE BIT(5) /* Parity Enable */ | 42 | #define SCSMR_PE BIT(5) /* Parity Enable */ |
40 | #define SCSMR_ODD BIT(4) /* Odd Parity */ | 43 | #define SCSMR_ODD BIT(4) /* Odd Parity */ |
41 | #define SCSMR_STOP BIT(3) /* Stop Bit Length */ | 44 | #define SCSMR_STOP BIT(3) /* Stop Bit Length */ |
42 | #define SCSMR_CKS 0x0003 /* Clock Select */ | 45 | #define SCSMR_CKS 0x0003 /* Clock Select */ |
43 | 46 | ||
47 | /* Serial Mode Register, SCIFA/SCIFB only bits */ | ||
48 | #define SCSMR_CKEDG BIT(12) /* Transmit/Receive Clock Edge Select */ | ||
49 | #define SCSMR_SRC_MASK 0x0700 /* Sampling Control */ | ||
50 | #define SCSMR_SRC_16 0x0000 /* Sampling rate 1/16 */ | ||
51 | #define SCSMR_SRC_5 0x0100 /* Sampling rate 1/5 */ | ||
52 | #define SCSMR_SRC_7 0x0200 /* Sampling rate 1/7 */ | ||
53 | #define SCSMR_SRC_11 0x0300 /* Sampling rate 1/11 */ | ||
54 | #define SCSMR_SRC_13 0x0400 /* Sampling rate 1/13 */ | ||
55 | #define SCSMR_SRC_17 0x0500 /* Sampling rate 1/17 */ | ||
56 | #define SCSMR_SRC_19 0x0600 /* Sampling rate 1/19 */ | ||
57 | #define SCSMR_SRC_27 0x0700 /* Sampling rate 1/27 */ | ||
58 | |||
44 | /* Serial Control Register, SCIFA/SCIFB only bits */ | 59 | /* Serial Control Register, SCIFA/SCIFB only bits */ |
45 | #define SCSCR_TDRQE BIT(15) /* Tx Data Transfer Request Enable */ | 60 | #define SCSCR_TDRQE BIT(15) /* Tx Data Transfer Request Enable */ |
46 | #define SCSCR_RDRQE BIT(14) /* Rx Data Transfer Request Enable */ | 61 | #define SCSCR_RDRQE BIT(14) /* Rx Data Transfer Request Enable */ |
diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c index ef26c4a60be4..18971063f95f 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c | |||
@@ -624,8 +624,6 @@ static int __init sprd_early_console_setup( | |||
624 | device->con->write = sprd_early_write; | 624 | device->con->write = sprd_early_write; |
625 | return 0; | 625 | return 0; |
626 | } | 626 | } |
627 | |||
628 | EARLYCON_DECLARE(sprd_serial, sprd_early_console_setup); | ||
629 | OF_EARLYCON_DECLARE(sprd_serial, "sprd,sc9836-uart", | 627 | OF_EARLYCON_DECLARE(sprd_serial, "sprd,sc9836-uart", |
630 | sprd_early_console_setup); | 628 | sprd_early_console_setup); |
631 | 629 | ||
diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c index b1c6bd3d483f..c9fdfc8bf47f 100644 --- a/drivers/tty/serial/uartlite.c +++ b/drivers/tty/serial/uartlite.c | |||
@@ -28,7 +28,7 @@ | |||
28 | #define ULITE_NAME "ttyUL" | 28 | #define ULITE_NAME "ttyUL" |
29 | #define ULITE_MAJOR 204 | 29 | #define ULITE_MAJOR 204 |
30 | #define ULITE_MINOR 187 | 30 | #define ULITE_MINOR 187 |
31 | #define ULITE_NR_UARTS 4 | 31 | #define ULITE_NR_UARTS 16 |
32 | 32 | ||
33 | /* --------------------------------------------------------------------- | 33 | /* --------------------------------------------------------------------- |
34 | * Register definitions | 34 | * Register definitions |
@@ -72,7 +72,7 @@ static void uartlite_outbe32(u32 val, void __iomem *addr) | |||
72 | iowrite32be(val, addr); | 72 | iowrite32be(val, addr); |
73 | } | 73 | } |
74 | 74 | ||
75 | static struct uartlite_reg_ops uartlite_be = { | 75 | static const struct uartlite_reg_ops uartlite_be = { |
76 | .in = uartlite_inbe32, | 76 | .in = uartlite_inbe32, |
77 | .out = uartlite_outbe32, | 77 | .out = uartlite_outbe32, |
78 | }; | 78 | }; |
@@ -87,21 +87,21 @@ static void uartlite_outle32(u32 val, void __iomem *addr) | |||
87 | iowrite32(val, addr); | 87 | iowrite32(val, addr); |
88 | } | 88 | } |
89 | 89 | ||
90 | static struct uartlite_reg_ops uartlite_le = { | 90 | static const struct uartlite_reg_ops uartlite_le = { |
91 | .in = uartlite_inle32, | 91 | .in = uartlite_inle32, |
92 | .out = uartlite_outle32, | 92 | .out = uartlite_outle32, |
93 | }; | 93 | }; |
94 | 94 | ||
95 | static inline u32 uart_in32(u32 offset, struct uart_port *port) | 95 | static inline u32 uart_in32(u32 offset, struct uart_port *port) |
96 | { | 96 | { |
97 | struct uartlite_reg_ops *reg_ops = port->private_data; | 97 | const struct uartlite_reg_ops *reg_ops = port->private_data; |
98 | 98 | ||
99 | return reg_ops->in(port->membase + offset); | 99 | return reg_ops->in(port->membase + offset); |
100 | } | 100 | } |
101 | 101 | ||
102 | static inline void uart_out32(u32 val, u32 offset, struct uart_port *port) | 102 | static inline void uart_out32(u32 val, u32 offset, struct uart_port *port) |
103 | { | 103 | { |
104 | struct uartlite_reg_ops *reg_ops = port->private_data; | 104 | const struct uartlite_reg_ops *reg_ops = port->private_data; |
105 | 105 | ||
106 | reg_ops->out(val, port->membase + offset); | 106 | reg_ops->out(val, port->membase + offset); |
107 | } | 107 | } |
@@ -193,12 +193,15 @@ static int ulite_transmit(struct uart_port *port, int stat) | |||
193 | static irqreturn_t ulite_isr(int irq, void *dev_id) | 193 | static irqreturn_t ulite_isr(int irq, void *dev_id) |
194 | { | 194 | { |
195 | struct uart_port *port = dev_id; | 195 | struct uart_port *port = dev_id; |
196 | int busy, n = 0; | 196 | int stat, busy, n = 0; |
197 | unsigned long flags; | ||
197 | 198 | ||
198 | do { | 199 | do { |
199 | int stat = uart_in32(ULITE_STATUS, port); | 200 | spin_lock_irqsave(&port->lock, flags); |
201 | stat = uart_in32(ULITE_STATUS, port); | ||
200 | busy = ulite_receive(port, stat); | 202 | busy = ulite_receive(port, stat); |
201 | busy |= ulite_transmit(port, stat); | 203 | busy |= ulite_transmit(port, stat); |
204 | spin_unlock_irqrestore(&port->lock, flags); | ||
202 | n++; | 205 | n++; |
203 | } while (busy); | 206 | } while (busy); |
204 | 207 | ||
@@ -259,7 +262,8 @@ static int ulite_startup(struct uart_port *port) | |||
259 | { | 262 | { |
260 | int ret; | 263 | int ret; |
261 | 264 | ||
262 | ret = request_irq(port->irq, ulite_isr, IRQF_SHARED, "uartlite", port); | 265 | ret = request_irq(port->irq, ulite_isr, IRQF_SHARED | IRQF_TRIGGER_RISING, |
266 | "uartlite", port); | ||
263 | if (ret) | 267 | if (ret) |
264 | return ret; | 268 | return ret; |
265 | 269 | ||
@@ -519,6 +523,47 @@ static int __init ulite_console_init(void) | |||
519 | 523 | ||
520 | console_initcall(ulite_console_init); | 524 | console_initcall(ulite_console_init); |
521 | 525 | ||
526 | static void early_uartlite_putc(struct uart_port *port, int c) | ||
527 | { | ||
528 | /* | ||
529 | * Limit how many times we'll spin waiting for TX FIFO status. | ||
530 | * This will prevent lockups if the base address is incorrectly | ||
531 | * set, or any other issue on the UARTLITE. | ||
532 | * This limit is pretty arbitrary, unless we are at about 10 baud | ||
533 | * we'll never timeout on a working UART. | ||
534 | */ | ||
535 | |||
536 | unsigned retries = 1000000; | ||
537 | /* read status bit - 0x8 offset */ | ||
538 | while (--retries && (readl(port->membase + 8) & (1 << 3))) | ||
539 | ; | ||
540 | |||
541 | /* Only attempt the iowrite if we didn't timeout */ | ||
542 | /* write to TX_FIFO - 0x4 offset */ | ||
543 | if (retries) | ||
544 | writel(c & 0xff, port->membase + 4); | ||
545 | } | ||
546 | |||
547 | static void early_uartlite_write(struct console *console, | ||
548 | const char *s, unsigned n) | ||
549 | { | ||
550 | struct earlycon_device *device = console->data; | ||
551 | uart_console_write(&device->port, s, n, early_uartlite_putc); | ||
552 | } | ||
553 | |||
554 | static int __init early_uartlite_setup(struct earlycon_device *device, | ||
555 | const char *options) | ||
556 | { | ||
557 | if (!device->port.membase) | ||
558 | return -ENODEV; | ||
559 | |||
560 | device->con->write = early_uartlite_write; | ||
561 | return 0; | ||
562 | } | ||
563 | EARLYCON_DECLARE(uartlite, early_uartlite_setup); | ||
564 | OF_EARLYCON_DECLARE(uartlite_b, "xlnx,opb-uartlite-1.00.b", early_uartlite_setup); | ||
565 | OF_EARLYCON_DECLARE(uartlite_a, "xlnx,xps-uartlite-1.00.a", early_uartlite_setup); | ||
566 | |||
522 | #endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */ | 567 | #endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */ |
523 | 568 | ||
524 | static struct uart_driver ulite_uart_driver = { | 569 | static struct uart_driver ulite_uart_driver = { |
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index 009e0dbc12d2..cd46e64c4255 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c | |||
@@ -50,24 +50,24 @@ module_param(rx_timeout, uint, S_IRUGO); | |||
50 | MODULE_PARM_DESC(rx_timeout, "Rx timeout, 1-255"); | 50 | MODULE_PARM_DESC(rx_timeout, "Rx timeout, 1-255"); |
51 | 51 | ||
52 | /* Register offsets for the UART. */ | 52 | /* Register offsets for the UART. */ |
53 | #define CDNS_UART_CR_OFFSET 0x00 /* Control Register */ | 53 | #define CDNS_UART_CR 0x00 /* Control Register */ |
54 | #define CDNS_UART_MR_OFFSET 0x04 /* Mode Register */ | 54 | #define CDNS_UART_MR 0x04 /* Mode Register */ |
55 | #define CDNS_UART_IER_OFFSET 0x08 /* Interrupt Enable */ | 55 | #define CDNS_UART_IER 0x08 /* Interrupt Enable */ |
56 | #define CDNS_UART_IDR_OFFSET 0x0C /* Interrupt Disable */ | 56 | #define CDNS_UART_IDR 0x0C /* Interrupt Disable */ |
57 | #define CDNS_UART_IMR_OFFSET 0x10 /* Interrupt Mask */ | 57 | #define CDNS_UART_IMR 0x10 /* Interrupt Mask */ |
58 | #define CDNS_UART_ISR_OFFSET 0x14 /* Interrupt Status */ | 58 | #define CDNS_UART_ISR 0x14 /* Interrupt Status */ |
59 | #define CDNS_UART_BAUDGEN_OFFSET 0x18 /* Baud Rate Generator */ | 59 | #define CDNS_UART_BAUDGEN 0x18 /* Baud Rate Generator */ |
60 | #define CDNS_UART_RXTOUT_OFFSET 0x1C /* RX Timeout */ | 60 | #define CDNS_UART_RXTOUT 0x1C /* RX Timeout */ |
61 | #define CDNS_UART_RXWM_OFFSET 0x20 /* RX FIFO Trigger Level */ | 61 | #define CDNS_UART_RXWM 0x20 /* RX FIFO Trigger Level */ |
62 | #define CDNS_UART_MODEMCR_OFFSET 0x24 /* Modem Control */ | 62 | #define CDNS_UART_MODEMCR 0x24 /* Modem Control */ |
63 | #define CDNS_UART_MODEMSR_OFFSET 0x28 /* Modem Status */ | 63 | #define CDNS_UART_MODEMSR 0x28 /* Modem Status */ |
64 | #define CDNS_UART_SR_OFFSET 0x2C /* Channel Status */ | 64 | #define CDNS_UART_SR 0x2C /* Channel Status */ |
65 | #define CDNS_UART_FIFO_OFFSET 0x30 /* FIFO */ | 65 | #define CDNS_UART_FIFO 0x30 /* FIFO */ |
66 | #define CDNS_UART_BAUDDIV_OFFSET 0x34 /* Baud Rate Divider */ | 66 | #define CDNS_UART_BAUDDIV 0x34 /* Baud Rate Divider */ |
67 | #define CDNS_UART_FLOWDEL_OFFSET 0x38 /* Flow Delay */ | 67 | #define CDNS_UART_FLOWDEL 0x38 /* Flow Delay */ |
68 | #define CDNS_UART_IRRX_PWIDTH_OFFSET 0x3C /* IR Min Received Pulse Width */ | 68 | #define CDNS_UART_IRRX_PWIDTH 0x3C /* IR Min Received Pulse Width */ |
69 | #define CDNS_UART_IRTX_PWIDTH_OFFSET 0x40 /* IR Transmitted pulse Width */ | 69 | #define CDNS_UART_IRTX_PWIDTH 0x40 /* IR Transmitted pulse Width */ |
70 | #define CDNS_UART_TXWM_OFFSET 0x44 /* TX FIFO Trigger Level */ | 70 | #define CDNS_UART_TXWM 0x44 /* TX FIFO Trigger Level */ |
71 | 71 | ||
72 | /* Control Register Bit Definitions */ | 72 | /* Control Register Bit Definitions */ |
73 | #define CDNS_UART_CR_STOPBRK 0x00000100 /* Stop TX break */ | 73 | #define CDNS_UART_CR_STOPBRK 0x00000100 /* Stop TX break */ |
@@ -126,6 +126,10 @@ MODULE_PARM_DESC(rx_timeout, "Rx timeout, 1-255"); | |||
126 | #define CDNS_UART_IXR_RXEMPTY 0x00000002 /* RX FIFO empty interrupt. */ | 126 | #define CDNS_UART_IXR_RXEMPTY 0x00000002 /* RX FIFO empty interrupt. */ |
127 | #define CDNS_UART_IXR_MASK 0x00001FFF /* Valid bit mask */ | 127 | #define CDNS_UART_IXR_MASK 0x00001FFF /* Valid bit mask */ |
128 | 128 | ||
129 | #define CDNS_UART_RX_IRQS (CDNS_UART_IXR_PARITY | CDNS_UART_IXR_FRAMING | \ | ||
130 | CDNS_UART_IXR_OVERRUN | CDNS_UART_IXR_RXTRIG | \ | ||
131 | CDNS_UART_IXR_TOUT) | ||
132 | |||
129 | /* Goes in read_status_mask for break detection as the HW doesn't do it*/ | 133 | /* Goes in read_status_mask for break detection as the HW doesn't do it*/ |
130 | #define CDNS_UART_IXR_BRK 0x80000000 | 134 | #define CDNS_UART_IXR_BRK 0x80000000 |
131 | 135 | ||
@@ -172,43 +176,22 @@ struct cdns_uart { | |||
172 | #define to_cdns_uart(_nb) container_of(_nb, struct cdns_uart, \ | 176 | #define to_cdns_uart(_nb) container_of(_nb, struct cdns_uart, \ |
173 | clk_rate_change_nb); | 177 | clk_rate_change_nb); |
174 | 178 | ||
175 | /** | 179 | static void cdns_uart_handle_rx(struct uart_port *port, unsigned int isrstatus) |
176 | * cdns_uart_isr - Interrupt handler | ||
177 | * @irq: Irq number | ||
178 | * @dev_id: Id of the port | ||
179 | * | ||
180 | * Return: IRQHANDLED | ||
181 | */ | ||
182 | static irqreturn_t cdns_uart_isr(int irq, void *dev_id) | ||
183 | { | 180 | { |
184 | struct uart_port *port = (struct uart_port *)dev_id; | ||
185 | unsigned long flags; | ||
186 | unsigned int isrstatus, numbytes; | ||
187 | unsigned int data; | ||
188 | char status = TTY_NORMAL; | ||
189 | |||
190 | spin_lock_irqsave(&port->lock, flags); | ||
191 | |||
192 | /* Read the interrupt status register to determine which | ||
193 | * interrupt(s) is/are active. | ||
194 | */ | ||
195 | isrstatus = readl(port->membase + CDNS_UART_ISR_OFFSET); | ||
196 | |||
197 | /* | 181 | /* |
198 | * There is no hardware break detection, so we interpret framing | 182 | * There is no hardware break detection, so we interpret framing |
199 | * error with all-zeros data as a break sequence. Most of the time, | 183 | * error with all-zeros data as a break sequence. Most of the time, |
200 | * there's another non-zero byte at the end of the sequence. | 184 | * there's another non-zero byte at the end of the sequence. |
201 | */ | 185 | */ |
202 | if (isrstatus & CDNS_UART_IXR_FRAMING) { | 186 | if (isrstatus & CDNS_UART_IXR_FRAMING) { |
203 | while (!(readl(port->membase + CDNS_UART_SR_OFFSET) & | 187 | while (!(readl(port->membase + CDNS_UART_SR) & |
204 | CDNS_UART_SR_RXEMPTY)) { | 188 | CDNS_UART_SR_RXEMPTY)) { |
205 | if (!readl(port->membase + CDNS_UART_FIFO_OFFSET)) { | 189 | if (!readl(port->membase + CDNS_UART_FIFO)) { |
206 | port->read_status_mask |= CDNS_UART_IXR_BRK; | 190 | port->read_status_mask |= CDNS_UART_IXR_BRK; |
207 | isrstatus &= ~CDNS_UART_IXR_FRAMING; | 191 | isrstatus &= ~CDNS_UART_IXR_FRAMING; |
208 | } | 192 | } |
209 | } | 193 | } |
210 | writel(CDNS_UART_IXR_FRAMING, | 194 | writel(CDNS_UART_IXR_FRAMING, port->membase + CDNS_UART_ISR); |
211 | port->membase + CDNS_UART_ISR_OFFSET); | ||
212 | } | 195 | } |
213 | 196 | ||
214 | /* drop byte with parity error if IGNPAR specified */ | 197 | /* drop byte with parity error if IGNPAR specified */ |
@@ -218,94 +201,106 @@ static irqreturn_t cdns_uart_isr(int irq, void *dev_id) | |||
218 | isrstatus &= port->read_status_mask; | 201 | isrstatus &= port->read_status_mask; |
219 | isrstatus &= ~port->ignore_status_mask; | 202 | isrstatus &= ~port->ignore_status_mask; |
220 | 203 | ||
221 | if ((isrstatus & CDNS_UART_IXR_TOUT) || | 204 | if (!(isrstatus & (CDNS_UART_IXR_TOUT | CDNS_UART_IXR_RXTRIG))) |
222 | (isrstatus & CDNS_UART_IXR_RXTRIG)) { | 205 | return; |
223 | /* Receive Timeout Interrupt */ | ||
224 | while (!(readl(port->membase + CDNS_UART_SR_OFFSET) & | ||
225 | CDNS_UART_SR_RXEMPTY)) { | ||
226 | data = readl(port->membase + CDNS_UART_FIFO_OFFSET); | ||
227 | |||
228 | /* Non-NULL byte after BREAK is garbage (99%) */ | ||
229 | if (data && (port->read_status_mask & | ||
230 | CDNS_UART_IXR_BRK)) { | ||
231 | port->read_status_mask &= ~CDNS_UART_IXR_BRK; | ||
232 | port->icount.brk++; | ||
233 | if (uart_handle_break(port)) | ||
234 | continue; | ||
235 | } | ||
236 | 206 | ||
237 | #ifdef SUPPORT_SYSRQ | 207 | while (!(readl(port->membase + CDNS_UART_SR) & CDNS_UART_SR_RXEMPTY)) { |
238 | /* | 208 | u32 data; |
239 | * uart_handle_sysrq_char() doesn't work if | 209 | char status = TTY_NORMAL; |
240 | * spinlocked, for some reason | ||
241 | */ | ||
242 | if (port->sysrq) { | ||
243 | spin_unlock(&port->lock); | ||
244 | if (uart_handle_sysrq_char(port, | ||
245 | (unsigned char)data)) { | ||
246 | spin_lock(&port->lock); | ||
247 | continue; | ||
248 | } | ||
249 | spin_lock(&port->lock); | ||
250 | } | ||
251 | #endif | ||
252 | 210 | ||
253 | port->icount.rx++; | 211 | data = readl(port->membase + CDNS_UART_FIFO); |
254 | 212 | ||
255 | if (isrstatus & CDNS_UART_IXR_PARITY) { | 213 | /* Non-NULL byte after BREAK is garbage (99%) */ |
256 | port->icount.parity++; | 214 | if (data && (port->read_status_mask & CDNS_UART_IXR_BRK)) { |
257 | status = TTY_PARITY; | 215 | port->read_status_mask &= ~CDNS_UART_IXR_BRK; |
258 | } else if (isrstatus & CDNS_UART_IXR_FRAMING) { | 216 | port->icount.brk++; |
259 | port->icount.frame++; | 217 | if (uart_handle_break(port)) |
260 | status = TTY_FRAME; | 218 | continue; |
261 | } else if (isrstatus & CDNS_UART_IXR_OVERRUN) { | 219 | } |
262 | port->icount.overrun++; | 220 | |
263 | } | 221 | if (uart_handle_sysrq_char(port, data)) |
222 | continue; | ||
223 | |||
224 | port->icount.rx++; | ||
264 | 225 | ||
265 | uart_insert_char(port, isrstatus, CDNS_UART_IXR_OVERRUN, | 226 | if (isrstatus & CDNS_UART_IXR_PARITY) { |
266 | data, status); | 227 | port->icount.parity++; |
228 | status = TTY_PARITY; | ||
229 | } else if (isrstatus & CDNS_UART_IXR_FRAMING) { | ||
230 | port->icount.frame++; | ||
231 | status = TTY_FRAME; | ||
232 | } else if (isrstatus & CDNS_UART_IXR_OVERRUN) { | ||
233 | port->icount.overrun++; | ||
267 | } | 234 | } |
268 | spin_unlock(&port->lock); | 235 | |
269 | tty_flip_buffer_push(&port->state->port); | 236 | uart_insert_char(port, isrstatus, CDNS_UART_IXR_OVERRUN, |
270 | spin_lock(&port->lock); | 237 | data, status); |
271 | } | 238 | } |
239 | tty_flip_buffer_push(&port->state->port); | ||
240 | } | ||
272 | 241 | ||
273 | /* Dispatch an appropriate handler */ | 242 | static void cdns_uart_handle_tx(struct uart_port *port) |
274 | if ((isrstatus & CDNS_UART_IXR_TXEMPTY) == CDNS_UART_IXR_TXEMPTY) { | 243 | { |
275 | if (uart_circ_empty(&port->state->xmit)) { | 244 | unsigned int numbytes; |
276 | writel(CDNS_UART_IXR_TXEMPTY, | ||
277 | port->membase + CDNS_UART_IDR_OFFSET); | ||
278 | } else { | ||
279 | numbytes = port->fifosize; | ||
280 | /* Break if no more data available in the UART buffer */ | ||
281 | while (numbytes--) { | ||
282 | if (uart_circ_empty(&port->state->xmit)) | ||
283 | break; | ||
284 | /* Get the data from the UART circular buffer | ||
285 | * and write it to the cdns_uart's TX_FIFO | ||
286 | * register. | ||
287 | */ | ||
288 | writel(port->state->xmit.buf[ | ||
289 | port->state->xmit.tail], | ||
290 | port->membase + CDNS_UART_FIFO_OFFSET); | ||
291 | |||
292 | port->icount.tx++; | ||
293 | |||
294 | /* Adjust the tail of the UART buffer and wrap | ||
295 | * the buffer if it reaches limit. | ||
296 | */ | ||
297 | port->state->xmit.tail = | ||
298 | (port->state->xmit.tail + 1) & | ||
299 | (UART_XMIT_SIZE - 1); | ||
300 | } | ||
301 | 245 | ||
302 | if (uart_circ_chars_pending( | 246 | if (uart_circ_empty(&port->state->xmit)) { |
303 | &port->state->xmit) < WAKEUP_CHARS) | 247 | writel(CDNS_UART_IXR_TXEMPTY, port->membase + CDNS_UART_IDR); |
304 | uart_write_wakeup(port); | 248 | return; |
305 | } | 249 | } |
250 | |||
251 | numbytes = port->fifosize; | ||
252 | while (numbytes && !uart_circ_empty(&port->state->xmit) && | ||
253 | !(readl(port->membase + CDNS_UART_SR) & CDNS_UART_SR_TXFULL)) { | ||
254 | /* | ||
255 | * Get the data from the UART circular buffer | ||
256 | * and write it to the cdns_uart's TX_FIFO | ||
257 | * register. | ||
258 | */ | ||
259 | writel(port->state->xmit.buf[port->state->xmit.tail], | ||
260 | port->membase + CDNS_UART_FIFO); | ||
261 | port->icount.tx++; | ||
262 | |||
263 | /* | ||
264 | * Adjust the tail of the UART buffer and wrap | ||
265 | * the buffer if it reaches limit. | ||
266 | */ | ||
267 | port->state->xmit.tail = | ||
268 | (port->state->xmit.tail + 1) & (UART_XMIT_SIZE - 1); | ||
269 | |||
270 | numbytes--; | ||
306 | } | 271 | } |
307 | 272 | ||
308 | writel(isrstatus, port->membase + CDNS_UART_ISR_OFFSET); | 273 | if (uart_circ_chars_pending(&port->state->xmit) < WAKEUP_CHARS) |
274 | uart_write_wakeup(port); | ||
275 | } | ||
276 | |||
277 | /** | ||
278 | * cdns_uart_isr - Interrupt handler | ||
279 | * @irq: Irq number | ||
280 | * @dev_id: Id of the port | ||
281 | * | ||
282 | * Return: IRQHANDLED | ||
283 | */ | ||
284 | static irqreturn_t cdns_uart_isr(int irq, void *dev_id) | ||
285 | { | ||
286 | struct uart_port *port = (struct uart_port *)dev_id; | ||
287 | unsigned long flags; | ||
288 | unsigned int isrstatus; | ||
289 | |||
290 | spin_lock_irqsave(&port->lock, flags); | ||
291 | |||
292 | /* Read the interrupt status register to determine which | ||
293 | * interrupt(s) is/are active. | ||
294 | */ | ||
295 | isrstatus = readl(port->membase + CDNS_UART_ISR); | ||
296 | |||
297 | if (isrstatus & CDNS_UART_RX_IRQS) | ||
298 | cdns_uart_handle_rx(port, isrstatus); | ||
299 | |||
300 | if ((isrstatus & CDNS_UART_IXR_TXEMPTY) == CDNS_UART_IXR_TXEMPTY) | ||
301 | cdns_uart_handle_tx(port); | ||
302 | |||
303 | writel(isrstatus, port->membase + CDNS_UART_ISR); | ||
309 | 304 | ||
310 | /* be sure to release the lock and tty before leaving */ | 305 | /* be sure to release the lock and tty before leaving */ |
311 | spin_unlock_irqrestore(&port->lock, flags); | 306 | spin_unlock_irqrestore(&port->lock, flags); |
@@ -395,14 +390,14 @@ static unsigned int cdns_uart_set_baud_rate(struct uart_port *port, | |||
395 | &div8); | 390 | &div8); |
396 | 391 | ||
397 | /* Write new divisors to hardware */ | 392 | /* Write new divisors to hardware */ |
398 | mreg = readl(port->membase + CDNS_UART_MR_OFFSET); | 393 | mreg = readl(port->membase + CDNS_UART_MR); |
399 | if (div8) | 394 | if (div8) |
400 | mreg |= CDNS_UART_MR_CLKSEL; | 395 | mreg |= CDNS_UART_MR_CLKSEL; |
401 | else | 396 | else |
402 | mreg &= ~CDNS_UART_MR_CLKSEL; | 397 | mreg &= ~CDNS_UART_MR_CLKSEL; |
403 | writel(mreg, port->membase + CDNS_UART_MR_OFFSET); | 398 | writel(mreg, port->membase + CDNS_UART_MR); |
404 | writel(cd, port->membase + CDNS_UART_BAUDGEN_OFFSET); | 399 | writel(cd, port->membase + CDNS_UART_BAUDGEN); |
405 | writel(bdiv, port->membase + CDNS_UART_BAUDDIV_OFFSET); | 400 | writel(bdiv, port->membase + CDNS_UART_BAUDDIV); |
406 | cdns_uart->baud = baud; | 401 | cdns_uart->baud = baud; |
407 | 402 | ||
408 | return calc_baud; | 403 | return calc_baud; |
@@ -449,9 +444,9 @@ static int cdns_uart_clk_notifier_cb(struct notifier_block *nb, | |||
449 | spin_lock_irqsave(&cdns_uart->port->lock, flags); | 444 | spin_lock_irqsave(&cdns_uart->port->lock, flags); |
450 | 445 | ||
451 | /* Disable the TX and RX to set baud rate */ | 446 | /* Disable the TX and RX to set baud rate */ |
452 | ctrl_reg = readl(port->membase + CDNS_UART_CR_OFFSET); | 447 | ctrl_reg = readl(port->membase + CDNS_UART_CR); |
453 | ctrl_reg |= CDNS_UART_CR_TX_DIS | CDNS_UART_CR_RX_DIS; | 448 | ctrl_reg |= CDNS_UART_CR_TX_DIS | CDNS_UART_CR_RX_DIS; |
454 | writel(ctrl_reg, port->membase + CDNS_UART_CR_OFFSET); | 449 | writel(ctrl_reg, port->membase + CDNS_UART_CR); |
455 | 450 | ||
456 | spin_unlock_irqrestore(&cdns_uart->port->lock, flags); | 451 | spin_unlock_irqrestore(&cdns_uart->port->lock, flags); |
457 | 452 | ||
@@ -476,11 +471,11 @@ static int cdns_uart_clk_notifier_cb(struct notifier_block *nb, | |||
476 | spin_lock_irqsave(&cdns_uart->port->lock, flags); | 471 | spin_lock_irqsave(&cdns_uart->port->lock, flags); |
477 | 472 | ||
478 | /* Set TX/RX Reset */ | 473 | /* Set TX/RX Reset */ |
479 | ctrl_reg = readl(port->membase + CDNS_UART_CR_OFFSET); | 474 | ctrl_reg = readl(port->membase + CDNS_UART_CR); |
480 | ctrl_reg |= CDNS_UART_CR_TXRST | CDNS_UART_CR_RXRST; | 475 | ctrl_reg |= CDNS_UART_CR_TXRST | CDNS_UART_CR_RXRST; |
481 | writel(ctrl_reg, port->membase + CDNS_UART_CR_OFFSET); | 476 | writel(ctrl_reg, port->membase + CDNS_UART_CR); |
482 | 477 | ||
483 | while (readl(port->membase + CDNS_UART_CR_OFFSET) & | 478 | while (readl(port->membase + CDNS_UART_CR) & |
484 | (CDNS_UART_CR_TXRST | CDNS_UART_CR_RXRST)) | 479 | (CDNS_UART_CR_TXRST | CDNS_UART_CR_RXRST)) |
485 | cpu_relax(); | 480 | cpu_relax(); |
486 | 481 | ||
@@ -489,11 +484,11 @@ static int cdns_uart_clk_notifier_cb(struct notifier_block *nb, | |||
489 | * enable bit and RX enable bit to enable the transmitter and | 484 | * enable bit and RX enable bit to enable the transmitter and |
490 | * receiver. | 485 | * receiver. |
491 | */ | 486 | */ |
492 | writel(rx_timeout, port->membase + CDNS_UART_RXTOUT_OFFSET); | 487 | writel(rx_timeout, port->membase + CDNS_UART_RXTOUT); |
493 | ctrl_reg = readl(port->membase + CDNS_UART_CR_OFFSET); | 488 | ctrl_reg = readl(port->membase + CDNS_UART_CR); |
494 | ctrl_reg &= ~(CDNS_UART_CR_TX_DIS | CDNS_UART_CR_RX_DIS); | 489 | ctrl_reg &= ~(CDNS_UART_CR_TX_DIS | CDNS_UART_CR_RX_DIS); |
495 | ctrl_reg |= CDNS_UART_CR_TX_EN | CDNS_UART_CR_RX_EN; | 490 | ctrl_reg |= CDNS_UART_CR_TX_EN | CDNS_UART_CR_RX_EN; |
496 | writel(ctrl_reg, port->membase + CDNS_UART_CR_OFFSET); | 491 | writel(ctrl_reg, port->membase + CDNS_UART_CR); |
497 | 492 | ||
498 | spin_unlock_irqrestore(&cdns_uart->port->lock, flags); | 493 | spin_unlock_irqrestore(&cdns_uart->port->lock, flags); |
499 | 494 | ||
@@ -510,43 +505,28 @@ static int cdns_uart_clk_notifier_cb(struct notifier_block *nb, | |||
510 | */ | 505 | */ |
511 | static void cdns_uart_start_tx(struct uart_port *port) | 506 | static void cdns_uart_start_tx(struct uart_port *port) |
512 | { | 507 | { |
513 | unsigned int status, numbytes = port->fifosize; | 508 | unsigned int status; |
514 | 509 | ||
515 | if (uart_circ_empty(&port->state->xmit) || uart_tx_stopped(port)) | 510 | if (uart_tx_stopped(port)) |
516 | return; | 511 | return; |
517 | 512 | ||
518 | status = readl(port->membase + CDNS_UART_CR_OFFSET); | 513 | /* |
519 | /* Set the TX enable bit and clear the TX disable bit to enable the | 514 | * Set the TX enable bit and clear the TX disable bit to enable the |
520 | * transmitter. | 515 | * transmitter. |
521 | */ | 516 | */ |
522 | writel((status & ~CDNS_UART_CR_TX_DIS) | CDNS_UART_CR_TX_EN, | 517 | status = readl(port->membase + CDNS_UART_CR); |
523 | port->membase + CDNS_UART_CR_OFFSET); | 518 | status &= ~CDNS_UART_CR_TX_DIS; |
519 | status |= CDNS_UART_CR_TX_EN; | ||
520 | writel(status, port->membase + CDNS_UART_CR); | ||
524 | 521 | ||
525 | while (numbytes-- && ((readl(port->membase + CDNS_UART_SR_OFFSET) & | 522 | if (uart_circ_empty(&port->state->xmit)) |
526 | CDNS_UART_SR_TXFULL)) != CDNS_UART_SR_TXFULL) { | 523 | return; |
527 | /* Break if no more data available in the UART buffer */ | ||
528 | if (uart_circ_empty(&port->state->xmit)) | ||
529 | break; | ||
530 | 524 | ||
531 | /* Get the data from the UART circular buffer and | 525 | cdns_uart_handle_tx(port); |
532 | * write it to the cdns_uart's TX_FIFO register. | ||
533 | */ | ||
534 | writel(port->state->xmit.buf[port->state->xmit.tail], | ||
535 | port->membase + CDNS_UART_FIFO_OFFSET); | ||
536 | port->icount.tx++; | ||
537 | 526 | ||
538 | /* Adjust the tail of the UART buffer and wrap | 527 | writel(CDNS_UART_IXR_TXEMPTY, port->membase + CDNS_UART_ISR); |
539 | * the buffer if it reaches limit. | ||
540 | */ | ||
541 | port->state->xmit.tail = (port->state->xmit.tail + 1) & | ||
542 | (UART_XMIT_SIZE - 1); | ||
543 | } | ||
544 | writel(CDNS_UART_IXR_TXEMPTY, port->membase + CDNS_UART_ISR_OFFSET); | ||
545 | /* Enable the TX Empty interrupt */ | 528 | /* Enable the TX Empty interrupt */ |
546 | writel(CDNS_UART_IXR_TXEMPTY, port->membase + CDNS_UART_IER_OFFSET); | 529 | writel(CDNS_UART_IXR_TXEMPTY, port->membase + CDNS_UART_IER); |
547 | |||
548 | if (uart_circ_chars_pending(&port->state->xmit) < WAKEUP_CHARS) | ||
549 | uart_write_wakeup(port); | ||
550 | } | 530 | } |
551 | 531 | ||
552 | /** | 532 | /** |
@@ -557,10 +537,10 @@ static void cdns_uart_stop_tx(struct uart_port *port) | |||
557 | { | 537 | { |
558 | unsigned int regval; | 538 | unsigned int regval; |
559 | 539 | ||
560 | regval = readl(port->membase + CDNS_UART_CR_OFFSET); | 540 | regval = readl(port->membase + CDNS_UART_CR); |
561 | regval |= CDNS_UART_CR_TX_DIS; | 541 | regval |= CDNS_UART_CR_TX_DIS; |
562 | /* Disable the transmitter */ | 542 | /* Disable the transmitter */ |
563 | writel(regval, port->membase + CDNS_UART_CR_OFFSET); | 543 | writel(regval, port->membase + CDNS_UART_CR); |
564 | } | 544 | } |
565 | 545 | ||
566 | /** | 546 | /** |
@@ -571,10 +551,13 @@ static void cdns_uart_stop_rx(struct uart_port *port) | |||
571 | { | 551 | { |
572 | unsigned int regval; | 552 | unsigned int regval; |
573 | 553 | ||
574 | regval = readl(port->membase + CDNS_UART_CR_OFFSET); | 554 | /* Disable RX IRQs */ |
575 | regval |= CDNS_UART_CR_RX_DIS; | 555 | writel(CDNS_UART_RX_IRQS, port->membase + CDNS_UART_IDR); |
556 | |||
576 | /* Disable the receiver */ | 557 | /* Disable the receiver */ |
577 | writel(regval, port->membase + CDNS_UART_CR_OFFSET); | 558 | regval = readl(port->membase + CDNS_UART_CR); |
559 | regval |= CDNS_UART_CR_RX_DIS; | ||
560 | writel(regval, port->membase + CDNS_UART_CR); | ||
578 | } | 561 | } |
579 | 562 | ||
580 | /** | 563 | /** |
@@ -587,7 +570,7 @@ static unsigned int cdns_uart_tx_empty(struct uart_port *port) | |||
587 | { | 570 | { |
588 | unsigned int status; | 571 | unsigned int status; |
589 | 572 | ||
590 | status = readl(port->membase + CDNS_UART_SR_OFFSET) & | 573 | status = readl(port->membase + CDNS_UART_SR) & |
591 | CDNS_UART_SR_TXEMPTY; | 574 | CDNS_UART_SR_TXEMPTY; |
592 | return status ? TIOCSER_TEMT : 0; | 575 | return status ? TIOCSER_TEMT : 0; |
593 | } | 576 | } |
@@ -605,15 +588,15 @@ static void cdns_uart_break_ctl(struct uart_port *port, int ctl) | |||
605 | 588 | ||
606 | spin_lock_irqsave(&port->lock, flags); | 589 | spin_lock_irqsave(&port->lock, flags); |
607 | 590 | ||
608 | status = readl(port->membase + CDNS_UART_CR_OFFSET); | 591 | status = readl(port->membase + CDNS_UART_CR); |
609 | 592 | ||
610 | if (ctl == -1) | 593 | if (ctl == -1) |
611 | writel(CDNS_UART_CR_STARTBRK | status, | 594 | writel(CDNS_UART_CR_STARTBRK | status, |
612 | port->membase + CDNS_UART_CR_OFFSET); | 595 | port->membase + CDNS_UART_CR); |
613 | else { | 596 | else { |
614 | if ((status & CDNS_UART_CR_STOPBRK) == 0) | 597 | if ((status & CDNS_UART_CR_STOPBRK) == 0) |
615 | writel(CDNS_UART_CR_STOPBRK | status, | 598 | writel(CDNS_UART_CR_STOPBRK | status, |
616 | port->membase + CDNS_UART_CR_OFFSET); | 599 | port->membase + CDNS_UART_CR); |
617 | } | 600 | } |
618 | spin_unlock_irqrestore(&port->lock, flags); | 601 | spin_unlock_irqrestore(&port->lock, flags); |
619 | } | 602 | } |
@@ -636,18 +619,18 @@ static void cdns_uart_set_termios(struct uart_port *port, | |||
636 | spin_lock_irqsave(&port->lock, flags); | 619 | spin_lock_irqsave(&port->lock, flags); |
637 | 620 | ||
638 | /* Wait for the transmit FIFO to empty before making changes */ | 621 | /* Wait for the transmit FIFO to empty before making changes */ |
639 | if (!(readl(port->membase + CDNS_UART_CR_OFFSET) & | 622 | if (!(readl(port->membase + CDNS_UART_CR) & |
640 | CDNS_UART_CR_TX_DIS)) { | 623 | CDNS_UART_CR_TX_DIS)) { |
641 | while (!(readl(port->membase + CDNS_UART_SR_OFFSET) & | 624 | while (!(readl(port->membase + CDNS_UART_SR) & |
642 | CDNS_UART_SR_TXEMPTY)) { | 625 | CDNS_UART_SR_TXEMPTY)) { |
643 | cpu_relax(); | 626 | cpu_relax(); |
644 | } | 627 | } |
645 | } | 628 | } |
646 | 629 | ||
647 | /* Disable the TX and RX to set baud rate */ | 630 | /* Disable the TX and RX to set baud rate */ |
648 | ctrl_reg = readl(port->membase + CDNS_UART_CR_OFFSET); | 631 | ctrl_reg = readl(port->membase + CDNS_UART_CR); |
649 | ctrl_reg |= CDNS_UART_CR_TX_DIS | CDNS_UART_CR_RX_DIS; | 632 | ctrl_reg |= CDNS_UART_CR_TX_DIS | CDNS_UART_CR_RX_DIS; |
650 | writel(ctrl_reg, port->membase + CDNS_UART_CR_OFFSET); | 633 | writel(ctrl_reg, port->membase + CDNS_UART_CR); |
651 | 634 | ||
652 | /* | 635 | /* |
653 | * Min baud rate = 6bps and Max Baud Rate is 10Mbps for 100Mhz clk | 636 | * Min baud rate = 6bps and Max Baud Rate is 10Mbps for 100Mhz clk |
@@ -666,20 +649,20 @@ static void cdns_uart_set_termios(struct uart_port *port, | |||
666 | uart_update_timeout(port, termios->c_cflag, baud); | 649 | uart_update_timeout(port, termios->c_cflag, baud); |
667 | 650 | ||
668 | /* Set TX/RX Reset */ | 651 | /* Set TX/RX Reset */ |
669 | ctrl_reg = readl(port->membase + CDNS_UART_CR_OFFSET); | 652 | ctrl_reg = readl(port->membase + CDNS_UART_CR); |
670 | ctrl_reg |= CDNS_UART_CR_TXRST | CDNS_UART_CR_RXRST; | 653 | ctrl_reg |= CDNS_UART_CR_TXRST | CDNS_UART_CR_RXRST; |
671 | writel(ctrl_reg, port->membase + CDNS_UART_CR_OFFSET); | 654 | writel(ctrl_reg, port->membase + CDNS_UART_CR); |
672 | 655 | ||
673 | /* | 656 | /* |
674 | * Clear the RX disable and TX disable bits and then set the TX enable | 657 | * Clear the RX disable and TX disable bits and then set the TX enable |
675 | * bit and RX enable bit to enable the transmitter and receiver. | 658 | * bit and RX enable bit to enable the transmitter and receiver. |
676 | */ | 659 | */ |
677 | ctrl_reg = readl(port->membase + CDNS_UART_CR_OFFSET); | 660 | ctrl_reg = readl(port->membase + CDNS_UART_CR); |
678 | ctrl_reg &= ~(CDNS_UART_CR_TX_DIS | CDNS_UART_CR_RX_DIS); | 661 | ctrl_reg &= ~(CDNS_UART_CR_TX_DIS | CDNS_UART_CR_RX_DIS); |
679 | ctrl_reg |= CDNS_UART_CR_TX_EN | CDNS_UART_CR_RX_EN; | 662 | ctrl_reg |= CDNS_UART_CR_TX_EN | CDNS_UART_CR_RX_EN; |
680 | writel(ctrl_reg, port->membase + CDNS_UART_CR_OFFSET); | 663 | writel(ctrl_reg, port->membase + CDNS_UART_CR); |
681 | 664 | ||
682 | writel(rx_timeout, port->membase + CDNS_UART_RXTOUT_OFFSET); | 665 | writel(rx_timeout, port->membase + CDNS_UART_RXTOUT); |
683 | 666 | ||
684 | port->read_status_mask = CDNS_UART_IXR_TXEMPTY | CDNS_UART_IXR_RXTRIG | | 667 | port->read_status_mask = CDNS_UART_IXR_TXEMPTY | CDNS_UART_IXR_RXTRIG | |
685 | CDNS_UART_IXR_OVERRUN | CDNS_UART_IXR_TOUT; | 668 | CDNS_UART_IXR_OVERRUN | CDNS_UART_IXR_TOUT; |
@@ -699,7 +682,7 @@ static void cdns_uart_set_termios(struct uart_port *port, | |||
699 | CDNS_UART_IXR_TOUT | CDNS_UART_IXR_PARITY | | 682 | CDNS_UART_IXR_TOUT | CDNS_UART_IXR_PARITY | |
700 | CDNS_UART_IXR_FRAMING | CDNS_UART_IXR_OVERRUN; | 683 | CDNS_UART_IXR_FRAMING | CDNS_UART_IXR_OVERRUN; |
701 | 684 | ||
702 | mode_reg = readl(port->membase + CDNS_UART_MR_OFFSET); | 685 | mode_reg = readl(port->membase + CDNS_UART_MR); |
703 | 686 | ||
704 | /* Handling Data Size */ | 687 | /* Handling Data Size */ |
705 | switch (termios->c_cflag & CSIZE) { | 688 | switch (termios->c_cflag & CSIZE) { |
@@ -740,7 +723,7 @@ static void cdns_uart_set_termios(struct uart_port *port, | |||
740 | cval |= CDNS_UART_MR_PARITY_NONE; | 723 | cval |= CDNS_UART_MR_PARITY_NONE; |
741 | } | 724 | } |
742 | cval |= mode_reg & 1; | 725 | cval |= mode_reg & 1; |
743 | writel(cval, port->membase + CDNS_UART_MR_OFFSET); | 726 | writel(cval, port->membase + CDNS_UART_MR); |
744 | 727 | ||
745 | spin_unlock_irqrestore(&port->lock, flags); | 728 | spin_unlock_irqrestore(&port->lock, flags); |
746 | } | 729 | } |
@@ -753,63 +736,67 @@ static void cdns_uart_set_termios(struct uart_port *port, | |||
753 | */ | 736 | */ |
754 | static int cdns_uart_startup(struct uart_port *port) | 737 | static int cdns_uart_startup(struct uart_port *port) |
755 | { | 738 | { |
756 | unsigned int retval = 0, status = 0; | 739 | int ret; |
740 | unsigned long flags; | ||
741 | unsigned int status = 0; | ||
757 | 742 | ||
758 | retval = request_irq(port->irq, cdns_uart_isr, 0, CDNS_UART_NAME, | 743 | spin_lock_irqsave(&port->lock, flags); |
759 | (void *)port); | ||
760 | if (retval) | ||
761 | return retval; | ||
762 | 744 | ||
763 | /* Disable the TX and RX */ | 745 | /* Disable the TX and RX */ |
764 | writel(CDNS_UART_CR_TX_DIS | CDNS_UART_CR_RX_DIS, | 746 | writel(CDNS_UART_CR_TX_DIS | CDNS_UART_CR_RX_DIS, |
765 | port->membase + CDNS_UART_CR_OFFSET); | 747 | port->membase + CDNS_UART_CR); |
766 | 748 | ||
767 | /* Set the Control Register with TX/RX Enable, TX/RX Reset, | 749 | /* Set the Control Register with TX/RX Enable, TX/RX Reset, |
768 | * no break chars. | 750 | * no break chars. |
769 | */ | 751 | */ |
770 | writel(CDNS_UART_CR_TXRST | CDNS_UART_CR_RXRST, | 752 | writel(CDNS_UART_CR_TXRST | CDNS_UART_CR_RXRST, |
771 | port->membase + CDNS_UART_CR_OFFSET); | 753 | port->membase + CDNS_UART_CR); |
772 | |||
773 | status = readl(port->membase + CDNS_UART_CR_OFFSET); | ||
774 | 754 | ||
775 | /* Clear the RX disable and TX disable bits and then set the TX enable | 755 | /* |
776 | * bit and RX enable bit to enable the transmitter and receiver. | 756 | * Clear the RX disable bit and then set the RX enable bit to enable |
757 | * the receiver. | ||
777 | */ | 758 | */ |
778 | writel((status & ~(CDNS_UART_CR_TX_DIS | CDNS_UART_CR_RX_DIS)) | 759 | status = readl(port->membase + CDNS_UART_CR); |
779 | | (CDNS_UART_CR_TX_EN | CDNS_UART_CR_RX_EN | | 760 | status &= CDNS_UART_CR_RX_DIS; |
780 | CDNS_UART_CR_STOPBRK), | 761 | status |= CDNS_UART_CR_RX_EN; |
781 | port->membase + CDNS_UART_CR_OFFSET); | 762 | writel(status, port->membase + CDNS_UART_CR); |
782 | 763 | ||
783 | /* Set the Mode Register with normal mode,8 data bits,1 stop bit, | 764 | /* Set the Mode Register with normal mode,8 data bits,1 stop bit, |
784 | * no parity. | 765 | * no parity. |
785 | */ | 766 | */ |
786 | writel(CDNS_UART_MR_CHMODE_NORM | CDNS_UART_MR_STOPMODE_1_BIT | 767 | writel(CDNS_UART_MR_CHMODE_NORM | CDNS_UART_MR_STOPMODE_1_BIT |
787 | | CDNS_UART_MR_PARITY_NONE | CDNS_UART_MR_CHARLEN_8_BIT, | 768 | | CDNS_UART_MR_PARITY_NONE | CDNS_UART_MR_CHARLEN_8_BIT, |
788 | port->membase + CDNS_UART_MR_OFFSET); | 769 | port->membase + CDNS_UART_MR); |
789 | 770 | ||
790 | /* | 771 | /* |
791 | * Set the RX FIFO Trigger level to use most of the FIFO, but it | 772 | * Set the RX FIFO Trigger level to use most of the FIFO, but it |
792 | * can be tuned with a module parameter | 773 | * can be tuned with a module parameter |
793 | */ | 774 | */ |
794 | writel(rx_trigger_level, port->membase + CDNS_UART_RXWM_OFFSET); | 775 | writel(rx_trigger_level, port->membase + CDNS_UART_RXWM); |
795 | 776 | ||
796 | /* | 777 | /* |
797 | * Receive Timeout register is enabled but it | 778 | * Receive Timeout register is enabled but it |
798 | * can be tuned with a module parameter | 779 | * can be tuned with a module parameter |
799 | */ | 780 | */ |
800 | writel(rx_timeout, port->membase + CDNS_UART_RXTOUT_OFFSET); | 781 | writel(rx_timeout, port->membase + CDNS_UART_RXTOUT); |
801 | 782 | ||
802 | /* Clear out any pending interrupts before enabling them */ | 783 | /* Clear out any pending interrupts before enabling them */ |
803 | writel(readl(port->membase + CDNS_UART_ISR_OFFSET), | 784 | writel(readl(port->membase + CDNS_UART_ISR), |
804 | port->membase + CDNS_UART_ISR_OFFSET); | 785 | port->membase + CDNS_UART_ISR); |
786 | |||
787 | spin_unlock_irqrestore(&port->lock, flags); | ||
788 | |||
789 | ret = request_irq(port->irq, cdns_uart_isr, 0, CDNS_UART_NAME, port); | ||
790 | if (ret) { | ||
791 | dev_err(port->dev, "request_irq '%d' failed with %d\n", | ||
792 | port->irq, ret); | ||
793 | return ret; | ||
794 | } | ||
805 | 795 | ||
806 | /* Set the Interrupt Registers with desired interrupts */ | 796 | /* Set the Interrupt Registers with desired interrupts */ |
807 | writel(CDNS_UART_IXR_TXEMPTY | CDNS_UART_IXR_PARITY | | 797 | writel(CDNS_UART_RX_IRQS, port->membase + CDNS_UART_IER); |
808 | CDNS_UART_IXR_FRAMING | CDNS_UART_IXR_OVERRUN | | ||
809 | CDNS_UART_IXR_RXTRIG | CDNS_UART_IXR_TOUT, | ||
810 | port->membase + CDNS_UART_IER_OFFSET); | ||
811 | 798 | ||
812 | return retval; | 799 | return 0; |
813 | } | 800 | } |
814 | 801 | ||
815 | /** | 802 | /** |
@@ -819,14 +806,21 @@ static int cdns_uart_startup(struct uart_port *port) | |||
819 | static void cdns_uart_shutdown(struct uart_port *port) | 806 | static void cdns_uart_shutdown(struct uart_port *port) |
820 | { | 807 | { |
821 | int status; | 808 | int status; |
809 | unsigned long flags; | ||
810 | |||
811 | spin_lock_irqsave(&port->lock, flags); | ||
822 | 812 | ||
823 | /* Disable interrupts */ | 813 | /* Disable interrupts */ |
824 | status = readl(port->membase + CDNS_UART_IMR_OFFSET); | 814 | status = readl(port->membase + CDNS_UART_IMR); |
825 | writel(status, port->membase + CDNS_UART_IDR_OFFSET); | 815 | writel(status, port->membase + CDNS_UART_IDR); |
816 | writel(0xffffffff, port->membase + CDNS_UART_ISR); | ||
826 | 817 | ||
827 | /* Disable the TX and RX */ | 818 | /* Disable the TX and RX */ |
828 | writel(CDNS_UART_CR_TX_DIS | CDNS_UART_CR_RX_DIS, | 819 | writel(CDNS_UART_CR_TX_DIS | CDNS_UART_CR_RX_DIS, |
829 | port->membase + CDNS_UART_CR_OFFSET); | 820 | port->membase + CDNS_UART_CR); |
821 | |||
822 | spin_unlock_irqrestore(&port->lock, flags); | ||
823 | |||
830 | free_irq(port->irq, port); | 824 | free_irq(port->irq, port); |
831 | } | 825 | } |
832 | 826 | ||
@@ -928,7 +922,7 @@ static void cdns_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
928 | { | 922 | { |
929 | u32 val; | 923 | u32 val; |
930 | 924 | ||
931 | val = readl(port->membase + CDNS_UART_MODEMCR_OFFSET); | 925 | val = readl(port->membase + CDNS_UART_MODEMCR); |
932 | 926 | ||
933 | val &= ~(CDNS_UART_MODEMCR_RTS | CDNS_UART_MODEMCR_DTR); | 927 | val &= ~(CDNS_UART_MODEMCR_RTS | CDNS_UART_MODEMCR_DTR); |
934 | 928 | ||
@@ -937,55 +931,46 @@ static void cdns_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
937 | if (mctrl & TIOCM_DTR) | 931 | if (mctrl & TIOCM_DTR) |
938 | val |= CDNS_UART_MODEMCR_DTR; | 932 | val |= CDNS_UART_MODEMCR_DTR; |
939 | 933 | ||
940 | writel(val, port->membase + CDNS_UART_MODEMCR_OFFSET); | 934 | writel(val, port->membase + CDNS_UART_MODEMCR); |
941 | } | 935 | } |
942 | 936 | ||
943 | #ifdef CONFIG_CONSOLE_POLL | 937 | #ifdef CONFIG_CONSOLE_POLL |
944 | static int cdns_uart_poll_get_char(struct uart_port *port) | 938 | static int cdns_uart_poll_get_char(struct uart_port *port) |
945 | { | 939 | { |
946 | u32 imr; | ||
947 | int c; | 940 | int c; |
941 | unsigned long flags; | ||
948 | 942 | ||
949 | /* Disable all interrupts */ | 943 | spin_lock_irqsave(&port->lock, flags); |
950 | imr = readl(port->membase + CDNS_UART_IMR_OFFSET); | ||
951 | writel(imr, port->membase + CDNS_UART_IDR_OFFSET); | ||
952 | 944 | ||
953 | /* Check if FIFO is empty */ | 945 | /* Check if FIFO is empty */ |
954 | if (readl(port->membase + CDNS_UART_SR_OFFSET) & CDNS_UART_SR_RXEMPTY) | 946 | if (readl(port->membase + CDNS_UART_SR) & CDNS_UART_SR_RXEMPTY) |
955 | c = NO_POLL_CHAR; | 947 | c = NO_POLL_CHAR; |
956 | else /* Read a character */ | 948 | else /* Read a character */ |
957 | c = (unsigned char) readl( | 949 | c = (unsigned char) readl(port->membase + CDNS_UART_FIFO); |
958 | port->membase + CDNS_UART_FIFO_OFFSET); | ||
959 | 950 | ||
960 | /* Enable interrupts */ | 951 | spin_unlock_irqrestore(&port->lock, flags); |
961 | writel(imr, port->membase + CDNS_UART_IER_OFFSET); | ||
962 | 952 | ||
963 | return c; | 953 | return c; |
964 | } | 954 | } |
965 | 955 | ||
966 | static void cdns_uart_poll_put_char(struct uart_port *port, unsigned char c) | 956 | static void cdns_uart_poll_put_char(struct uart_port *port, unsigned char c) |
967 | { | 957 | { |
968 | u32 imr; | 958 | unsigned long flags; |
969 | 959 | ||
970 | /* Disable all interrupts */ | 960 | spin_lock_irqsave(&port->lock, flags); |
971 | imr = readl(port->membase + CDNS_UART_IMR_OFFSET); | ||
972 | writel(imr, port->membase + CDNS_UART_IDR_OFFSET); | ||
973 | 961 | ||
974 | /* Wait until FIFO is empty */ | 962 | /* Wait until FIFO is empty */ |
975 | while (!(readl(port->membase + CDNS_UART_SR_OFFSET) & | 963 | while (!(readl(port->membase + CDNS_UART_SR) & CDNS_UART_SR_TXEMPTY)) |
976 | CDNS_UART_SR_TXEMPTY)) | ||
977 | cpu_relax(); | 964 | cpu_relax(); |
978 | 965 | ||
979 | /* Write a character */ | 966 | /* Write a character */ |
980 | writel(c, port->membase + CDNS_UART_FIFO_OFFSET); | 967 | writel(c, port->membase + CDNS_UART_FIFO); |
981 | 968 | ||
982 | /* Wait until FIFO is empty */ | 969 | /* Wait until FIFO is empty */ |
983 | while (!(readl(port->membase + CDNS_UART_SR_OFFSET) & | 970 | while (!(readl(port->membase + CDNS_UART_SR) & CDNS_UART_SR_TXEMPTY)) |
984 | CDNS_UART_SR_TXEMPTY)) | ||
985 | cpu_relax(); | 971 | cpu_relax(); |
986 | 972 | ||
987 | /* Enable interrupts */ | 973 | spin_unlock_irqrestore(&port->lock, flags); |
988 | writel(imr, port->membase + CDNS_UART_IER_OFFSET); | ||
989 | 974 | ||
990 | return; | 975 | return; |
991 | } | 976 | } |
@@ -1059,8 +1044,7 @@ static struct uart_port *cdns_uart_get_port(int id) | |||
1059 | */ | 1044 | */ |
1060 | static void cdns_uart_console_wait_tx(struct uart_port *port) | 1045 | static void cdns_uart_console_wait_tx(struct uart_port *port) |
1061 | { | 1046 | { |
1062 | while (!(readl(port->membase + CDNS_UART_SR_OFFSET) & | 1047 | while (!(readl(port->membase + CDNS_UART_SR) & CDNS_UART_SR_TXEMPTY)) |
1063 | CDNS_UART_SR_TXEMPTY)) | ||
1064 | barrier(); | 1048 | barrier(); |
1065 | } | 1049 | } |
1066 | 1050 | ||
@@ -1072,7 +1056,7 @@ static void cdns_uart_console_wait_tx(struct uart_port *port) | |||
1072 | static void cdns_uart_console_putchar(struct uart_port *port, int ch) | 1056 | static void cdns_uart_console_putchar(struct uart_port *port, int ch) |
1073 | { | 1057 | { |
1074 | cdns_uart_console_wait_tx(port); | 1058 | cdns_uart_console_wait_tx(port); |
1075 | writel(ch, port->membase + CDNS_UART_FIFO_OFFSET); | 1059 | writel(ch, port->membase + CDNS_UART_FIFO); |
1076 | } | 1060 | } |
1077 | 1061 | ||
1078 | static void __init cdns_early_write(struct console *con, const char *s, | 1062 | static void __init cdns_early_write(struct console *con, const char *s, |
@@ -1093,7 +1077,9 @@ static int __init cdns_early_console_setup(struct earlycon_device *device, | |||
1093 | 1077 | ||
1094 | return 0; | 1078 | return 0; |
1095 | } | 1079 | } |
1096 | EARLYCON_DECLARE(cdns, cdns_early_console_setup); | 1080 | OF_EARLYCON_DECLARE(cdns, "xlnx,xuartps", cdns_early_console_setup); |
1081 | OF_EARLYCON_DECLARE(cdns, "cdns,uart-r1p8", cdns_early_console_setup); | ||
1082 | OF_EARLYCON_DECLARE(cdns, "cdns,uart-r1p12", cdns_early_console_setup); | ||
1097 | 1083 | ||
1098 | /** | 1084 | /** |
1099 | * cdns_uart_console_write - perform write operation | 1085 | * cdns_uart_console_write - perform write operation |
@@ -1109,30 +1095,33 @@ static void cdns_uart_console_write(struct console *co, const char *s, | |||
1109 | unsigned int imr, ctrl; | 1095 | unsigned int imr, ctrl; |
1110 | int locked = 1; | 1096 | int locked = 1; |
1111 | 1097 | ||
1112 | if (oops_in_progress) | 1098 | if (port->sysrq) |
1099 | locked = 0; | ||
1100 | else if (oops_in_progress) | ||
1113 | locked = spin_trylock_irqsave(&port->lock, flags); | 1101 | locked = spin_trylock_irqsave(&port->lock, flags); |
1114 | else | 1102 | else |
1115 | spin_lock_irqsave(&port->lock, flags); | 1103 | spin_lock_irqsave(&port->lock, flags); |
1116 | 1104 | ||
1117 | /* save and disable interrupt */ | 1105 | /* save and disable interrupt */ |
1118 | imr = readl(port->membase + CDNS_UART_IMR_OFFSET); | 1106 | imr = readl(port->membase + CDNS_UART_IMR); |
1119 | writel(imr, port->membase + CDNS_UART_IDR_OFFSET); | 1107 | writel(imr, port->membase + CDNS_UART_IDR); |
1120 | 1108 | ||
1121 | /* | 1109 | /* |
1122 | * Make sure that the tx part is enabled. Set the TX enable bit and | 1110 | * Make sure that the tx part is enabled. Set the TX enable bit and |
1123 | * clear the TX disable bit to enable the transmitter. | 1111 | * clear the TX disable bit to enable the transmitter. |
1124 | */ | 1112 | */ |
1125 | ctrl = readl(port->membase + CDNS_UART_CR_OFFSET); | 1113 | ctrl = readl(port->membase + CDNS_UART_CR); |
1126 | writel((ctrl & ~CDNS_UART_CR_TX_DIS) | CDNS_UART_CR_TX_EN, | 1114 | ctrl &= ~CDNS_UART_CR_TX_DIS; |
1127 | port->membase + CDNS_UART_CR_OFFSET); | 1115 | ctrl |= CDNS_UART_CR_TX_EN; |
1116 | writel(ctrl, port->membase + CDNS_UART_CR); | ||
1128 | 1117 | ||
1129 | uart_console_write(port, s, count, cdns_uart_console_putchar); | 1118 | uart_console_write(port, s, count, cdns_uart_console_putchar); |
1130 | cdns_uart_console_wait_tx(port); | 1119 | cdns_uart_console_wait_tx(port); |
1131 | 1120 | ||
1132 | writel(ctrl, port->membase + CDNS_UART_CR_OFFSET); | 1121 | writel(ctrl, port->membase + CDNS_UART_CR); |
1133 | 1122 | ||
1134 | /* restore interrupt state */ | 1123 | /* restore interrupt state */ |
1135 | writel(imr, port->membase + CDNS_UART_IER_OFFSET); | 1124 | writel(imr, port->membase + CDNS_UART_IER); |
1136 | 1125 | ||
1137 | if (locked) | 1126 | if (locked) |
1138 | spin_unlock_irqrestore(&port->lock, flags); | 1127 | spin_unlock_irqrestore(&port->lock, flags); |
@@ -1244,14 +1233,13 @@ static int cdns_uart_suspend(struct device *device) | |||
1244 | 1233 | ||
1245 | spin_lock_irqsave(&port->lock, flags); | 1234 | spin_lock_irqsave(&port->lock, flags); |
1246 | /* Empty the receive FIFO 1st before making changes */ | 1235 | /* Empty the receive FIFO 1st before making changes */ |
1247 | while (!(readl(port->membase + CDNS_UART_SR_OFFSET) & | 1236 | while (!(readl(port->membase + CDNS_UART_SR) & |
1248 | CDNS_UART_SR_RXEMPTY)) | 1237 | CDNS_UART_SR_RXEMPTY)) |
1249 | readl(port->membase + CDNS_UART_FIFO_OFFSET); | 1238 | readl(port->membase + CDNS_UART_FIFO); |
1250 | /* set RX trigger level to 1 */ | 1239 | /* set RX trigger level to 1 */ |
1251 | writel(1, port->membase + CDNS_UART_RXWM_OFFSET); | 1240 | writel(1, port->membase + CDNS_UART_RXWM); |
1252 | /* disable RX timeout interrups */ | 1241 | /* disable RX timeout interrups */ |
1253 | writel(CDNS_UART_IXR_TOUT, | 1242 | writel(CDNS_UART_IXR_TOUT, port->membase + CDNS_UART_IDR); |
1254 | port->membase + CDNS_UART_IDR_OFFSET); | ||
1255 | spin_unlock_irqrestore(&port->lock, flags); | 1243 | spin_unlock_irqrestore(&port->lock, flags); |
1256 | } | 1244 | } |
1257 | 1245 | ||
@@ -1290,30 +1278,28 @@ static int cdns_uart_resume(struct device *device) | |||
1290 | spin_lock_irqsave(&port->lock, flags); | 1278 | spin_lock_irqsave(&port->lock, flags); |
1291 | 1279 | ||
1292 | /* Set TX/RX Reset */ | 1280 | /* Set TX/RX Reset */ |
1293 | ctrl_reg = readl(port->membase + CDNS_UART_CR_OFFSET); | 1281 | ctrl_reg = readl(port->membase + CDNS_UART_CR); |
1294 | ctrl_reg |= CDNS_UART_CR_TXRST | CDNS_UART_CR_RXRST; | 1282 | ctrl_reg |= CDNS_UART_CR_TXRST | CDNS_UART_CR_RXRST; |
1295 | writel(ctrl_reg, port->membase + CDNS_UART_CR_OFFSET); | 1283 | writel(ctrl_reg, port->membase + CDNS_UART_CR); |
1296 | while (readl(port->membase + CDNS_UART_CR_OFFSET) & | 1284 | while (readl(port->membase + CDNS_UART_CR) & |
1297 | (CDNS_UART_CR_TXRST | CDNS_UART_CR_RXRST)) | 1285 | (CDNS_UART_CR_TXRST | CDNS_UART_CR_RXRST)) |
1298 | cpu_relax(); | 1286 | cpu_relax(); |
1299 | 1287 | ||
1300 | /* restore rx timeout value */ | 1288 | /* restore rx timeout value */ |
1301 | writel(rx_timeout, port->membase + CDNS_UART_RXTOUT_OFFSET); | 1289 | writel(rx_timeout, port->membase + CDNS_UART_RXTOUT); |
1302 | /* Enable Tx/Rx */ | 1290 | /* Enable Tx/Rx */ |
1303 | ctrl_reg = readl(port->membase + CDNS_UART_CR_OFFSET); | 1291 | ctrl_reg = readl(port->membase + CDNS_UART_CR); |
1304 | ctrl_reg &= ~(CDNS_UART_CR_TX_DIS | CDNS_UART_CR_RX_DIS); | 1292 | ctrl_reg &= ~(CDNS_UART_CR_TX_DIS | CDNS_UART_CR_RX_DIS); |
1305 | ctrl_reg |= CDNS_UART_CR_TX_EN | CDNS_UART_CR_RX_EN; | 1293 | ctrl_reg |= CDNS_UART_CR_TX_EN | CDNS_UART_CR_RX_EN; |
1306 | writel(ctrl_reg, port->membase + CDNS_UART_CR_OFFSET); | 1294 | writel(ctrl_reg, port->membase + CDNS_UART_CR); |
1307 | 1295 | ||
1308 | spin_unlock_irqrestore(&port->lock, flags); | 1296 | spin_unlock_irqrestore(&port->lock, flags); |
1309 | } else { | 1297 | } else { |
1310 | spin_lock_irqsave(&port->lock, flags); | 1298 | spin_lock_irqsave(&port->lock, flags); |
1311 | /* restore original rx trigger level */ | 1299 | /* restore original rx trigger level */ |
1312 | writel(rx_trigger_level, | 1300 | writel(rx_trigger_level, port->membase + CDNS_UART_RXWM); |
1313 | port->membase + CDNS_UART_RXWM_OFFSET); | ||
1314 | /* enable RX timeout interrupt */ | 1301 | /* enable RX timeout interrupt */ |
1315 | writel(CDNS_UART_IXR_TOUT, | 1302 | writel(CDNS_UART_IXR_TOUT, port->membase + CDNS_UART_IER); |
1316 | port->membase + CDNS_UART_IER_OFFSET); | ||
1317 | spin_unlock_irqrestore(&port->lock, flags); | 1303 | spin_unlock_irqrestore(&port->lock, flags); |
1318 | } | 1304 | } |
1319 | 1305 | ||
@@ -1406,27 +1392,30 @@ static int cdns_uart_probe(struct platform_device *pdev) | |||
1406 | dev_err(&pdev->dev, "Cannot get uart_port structure\n"); | 1392 | dev_err(&pdev->dev, "Cannot get uart_port structure\n"); |
1407 | rc = -ENODEV; | 1393 | rc = -ENODEV; |
1408 | goto err_out_notif_unreg; | 1394 | goto err_out_notif_unreg; |
1409 | } else { | ||
1410 | /* Register the port. | ||
1411 | * This function also registers this device with the tty layer | ||
1412 | * and triggers invocation of the config_port() entry point. | ||
1413 | */ | ||
1414 | port->mapbase = res->start; | ||
1415 | port->irq = irq; | ||
1416 | port->dev = &pdev->dev; | ||
1417 | port->uartclk = clk_get_rate(cdns_uart_data->uartclk); | ||
1418 | port->private_data = cdns_uart_data; | ||
1419 | cdns_uart_data->port = port; | ||
1420 | platform_set_drvdata(pdev, port); | ||
1421 | rc = uart_add_one_port(&cdns_uart_uart_driver, port); | ||
1422 | if (rc) { | ||
1423 | dev_err(&pdev->dev, | ||
1424 | "uart_add_one_port() failed; err=%i\n", rc); | ||
1425 | goto err_out_notif_unreg; | ||
1426 | } | ||
1427 | return 0; | ||
1428 | } | 1395 | } |
1429 | 1396 | ||
1397 | /* | ||
1398 | * Register the port. | ||
1399 | * This function also registers this device with the tty layer | ||
1400 | * and triggers invocation of the config_port() entry point. | ||
1401 | */ | ||
1402 | port->mapbase = res->start; | ||
1403 | port->irq = irq; | ||
1404 | port->dev = &pdev->dev; | ||
1405 | port->uartclk = clk_get_rate(cdns_uart_data->uartclk); | ||
1406 | port->private_data = cdns_uart_data; | ||
1407 | cdns_uart_data->port = port; | ||
1408 | platform_set_drvdata(pdev, port); | ||
1409 | |||
1410 | rc = uart_add_one_port(&cdns_uart_uart_driver, port); | ||
1411 | if (rc) { | ||
1412 | dev_err(&pdev->dev, | ||
1413 | "uart_add_one_port() failed; err=%i\n", rc); | ||
1414 | goto err_out_notif_unreg; | ||
1415 | } | ||
1416 | |||
1417 | return 0; | ||
1418 | |||
1430 | err_out_notif_unreg: | 1419 | err_out_notif_unreg: |
1431 | #ifdef CONFIG_COMMON_CLK | 1420 | #ifdef CONFIG_COMMON_CLK |
1432 | clk_notifier_unregister(cdns_uart_data->uartclk, | 1421 | clk_notifier_unregister(cdns_uart_data->uartclk, |
diff --git a/drivers/tty/serial/zs.c b/drivers/tty/serial/zs.c index 2b65bb7ffb8a..eeefd76a30da 100644 --- a/drivers/tty/serial/zs.c +++ b/drivers/tty/serial/zs.c | |||
@@ -1181,6 +1181,10 @@ static void zs_console_write(struct console *co, const char *s, | |||
1181 | if (txint & TxINT_ENAB) { | 1181 | if (txint & TxINT_ENAB) { |
1182 | zport->regs[1] |= TxINT_ENAB; | 1182 | zport->regs[1] |= TxINT_ENAB; |
1183 | write_zsreg(zport, R1, zport->regs[1]); | 1183 | write_zsreg(zport, R1, zport->regs[1]); |
1184 | |||
1185 | /* Resume any transmission as the TxIP bit won't be set. */ | ||
1186 | if (!zport->tx_stopped) | ||
1187 | zs_raw_transmit_chars(zport); | ||
1184 | } | 1188 | } |
1185 | spin_unlock_irqrestore(&scc->zlock, flags); | 1189 | spin_unlock_irqrestore(&scc->zlock, flags); |
1186 | } | 1190 | } |
diff --git a/drivers/tty/synclink.c b/drivers/tty/synclink.c index 6188059fd523..f5476e270734 100644 --- a/drivers/tty/synclink.c +++ b/drivers/tty/synclink.c | |||
@@ -2363,7 +2363,7 @@ static void mgsl_throttle(struct tty_struct * tty) | |||
2363 | if (I_IXOFF(tty)) | 2363 | if (I_IXOFF(tty)) |
2364 | mgsl_send_xchar(tty, STOP_CHAR(tty)); | 2364 | mgsl_send_xchar(tty, STOP_CHAR(tty)); |
2365 | 2365 | ||
2366 | if (tty->termios.c_cflag & CRTSCTS) { | 2366 | if (C_CRTSCTS(tty)) { |
2367 | spin_lock_irqsave(&info->irq_spinlock,flags); | 2367 | spin_lock_irqsave(&info->irq_spinlock,flags); |
2368 | info->serial_signals &= ~SerialSignal_RTS; | 2368 | info->serial_signals &= ~SerialSignal_RTS; |
2369 | usc_set_serial_signals(info); | 2369 | usc_set_serial_signals(info); |
@@ -2397,7 +2397,7 @@ static void mgsl_unthrottle(struct tty_struct * tty) | |||
2397 | mgsl_send_xchar(tty, START_CHAR(tty)); | 2397 | mgsl_send_xchar(tty, START_CHAR(tty)); |
2398 | } | 2398 | } |
2399 | 2399 | ||
2400 | if (tty->termios.c_cflag & CRTSCTS) { | 2400 | if (C_CRTSCTS(tty)) { |
2401 | spin_lock_irqsave(&info->irq_spinlock,flags); | 2401 | spin_lock_irqsave(&info->irq_spinlock,flags); |
2402 | info->serial_signals |= SerialSignal_RTS; | 2402 | info->serial_signals |= SerialSignal_RTS; |
2403 | usc_set_serial_signals(info); | 2403 | usc_set_serial_signals(info); |
@@ -3039,30 +3039,25 @@ static void mgsl_set_termios(struct tty_struct *tty, struct ktermios *old_termio | |||
3039 | mgsl_change_params(info); | 3039 | mgsl_change_params(info); |
3040 | 3040 | ||
3041 | /* Handle transition to B0 status */ | 3041 | /* Handle transition to B0 status */ |
3042 | if (old_termios->c_cflag & CBAUD && | 3042 | if ((old_termios->c_cflag & CBAUD) && !C_BAUD(tty)) { |
3043 | !(tty->termios.c_cflag & CBAUD)) { | ||
3044 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); | 3043 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
3045 | spin_lock_irqsave(&info->irq_spinlock,flags); | 3044 | spin_lock_irqsave(&info->irq_spinlock,flags); |
3046 | usc_set_serial_signals(info); | 3045 | usc_set_serial_signals(info); |
3047 | spin_unlock_irqrestore(&info->irq_spinlock,flags); | 3046 | spin_unlock_irqrestore(&info->irq_spinlock,flags); |
3048 | } | 3047 | } |
3049 | 3048 | ||
3050 | /* Handle transition away from B0 status */ | 3049 | /* Handle transition away from B0 status */ |
3051 | if (!(old_termios->c_cflag & CBAUD) && | 3050 | if (!(old_termios->c_cflag & CBAUD) && C_BAUD(tty)) { |
3052 | tty->termios.c_cflag & CBAUD) { | ||
3053 | info->serial_signals |= SerialSignal_DTR; | 3051 | info->serial_signals |= SerialSignal_DTR; |
3054 | if (!(tty->termios.c_cflag & CRTSCTS) || | 3052 | if (!C_CRTSCTS(tty) || !test_bit(TTY_THROTTLED, &tty->flags)) |
3055 | !test_bit(TTY_THROTTLED, &tty->flags)) { | ||
3056 | info->serial_signals |= SerialSignal_RTS; | 3053 | info->serial_signals |= SerialSignal_RTS; |
3057 | } | ||
3058 | spin_lock_irqsave(&info->irq_spinlock,flags); | 3054 | spin_lock_irqsave(&info->irq_spinlock,flags); |
3059 | usc_set_serial_signals(info); | 3055 | usc_set_serial_signals(info); |
3060 | spin_unlock_irqrestore(&info->irq_spinlock,flags); | 3056 | spin_unlock_irqrestore(&info->irq_spinlock,flags); |
3061 | } | 3057 | } |
3062 | 3058 | ||
3063 | /* Handle turning off CRTSCTS */ | 3059 | /* Handle turning off CRTSCTS */ |
3064 | if (old_termios->c_cflag & CRTSCTS && | 3060 | if (old_termios->c_cflag & CRTSCTS && !C_CRTSCTS(tty)) { |
3065 | !(tty->termios.c_cflag & CRTSCTS)) { | ||
3066 | tty->hw_stopped = 0; | 3061 | tty->hw_stopped = 0; |
3067 | mgsl_start(tty); | 3062 | mgsl_start(tty); |
3068 | } | 3063 | } |
@@ -3281,7 +3276,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
3281 | return 0; | 3276 | return 0; |
3282 | } | 3277 | } |
3283 | 3278 | ||
3284 | if (tty->termios.c_cflag & CLOCAL) | 3279 | if (C_CLOCAL(tty)) |
3285 | do_clocal = true; | 3280 | do_clocal = true; |
3286 | 3281 | ||
3287 | /* Wait for carrier detect and the line to become | 3282 | /* Wait for carrier detect and the line to become |
diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index 5505ea842179..c0a2f5a1b1c2 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c | |||
@@ -774,8 +774,7 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
774 | change_params(info); | 774 | change_params(info); |
775 | 775 | ||
776 | /* Handle transition to B0 status */ | 776 | /* Handle transition to B0 status */ |
777 | if (old_termios->c_cflag & CBAUD && | 777 | if ((old_termios->c_cflag & CBAUD) && !C_BAUD(tty)) { |
778 | !(tty->termios.c_cflag & CBAUD)) { | ||
779 | info->signals &= ~(SerialSignal_RTS | SerialSignal_DTR); | 778 | info->signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
780 | spin_lock_irqsave(&info->lock,flags); | 779 | spin_lock_irqsave(&info->lock,flags); |
781 | set_signals(info); | 780 | set_signals(info); |
@@ -783,21 +782,17 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
783 | } | 782 | } |
784 | 783 | ||
785 | /* Handle transition away from B0 status */ | 784 | /* Handle transition away from B0 status */ |
786 | if (!(old_termios->c_cflag & CBAUD) && | 785 | if (!(old_termios->c_cflag & CBAUD) && C_BAUD(tty)) { |
787 | tty->termios.c_cflag & CBAUD) { | ||
788 | info->signals |= SerialSignal_DTR; | 786 | info->signals |= SerialSignal_DTR; |
789 | if (!(tty->termios.c_cflag & CRTSCTS) || | 787 | if (!C_CRTSCTS(tty) || !test_bit(TTY_THROTTLED, &tty->flags)) |
790 | !test_bit(TTY_THROTTLED, &tty->flags)) { | ||
791 | info->signals |= SerialSignal_RTS; | 788 | info->signals |= SerialSignal_RTS; |
792 | } | ||
793 | spin_lock_irqsave(&info->lock,flags); | 789 | spin_lock_irqsave(&info->lock,flags); |
794 | set_signals(info); | 790 | set_signals(info); |
795 | spin_unlock_irqrestore(&info->lock,flags); | 791 | spin_unlock_irqrestore(&info->lock,flags); |
796 | } | 792 | } |
797 | 793 | ||
798 | /* Handle turning off CRTSCTS */ | 794 | /* Handle turning off CRTSCTS */ |
799 | if (old_termios->c_cflag & CRTSCTS && | 795 | if ((old_termios->c_cflag & CRTSCTS) && !C_CRTSCTS(tty)) { |
800 | !(tty->termios.c_cflag & CRTSCTS)) { | ||
801 | tty->hw_stopped = 0; | 796 | tty->hw_stopped = 0; |
802 | tx_release(tty); | 797 | tx_release(tty); |
803 | } | 798 | } |
@@ -1362,7 +1357,7 @@ static void throttle(struct tty_struct * tty) | |||
1362 | DBGINFO(("%s throttle\n", info->device_name)); | 1357 | DBGINFO(("%s throttle\n", info->device_name)); |
1363 | if (I_IXOFF(tty)) | 1358 | if (I_IXOFF(tty)) |
1364 | send_xchar(tty, STOP_CHAR(tty)); | 1359 | send_xchar(tty, STOP_CHAR(tty)); |
1365 | if (tty->termios.c_cflag & CRTSCTS) { | 1360 | if (C_CRTSCTS(tty)) { |
1366 | spin_lock_irqsave(&info->lock,flags); | 1361 | spin_lock_irqsave(&info->lock,flags); |
1367 | info->signals &= ~SerialSignal_RTS; | 1362 | info->signals &= ~SerialSignal_RTS; |
1368 | set_signals(info); | 1363 | set_signals(info); |
@@ -1387,7 +1382,7 @@ static void unthrottle(struct tty_struct * tty) | |||
1387 | else | 1382 | else |
1388 | send_xchar(tty, START_CHAR(tty)); | 1383 | send_xchar(tty, START_CHAR(tty)); |
1389 | } | 1384 | } |
1390 | if (tty->termios.c_cflag & CRTSCTS) { | 1385 | if (C_CRTSCTS(tty)) { |
1391 | spin_lock_irqsave(&info->lock,flags); | 1386 | spin_lock_irqsave(&info->lock,flags); |
1392 | info->signals |= SerialSignal_RTS; | 1387 | info->signals |= SerialSignal_RTS; |
1393 | set_signals(info); | 1388 | set_signals(info); |
@@ -3280,7 +3275,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3280 | return 0; | 3275 | return 0; |
3281 | } | 3276 | } |
3282 | 3277 | ||
3283 | if (tty->termios.c_cflag & CLOCAL) | 3278 | if (C_CLOCAL(tty)) |
3284 | do_clocal = true; | 3279 | do_clocal = true; |
3285 | 3280 | ||
3286 | /* Wait for carrier detect and the line to become | 3281 | /* Wait for carrier detect and the line to become |
diff --git a/drivers/tty/synclinkmp.c b/drivers/tty/synclinkmp.c index fb00a06dfa4b..90da0c712262 100644 --- a/drivers/tty/synclinkmp.c +++ b/drivers/tty/synclinkmp.c | |||
@@ -549,8 +549,8 @@ static int tiocmset(struct tty_struct *tty, | |||
549 | unsigned int set, unsigned int clear); | 549 | unsigned int set, unsigned int clear); |
550 | static int set_break(struct tty_struct *tty, int break_state); | 550 | static int set_break(struct tty_struct *tty, int break_state); |
551 | 551 | ||
552 | static void add_device(SLMP_INFO *info); | 552 | static int add_device(SLMP_INFO *info); |
553 | static void device_init(int adapter_num, struct pci_dev *pdev); | 553 | static int device_init(int adapter_num, struct pci_dev *pdev); |
554 | static int claim_resources(SLMP_INFO *info); | 554 | static int claim_resources(SLMP_INFO *info); |
555 | static void release_resources(SLMP_INFO *info); | 555 | static void release_resources(SLMP_INFO *info); |
556 | 556 | ||
@@ -871,8 +871,7 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
871 | change_params(info); | 871 | change_params(info); |
872 | 872 | ||
873 | /* Handle transition to B0 status */ | 873 | /* Handle transition to B0 status */ |
874 | if (old_termios->c_cflag & CBAUD && | 874 | if ((old_termios->c_cflag & CBAUD) && !C_BAUD(tty)) { |
875 | !(tty->termios.c_cflag & CBAUD)) { | ||
876 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); | 875 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
877 | spin_lock_irqsave(&info->lock,flags); | 876 | spin_lock_irqsave(&info->lock,flags); |
878 | set_signals(info); | 877 | set_signals(info); |
@@ -880,21 +879,17 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
880 | } | 879 | } |
881 | 880 | ||
882 | /* Handle transition away from B0 status */ | 881 | /* Handle transition away from B0 status */ |
883 | if (!(old_termios->c_cflag & CBAUD) && | 882 | if (!(old_termios->c_cflag & CBAUD) && C_BAUD(tty)) { |
884 | tty->termios.c_cflag & CBAUD) { | ||
885 | info->serial_signals |= SerialSignal_DTR; | 883 | info->serial_signals |= SerialSignal_DTR; |
886 | if (!(tty->termios.c_cflag & CRTSCTS) || | 884 | if (!C_CRTSCTS(tty) || !test_bit(TTY_THROTTLED, &tty->flags)) |
887 | !test_bit(TTY_THROTTLED, &tty->flags)) { | ||
888 | info->serial_signals |= SerialSignal_RTS; | 885 | info->serial_signals |= SerialSignal_RTS; |
889 | } | ||
890 | spin_lock_irqsave(&info->lock,flags); | 886 | spin_lock_irqsave(&info->lock,flags); |
891 | set_signals(info); | 887 | set_signals(info); |
892 | spin_unlock_irqrestore(&info->lock,flags); | 888 | spin_unlock_irqrestore(&info->lock,flags); |
893 | } | 889 | } |
894 | 890 | ||
895 | /* Handle turning off CRTSCTS */ | 891 | /* Handle turning off CRTSCTS */ |
896 | if (old_termios->c_cflag & CRTSCTS && | 892 | if (old_termios->c_cflag & CRTSCTS && !C_CRTSCTS(tty)) { |
897 | !(tty->termios.c_cflag & CRTSCTS)) { | ||
898 | tty->hw_stopped = 0; | 893 | tty->hw_stopped = 0; |
899 | tx_release(tty); | 894 | tx_release(tty); |
900 | } | 895 | } |
@@ -1472,7 +1467,7 @@ static void throttle(struct tty_struct * tty) | |||
1472 | if (I_IXOFF(tty)) | 1467 | if (I_IXOFF(tty)) |
1473 | send_xchar(tty, STOP_CHAR(tty)); | 1468 | send_xchar(tty, STOP_CHAR(tty)); |
1474 | 1469 | ||
1475 | if (tty->termios.c_cflag & CRTSCTS) { | 1470 | if (C_CRTSCTS(tty)) { |
1476 | spin_lock_irqsave(&info->lock,flags); | 1471 | spin_lock_irqsave(&info->lock,flags); |
1477 | info->serial_signals &= ~SerialSignal_RTS; | 1472 | info->serial_signals &= ~SerialSignal_RTS; |
1478 | set_signals(info); | 1473 | set_signals(info); |
@@ -1501,7 +1496,7 @@ static void unthrottle(struct tty_struct * tty) | |||
1501 | send_xchar(tty, START_CHAR(tty)); | 1496 | send_xchar(tty, START_CHAR(tty)); |
1502 | } | 1497 | } |
1503 | 1498 | ||
1504 | if (tty->termios.c_cflag & CRTSCTS) { | 1499 | if (C_CRTSCTS(tty)) { |
1505 | spin_lock_irqsave(&info->lock,flags); | 1500 | spin_lock_irqsave(&info->lock,flags); |
1506 | info->serial_signals |= SerialSignal_RTS; | 1501 | info->serial_signals |= SerialSignal_RTS; |
1507 | set_signals(info); | 1502 | set_signals(info); |
@@ -3297,7 +3292,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3297 | return 0; | 3292 | return 0; |
3298 | } | 3293 | } |
3299 | 3294 | ||
3300 | if (tty->termios.c_cflag & CLOCAL) | 3295 | if (C_CLOCAL(tty)) |
3301 | do_clocal = true; | 3296 | do_clocal = true; |
3302 | 3297 | ||
3303 | /* Wait for carrier detect and the line to become | 3298 | /* Wait for carrier detect and the line to become |
@@ -3693,7 +3688,7 @@ static void release_resources(SLMP_INFO *info) | |||
3693 | /* Add the specified device instance data structure to the | 3688 | /* Add the specified device instance data structure to the |
3694 | * global linked list of devices and increment the device count. | 3689 | * global linked list of devices and increment the device count. |
3695 | */ | 3690 | */ |
3696 | static void add_device(SLMP_INFO *info) | 3691 | static int add_device(SLMP_INFO *info) |
3697 | { | 3692 | { |
3698 | info->next_device = NULL; | 3693 | info->next_device = NULL; |
3699 | info->line = synclinkmp_device_count; | 3694 | info->line = synclinkmp_device_count; |
@@ -3731,7 +3726,9 @@ static void add_device(SLMP_INFO *info) | |||
3731 | info->max_frame_size ); | 3726 | info->max_frame_size ); |
3732 | 3727 | ||
3733 | #if SYNCLINK_GENERIC_HDLC | 3728 | #if SYNCLINK_GENERIC_HDLC |
3734 | hdlcdev_init(info); | 3729 | return hdlcdev_init(info); |
3730 | #else | ||
3731 | return 0; | ||
3735 | #endif | 3732 | #endif |
3736 | } | 3733 | } |
3737 | 3734 | ||
@@ -3820,10 +3817,10 @@ static SLMP_INFO *alloc_dev(int adapter_num, int port_num, struct pci_dev *pdev) | |||
3820 | return info; | 3817 | return info; |
3821 | } | 3818 | } |
3822 | 3819 | ||
3823 | static void device_init(int adapter_num, struct pci_dev *pdev) | 3820 | static int device_init(int adapter_num, struct pci_dev *pdev) |
3824 | { | 3821 | { |
3825 | SLMP_INFO *port_array[SCA_MAX_PORTS]; | 3822 | SLMP_INFO *port_array[SCA_MAX_PORTS]; |
3826 | int port; | 3823 | int port, rc; |
3827 | 3824 | ||
3828 | /* allocate device instances for up to SCA_MAX_PORTS devices */ | 3825 | /* allocate device instances for up to SCA_MAX_PORTS devices */ |
3829 | for ( port = 0; port < SCA_MAX_PORTS; ++port ) { | 3826 | for ( port = 0; port < SCA_MAX_PORTS; ++port ) { |
@@ -3833,14 +3830,16 @@ static void device_init(int adapter_num, struct pci_dev *pdev) | |||
3833 | tty_port_destroy(&port_array[port]->port); | 3830 | tty_port_destroy(&port_array[port]->port); |
3834 | kfree(port_array[port]); | 3831 | kfree(port_array[port]); |
3835 | } | 3832 | } |
3836 | return; | 3833 | return -ENOMEM; |
3837 | } | 3834 | } |
3838 | } | 3835 | } |
3839 | 3836 | ||
3840 | /* give copy of port_array to all ports and add to device list */ | 3837 | /* give copy of port_array to all ports and add to device list */ |
3841 | for ( port = 0; port < SCA_MAX_PORTS; ++port ) { | 3838 | for ( port = 0; port < SCA_MAX_PORTS; ++port ) { |
3842 | memcpy(port_array[port]->port_array,port_array,sizeof(port_array)); | 3839 | memcpy(port_array[port]->port_array,port_array,sizeof(port_array)); |
3843 | add_device( port_array[port] ); | 3840 | rc = add_device( port_array[port] ); |
3841 | if (rc) | ||
3842 | goto err_add; | ||
3844 | spin_lock_init(&port_array[port]->lock); | 3843 | spin_lock_init(&port_array[port]->lock); |
3845 | } | 3844 | } |
3846 | 3845 | ||
@@ -3860,21 +3859,30 @@ static void device_init(int adapter_num, struct pci_dev *pdev) | |||
3860 | alloc_dma_bufs(port_array[port]); | 3859 | alloc_dma_bufs(port_array[port]); |
3861 | } | 3860 | } |
3862 | 3861 | ||
3863 | if ( request_irq(port_array[0]->irq_level, | 3862 | rc = request_irq(port_array[0]->irq_level, |
3864 | synclinkmp_interrupt, | 3863 | synclinkmp_interrupt, |
3865 | port_array[0]->irq_flags, | 3864 | port_array[0]->irq_flags, |
3866 | port_array[0]->device_name, | 3865 | port_array[0]->device_name, |
3867 | port_array[0]) < 0 ) { | 3866 | port_array[0]); |
3867 | if ( rc ) { | ||
3868 | printk( "%s(%d):%s Can't request interrupt, IRQ=%d\n", | 3868 | printk( "%s(%d):%s Can't request interrupt, IRQ=%d\n", |
3869 | __FILE__,__LINE__, | 3869 | __FILE__,__LINE__, |
3870 | port_array[0]->device_name, | 3870 | port_array[0]->device_name, |
3871 | port_array[0]->irq_level ); | 3871 | port_array[0]->irq_level ); |
3872 | goto err_irq; | ||
3872 | } | 3873 | } |
3873 | else { | 3874 | port_array[0]->irq_requested = true; |
3874 | port_array[0]->irq_requested = true; | 3875 | adapter_test(port_array[0]); |
3875 | adapter_test(port_array[0]); | ||
3876 | } | ||
3877 | } | 3876 | } |
3877 | return 0; | ||
3878 | err_irq: | ||
3879 | release_resources( port_array[0] ); | ||
3880 | err_add: | ||
3881 | for ( port = 0; port < SCA_MAX_PORTS; ++port ) { | ||
3882 | tty_port_destroy(&port_array[port]->port); | ||
3883 | kfree(port_array[port]); | ||
3884 | } | ||
3885 | return rc; | ||
3878 | } | 3886 | } |
3879 | 3887 | ||
3880 | static const struct tty_operations ops = { | 3888 | static const struct tty_operations ops = { |
@@ -5589,8 +5597,7 @@ static int synclinkmp_init_one (struct pci_dev *dev, | |||
5589 | printk("error enabling pci device %p\n", dev); | 5597 | printk("error enabling pci device %p\n", dev); |
5590 | return -EIO; | 5598 | return -EIO; |
5591 | } | 5599 | } |
5592 | device_init( ++synclinkmp_adapter_count, dev ); | 5600 | return device_init( ++synclinkmp_adapter_count, dev ); |
5593 | return 0; | ||
5594 | } | 5601 | } |
5595 | 5602 | ||
5596 | static void synclinkmp_remove_one (struct pci_dev *dev) | 5603 | static void synclinkmp_remove_one (struct pci_dev *dev) |
diff --git a/drivers/tty/tty_audit.c b/drivers/tty/tty_audit.c index 3d245cd3d8e6..df2d735338e2 100644 --- a/drivers/tty/tty_audit.c +++ b/drivers/tty/tty_audit.c | |||
@@ -14,16 +14,23 @@ | |||
14 | #include <linux/tty.h> | 14 | #include <linux/tty.h> |
15 | 15 | ||
16 | struct tty_audit_buf { | 16 | struct tty_audit_buf { |
17 | atomic_t count; | ||
18 | struct mutex mutex; /* Protects all data below */ | 17 | struct mutex mutex; /* Protects all data below */ |
19 | int major, minor; /* The TTY which the data is from */ | 18 | dev_t dev; /* The TTY which the data is from */ |
20 | unsigned icanon:1; | 19 | unsigned icanon:1; |
21 | size_t valid; | 20 | size_t valid; |
22 | unsigned char *data; /* Allocated size N_TTY_BUF_SIZE */ | 21 | unsigned char *data; /* Allocated size N_TTY_BUF_SIZE */ |
23 | }; | 22 | }; |
24 | 23 | ||
25 | static struct tty_audit_buf *tty_audit_buf_alloc(int major, int minor, | 24 | static struct tty_audit_buf *tty_audit_buf_ref(void) |
26 | unsigned icanon) | 25 | { |
26 | struct tty_audit_buf *buf; | ||
27 | |||
28 | buf = current->signal->tty_audit_buf; | ||
29 | WARN_ON(buf == ERR_PTR(-ESRCH)); | ||
30 | return buf; | ||
31 | } | ||
32 | |||
33 | static struct tty_audit_buf *tty_audit_buf_alloc(void) | ||
27 | { | 34 | { |
28 | struct tty_audit_buf *buf; | 35 | struct tty_audit_buf *buf; |
29 | 36 | ||
@@ -33,11 +40,9 @@ static struct tty_audit_buf *tty_audit_buf_alloc(int major, int minor, | |||
33 | buf->data = kmalloc(N_TTY_BUF_SIZE, GFP_KERNEL); | 40 | buf->data = kmalloc(N_TTY_BUF_SIZE, GFP_KERNEL); |
34 | if (!buf->data) | 41 | if (!buf->data) |
35 | goto err_buf; | 42 | goto err_buf; |
36 | atomic_set(&buf->count, 1); | ||
37 | mutex_init(&buf->mutex); | 43 | mutex_init(&buf->mutex); |
38 | buf->major = major; | 44 | buf->dev = MKDEV(0, 0); |
39 | buf->minor = minor; | 45 | buf->icanon = 0; |
40 | buf->icanon = icanon; | ||
41 | buf->valid = 0; | 46 | buf->valid = 0; |
42 | return buf; | 47 | return buf; |
43 | 48 | ||
@@ -54,13 +59,7 @@ static void tty_audit_buf_free(struct tty_audit_buf *buf) | |||
54 | kfree(buf); | 59 | kfree(buf); |
55 | } | 60 | } |
56 | 61 | ||
57 | static void tty_audit_buf_put(struct tty_audit_buf *buf) | 62 | static void tty_audit_log(const char *description, dev_t dev, |
58 | { | ||
59 | if (atomic_dec_and_test(&buf->count)) | ||
60 | tty_audit_buf_free(buf); | ||
61 | } | ||
62 | |||
63 | static void tty_audit_log(const char *description, int major, int minor, | ||
64 | unsigned char *data, size_t size) | 63 | unsigned char *data, size_t size) |
65 | { | 64 | { |
66 | struct audit_buffer *ab; | 65 | struct audit_buffer *ab; |
@@ -76,7 +75,7 @@ static void tty_audit_log(const char *description, int major, int minor, | |||
76 | 75 | ||
77 | audit_log_format(ab, "%s pid=%u uid=%u auid=%u ses=%u major=%d" | 76 | audit_log_format(ab, "%s pid=%u uid=%u auid=%u ses=%u major=%d" |
78 | " minor=%d comm=", description, pid, uid, | 77 | " minor=%d comm=", description, pid, uid, |
79 | loginuid, sessionid, major, minor); | 78 | loginuid, sessionid, MAJOR(dev), MINOR(dev)); |
80 | get_task_comm(name, tsk); | 79 | get_task_comm(name, tsk); |
81 | audit_log_untrustedstring(ab, name); | 80 | audit_log_untrustedstring(ab, name); |
82 | audit_log_format(ab, " data="); | 81 | audit_log_format(ab, " data="); |
@@ -99,7 +98,7 @@ static void tty_audit_buf_push(struct tty_audit_buf *buf) | |||
99 | buf->valid = 0; | 98 | buf->valid = 0; |
100 | return; | 99 | return; |
101 | } | 100 | } |
102 | tty_audit_log("tty", buf->major, buf->minor, buf->data, buf->valid); | 101 | tty_audit_log("tty", buf->dev, buf->data, buf->valid); |
103 | buf->valid = 0; | 102 | buf->valid = 0; |
104 | } | 103 | } |
105 | 104 | ||
@@ -108,21 +107,20 @@ static void tty_audit_buf_push(struct tty_audit_buf *buf) | |||
108 | * | 107 | * |
109 | * Make sure all buffered data is written out and deallocate the buffer. | 108 | * Make sure all buffered data is written out and deallocate the buffer. |
110 | * Only needs to be called if current->signal->tty_audit_buf != %NULL. | 109 | * Only needs to be called if current->signal->tty_audit_buf != %NULL. |
110 | * | ||
111 | * The process is single-threaded at this point; no other threads share | ||
112 | * current->signal. | ||
111 | */ | 113 | */ |
112 | void tty_audit_exit(void) | 114 | void tty_audit_exit(void) |
113 | { | 115 | { |
114 | struct tty_audit_buf *buf; | 116 | struct tty_audit_buf *buf; |
115 | 117 | ||
116 | buf = current->signal->tty_audit_buf; | 118 | buf = xchg(¤t->signal->tty_audit_buf, ERR_PTR(-ESRCH)); |
117 | current->signal->tty_audit_buf = NULL; | ||
118 | if (!buf) | 119 | if (!buf) |
119 | return; | 120 | return; |
120 | 121 | ||
121 | mutex_lock(&buf->mutex); | ||
122 | tty_audit_buf_push(buf); | 122 | tty_audit_buf_push(buf); |
123 | mutex_unlock(&buf->mutex); | 123 | tty_audit_buf_free(buf); |
124 | |||
125 | tty_audit_buf_put(buf); | ||
126 | } | 124 | } |
127 | 125 | ||
128 | /** | 126 | /** |
@@ -133,7 +131,6 @@ void tty_audit_exit(void) | |||
133 | void tty_audit_fork(struct signal_struct *sig) | 131 | void tty_audit_fork(struct signal_struct *sig) |
134 | { | 132 | { |
135 | sig->audit_tty = current->signal->audit_tty; | 133 | sig->audit_tty = current->signal->audit_tty; |
136 | sig->audit_tty_log_passwd = current->signal->audit_tty_log_passwd; | ||
137 | } | 134 | } |
138 | 135 | ||
139 | /** | 136 | /** |
@@ -141,123 +138,62 @@ void tty_audit_fork(struct signal_struct *sig) | |||
141 | */ | 138 | */ |
142 | void tty_audit_tiocsti(struct tty_struct *tty, char ch) | 139 | void tty_audit_tiocsti(struct tty_struct *tty, char ch) |
143 | { | 140 | { |
144 | struct tty_audit_buf *buf; | 141 | dev_t dev; |
145 | int major, minor, should_audit; | ||
146 | unsigned long flags; | ||
147 | 142 | ||
148 | spin_lock_irqsave(¤t->sighand->siglock, flags); | 143 | dev = MKDEV(tty->driver->major, tty->driver->minor_start) + tty->index; |
149 | should_audit = current->signal->audit_tty; | 144 | if (tty_audit_push()) |
150 | buf = current->signal->tty_audit_buf; | 145 | return; |
151 | if (buf) | ||
152 | atomic_inc(&buf->count); | ||
153 | spin_unlock_irqrestore(¤t->sighand->siglock, flags); | ||
154 | |||
155 | major = tty->driver->major; | ||
156 | minor = tty->driver->minor_start + tty->index; | ||
157 | if (buf) { | ||
158 | mutex_lock(&buf->mutex); | ||
159 | if (buf->major == major && buf->minor == minor) | ||
160 | tty_audit_buf_push(buf); | ||
161 | mutex_unlock(&buf->mutex); | ||
162 | tty_audit_buf_put(buf); | ||
163 | } | ||
164 | |||
165 | if (should_audit && audit_enabled) { | ||
166 | kuid_t auid; | ||
167 | unsigned int sessionid; | ||
168 | 146 | ||
169 | auid = audit_get_loginuid(current); | 147 | if (audit_enabled) |
170 | sessionid = audit_get_sessionid(current); | 148 | tty_audit_log("ioctl=TIOCSTI", dev, &ch, 1); |
171 | tty_audit_log("ioctl=TIOCSTI", major, minor, &ch, 1); | ||
172 | } | ||
173 | } | 149 | } |
174 | 150 | ||
175 | /** | 151 | /** |
176 | * tty_audit_push_current - Flush current's pending audit data | 152 | * tty_audit_push - Flush current's pending audit data |
177 | * | 153 | * |
178 | * Try to lock sighand and get a reference to the tty audit buffer if available. | 154 | * Returns 0 if success, -EPERM if tty audit is disabled |
179 | * Flush the buffer or return an appropriate error code. | ||
180 | */ | 155 | */ |
181 | int tty_audit_push_current(void) | 156 | int tty_audit_push(void) |
182 | { | 157 | { |
183 | struct tty_audit_buf *buf = ERR_PTR(-EPERM); | 158 | struct tty_audit_buf *buf; |
184 | struct task_struct *tsk = current; | ||
185 | unsigned long flags; | ||
186 | 159 | ||
187 | if (!lock_task_sighand(tsk, &flags)) | 160 | if (~current->signal->audit_tty & AUDIT_TTY_ENABLE) |
188 | return -ESRCH; | 161 | return -EPERM; |
189 | 162 | ||
190 | if (tsk->signal->audit_tty) { | 163 | buf = tty_audit_buf_ref(); |
191 | buf = tsk->signal->tty_audit_buf; | 164 | if (!IS_ERR_OR_NULL(buf)) { |
192 | if (buf) | 165 | mutex_lock(&buf->mutex); |
193 | atomic_inc(&buf->count); | 166 | tty_audit_buf_push(buf); |
167 | mutex_unlock(&buf->mutex); | ||
194 | } | 168 | } |
195 | unlock_task_sighand(tsk, &flags); | ||
196 | |||
197 | /* | ||
198 | * Return 0 when signal->audit_tty set | ||
199 | * but tsk->signal->tty_audit_buf == NULL. | ||
200 | */ | ||
201 | if (!buf || IS_ERR(buf)) | ||
202 | return PTR_ERR(buf); | ||
203 | |||
204 | mutex_lock(&buf->mutex); | ||
205 | tty_audit_buf_push(buf); | ||
206 | mutex_unlock(&buf->mutex); | ||
207 | |||
208 | tty_audit_buf_put(buf); | ||
209 | return 0; | 169 | return 0; |
210 | } | 170 | } |
211 | 171 | ||
212 | /** | 172 | /** |
213 | * tty_audit_buf_get - Get an audit buffer. | 173 | * tty_audit_buf_get - Get an audit buffer. |
214 | * | 174 | * |
215 | * Get an audit buffer for @tty, allocate it if necessary. Return %NULL | 175 | * Get an audit buffer, allocate it if necessary. Return %NULL |
216 | * if TTY auditing is disabled or out of memory. Otherwise, return a new | 176 | * if out of memory or ERR_PTR(-ESRCH) if tty_audit_exit() has already |
217 | * reference to the buffer. | 177 | * occurred. Otherwise, return a new reference to the buffer. |
218 | */ | 178 | */ |
219 | static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty, | 179 | static struct tty_audit_buf *tty_audit_buf_get(void) |
220 | unsigned icanon) | ||
221 | { | 180 | { |
222 | struct tty_audit_buf *buf, *buf2; | 181 | struct tty_audit_buf *buf; |
223 | unsigned long flags; | 182 | |
224 | 183 | buf = tty_audit_buf_ref(); | |
225 | buf = NULL; | 184 | if (buf) |
226 | buf2 = NULL; | 185 | return buf; |
227 | spin_lock_irqsave(¤t->sighand->siglock, flags); | ||
228 | if (likely(!current->signal->audit_tty)) | ||
229 | goto out; | ||
230 | buf = current->signal->tty_audit_buf; | ||
231 | if (buf) { | ||
232 | atomic_inc(&buf->count); | ||
233 | goto out; | ||
234 | } | ||
235 | spin_unlock_irqrestore(¤t->sighand->siglock, flags); | ||
236 | 186 | ||
237 | buf2 = tty_audit_buf_alloc(tty->driver->major, | 187 | buf = tty_audit_buf_alloc(); |
238 | tty->driver->minor_start + tty->index, | 188 | if (buf == NULL) { |
239 | icanon); | ||
240 | if (buf2 == NULL) { | ||
241 | audit_log_lost("out of memory in TTY auditing"); | 189 | audit_log_lost("out of memory in TTY auditing"); |
242 | return NULL; | 190 | return NULL; |
243 | } | 191 | } |
244 | 192 | ||
245 | spin_lock_irqsave(¤t->sighand->siglock, flags); | 193 | /* Race to use this buffer, free it if another wins */ |
246 | if (!current->signal->audit_tty) | 194 | if (cmpxchg(¤t->signal->tty_audit_buf, NULL, buf) != NULL) |
247 | goto out; | 195 | tty_audit_buf_free(buf); |
248 | buf = current->signal->tty_audit_buf; | 196 | return tty_audit_buf_ref(); |
249 | if (!buf) { | ||
250 | current->signal->tty_audit_buf = buf2; | ||
251 | buf = buf2; | ||
252 | buf2 = NULL; | ||
253 | } | ||
254 | atomic_inc(&buf->count); | ||
255 | /* Fall through */ | ||
256 | out: | ||
257 | spin_unlock_irqrestore(¤t->sighand->siglock, flags); | ||
258 | if (buf2) | ||
259 | tty_audit_buf_free(buf2); | ||
260 | return buf; | ||
261 | } | 197 | } |
262 | 198 | ||
263 | /** | 199 | /** |
@@ -265,39 +201,36 @@ static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty, | |||
265 | * | 201 | * |
266 | * Audit @data of @size from @tty, if necessary. | 202 | * Audit @data of @size from @tty, if necessary. |
267 | */ | 203 | */ |
268 | void tty_audit_add_data(struct tty_struct *tty, const void *data, | 204 | void tty_audit_add_data(struct tty_struct *tty, const void *data, size_t size) |
269 | size_t size, unsigned icanon) | ||
270 | { | 205 | { |
271 | struct tty_audit_buf *buf; | 206 | struct tty_audit_buf *buf; |
272 | int major, minor; | 207 | unsigned int icanon = !!L_ICANON(tty); |
273 | int audit_log_tty_passwd; | 208 | unsigned int audit_tty; |
274 | unsigned long flags; | 209 | dev_t dev; |
275 | 210 | ||
276 | if (unlikely(size == 0)) | 211 | audit_tty = READ_ONCE(current->signal->audit_tty); |
212 | if (~audit_tty & AUDIT_TTY_ENABLE) | ||
277 | return; | 213 | return; |
278 | 214 | ||
279 | spin_lock_irqsave(¤t->sighand->siglock, flags); | 215 | if (unlikely(size == 0)) |
280 | audit_log_tty_passwd = current->signal->audit_tty_log_passwd; | ||
281 | spin_unlock_irqrestore(¤t->sighand->siglock, flags); | ||
282 | if (!audit_log_tty_passwd && icanon && !L_ECHO(tty)) | ||
283 | return; | 216 | return; |
284 | 217 | ||
285 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY | 218 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY |
286 | && tty->driver->subtype == PTY_TYPE_MASTER) | 219 | && tty->driver->subtype == PTY_TYPE_MASTER) |
287 | return; | 220 | return; |
288 | 221 | ||
289 | buf = tty_audit_buf_get(tty, icanon); | 222 | if ((~audit_tty & AUDIT_TTY_LOG_PASSWD) && icanon && !L_ECHO(tty)) |
290 | if (!buf) | 223 | return; |
224 | |||
225 | buf = tty_audit_buf_get(); | ||
226 | if (IS_ERR_OR_NULL(buf)) | ||
291 | return; | 227 | return; |
292 | 228 | ||
293 | mutex_lock(&buf->mutex); | 229 | mutex_lock(&buf->mutex); |
294 | major = tty->driver->major; | 230 | dev = MKDEV(tty->driver->major, tty->driver->minor_start) + tty->index; |
295 | minor = tty->driver->minor_start + tty->index; | 231 | if (buf->dev != dev || buf->icanon != icanon) { |
296 | if (buf->major != major || buf->minor != minor | ||
297 | || buf->icanon != icanon) { | ||
298 | tty_audit_buf_push(buf); | 232 | tty_audit_buf_push(buf); |
299 | buf->major = major; | 233 | buf->dev = dev; |
300 | buf->minor = minor; | ||
301 | buf->icanon = icanon; | 234 | buf->icanon = icanon; |
302 | } | 235 | } |
303 | do { | 236 | do { |
@@ -314,38 +247,4 @@ void tty_audit_add_data(struct tty_struct *tty, const void *data, | |||
314 | tty_audit_buf_push(buf); | 247 | tty_audit_buf_push(buf); |
315 | } while (size != 0); | 248 | } while (size != 0); |
316 | mutex_unlock(&buf->mutex); | 249 | mutex_unlock(&buf->mutex); |
317 | tty_audit_buf_put(buf); | ||
318 | } | ||
319 | |||
320 | /** | ||
321 | * tty_audit_push - Push buffered data out | ||
322 | * | ||
323 | * Make sure no audit data is pending for @tty on the current process. | ||
324 | */ | ||
325 | void tty_audit_push(struct tty_struct *tty) | ||
326 | { | ||
327 | struct tty_audit_buf *buf; | ||
328 | unsigned long flags; | ||
329 | |||
330 | spin_lock_irqsave(¤t->sighand->siglock, flags); | ||
331 | if (likely(!current->signal->audit_tty)) { | ||
332 | spin_unlock_irqrestore(¤t->sighand->siglock, flags); | ||
333 | return; | ||
334 | } | ||
335 | buf = current->signal->tty_audit_buf; | ||
336 | if (buf) | ||
337 | atomic_inc(&buf->count); | ||
338 | spin_unlock_irqrestore(¤t->sighand->siglock, flags); | ||
339 | |||
340 | if (buf) { | ||
341 | int major, minor; | ||
342 | |||
343 | major = tty->driver->major; | ||
344 | minor = tty->driver->minor_start + tty->index; | ||
345 | mutex_lock(&buf->mutex); | ||
346 | if (buf->major == major && buf->minor == minor) | ||
347 | tty_audit_buf_push(buf); | ||
348 | mutex_unlock(&buf->mutex); | ||
349 | tty_audit_buf_put(buf); | ||
350 | } | ||
351 | } | 250 | } |
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 3cd31e0d4bd9..a946e49a2626 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c | |||
@@ -435,25 +435,42 @@ int tty_prepare_flip_string(struct tty_port *port, unsigned char **chars, | |||
435 | } | 435 | } |
436 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string); | 436 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string); |
437 | 437 | ||
438 | /** | ||
439 | * tty_ldisc_receive_buf - forward data to line discipline | ||
440 | * @ld: line discipline to process input | ||
441 | * @p: char buffer | ||
442 | * @f: TTY_* flags buffer | ||
443 | * @count: number of bytes to process | ||
444 | * | ||
445 | * Callers other than flush_to_ldisc() need to exclude the kworker | ||
446 | * from concurrent use of the line discipline, see paste_selection(). | ||
447 | * | ||
448 | * Returns the number of bytes not processed | ||
449 | */ | ||
450 | int tty_ldisc_receive_buf(struct tty_ldisc *ld, unsigned char *p, | ||
451 | char *f, int count) | ||
452 | { | ||
453 | if (ld->ops->receive_buf2) | ||
454 | count = ld->ops->receive_buf2(ld->tty, p, f, count); | ||
455 | else { | ||
456 | count = min_t(int, count, ld->tty->receive_room); | ||
457 | if (count && ld->ops->receive_buf) | ||
458 | ld->ops->receive_buf(ld->tty, p, f, count); | ||
459 | } | ||
460 | return count; | ||
461 | } | ||
462 | EXPORT_SYMBOL_GPL(tty_ldisc_receive_buf); | ||
438 | 463 | ||
439 | static int | 464 | static int |
440 | receive_buf(struct tty_struct *tty, struct tty_buffer *head, int count) | 465 | receive_buf(struct tty_ldisc *ld, struct tty_buffer *head, int count) |
441 | { | 466 | { |
442 | struct tty_ldisc *disc = tty->ldisc; | ||
443 | unsigned char *p = char_buf_ptr(head, head->read); | 467 | unsigned char *p = char_buf_ptr(head, head->read); |
444 | char *f = NULL; | 468 | char *f = NULL; |
445 | 469 | ||
446 | if (~head->flags & TTYB_NORMAL) | 470 | if (~head->flags & TTYB_NORMAL) |
447 | f = flag_buf_ptr(head, head->read); | 471 | f = flag_buf_ptr(head, head->read); |
448 | 472 | ||
449 | if (disc->ops->receive_buf2) | 473 | return tty_ldisc_receive_buf(ld, p, f, count); |
450 | count = disc->ops->receive_buf2(tty, p, f, count); | ||
451 | else { | ||
452 | count = min_t(int, count, tty->receive_room); | ||
453 | if (count && disc->ops->receive_buf) | ||
454 | disc->ops->receive_buf(tty, p, f, count); | ||
455 | } | ||
456 | return count; | ||
457 | } | 474 | } |
458 | 475 | ||
459 | /** | 476 | /** |
@@ -514,7 +531,7 @@ static void flush_to_ldisc(struct work_struct *work) | |||
514 | continue; | 531 | continue; |
515 | } | 532 | } |
516 | 533 | ||
517 | count = receive_buf(tty, head, count); | 534 | count = receive_buf(disc, head, count); |
518 | if (!count) | 535 | if (!count) |
519 | break; | 536 | break; |
520 | head->read += count; | 537 | head->read += count; |
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index a7eacef1bd22..8d26ed79bb4c 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
@@ -123,7 +123,8 @@ struct ktermios tty_std_termios = { /* for the benefit of tty drivers */ | |||
123 | ECHOCTL | ECHOKE | IEXTEN, | 123 | ECHOCTL | ECHOKE | IEXTEN, |
124 | .c_cc = INIT_C_CC, | 124 | .c_cc = INIT_C_CC, |
125 | .c_ispeed = 38400, | 125 | .c_ispeed = 38400, |
126 | .c_ospeed = 38400 | 126 | .c_ospeed = 38400, |
127 | /* .c_line = N_TTY, */ | ||
127 | }; | 128 | }; |
128 | 129 | ||
129 | EXPORT_SYMBOL(tty_std_termios); | 130 | EXPORT_SYMBOL(tty_std_termios); |
@@ -134,13 +135,8 @@ EXPORT_SYMBOL(tty_std_termios); | |||
134 | 135 | ||
135 | LIST_HEAD(tty_drivers); /* linked list of tty drivers */ | 136 | LIST_HEAD(tty_drivers); /* linked list of tty drivers */ |
136 | 137 | ||
137 | /* Mutex to protect creating and releasing a tty. This is shared with | 138 | /* Mutex to protect creating and releasing a tty */ |
138 | vt.c for deeply disgusting hack reasons */ | ||
139 | DEFINE_MUTEX(tty_mutex); | 139 | DEFINE_MUTEX(tty_mutex); |
140 | EXPORT_SYMBOL(tty_mutex); | ||
141 | |||
142 | /* Spinlock to protect the tty->tty_files list */ | ||
143 | DEFINE_SPINLOCK(tty_files_lock); | ||
144 | 140 | ||
145 | static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); | 141 | static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); |
146 | static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *); | 142 | static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *); |
@@ -168,10 +164,9 @@ static void release_tty(struct tty_struct *tty, int idx); | |||
168 | * Locking: none. Must be called after tty is definitely unused | 164 | * Locking: none. Must be called after tty is definitely unused |
169 | */ | 165 | */ |
170 | 166 | ||
171 | void free_tty_struct(struct tty_struct *tty) | 167 | static void free_tty_struct(struct tty_struct *tty) |
172 | { | 168 | { |
173 | if (!tty) | 169 | tty_ldisc_deinit(tty); |
174 | return; | ||
175 | put_device(tty->dev); | 170 | put_device(tty->dev); |
176 | kfree(tty->write_buf); | 171 | kfree(tty->write_buf); |
177 | tty->magic = 0xDEADDEAD; | 172 | tty->magic = 0xDEADDEAD; |
@@ -204,9 +199,9 @@ void tty_add_file(struct tty_struct *tty, struct file *file) | |||
204 | priv->tty = tty; | 199 | priv->tty = tty; |
205 | priv->file = file; | 200 | priv->file = file; |
206 | 201 | ||
207 | spin_lock(&tty_files_lock); | 202 | spin_lock(&tty->files_lock); |
208 | list_add(&priv->list, &tty->tty_files); | 203 | list_add(&priv->list, &tty->tty_files); |
209 | spin_unlock(&tty_files_lock); | 204 | spin_unlock(&tty->files_lock); |
210 | } | 205 | } |
211 | 206 | ||
212 | /** | 207 | /** |
@@ -227,10 +222,11 @@ void tty_free_file(struct file *file) | |||
227 | static void tty_del_file(struct file *file) | 222 | static void tty_del_file(struct file *file) |
228 | { | 223 | { |
229 | struct tty_file_private *priv = file->private_data; | 224 | struct tty_file_private *priv = file->private_data; |
225 | struct tty_struct *tty = priv->tty; | ||
230 | 226 | ||
231 | spin_lock(&tty_files_lock); | 227 | spin_lock(&tty->files_lock); |
232 | list_del(&priv->list); | 228 | list_del(&priv->list); |
233 | spin_unlock(&tty_files_lock); | 229 | spin_unlock(&tty->files_lock); |
234 | tty_free_file(file); | 230 | tty_free_file(file); |
235 | } | 231 | } |
236 | 232 | ||
@@ -288,11 +284,11 @@ static int check_tty_count(struct tty_struct *tty, const char *routine) | |||
288 | struct list_head *p; | 284 | struct list_head *p; |
289 | int count = 0; | 285 | int count = 0; |
290 | 286 | ||
291 | spin_lock(&tty_files_lock); | 287 | spin_lock(&tty->files_lock); |
292 | list_for_each(p, &tty->tty_files) { | 288 | list_for_each(p, &tty->tty_files) { |
293 | count++; | 289 | count++; |
294 | } | 290 | } |
295 | spin_unlock(&tty_files_lock); | 291 | spin_unlock(&tty->files_lock); |
296 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 292 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
297 | tty->driver->subtype == PTY_TYPE_SLAVE && | 293 | tty->driver->subtype == PTY_TYPE_SLAVE && |
298 | tty->link && tty->link->count) | 294 | tty->link && tty->link->count) |
@@ -383,6 +379,12 @@ struct tty_driver *tty_find_polling_driver(char *name, int *line) | |||
383 | EXPORT_SYMBOL_GPL(tty_find_polling_driver); | 379 | EXPORT_SYMBOL_GPL(tty_find_polling_driver); |
384 | #endif | 380 | #endif |
385 | 381 | ||
382 | static int is_ignored(int sig) | ||
383 | { | ||
384 | return (sigismember(¤t->blocked, sig) || | ||
385 | current->sighand->action[sig-1].sa.sa_handler == SIG_IGN); | ||
386 | } | ||
387 | |||
386 | /** | 388 | /** |
387 | * tty_check_change - check for POSIX terminal changes | 389 | * tty_check_change - check for POSIX terminal changes |
388 | * @tty: tty to check | 390 | * @tty: tty to check |
@@ -466,6 +468,11 @@ static long hung_up_tty_compat_ioctl(struct file *file, | |||
466 | return cmd == TIOCSPGRP ? -ENOTTY : -EIO; | 468 | return cmd == TIOCSPGRP ? -ENOTTY : -EIO; |
467 | } | 469 | } |
468 | 470 | ||
471 | static int hung_up_tty_fasync(int fd, struct file *file, int on) | ||
472 | { | ||
473 | return -ENOTTY; | ||
474 | } | ||
475 | |||
469 | static const struct file_operations tty_fops = { | 476 | static const struct file_operations tty_fops = { |
470 | .llseek = no_llseek, | 477 | .llseek = no_llseek, |
471 | .read = tty_read, | 478 | .read = tty_read, |
@@ -498,6 +505,7 @@ static const struct file_operations hung_up_tty_fops = { | |||
498 | .unlocked_ioctl = hung_up_tty_ioctl, | 505 | .unlocked_ioctl = hung_up_tty_ioctl, |
499 | .compat_ioctl = hung_up_tty_compat_ioctl, | 506 | .compat_ioctl = hung_up_tty_compat_ioctl, |
500 | .release = tty_release, | 507 | .release = tty_release, |
508 | .fasync = hung_up_tty_fasync, | ||
501 | }; | 509 | }; |
502 | 510 | ||
503 | static DEFINE_SPINLOCK(redirect_lock); | 511 | static DEFINE_SPINLOCK(redirect_lock); |
@@ -709,7 +717,7 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session) | |||
709 | workqueue with the lock held */ | 717 | workqueue with the lock held */ |
710 | check_tty_count(tty, "tty_hangup"); | 718 | check_tty_count(tty, "tty_hangup"); |
711 | 719 | ||
712 | spin_lock(&tty_files_lock); | 720 | spin_lock(&tty->files_lock); |
713 | /* This breaks for file handles being sent over AF_UNIX sockets ? */ | 721 | /* This breaks for file handles being sent over AF_UNIX sockets ? */ |
714 | list_for_each_entry(priv, &tty->tty_files, list) { | 722 | list_for_each_entry(priv, &tty->tty_files, list) { |
715 | filp = priv->file; | 723 | filp = priv->file; |
@@ -721,14 +729,14 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session) | |||
721 | __tty_fasync(-1, filp, 0); /* can't block */ | 729 | __tty_fasync(-1, filp, 0); /* can't block */ |
722 | filp->f_op = &hung_up_tty_fops; | 730 | filp->f_op = &hung_up_tty_fops; |
723 | } | 731 | } |
724 | spin_unlock(&tty_files_lock); | 732 | spin_unlock(&tty->files_lock); |
725 | 733 | ||
726 | refs = tty_signal_session_leader(tty, exit_session); | 734 | refs = tty_signal_session_leader(tty, exit_session); |
727 | /* Account for the p->signal references we killed */ | 735 | /* Account for the p->signal references we killed */ |
728 | while (refs--) | 736 | while (refs--) |
729 | tty_kref_put(tty); | 737 | tty_kref_put(tty); |
730 | 738 | ||
731 | tty_ldisc_hangup(tty); | 739 | tty_ldisc_hangup(tty, cons_filp != NULL); |
732 | 740 | ||
733 | spin_lock_irq(&tty->ctrl_lock); | 741 | spin_lock_irq(&tty->ctrl_lock); |
734 | clear_bit(TTY_THROTTLED, &tty->flags); | 742 | clear_bit(TTY_THROTTLED, &tty->flags); |
@@ -753,10 +761,9 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session) | |||
753 | } else if (tty->ops->hangup) | 761 | } else if (tty->ops->hangup) |
754 | tty->ops->hangup(tty); | 762 | tty->ops->hangup(tty); |
755 | /* | 763 | /* |
756 | * We don't want to have driver/ldisc interactions beyond | 764 | * We don't want to have driver/ldisc interactions beyond the ones |
757 | * the ones we did here. The driver layer expects no | 765 | * we did here. The driver layer expects no calls after ->hangup() |
758 | * calls after ->hangup() from the ldisc side. However we | 766 | * from the ldisc side, which is now guaranteed. |
759 | * can't yet guarantee all that. | ||
760 | */ | 767 | */ |
761 | set_bit(TTY_HUPPED, &tty->flags); | 768 | set_bit(TTY_HUPPED, &tty->flags); |
762 | tty_unlock(tty); | 769 | tty_unlock(tty); |
@@ -1069,6 +1076,8 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count, | |||
1069 | /* We want to wait for the line discipline to sort out in this | 1076 | /* We want to wait for the line discipline to sort out in this |
1070 | situation */ | 1077 | situation */ |
1071 | ld = tty_ldisc_ref_wait(tty); | 1078 | ld = tty_ldisc_ref_wait(tty); |
1079 | if (!ld) | ||
1080 | return hung_up_tty_read(file, buf, count, ppos); | ||
1072 | if (ld->ops->read) | 1081 | if (ld->ops->read) |
1073 | i = ld->ops->read(tty, file, buf, count); | 1082 | i = ld->ops->read(tty, file, buf, count); |
1074 | else | 1083 | else |
@@ -1243,6 +1252,8 @@ static ssize_t tty_write(struct file *file, const char __user *buf, | |||
1243 | if (tty->ops->write_room == NULL) | 1252 | if (tty->ops->write_room == NULL) |
1244 | tty_err(tty, "missing write_room method\n"); | 1253 | tty_err(tty, "missing write_room method\n"); |
1245 | ld = tty_ldisc_ref_wait(tty); | 1254 | ld = tty_ldisc_ref_wait(tty); |
1255 | if (!ld) | ||
1256 | return hung_up_tty_write(file, buf, count, ppos); | ||
1246 | if (!ld->ops->write) | 1257 | if (!ld->ops->write) |
1247 | ret = -EIO; | 1258 | ret = -EIO; |
1248 | else | 1259 | else |
@@ -1378,7 +1389,7 @@ static struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver, | |||
1378 | * the tty_mutex currently so we can be relaxed about ordering. | 1389 | * the tty_mutex currently so we can be relaxed about ordering. |
1379 | */ | 1390 | */ |
1380 | 1391 | ||
1381 | int tty_init_termios(struct tty_struct *tty) | 1392 | void tty_init_termios(struct tty_struct *tty) |
1382 | { | 1393 | { |
1383 | struct ktermios *tp; | 1394 | struct ktermios *tp; |
1384 | int idx = tty->index; | 1395 | int idx = tty->index; |
@@ -1388,24 +1399,21 @@ int tty_init_termios(struct tty_struct *tty) | |||
1388 | else { | 1399 | else { |
1389 | /* Check for lazy saved data */ | 1400 | /* Check for lazy saved data */ |
1390 | tp = tty->driver->termios[idx]; | 1401 | tp = tty->driver->termios[idx]; |
1391 | if (tp != NULL) | 1402 | if (tp != NULL) { |
1392 | tty->termios = *tp; | 1403 | tty->termios = *tp; |
1393 | else | 1404 | tty->termios.c_line = tty->driver->init_termios.c_line; |
1405 | } else | ||
1394 | tty->termios = tty->driver->init_termios; | 1406 | tty->termios = tty->driver->init_termios; |
1395 | } | 1407 | } |
1396 | /* Compatibility until drivers always set this */ | 1408 | /* Compatibility until drivers always set this */ |
1397 | tty->termios.c_ispeed = tty_termios_input_baud_rate(&tty->termios); | 1409 | tty->termios.c_ispeed = tty_termios_input_baud_rate(&tty->termios); |
1398 | tty->termios.c_ospeed = tty_termios_baud_rate(&tty->termios); | 1410 | tty->termios.c_ospeed = tty_termios_baud_rate(&tty->termios); |
1399 | return 0; | ||
1400 | } | 1411 | } |
1401 | EXPORT_SYMBOL_GPL(tty_init_termios); | 1412 | EXPORT_SYMBOL_GPL(tty_init_termios); |
1402 | 1413 | ||
1403 | int tty_standard_install(struct tty_driver *driver, struct tty_struct *tty) | 1414 | int tty_standard_install(struct tty_driver *driver, struct tty_struct *tty) |
1404 | { | 1415 | { |
1405 | int ret = tty_init_termios(tty); | 1416 | tty_init_termios(tty); |
1406 | if (ret) | ||
1407 | return ret; | ||
1408 | |||
1409 | tty_driver_kref_get(driver); | 1417 | tty_driver_kref_get(driver); |
1410 | tty->count++; | 1418 | tty->count++; |
1411 | driver->ttys[tty->index] = tty; | 1419 | driver->ttys[tty->index] = tty; |
@@ -1442,7 +1450,7 @@ static int tty_driver_install_tty(struct tty_driver *driver, | |||
1442 | * | 1450 | * |
1443 | * Locking: tty_mutex for now | 1451 | * Locking: tty_mutex for now |
1444 | */ | 1452 | */ |
1445 | void tty_driver_remove_tty(struct tty_driver *driver, struct tty_struct *tty) | 1453 | static void tty_driver_remove_tty(struct tty_driver *driver, struct tty_struct *tty) |
1446 | { | 1454 | { |
1447 | if (driver->ops->remove) | 1455 | if (driver->ops->remove) |
1448 | driver->ops->remove(driver, tty); | 1456 | driver->ops->remove(driver, tty); |
@@ -1475,7 +1483,8 @@ static int tty_reopen(struct tty_struct *tty) | |||
1475 | 1483 | ||
1476 | tty->count++; | 1484 | tty->count++; |
1477 | 1485 | ||
1478 | WARN_ON(!tty->ldisc); | 1486 | if (!tty->ldisc) |
1487 | return tty_ldisc_reinit(tty, tty->termios.c_line); | ||
1479 | 1488 | ||
1480 | return 0; | 1489 | return 0; |
1481 | } | 1490 | } |
@@ -1529,7 +1538,7 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) | |||
1529 | tty_lock(tty); | 1538 | tty_lock(tty); |
1530 | retval = tty_driver_install_tty(driver, tty); | 1539 | retval = tty_driver_install_tty(driver, tty); |
1531 | if (retval < 0) | 1540 | if (retval < 0) |
1532 | goto err_deinit_tty; | 1541 | goto err_free_tty; |
1533 | 1542 | ||
1534 | if (!tty->port) | 1543 | if (!tty->port) |
1535 | tty->port = driver->ports[idx]; | 1544 | tty->port = driver->ports[idx]; |
@@ -1551,9 +1560,8 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) | |||
1551 | /* Return the tty locked so that it cannot vanish under the caller */ | 1560 | /* Return the tty locked so that it cannot vanish under the caller */ |
1552 | return tty; | 1561 | return tty; |
1553 | 1562 | ||
1554 | err_deinit_tty: | 1563 | err_free_tty: |
1555 | tty_unlock(tty); | 1564 | tty_unlock(tty); |
1556 | deinitialize_tty_struct(tty); | ||
1557 | free_tty_struct(tty); | 1565 | free_tty_struct(tty); |
1558 | err_module_put: | 1566 | err_module_put: |
1559 | module_put(driver->owner); | 1567 | module_put(driver->owner); |
@@ -1568,7 +1576,7 @@ err_release_tty: | |||
1568 | return ERR_PTR(retval); | 1576 | return ERR_PTR(retval); |
1569 | } | 1577 | } |
1570 | 1578 | ||
1571 | void tty_free_termios(struct tty_struct *tty) | 1579 | static void tty_free_termios(struct tty_struct *tty) |
1572 | { | 1580 | { |
1573 | struct ktermios *tp; | 1581 | struct ktermios *tp; |
1574 | int idx = tty->index; | 1582 | int idx = tty->index; |
@@ -1587,7 +1595,6 @@ void tty_free_termios(struct tty_struct *tty) | |||
1587 | } | 1595 | } |
1588 | *tp = tty->termios; | 1596 | *tp = tty->termios; |
1589 | } | 1597 | } |
1590 | EXPORT_SYMBOL(tty_free_termios); | ||
1591 | 1598 | ||
1592 | /** | 1599 | /** |
1593 | * tty_flush_works - flush all works of a tty/pty pair | 1600 | * tty_flush_works - flush all works of a tty/pty pair |
@@ -1634,9 +1641,9 @@ static void release_one_tty(struct work_struct *work) | |||
1634 | tty_driver_kref_put(driver); | 1641 | tty_driver_kref_put(driver); |
1635 | module_put(owner); | 1642 | module_put(owner); |
1636 | 1643 | ||
1637 | spin_lock(&tty_files_lock); | 1644 | spin_lock(&tty->files_lock); |
1638 | list_del_init(&tty->tty_files); | 1645 | list_del_init(&tty->tty_files); |
1639 | spin_unlock(&tty_files_lock); | 1646 | spin_unlock(&tty->files_lock); |
1640 | 1647 | ||
1641 | put_pid(tty->pgrp); | 1648 | put_pid(tty->pgrp); |
1642 | put_pid(tty->session); | 1649 | put_pid(tty->session); |
@@ -1967,7 +1974,7 @@ static struct tty_struct *tty_open_current_tty(dev_t device, struct file *filp) | |||
1967 | * Locking: tty_mutex protects get_tty_driver | 1974 | * Locking: tty_mutex protects get_tty_driver |
1968 | */ | 1975 | */ |
1969 | static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp, | 1976 | static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp, |
1970 | int *noctty, int *index) | 1977 | int *index) |
1971 | { | 1978 | { |
1972 | struct tty_driver *driver; | 1979 | struct tty_driver *driver; |
1973 | 1980 | ||
@@ -1977,7 +1984,6 @@ static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp, | |||
1977 | extern struct tty_driver *console_driver; | 1984 | extern struct tty_driver *console_driver; |
1978 | driver = tty_driver_kref_get(console_driver); | 1985 | driver = tty_driver_kref_get(console_driver); |
1979 | *index = fg_console; | 1986 | *index = fg_console; |
1980 | *noctty = 1; | ||
1981 | break; | 1987 | break; |
1982 | } | 1988 | } |
1983 | #endif | 1989 | #endif |
@@ -1988,7 +1994,6 @@ static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp, | |||
1988 | if (driver) { | 1994 | if (driver) { |
1989 | /* Don't let /dev/console block */ | 1995 | /* Don't let /dev/console block */ |
1990 | filp->f_flags |= O_NONBLOCK; | 1996 | filp->f_flags |= O_NONBLOCK; |
1991 | *noctty = 1; | ||
1992 | break; | 1997 | break; |
1993 | } | 1998 | } |
1994 | } | 1999 | } |
@@ -2004,6 +2009,69 @@ static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp, | |||
2004 | } | 2009 | } |
2005 | 2010 | ||
2006 | /** | 2011 | /** |
2012 | * tty_open_by_driver - open a tty device | ||
2013 | * @device: dev_t of device to open | ||
2014 | * @inode: inode of device file | ||
2015 | * @filp: file pointer to tty | ||
2016 | * | ||
2017 | * Performs the driver lookup, checks for a reopen, or otherwise | ||
2018 | * performs the first-time tty initialization. | ||
2019 | * | ||
2020 | * Returns the locked initialized or re-opened &tty_struct | ||
2021 | * | ||
2022 | * Claims the global tty_mutex to serialize: | ||
2023 | * - concurrent first-time tty initialization | ||
2024 | * - concurrent tty driver removal w/ lookup | ||
2025 | * - concurrent tty removal from driver table | ||
2026 | */ | ||
2027 | static struct tty_struct *tty_open_by_driver(dev_t device, struct inode *inode, | ||
2028 | struct file *filp) | ||
2029 | { | ||
2030 | struct tty_struct *tty; | ||
2031 | struct tty_driver *driver = NULL; | ||
2032 | int index = -1; | ||
2033 | int retval; | ||
2034 | |||
2035 | mutex_lock(&tty_mutex); | ||
2036 | driver = tty_lookup_driver(device, filp, &index); | ||
2037 | if (IS_ERR(driver)) { | ||
2038 | mutex_unlock(&tty_mutex); | ||
2039 | return ERR_CAST(driver); | ||
2040 | } | ||
2041 | |||
2042 | /* check whether we're reopening an existing tty */ | ||
2043 | tty = tty_driver_lookup_tty(driver, inode, index); | ||
2044 | if (IS_ERR(tty)) { | ||
2045 | mutex_unlock(&tty_mutex); | ||
2046 | goto out; | ||
2047 | } | ||
2048 | |||
2049 | if (tty) { | ||
2050 | mutex_unlock(&tty_mutex); | ||
2051 | retval = tty_lock_interruptible(tty); | ||
2052 | if (retval) { | ||
2053 | if (retval == -EINTR) | ||
2054 | retval = -ERESTARTSYS; | ||
2055 | tty = ERR_PTR(retval); | ||
2056 | goto out; | ||
2057 | } | ||
2058 | /* safe to drop the kref from tty_driver_lookup_tty() */ | ||
2059 | tty_kref_put(tty); | ||
2060 | retval = tty_reopen(tty); | ||
2061 | if (retval < 0) { | ||
2062 | tty_unlock(tty); | ||
2063 | tty = ERR_PTR(retval); | ||
2064 | } | ||
2065 | } else { /* Returns with the tty_lock held for now */ | ||
2066 | tty = tty_init_dev(driver, index); | ||
2067 | mutex_unlock(&tty_mutex); | ||
2068 | } | ||
2069 | out: | ||
2070 | tty_driver_kref_put(driver); | ||
2071 | return tty; | ||
2072 | } | ||
2073 | |||
2074 | /** | ||
2007 | * tty_open - open a tty device | 2075 | * tty_open - open a tty device |
2008 | * @inode: inode of device file | 2076 | * @inode: inode of device file |
2009 | * @filp: file pointer to tty | 2077 | * @filp: file pointer to tty |
@@ -2031,8 +2099,6 @@ static int tty_open(struct inode *inode, struct file *filp) | |||
2031 | { | 2099 | { |
2032 | struct tty_struct *tty; | 2100 | struct tty_struct *tty; |
2033 | int noctty, retval; | 2101 | int noctty, retval; |
2034 | struct tty_driver *driver = NULL; | ||
2035 | int index; | ||
2036 | dev_t device = inode->i_rdev; | 2102 | dev_t device = inode->i_rdev; |
2037 | unsigned saved_flags = filp->f_flags; | 2103 | unsigned saved_flags = filp->f_flags; |
2038 | 2104 | ||
@@ -2043,53 +2109,15 @@ retry_open: | |||
2043 | if (retval) | 2109 | if (retval) |
2044 | return -ENOMEM; | 2110 | return -ENOMEM; |
2045 | 2111 | ||
2046 | noctty = filp->f_flags & O_NOCTTY; | ||
2047 | index = -1; | ||
2048 | retval = 0; | ||
2049 | |||
2050 | tty = tty_open_current_tty(device, filp); | 2112 | tty = tty_open_current_tty(device, filp); |
2051 | if (!tty) { | 2113 | if (!tty) |
2052 | mutex_lock(&tty_mutex); | 2114 | tty = tty_open_by_driver(device, inode, filp); |
2053 | driver = tty_lookup_driver(device, filp, &noctty, &index); | ||
2054 | if (IS_ERR(driver)) { | ||
2055 | retval = PTR_ERR(driver); | ||
2056 | goto err_unlock; | ||
2057 | } | ||
2058 | |||
2059 | /* check whether we're reopening an existing tty */ | ||
2060 | tty = tty_driver_lookup_tty(driver, inode, index); | ||
2061 | if (IS_ERR(tty)) { | ||
2062 | retval = PTR_ERR(tty); | ||
2063 | goto err_unlock; | ||
2064 | } | ||
2065 | |||
2066 | if (tty) { | ||
2067 | mutex_unlock(&tty_mutex); | ||
2068 | retval = tty_lock_interruptible(tty); | ||
2069 | tty_kref_put(tty); /* drop kref from tty_driver_lookup_tty() */ | ||
2070 | if (retval) { | ||
2071 | if (retval == -EINTR) | ||
2072 | retval = -ERESTARTSYS; | ||
2073 | goto err_unref; | ||
2074 | } | ||
2075 | retval = tty_reopen(tty); | ||
2076 | if (retval < 0) { | ||
2077 | tty_unlock(tty); | ||
2078 | tty = ERR_PTR(retval); | ||
2079 | } | ||
2080 | } else { /* Returns with the tty_lock held for now */ | ||
2081 | tty = tty_init_dev(driver, index); | ||
2082 | mutex_unlock(&tty_mutex); | ||
2083 | } | ||
2084 | |||
2085 | tty_driver_kref_put(driver); | ||
2086 | } | ||
2087 | 2115 | ||
2088 | if (IS_ERR(tty)) { | 2116 | if (IS_ERR(tty)) { |
2117 | tty_free_file(filp); | ||
2089 | retval = PTR_ERR(tty); | 2118 | retval = PTR_ERR(tty); |
2090 | if (retval != -EAGAIN || signal_pending(current)) | 2119 | if (retval != -EAGAIN || signal_pending(current)) |
2091 | goto err_file; | 2120 | return retval; |
2092 | tty_free_file(filp); | ||
2093 | schedule(); | 2121 | schedule(); |
2094 | goto retry_open; | 2122 | goto retry_open; |
2095 | } | 2123 | } |
@@ -2097,10 +2125,6 @@ retry_open: | |||
2097 | tty_add_file(tty, filp); | 2125 | tty_add_file(tty, filp); |
2098 | 2126 | ||
2099 | check_tty_count(tty, __func__); | 2127 | check_tty_count(tty, __func__); |
2100 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && | ||
2101 | tty->driver->subtype == PTY_TYPE_MASTER) | ||
2102 | noctty = 1; | ||
2103 | |||
2104 | tty_debug_hangup(tty, "opening (count=%d)\n", tty->count); | 2128 | tty_debug_hangup(tty, "opening (count=%d)\n", tty->count); |
2105 | 2129 | ||
2106 | if (tty->ops->open) | 2130 | if (tty->ops->open) |
@@ -2133,6 +2157,12 @@ retry_open: | |||
2133 | 2157 | ||
2134 | read_lock(&tasklist_lock); | 2158 | read_lock(&tasklist_lock); |
2135 | spin_lock_irq(¤t->sighand->siglock); | 2159 | spin_lock_irq(¤t->sighand->siglock); |
2160 | noctty = (filp->f_flags & O_NOCTTY) || | ||
2161 | device == MKDEV(TTY_MAJOR, 0) || | ||
2162 | device == MKDEV(TTYAUX_MAJOR, 1) || | ||
2163 | (tty->driver->type == TTY_DRIVER_TYPE_PTY && | ||
2164 | tty->driver->subtype == PTY_TYPE_MASTER); | ||
2165 | |||
2136 | if (!noctty && | 2166 | if (!noctty && |
2137 | current->signal->leader && | 2167 | current->signal->leader && |
2138 | !current->signal->tty && | 2168 | !current->signal->tty && |
@@ -2158,15 +2188,6 @@ retry_open: | |||
2158 | read_unlock(&tasklist_lock); | 2188 | read_unlock(&tasklist_lock); |
2159 | tty_unlock(tty); | 2189 | tty_unlock(tty); |
2160 | return 0; | 2190 | return 0; |
2161 | err_unlock: | ||
2162 | mutex_unlock(&tty_mutex); | ||
2163 | err_unref: | ||
2164 | /* after locks to avoid deadlock */ | ||
2165 | if (!IS_ERR_OR_NULL(driver)) | ||
2166 | tty_driver_kref_put(driver); | ||
2167 | err_file: | ||
2168 | tty_free_file(filp); | ||
2169 | return retval; | ||
2170 | } | 2191 | } |
2171 | 2192 | ||
2172 | 2193 | ||
@@ -2193,6 +2214,8 @@ static unsigned int tty_poll(struct file *filp, poll_table *wait) | |||
2193 | return 0; | 2214 | return 0; |
2194 | 2215 | ||
2195 | ld = tty_ldisc_ref_wait(tty); | 2216 | ld = tty_ldisc_ref_wait(tty); |
2217 | if (!ld) | ||
2218 | return hung_up_tty_poll(filp, wait); | ||
2196 | if (ld->ops->poll) | 2219 | if (ld->ops->poll) |
2197 | ret = ld->ops->poll(tty, filp, wait); | 2220 | ret = ld->ops->poll(tty, filp, wait); |
2198 | tty_ldisc_deref(ld); | 2221 | tty_ldisc_deref(ld); |
@@ -2202,7 +2225,6 @@ static unsigned int tty_poll(struct file *filp, poll_table *wait) | |||
2202 | static int __tty_fasync(int fd, struct file *filp, int on) | 2225 | static int __tty_fasync(int fd, struct file *filp, int on) |
2203 | { | 2226 | { |
2204 | struct tty_struct *tty = file_tty(filp); | 2227 | struct tty_struct *tty = file_tty(filp); |
2205 | struct tty_ldisc *ldisc; | ||
2206 | unsigned long flags; | 2228 | unsigned long flags; |
2207 | int retval = 0; | 2229 | int retval = 0; |
2208 | 2230 | ||
@@ -2213,13 +2235,6 @@ static int __tty_fasync(int fd, struct file *filp, int on) | |||
2213 | if (retval <= 0) | 2235 | if (retval <= 0) |
2214 | goto out; | 2236 | goto out; |
2215 | 2237 | ||
2216 | ldisc = tty_ldisc_ref(tty); | ||
2217 | if (ldisc) { | ||
2218 | if (ldisc->ops->fasync) | ||
2219 | ldisc->ops->fasync(tty, on); | ||
2220 | tty_ldisc_deref(ldisc); | ||
2221 | } | ||
2222 | |||
2223 | if (on) { | 2238 | if (on) { |
2224 | enum pid_type type; | 2239 | enum pid_type type; |
2225 | struct pid *pid; | 2240 | struct pid *pid; |
@@ -2245,10 +2260,11 @@ out: | |||
2245 | static int tty_fasync(int fd, struct file *filp, int on) | 2260 | static int tty_fasync(int fd, struct file *filp, int on) |
2246 | { | 2261 | { |
2247 | struct tty_struct *tty = file_tty(filp); | 2262 | struct tty_struct *tty = file_tty(filp); |
2248 | int retval; | 2263 | int retval = -ENOTTY; |
2249 | 2264 | ||
2250 | tty_lock(tty); | 2265 | tty_lock(tty); |
2251 | retval = __tty_fasync(fd, filp, on); | 2266 | if (!tty_hung_up_p(filp)) |
2267 | retval = __tty_fasync(fd, filp, on); | ||
2252 | tty_unlock(tty); | 2268 | tty_unlock(tty); |
2253 | 2269 | ||
2254 | return retval; | 2270 | return retval; |
@@ -2282,6 +2298,8 @@ static int tiocsti(struct tty_struct *tty, char __user *p) | |||
2282 | return -EFAULT; | 2298 | return -EFAULT; |
2283 | tty_audit_tiocsti(tty, ch); | 2299 | tty_audit_tiocsti(tty, ch); |
2284 | ld = tty_ldisc_ref_wait(tty); | 2300 | ld = tty_ldisc_ref_wait(tty); |
2301 | if (!ld) | ||
2302 | return -EIO; | ||
2285 | ld->ops->receive_buf(tty, &ch, &mbz, 1); | 2303 | ld->ops->receive_buf(tty, &ch, &mbz, 1); |
2286 | tty_ldisc_deref(ld); | 2304 | tty_ldisc_deref(ld); |
2287 | return 0; | 2305 | return 0; |
@@ -2646,13 +2664,13 @@ static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t _ | |||
2646 | 2664 | ||
2647 | static int tiocsetd(struct tty_struct *tty, int __user *p) | 2665 | static int tiocsetd(struct tty_struct *tty, int __user *p) |
2648 | { | 2666 | { |
2649 | int ldisc; | 2667 | int disc; |
2650 | int ret; | 2668 | int ret; |
2651 | 2669 | ||
2652 | if (get_user(ldisc, p)) | 2670 | if (get_user(disc, p)) |
2653 | return -EFAULT; | 2671 | return -EFAULT; |
2654 | 2672 | ||
2655 | ret = tty_set_ldisc(tty, ldisc); | 2673 | ret = tty_set_ldisc(tty, disc); |
2656 | 2674 | ||
2657 | return ret; | 2675 | return ret; |
2658 | } | 2676 | } |
@@ -2674,6 +2692,8 @@ static int tiocgetd(struct tty_struct *tty, int __user *p) | |||
2674 | int ret; | 2692 | int ret; |
2675 | 2693 | ||
2676 | ld = tty_ldisc_ref_wait(tty); | 2694 | ld = tty_ldisc_ref_wait(tty); |
2695 | if (!ld) | ||
2696 | return -EIO; | ||
2677 | ret = put_user(ld->ops->num, p); | 2697 | ret = put_user(ld->ops->num, p); |
2678 | tty_ldisc_deref(ld); | 2698 | tty_ldisc_deref(ld); |
2679 | return ret; | 2699 | return ret; |
@@ -2971,6 +2991,8 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
2971 | return retval; | 2991 | return retval; |
2972 | } | 2992 | } |
2973 | ld = tty_ldisc_ref_wait(tty); | 2993 | ld = tty_ldisc_ref_wait(tty); |
2994 | if (!ld) | ||
2995 | return hung_up_tty_ioctl(file, cmd, arg); | ||
2974 | retval = -EINVAL; | 2996 | retval = -EINVAL; |
2975 | if (ld->ops->ioctl) { | 2997 | if (ld->ops->ioctl) { |
2976 | retval = ld->ops->ioctl(tty, file, cmd, arg); | 2998 | retval = ld->ops->ioctl(tty, file, cmd, arg); |
@@ -2999,6 +3021,8 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd, | |||
2999 | } | 3021 | } |
3000 | 3022 | ||
3001 | ld = tty_ldisc_ref_wait(tty); | 3023 | ld = tty_ldisc_ref_wait(tty); |
3024 | if (!ld) | ||
3025 | return hung_up_tty_compat_ioctl(file, cmd, arg); | ||
3002 | if (ld->ops->compat_ioctl) | 3026 | if (ld->ops->compat_ioctl) |
3003 | retval = ld->ops->compat_ioctl(tty, file, cmd, arg); | 3027 | retval = ld->ops->compat_ioctl(tty, file, cmd, arg); |
3004 | else | 3028 | else |
@@ -3149,6 +3173,7 @@ struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx) | |||
3149 | mutex_init(&tty->atomic_write_lock); | 3173 | mutex_init(&tty->atomic_write_lock); |
3150 | spin_lock_init(&tty->ctrl_lock); | 3174 | spin_lock_init(&tty->ctrl_lock); |
3151 | spin_lock_init(&tty->flow_lock); | 3175 | spin_lock_init(&tty->flow_lock); |
3176 | spin_lock_init(&tty->files_lock); | ||
3152 | INIT_LIST_HEAD(&tty->tty_files); | 3177 | INIT_LIST_HEAD(&tty->tty_files); |
3153 | INIT_WORK(&tty->SAK_work, do_SAK_work); | 3178 | INIT_WORK(&tty->SAK_work, do_SAK_work); |
3154 | 3179 | ||
@@ -3162,20 +3187,6 @@ struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx) | |||
3162 | } | 3187 | } |
3163 | 3188 | ||
3164 | /** | 3189 | /** |
3165 | * deinitialize_tty_struct | ||
3166 | * @tty: tty to deinitialize | ||
3167 | * | ||
3168 | * This subroutine deinitializes a tty structure that has been newly | ||
3169 | * allocated but tty_release cannot be called on that yet. | ||
3170 | * | ||
3171 | * Locking: none - tty in question must not be exposed at this point | ||
3172 | */ | ||
3173 | void deinitialize_tty_struct(struct tty_struct *tty) | ||
3174 | { | ||
3175 | tty_ldisc_deinit(tty); | ||
3176 | } | ||
3177 | |||
3178 | /** | ||
3179 | * tty_put_char - write one character to a tty | 3190 | * tty_put_char - write one character to a tty |
3180 | * @tty: tty | 3191 | * @tty: tty |
3181 | * @ch: character | 3192 | * @ch: character |
@@ -3569,7 +3580,7 @@ void __init console_init(void) | |||
3569 | initcall_t *call; | 3580 | initcall_t *call; |
3570 | 3581 | ||
3571 | /* Setup the default TTY line discipline. */ | 3582 | /* Setup the default TTY line discipline. */ |
3572 | tty_ldisc_begin(); | 3583 | n_tty_init(); |
3573 | 3584 | ||
3574 | /* | 3585 | /* |
3575 | * set up the console device so that later boot sequences can | 3586 | * set up the console device so that later boot sequences can |
diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 0ea351388724..23bf5bb1d8bf 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c | |||
@@ -719,16 +719,16 @@ static int get_sgflags(struct tty_struct *tty) | |||
719 | { | 719 | { |
720 | int flags = 0; | 720 | int flags = 0; |
721 | 721 | ||
722 | if (!(tty->termios.c_lflag & ICANON)) { | 722 | if (!L_ICANON(tty)) { |
723 | if (tty->termios.c_lflag & ISIG) | 723 | if (L_ISIG(tty)) |
724 | flags |= 0x02; /* cbreak */ | 724 | flags |= 0x02; /* cbreak */ |
725 | else | 725 | else |
726 | flags |= 0x20; /* raw */ | 726 | flags |= 0x20; /* raw */ |
727 | } | 727 | } |
728 | if (tty->termios.c_lflag & ECHO) | 728 | if (L_ECHO(tty)) |
729 | flags |= 0x08; /* echo */ | 729 | flags |= 0x08; /* echo */ |
730 | if (tty->termios.c_oflag & OPOST) | 730 | if (O_OPOST(tty)) |
731 | if (tty->termios.c_oflag & ONLCR) | 731 | if (O_ONLCR(tty)) |
732 | flags |= 0x10; /* crmod */ | 732 | flags |= 0x10; /* crmod */ |
733 | return flags; | 733 | return flags; |
734 | } | 734 | } |
@@ -908,7 +908,7 @@ static int tty_change_softcar(struct tty_struct *tty, int arg) | |||
908 | tty->termios.c_cflag |= bit; | 908 | tty->termios.c_cflag |= bit; |
909 | if (tty->ops->set_termios) | 909 | if (tty->ops->set_termios) |
910 | tty->ops->set_termios(tty, &old); | 910 | tty->ops->set_termios(tty, &old); |
911 | if ((tty->termios.c_cflag & CLOCAL) != bit) | 911 | if (C_CLOCAL(tty) != bit) |
912 | ret = -EINVAL; | 912 | ret = -EINVAL; |
913 | up_write(&tty->termios_rwsem); | 913 | up_write(&tty->termios_rwsem); |
914 | return ret; | 914 | return ret; |
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index a054d03c22e7..68947f6de5ad 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c | |||
@@ -140,9 +140,16 @@ static void put_ldops(struct tty_ldisc_ops *ldops) | |||
140 | * @disc: ldisc number | 140 | * @disc: ldisc number |
141 | * | 141 | * |
142 | * Takes a reference to a line discipline. Deals with refcounts and | 142 | * Takes a reference to a line discipline. Deals with refcounts and |
143 | * module locking counts. Returns NULL if the discipline is not available. | 143 | * module locking counts. |
144 | * Returns a pointer to the discipline and bumps the ref count if it is | 144 | * |
145 | * available | 145 | * Returns: -EINVAL if the discipline index is not [N_TTY..NR_LDISCS] or |
146 | * if the discipline is not registered | ||
147 | * -EAGAIN if request_module() failed to load or register the | ||
148 | * the discipline | ||
149 | * -ENOMEM if allocation failure | ||
150 | * | ||
151 | * Otherwise, returns a pointer to the discipline and bumps the | ||
152 | * ref count | ||
146 | * | 153 | * |
147 | * Locking: | 154 | * Locking: |
148 | * takes tty_ldiscs_lock to guard against ldisc races | 155 | * takes tty_ldiscs_lock to guard against ldisc races |
@@ -250,19 +257,23 @@ const struct file_operations tty_ldiscs_proc_fops = { | |||
250 | * reference to it. If the line discipline is in flux then | 257 | * reference to it. If the line discipline is in flux then |
251 | * wait patiently until it changes. | 258 | * wait patiently until it changes. |
252 | * | 259 | * |
260 | * Returns: NULL if the tty has been hungup and not re-opened with | ||
261 | * a new file descriptor, otherwise valid ldisc reference | ||
262 | * | ||
253 | * Note: Must not be called from an IRQ/timer context. The caller | 263 | * Note: Must not be called from an IRQ/timer context. The caller |
254 | * must also be careful not to hold other locks that will deadlock | 264 | * must also be careful not to hold other locks that will deadlock |
255 | * against a discipline change, such as an existing ldisc reference | 265 | * against a discipline change, such as an existing ldisc reference |
256 | * (which we check for) | 266 | * (which we check for) |
257 | * | 267 | * |
258 | * Note: only callable from a file_operations routine (which | 268 | * Note: a file_operations routine (read/poll/write) should use this |
259 | * guarantees tty->ldisc != NULL when the lock is acquired). | 269 | * function to wait for any ldisc lifetime events to finish. |
260 | */ | 270 | */ |
261 | 271 | ||
262 | struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty) | 272 | struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty) |
263 | { | 273 | { |
264 | ldsem_down_read(&tty->ldisc_sem, MAX_SCHEDULE_TIMEOUT); | 274 | ldsem_down_read(&tty->ldisc_sem, MAX_SCHEDULE_TIMEOUT); |
265 | WARN_ON(!tty->ldisc); | 275 | if (!tty->ldisc) |
276 | ldsem_up_read(&tty->ldisc_sem); | ||
266 | return tty->ldisc; | 277 | return tty->ldisc; |
267 | } | 278 | } |
268 | EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait); | 279 | EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait); |
@@ -304,13 +315,13 @@ void tty_ldisc_deref(struct tty_ldisc *ld) | |||
304 | EXPORT_SYMBOL_GPL(tty_ldisc_deref); | 315 | EXPORT_SYMBOL_GPL(tty_ldisc_deref); |
305 | 316 | ||
306 | 317 | ||
307 | static inline int __lockfunc | 318 | static inline int |
308 | __tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout) | 319 | __tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout) |
309 | { | 320 | { |
310 | return ldsem_down_write(&tty->ldisc_sem, timeout); | 321 | return ldsem_down_write(&tty->ldisc_sem, timeout); |
311 | } | 322 | } |
312 | 323 | ||
313 | static inline int __lockfunc | 324 | static inline int |
314 | __tty_ldisc_lock_nested(struct tty_struct *tty, unsigned long timeout) | 325 | __tty_ldisc_lock_nested(struct tty_struct *tty, unsigned long timeout) |
315 | { | 326 | { |
316 | return ldsem_down_write_nested(&tty->ldisc_sem, | 327 | return ldsem_down_write_nested(&tty->ldisc_sem, |
@@ -322,8 +333,7 @@ static inline void __tty_ldisc_unlock(struct tty_struct *tty) | |||
322 | ldsem_up_write(&tty->ldisc_sem); | 333 | ldsem_up_write(&tty->ldisc_sem); |
323 | } | 334 | } |
324 | 335 | ||
325 | static int __lockfunc | 336 | static int tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout) |
326 | tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout) | ||
327 | { | 337 | { |
328 | int ret; | 338 | int ret; |
329 | 339 | ||
@@ -340,7 +350,7 @@ static void tty_ldisc_unlock(struct tty_struct *tty) | |||
340 | __tty_ldisc_unlock(tty); | 350 | __tty_ldisc_unlock(tty); |
341 | } | 351 | } |
342 | 352 | ||
343 | static int __lockfunc | 353 | static int |
344 | tty_ldisc_lock_pair_timeout(struct tty_struct *tty, struct tty_struct *tty2, | 354 | tty_ldisc_lock_pair_timeout(struct tty_struct *tty, struct tty_struct *tty2, |
345 | unsigned long timeout) | 355 | unsigned long timeout) |
346 | { | 356 | { |
@@ -376,14 +386,13 @@ tty_ldisc_lock_pair_timeout(struct tty_struct *tty, struct tty_struct *tty2, | |||
376 | return 0; | 386 | return 0; |
377 | } | 387 | } |
378 | 388 | ||
379 | static void __lockfunc | 389 | static void tty_ldisc_lock_pair(struct tty_struct *tty, struct tty_struct *tty2) |
380 | tty_ldisc_lock_pair(struct tty_struct *tty, struct tty_struct *tty2) | ||
381 | { | 390 | { |
382 | tty_ldisc_lock_pair_timeout(tty, tty2, MAX_SCHEDULE_TIMEOUT); | 391 | tty_ldisc_lock_pair_timeout(tty, tty2, MAX_SCHEDULE_TIMEOUT); |
383 | } | 392 | } |
384 | 393 | ||
385 | static void __lockfunc tty_ldisc_unlock_pair(struct tty_struct *tty, | 394 | static void tty_ldisc_unlock_pair(struct tty_struct *tty, |
386 | struct tty_struct *tty2) | 395 | struct tty_struct *tty2) |
387 | { | 396 | { |
388 | __tty_ldisc_unlock(tty); | 397 | __tty_ldisc_unlock(tty); |
389 | if (tty2) | 398 | if (tty2) |
@@ -411,7 +420,7 @@ EXPORT_SYMBOL_GPL(tty_ldisc_flush); | |||
411 | /** | 420 | /** |
412 | * tty_set_termios_ldisc - set ldisc field | 421 | * tty_set_termios_ldisc - set ldisc field |
413 | * @tty: tty structure | 422 | * @tty: tty structure |
414 | * @num: line discipline number | 423 | * @disc: line discipline number |
415 | * | 424 | * |
416 | * This is probably overkill for real world processors but | 425 | * This is probably overkill for real world processors but |
417 | * they are not on hot paths so a little discipline won't do | 426 | * they are not on hot paths so a little discipline won't do |
@@ -424,10 +433,10 @@ EXPORT_SYMBOL_GPL(tty_ldisc_flush); | |||
424 | * Locking: takes termios_rwsem | 433 | * Locking: takes termios_rwsem |
425 | */ | 434 | */ |
426 | 435 | ||
427 | static void tty_set_termios_ldisc(struct tty_struct *tty, int num) | 436 | static void tty_set_termios_ldisc(struct tty_struct *tty, int disc) |
428 | { | 437 | { |
429 | down_write(&tty->termios_rwsem); | 438 | down_write(&tty->termios_rwsem); |
430 | tty->termios.c_line = num; | 439 | tty->termios.c_line = disc; |
431 | up_write(&tty->termios_rwsem); | 440 | up_write(&tty->termios_rwsem); |
432 | 441 | ||
433 | tty->disc_data = NULL; | 442 | tty->disc_data = NULL; |
@@ -455,7 +464,7 @@ static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld) | |||
455 | if (ret) | 464 | if (ret) |
456 | clear_bit(TTY_LDISC_OPEN, &tty->flags); | 465 | clear_bit(TTY_LDISC_OPEN, &tty->flags); |
457 | 466 | ||
458 | tty_ldisc_debug(tty, "%p: opened\n", tty->ldisc); | 467 | tty_ldisc_debug(tty, "%p: opened\n", ld); |
459 | return ret; | 468 | return ret; |
460 | } | 469 | } |
461 | return 0; | 470 | return 0; |
@@ -476,7 +485,7 @@ static void tty_ldisc_close(struct tty_struct *tty, struct tty_ldisc *ld) | |||
476 | clear_bit(TTY_LDISC_OPEN, &tty->flags); | 485 | clear_bit(TTY_LDISC_OPEN, &tty->flags); |
477 | if (ld->ops->close) | 486 | if (ld->ops->close) |
478 | ld->ops->close(tty); | 487 | ld->ops->close(tty); |
479 | tty_ldisc_debug(tty, "%p: closed\n", tty->ldisc); | 488 | tty_ldisc_debug(tty, "%p: closed\n", ld); |
480 | } | 489 | } |
481 | 490 | ||
482 | /** | 491 | /** |
@@ -525,12 +534,12 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old) | |||
525 | * the close of one side of a tty/pty pair, and eventually hangup. | 534 | * the close of one side of a tty/pty pair, and eventually hangup. |
526 | */ | 535 | */ |
527 | 536 | ||
528 | int tty_set_ldisc(struct tty_struct *tty, int ldisc) | 537 | int tty_set_ldisc(struct tty_struct *tty, int disc) |
529 | { | 538 | { |
530 | int retval; | 539 | int retval; |
531 | struct tty_ldisc *old_ldisc, *new_ldisc; | 540 | struct tty_ldisc *old_ldisc, *new_ldisc; |
532 | 541 | ||
533 | new_ldisc = tty_ldisc_get(tty, ldisc); | 542 | new_ldisc = tty_ldisc_get(tty, disc); |
534 | if (IS_ERR(new_ldisc)) | 543 | if (IS_ERR(new_ldisc)) |
535 | return PTR_ERR(new_ldisc); | 544 | return PTR_ERR(new_ldisc); |
536 | 545 | ||
@@ -539,8 +548,13 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
539 | if (retval) | 548 | if (retval) |
540 | goto err; | 549 | goto err; |
541 | 550 | ||
551 | if (!tty->ldisc) { | ||
552 | retval = -EIO; | ||
553 | goto out; | ||
554 | } | ||
555 | |||
542 | /* Check the no-op case */ | 556 | /* Check the no-op case */ |
543 | if (tty->ldisc->ops->num == ldisc) | 557 | if (tty->ldisc->ops->num == disc) |
544 | goto out; | 558 | goto out; |
545 | 559 | ||
546 | if (test_bit(TTY_HUPPED, &tty->flags)) { | 560 | if (test_bit(TTY_HUPPED, &tty->flags)) { |
@@ -556,7 +570,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
556 | 570 | ||
557 | /* Now set up the new line discipline. */ | 571 | /* Now set up the new line discipline. */ |
558 | tty->ldisc = new_ldisc; | 572 | tty->ldisc = new_ldisc; |
559 | tty_set_termios_ldisc(tty, ldisc); | 573 | tty_set_termios_ldisc(tty, disc); |
560 | 574 | ||
561 | retval = tty_ldisc_open(tty, new_ldisc); | 575 | retval = tty_ldisc_open(tty, new_ldisc); |
562 | if (retval < 0) { | 576 | if (retval < 0) { |
@@ -590,6 +604,25 @@ err: | |||
590 | } | 604 | } |
591 | 605 | ||
592 | /** | 606 | /** |
607 | * tty_ldisc_kill - teardown ldisc | ||
608 | * @tty: tty being released | ||
609 | * | ||
610 | * Perform final close of the ldisc and reset tty->ldisc | ||
611 | */ | ||
612 | static void tty_ldisc_kill(struct tty_struct *tty) | ||
613 | { | ||
614 | if (!tty->ldisc) | ||
615 | return; | ||
616 | /* | ||
617 | * Now kill off the ldisc | ||
618 | */ | ||
619 | tty_ldisc_close(tty, tty->ldisc); | ||
620 | tty_ldisc_put(tty->ldisc); | ||
621 | /* Force an oops if we mess this up */ | ||
622 | tty->ldisc = NULL; | ||
623 | } | ||
624 | |||
625 | /** | ||
593 | * tty_reset_termios - reset terminal state | 626 | * tty_reset_termios - reset terminal state |
594 | * @tty: tty to reset | 627 | * @tty: tty to reset |
595 | * | 628 | * |
@@ -609,28 +642,44 @@ static void tty_reset_termios(struct tty_struct *tty) | |||
609 | /** | 642 | /** |
610 | * tty_ldisc_reinit - reinitialise the tty ldisc | 643 | * tty_ldisc_reinit - reinitialise the tty ldisc |
611 | * @tty: tty to reinit | 644 | * @tty: tty to reinit |
612 | * @ldisc: line discipline to reinitialize | 645 | * @disc: line discipline to reinitialize |
646 | * | ||
647 | * Completely reinitialize the line discipline state, by closing the | ||
648 | * current instance, if there is one, and opening a new instance. If | ||
649 | * an error occurs opening the new non-N_TTY instance, the instance | ||
650 | * is dropped and tty->ldisc reset to NULL. The caller can then retry | ||
651 | * with N_TTY instead. | ||
613 | * | 652 | * |
614 | * Switch the tty to a line discipline and leave the ldisc | 653 | * Returns 0 if successful, otherwise error code < 0 |
615 | * state closed | ||
616 | */ | 654 | */ |
617 | 655 | ||
618 | static int tty_ldisc_reinit(struct tty_struct *tty, int ldisc) | 656 | int tty_ldisc_reinit(struct tty_struct *tty, int disc) |
619 | { | 657 | { |
620 | struct tty_ldisc *ld = tty_ldisc_get(tty, ldisc); | 658 | struct tty_ldisc *ld; |
659 | int retval; | ||
621 | 660 | ||
622 | if (IS_ERR(ld)) | 661 | ld = tty_ldisc_get(tty, disc); |
623 | return -1; | 662 | if (IS_ERR(ld)) { |
663 | BUG_ON(disc == N_TTY); | ||
664 | return PTR_ERR(ld); | ||
665 | } | ||
624 | 666 | ||
625 | tty_ldisc_close(tty, tty->ldisc); | 667 | if (tty->ldisc) { |
626 | tty_ldisc_put(tty->ldisc); | 668 | tty_ldisc_close(tty, tty->ldisc); |
627 | /* | 669 | tty_ldisc_put(tty->ldisc); |
628 | * Switch the line discipline back | 670 | } |
629 | */ | ||
630 | tty->ldisc = ld; | ||
631 | tty_set_termios_ldisc(tty, ldisc); | ||
632 | 671 | ||
633 | return 0; | 672 | /* switch the line discipline */ |
673 | tty->ldisc = ld; | ||
674 | tty_set_termios_ldisc(tty, disc); | ||
675 | retval = tty_ldisc_open(tty, tty->ldisc); | ||
676 | if (retval) { | ||
677 | if (!WARN_ON(disc == N_TTY)) { | ||
678 | tty_ldisc_put(tty->ldisc); | ||
679 | tty->ldisc = NULL; | ||
680 | } | ||
681 | } | ||
682 | return retval; | ||
634 | } | 683 | } |
635 | 684 | ||
636 | /** | 685 | /** |
@@ -648,13 +697,11 @@ static int tty_ldisc_reinit(struct tty_struct *tty, int ldisc) | |||
648 | * tty itself so we must be careful about locking rules. | 697 | * tty itself so we must be careful about locking rules. |
649 | */ | 698 | */ |
650 | 699 | ||
651 | void tty_ldisc_hangup(struct tty_struct *tty) | 700 | void tty_ldisc_hangup(struct tty_struct *tty, bool reinit) |
652 | { | 701 | { |
653 | struct tty_ldisc *ld; | 702 | struct tty_ldisc *ld; |
654 | int reset = tty->driver->flags & TTY_DRIVER_RESET_TERMIOS; | ||
655 | int err = 0; | ||
656 | 703 | ||
657 | tty_ldisc_debug(tty, "%p: closing\n", tty->ldisc); | 704 | tty_ldisc_debug(tty, "%p: hangup\n", tty->ldisc); |
658 | 705 | ||
659 | ld = tty_ldisc_ref(tty); | 706 | ld = tty_ldisc_ref(tty); |
660 | if (ld != NULL) { | 707 | if (ld != NULL) { |
@@ -680,31 +727,17 @@ void tty_ldisc_hangup(struct tty_struct *tty) | |||
680 | */ | 727 | */ |
681 | tty_ldisc_lock(tty, MAX_SCHEDULE_TIMEOUT); | 728 | tty_ldisc_lock(tty, MAX_SCHEDULE_TIMEOUT); |
682 | 729 | ||
683 | if (tty->ldisc) { | 730 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) |
684 | 731 | tty_reset_termios(tty); | |
685 | /* At this point we have a halted ldisc; we want to close it and | ||
686 | reopen a new ldisc. We could defer the reopen to the next | ||
687 | open but it means auditing a lot of other paths so this is | ||
688 | a FIXME */ | ||
689 | if (reset == 0) { | ||
690 | 732 | ||
691 | if (!tty_ldisc_reinit(tty, tty->termios.c_line)) | 733 | if (tty->ldisc) { |
692 | err = tty_ldisc_open(tty, tty->ldisc); | 734 | if (reinit) { |
693 | else | 735 | if (tty_ldisc_reinit(tty, tty->termios.c_line) < 0) |
694 | err = 1; | 736 | tty_ldisc_reinit(tty, N_TTY); |
695 | } | 737 | } else |
696 | /* If the re-open fails or we reset then go to N_TTY. The | 738 | tty_ldisc_kill(tty); |
697 | N_TTY open cannot fail */ | ||
698 | if (reset || err) { | ||
699 | BUG_ON(tty_ldisc_reinit(tty, N_TTY)); | ||
700 | WARN_ON(tty_ldisc_open(tty, tty->ldisc)); | ||
701 | } | ||
702 | } | 739 | } |
703 | tty_ldisc_unlock(tty); | 740 | tty_ldisc_unlock(tty); |
704 | if (reset) | ||
705 | tty_reset_termios(tty); | ||
706 | |||
707 | tty_ldisc_debug(tty, "%p: re-opened\n", tty->ldisc); | ||
708 | } | 741 | } |
709 | 742 | ||
710 | /** | 743 | /** |
@@ -719,44 +752,26 @@ void tty_ldisc_hangup(struct tty_struct *tty) | |||
719 | 752 | ||
720 | int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty) | 753 | int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty) |
721 | { | 754 | { |
722 | struct tty_ldisc *ld = tty->ldisc; | 755 | int retval = tty_ldisc_open(tty, tty->ldisc); |
723 | int retval; | ||
724 | |||
725 | retval = tty_ldisc_open(tty, ld); | ||
726 | if (retval) | 756 | if (retval) |
727 | return retval; | 757 | return retval; |
728 | 758 | ||
729 | if (o_tty) { | 759 | if (o_tty) { |
730 | retval = tty_ldisc_open(o_tty, o_tty->ldisc); | 760 | retval = tty_ldisc_open(o_tty, o_tty->ldisc); |
731 | if (retval) { | 761 | if (retval) { |
732 | tty_ldisc_close(tty, ld); | 762 | tty_ldisc_close(tty, tty->ldisc); |
733 | return retval; | 763 | return retval; |
734 | } | 764 | } |
735 | } | 765 | } |
736 | return 0; | 766 | return 0; |
737 | } | 767 | } |
738 | 768 | ||
739 | static void tty_ldisc_kill(struct tty_struct *tty) | ||
740 | { | ||
741 | /* | ||
742 | * Now kill off the ldisc | ||
743 | */ | ||
744 | tty_ldisc_close(tty, tty->ldisc); | ||
745 | tty_ldisc_put(tty->ldisc); | ||
746 | /* Force an oops if we mess this up */ | ||
747 | tty->ldisc = NULL; | ||
748 | |||
749 | /* Ensure the next open requests the N_TTY ldisc */ | ||
750 | tty_set_termios_ldisc(tty, N_TTY); | ||
751 | } | ||
752 | |||
753 | /** | 769 | /** |
754 | * tty_ldisc_release - release line discipline | 770 | * tty_ldisc_release - release line discipline |
755 | * @tty: tty being shut down (or one end of pty pair) | 771 | * @tty: tty being shut down (or one end of pty pair) |
756 | * | 772 | * |
757 | * Called during the final close of a tty or a pty pair in order to shut | 773 | * Called during the final close of a tty or a pty pair in order to shut |
758 | * down the line discpline layer. On exit, each ldisc assigned is N_TTY and | 774 | * down the line discpline layer. On exit, each tty's ldisc is NULL. |
759 | * each ldisc has not been opened. | ||
760 | */ | 775 | */ |
761 | 776 | ||
762 | void tty_ldisc_release(struct tty_struct *tty) | 777 | void tty_ldisc_release(struct tty_struct *tty) |
@@ -797,7 +812,7 @@ void tty_ldisc_init(struct tty_struct *tty) | |||
797 | } | 812 | } |
798 | 813 | ||
799 | /** | 814 | /** |
800 | * tty_ldisc_init - ldisc cleanup for new tty | 815 | * tty_ldisc_deinit - ldisc cleanup for new tty |
801 | * @tty: tty that was allocated recently | 816 | * @tty: tty that was allocated recently |
802 | * | 817 | * |
803 | * The tty structure must not becompletely set up (tty_ldisc_setup) when | 818 | * The tty structure must not becompletely set up (tty_ldisc_setup) when |
@@ -805,12 +820,7 @@ void tty_ldisc_init(struct tty_struct *tty) | |||
805 | */ | 820 | */ |
806 | void tty_ldisc_deinit(struct tty_struct *tty) | 821 | void tty_ldisc_deinit(struct tty_struct *tty) |
807 | { | 822 | { |
808 | tty_ldisc_put(tty->ldisc); | 823 | if (tty->ldisc) |
824 | tty_ldisc_put(tty->ldisc); | ||
809 | tty->ldisc = NULL; | 825 | tty->ldisc = NULL; |
810 | } | 826 | } |
811 | |||
812 | void tty_ldisc_begin(void) | ||
813 | { | ||
814 | /* Setup the default TTY line discipline. */ | ||
815 | (void) tty_register_ldisc(N_TTY, &tty_ldisc_N_TTY); | ||
816 | } | ||
diff --git a/drivers/tty/tty_mutex.c b/drivers/tty/tty_mutex.c index dfa9ec03fa8e..d8bae67a6174 100644 --- a/drivers/tty/tty_mutex.c +++ b/drivers/tty/tty_mutex.c | |||
@@ -10,7 +10,7 @@ | |||
10 | * Getting the big tty mutex. | 10 | * Getting the big tty mutex. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | void __lockfunc tty_lock(struct tty_struct *tty) | 13 | void tty_lock(struct tty_struct *tty) |
14 | { | 14 | { |
15 | if (WARN(tty->magic != TTY_MAGIC, "L Bad %p\n", tty)) | 15 | if (WARN(tty->magic != TTY_MAGIC, "L Bad %p\n", tty)) |
16 | return; | 16 | return; |
@@ -32,7 +32,7 @@ int tty_lock_interruptible(struct tty_struct *tty) | |||
32 | return ret; | 32 | return ret; |
33 | } | 33 | } |
34 | 34 | ||
35 | void __lockfunc tty_unlock(struct tty_struct *tty) | 35 | void tty_unlock(struct tty_struct *tty) |
36 | { | 36 | { |
37 | if (WARN(tty->magic != TTY_MAGIC, "U Bad %p\n", tty)) | 37 | if (WARN(tty->magic != TTY_MAGIC, "U Bad %p\n", tty)) |
38 | return; | 38 | return; |
@@ -41,13 +41,13 @@ void __lockfunc tty_unlock(struct tty_struct *tty) | |||
41 | } | 41 | } |
42 | EXPORT_SYMBOL(tty_unlock); | 42 | EXPORT_SYMBOL(tty_unlock); |
43 | 43 | ||
44 | void __lockfunc tty_lock_slave(struct tty_struct *tty) | 44 | void tty_lock_slave(struct tty_struct *tty) |
45 | { | 45 | { |
46 | if (tty && tty != tty->link) | 46 | if (tty && tty != tty->link) |
47 | tty_lock(tty); | 47 | tty_lock(tty); |
48 | } | 48 | } |
49 | 49 | ||
50 | void __lockfunc tty_unlock_slave(struct tty_struct *tty) | 50 | void tty_unlock_slave(struct tty_struct *tty) |
51 | { | 51 | { |
52 | if (tty && tty != tty->link) | 52 | if (tty && tty != tty->link) |
53 | tty_unlock(tty); | 53 | tty_unlock(tty); |
diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 846ed481c24f..dbcca30a54b1 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c | |||
@@ -370,7 +370,7 @@ int tty_port_block_til_ready(struct tty_port *port, | |||
370 | } | 370 | } |
371 | if (filp->f_flags & O_NONBLOCK) { | 371 | if (filp->f_flags & O_NONBLOCK) { |
372 | /* Indicate we are open */ | 372 | /* Indicate we are open */ |
373 | if (tty->termios.c_cflag & CBAUD) | 373 | if (C_BAUD(tty)) |
374 | tty_port_raise_dtr_rts(port); | 374 | tty_port_raise_dtr_rts(port); |
375 | port->flags |= ASYNC_NORMAL_ACTIVE; | 375 | port->flags |= ASYNC_NORMAL_ACTIVE; |
376 | return 0; | 376 | return 0; |
@@ -476,7 +476,6 @@ int tty_port_close_start(struct tty_port *port, | |||
476 | spin_unlock_irqrestore(&port->lock, flags); | 476 | spin_unlock_irqrestore(&port->lock, flags); |
477 | return 0; | 477 | return 0; |
478 | } | 478 | } |
479 | set_bit(ASYNCB_CLOSING, &port->flags); | ||
480 | spin_unlock_irqrestore(&port->lock, flags); | 479 | spin_unlock_irqrestore(&port->lock, flags); |
481 | 480 | ||
482 | tty->closing = 1; | 481 | tty->closing = 1; |
@@ -510,14 +509,12 @@ void tty_port_close_end(struct tty_port *port, struct tty_struct *tty) | |||
510 | 509 | ||
511 | if (port->blocked_open) { | 510 | if (port->blocked_open) { |
512 | spin_unlock_irqrestore(&port->lock, flags); | 511 | spin_unlock_irqrestore(&port->lock, flags); |
513 | if (port->close_delay) { | 512 | if (port->close_delay) |
514 | msleep_interruptible( | 513 | msleep_interruptible(jiffies_to_msecs(port->close_delay)); |
515 | jiffies_to_msecs(port->close_delay)); | ||
516 | } | ||
517 | spin_lock_irqsave(&port->lock, flags); | 514 | spin_lock_irqsave(&port->lock, flags); |
518 | wake_up_interruptible(&port->open_wait); | 515 | wake_up_interruptible(&port->open_wait); |
519 | } | 516 | } |
520 | port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); | 517 | port->flags &= ~ASYNC_NORMAL_ACTIVE; |
521 | spin_unlock_irqrestore(&port->lock, flags); | 518 | spin_unlock_irqrestore(&port->lock, flags); |
522 | } | 519 | } |
523 | EXPORT_SYMBOL(tty_port_close_end); | 520 | EXPORT_SYMBOL(tty_port_close_end); |
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c index 6f0336fff501..f973bfce5d08 100644 --- a/drivers/tty/vt/keyboard.c +++ b/drivers/tty/vt/keyboard.c | |||
@@ -1706,16 +1706,12 @@ int vt_do_diacrit(unsigned int cmd, void __user *udp, int perm) | |||
1706 | return -EINVAL; | 1706 | return -EINVAL; |
1707 | 1707 | ||
1708 | if (ct) { | 1708 | if (ct) { |
1709 | dia = kmalloc(sizeof(struct kbdiacr) * ct, | ||
1710 | GFP_KERNEL); | ||
1711 | if (!dia) | ||
1712 | return -ENOMEM; | ||
1713 | 1709 | ||
1714 | if (copy_from_user(dia, a->kbdiacr, | 1710 | dia = memdup_user(a->kbdiacr, |
1715 | sizeof(struct kbdiacr) * ct)) { | 1711 | sizeof(struct kbdiacr) * ct); |
1716 | kfree(dia); | 1712 | if (IS_ERR(dia)) |
1717 | return -EFAULT; | 1713 | return PTR_ERR(dia); |
1718 | } | 1714 | |
1719 | } | 1715 | } |
1720 | 1716 | ||
1721 | spin_lock_irqsave(&kbd_event_lock, flags); | 1717 | spin_lock_irqsave(&kbd_event_lock, flags); |
diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c index 381a2b13682c..4dd9dd2270a0 100644 --- a/drivers/tty/vt/selection.c +++ b/drivers/tty/vt/selection.c | |||
@@ -347,6 +347,8 @@ int paste_selection(struct tty_struct *tty) | |||
347 | console_unlock(); | 347 | console_unlock(); |
348 | 348 | ||
349 | ld = tty_ldisc_ref_wait(tty); | 349 | ld = tty_ldisc_ref_wait(tty); |
350 | if (!ld) | ||
351 | return -EIO; /* ldisc was hung up */ | ||
350 | tty_buffer_lock_exclusive(&vc->port); | 352 | tty_buffer_lock_exclusive(&vc->port); |
351 | 353 | ||
352 | add_wait_queue(&vc->paste_wait, &wait); | 354 | add_wait_queue(&vc->paste_wait, &wait); |
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index bd51bdd0a7bf..3e3c7575e92d 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c | |||
@@ -568,7 +568,7 @@ static void delete_char(struct vc_data *vc, unsigned int nr) | |||
568 | vc->vc_cols - vc->vc_x); | 568 | vc->vc_cols - vc->vc_x); |
569 | } | 569 | } |
570 | 570 | ||
571 | static int softcursor_original; | 571 | static int softcursor_original = -1; |
572 | 572 | ||
573 | static void add_softcursor(struct vc_data *vc) | 573 | static void add_softcursor(struct vc_data *vc) |
574 | { | 574 | { |
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index 3806e7014199..a66b01bb1fa1 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c | |||
@@ -147,10 +147,7 @@ static int usb_console_setup(struct console *co, char *options) | |||
147 | kref_get(&tty->driver->kref); | 147 | kref_get(&tty->driver->kref); |
148 | __module_get(tty->driver->owner); | 148 | __module_get(tty->driver->owner); |
149 | tty->ops = &usb_console_fake_tty_ops; | 149 | tty->ops = &usb_console_fake_tty_ops; |
150 | if (tty_init_termios(tty)) { | 150 | tty_init_termios(tty); |
151 | retval = -ENOMEM; | ||
152 | goto put_tty; | ||
153 | } | ||
154 | tty_port_tty_set(&port->port, tty); | 151 | tty_port_tty_set(&port->port, tty); |
155 | } | 152 | } |
156 | 153 | ||
@@ -185,7 +182,6 @@ static int usb_console_setup(struct console *co, char *options) | |||
185 | 182 | ||
186 | fail: | 183 | fail: |
187 | tty_port_tty_set(&port->port, NULL); | 184 | tty_port_tty_set(&port->port, NULL); |
188 | put_tty: | ||
189 | tty_kref_put(tty); | 185 | tty_kref_put(tty); |
190 | reset_open_count: | 186 | reset_open_count: |
191 | port->port.count = 0; | 187 | port->port.count = 0; |
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 01bf53392819..b283eb8b86d6 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
@@ -1165,8 +1165,7 @@ static void cypress_read_int_callback(struct urb *urb) | |||
1165 | 1165 | ||
1166 | /* hangup, as defined in acm.c... this might be a bad place for it | 1166 | /* hangup, as defined in acm.c... this might be a bad place for it |
1167 | * though */ | 1167 | * though */ |
1168 | if (tty && !(tty->termios.c_cflag & CLOCAL) && | 1168 | if (tty && !C_CLOCAL(tty) && !(priv->current_status & UART_CD)) { |
1169 | !(priv->current_status & UART_CD)) { | ||
1170 | dev_dbg(dev, "%s - calling hangup\n", __func__); | 1169 | dev_dbg(dev, "%s - calling hangup\n", __func__); |
1171 | tty_hangup(tty); | 1170 | tty_hangup(tty); |
1172 | goto continue_read; | 1171 | goto continue_read; |
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index 12b0e67473ba..010a42a92688 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c | |||
@@ -695,11 +695,11 @@ static void digi_set_termios(struct tty_struct *tty, | |||
695 | arg = -1; | 695 | arg = -1; |
696 | 696 | ||
697 | /* reassert DTR and (maybe) RTS on transition from B0 */ | 697 | /* reassert DTR and (maybe) RTS on transition from B0 */ |
698 | if ((old_cflag&CBAUD) == B0) { | 698 | if ((old_cflag & CBAUD) == B0) { |
699 | /* don't set RTS if using hardware flow control */ | 699 | /* don't set RTS if using hardware flow control */ |
700 | /* and throttling input */ | 700 | /* and throttling input */ |
701 | modem_signals = TIOCM_DTR; | 701 | modem_signals = TIOCM_DTR; |
702 | if (!(tty->termios.c_cflag & CRTSCTS) || | 702 | if (!C_CRTSCTS(tty) || |
703 | !test_bit(TTY_THROTTLED, &tty->flags)) | 703 | !test_bit(TTY_THROTTLED, &tty->flags)) |
704 | modem_signals |= TIOCM_RTS; | 704 | modem_signals |= TIOCM_RTS; |
705 | digi_set_modem_signals(port, modem_signals, 1); | 705 | digi_set_modem_signals(port, modem_signals, 1); |
@@ -1491,8 +1491,8 @@ static int digi_read_oob_callback(struct urb *urb) | |||
1491 | 1491 | ||
1492 | rts = 0; | 1492 | rts = 0; |
1493 | if (tty) | 1493 | if (tty) |
1494 | rts = tty->termios.c_cflag & CRTSCTS; | 1494 | rts = C_CRTSCTS(tty); |
1495 | 1495 | ||
1496 | if (tty && opcode == DIGI_CMD_READ_INPUT_SIGNALS) { | 1496 | if (tty && opcode == DIGI_CMD_READ_INPUT_SIGNALS) { |
1497 | spin_lock(&priv->dp_port_lock); | 1497 | spin_lock(&priv->dp_port_lock); |
1498 | /* convert from digi flags to termiox flags */ | 1498 | /* convert from digi flags to termiox flags */ |
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index f49327d20ee8..f3007ecdd1b4 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c | |||
@@ -1398,7 +1398,7 @@ static void edge_throttle(struct tty_struct *tty) | |||
1398 | } | 1398 | } |
1399 | 1399 | ||
1400 | /* if we are implementing RTS/CTS, toggle that line */ | 1400 | /* if we are implementing RTS/CTS, toggle that line */ |
1401 | if (tty->termios.c_cflag & CRTSCTS) { | 1401 | if (C_CRTSCTS(tty)) { |
1402 | edge_port->shadowMCR &= ~MCR_RTS; | 1402 | edge_port->shadowMCR &= ~MCR_RTS; |
1403 | status = send_cmd_write_uart_register(edge_port, MCR, | 1403 | status = send_cmd_write_uart_register(edge_port, MCR, |
1404 | edge_port->shadowMCR); | 1404 | edge_port->shadowMCR); |
@@ -1435,7 +1435,7 @@ static void edge_unthrottle(struct tty_struct *tty) | |||
1435 | return; | 1435 | return; |
1436 | } | 1436 | } |
1437 | /* if we are implementing RTS/CTS, toggle that line */ | 1437 | /* if we are implementing RTS/CTS, toggle that line */ |
1438 | if (tty->termios.c_cflag & CRTSCTS) { | 1438 | if (C_CRTSCTS(tty)) { |
1439 | edge_port->shadowMCR |= MCR_RTS; | 1439 | edge_port->shadowMCR |= MCR_RTS; |
1440 | send_cmd_write_uart_register(edge_port, MCR, | 1440 | send_cmd_write_uart_register(edge_port, MCR, |
1441 | edge_port->shadowMCR); | 1441 | edge_port->shadowMCR); |
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index fd707d6a10e2..4446b8d70ac2 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c | |||
@@ -428,7 +428,7 @@ static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
428 | * either. | 428 | * either. |
429 | */ | 429 | */ |
430 | spin_lock_irqsave(&priv->lock, flags); | 430 | spin_lock_irqsave(&priv->lock, flags); |
431 | if (tty && (tty->termios.c_cflag & CBAUD)) | 431 | if (tty && C_BAUD(tty)) |
432 | priv->control_state = TIOCM_DTR | TIOCM_RTS; | 432 | priv->control_state = TIOCM_DTR | TIOCM_RTS; |
433 | else | 433 | else |
434 | priv->control_state = 0; | 434 | priv->control_state = 0; |
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 78b4f64c6b00..2eddbe538cda 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c | |||
@@ -1308,7 +1308,7 @@ static void mos7720_throttle(struct tty_struct *tty) | |||
1308 | } | 1308 | } |
1309 | 1309 | ||
1310 | /* if we are implementing RTS/CTS, toggle that line */ | 1310 | /* if we are implementing RTS/CTS, toggle that line */ |
1311 | if (tty->termios.c_cflag & CRTSCTS) { | 1311 | if (C_CRTSCTS(tty)) { |
1312 | mos7720_port->shadowMCR &= ~UART_MCR_RTS; | 1312 | mos7720_port->shadowMCR &= ~UART_MCR_RTS; |
1313 | write_mos_reg(port->serial, port->port_number, MOS7720_MCR, | 1313 | write_mos_reg(port->serial, port->port_number, MOS7720_MCR, |
1314 | mos7720_port->shadowMCR); | 1314 | mos7720_port->shadowMCR); |
@@ -1338,7 +1338,7 @@ static void mos7720_unthrottle(struct tty_struct *tty) | |||
1338 | } | 1338 | } |
1339 | 1339 | ||
1340 | /* if we are implementing RTS/CTS, toggle that line */ | 1340 | /* if we are implementing RTS/CTS, toggle that line */ |
1341 | if (tty->termios.c_cflag & CRTSCTS) { | 1341 | if (C_CRTSCTS(tty)) { |
1342 | mos7720_port->shadowMCR |= UART_MCR_RTS; | 1342 | mos7720_port->shadowMCR |= UART_MCR_RTS; |
1343 | write_mos_reg(port->serial, port->port_number, MOS7720_MCR, | 1343 | write_mos_reg(port->serial, port->port_number, MOS7720_MCR, |
1344 | mos7720_port->shadowMCR); | 1344 | mos7720_port->shadowMCR); |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 2c69bfcdacc6..02ea975754f5 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -1425,7 +1425,7 @@ static void mos7840_throttle(struct tty_struct *tty) | |||
1425 | return; | 1425 | return; |
1426 | } | 1426 | } |
1427 | /* if we are implementing RTS/CTS, toggle that line */ | 1427 | /* if we are implementing RTS/CTS, toggle that line */ |
1428 | if (tty->termios.c_cflag & CRTSCTS) { | 1428 | if (C_CRTSCTS(tty)) { |
1429 | mos7840_port->shadowMCR &= ~MCR_RTS; | 1429 | mos7840_port->shadowMCR &= ~MCR_RTS; |
1430 | status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, | 1430 | status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, |
1431 | mos7840_port->shadowMCR); | 1431 | mos7840_port->shadowMCR); |
@@ -1466,7 +1466,7 @@ static void mos7840_unthrottle(struct tty_struct *tty) | |||
1466 | } | 1466 | } |
1467 | 1467 | ||
1468 | /* if we are implementing RTS/CTS, toggle that line */ | 1468 | /* if we are implementing RTS/CTS, toggle that line */ |
1469 | if (tty->termios.c_cflag & CRTSCTS) { | 1469 | if (C_CRTSCTS(tty)) { |
1470 | mos7840_port->shadowMCR |= MCR_RTS; | 1470 | mos7840_port->shadowMCR |= MCR_RTS; |
1471 | status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, | 1471 | status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, |
1472 | mos7840_port->shadowMCR); | 1472 | mos7840_port->shadowMCR); |
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 772c784ba763..8f5a12ab2f2b 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h | |||
@@ -157,7 +157,7 @@ | |||
157 | #define EARLYCON_TABLE() STRUCT_ALIGN(); \ | 157 | #define EARLYCON_TABLE() STRUCT_ALIGN(); \ |
158 | VMLINUX_SYMBOL(__earlycon_table) = .; \ | 158 | VMLINUX_SYMBOL(__earlycon_table) = .; \ |
159 | *(__earlycon_table) \ | 159 | *(__earlycon_table) \ |
160 | *(__earlycon_table_end) | 160 | VMLINUX_SYMBOL(__earlycon_table_end) = .; |
161 | #else | 161 | #else |
162 | #define EARLYCON_TABLE() | 162 | #define EARLYCON_TABLE() |
163 | #endif | 163 | #endif |
@@ -179,7 +179,6 @@ | |||
179 | #define RESERVEDMEM_OF_TABLES() OF_TABLE(CONFIG_OF_RESERVED_MEM, reservedmem) | 179 | #define RESERVEDMEM_OF_TABLES() OF_TABLE(CONFIG_OF_RESERVED_MEM, reservedmem) |
180 | #define CPU_METHOD_OF_TABLES() OF_TABLE(CONFIG_SMP, cpu_method) | 180 | #define CPU_METHOD_OF_TABLES() OF_TABLE(CONFIG_SMP, cpu_method) |
181 | #define CPUIDLE_METHOD_OF_TABLES() OF_TABLE(CONFIG_CPU_IDLE, cpuidle_method) | 181 | #define CPUIDLE_METHOD_OF_TABLES() OF_TABLE(CONFIG_CPU_IDLE, cpuidle_method) |
182 | #define EARLYCON_OF_TABLES() OF_TABLE(CONFIG_SERIAL_EARLYCON, earlycon) | ||
183 | 182 | ||
184 | #ifdef CONFIG_ACPI | 183 | #ifdef CONFIG_ACPI |
185 | #define ACPI_PROBE_TABLE(name) \ | 184 | #define ACPI_PROBE_TABLE(name) \ |
@@ -527,8 +526,7 @@ | |||
527 | IRQCHIP_OF_MATCH_TABLE() \ | 526 | IRQCHIP_OF_MATCH_TABLE() \ |
528 | ACPI_PROBE_TABLE(irqchip) \ | 527 | ACPI_PROBE_TABLE(irqchip) \ |
529 | ACPI_PROBE_TABLE(clksrc) \ | 528 | ACPI_PROBE_TABLE(clksrc) \ |
530 | EARLYCON_TABLE() \ | 529 | EARLYCON_TABLE() |
531 | EARLYCON_OF_TABLES() | ||
532 | 530 | ||
533 | #define INIT_TEXT \ | 531 | #define INIT_TEXT \ |
534 | *(.init.text) \ | 532 | *(.init.text) \ |
diff --git a/include/linux/atmel_serial.h b/include/linux/atmel_serial.h index ee696d7e8a43..5a4d664af87a 100644 --- a/include/linux/atmel_serial.h +++ b/include/linux/atmel_serial.h | |||
@@ -119,7 +119,8 @@ | |||
119 | #define ATMEL_US_BRGR 0x20 /* Baud Rate Generator Register */ | 119 | #define ATMEL_US_BRGR 0x20 /* Baud Rate Generator Register */ |
120 | #define ATMEL_US_CD GENMASK(15, 0) /* Clock Divider */ | 120 | #define ATMEL_US_CD GENMASK(15, 0) /* Clock Divider */ |
121 | 121 | ||
122 | #define ATMEL_US_RTOR 0x24 /* Receiver Time-out Register */ | 122 | #define ATMEL_US_RTOR 0x24 /* Receiver Time-out Register for USART */ |
123 | #define ATMEL_UA_RTOR 0x28 /* Receiver Time-out Register for UART */ | ||
123 | #define ATMEL_US_TO GENMASK(15, 0) /* Time-out Value */ | 124 | #define ATMEL_US_TO GENMASK(15, 0) /* Time-out Value */ |
124 | 125 | ||
125 | #define ATMEL_US_TTGR 0x28 /* Transmitter Timeguard Register */ | 126 | #define ATMEL_US_TTGR 0x28 /* Transmitter Timeguard Register */ |
diff --git a/include/linux/audit.h b/include/linux/audit.h index b40ed5df5542..e38e3fc13ea8 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
@@ -109,6 +109,10 @@ extern int audit_classify_compat_syscall(int abi, unsigned syscall); | |||
109 | /* maximized args number that audit_socketcall can process */ | 109 | /* maximized args number that audit_socketcall can process */ |
110 | #define AUDITSC_ARGS 6 | 110 | #define AUDITSC_ARGS 6 |
111 | 111 | ||
112 | /* bit values for ->signal->audit_tty */ | ||
113 | #define AUDIT_TTY_ENABLE BIT(0) | ||
114 | #define AUDIT_TTY_LOG_PASSWD BIT(1) | ||
115 | |||
112 | struct filename; | 116 | struct filename; |
113 | 117 | ||
114 | extern void audit_log_session_info(struct audit_buffer *ab); | 118 | extern void audit_log_session_info(struct audit_buffer *ab); |
diff --git a/include/linux/isdn.h b/include/linux/isdn.h index 1e9a0f2a8626..df97c8444f5d 100644 --- a/include/linux/isdn.h +++ b/include/linux/isdn.h | |||
@@ -319,6 +319,7 @@ typedef struct modem_info { | |||
319 | int online; /* 1 = B-Channel is up, drop data */ | 319 | int online; /* 1 = B-Channel is up, drop data */ |
320 | /* 2 = B-Channel is up, deliver d.*/ | 320 | /* 2 = B-Channel is up, deliver d.*/ |
321 | int dialing; /* Dial in progress or ATA */ | 321 | int dialing; /* Dial in progress or ATA */ |
322 | int closing; | ||
322 | int rcvsched; /* Receive needs schedule */ | 323 | int rcvsched; /* Receive needs schedule */ |
323 | int isdn_driver; /* Index to isdn-driver */ | 324 | int isdn_driver; /* Index to isdn-driver */ |
324 | int isdn_channel; /* Index to isdn-channel */ | 325 | int isdn_channel; /* Index to isdn-channel */ |
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h index df9ef3801812..2fbe8682a66f 100644 --- a/include/linux/of_fdt.h +++ b/include/linux/of_fdt.h | |||
@@ -88,7 +88,7 @@ extern void unflatten_device_tree(void); | |||
88 | extern void unflatten_and_copy_device_tree(void); | 88 | extern void unflatten_and_copy_device_tree(void); |
89 | extern void early_init_devtree(void *); | 89 | extern void early_init_devtree(void *); |
90 | extern void early_get_first_memblock_info(void *, phys_addr_t *); | 90 | extern void early_get_first_memblock_info(void *, phys_addr_t *); |
91 | extern u64 fdt_translate_address(const void *blob, int node_offset); | 91 | extern u64 of_flat_dt_translate_address(unsigned long node); |
92 | extern void of_fdt_limit_memory(int limit); | 92 | extern void of_fdt_limit_memory(int limit); |
93 | #else /* CONFIG_OF_FLATTREE */ | 93 | #else /* CONFIG_OF_FLATTREE */ |
94 | static inline void early_init_fdt_scan_reserved_mem(void) {} | 94 | static inline void early_init_fdt_scan_reserved_mem(void) {} |
diff --git a/include/linux/platform_data/sa11x0-serial.h b/include/linux/platform_data/sa11x0-serial.h index 4504d5d592f0..009e1d83fe39 100644 --- a/include/linux/platform_data/sa11x0-serial.h +++ b/include/linux/platform_data/sa11x0-serial.h | |||
@@ -26,8 +26,12 @@ struct sa1100_port_fns { | |||
26 | void sa1100_register_uart_fns(struct sa1100_port_fns *fns); | 26 | void sa1100_register_uart_fns(struct sa1100_port_fns *fns); |
27 | void sa1100_register_uart(int idx, int port); | 27 | void sa1100_register_uart(int idx, int port); |
28 | #else | 28 | #else |
29 | #define sa1100_register_uart_fns(fns) do { } while (0) | 29 | static inline void sa1100_register_uart_fns(struct sa1100_port_fns *fns) |
30 | #define sa1100_register_uart(idx,port) do { } while (0) | 30 | { |
31 | } | ||
32 | static inline void sa1100_register_uart(int idx, int port) | ||
33 | { | ||
34 | } | ||
31 | #endif | 35 | #endif |
32 | 36 | ||
33 | #endif | 37 | #endif |
diff --git a/include/linux/platform_data/serial-omap.h b/include/linux/platform_data/serial-omap.h index d09275f3cde3..2ba2c34ca3d3 100644 --- a/include/linux/platform_data/serial-omap.h +++ b/include/linux/platform_data/serial-omap.h | |||
@@ -21,7 +21,7 @@ | |||
21 | #include <linux/device.h> | 21 | #include <linux/device.h> |
22 | #include <linux/pm_qos.h> | 22 | #include <linux/pm_qos.h> |
23 | 23 | ||
24 | #define DRIVER_NAME "omap_uart" | 24 | #define OMAP_SERIAL_DRIVER_NAME "omap_uart" |
25 | 25 | ||
26 | /* | 26 | /* |
27 | * Use tty device name as ttyO, [O -> OMAP] | 27 | * Use tty device name as ttyO, [O -> OMAP] |
diff --git a/include/linux/sched.h b/include/linux/sched.h index eb7f2f84009b..bd242bed4abb 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -777,7 +777,6 @@ struct signal_struct { | |||
777 | #endif | 777 | #endif |
778 | #ifdef CONFIG_AUDIT | 778 | #ifdef CONFIG_AUDIT |
779 | unsigned audit_tty; | 779 | unsigned audit_tty; |
780 | unsigned audit_tty_log_passwd; | ||
781 | struct tty_audit_buf *tty_audit_buf; | 780 | struct tty_audit_buf *tty_audit_buf; |
782 | #endif | 781 | #endif |
783 | 782 | ||
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h index faa0e0370ce7..434879759725 100644 --- a/include/linux/serial_8250.h +++ b/include/linux/serial_8250.h | |||
@@ -76,6 +76,12 @@ struct uart_8250_ops { | |||
76 | void (*release_irq)(struct uart_8250_port *); | 76 | void (*release_irq)(struct uart_8250_port *); |
77 | }; | 77 | }; |
78 | 78 | ||
79 | struct uart_8250_em485 { | ||
80 | struct timer_list start_tx_timer; /* "rs485 start tx" timer */ | ||
81 | struct timer_list stop_tx_timer; /* "rs485 stop tx" timer */ | ||
82 | struct timer_list *active_timer; /* pointer to active timer */ | ||
83 | }; | ||
84 | |||
79 | /* | 85 | /* |
80 | * This should be used by drivers which want to register | 86 | * This should be used by drivers which want to register |
81 | * their own 8250 ports without registering their own | 87 | * their own 8250 ports without registering their own |
@@ -122,6 +128,8 @@ struct uart_8250_port { | |||
122 | /* 8250 specific callbacks */ | 128 | /* 8250 specific callbacks */ |
123 | int (*dl_read)(struct uart_8250_port *); | 129 | int (*dl_read)(struct uart_8250_port *); |
124 | void (*dl_write)(struct uart_8250_port *, int); | 130 | void (*dl_write)(struct uart_8250_port *, int); |
131 | |||
132 | struct uart_8250_em485 *em485; | ||
125 | }; | 133 | }; |
126 | 134 | ||
127 | static inline struct uart_8250_port *up_to_u8250p(struct uart_port *up) | 135 | static inline struct uart_8250_port *up_to_u8250p(struct uart_port *up) |
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index e03d6ba5e5b4..cbfcf38e220d 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h | |||
@@ -342,21 +342,26 @@ struct earlycon_device { | |||
342 | 342 | ||
343 | struct earlycon_id { | 343 | struct earlycon_id { |
344 | char name[16]; | 344 | char name[16]; |
345 | char compatible[128]; | ||
345 | int (*setup)(struct earlycon_device *, const char *options); | 346 | int (*setup)(struct earlycon_device *, const char *options); |
346 | } __aligned(32); | 347 | } __aligned(32); |
347 | 348 | ||
348 | extern int setup_earlycon(char *buf); | 349 | extern const struct earlycon_id __earlycon_table[]; |
349 | extern int of_setup_earlycon(unsigned long addr, | 350 | extern const struct earlycon_id __earlycon_table_end[]; |
350 | int (*setup)(struct earlycon_device *, const char *)); | 351 | |
352 | #define OF_EARLYCON_DECLARE(_name, compat, fn) \ | ||
353 | static const struct earlycon_id __UNIQUE_ID(__earlycon_##_name) \ | ||
354 | __used __section(__earlycon_table) \ | ||
355 | = { .name = __stringify(_name), \ | ||
356 | .compatible = compat, \ | ||
357 | .setup = fn } | ||
351 | 358 | ||
352 | #define EARLYCON_DECLARE(_name, func) \ | 359 | #define EARLYCON_DECLARE(_name, fn) OF_EARLYCON_DECLARE(_name, "", fn) |
353 | static const struct earlycon_id __earlycon_##_name \ | ||
354 | __used __section(__earlycon_table) \ | ||
355 | = { .name = __stringify(_name), \ | ||
356 | .setup = func } | ||
357 | 360 | ||
358 | #define OF_EARLYCON_DECLARE(name, compat, fn) \ | 361 | extern int setup_earlycon(char *buf); |
359 | _OF_DECLARE(earlycon, name, compat, fn, void *) | 362 | extern int of_setup_earlycon(const struct earlycon_id *match, |
363 | unsigned long node, | ||
364 | const char *options); | ||
360 | 365 | ||
361 | struct uart_port *uart_get_console(struct uart_port *ports, int nr, | 366 | struct uart_port *uart_get_console(struct uart_port *ports, int nr, |
362 | struct console *c); | 367 | struct console *c); |
diff --git a/include/linux/tty.h b/include/linux/tty.h index d9fb4b043f56..3b09f235db66 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
@@ -302,6 +302,7 @@ struct tty_struct { | |||
302 | struct work_struct hangup_work; | 302 | struct work_struct hangup_work; |
303 | void *disc_data; | 303 | void *disc_data; |
304 | void *driver_data; | 304 | void *driver_data; |
305 | spinlock_t files_lock; /* protects tty_files list */ | ||
305 | struct list_head tty_files; | 306 | struct list_head tty_files; |
306 | 307 | ||
307 | #define N_TTY_BUF_SIZE 4096 | 308 | #define N_TTY_BUF_SIZE 4096 |
@@ -336,7 +337,6 @@ struct tty_file_private { | |||
336 | #define TTY_IO_ERROR 1 /* Cause an I/O error (may be no ldisc too) */ | 337 | #define TTY_IO_ERROR 1 /* Cause an I/O error (may be no ldisc too) */ |
337 | #define TTY_OTHER_CLOSED 2 /* Other side (if any) has closed */ | 338 | #define TTY_OTHER_CLOSED 2 /* Other side (if any) has closed */ |
338 | #define TTY_EXCLUSIVE 3 /* Exclusive open mode */ | 339 | #define TTY_EXCLUSIVE 3 /* Exclusive open mode */ |
339 | #define TTY_DEBUG 4 /* Debugging */ | ||
340 | #define TTY_DO_WRITE_WAKEUP 5 /* Call write_wakeup after queuing new */ | 340 | #define TTY_DO_WRITE_WAKEUP 5 /* Call write_wakeup after queuing new */ |
341 | #define TTY_OTHER_DONE 6 /* Closed pty has completed input processing */ | 341 | #define TTY_OTHER_DONE 6 /* Closed pty has completed input processing */ |
342 | #define TTY_LDISC_OPEN 11 /* Line discipline is open */ | 342 | #define TTY_LDISC_OPEN 11 /* Line discipline is open */ |
@@ -433,8 +433,6 @@ extern struct device *tty_register_device_attr(struct tty_driver *driver, | |||
433 | void *drvdata, | 433 | void *drvdata, |
434 | const struct attribute_group **attr_grp); | 434 | const struct attribute_group **attr_grp); |
435 | extern void tty_unregister_device(struct tty_driver *driver, unsigned index); | 435 | extern void tty_unregister_device(struct tty_driver *driver, unsigned index); |
436 | extern int tty_read_raw_data(struct tty_struct *tty, unsigned char *bufp, | ||
437 | int buflen); | ||
438 | extern void tty_write_message(struct tty_struct *tty, char *msg); | 436 | extern void tty_write_message(struct tty_struct *tty, char *msg); |
439 | extern int tty_send_xchar(struct tty_struct *tty, char ch); | 437 | extern int tty_send_xchar(struct tty_struct *tty, char ch); |
440 | extern int tty_put_char(struct tty_struct *tty, unsigned char c); | 438 | extern int tty_put_char(struct tty_struct *tty, unsigned char c); |
@@ -446,12 +444,7 @@ extern void tty_unthrottle(struct tty_struct *tty); | |||
446 | extern int tty_throttle_safe(struct tty_struct *tty); | 444 | extern int tty_throttle_safe(struct tty_struct *tty); |
447 | extern int tty_unthrottle_safe(struct tty_struct *tty); | 445 | extern int tty_unthrottle_safe(struct tty_struct *tty); |
448 | extern int tty_do_resize(struct tty_struct *tty, struct winsize *ws); | 446 | extern int tty_do_resize(struct tty_struct *tty, struct winsize *ws); |
449 | extern void tty_driver_remove_tty(struct tty_driver *driver, | ||
450 | struct tty_struct *tty); | ||
451 | extern void tty_free_termios(struct tty_struct *tty); | ||
452 | extern int is_current_pgrp_orphaned(void); | 447 | extern int is_current_pgrp_orphaned(void); |
453 | extern int is_ignored(int sig); | ||
454 | extern int tty_signal(int sig, struct tty_struct *tty); | ||
455 | extern void tty_hangup(struct tty_struct *tty); | 448 | extern void tty_hangup(struct tty_struct *tty); |
456 | extern void tty_vhangup(struct tty_struct *tty); | 449 | extern void tty_vhangup(struct tty_struct *tty); |
457 | extern int tty_hung_up_p(struct file *filp); | 450 | extern int tty_hung_up_p(struct file *filp); |
@@ -493,7 +486,8 @@ extern int tty_set_termios(struct tty_struct *tty, struct ktermios *kt); | |||
493 | extern struct tty_ldisc *tty_ldisc_ref(struct tty_struct *); | 486 | extern struct tty_ldisc *tty_ldisc_ref(struct tty_struct *); |
494 | extern void tty_ldisc_deref(struct tty_ldisc *); | 487 | extern void tty_ldisc_deref(struct tty_ldisc *); |
495 | extern struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *); | 488 | extern struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *); |
496 | extern void tty_ldisc_hangup(struct tty_struct *tty); | 489 | extern void tty_ldisc_hangup(struct tty_struct *tty, bool reset); |
490 | extern int tty_ldisc_reinit(struct tty_struct *tty, int disc); | ||
497 | extern const struct file_operations tty_ldiscs_proc_fops; | 491 | extern const struct file_operations tty_ldiscs_proc_fops; |
498 | 492 | ||
499 | extern void tty_wakeup(struct tty_struct *tty); | 493 | extern void tty_wakeup(struct tty_struct *tty); |
@@ -508,16 +502,13 @@ extern struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx); | |||
508 | extern int tty_alloc_file(struct file *file); | 502 | extern int tty_alloc_file(struct file *file); |
509 | extern void tty_add_file(struct tty_struct *tty, struct file *file); | 503 | extern void tty_add_file(struct tty_struct *tty, struct file *file); |
510 | extern void tty_free_file(struct file *file); | 504 | extern void tty_free_file(struct file *file); |
511 | extern void free_tty_struct(struct tty_struct *tty); | ||
512 | extern void deinitialize_tty_struct(struct tty_struct *tty); | ||
513 | extern struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx); | 505 | extern struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx); |
514 | extern int tty_release(struct inode *inode, struct file *filp); | 506 | extern int tty_release(struct inode *inode, struct file *filp); |
515 | extern int tty_init_termios(struct tty_struct *tty); | 507 | extern void tty_init_termios(struct tty_struct *tty); |
516 | extern int tty_standard_install(struct tty_driver *driver, | 508 | extern int tty_standard_install(struct tty_driver *driver, |
517 | struct tty_struct *tty); | 509 | struct tty_struct *tty); |
518 | 510 | ||
519 | extern struct mutex tty_mutex; | 511 | extern struct mutex tty_mutex; |
520 | extern spinlock_t tty_files_lock; | ||
521 | 512 | ||
522 | #define tty_is_writelocked(tty) (mutex_is_locked(&tty->atomic_write_lock)) | 513 | #define tty_is_writelocked(tty) (mutex_is_locked(&tty->atomic_write_lock)) |
523 | 514 | ||
@@ -575,43 +566,29 @@ static inline int tty_port_users(struct tty_port *port) | |||
575 | 566 | ||
576 | extern int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc); | 567 | extern int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc); |
577 | extern int tty_unregister_ldisc(int disc); | 568 | extern int tty_unregister_ldisc(int disc); |
578 | extern int tty_set_ldisc(struct tty_struct *tty, int ldisc); | 569 | extern int tty_set_ldisc(struct tty_struct *tty, int disc); |
579 | extern int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty); | 570 | extern int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty); |
580 | extern void tty_ldisc_release(struct tty_struct *tty); | 571 | extern void tty_ldisc_release(struct tty_struct *tty); |
581 | extern void tty_ldisc_init(struct tty_struct *tty); | 572 | extern void tty_ldisc_init(struct tty_struct *tty); |
582 | extern void tty_ldisc_deinit(struct tty_struct *tty); | 573 | extern void tty_ldisc_deinit(struct tty_struct *tty); |
583 | extern void tty_ldisc_begin(void); | 574 | extern int tty_ldisc_receive_buf(struct tty_ldisc *ld, unsigned char *p, |
584 | 575 | char *f, int count); | |
585 | static inline int tty_ldisc_receive_buf(struct tty_ldisc *ld, unsigned char *p, | ||
586 | char *f, int count) | ||
587 | { | ||
588 | if (ld->ops->receive_buf2) | ||
589 | count = ld->ops->receive_buf2(ld->tty, p, f, count); | ||
590 | else { | ||
591 | count = min_t(int, count, ld->tty->receive_room); | ||
592 | if (count) | ||
593 | ld->ops->receive_buf(ld->tty, p, f, count); | ||
594 | } | ||
595 | return count; | ||
596 | } | ||
597 | |||
598 | 576 | ||
599 | /* n_tty.c */ | 577 | /* n_tty.c */ |
600 | extern struct tty_ldisc_ops tty_ldisc_N_TTY; | ||
601 | extern void n_tty_inherit_ops(struct tty_ldisc_ops *ops); | 578 | extern void n_tty_inherit_ops(struct tty_ldisc_ops *ops); |
579 | extern void __init n_tty_init(void); | ||
602 | 580 | ||
603 | /* tty_audit.c */ | 581 | /* tty_audit.c */ |
604 | #ifdef CONFIG_AUDIT | 582 | #ifdef CONFIG_AUDIT |
605 | extern void tty_audit_add_data(struct tty_struct *tty, const void *data, | 583 | extern void tty_audit_add_data(struct tty_struct *tty, const void *data, |
606 | size_t size, unsigned icanon); | 584 | size_t size); |
607 | extern void tty_audit_exit(void); | 585 | extern void tty_audit_exit(void); |
608 | extern void tty_audit_fork(struct signal_struct *sig); | 586 | extern void tty_audit_fork(struct signal_struct *sig); |
609 | extern void tty_audit_tiocsti(struct tty_struct *tty, char ch); | 587 | extern void tty_audit_tiocsti(struct tty_struct *tty, char ch); |
610 | extern void tty_audit_push(struct tty_struct *tty); | 588 | extern int tty_audit_push(void); |
611 | extern int tty_audit_push_current(void); | ||
612 | #else | 589 | #else |
613 | static inline void tty_audit_add_data(struct tty_struct *tty, const void *data, | 590 | static inline void tty_audit_add_data(struct tty_struct *tty, const void *data, |
614 | size_t size, unsigned icanon) | 591 | size_t size) |
615 | { | 592 | { |
616 | } | 593 | } |
617 | static inline void tty_audit_tiocsti(struct tty_struct *tty, char ch) | 594 | static inline void tty_audit_tiocsti(struct tty_struct *tty, char ch) |
@@ -623,10 +600,7 @@ static inline void tty_audit_exit(void) | |||
623 | static inline void tty_audit_fork(struct signal_struct *sig) | 600 | static inline void tty_audit_fork(struct signal_struct *sig) |
624 | { | 601 | { |
625 | } | 602 | } |
626 | static inline void tty_audit_push(struct tty_struct *tty) | 603 | static inline int tty_audit_push(void) |
627 | { | ||
628 | } | ||
629 | static inline int tty_audit_push_current(void) | ||
630 | { | 604 | { |
631 | return 0; | 605 | return 0; |
632 | } | 606 | } |
@@ -648,11 +622,11 @@ extern long vt_compat_ioctl(struct tty_struct *tty, | |||
648 | 622 | ||
649 | /* tty_mutex.c */ | 623 | /* tty_mutex.c */ |
650 | /* functions for preparation of BKL removal */ | 624 | /* functions for preparation of BKL removal */ |
651 | extern void __lockfunc tty_lock(struct tty_struct *tty); | 625 | extern void tty_lock(struct tty_struct *tty); |
652 | extern int tty_lock_interruptible(struct tty_struct *tty); | 626 | extern int tty_lock_interruptible(struct tty_struct *tty); |
653 | extern void __lockfunc tty_unlock(struct tty_struct *tty); | 627 | extern void tty_unlock(struct tty_struct *tty); |
654 | extern void __lockfunc tty_lock_slave(struct tty_struct *tty); | 628 | extern void tty_lock_slave(struct tty_struct *tty); |
655 | extern void __lockfunc tty_unlock_slave(struct tty_struct *tty); | 629 | extern void tty_unlock_slave(struct tty_struct *tty); |
656 | extern void tty_set_lock_subclass(struct tty_struct *tty); | 630 | extern void tty_set_lock_subclass(struct tty_struct *tty); |
657 | 631 | ||
658 | #ifdef CONFIG_PROC_FS | 632 | #ifdef CONFIG_PROC_FS |
diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h index 00c9d688d7b7..3971cf0eb467 100644 --- a/include/linux/tty_ldisc.h +++ b/include/linux/tty_ldisc.h | |||
@@ -25,12 +25,6 @@ | |||
25 | * buffers of any input characters it may have queued to be | 25 | * buffers of any input characters it may have queued to be |
26 | * delivered to the user mode process. | 26 | * delivered to the user mode process. |
27 | * | 27 | * |
28 | * ssize_t (*chars_in_buffer)(struct tty_struct *tty); | ||
29 | * | ||
30 | * This function returns the number of input characters the line | ||
31 | * discipline may have queued up to be delivered to the user mode | ||
32 | * process. | ||
33 | * | ||
34 | * ssize_t (*read)(struct tty_struct * tty, struct file * file, | 28 | * ssize_t (*read)(struct tty_struct * tty, struct file * file, |
35 | * unsigned char * buf, size_t nr); | 29 | * unsigned char * buf, size_t nr); |
36 | * | 30 | * |
@@ -104,11 +98,6 @@ | |||
104 | * seek to perform this action quickly but should wait until | 98 | * seek to perform this action quickly but should wait until |
105 | * any pending driver I/O is completed. | 99 | * any pending driver I/O is completed. |
106 | * | 100 | * |
107 | * void (*fasync)(struct tty_struct *, int on) | ||
108 | * | ||
109 | * Notify line discipline when signal-driven I/O is enabled or | ||
110 | * disabled. | ||
111 | * | ||
112 | * void (*dcd_change)(struct tty_struct *tty, unsigned int status) | 101 | * void (*dcd_change)(struct tty_struct *tty, unsigned int status) |
113 | * | 102 | * |
114 | * Tells the discipline that the DCD pin has changed its status. | 103 | * Tells the discipline that the DCD pin has changed its status. |
@@ -188,7 +177,6 @@ struct tty_ldisc_ops { | |||
188 | int (*open)(struct tty_struct *); | 177 | int (*open)(struct tty_struct *); |
189 | void (*close)(struct tty_struct *); | 178 | void (*close)(struct tty_struct *); |
190 | void (*flush_buffer)(struct tty_struct *tty); | 179 | void (*flush_buffer)(struct tty_struct *tty); |
191 | ssize_t (*chars_in_buffer)(struct tty_struct *tty); | ||
192 | ssize_t (*read)(struct tty_struct *tty, struct file *file, | 180 | ssize_t (*read)(struct tty_struct *tty, struct file *file, |
193 | unsigned char __user *buf, size_t nr); | 181 | unsigned char __user *buf, size_t nr); |
194 | ssize_t (*write)(struct tty_struct *tty, struct file *file, | 182 | ssize_t (*write)(struct tty_struct *tty, struct file *file, |
@@ -209,7 +197,6 @@ struct tty_ldisc_ops { | |||
209 | char *fp, int count); | 197 | char *fp, int count); |
210 | void (*write_wakeup)(struct tty_struct *); | 198 | void (*write_wakeup)(struct tty_struct *); |
211 | void (*dcd_change)(struct tty_struct *, unsigned int); | 199 | void (*dcd_change)(struct tty_struct *, unsigned int); |
212 | void (*fasync)(struct tty_struct *tty, int on); | ||
213 | int (*receive_buf2)(struct tty_struct *, const unsigned char *cp, | 200 | int (*receive_buf2)(struct tty_struct *, const unsigned char *cp, |
214 | char *fp, int count); | 201 | char *fp, int count); |
215 | 202 | ||
diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h index 3e5d757407fb..e513a4ee369b 100644 --- a/include/uapi/linux/serial_core.h +++ b/include/uapi/linux/serial_core.h | |||
@@ -261,4 +261,7 @@ | |||
261 | /* STM32 USART */ | 261 | /* STM32 USART */ |
262 | #define PORT_STM32 113 | 262 | #define PORT_STM32 113 |
263 | 263 | ||
264 | /* MVEBU UART */ | ||
265 | #define PORT_MVEBU 114 | ||
266 | |||
264 | #endif /* _UAPILINUX_SERIAL_CORE_H */ | 267 | #endif /* _UAPILINUX_SERIAL_CORE_H */ |
diff --git a/kernel/audit.c b/kernel/audit.c index 3a3e5deeda8d..2651e423b2dc 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
@@ -920,7 +920,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
920 | if (err == 1) { /* match or error */ | 920 | if (err == 1) { /* match or error */ |
921 | err = 0; | 921 | err = 0; |
922 | if (msg_type == AUDIT_USER_TTY) { | 922 | if (msg_type == AUDIT_USER_TTY) { |
923 | err = tty_audit_push_current(); | 923 | err = tty_audit_push(); |
924 | if (err) | 924 | if (err) |
925 | break; | 925 | break; |
926 | } | 926 | } |
@@ -1030,20 +1030,19 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
1030 | break; | 1030 | break; |
1031 | case AUDIT_TTY_GET: { | 1031 | case AUDIT_TTY_GET: { |
1032 | struct audit_tty_status s; | 1032 | struct audit_tty_status s; |
1033 | struct task_struct *tsk = current; | 1033 | unsigned int t; |
1034 | 1034 | ||
1035 | spin_lock(&tsk->sighand->siglock); | 1035 | t = READ_ONCE(current->signal->audit_tty); |
1036 | s.enabled = tsk->signal->audit_tty; | 1036 | s.enabled = t & AUDIT_TTY_ENABLE; |
1037 | s.log_passwd = tsk->signal->audit_tty_log_passwd; | 1037 | s.log_passwd = !!(t & AUDIT_TTY_LOG_PASSWD); |
1038 | spin_unlock(&tsk->sighand->siglock); | ||
1039 | 1038 | ||
1040 | audit_send_reply(skb, seq, AUDIT_TTY_GET, 0, 0, &s, sizeof(s)); | 1039 | audit_send_reply(skb, seq, AUDIT_TTY_GET, 0, 0, &s, sizeof(s)); |
1041 | break; | 1040 | break; |
1042 | } | 1041 | } |
1043 | case AUDIT_TTY_SET: { | 1042 | case AUDIT_TTY_SET: { |
1044 | struct audit_tty_status s, old; | 1043 | struct audit_tty_status s, old; |
1045 | struct task_struct *tsk = current; | ||
1046 | struct audit_buffer *ab; | 1044 | struct audit_buffer *ab; |
1045 | unsigned int t; | ||
1047 | 1046 | ||
1048 | memset(&s, 0, sizeof(s)); | 1047 | memset(&s, 0, sizeof(s)); |
1049 | /* guard against past and future API changes */ | 1048 | /* guard against past and future API changes */ |
@@ -1053,14 +1052,14 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
1053 | (s.log_passwd != 0 && s.log_passwd != 1)) | 1052 | (s.log_passwd != 0 && s.log_passwd != 1)) |
1054 | err = -EINVAL; | 1053 | err = -EINVAL; |
1055 | 1054 | ||
1056 | spin_lock(&tsk->sighand->siglock); | 1055 | if (err) |
1057 | old.enabled = tsk->signal->audit_tty; | 1056 | t = READ_ONCE(current->signal->audit_tty); |
1058 | old.log_passwd = tsk->signal->audit_tty_log_passwd; | 1057 | else { |
1059 | if (!err) { | 1058 | t = s.enabled | (-s.log_passwd & AUDIT_TTY_LOG_PASSWD); |
1060 | tsk->signal->audit_tty = s.enabled; | 1059 | t = xchg(¤t->signal->audit_tty, t); |
1061 | tsk->signal->audit_tty_log_passwd = s.log_passwd; | ||
1062 | } | 1060 | } |
1063 | spin_unlock(&tsk->sighand->siglock); | 1061 | old.enabled = t & AUDIT_TTY_ENABLE; |
1062 | old.log_passwd = !!(t & AUDIT_TTY_LOG_PASSWD); | ||
1064 | 1063 | ||
1065 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE); | 1064 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE); |
1066 | audit_log_format(ab, " op=tty_set old-enabled=%d new-enabled=%d" | 1065 | audit_log_format(ab, " op=tty_set old-enabled=%d new-enabled=%d" |
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c index a4237707f79d..da126ee6d218 100644 --- a/net/irda/ircomm/ircomm_tty.c +++ b/net/irda/ircomm/ircomm_tty.c | |||
@@ -287,14 +287,14 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self, | |||
287 | 287 | ||
288 | if (filp->f_flags & O_NONBLOCK) { | 288 | if (filp->f_flags & O_NONBLOCK) { |
289 | /* nonblock mode is set */ | 289 | /* nonblock mode is set */ |
290 | if (tty->termios.c_cflag & CBAUD) | 290 | if (C_BAUD(tty)) |
291 | tty_port_raise_dtr_rts(port); | 291 | tty_port_raise_dtr_rts(port); |
292 | port->flags |= ASYNC_NORMAL_ACTIVE; | 292 | port->flags |= ASYNC_NORMAL_ACTIVE; |
293 | pr_debug("%s(), O_NONBLOCK requested!\n", __func__); | 293 | pr_debug("%s(), O_NONBLOCK requested!\n", __func__); |
294 | return 0; | 294 | return 0; |
295 | } | 295 | } |
296 | 296 | ||
297 | if (tty->termios.c_cflag & CLOCAL) { | 297 | if (C_CLOCAL(tty)) { |
298 | pr_debug("%s(), doing CLOCAL!\n", __func__); | 298 | pr_debug("%s(), doing CLOCAL!\n", __func__); |
299 | do_clocal = 1; | 299 | do_clocal = 1; |
300 | } | 300 | } |
@@ -806,7 +806,7 @@ static void ircomm_tty_throttle(struct tty_struct *tty) | |||
806 | ircomm_tty_send_xchar(tty, STOP_CHAR(tty)); | 806 | ircomm_tty_send_xchar(tty, STOP_CHAR(tty)); |
807 | 807 | ||
808 | /* Hardware flow control? */ | 808 | /* Hardware flow control? */ |
809 | if (tty->termios.c_cflag & CRTSCTS) { | 809 | if (C_CRTSCTS(tty)) { |
810 | self->settings.dte &= ~IRCOMM_RTS; | 810 | self->settings.dte &= ~IRCOMM_RTS; |
811 | self->settings.dte |= IRCOMM_DELTA_RTS; | 811 | self->settings.dte |= IRCOMM_DELTA_RTS; |
812 | 812 | ||
@@ -831,12 +831,11 @@ static void ircomm_tty_unthrottle(struct tty_struct *tty) | |||
831 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); | 831 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); |
832 | 832 | ||
833 | /* Using software flow control? */ | 833 | /* Using software flow control? */ |
834 | if (I_IXOFF(tty)) { | 834 | if (I_IXOFF(tty)) |
835 | ircomm_tty_send_xchar(tty, START_CHAR(tty)); | 835 | ircomm_tty_send_xchar(tty, START_CHAR(tty)); |
836 | } | ||
837 | 836 | ||
838 | /* Using hardware flow control? */ | 837 | /* Using hardware flow control? */ |
839 | if (tty->termios.c_cflag & CRTSCTS) { | 838 | if (C_CRTSCTS(tty)) { |
840 | self->settings.dte |= (IRCOMM_RTS|IRCOMM_DELTA_RTS); | 839 | self->settings.dte |= (IRCOMM_RTS|IRCOMM_DELTA_RTS); |
841 | 840 | ||
842 | ircomm_param_request(self, IRCOMM_DTE, TRUE); | 841 | ircomm_param_request(self, IRCOMM_DTE, TRUE); |
@@ -1268,10 +1267,6 @@ static void ircomm_tty_line_info(struct ircomm_tty_cb *self, struct seq_file *m) | |||
1268 | seq_printf(m, "%cASYNC_LOW_LATENCY", sep); | 1267 | seq_printf(m, "%cASYNC_LOW_LATENCY", sep); |
1269 | sep = '|'; | 1268 | sep = '|'; |
1270 | } | 1269 | } |
1271 | if (self->port.flags & ASYNC_CLOSING) { | ||
1272 | seq_printf(m, "%cASYNC_CLOSING", sep); | ||
1273 | sep = '|'; | ||
1274 | } | ||
1275 | if (self->port.flags & ASYNC_NORMAL_ACTIVE) { | 1270 | if (self->port.flags & ASYNC_NORMAL_ACTIVE) { |
1276 | seq_printf(m, "%cASYNC_NORMAL_ACTIVE", sep); | 1271 | seq_printf(m, "%cASYNC_NORMAL_ACTIVE", sep); |
1277 | sep = '|'; | 1272 | sep = '|'; |
diff --git a/net/irda/ircomm/ircomm_tty_ioctl.c b/net/irda/ircomm/ircomm_tty_ioctl.c index 75ccdbd0728e..d3687aaa23de 100644 --- a/net/irda/ircomm/ircomm_tty_ioctl.c +++ b/net/irda/ircomm/ircomm_tty_ioctl.c | |||
@@ -158,26 +158,21 @@ void ircomm_tty_set_termios(struct tty_struct *tty, | |||
158 | ircomm_tty_change_speed(self, tty); | 158 | ircomm_tty_change_speed(self, tty); |
159 | 159 | ||
160 | /* Handle transition to B0 status */ | 160 | /* Handle transition to B0 status */ |
161 | if ((old_termios->c_cflag & CBAUD) && | 161 | if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD)) { |
162 | !(cflag & CBAUD)) { | ||
163 | self->settings.dte &= ~(IRCOMM_DTR|IRCOMM_RTS); | 162 | self->settings.dte &= ~(IRCOMM_DTR|IRCOMM_RTS); |
164 | ircomm_param_request(self, IRCOMM_DTE, TRUE); | 163 | ircomm_param_request(self, IRCOMM_DTE, TRUE); |
165 | } | 164 | } |
166 | 165 | ||
167 | /* Handle transition away from B0 status */ | 166 | /* Handle transition away from B0 status */ |
168 | if (!(old_termios->c_cflag & CBAUD) && | 167 | if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { |
169 | (cflag & CBAUD)) { | ||
170 | self->settings.dte |= IRCOMM_DTR; | 168 | self->settings.dte |= IRCOMM_DTR; |
171 | if (!(tty->termios.c_cflag & CRTSCTS) || | 169 | if (!C_CRTSCTS(tty) || !test_bit(TTY_THROTTLED, &tty->flags)) |
172 | !test_bit(TTY_THROTTLED, &tty->flags)) { | ||
173 | self->settings.dte |= IRCOMM_RTS; | 170 | self->settings.dte |= IRCOMM_RTS; |
174 | } | ||
175 | ircomm_param_request(self, IRCOMM_DTE, TRUE); | 171 | ircomm_param_request(self, IRCOMM_DTE, TRUE); |
176 | } | 172 | } |
177 | 173 | ||
178 | /* Handle turning off CRTSCTS */ | 174 | /* Handle turning off CRTSCTS */ |
179 | if ((old_termios->c_cflag & CRTSCTS) && | 175 | if ((old_termios->c_cflag & CRTSCTS) && !C_CRTSCTS(tty)) |
180 | !(tty->termios.c_cflag & CRTSCTS)) | ||
181 | { | 176 | { |
182 | tty->hw_stopped = 0; | 177 | tty->hw_stopped = 0; |
183 | ircomm_tty_start(tty); | 178 | ircomm_tty_start(tty); |
diff --git a/net/nfc/nci/uart.c b/net/nfc/nci/uart.c index 21d8875673a4..c468eabd6943 100644 --- a/net/nfc/nci/uart.c +++ b/net/nfc/nci/uart.c | |||
@@ -171,14 +171,7 @@ static int nci_uart_tty_open(struct tty_struct *tty) | |||
171 | tty->disc_data = NULL; | 171 | tty->disc_data = NULL; |
172 | tty->receive_room = 65536; | 172 | tty->receive_room = 65536; |
173 | 173 | ||
174 | /* Flush any pending characters in the driver and line discipline. */ | 174 | /* Flush any pending characters in the driver */ |
175 | |||
176 | /* FIXME: why is this needed. Note don't use ldisc_ref here as the | ||
177 | * open path is before the ldisc is referencable. | ||
178 | */ | ||
179 | |||
180 | if (tty->ldisc->ops->flush_buffer) | ||
181 | tty->ldisc->ops->flush_buffer(tty); | ||
182 | tty_driver_flush_buffer(tty); | 175 | tty_driver_flush_buffer(tty); |
183 | 176 | ||
184 | return 0; | 177 | return 0; |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index f1ab71504e1d..912deee3f01e 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -2415,7 +2415,7 @@ static inline void flush_unauthorized_files(const struct cred *cred, | |||
2415 | 2415 | ||
2416 | tty = get_current_tty(); | 2416 | tty = get_current_tty(); |
2417 | if (tty) { | 2417 | if (tty) { |
2418 | spin_lock(&tty_files_lock); | 2418 | spin_lock(&tty->files_lock); |
2419 | if (!list_empty(&tty->tty_files)) { | 2419 | if (!list_empty(&tty->tty_files)) { |
2420 | struct tty_file_private *file_priv; | 2420 | struct tty_file_private *file_priv; |
2421 | 2421 | ||
@@ -2430,7 +2430,7 @@ static inline void flush_unauthorized_files(const struct cred *cred, | |||
2430 | if (file_path_has_perm(cred, file, FILE__READ | FILE__WRITE)) | 2430 | if (file_path_has_perm(cred, file, FILE__READ | FILE__WRITE)) |
2431 | drop_tty = 1; | 2431 | drop_tty = 1; |
2432 | } | 2432 | } |
2433 | spin_unlock(&tty_files_lock); | 2433 | spin_unlock(&tty->files_lock); |
2434 | tty_kref_put(tty); | 2434 | tty_kref_put(tty); |
2435 | } | 2435 | } |
2436 | /* Reset controlling tty. */ | 2436 | /* Reset controlling tty. */ |