diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-29 15:16:17 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-29 15:16:17 -0400 |
commit | 507ffe4f3840ac24890a8123c702cf1b7fe4d33c (patch) | |
tree | 1046888f9db00f268a0056d7f6e427e21502f84c | |
parent | fdc719b63ae35d6a2d8a2a2c76eed813294664bf (diff) | |
parent | 45efcb2d32d35f6509543e477568842d8467035d (diff) |
Merge tag 'tty-3.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty/serial driver update from Greg Kroah-Hartman:
"Here's the big tty/serial driver merge request for 3.10-rc1
Once again, Jiri has a number of TTY driver fixes and cleanups, and
Peter Hurley came through with a bunch of ldisc fixes that resolve a
number of reported issues. There are some other serial driver
cleanups as well.
All of these have been in the linux-next tree for a while"
* tag 'tty-3.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (117 commits)
tty/serial/sirf: fix MODULE_DEVICE_TABLE
serial: mxs: drop superfluous {get|put}_device
serial: mxs: fix buffer overflow
ARM: PL011: add support for extended FIFO-size of PL011-r1p5
serial_core.c: add put_device() after device_find_child()
tty: Fix unsafe bit ops in tty_throttle_safe/unthrottle_safe
serial: sccnxp: Replace pdata.init/exit with regulator API
serial: sccnxp: Do not override device name
TTY: pty, fix compilation warning
TTY: rocket, fix compilation warning
TTY: ircomm: fix DTR being raised on hang up
TTY: synclinkmp: fix DTR being raised on hang up
TTY: synclink_gt: fix DTR being raised on hang up
TTY: synclink: fix DTR being raised on hang up
serial: 8250_dw: Fix the stub for dw8250_probe_acpi()
serial: 8250_dw: Convert to devm_ioremap()
serial: 8250_dw: Set port capabilities based on CPR register
serial: 8250_dw: Let ACPI code extract the DMA client info
serial: 8250_dw: Support clk framework also with ACPI
serial: 8250_dw: Enable runtime PM
...
92 files changed, 1670 insertions, 1611 deletions
diff --git a/Documentation/devicetree/bindings/tty/serial/of-serial.txt b/Documentation/devicetree/bindings/tty/serial/of-serial.txt index 8f01cb190f25..1928a3e83cd0 100644 --- a/Documentation/devicetree/bindings/tty/serial/of-serial.txt +++ b/Documentation/devicetree/bindings/tty/serial/of-serial.txt | |||
@@ -33,6 +33,10 @@ Optional properties: | |||
33 | RTAS and should not be registered. | 33 | RTAS and should not be registered. |
34 | - no-loopback-test: set to indicate that the port does not implements loopback | 34 | - no-loopback-test: set to indicate that the port does not implements loopback |
35 | test mode | 35 | test mode |
36 | - fifo-size: the fifo size of the UART. | ||
37 | - auto-flow-control: one way to enable automatic flow control support. The | ||
38 | driver is allowed to detect support for the capability even without this | ||
39 | property. | ||
36 | 40 | ||
37 | Example: | 41 | Example: |
38 | 42 | ||
diff --git a/arch/arm/mach-s3c24xx/clock-s3c2440.c b/arch/arm/mach-s3c24xx/clock-s3c2440.c index 04b87ec92537..1069b5680826 100644 --- a/arch/arm/mach-s3c24xx/clock-s3c2440.c +++ b/arch/arm/mach-s3c24xx/clock-s3c2440.c | |||
@@ -123,6 +123,11 @@ static struct clk s3c2440_clk_ac97 = { | |||
123 | .ctrlbit = S3C2440_CLKCON_AC97, | 123 | .ctrlbit = S3C2440_CLKCON_AC97, |
124 | }; | 124 | }; |
125 | 125 | ||
126 | #define S3C24XX_VA_UART0 (S3C_VA_UART) | ||
127 | #define S3C24XX_VA_UART1 (S3C_VA_UART + 0x4000 ) | ||
128 | #define S3C24XX_VA_UART2 (S3C_VA_UART + 0x8000 ) | ||
129 | #define S3C24XX_VA_UART3 (S3C_VA_UART + 0xC000 ) | ||
130 | |||
126 | static unsigned long s3c2440_fclk_n_getrate(struct clk *clk) | 131 | static unsigned long s3c2440_fclk_n_getrate(struct clk *clk) |
127 | { | 132 | { |
128 | unsigned long ucon0, ucon1, ucon2, divisor; | 133 | unsigned long ucon0, ucon1, ucon2, divisor; |
diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c index 6bcf87f65f9e..92e609440c57 100644 --- a/arch/arm/mach-s3c24xx/common.c +++ b/arch/arm/mach-s3c24xx/common.c | |||
@@ -239,6 +239,11 @@ void __init s3c24xx_init_io(struct map_desc *mach_desc, int size) | |||
239 | 239 | ||
240 | /* Serial port registrations */ | 240 | /* Serial port registrations */ |
241 | 241 | ||
242 | #define S3C2410_PA_UART0 (S3C24XX_PA_UART) | ||
243 | #define S3C2410_PA_UART1 (S3C24XX_PA_UART + 0x4000 ) | ||
244 | #define S3C2410_PA_UART2 (S3C24XX_PA_UART + 0x8000 ) | ||
245 | #define S3C2443_PA_UART3 (S3C24XX_PA_UART + 0xC000 ) | ||
246 | |||
242 | static struct resource s3c2410_uart0_resource[] = { | 247 | static struct resource s3c2410_uart0_resource[] = { |
243 | [0] = DEFINE_RES_MEM(S3C2410_PA_UART0, SZ_16K), | 248 | [0] = DEFINE_RES_MEM(S3C2410_PA_UART0, SZ_16K), |
244 | [1] = DEFINE_RES_NAMED(IRQ_S3CUART_RX0, \ | 249 | [1] = DEFINE_RES_NAMED(IRQ_S3CUART_RX0, \ |
diff --git a/arch/arm/plat-samsung/include/plat/regs-serial.h b/arch/arm/plat-samsung/include/plat/regs-serial.h index 29c26a818842..f05f2afa440d 100644 --- a/arch/arm/plat-samsung/include/plat/regs-serial.h +++ b/arch/arm/plat-samsung/include/plat/regs-serial.h | |||
@@ -1,281 +1 @@ | |||
1 | /* arch/arm/plat-samsung/include/plat/regs-serial.h | #include <linux/serial_s3c.h> | |
2 | * | ||
3 | * From linux/include/asm-arm/hardware/serial_s3c2410.h | ||
4 | * | ||
5 | * Internal header file for Samsung S3C2410 serial ports (UART0-2) | ||
6 | * | ||
7 | * Copyright (C) 2002 Shane Nay (shane@minirl.com) | ||
8 | * | ||
9 | * Additional defines, Copyright 2003 Simtec Electronics (linux@simtec.co.uk) | ||
10 | * | ||
11 | * Adapted from: | ||
12 | * | ||
13 | * Internal header file for MX1ADS serial ports (UART1 & 2) | ||
14 | * | ||
15 | * Copyright (C) 2002 Shane Nay (shane@minirl.com) | ||
16 | * | ||
17 | * This program is free software; you can redistribute it and/or modify | ||
18 | * it under the terms of the GNU General Public License as published by | ||
19 | * the Free Software Foundation; either version 2 of the License, or | ||
20 | * (at your option) any later version. | ||
21 | * | ||
22 | * This program is distributed in the hope that it will be useful, | ||
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
25 | * GNU General Public License for more details. | ||
26 | * | ||
27 | * You should have received a copy of the GNU General Public License | ||
28 | * along with this program; if not, write to the Free Software | ||
29 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
30 | */ | ||
31 | |||
32 | #ifndef __ASM_ARM_REGS_SERIAL_H | ||
33 | #define __ASM_ARM_REGS_SERIAL_H | ||
34 | |||
35 | #define S3C24XX_VA_UART0 (S3C_VA_UART) | ||
36 | #define S3C24XX_VA_UART1 (S3C_VA_UART + 0x4000 ) | ||
37 | #define S3C24XX_VA_UART2 (S3C_VA_UART + 0x8000 ) | ||
38 | #define S3C24XX_VA_UART3 (S3C_VA_UART + 0xC000 ) | ||
39 | |||
40 | #define S3C2410_PA_UART0 (S3C24XX_PA_UART) | ||
41 | #define S3C2410_PA_UART1 (S3C24XX_PA_UART + 0x4000 ) | ||
42 | #define S3C2410_PA_UART2 (S3C24XX_PA_UART + 0x8000 ) | ||
43 | #define S3C2443_PA_UART3 (S3C24XX_PA_UART + 0xC000 ) | ||
44 | |||
45 | #define S3C2410_URXH (0x24) | ||
46 | #define S3C2410_UTXH (0x20) | ||
47 | #define S3C2410_ULCON (0x00) | ||
48 | #define S3C2410_UCON (0x04) | ||
49 | #define S3C2410_UFCON (0x08) | ||
50 | #define S3C2410_UMCON (0x0C) | ||
51 | #define S3C2410_UBRDIV (0x28) | ||
52 | #define S3C2410_UTRSTAT (0x10) | ||
53 | #define S3C2410_UERSTAT (0x14) | ||
54 | #define S3C2410_UFSTAT (0x18) | ||
55 | #define S3C2410_UMSTAT (0x1C) | ||
56 | |||
57 | #define S3C2410_LCON_CFGMASK ((0xF<<3)|(0x3)) | ||
58 | |||
59 | #define S3C2410_LCON_CS5 (0x0) | ||
60 | #define S3C2410_LCON_CS6 (0x1) | ||
61 | #define S3C2410_LCON_CS7 (0x2) | ||
62 | #define S3C2410_LCON_CS8 (0x3) | ||
63 | #define S3C2410_LCON_CSMASK (0x3) | ||
64 | |||
65 | #define S3C2410_LCON_PNONE (0x0) | ||
66 | #define S3C2410_LCON_PEVEN (0x5 << 3) | ||
67 | #define S3C2410_LCON_PODD (0x4 << 3) | ||
68 | #define S3C2410_LCON_PMASK (0x7 << 3) | ||
69 | |||
70 | #define S3C2410_LCON_STOPB (1<<2) | ||
71 | #define S3C2410_LCON_IRM (1<<6) | ||
72 | |||
73 | #define S3C2440_UCON_CLKMASK (3<<10) | ||
74 | #define S3C2440_UCON_CLKSHIFT (10) | ||
75 | #define S3C2440_UCON_PCLK (0<<10) | ||
76 | #define S3C2440_UCON_UCLK (1<<10) | ||
77 | #define S3C2440_UCON_PCLK2 (2<<10) | ||
78 | #define S3C2440_UCON_FCLK (3<<10) | ||
79 | #define S3C2443_UCON_EPLL (3<<10) | ||
80 | |||
81 | #define S3C6400_UCON_CLKMASK (3<<10) | ||
82 | #define S3C6400_UCON_CLKSHIFT (10) | ||
83 | #define S3C6400_UCON_PCLK (0<<10) | ||
84 | #define S3C6400_UCON_PCLK2 (2<<10) | ||
85 | #define S3C6400_UCON_UCLK0 (1<<10) | ||
86 | #define S3C6400_UCON_UCLK1 (3<<10) | ||
87 | |||
88 | #define S3C2440_UCON2_FCLK_EN (1<<15) | ||
89 | #define S3C2440_UCON0_DIVMASK (15 << 12) | ||
90 | #define S3C2440_UCON1_DIVMASK (15 << 12) | ||
91 | #define S3C2440_UCON2_DIVMASK (7 << 12) | ||
92 | #define S3C2440_UCON_DIVSHIFT (12) | ||
93 | |||
94 | #define S3C2412_UCON_CLKMASK (3<<10) | ||
95 | #define S3C2412_UCON_CLKSHIFT (10) | ||
96 | #define S3C2412_UCON_UCLK (1<<10) | ||
97 | #define S3C2412_UCON_USYSCLK (3<<10) | ||
98 | #define S3C2412_UCON_PCLK (0<<10) | ||
99 | #define S3C2412_UCON_PCLK2 (2<<10) | ||
100 | |||
101 | #define S3C2410_UCON_CLKMASK (1 << 10) | ||
102 | #define S3C2410_UCON_CLKSHIFT (10) | ||
103 | #define S3C2410_UCON_UCLK (1<<10) | ||
104 | #define S3C2410_UCON_SBREAK (1<<4) | ||
105 | |||
106 | #define S3C2410_UCON_TXILEVEL (1<<9) | ||
107 | #define S3C2410_UCON_RXILEVEL (1<<8) | ||
108 | #define S3C2410_UCON_TXIRQMODE (1<<2) | ||
109 | #define S3C2410_UCON_RXIRQMODE (1<<0) | ||
110 | #define S3C2410_UCON_RXFIFO_TOI (1<<7) | ||
111 | #define S3C2443_UCON_RXERR_IRQEN (1<<6) | ||
112 | #define S3C2443_UCON_LOOPBACK (1<<5) | ||
113 | |||
114 | #define S3C2410_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ | ||
115 | S3C2410_UCON_RXILEVEL | \ | ||
116 | S3C2410_UCON_TXIRQMODE | \ | ||
117 | S3C2410_UCON_RXIRQMODE | \ | ||
118 | S3C2410_UCON_RXFIFO_TOI) | ||
119 | |||
120 | #define S3C2410_UFCON_FIFOMODE (1<<0) | ||
121 | #define S3C2410_UFCON_TXTRIG0 (0<<6) | ||
122 | #define S3C2410_UFCON_RXTRIG8 (1<<4) | ||
123 | #define S3C2410_UFCON_RXTRIG12 (2<<4) | ||
124 | |||
125 | /* S3C2440 FIFO trigger levels */ | ||
126 | #define S3C2440_UFCON_RXTRIG1 (0<<4) | ||
127 | #define S3C2440_UFCON_RXTRIG8 (1<<4) | ||
128 | #define S3C2440_UFCON_RXTRIG16 (2<<4) | ||
129 | #define S3C2440_UFCON_RXTRIG32 (3<<4) | ||
130 | |||
131 | #define S3C2440_UFCON_TXTRIG0 (0<<6) | ||
132 | #define S3C2440_UFCON_TXTRIG16 (1<<6) | ||
133 | #define S3C2440_UFCON_TXTRIG32 (2<<6) | ||
134 | #define S3C2440_UFCON_TXTRIG48 (3<<6) | ||
135 | |||
136 | #define S3C2410_UFCON_RESETBOTH (3<<1) | ||
137 | #define S3C2410_UFCON_RESETTX (1<<2) | ||
138 | #define S3C2410_UFCON_RESETRX (1<<1) | ||
139 | |||
140 | #define S3C2410_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \ | ||
141 | S3C2410_UFCON_TXTRIG0 | \ | ||
142 | S3C2410_UFCON_RXTRIG8 ) | ||
143 | |||
144 | #define S3C2410_UMCOM_AFC (1<<4) | ||
145 | #define S3C2410_UMCOM_RTS_LOW (1<<0) | ||
146 | |||
147 | #define S3C2412_UMCON_AFC_63 (0<<5) /* same as s3c2443 */ | ||
148 | #define S3C2412_UMCON_AFC_56 (1<<5) | ||
149 | #define S3C2412_UMCON_AFC_48 (2<<5) | ||
150 | #define S3C2412_UMCON_AFC_40 (3<<5) | ||
151 | #define S3C2412_UMCON_AFC_32 (4<<5) | ||
152 | #define S3C2412_UMCON_AFC_24 (5<<5) | ||
153 | #define S3C2412_UMCON_AFC_16 (6<<5) | ||
154 | #define S3C2412_UMCON_AFC_8 (7<<5) | ||
155 | |||
156 | #define S3C2410_UFSTAT_TXFULL (1<<9) | ||
157 | #define S3C2410_UFSTAT_RXFULL (1<<8) | ||
158 | #define S3C2410_UFSTAT_TXMASK (15<<4) | ||
159 | #define S3C2410_UFSTAT_TXSHIFT (4) | ||
160 | #define S3C2410_UFSTAT_RXMASK (15<<0) | ||
161 | #define S3C2410_UFSTAT_RXSHIFT (0) | ||
162 | |||
163 | /* UFSTAT S3C2443 same as S3C2440 */ | ||
164 | #define S3C2440_UFSTAT_TXFULL (1<<14) | ||
165 | #define S3C2440_UFSTAT_RXFULL (1<<6) | ||
166 | #define S3C2440_UFSTAT_TXSHIFT (8) | ||
167 | #define S3C2440_UFSTAT_RXSHIFT (0) | ||
168 | #define S3C2440_UFSTAT_TXMASK (63<<8) | ||
169 | #define S3C2440_UFSTAT_RXMASK (63) | ||
170 | |||
171 | #define S3C2410_UTRSTAT_TXE (1<<2) | ||
172 | #define S3C2410_UTRSTAT_TXFE (1<<1) | ||
173 | #define S3C2410_UTRSTAT_RXDR (1<<0) | ||
174 | |||
175 | #define S3C2410_UERSTAT_OVERRUN (1<<0) | ||
176 | #define S3C2410_UERSTAT_FRAME (1<<2) | ||
177 | #define S3C2410_UERSTAT_BREAK (1<<3) | ||
178 | #define S3C2443_UERSTAT_PARITY (1<<1) | ||
179 | |||
180 | #define S3C2410_UERSTAT_ANY (S3C2410_UERSTAT_OVERRUN | \ | ||
181 | S3C2410_UERSTAT_FRAME | \ | ||
182 | S3C2410_UERSTAT_BREAK) | ||
183 | |||
184 | #define S3C2410_UMSTAT_CTS (1<<0) | ||
185 | #define S3C2410_UMSTAT_DeltaCTS (1<<2) | ||
186 | |||
187 | #define S3C2443_DIVSLOT (0x2C) | ||
188 | |||
189 | /* S3C64XX interrupt registers. */ | ||
190 | #define S3C64XX_UINTP 0x30 | ||
191 | #define S3C64XX_UINTSP 0x34 | ||
192 | #define S3C64XX_UINTM 0x38 | ||
193 | |||
194 | #define S3C64XX_UINTM_RXD (0) | ||
195 | #define S3C64XX_UINTM_TXD (2) | ||
196 | #define S3C64XX_UINTM_RXD_MSK (1 << S3C64XX_UINTM_RXD) | ||
197 | #define S3C64XX_UINTM_TXD_MSK (1 << S3C64XX_UINTM_TXD) | ||
198 | |||
199 | /* Following are specific to S5PV210 */ | ||
200 | #define S5PV210_UCON_CLKMASK (1<<10) | ||
201 | #define S5PV210_UCON_CLKSHIFT (10) | ||
202 | #define S5PV210_UCON_PCLK (0<<10) | ||
203 | #define S5PV210_UCON_UCLK (1<<10) | ||
204 | |||
205 | #define S5PV210_UFCON_TXTRIG0 (0<<8) | ||
206 | #define S5PV210_UFCON_TXTRIG4 (1<<8) | ||
207 | #define S5PV210_UFCON_TXTRIG8 (2<<8) | ||
208 | #define S5PV210_UFCON_TXTRIG16 (3<<8) | ||
209 | #define S5PV210_UFCON_TXTRIG32 (4<<8) | ||
210 | #define S5PV210_UFCON_TXTRIG64 (5<<8) | ||
211 | #define S5PV210_UFCON_TXTRIG128 (6<<8) | ||
212 | #define S5PV210_UFCON_TXTRIG256 (7<<8) | ||
213 | |||
214 | #define S5PV210_UFCON_RXTRIG1 (0<<4) | ||
215 | #define S5PV210_UFCON_RXTRIG4 (1<<4) | ||
216 | #define S5PV210_UFCON_RXTRIG8 (2<<4) | ||
217 | #define S5PV210_UFCON_RXTRIG16 (3<<4) | ||
218 | #define S5PV210_UFCON_RXTRIG32 (4<<4) | ||
219 | #define S5PV210_UFCON_RXTRIG64 (5<<4) | ||
220 | #define S5PV210_UFCON_RXTRIG128 (6<<4) | ||
221 | #define S5PV210_UFCON_RXTRIG256 (7<<4) | ||
222 | |||
223 | #define S5PV210_UFSTAT_TXFULL (1<<24) | ||
224 | #define S5PV210_UFSTAT_RXFULL (1<<8) | ||
225 | #define S5PV210_UFSTAT_TXMASK (255<<16) | ||
226 | #define S5PV210_UFSTAT_TXSHIFT (16) | ||
227 | #define S5PV210_UFSTAT_RXMASK (255<<0) | ||
228 | #define S5PV210_UFSTAT_RXSHIFT (0) | ||
229 | |||
230 | #define S3C2410_UCON_CLKSEL0 (1 << 0) | ||
231 | #define S3C2410_UCON_CLKSEL1 (1 << 1) | ||
232 | #define S3C2410_UCON_CLKSEL2 (1 << 2) | ||
233 | #define S3C2410_UCON_CLKSEL3 (1 << 3) | ||
234 | |||
235 | /* Default values for s5pv210 UCON and UFCON uart registers */ | ||
236 | #define S5PV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ | ||
237 | S3C2410_UCON_RXILEVEL | \ | ||
238 | S3C2410_UCON_TXIRQMODE | \ | ||
239 | S3C2410_UCON_RXIRQMODE | \ | ||
240 | S3C2410_UCON_RXFIFO_TOI | \ | ||
241 | S3C2443_UCON_RXERR_IRQEN) | ||
242 | |||
243 | #define S5PV210_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \ | ||
244 | S5PV210_UFCON_TXTRIG4 | \ | ||
245 | S5PV210_UFCON_RXTRIG4) | ||
246 | |||
247 | #ifndef __ASSEMBLY__ | ||
248 | |||
249 | /* configuration structure for per-machine configurations for the | ||
250 | * serial port | ||
251 | * | ||
252 | * the pointer is setup by the machine specific initialisation from the | ||
253 | * arch/arm/mach-s3c2410/ directory. | ||
254 | */ | ||
255 | |||
256 | struct s3c2410_uartcfg { | ||
257 | unsigned char hwport; /* hardware port number */ | ||
258 | unsigned char unused; | ||
259 | unsigned short flags; | ||
260 | upf_t uart_flags; /* default uart flags */ | ||
261 | unsigned int clk_sel; | ||
262 | |||
263 | unsigned int has_fracval; | ||
264 | |||
265 | unsigned long ucon; /* value of ucon for port */ | ||
266 | unsigned long ulcon; /* value of ulcon for port */ | ||
267 | unsigned long ufcon; /* value of ufcon for port */ | ||
268 | }; | ||
269 | |||
270 | /* s3c24xx_uart_devs | ||
271 | * | ||
272 | * this is exported from the core as we cannot use driver_register(), | ||
273 | * or platform_add_device() before the console_initcall() | ||
274 | */ | ||
275 | |||
276 | extern struct platform_device *s3c24xx_uart_devs[4]; | ||
277 | |||
278 | #endif /* __ASSEMBLY__ */ | ||
279 | |||
280 | #endif /* __ASM_ARM_REGS_SERIAL_H */ | ||
281 | |||
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index da2f319fb71d..e70cadec7ce6 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c | |||
@@ -142,8 +142,7 @@ static void transmit_chars(struct tty_struct *tty, struct serial_state *info, | |||
142 | goto out; | 142 | goto out; |
143 | } | 143 | } |
144 | 144 | ||
145 | if (info->xmit.head == info->xmit.tail || tty->stopped || | 145 | if (info->xmit.head == info->xmit.tail || tty->stopped) { |
146 | tty->hw_stopped) { | ||
147 | #ifdef SIMSERIAL_DEBUG | 146 | #ifdef SIMSERIAL_DEBUG |
148 | printk("transmit_chars: head=%d, tail=%d, stopped=%d\n", | 147 | printk("transmit_chars: head=%d, tail=%d, stopped=%d\n", |
149 | info->xmit.head, info->xmit.tail, tty->stopped); | 148 | info->xmit.head, info->xmit.tail, tty->stopped); |
@@ -181,7 +180,7 @@ static void rs_flush_chars(struct tty_struct *tty) | |||
181 | struct serial_state *info = tty->driver_data; | 180 | struct serial_state *info = tty->driver_data; |
182 | 181 | ||
183 | if (info->xmit.head == info->xmit.tail || tty->stopped || | 182 | if (info->xmit.head == info->xmit.tail || tty->stopped || |
184 | tty->hw_stopped || !info->xmit.buf) | 183 | !info->xmit.buf) |
185 | return; | 184 | return; |
186 | 185 | ||
187 | transmit_chars(tty, info, NULL); | 186 | transmit_chars(tty, info, NULL); |
@@ -217,7 +216,7 @@ static int rs_write(struct tty_struct * tty, | |||
217 | * Hey, we transmit directly from here in our case | 216 | * Hey, we transmit directly from here in our case |
218 | */ | 217 | */ |
219 | if (CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) && | 218 | if (CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) && |
220 | !tty->stopped && !tty->hw_stopped) | 219 | !tty->stopped) |
221 | transmit_chars(tty, info, NULL); | 220 | transmit_chars(tty, info, NULL); |
222 | 221 | ||
223 | return ret; | 222 | return ret; |
@@ -325,14 +324,6 @@ static int rs_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) | |||
325 | 324 | ||
326 | #define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) | 325 | #define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) |
327 | 326 | ||
328 | static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | ||
329 | { | ||
330 | /* Handle turning off CRTSCTS */ | ||
331 | if ((old_termios->c_cflag & CRTSCTS) && | ||
332 | !(tty->termios.c_cflag & CRTSCTS)) { | ||
333 | tty->hw_stopped = 0; | ||
334 | } | ||
335 | } | ||
336 | /* | 327 | /* |
337 | * This routine will shutdown a serial port; interrupts are disabled, and | 328 | * This routine will shutdown a serial port; interrupts are disabled, and |
338 | * DTR is dropped if the hangup on close termio flag is on. | 329 | * DTR is dropped if the hangup on close termio flag is on. |
@@ -481,7 +472,6 @@ static const struct tty_operations hp_ops = { | |||
481 | .throttle = rs_throttle, | 472 | .throttle = rs_throttle, |
482 | .unthrottle = rs_unthrottle, | 473 | .unthrottle = rs_unthrottle, |
483 | .send_xchar = rs_send_xchar, | 474 | .send_xchar = rs_send_xchar, |
484 | .set_termios = rs_set_termios, | ||
485 | .hangup = rs_hangup, | 475 | .hangup = rs_hangup, |
486 | .proc_fops = &rs_proc_fops, | 476 | .proc_fops = &rs_proc_fops, |
487 | }; | 477 | }; |
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 80b47cb71e0a..acbe6c67afba 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c | |||
@@ -568,11 +568,7 @@ void chan_interrupt(struct line *line, int irq) | |||
568 | reactivate_fd(chan->fd, irq); | 568 | reactivate_fd(chan->fd, irq); |
569 | if (err == -EIO) { | 569 | if (err == -EIO) { |
570 | if (chan->primary) { | 570 | if (chan->primary) { |
571 | struct tty_struct *tty = tty_port_tty_get(&line->port); | 571 | tty_port_tty_hangup(&line->port, false); |
572 | if (tty != NULL) { | ||
573 | tty_hangup(tty); | ||
574 | tty_kref_put(tty); | ||
575 | } | ||
576 | if (line->chan_out != chan) | 572 | if (line->chan_out != chan) |
577 | close_one_chan(line->chan_out, 1); | 573 | close_one_chan(line->chan_out, 1); |
578 | } | 574 | } |
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index be541cf69fd2..8035145f043b 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c | |||
@@ -248,7 +248,6 @@ static irqreturn_t line_write_interrupt(int irq, void *data) | |||
248 | { | 248 | { |
249 | struct chan *chan = data; | 249 | struct chan *chan = data; |
250 | struct line *line = chan->line; | 250 | struct line *line = chan->line; |
251 | struct tty_struct *tty; | ||
252 | int err; | 251 | int err; |
253 | 252 | ||
254 | /* | 253 | /* |
@@ -267,12 +266,7 @@ static irqreturn_t line_write_interrupt(int irq, void *data) | |||
267 | } | 266 | } |
268 | spin_unlock(&line->lock); | 267 | spin_unlock(&line->lock); |
269 | 268 | ||
270 | tty = tty_port_tty_get(&line->port); | 269 | tty_port_tty_wakeup(&line->port); |
271 | if (tty == NULL) | ||
272 | return IRQ_NONE; | ||
273 | |||
274 | tty_wakeup(tty); | ||
275 | tty_kref_put(tty); | ||
276 | 270 | ||
277 | return IRQ_HANDLED; | 271 | return IRQ_HANDLED; |
278 | } | 272 | } |
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 89562a845f6a..ac6f72b455d1 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c | |||
@@ -569,7 +569,6 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb) | |||
569 | { | 569 | { |
570 | struct capidev *cdev = ap->private; | 570 | struct capidev *cdev = ap->private; |
571 | #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE | 571 | #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE |
572 | struct tty_struct *tty; | ||
573 | struct capiminor *mp; | 572 | struct capiminor *mp; |
574 | u16 datahandle; | 573 | u16 datahandle; |
575 | struct capincci *np; | 574 | struct capincci *np; |
@@ -627,11 +626,7 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb) | |||
627 | CAPIMSG_U16(skb->data, CAPIMSG_BASELEN + 4 + 2)); | 626 | CAPIMSG_U16(skb->data, CAPIMSG_BASELEN + 4 + 2)); |
628 | kfree_skb(skb); | 627 | kfree_skb(skb); |
629 | capiminor_del_ack(mp, datahandle); | 628 | capiminor_del_ack(mp, datahandle); |
630 | tty = tty_port_tty_get(&mp->port); | 629 | tty_port_tty_wakeup(&mp->port); |
631 | if (tty) { | ||
632 | tty_wakeup(tty); | ||
633 | tty_kref_put(tty); | ||
634 | } | ||
635 | handle_minor_send(mp); | 630 | handle_minor_send(mp); |
636 | 631 | ||
637 | } else { | 632 | } else { |
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index e2b539675b66..600c79b030cd 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c | |||
@@ -487,12 +487,8 @@ static const struct tty_operations if_ops = { | |||
487 | static void if_wake(unsigned long data) | 487 | static void if_wake(unsigned long data) |
488 | { | 488 | { |
489 | struct cardstate *cs = (struct cardstate *)data; | 489 | struct cardstate *cs = (struct cardstate *)data; |
490 | struct tty_struct *tty = tty_port_tty_get(&cs->port); | ||
491 | 490 | ||
492 | if (tty) { | 491 | tty_port_tty_wakeup(&cs->port); |
493 | tty_wakeup(tty); | ||
494 | tty_kref_put(tty); | ||
495 | } | ||
496 | } | 492 | } |
497 | 493 | ||
498 | /*** interface to common ***/ | 494 | /*** interface to common ***/ |
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index ebaebdf30f98..b72afd81a7bb 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c | |||
@@ -1472,9 +1472,6 @@ isdn_tty_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
1472 | tty->termios.c_ospeed == old_termios->c_ospeed) | 1472 | tty->termios.c_ospeed == old_termios->c_ospeed) |
1473 | return; | 1473 | return; |
1474 | isdn_tty_change_speed(info); | 1474 | isdn_tty_change_speed(info); |
1475 | if ((old_termios->c_cflag & CRTSCTS) && | ||
1476 | !(tty->termios.c_cflag & CRTSCTS)) | ||
1477 | tty->hw_stopped = 0; | ||
1478 | } | 1475 | } |
1479 | } | 1476 | } |
1480 | 1477 | ||
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c index c931dfe6a59c..f093cea0d060 100644 --- a/drivers/mmc/card/sdio_uart.c +++ b/drivers/mmc/card/sdio_uart.c | |||
@@ -134,7 +134,6 @@ static void sdio_uart_port_put(struct sdio_uart_port *port) | |||
134 | static void sdio_uart_port_remove(struct sdio_uart_port *port) | 134 | static void sdio_uart_port_remove(struct sdio_uart_port *port) |
135 | { | 135 | { |
136 | struct sdio_func *func; | 136 | struct sdio_func *func; |
137 | struct tty_struct *tty; | ||
138 | 137 | ||
139 | BUG_ON(sdio_uart_table[port->index] != port); | 138 | BUG_ON(sdio_uart_table[port->index] != port); |
140 | 139 | ||
@@ -155,12 +154,8 @@ static void sdio_uart_port_remove(struct sdio_uart_port *port) | |||
155 | sdio_claim_host(func); | 154 | sdio_claim_host(func); |
156 | port->func = NULL; | 155 | port->func = NULL; |
157 | mutex_unlock(&port->func_lock); | 156 | mutex_unlock(&port->func_lock); |
158 | tty = tty_port_tty_get(&port->port); | ||
159 | /* tty_hangup is async so is this safe as is ?? */ | 157 | /* tty_hangup is async so is this safe as is ?? */ |
160 | if (tty) { | 158 | tty_port_tty_hangup(&port->port, false); |
161 | tty_hangup(tty); | ||
162 | tty_kref_put(tty); | ||
163 | } | ||
164 | mutex_unlock(&port->port.mutex); | 159 | mutex_unlock(&port->port.mutex); |
165 | sdio_release_irq(func); | 160 | sdio_release_irq(func); |
166 | sdio_disable_func(func); | 161 | sdio_disable_func(func); |
@@ -492,11 +487,7 @@ static void sdio_uart_check_modem_status(struct sdio_uart_port *port) | |||
492 | wake_up_interruptible(&port->port.open_wait); | 487 | wake_up_interruptible(&port->port.open_wait); |
493 | else { | 488 | else { |
494 | /* DCD drop - hang up if tty attached */ | 489 | /* DCD drop - hang up if tty attached */ |
495 | tty = tty_port_tty_get(&port->port); | 490 | tty_port_tty_hangup(&port->port, false); |
496 | if (tty) { | ||
497 | tty_hangup(tty); | ||
498 | tty_kref_put(tty); | ||
499 | } | ||
500 | } | 491 | } |
501 | } | 492 | } |
502 | if (status & UART_MSR_DCTS) { | 493 | if (status & UART_MSR_DCTS) { |
diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c index 666891a9a248..be90debc7cd1 100644 --- a/drivers/net/caif/caif_serial.c +++ b/drivers/net/caif/caif_serial.c | |||
@@ -88,11 +88,9 @@ static inline void update_tty_status(struct ser_device *ser) | |||
88 | { | 88 | { |
89 | ser->tty_status = | 89 | ser->tty_status = |
90 | ser->tty->stopped << 5 | | 90 | ser->tty->stopped << 5 | |
91 | ser->tty->hw_stopped << 4 | | ||
92 | ser->tty->flow_stopped << 3 | | 91 | ser->tty->flow_stopped << 3 | |
93 | ser->tty->packet << 2 | | 92 | ser->tty->packet << 2 | |
94 | ser->tty->port->low_latency << 1 | | 93 | ser->tty->port->low_latency << 1; |
95 | ser->tty->warned; | ||
96 | } | 94 | } |
97 | static inline void debugfs_init(struct ser_device *ser, struct tty_struct *tty) | 95 | static inline void debugfs_init(struct ser_device *ser, struct tty_struct *tty) |
98 | { | 96 | { |
diff --git a/drivers/net/ppp/ppp_async.c b/drivers/net/ppp/ppp_async.c index a031f6b456b4..9c889e0303dd 100644 --- a/drivers/net/ppp/ppp_async.c +++ b/drivers/net/ppp/ppp_async.c | |||
@@ -314,7 +314,7 @@ ppp_asynctty_ioctl(struct tty_struct *tty, struct file *file, | |||
314 | /* flush our buffers and the serial port's buffer */ | 314 | /* flush our buffers and the serial port's buffer */ |
315 | if (arg == TCIOFLUSH || arg == TCOFLUSH) | 315 | if (arg == TCIOFLUSH || arg == TCOFLUSH) |
316 | ppp_async_flush_output(ap); | 316 | ppp_async_flush_output(ap); |
317 | err = tty_perform_flush(tty, arg); | 317 | err = n_tty_ioctl_helper(tty, file, cmd, arg); |
318 | break; | 318 | break; |
319 | 319 | ||
320 | case FIONREAD: | 320 | case FIONREAD: |
diff --git a/drivers/net/ppp/ppp_synctty.c b/drivers/net/ppp/ppp_synctty.c index 1a12033d2efa..bdf3b13a71a8 100644 --- a/drivers/net/ppp/ppp_synctty.c +++ b/drivers/net/ppp/ppp_synctty.c | |||
@@ -355,7 +355,7 @@ ppp_synctty_ioctl(struct tty_struct *tty, struct file *file, | |||
355 | /* flush our buffers and the serial port's buffer */ | 355 | /* flush our buffers and the serial port's buffer */ |
356 | if (arg == TCIOFLUSH || arg == TCOFLUSH) | 356 | if (arg == TCIOFLUSH || arg == TCOFLUSH) |
357 | ppp_sync_flush_output(ap); | 357 | ppp_sync_flush_output(ap); |
358 | err = tty_perform_flush(tty, arg); | 358 | err = n_tty_ioctl_helper(tty, file, cmd, arg); |
359 | break; | 359 | break; |
360 | 360 | ||
361 | case FIONREAD: | 361 | case FIONREAD: |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index e2dd3249b6bd..cba1d46e672e 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
@@ -1925,7 +1925,6 @@ static void hso_std_serial_write_bulk_callback(struct urb *urb) | |||
1925 | { | 1925 | { |
1926 | struct hso_serial *serial = urb->context; | 1926 | struct hso_serial *serial = urb->context; |
1927 | int status = urb->status; | 1927 | int status = urb->status; |
1928 | struct tty_struct *tty; | ||
1929 | 1928 | ||
1930 | /* sanity check */ | 1929 | /* sanity check */ |
1931 | if (!serial) { | 1930 | if (!serial) { |
@@ -1941,11 +1940,7 @@ static void hso_std_serial_write_bulk_callback(struct urb *urb) | |||
1941 | return; | 1940 | return; |
1942 | } | 1941 | } |
1943 | hso_put_activity(serial->parent); | 1942 | hso_put_activity(serial->parent); |
1944 | tty = tty_port_tty_get(&serial->port); | 1943 | tty_port_tty_wakeup(&serial->port); |
1945 | if (tty) { | ||
1946 | tty_wakeup(tty); | ||
1947 | tty_kref_put(tty); | ||
1948 | } | ||
1949 | hso_kick_transmit(serial); | 1944 | hso_kick_transmit(serial); |
1950 | 1945 | ||
1951 | D1(" "); | 1946 | D1(" "); |
@@ -2008,12 +2003,8 @@ static void ctrl_callback(struct urb *urb) | |||
2008 | put_rxbuf_data_and_resubmit_ctrl_urb(serial); | 2003 | put_rxbuf_data_and_resubmit_ctrl_urb(serial); |
2009 | spin_unlock(&serial->serial_lock); | 2004 | spin_unlock(&serial->serial_lock); |
2010 | } else { | 2005 | } else { |
2011 | struct tty_struct *tty = tty_port_tty_get(&serial->port); | ||
2012 | hso_put_activity(serial->parent); | 2006 | hso_put_activity(serial->parent); |
2013 | if (tty) { | 2007 | tty_port_tty_wakeup(&serial->port); |
2014 | tty_wakeup(tty); | ||
2015 | tty_kref_put(tty); | ||
2016 | } | ||
2017 | /* response to a write command */ | 2008 | /* response to a write command */ |
2018 | hso_kick_transmit(serial); | 2009 | hso_kick_transmit(serial); |
2019 | } | 2010 | } |
@@ -3133,18 +3124,13 @@ static void hso_serial_ref_free(struct kref *ref) | |||
3133 | static void hso_free_interface(struct usb_interface *interface) | 3124 | static void hso_free_interface(struct usb_interface *interface) |
3134 | { | 3125 | { |
3135 | struct hso_serial *hso_dev; | 3126 | struct hso_serial *hso_dev; |
3136 | struct tty_struct *tty; | ||
3137 | int i; | 3127 | int i; |
3138 | 3128 | ||
3139 | for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) { | 3129 | for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) { |
3140 | if (serial_table[i] && | 3130 | if (serial_table[i] && |
3141 | (serial_table[i]->interface == interface)) { | 3131 | (serial_table[i]->interface == interface)) { |
3142 | hso_dev = dev2ser(serial_table[i]); | 3132 | hso_dev = dev2ser(serial_table[i]); |
3143 | tty = tty_port_tty_get(&hso_dev->port); | 3133 | tty_port_tty_hangup(&hso_dev->port, false); |
3144 | if (tty) { | ||
3145 | tty_hangup(tty); | ||
3146 | tty_kref_put(tty); | ||
3147 | } | ||
3148 | mutex_lock(&hso_dev->parent->mutex); | 3134 | mutex_lock(&hso_dev->parent->mutex); |
3149 | hso_dev->parent->usb_gone = 1; | 3135 | hso_dev->parent->usb_gone = 1; |
3150 | mutex_unlock(&hso_dev->parent->mutex); | 3136 | mutex_unlock(&hso_dev->parent->mutex); |
diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c index 14b4cb8abcc8..7ed7a5987816 100644 --- a/drivers/s390/char/sclp_tty.c +++ b/drivers/s390/char/sclp_tty.c | |||
@@ -107,7 +107,6 @@ sclp_tty_write_room (struct tty_struct *tty) | |||
107 | static void | 107 | static void |
108 | sclp_ttybuf_callback(struct sclp_buffer *buffer, int rc) | 108 | sclp_ttybuf_callback(struct sclp_buffer *buffer, int rc) |
109 | { | 109 | { |
110 | struct tty_struct *tty; | ||
111 | unsigned long flags; | 110 | unsigned long flags; |
112 | void *page; | 111 | void *page; |
113 | 112 | ||
@@ -125,12 +124,8 @@ sclp_ttybuf_callback(struct sclp_buffer *buffer, int rc) | |||
125 | struct sclp_buffer, list); | 124 | struct sclp_buffer, list); |
126 | spin_unlock_irqrestore(&sclp_tty_lock, flags); | 125 | spin_unlock_irqrestore(&sclp_tty_lock, flags); |
127 | } while (buffer && sclp_emit_buffer(buffer, sclp_ttybuf_callback)); | 126 | } while (buffer && sclp_emit_buffer(buffer, sclp_ttybuf_callback)); |
128 | /* check if the tty needs a wake up call */ | 127 | |
129 | tty = tty_port_tty_get(&sclp_port); | 128 | tty_port_tty_wakeup(&sclp_port); |
130 | if (tty != NULL) { | ||
131 | tty_wakeup(tty); | ||
132 | tty_kref_put(tty); | ||
133 | } | ||
134 | } | 129 | } |
135 | 130 | ||
136 | static inline void | 131 | static inline void |
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index 6c92f62623be..5aaaa2ec8df4 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c | |||
@@ -114,7 +114,6 @@ static struct sclp_register sclp_vt220_register = { | |||
114 | static void | 114 | static void |
115 | sclp_vt220_process_queue(struct sclp_vt220_request *request) | 115 | sclp_vt220_process_queue(struct sclp_vt220_request *request) |
116 | { | 116 | { |
117 | struct tty_struct *tty; | ||
118 | unsigned long flags; | 117 | unsigned long flags; |
119 | void *page; | 118 | void *page; |
120 | 119 | ||
@@ -139,12 +138,7 @@ sclp_vt220_process_queue(struct sclp_vt220_request *request) | |||
139 | } while (__sclp_vt220_emit(request)); | 138 | } while (__sclp_vt220_emit(request)); |
140 | if (request == NULL && sclp_vt220_flush_later) | 139 | if (request == NULL && sclp_vt220_flush_later) |
141 | sclp_vt220_emit_current(); | 140 | sclp_vt220_emit_current(); |
142 | /* Check if the tty needs a wake up call */ | 141 | tty_port_tty_wakeup(&sclp_vt220_port); |
143 | tty = tty_port_tty_get(&sclp_vt220_port); | ||
144 | if (tty) { | ||
145 | tty_wakeup(tty); | ||
146 | tty_kref_put(tty); | ||
147 | } | ||
148 | } | 142 | } |
149 | 143 | ||
150 | #define SCLP_BUFFER_MAX_RETRY 1 | 144 | #define SCLP_BUFFER_MAX_RETRY 1 |
diff --git a/drivers/staging/fwserial/fwserial.c b/drivers/staging/fwserial/fwserial.c index 0263e98b445d..e5818a1c2262 100644 --- a/drivers/staging/fwserial/fwserial.c +++ b/drivers/staging/fwserial/fwserial.c | |||
@@ -744,7 +744,6 @@ static void fwtty_tx_complete(struct fw_card *card, int rcode, | |||
744 | struct fwtty_transaction *txn) | 744 | struct fwtty_transaction *txn) |
745 | { | 745 | { |
746 | struct fwtty_port *port = txn->port; | 746 | struct fwtty_port *port = txn->port; |
747 | struct tty_struct *tty; | ||
748 | int len; | 747 | int len; |
749 | 748 | ||
750 | fwtty_dbg(port, "rcode: %d", rcode); | 749 | fwtty_dbg(port, "rcode: %d", rcode); |
@@ -769,13 +768,8 @@ static void fwtty_tx_complete(struct fw_card *card, int rcode, | |||
769 | port->stats.dropped += txn->dma_pended.len; | 768 | port->stats.dropped += txn->dma_pended.len; |
770 | } | 769 | } |
771 | 770 | ||
772 | if (len < WAKEUP_CHARS) { | 771 | if (len < WAKEUP_CHARS) |
773 | tty = tty_port_tty_get(&port->port); | 772 | tty_port_tty_wakeup(&port->port); |
774 | if (tty) { | ||
775 | tty_wakeup(tty); | ||
776 | tty_kref_put(tty); | ||
777 | } | ||
778 | } | ||
779 | } | 773 | } |
780 | 774 | ||
781 | static int fwtty_tx(struct fwtty_port *port, bool drain) | 775 | static int fwtty_tx(struct fwtty_port *port, bool drain) |
diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c index b1bb1a6abe81..8a6e5ea476e1 100644 --- a/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/drivers/staging/serqt_usb2/serqt_usb2.c | |||
@@ -264,7 +264,6 @@ static void ProcessRxChar(struct usb_serial_port *port, unsigned char data) | |||
264 | 264 | ||
265 | static void qt_write_bulk_callback(struct urb *urb) | 265 | static void qt_write_bulk_callback(struct urb *urb) |
266 | { | 266 | { |
267 | struct tty_struct *tty; | ||
268 | int status; | 267 | int status; |
269 | struct quatech_port *quatech_port; | 268 | struct quatech_port *quatech_port; |
270 | 269 | ||
@@ -278,11 +277,7 @@ static void qt_write_bulk_callback(struct urb *urb) | |||
278 | 277 | ||
279 | quatech_port = urb->context; | 278 | quatech_port = urb->context; |
280 | 279 | ||
281 | tty = tty_port_tty_get(&quatech_port->port->port); | 280 | tty_port_tty_wakeup(&quatech_port->port->port); |
282 | |||
283 | if (tty) | ||
284 | tty_wakeup(tty); | ||
285 | tty_kref_put(tty); | ||
286 | } | 281 | } |
287 | 282 | ||
288 | static void qt_interrupt_callback(struct urb *urb) | 283 | static void qt_interrupt_callback(struct urb *urb) |
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index fc700342d43f..083710e02367 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c | |||
@@ -1798,19 +1798,7 @@ static struct platform_driver amiga_serial_driver = { | |||
1798 | }, | 1798 | }, |
1799 | }; | 1799 | }; |
1800 | 1800 | ||
1801 | static int __init amiga_serial_init(void) | 1801 | module_platform_driver_probe(amiga_serial_driver, amiga_serial_probe); |
1802 | { | ||
1803 | return platform_driver_probe(&amiga_serial_driver, amiga_serial_probe); | ||
1804 | } | ||
1805 | |||
1806 | module_init(amiga_serial_init); | ||
1807 | |||
1808 | static void __exit amiga_serial_exit(void) | ||
1809 | { | ||
1810 | platform_driver_unregister(&amiga_serial_driver); | ||
1811 | } | ||
1812 | |||
1813 | module_exit(amiga_serial_exit); | ||
1814 | 1802 | ||
1815 | 1803 | ||
1816 | #if defined(CONFIG_SERIAL_CONSOLE) && !defined(MODULE) | 1804 | #if defined(CONFIG_SERIAL_CONSOLE) && !defined(MODULE) |
diff --git a/drivers/tty/cyclades.c b/drivers/tty/cyclades.c index 345bd0e0884e..33f83fee9fae 100644 --- a/drivers/tty/cyclades.c +++ b/drivers/tty/cyclades.c | |||
@@ -1124,14 +1124,8 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1124 | readl(&info->u.cyz.ch_ctrl->rs_status); | 1124 | readl(&info->u.cyz.ch_ctrl->rs_status); |
1125 | if (dcd & C_RS_DCD) | 1125 | if (dcd & C_RS_DCD) |
1126 | wake_up_interruptible(&info->port.open_wait); | 1126 | wake_up_interruptible(&info->port.open_wait); |
1127 | else { | 1127 | else |
1128 | struct tty_struct *tty; | 1128 | tty_port_tty_hangup(&info->port, false); |
1129 | tty = tty_port_tty_get(&info->port); | ||
1130 | if (tty) { | ||
1131 | tty_hangup(tty); | ||
1132 | tty_kref_put(tty); | ||
1133 | } | ||
1134 | } | ||
1135 | } | 1129 | } |
1136 | break; | 1130 | break; |
1137 | case C_CM_MCTS: | 1131 | case C_CM_MCTS: |
diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c index ed92622b8949..6d0c27cd03da 100644 --- a/drivers/tty/ehv_bytechan.c +++ b/drivers/tty/ehv_bytechan.c | |||
@@ -472,13 +472,9 @@ static void ehv_bc_tx_dequeue(struct ehv_bc_data *bc) | |||
472 | static irqreturn_t ehv_bc_tty_tx_isr(int irq, void *data) | 472 | static irqreturn_t ehv_bc_tty_tx_isr(int irq, void *data) |
473 | { | 473 | { |
474 | struct ehv_bc_data *bc = data; | 474 | struct ehv_bc_data *bc = data; |
475 | struct tty_struct *ttys = tty_port_tty_get(&bc->port); | ||
476 | 475 | ||
477 | ehv_bc_tx_dequeue(bc); | 476 | ehv_bc_tx_dequeue(bc); |
478 | if (ttys) { | 477 | tty_port_tty_wakeup(&bc->port); |
479 | tty_wakeup(ttys); | ||
480 | tty_kref_put(ttys); | ||
481 | } | ||
482 | 478 | ||
483 | return IRQ_HANDLED; | 479 | return IRQ_HANDLED; |
484 | } | 480 | } |
diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c index ef95a154854a..41901997c0d6 100644 --- a/drivers/tty/hvc/hvsi.c +++ b/drivers/tty/hvc/hvsi.c | |||
@@ -861,7 +861,6 @@ static void hvsi_write_worker(struct work_struct *work) | |||
861 | { | 861 | { |
862 | struct hvsi_struct *hp = | 862 | struct hvsi_struct *hp = |
863 | container_of(work, struct hvsi_struct, writer.work); | 863 | container_of(work, struct hvsi_struct, writer.work); |
864 | struct tty_struct *tty; | ||
865 | unsigned long flags; | 864 | unsigned long flags; |
866 | #ifdef DEBUG | 865 | #ifdef DEBUG |
867 | static long start_j = 0; | 866 | static long start_j = 0; |
@@ -895,11 +894,7 @@ static void hvsi_write_worker(struct work_struct *work) | |||
895 | start_j = 0; | 894 | start_j = 0; |
896 | #endif /* DEBUG */ | 895 | #endif /* DEBUG */ |
897 | wake_up_all(&hp->emptyq); | 896 | wake_up_all(&hp->emptyq); |
898 | tty = tty_port_tty_get(&hp->port); | 897 | tty_port_tty_wakeup(&hp->port); |
899 | if (tty) { | ||
900 | tty_wakeup(tty); | ||
901 | tty_kref_put(tty); | ||
902 | } | ||
903 | } | 898 | } |
904 | 899 | ||
905 | out: | 900 | out: |
diff --git a/drivers/tty/ipwireless/hardware.c b/drivers/tty/ipwireless/hardware.c index 97a511f4185d..2c14842541dd 100644 --- a/drivers/tty/ipwireless/hardware.c +++ b/drivers/tty/ipwireless/hardware.c | |||
@@ -1732,8 +1732,7 @@ void ipwireless_hardware_free(struct ipw_hardware *hw) | |||
1732 | flush_work(&hw->work_rx); | 1732 | flush_work(&hw->work_rx); |
1733 | 1733 | ||
1734 | for (i = 0; i < NL_NUM_OF_ADDRESSES; i++) | 1734 | for (i = 0; i < NL_NUM_OF_ADDRESSES; i++) |
1735 | if (hw->packet_assembler[i] != NULL) | 1735 | kfree(hw->packet_assembler[i]); |
1736 | kfree(hw->packet_assembler[i]); | ||
1737 | 1736 | ||
1738 | for (i = 0; i < NL_NUM_OF_PRIORITIES; i++) | 1737 | for (i = 0; i < NL_NUM_OF_PRIORITIES; i++) |
1739 | list_for_each_entry_safe(tp, tq, &hw->tx_queue[i], queue) { | 1738 | list_for_each_entry_safe(tp, tq, &hw->tx_queue[i], queue) { |
diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c index adeac255e526..1deaca4674e4 100644 --- a/drivers/tty/moxa.c +++ b/drivers/tty/moxa.c | |||
@@ -913,16 +913,12 @@ static void moxa_board_deinit(struct moxa_board_conf *brd) | |||
913 | 913 | ||
914 | /* pci hot-un-plug support */ | 914 | /* pci hot-un-plug support */ |
915 | for (a = 0; a < brd->numPorts; a++) | 915 | for (a = 0; a < brd->numPorts; a++) |
916 | if (brd->ports[a].port.flags & ASYNC_INITIALIZED) { | 916 | if (brd->ports[a].port.flags & ASYNC_INITIALIZED) |
917 | struct tty_struct *tty = tty_port_tty_get( | 917 | tty_port_tty_hangup(&brd->ports[a].port, false); |
918 | &brd->ports[a].port); | 918 | |
919 | if (tty) { | ||
920 | tty_hangup(tty); | ||
921 | tty_kref_put(tty); | ||
922 | } | ||
923 | } | ||
924 | for (a = 0; a < MAX_PORTS_PER_BOARD; a++) | 919 | for (a = 0; a < MAX_PORTS_PER_BOARD; a++) |
925 | tty_port_destroy(&brd->ports[a].port); | 920 | tty_port_destroy(&brd->ports[a].port); |
921 | |||
926 | while (1) { | 922 | while (1) { |
927 | opened = 0; | 923 | opened = 0; |
928 | for (a = 0; a < brd->numPorts; a++) | 924 | for (a = 0; a < brd->numPorts; a++) |
@@ -1365,7 +1361,6 @@ static void moxa_hangup(struct tty_struct *tty) | |||
1365 | 1361 | ||
1366 | static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd) | 1362 | static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd) |
1367 | { | 1363 | { |
1368 | struct tty_struct *tty; | ||
1369 | unsigned long flags; | 1364 | unsigned long flags; |
1370 | dcd = !!dcd; | 1365 | dcd = !!dcd; |
1371 | 1366 | ||
@@ -1373,10 +1368,8 @@ static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd) | |||
1373 | if (dcd != p->DCDState) { | 1368 | if (dcd != p->DCDState) { |
1374 | p->DCDState = dcd; | 1369 | p->DCDState = dcd; |
1375 | spin_unlock_irqrestore(&p->port.lock, flags); | 1370 | spin_unlock_irqrestore(&p->port.lock, flags); |
1376 | tty = tty_port_tty_get(&p->port); | 1371 | if (!dcd) |
1377 | if (tty && !C_CLOCAL(tty) && !dcd) | 1372 | tty_port_tty_hangup(&p->port, true); |
1378 | tty_hangup(tty); | ||
1379 | tty_kref_put(tty); | ||
1380 | } | 1373 | } |
1381 | else | 1374 | else |
1382 | spin_unlock_irqrestore(&p->port.lock, flags); | 1375 | spin_unlock_irqrestore(&p->port.lock, flags); |
diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 302909ccf183..71d6eb2c93b1 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c | |||
@@ -1084,6 +1084,10 @@ static void mxser_close(struct tty_struct *tty, struct file *filp) | |||
1084 | mutex_lock(&port->mutex); | 1084 | mutex_lock(&port->mutex); |
1085 | mxser_close_port(port); | 1085 | mxser_close_port(port); |
1086 | mxser_flush_buffer(tty); | 1086 | mxser_flush_buffer(tty); |
1087 | if (test_bit(ASYNCB_INITIALIZED, &port->flags)) { | ||
1088 | if (C_HUPCL(tty)) | ||
1089 | tty_port_lower_dtr_rts(port); | ||
1090 | } | ||
1087 | mxser_shutdown_port(port); | 1091 | mxser_shutdown_port(port); |
1088 | clear_bit(ASYNCB_INITIALIZED, &port->flags); | 1092 | clear_bit(ASYNCB_INITIALIZED, &port->flags); |
1089 | mutex_unlock(&port->mutex); | 1093 | mutex_unlock(&port->mutex); |
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 4a43ef5d7962..642239015b46 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c | |||
@@ -1418,11 +1418,7 @@ static void gsm_dlci_close(struct gsm_dlci *dlci) | |||
1418 | pr_debug("DLCI %d goes closed.\n", dlci->addr); | 1418 | pr_debug("DLCI %d goes closed.\n", dlci->addr); |
1419 | dlci->state = DLCI_CLOSED; | 1419 | dlci->state = DLCI_CLOSED; |
1420 | if (dlci->addr != 0) { | 1420 | if (dlci->addr != 0) { |
1421 | struct tty_struct *tty = tty_port_tty_get(&dlci->port); | 1421 | tty_port_tty_hangup(&dlci->port, false); |
1422 | if (tty) { | ||
1423 | tty_hangup(tty); | ||
1424 | tty_kref_put(tty); | ||
1425 | } | ||
1426 | kfifo_reset(dlci->fifo); | 1422 | kfifo_reset(dlci->fifo); |
1427 | } else | 1423 | } else |
1428 | dlci->gsm->dead = 1; | 1424 | dlci->gsm->dead = 1; |
@@ -2968,6 +2964,10 @@ static void gsmtty_close(struct tty_struct *tty, struct file *filp) | |||
2968 | if (tty_port_close_start(&dlci->port, tty, filp) == 0) | 2964 | if (tty_port_close_start(&dlci->port, tty, filp) == 0) |
2969 | goto out; | 2965 | goto out; |
2970 | gsm_dlci_begin_close(dlci); | 2966 | gsm_dlci_begin_close(dlci); |
2967 | if (test_bit(ASYNCB_INITIALIZED, &dlci->port.flags)) { | ||
2968 | if (C_HUPCL(tty)) | ||
2969 | tty_port_lower_dtr_rts(&dlci->port); | ||
2970 | } | ||
2971 | tty_port_close_end(&dlci->port, tty); | 2971 | tty_port_close_end(&dlci->port, tty); |
2972 | tty_port_tty_set(&dlci->port, NULL); | 2972 | tty_port_tty_set(&dlci->port, NULL); |
2973 | out: | 2973 | out: |
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 05e72bea9b07..d655416087b7 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c | |||
@@ -153,6 +153,12 @@ static void n_tty_set_room(struct tty_struct *tty) | |||
153 | if (left && !old_left) { | 153 | if (left && !old_left) { |
154 | WARN_RATELIMIT(tty->port->itty == NULL, | 154 | WARN_RATELIMIT(tty->port->itty == NULL, |
155 | "scheduling with invalid itty\n"); | 155 | "scheduling with invalid itty\n"); |
156 | /* see if ldisc has been killed - if so, this means that | ||
157 | * even though the ldisc has been halted and ->buf.work | ||
158 | * cancelled, ->buf.work is about to be rescheduled | ||
159 | */ | ||
160 | WARN_RATELIMIT(test_bit(TTY_LDISC_HALTED, &tty->flags), | ||
161 | "scheduling buffer work for halted ldisc\n"); | ||
156 | schedule_work(&tty->port->buf.work); | 162 | schedule_work(&tty->port->buf.work); |
157 | } | 163 | } |
158 | } | 164 | } |
@@ -189,34 +195,17 @@ static void put_tty_queue(unsigned char c, struct n_tty_data *ldata) | |||
189 | } | 195 | } |
190 | 196 | ||
191 | /** | 197 | /** |
192 | * check_unthrottle - allow new receive data | ||
193 | * @tty; tty device | ||
194 | * | ||
195 | * Check whether to call the driver unthrottle functions | ||
196 | * | ||
197 | * Can sleep, may be called under the atomic_read_lock mutex but | ||
198 | * this is not guaranteed. | ||
199 | */ | ||
200 | static void check_unthrottle(struct tty_struct *tty) | ||
201 | { | ||
202 | if (tty->count) | ||
203 | tty_unthrottle(tty); | ||
204 | } | ||
205 | |||
206 | /** | ||
207 | * reset_buffer_flags - reset buffer state | 198 | * reset_buffer_flags - reset buffer state |
208 | * @tty: terminal to reset | 199 | * @tty: terminal to reset |
209 | * | 200 | * |
210 | * Reset the read buffer counters, clear the flags, | 201 | * Reset the read buffer counters and clear the flags. |
211 | * and make sure the driver is unthrottled. Called | 202 | * Called from n_tty_open() and n_tty_flush_buffer(). |
212 | * from n_tty_open() and n_tty_flush_buffer(). | ||
213 | * | 203 | * |
214 | * Locking: tty_read_lock for read fields. | 204 | * Locking: tty_read_lock for read fields. |
215 | */ | 205 | */ |
216 | 206 | ||
217 | static void reset_buffer_flags(struct tty_struct *tty) | 207 | static void reset_buffer_flags(struct n_tty_data *ldata) |
218 | { | 208 | { |
219 | struct n_tty_data *ldata = tty->disc_data; | ||
220 | unsigned long flags; | 209 | unsigned long flags; |
221 | 210 | ||
222 | raw_spin_lock_irqsave(&ldata->read_lock, flags); | 211 | raw_spin_lock_irqsave(&ldata->read_lock, flags); |
@@ -229,36 +218,38 @@ static void reset_buffer_flags(struct tty_struct *tty) | |||
229 | 218 | ||
230 | ldata->canon_head = ldata->canon_data = ldata->erasing = 0; | 219 | ldata->canon_head = ldata->canon_data = ldata->erasing = 0; |
231 | bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE); | 220 | bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE); |
232 | n_tty_set_room(tty); | 221 | } |
222 | |||
223 | static void n_tty_packet_mode_flush(struct tty_struct *tty) | ||
224 | { | ||
225 | unsigned long flags; | ||
226 | |||
227 | spin_lock_irqsave(&tty->ctrl_lock, flags); | ||
228 | if (tty->link->packet) { | ||
229 | tty->ctrl_status |= TIOCPKT_FLUSHREAD; | ||
230 | wake_up_interruptible(&tty->link->read_wait); | ||
231 | } | ||
232 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | ||
233 | } | 233 | } |
234 | 234 | ||
235 | /** | 235 | /** |
236 | * n_tty_flush_buffer - clean input queue | 236 | * n_tty_flush_buffer - clean input queue |
237 | * @tty: terminal device | 237 | * @tty: terminal device |
238 | * | 238 | * |
239 | * Flush the input buffer. Called when the line discipline is | 239 | * Flush the input buffer. Called when the tty layer wants the |
240 | * being closed, when the tty layer wants the buffer flushed (eg | 240 | * buffer flushed (eg at hangup) or when the N_TTY line discipline |
241 | * at hangup) or when the N_TTY line discipline internally has to | 241 | * internally has to clean the pending queue (for example some signals). |
242 | * clean the pending queue (for example some signals). | ||
243 | * | 242 | * |
244 | * Locking: ctrl_lock, read_lock. | 243 | * Locking: ctrl_lock, read_lock. |
245 | */ | 244 | */ |
246 | 245 | ||
247 | static void n_tty_flush_buffer(struct tty_struct *tty) | 246 | static void n_tty_flush_buffer(struct tty_struct *tty) |
248 | { | 247 | { |
249 | unsigned long flags; | 248 | reset_buffer_flags(tty->disc_data); |
250 | /* clear everything and unthrottle the driver */ | 249 | n_tty_set_room(tty); |
251 | reset_buffer_flags(tty); | ||
252 | |||
253 | if (!tty->link) | ||
254 | return; | ||
255 | 250 | ||
256 | spin_lock_irqsave(&tty->ctrl_lock, flags); | 251 | if (tty->link) |
257 | if (tty->link->packet) { | 252 | n_tty_packet_mode_flush(tty); |
258 | tty->ctrl_status |= TIOCPKT_FLUSHREAD; | ||
259 | wake_up_interruptible(&tty->link->read_wait); | ||
260 | } | ||
261 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | ||
262 | } | 253 | } |
263 | 254 | ||
264 | /** | 255 | /** |
@@ -1032,23 +1023,19 @@ static void eraser(unsigned char c, struct tty_struct *tty) | |||
1032 | * isig - handle the ISIG optio | 1023 | * isig - handle the ISIG optio |
1033 | * @sig: signal | 1024 | * @sig: signal |
1034 | * @tty: terminal | 1025 | * @tty: terminal |
1035 | * @flush: force flush | ||
1036 | * | 1026 | * |
1037 | * Called when a signal is being sent due to terminal input. This | 1027 | * Called when a signal is being sent due to terminal input. |
1038 | * may caus terminal flushing to take place according to the termios | 1028 | * Called from the driver receive_buf path so serialized. |
1039 | * settings and character used. Called from the driver receive_buf | ||
1040 | * path so serialized. | ||
1041 | * | 1029 | * |
1042 | * Locking: ctrl_lock, read_lock (both via flush buffer) | 1030 | * Locking: ctrl_lock |
1043 | */ | 1031 | */ |
1044 | 1032 | ||
1045 | static inline void isig(int sig, struct tty_struct *tty, int flush) | 1033 | static inline void isig(int sig, struct tty_struct *tty) |
1046 | { | 1034 | { |
1047 | if (tty->pgrp) | 1035 | struct pid *tty_pgrp = tty_get_pgrp(tty); |
1048 | kill_pgrp(tty->pgrp, sig, 1); | 1036 | if (tty_pgrp) { |
1049 | if (flush || !L_NOFLSH(tty)) { | 1037 | kill_pgrp(tty_pgrp, sig, 1); |
1050 | n_tty_flush_buffer(tty); | 1038 | put_pid(tty_pgrp); |
1051 | tty_driver_flush_buffer(tty); | ||
1052 | } | 1039 | } |
1053 | } | 1040 | } |
1054 | 1041 | ||
@@ -1069,7 +1056,11 @@ static inline void n_tty_receive_break(struct tty_struct *tty) | |||
1069 | if (I_IGNBRK(tty)) | 1056 | if (I_IGNBRK(tty)) |
1070 | return; | 1057 | return; |
1071 | if (I_BRKINT(tty)) { | 1058 | if (I_BRKINT(tty)) { |
1072 | isig(SIGINT, tty, 1); | 1059 | isig(SIGINT, tty); |
1060 | if (!L_NOFLSH(tty)) { | ||
1061 | n_tty_flush_buffer(tty); | ||
1062 | tty_driver_flush_buffer(tty); | ||
1063 | } | ||
1073 | return; | 1064 | return; |
1074 | } | 1065 | } |
1075 | if (I_PARMRK(tty)) { | 1066 | if (I_PARMRK(tty)) { |
@@ -1236,11 +1227,6 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) | |||
1236 | signal = SIGTSTP; | 1227 | signal = SIGTSTP; |
1237 | if (c == SUSP_CHAR(tty)) { | 1228 | if (c == SUSP_CHAR(tty)) { |
1238 | send_signal: | 1229 | send_signal: |
1239 | /* | ||
1240 | * Note that we do not use isig() here because we want | ||
1241 | * the order to be: | ||
1242 | * 1) flush, 2) echo, 3) signal | ||
1243 | */ | ||
1244 | if (!L_NOFLSH(tty)) { | 1230 | if (!L_NOFLSH(tty)) { |
1245 | n_tty_flush_buffer(tty); | 1231 | n_tty_flush_buffer(tty); |
1246 | tty_driver_flush_buffer(tty); | 1232 | tty_driver_flush_buffer(tty); |
@@ -1251,8 +1237,7 @@ send_signal: | |||
1251 | echo_char(c, tty); | 1237 | echo_char(c, tty); |
1252 | process_echoes(tty); | 1238 | process_echoes(tty); |
1253 | } | 1239 | } |
1254 | if (tty->pgrp) | 1240 | isig(signal, tty); |
1255 | kill_pgrp(tty->pgrp, signal, 1); | ||
1256 | return; | 1241 | return; |
1257 | } | 1242 | } |
1258 | } | 1243 | } |
@@ -1483,14 +1468,14 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
1483 | * mode. We don't want to throttle the driver if we're in | 1468 | * mode. We don't want to throttle the driver if we're in |
1484 | * canonical mode and don't have a newline yet! | 1469 | * canonical mode and don't have a newline yet! |
1485 | */ | 1470 | */ |
1486 | if (tty->receive_room < TTY_THRESHOLD_THROTTLE) | 1471 | while (1) { |
1487 | tty_throttle(tty); | 1472 | tty_set_flow_change(tty, TTY_THROTTLE_SAFE); |
1488 | 1473 | if (tty->receive_room >= TTY_THRESHOLD_THROTTLE) | |
1489 | /* FIXME: there is a tiny race here if the receive room check runs | 1474 | break; |
1490 | before the other work executes and empties the buffer (upping | 1475 | if (!tty_throttle_safe(tty)) |
1491 | the receiving room and unthrottling. We then throttle and get | 1476 | break; |
1492 | stuck. This has been observed and traced down by Vincent Pillet/ | 1477 | } |
1493 | We need to address this when we sort out out the rx path locking */ | 1478 | __tty_set_flow_change(tty, 0); |
1494 | } | 1479 | } |
1495 | 1480 | ||
1496 | int is_ignored(int sig) | 1481 | int is_ignored(int sig) |
@@ -1607,7 +1592,9 @@ static void n_tty_close(struct tty_struct *tty) | |||
1607 | { | 1592 | { |
1608 | struct n_tty_data *ldata = tty->disc_data; | 1593 | struct n_tty_data *ldata = tty->disc_data; |
1609 | 1594 | ||
1610 | n_tty_flush_buffer(tty); | 1595 | if (tty->link) |
1596 | n_tty_packet_mode_flush(tty); | ||
1597 | |||
1611 | kfree(ldata->read_buf); | 1598 | kfree(ldata->read_buf); |
1612 | kfree(ldata->echo_buf); | 1599 | kfree(ldata->echo_buf); |
1613 | kfree(ldata); | 1600 | kfree(ldata); |
@@ -1645,12 +1632,14 @@ static int n_tty_open(struct tty_struct *tty) | |||
1645 | goto err_free_bufs; | 1632 | goto err_free_bufs; |
1646 | 1633 | ||
1647 | tty->disc_data = ldata; | 1634 | tty->disc_data = ldata; |
1648 | reset_buffer_flags(tty); | 1635 | reset_buffer_flags(tty->disc_data); |
1649 | tty_unthrottle(tty); | ||
1650 | ldata->column = 0; | 1636 | ldata->column = 0; |
1651 | n_tty_set_termios(tty, NULL); | ||
1652 | tty->minimum_to_wake = 1; | 1637 | tty->minimum_to_wake = 1; |
1653 | tty->closing = 0; | 1638 | tty->closing = 0; |
1639 | /* indicate buffer work may resume */ | ||
1640 | clear_bit(TTY_LDISC_HALTED, &tty->flags); | ||
1641 | n_tty_set_termios(tty, NULL); | ||
1642 | tty_unthrottle(tty); | ||
1654 | 1643 | ||
1655 | return 0; | 1644 | return 0; |
1656 | err_free_bufs: | 1645 | err_free_bufs: |
@@ -1740,10 +1729,9 @@ extern ssize_t redirected_tty_write(struct file *, const char __user *, | |||
1740 | * and if appropriate send any needed signals and return a negative | 1729 | * and if appropriate send any needed signals and return a negative |
1741 | * error code if action should be taken. | 1730 | * error code if action should be taken. |
1742 | * | 1731 | * |
1743 | * FIXME: | 1732 | * Locking: redirected write test is safe |
1744 | * Locking: None - redirected write test is safe, testing | 1733 | * current->signal->tty check is safe |
1745 | * current->signal should possibly lock current->sighand | 1734 | * ctrl_lock to safely reference tty->pgrp |
1746 | * pgrp locking ? | ||
1747 | */ | 1735 | */ |
1748 | 1736 | ||
1749 | static int job_control(struct tty_struct *tty, struct file *file) | 1737 | static int job_control(struct tty_struct *tty, struct file *file) |
@@ -1753,19 +1741,22 @@ static int job_control(struct tty_struct *tty, struct file *file) | |||
1753 | /* NOTE: not yet done after every sleep pending a thorough | 1741 | /* NOTE: not yet done after every sleep pending a thorough |
1754 | check of the logic of this change. -- jlc */ | 1742 | check of the logic of this change. -- jlc */ |
1755 | /* don't stop on /dev/console */ | 1743 | /* don't stop on /dev/console */ |
1756 | if (file->f_op->write != redirected_tty_write && | 1744 | if (file->f_op->write == redirected_tty_write || |
1757 | current->signal->tty == tty) { | 1745 | current->signal->tty != tty) |
1758 | if (!tty->pgrp) | 1746 | return 0; |
1759 | printk(KERN_ERR "n_tty_read: no tty->pgrp!\n"); | 1747 | |
1760 | else if (task_pgrp(current) != tty->pgrp) { | 1748 | spin_lock_irq(&tty->ctrl_lock); |
1761 | if (is_ignored(SIGTTIN) || | 1749 | if (!tty->pgrp) |
1762 | is_current_pgrp_orphaned()) | 1750 | printk(KERN_ERR "n_tty_read: no tty->pgrp!\n"); |
1763 | return -EIO; | 1751 | else if (task_pgrp(current) != tty->pgrp) { |
1764 | kill_pgrp(task_pgrp(current), SIGTTIN, 1); | 1752 | spin_unlock_irq(&tty->ctrl_lock); |
1765 | set_thread_flag(TIF_SIGPENDING); | 1753 | if (is_ignored(SIGTTIN) || is_current_pgrp_orphaned()) |
1766 | return -ERESTARTSYS; | 1754 | return -EIO; |
1767 | } | 1755 | kill_pgrp(task_pgrp(current), SIGTTIN, 1); |
1756 | set_thread_flag(TIF_SIGPENDING); | ||
1757 | return -ERESTARTSYS; | ||
1768 | } | 1758 | } |
1759 | spin_unlock_irq(&tty->ctrl_lock); | ||
1769 | return 0; | 1760 | return 0; |
1770 | } | 1761 | } |
1771 | 1762 | ||
@@ -1959,10 +1950,17 @@ do_it_again: | |||
1959 | * longer than TTY_THRESHOLD_UNTHROTTLE in canonical mode, | 1950 | * longer than TTY_THRESHOLD_UNTHROTTLE in canonical mode, |
1960 | * we won't get any more characters. | 1951 | * we won't get any more characters. |
1961 | */ | 1952 | */ |
1962 | if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE) { | 1953 | while (1) { |
1954 | tty_set_flow_change(tty, TTY_UNTHROTTLE_SAFE); | ||
1955 | if (n_tty_chars_in_buffer(tty) > TTY_THRESHOLD_UNTHROTTLE) | ||
1956 | break; | ||
1957 | if (!tty->count) | ||
1958 | break; | ||
1963 | n_tty_set_room(tty); | 1959 | n_tty_set_room(tty); |
1964 | check_unthrottle(tty); | 1960 | if (!tty_unthrottle_safe(tty)) |
1961 | break; | ||
1965 | } | 1962 | } |
1963 | __tty_set_flow_change(tty, 0); | ||
1966 | 1964 | ||
1967 | if (b - buf >= minimum) | 1965 | if (b - buf >= minimum) |
1968 | break; | 1966 | break; |
diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index 2dff19796157..d6080c3831ef 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c | |||
@@ -791,7 +791,6 @@ static int send_data(enum port_type index, struct nozomi *dc) | |||
791 | const u8 toggle = port->toggle_ul; | 791 | const u8 toggle = port->toggle_ul; |
792 | void __iomem *addr = port->ul_addr[toggle]; | 792 | void __iomem *addr = port->ul_addr[toggle]; |
793 | const u32 ul_size = port->ul_size[toggle]; | 793 | const u32 ul_size = port->ul_size[toggle]; |
794 | struct tty_struct *tty = tty_port_tty_get(&port->port); | ||
795 | 794 | ||
796 | /* Get data from tty and place in buf for now */ | 795 | /* Get data from tty and place in buf for now */ |
797 | size = kfifo_out(&port->fifo_ul, dc->send_buf, | 796 | size = kfifo_out(&port->fifo_ul, dc->send_buf, |
@@ -799,7 +798,6 @@ static int send_data(enum port_type index, struct nozomi *dc) | |||
799 | 798 | ||
800 | if (size == 0) { | 799 | if (size == 0) { |
801 | DBG4("No more data to send, disable link:"); | 800 | DBG4("No more data to send, disable link:"); |
802 | tty_kref_put(tty); | ||
803 | return 0; | 801 | return 0; |
804 | } | 802 | } |
805 | 803 | ||
@@ -809,10 +807,8 @@ static int send_data(enum port_type index, struct nozomi *dc) | |||
809 | write_mem32(addr, (u32 *) &size, 4); | 807 | write_mem32(addr, (u32 *) &size, 4); |
810 | write_mem32(addr + 4, (u32 *) dc->send_buf, size); | 808 | write_mem32(addr + 4, (u32 *) dc->send_buf, size); |
811 | 809 | ||
812 | if (tty) | 810 | tty_port_tty_wakeup(&port->port); |
813 | tty_wakeup(tty); | ||
814 | 811 | ||
815 | tty_kref_put(tty); | ||
816 | return 1; | 812 | return 1; |
817 | } | 813 | } |
818 | 814 | ||
@@ -1505,12 +1501,9 @@ static void tty_exit(struct nozomi *dc) | |||
1505 | 1501 | ||
1506 | DBG1(" "); | 1502 | DBG1(" "); |
1507 | 1503 | ||
1508 | for (i = 0; i < MAX_PORT; ++i) { | 1504 | for (i = 0; i < MAX_PORT; ++i) |
1509 | struct tty_struct *tty = tty_port_tty_get(&dc->port[i].port); | 1505 | tty_port_tty_hangup(&dc->port[i].port, false); |
1510 | if (tty && list_empty(&tty->hangup_work.entry)) | 1506 | |
1511 | tty_hangup(tty); | ||
1512 | tty_kref_put(tty); | ||
1513 | } | ||
1514 | /* Racy below - surely should wait for scheduled work to be done or | 1507 | /* Racy below - surely should wait for scheduled work to be done or |
1515 | complete off a hangup method ? */ | 1508 | complete off a hangup method ? */ |
1516 | while (dc->open_ttys) | 1509 | while (dc->open_ttys) |
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index c24b4db243b9..a62798fcc014 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c | |||
@@ -405,15 +405,8 @@ err: | |||
405 | return retval; | 405 | return retval; |
406 | } | 406 | } |
407 | 407 | ||
408 | /* this is called once with whichever end is closed last */ | ||
409 | static void pty_unix98_shutdown(struct tty_struct *tty) | ||
410 | { | ||
411 | devpts_kill_index(tty->driver_data, tty->index); | ||
412 | } | ||
413 | |||
414 | static void pty_cleanup(struct tty_struct *tty) | 408 | static void pty_cleanup(struct tty_struct *tty) |
415 | { | 409 | { |
416 | tty->port->itty = NULL; | ||
417 | tty_port_put(tty->port); | 410 | tty_port_put(tty->port); |
418 | } | 411 | } |
419 | 412 | ||
@@ -627,6 +620,12 @@ static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) | |||
627 | { | 620 | { |
628 | } | 621 | } |
629 | 622 | ||
623 | /* this is called once with whichever end is closed last */ | ||
624 | static void pty_unix98_shutdown(struct tty_struct *tty) | ||
625 | { | ||
626 | devpts_kill_index(tty->driver_data, tty->index); | ||
627 | } | ||
628 | |||
630 | static const struct tty_operations ptm_unix98_ops = { | 629 | static const struct tty_operations ptm_unix98_ops = { |
631 | .lookup = ptm_unix98_lookup, | 630 | .lookup = ptm_unix98_lookup, |
632 | .install = pty_unix98_install, | 631 | .install = pty_unix98_install, |
diff --git a/drivers/tty/rocket.c b/drivers/tty/rocket.c index 1d270034bfc3..82d35c5a58fd 100644 --- a/drivers/tty/rocket.c +++ b/drivers/tty/rocket.c | |||
@@ -449,7 +449,7 @@ static void rp_do_transmit(struct r_port *info) | |||
449 | 449 | ||
450 | /* Loop sending data to FIFO until done or FIFO full */ | 450 | /* Loop sending data to FIFO until done or FIFO full */ |
451 | while (1) { | 451 | while (1) { |
452 | if (tty->stopped || tty->hw_stopped) | 452 | if (tty->stopped) |
453 | break; | 453 | break; |
454 | c = min(info->xmit_fifo_room, info->xmit_cnt); | 454 | c = min(info->xmit_fifo_room, info->xmit_cnt); |
455 | c = min(c, XMIT_BUF_SIZE - info->xmit_tail); | 455 | c = min(c, XMIT_BUF_SIZE - info->xmit_tail); |
@@ -521,15 +521,10 @@ static void rp_handle_port(struct r_port *info) | |||
521 | (ChanStatus & CD_ACT) ? "on" : "off"); | 521 | (ChanStatus & CD_ACT) ? "on" : "off"); |
522 | #endif | 522 | #endif |
523 | if (!(ChanStatus & CD_ACT) && info->cd_status) { | 523 | if (!(ChanStatus & CD_ACT) && info->cd_status) { |
524 | struct tty_struct *tty; | ||
525 | #ifdef ROCKET_DEBUG_HANGUP | 524 | #ifdef ROCKET_DEBUG_HANGUP |
526 | printk(KERN_INFO "CD drop, calling hangup.\n"); | 525 | printk(KERN_INFO "CD drop, calling hangup.\n"); |
527 | #endif | 526 | #endif |
528 | tty = tty_port_tty_get(&info->port); | 527 | tty_port_tty_hangup(&info->port, false); |
529 | if (tty) { | ||
530 | tty_hangup(tty); | ||
531 | tty_kref_put(tty); | ||
532 | } | ||
533 | } | 528 | } |
534 | info->cd_status = (ChanStatus & CD_ACT) ? 1 : 0; | 529 | info->cd_status = (ChanStatus & CD_ACT) ? 1 : 0; |
535 | wake_up_interruptible(&info->port.open_wait); | 530 | wake_up_interruptible(&info->port.open_wait); |
@@ -1111,15 +1106,12 @@ static void rp_set_termios(struct tty_struct *tty, | |||
1111 | 1106 | ||
1112 | /* Handle transition away from B0 status */ | 1107 | /* Handle transition away from B0 status */ |
1113 | if (!(old_termios->c_cflag & CBAUD) && (tty->termios.c_cflag & CBAUD)) { | 1108 | if (!(old_termios->c_cflag & CBAUD) && (tty->termios.c_cflag & CBAUD)) { |
1114 | if (!tty->hw_stopped || !(tty->termios.c_cflag & CRTSCTS)) | 1109 | sSetRTS(cp); |
1115 | sSetRTS(cp); | ||
1116 | sSetDTR(cp); | 1110 | sSetDTR(cp); |
1117 | } | 1111 | } |
1118 | 1112 | ||
1119 | if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios.c_cflag & CRTSCTS)) { | 1113 | if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios.c_cflag & CRTSCTS)) |
1120 | tty->hw_stopped = 0; | ||
1121 | rp_start(tty); | 1114 | rp_start(tty); |
1122 | } | ||
1123 | } | 1115 | } |
1124 | 1116 | ||
1125 | static int rp_break(struct tty_struct *tty, int break_state) | 1117 | static int rp_break(struct tty_struct *tty, int break_state) |
@@ -1575,10 +1567,10 @@ static int rp_put_char(struct tty_struct *tty, unsigned char ch) | |||
1575 | spin_lock_irqsave(&info->slock, flags); | 1567 | spin_lock_irqsave(&info->slock, flags); |
1576 | cp = &info->channel; | 1568 | cp = &info->channel; |
1577 | 1569 | ||
1578 | if (!tty->stopped && !tty->hw_stopped && info->xmit_fifo_room == 0) | 1570 | if (!tty->stopped && info->xmit_fifo_room == 0) |
1579 | info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp); | 1571 | info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp); |
1580 | 1572 | ||
1581 | if (tty->stopped || tty->hw_stopped || info->xmit_fifo_room == 0 || info->xmit_cnt != 0) { | 1573 | if (tty->stopped || info->xmit_fifo_room == 0 || info->xmit_cnt != 0) { |
1582 | info->xmit_buf[info->xmit_head++] = ch; | 1574 | info->xmit_buf[info->xmit_head++] = ch; |
1583 | info->xmit_head &= XMIT_BUF_SIZE - 1; | 1575 | info->xmit_head &= XMIT_BUF_SIZE - 1; |
1584 | info->xmit_cnt++; | 1576 | info->xmit_cnt++; |
@@ -1619,14 +1611,14 @@ static int rp_write(struct tty_struct *tty, | |||
1619 | #endif | 1611 | #endif |
1620 | cp = &info->channel; | 1612 | cp = &info->channel; |
1621 | 1613 | ||
1622 | if (!tty->stopped && !tty->hw_stopped && info->xmit_fifo_room < count) | 1614 | if (!tty->stopped && info->xmit_fifo_room < count) |
1623 | info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp); | 1615 | info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp); |
1624 | 1616 | ||
1625 | /* | 1617 | /* |
1626 | * If the write queue for the port is empty, and there is FIFO space, stuff bytes | 1618 | * If the write queue for the port is empty, and there is FIFO space, stuff bytes |
1627 | * into FIFO. Use the write queue for temp storage. | 1619 | * into FIFO. Use the write queue for temp storage. |
1628 | */ | 1620 | */ |
1629 | if (!tty->stopped && !tty->hw_stopped && info->xmit_cnt == 0 && info->xmit_fifo_room > 0) { | 1621 | if (!tty->stopped && info->xmit_cnt == 0 && info->xmit_fifo_room > 0) { |
1630 | c = min(count, info->xmit_fifo_room); | 1622 | c = min(count, info->xmit_fifo_room); |
1631 | b = buf; | 1623 | b = buf; |
1632 | 1624 | ||
@@ -1674,7 +1666,7 @@ static int rp_write(struct tty_struct *tty, | |||
1674 | retval += c; | 1666 | retval += c; |
1675 | } | 1667 | } |
1676 | 1668 | ||
1677 | if ((retval > 0) && !tty->stopped && !tty->hw_stopped) | 1669 | if ((retval > 0) && !tty->stopped) |
1678 | set_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); | 1670 | set_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); |
1679 | 1671 | ||
1680 | end: | 1672 | end: |
@@ -2527,6 +2519,7 @@ static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO, | |||
2527 | return (CtlP->NumAiop); | 2519 | return (CtlP->NumAiop); |
2528 | } | 2520 | } |
2529 | 2521 | ||
2522 | #ifdef CONFIG_PCI | ||
2530 | /*************************************************************************** | 2523 | /*************************************************************************** |
2531 | Function: sPCIInitController | 2524 | Function: sPCIInitController |
2532 | Purpose: Initialization of controller global registers and controller | 2525 | Purpose: Initialization of controller global registers and controller |
@@ -2647,6 +2640,26 @@ static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum, | |||
2647 | return (CtlP->NumAiop); | 2640 | return (CtlP->NumAiop); |
2648 | } | 2641 | } |
2649 | 2642 | ||
2643 | /* Resets the speaker controller on RocketModem II and III devices */ | ||
2644 | static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model) | ||
2645 | { | ||
2646 | ByteIO_t addr; | ||
2647 | |||
2648 | /* RocketModem II speaker control is at the 8th port location of offset 0x40 */ | ||
2649 | if ((model == MODEL_RP4M) || (model == MODEL_RP6M)) { | ||
2650 | addr = CtlP->AiopIO[0] + 0x4F; | ||
2651 | sOutB(addr, 0); | ||
2652 | } | ||
2653 | |||
2654 | /* RocketModem III speaker control is at the 1st port location of offset 0x80 */ | ||
2655 | if ((model == MODEL_UPCI_RM3_8PORT) | ||
2656 | || (model == MODEL_UPCI_RM3_4PORT)) { | ||
2657 | addr = CtlP->AiopIO[0] + 0x88; | ||
2658 | sOutB(addr, 0); | ||
2659 | } | ||
2660 | } | ||
2661 | #endif | ||
2662 | |||
2650 | /*************************************************************************** | 2663 | /*************************************************************************** |
2651 | Function: sReadAiopID | 2664 | Function: sReadAiopID |
2652 | Purpose: Read the AIOP idenfication number directly from an AIOP. | 2665 | Purpose: Read the AIOP idenfication number directly from an AIOP. |
@@ -3136,25 +3149,6 @@ static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on) | |||
3136 | sOutB(addr + chan, 0); /* apply or remove reset */ | 3149 | sOutB(addr + chan, 0); /* apply or remove reset */ |
3137 | } | 3150 | } |
3138 | 3151 | ||
3139 | /* Resets the speaker controller on RocketModem II and III devices */ | ||
3140 | static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model) | ||
3141 | { | ||
3142 | ByteIO_t addr; | ||
3143 | |||
3144 | /* RocketModem II speaker control is at the 8th port location of offset 0x40 */ | ||
3145 | if ((model == MODEL_RP4M) || (model == MODEL_RP6M)) { | ||
3146 | addr = CtlP->AiopIO[0] + 0x4F; | ||
3147 | sOutB(addr, 0); | ||
3148 | } | ||
3149 | |||
3150 | /* RocketModem III speaker control is at the 1st port location of offset 0x80 */ | ||
3151 | if ((model == MODEL_UPCI_RM3_8PORT) | ||
3152 | || (model == MODEL_UPCI_RM3_4PORT)) { | ||
3153 | addr = CtlP->AiopIO[0] + 0x88; | ||
3154 | sOutB(addr, 0); | ||
3155 | } | ||
3156 | } | ||
3157 | |||
3158 | /* Returns the line number given the controller (board), aiop and channel number */ | 3152 | /* Returns the line number given the controller (board), aiop and channel number */ |
3159 | static unsigned char GetLineNumber(int ctrl, int aiop, int ch) | 3153 | static unsigned char GetLineNumber(int ctrl, int aiop, int ch) |
3160 | { | 3154 | { |
diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c index 49399470794d..ef2e08e9b590 100644 --- a/drivers/tty/serial/68328serial.c +++ b/drivers/tty/serial/68328serial.c | |||
@@ -630,8 +630,7 @@ static void rs_flush_chars(struct tty_struct *tty) | |||
630 | /* Enable transmitter */ | 630 | /* Enable transmitter */ |
631 | local_irq_save(flags); | 631 | local_irq_save(flags); |
632 | 632 | ||
633 | if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || | 633 | if (info->xmit_cnt <= 0 || tty->stopped || !info->xmit_buf) { |
634 | !info->xmit_buf) { | ||
635 | local_irq_restore(flags); | 634 | local_irq_restore(flags); |
636 | return; | 635 | return; |
637 | } | 636 | } |
@@ -697,7 +696,7 @@ static int rs_write(struct tty_struct * tty, | |||
697 | total += c; | 696 | total += c; |
698 | } | 697 | } |
699 | 698 | ||
700 | if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) { | 699 | if (info->xmit_cnt && !tty->stopped) { |
701 | /* Enable transmitter */ | 700 | /* Enable transmitter */ |
702 | local_irq_disable(); | 701 | local_irq_disable(); |
703 | #ifndef USE_INTS | 702 | #ifndef USE_INTS |
@@ -978,10 +977,8 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
978 | change_speed(info, tty); | 977 | change_speed(info, tty); |
979 | 978 | ||
980 | if ((old_termios->c_cflag & CRTSCTS) && | 979 | if ((old_termios->c_cflag & CRTSCTS) && |
981 | !(tty->termios.c_cflag & CRTSCTS)) { | 980 | !(tty->termios.c_cflag & CRTSCTS)) |
982 | tty->hw_stopped = 0; | ||
983 | rs_start(tty); | 981 | rs_start(tty); |
984 | } | ||
985 | 982 | ||
986 | } | 983 | } |
987 | 984 | ||
diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h index 34eb676916fe..1ebf8538b4fa 100644 --- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h | |||
@@ -117,13 +117,6 @@ static inline void serial_dl_write(struct uart_8250_port *up, int value) | |||
117 | * is cleared, the machine locks up with endless interrupts. | 117 | * is cleared, the machine locks up with endless interrupts. |
118 | */ | 118 | */ |
119 | #define ALPHA_KLUDGE_MCR (UART_MCR_OUT2 | UART_MCR_OUT1) | 119 | #define ALPHA_KLUDGE_MCR (UART_MCR_OUT2 | UART_MCR_OUT1) |
120 | #elif defined(CONFIG_SBC8560) | ||
121 | /* | ||
122 | * WindRiver did something similarly broken on their SBC8560 board. The | ||
123 | * UART tristates its IRQ output while OUT2 is clear, but they pulled | ||
124 | * the interrupt line _up_ instead of down, so if we register the IRQ | ||
125 | * while the UART is in that state, we die in an IRQ storm. */ | ||
126 | #define ALPHA_KLUDGE_MCR (UART_MCR_OUT2) | ||
127 | #else | 120 | #else |
128 | #define ALPHA_KLUDGE_MCR 0 | 121 | #define ALPHA_KLUDGE_MCR 0 |
129 | #endif | 122 | #endif |
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 35f9c96aada9..46528d57be72 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c | |||
@@ -2755,7 +2755,7 @@ static void __init serial8250_isa_init_ports(void) | |||
2755 | if (nr_uarts > UART_NR) | 2755 | if (nr_uarts > UART_NR) |
2756 | nr_uarts = UART_NR; | 2756 | nr_uarts = UART_NR; |
2757 | 2757 | ||
2758 | for (i = 0; i < nr_uarts; i++) { | 2758 | for (i = 0; i < UART_NR; i++) { |
2759 | struct uart_8250_port *up = &serial8250_ports[i]; | 2759 | struct uart_8250_port *up = &serial8250_ports[i]; |
2760 | struct uart_port *port = &up->port; | 2760 | struct uart_port *port = &up->port; |
2761 | 2761 | ||
@@ -2916,7 +2916,7 @@ static int __init serial8250_console_setup(struct console *co, char *options) | |||
2916 | * if so, search for the first available port that does have | 2916 | * if so, search for the first available port that does have |
2917 | * console support. | 2917 | * console support. |
2918 | */ | 2918 | */ |
2919 | if (co->index >= nr_uarts) | 2919 | if (co->index >= UART_NR) |
2920 | co->index = 0; | 2920 | co->index = 0; |
2921 | port = &serial8250_ports[co->index].port; | 2921 | port = &serial8250_ports[co->index].port; |
2922 | if (!port->iobase && !port->membase) | 2922 | if (!port->iobase && !port->membase) |
@@ -2957,7 +2957,7 @@ int serial8250_find_port(struct uart_port *p) | |||
2957 | int line; | 2957 | int line; |
2958 | struct uart_port *port; | 2958 | struct uart_port *port; |
2959 | 2959 | ||
2960 | for (line = 0; line < nr_uarts; line++) { | 2960 | for (line = 0; line < UART_NR; line++) { |
2961 | port = &serial8250_ports[line].port; | 2961 | port = &serial8250_ports[line].port; |
2962 | if (uart_match_port(p, port)) | 2962 | if (uart_match_port(p, port)) |
2963 | return line; | 2963 | return line; |
@@ -3110,7 +3110,7 @@ static int serial8250_remove(struct platform_device *dev) | |||
3110 | { | 3110 | { |
3111 | int i; | 3111 | int i; |
3112 | 3112 | ||
3113 | for (i = 0; i < nr_uarts; i++) { | 3113 | for (i = 0; i < UART_NR; i++) { |
3114 | struct uart_8250_port *up = &serial8250_ports[i]; | 3114 | struct uart_8250_port *up = &serial8250_ports[i]; |
3115 | 3115 | ||
3116 | if (up->port.dev == &dev->dev) | 3116 | if (up->port.dev == &dev->dev) |
@@ -3178,7 +3178,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port * | |||
3178 | /* | 3178 | /* |
3179 | * First, find a port entry which matches. | 3179 | * First, find a port entry which matches. |
3180 | */ | 3180 | */ |
3181 | for (i = 0; i < nr_uarts; i++) | 3181 | for (i = 0; i < UART_NR; i++) |
3182 | if (uart_match_port(&serial8250_ports[i].port, port)) | 3182 | if (uart_match_port(&serial8250_ports[i].port, port)) |
3183 | return &serial8250_ports[i]; | 3183 | return &serial8250_ports[i]; |
3184 | 3184 | ||
@@ -3187,7 +3187,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port * | |||
3187 | * free entry. We look for one which hasn't been previously | 3187 | * free entry. We look for one which hasn't been previously |
3188 | * used (indicated by zero iobase). | 3188 | * used (indicated by zero iobase). |
3189 | */ | 3189 | */ |
3190 | for (i = 0; i < nr_uarts; i++) | 3190 | for (i = 0; i < UART_NR; i++) |
3191 | if (serial8250_ports[i].port.type == PORT_UNKNOWN && | 3191 | if (serial8250_ports[i].port.type == PORT_UNKNOWN && |
3192 | serial8250_ports[i].port.iobase == 0) | 3192 | serial8250_ports[i].port.iobase == 0) |
3193 | return &serial8250_ports[i]; | 3193 | return &serial8250_ports[i]; |
@@ -3196,7 +3196,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port * | |||
3196 | * That also failed. Last resort is to find any entry which | 3196 | * That also failed. Last resort is to find any entry which |
3197 | * doesn't have a real port associated with it. | 3197 | * doesn't have a real port associated with it. |
3198 | */ | 3198 | */ |
3199 | for (i = 0; i < nr_uarts; i++) | 3199 | for (i = 0; i < UART_NR; i++) |
3200 | if (serial8250_ports[i].port.type == PORT_UNKNOWN) | 3200 | if (serial8250_ports[i].port.type == PORT_UNKNOWN) |
3201 | return &serial8250_ports[i]; | 3201 | return &serial8250_ports[i]; |
3202 | 3202 | ||
@@ -3247,6 +3247,10 @@ int serial8250_register_8250_port(struct uart_8250_port *up) | |||
3247 | uart->tx_loadsz = up->tx_loadsz; | 3247 | uart->tx_loadsz = up->tx_loadsz; |
3248 | uart->capabilities = up->capabilities; | 3248 | uart->capabilities = up->capabilities; |
3249 | 3249 | ||
3250 | /* Take tx_loadsz from fifosize if it wasn't set separately */ | ||
3251 | if (uart->port.fifosize && !uart->tx_loadsz) | ||
3252 | uart->tx_loadsz = uart->port.fifosize; | ||
3253 | |||
3250 | if (up->port.dev) | 3254 | if (up->port.dev) |
3251 | uart->port.dev = up->port.dev; | 3255 | uart->port.dev = up->port.dev; |
3252 | 3256 | ||
diff --git a/drivers/tty/serial/8250/8250_dma.c b/drivers/tty/serial/8250/8250_dma.c index b9f7fd28112e..7046769608d4 100644 --- a/drivers/tty/serial/8250/8250_dma.c +++ b/drivers/tty/serial/8250/8250_dma.c | |||
@@ -33,10 +33,8 @@ static void __dma_tx_complete(void *param) | |||
33 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 33 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
34 | uart_write_wakeup(&p->port); | 34 | uart_write_wakeup(&p->port); |
35 | 35 | ||
36 | if (!uart_circ_empty(xmit) && !uart_tx_stopped(&p->port)) { | 36 | if (!uart_circ_empty(xmit) && !uart_tx_stopped(&p->port)) |
37 | serial8250_tx_dma(p); | 37 | serial8250_tx_dma(p); |
38 | uart_write_wakeup(&p->port); | ||
39 | } | ||
40 | } | 38 | } |
41 | 39 | ||
42 | static void __dma_rx_complete(void *param) | 40 | static void __dma_rx_complete(void *param) |
@@ -67,12 +65,11 @@ int serial8250_tx_dma(struct uart_8250_port *p) | |||
67 | struct circ_buf *xmit = &p->port.state->xmit; | 65 | struct circ_buf *xmit = &p->port.state->xmit; |
68 | struct dma_async_tx_descriptor *desc; | 66 | struct dma_async_tx_descriptor *desc; |
69 | 67 | ||
70 | if (dma->tx_running) | 68 | if (uart_tx_stopped(&p->port) || dma->tx_running || |
71 | return -EBUSY; | 69 | uart_circ_empty(xmit)) |
70 | return 0; | ||
72 | 71 | ||
73 | dma->tx_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); | 72 | dma->tx_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); |
74 | if (!dma->tx_size) | ||
75 | return -EINVAL; | ||
76 | 73 | ||
77 | desc = dmaengine_prep_slave_single(dma->txchan, | 74 | desc = dmaengine_prep_slave_single(dma->txchan, |
78 | dma->tx_addr + xmit->tail, | 75 | dma->tx_addr + xmit->tail, |
@@ -104,20 +101,29 @@ int serial8250_rx_dma(struct uart_8250_port *p, unsigned int iir) | |||
104 | struct dma_tx_state state; | 101 | struct dma_tx_state state; |
105 | int dma_status; | 102 | int dma_status; |
106 | 103 | ||
107 | /* | 104 | dma_status = dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); |
108 | * If RCVR FIFO trigger level was not reached, complete the transfer and | 105 | |
109 | * let 8250.c copy the remaining data. | 106 | switch (iir & 0x3f) { |
110 | */ | 107 | case UART_IIR_RLSI: |
111 | if ((iir & 0x3f) == UART_IIR_RX_TIMEOUT) { | 108 | /* 8250_core handles errors and break interrupts */ |
112 | dma_status = dmaengine_tx_status(dma->rxchan, dma->rx_cookie, | 109 | return -EIO; |
113 | &state); | 110 | case UART_IIR_RX_TIMEOUT: |
111 | /* | ||
112 | * If RCVR FIFO trigger level was not reached, complete the | ||
113 | * transfer and let 8250_core copy the remaining data. | ||
114 | */ | ||
114 | if (dma_status == DMA_IN_PROGRESS) { | 115 | if (dma_status == DMA_IN_PROGRESS) { |
115 | dmaengine_pause(dma->rxchan); | 116 | dmaengine_pause(dma->rxchan); |
116 | __dma_rx_complete(p); | 117 | __dma_rx_complete(p); |
117 | } | 118 | } |
118 | return -ETIMEDOUT; | 119 | return -ETIMEDOUT; |
120 | default: | ||
121 | break; | ||
119 | } | 122 | } |
120 | 123 | ||
124 | if (dma_status) | ||
125 | return 0; | ||
126 | |||
121 | desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr, | 127 | desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr, |
122 | dma->rx_size, DMA_DEV_TO_MEM, | 128 | dma->rx_size, DMA_DEV_TO_MEM, |
123 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 129 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
@@ -143,21 +149,31 @@ int serial8250_request_dma(struct uart_8250_port *p) | |||
143 | struct uart_8250_dma *dma = p->dma; | 149 | struct uart_8250_dma *dma = p->dma; |
144 | dma_cap_mask_t mask; | 150 | dma_cap_mask_t mask; |
145 | 151 | ||
146 | dma->rxconf.src_addr = p->port.mapbase + UART_RX; | 152 | /* Default slave configuration parameters */ |
147 | dma->txconf.dst_addr = p->port.mapbase + UART_TX; | 153 | dma->rxconf.direction = DMA_DEV_TO_MEM; |
154 | dma->rxconf.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||
155 | dma->rxconf.src_addr = p->port.mapbase + UART_RX; | ||
156 | |||
157 | dma->txconf.direction = DMA_MEM_TO_DEV; | ||
158 | dma->txconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||
159 | dma->txconf.dst_addr = p->port.mapbase + UART_TX; | ||
148 | 160 | ||
149 | dma_cap_zero(mask); | 161 | dma_cap_zero(mask); |
150 | dma_cap_set(DMA_SLAVE, mask); | 162 | dma_cap_set(DMA_SLAVE, mask); |
151 | 163 | ||
152 | /* Get a channel for RX */ | 164 | /* Get a channel for RX */ |
153 | dma->rxchan = dma_request_channel(mask, dma->fn, dma->rx_param); | 165 | dma->rxchan = dma_request_slave_channel_compat(mask, |
166 | dma->fn, dma->rx_param, | ||
167 | p->port.dev, "rx"); | ||
154 | if (!dma->rxchan) | 168 | if (!dma->rxchan) |
155 | return -ENODEV; | 169 | return -ENODEV; |
156 | 170 | ||
157 | dmaengine_slave_config(dma->rxchan, &dma->rxconf); | 171 | dmaengine_slave_config(dma->rxchan, &dma->rxconf); |
158 | 172 | ||
159 | /* Get a channel for TX */ | 173 | /* Get a channel for TX */ |
160 | dma->txchan = dma_request_channel(mask, dma->fn, dma->tx_param); | 174 | dma->txchan = dma_request_slave_channel_compat(mask, |
175 | dma->fn, dma->tx_param, | ||
176 | p->port.dev, "tx"); | ||
161 | if (!dma->txchan) { | 177 | if (!dma->txchan) { |
162 | dma_release_channel(dma->rxchan); | 178 | dma_release_channel(dma->rxchan); |
163 | return -ENODEV; | 179 | return -ENODEV; |
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index db0e66f6dd0e..beaa283f5cc6 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c | |||
@@ -26,6 +26,8 @@ | |||
26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/acpi.h> | 28 | #include <linux/acpi.h> |
29 | #include <linux/clk.h> | ||
30 | #include <linux/pm_runtime.h> | ||
29 | 31 | ||
30 | #include "8250.h" | 32 | #include "8250.h" |
31 | 33 | ||
@@ -34,9 +36,6 @@ | |||
34 | #define DW_UART_CPR 0xf4 /* Component Parameter Register */ | 36 | #define DW_UART_CPR 0xf4 /* Component Parameter Register */ |
35 | #define DW_UART_UCV 0xf8 /* UART Component Version */ | 37 | #define DW_UART_UCV 0xf8 /* UART Component Version */ |
36 | 38 | ||
37 | /* Intel Low Power Subsystem specific */ | ||
38 | #define LPSS_PRV_CLOCK_PARAMS 0x800 | ||
39 | |||
40 | /* Component Parameter Register bits */ | 39 | /* Component Parameter Register bits */ |
41 | #define DW_UART_CPR_ABP_DATA_WIDTH (3 << 0) | 40 | #define DW_UART_CPR_ABP_DATA_WIDTH (3 << 0) |
42 | #define DW_UART_CPR_AFCE_MODE (1 << 4) | 41 | #define DW_UART_CPR_AFCE_MODE (1 << 4) |
@@ -55,8 +54,9 @@ | |||
55 | 54 | ||
56 | 55 | ||
57 | struct dw8250_data { | 56 | struct dw8250_data { |
58 | int last_lcr; | 57 | int last_lcr; |
59 | int line; | 58 | int line; |
59 | struct clk *clk; | ||
60 | }; | 60 | }; |
61 | 61 | ||
62 | static void dw8250_serial_out(struct uart_port *p, int offset, int value) | 62 | static void dw8250_serial_out(struct uart_port *p, int offset, int value) |
@@ -113,6 +113,18 @@ static int dw8250_handle_irq(struct uart_port *p) | |||
113 | return 0; | 113 | return 0; |
114 | } | 114 | } |
115 | 115 | ||
116 | static void | ||
117 | dw8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old) | ||
118 | { | ||
119 | if (!state) | ||
120 | pm_runtime_get_sync(port->dev); | ||
121 | |||
122 | serial8250_do_pm(port, state, old); | ||
123 | |||
124 | if (state) | ||
125 | pm_runtime_put_sync_suspend(port->dev); | ||
126 | } | ||
127 | |||
116 | static int dw8250_probe_of(struct uart_port *p) | 128 | static int dw8250_probe_of(struct uart_port *p) |
117 | { | 129 | { |
118 | struct device_node *np = p->dev->of_node; | 130 | struct device_node *np = p->dev->of_node; |
@@ -136,8 +148,13 @@ static int dw8250_probe_of(struct uart_port *p) | |||
136 | if (!of_property_read_u32(np, "reg-shift", &val)) | 148 | if (!of_property_read_u32(np, "reg-shift", &val)) |
137 | p->regshift = val; | 149 | p->regshift = val; |
138 | 150 | ||
151 | /* clock got configured through clk api, all done */ | ||
152 | if (p->uartclk) | ||
153 | return 0; | ||
154 | |||
155 | /* try to find out clock frequency from DT as fallback */ | ||
139 | if (of_property_read_u32(np, "clock-frequency", &val)) { | 156 | if (of_property_read_u32(np, "clock-frequency", &val)) { |
140 | dev_err(p->dev, "no clock-frequency property set\n"); | 157 | dev_err(p->dev, "clk or clock-frequency not defined\n"); |
141 | return -EINVAL; | 158 | return -EINVAL; |
142 | } | 159 | } |
143 | p->uartclk = val; | 160 | p->uartclk = val; |
@@ -146,67 +163,10 @@ static int dw8250_probe_of(struct uart_port *p) | |||
146 | } | 163 | } |
147 | 164 | ||
148 | #ifdef CONFIG_ACPI | 165 | #ifdef CONFIG_ACPI |
149 | static bool dw8250_acpi_dma_filter(struct dma_chan *chan, void *parm) | 166 | static int dw8250_probe_acpi(struct uart_8250_port *up) |
150 | { | ||
151 | return chan->chan_id == *(int *)parm; | ||
152 | } | ||
153 | |||
154 | static acpi_status | ||
155 | dw8250_acpi_walk_resource(struct acpi_resource *res, void *data) | ||
156 | { | ||
157 | struct uart_port *p = data; | ||
158 | struct uart_8250_port *port; | ||
159 | struct uart_8250_dma *dma; | ||
160 | struct acpi_resource_fixed_dma *fixed_dma; | ||
161 | struct dma_slave_config *slave; | ||
162 | |||
163 | port = container_of(p, struct uart_8250_port, port); | ||
164 | |||
165 | switch (res->type) { | ||
166 | case ACPI_RESOURCE_TYPE_FIXED_DMA: | ||
167 | fixed_dma = &res->data.fixed_dma; | ||
168 | |||
169 | /* TX comes first */ | ||
170 | if (!port->dma) { | ||
171 | dma = devm_kzalloc(p->dev, sizeof(*dma), GFP_KERNEL); | ||
172 | if (!dma) | ||
173 | return AE_NO_MEMORY; | ||
174 | |||
175 | port->dma = dma; | ||
176 | slave = &dma->txconf; | ||
177 | |||
178 | slave->direction = DMA_MEM_TO_DEV; | ||
179 | slave->dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||
180 | slave->slave_id = fixed_dma->request_lines; | ||
181 | slave->dst_maxburst = port->tx_loadsz / 4; | ||
182 | |||
183 | dma->tx_chan_id = fixed_dma->channels; | ||
184 | dma->tx_param = &dma->tx_chan_id; | ||
185 | dma->fn = dw8250_acpi_dma_filter; | ||
186 | } else { | ||
187 | dma = port->dma; | ||
188 | slave = &dma->rxconf; | ||
189 | |||
190 | slave->direction = DMA_DEV_TO_MEM; | ||
191 | slave->src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||
192 | slave->slave_id = fixed_dma->request_lines; | ||
193 | slave->src_maxburst = p->fifosize / 4; | ||
194 | |||
195 | dma->rx_chan_id = fixed_dma->channels; | ||
196 | dma->rx_param = &dma->rx_chan_id; | ||
197 | } | ||
198 | |||
199 | break; | ||
200 | } | ||
201 | |||
202 | return AE_OK; | ||
203 | } | ||
204 | |||
205 | static int dw8250_probe_acpi(struct uart_port *p) | ||
206 | { | 167 | { |
207 | const struct acpi_device_id *id; | 168 | const struct acpi_device_id *id; |
208 | acpi_status status; | 169 | struct uart_port *p = &up->port; |
209 | u32 reg; | ||
210 | 170 | ||
211 | id = acpi_match_device(p->dev->driver->acpi_match_table, p->dev); | 171 | id = acpi_match_device(p->dev->driver->acpi_match_table, p->dev); |
212 | if (!id) | 172 | if (!id) |
@@ -216,26 +176,21 @@ static int dw8250_probe_acpi(struct uart_port *p) | |||
216 | p->serial_in = dw8250_serial_in32; | 176 | p->serial_in = dw8250_serial_in32; |
217 | p->serial_out = dw8250_serial_out32; | 177 | p->serial_out = dw8250_serial_out32; |
218 | p->regshift = 2; | 178 | p->regshift = 2; |
219 | p->uartclk = (unsigned int)id->driver_data; | ||
220 | 179 | ||
221 | status = acpi_walk_resources(ACPI_HANDLE(p->dev), METHOD_NAME__CRS, | 180 | if (!p->uartclk) |
222 | dw8250_acpi_walk_resource, p); | 181 | p->uartclk = (unsigned int)id->driver_data; |
223 | if (ACPI_FAILURE(status)) { | ||
224 | dev_err_ratelimited(p->dev, "%s failed \"%s\"\n", __func__, | ||
225 | acpi_format_exception(status)); | ||
226 | return -ENODEV; | ||
227 | } | ||
228 | 182 | ||
229 | /* Fix Haswell issue where the clocks do not get enabled */ | 183 | up->dma = devm_kzalloc(p->dev, sizeof(*up->dma), GFP_KERNEL); |
230 | if (!strcmp(id->id, "INT33C4") || !strcmp(id->id, "INT33C5")) { | 184 | if (!up->dma) |
231 | reg = readl(p->membase + LPSS_PRV_CLOCK_PARAMS); | 185 | return -ENOMEM; |
232 | writel(reg | 1, p->membase + LPSS_PRV_CLOCK_PARAMS); | 186 | |
233 | } | 187 | up->dma->rxconf.src_maxburst = p->fifosize / 4; |
188 | up->dma->txconf.dst_maxburst = p->fifosize / 4; | ||
234 | 189 | ||
235 | return 0; | 190 | return 0; |
236 | } | 191 | } |
237 | #else | 192 | #else |
238 | static inline int dw8250_probe_acpi(struct uart_port *p) | 193 | static inline int dw8250_probe_acpi(struct uart_8250_port *up) |
239 | { | 194 | { |
240 | return -ENODEV; | 195 | return -ENODEV; |
241 | } | 196 | } |
@@ -266,7 +221,11 @@ static void dw8250_setup_port(struct uart_8250_port *up) | |||
266 | p->flags |= UPF_FIXED_TYPE; | 221 | p->flags |= UPF_FIXED_TYPE; |
267 | p->fifosize = DW_UART_CPR_FIFO_SIZE(reg); | 222 | p->fifosize = DW_UART_CPR_FIFO_SIZE(reg); |
268 | up->tx_loadsz = p->fifosize; | 223 | up->tx_loadsz = p->fifosize; |
224 | up->capabilities = UART_CAP_FIFO; | ||
269 | } | 225 | } |
226 | |||
227 | if (reg & DW_UART_CPR_AFCE_MODE) | ||
228 | up->capabilities |= UART_CAP_AFE; | ||
270 | } | 229 | } |
271 | 230 | ||
272 | static int dw8250_probe(struct platform_device *pdev) | 231 | static int dw8250_probe(struct platform_device *pdev) |
@@ -286,17 +245,30 @@ static int dw8250_probe(struct platform_device *pdev) | |||
286 | uart.port.mapbase = regs->start; | 245 | uart.port.mapbase = regs->start; |
287 | uart.port.irq = irq->start; | 246 | uart.port.irq = irq->start; |
288 | uart.port.handle_irq = dw8250_handle_irq; | 247 | uart.port.handle_irq = dw8250_handle_irq; |
248 | uart.port.pm = dw8250_do_pm; | ||
289 | uart.port.type = PORT_8250; | 249 | uart.port.type = PORT_8250; |
290 | uart.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_FIXED_PORT; | 250 | uart.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_FIXED_PORT; |
291 | uart.port.dev = &pdev->dev; | 251 | uart.port.dev = &pdev->dev; |
292 | 252 | ||
293 | uart.port.membase = ioremap(regs->start, resource_size(regs)); | 253 | uart.port.membase = devm_ioremap(&pdev->dev, regs->start, |
254 | resource_size(regs)); | ||
294 | if (!uart.port.membase) | 255 | if (!uart.port.membase) |
295 | return -ENOMEM; | 256 | return -ENOMEM; |
296 | 257 | ||
258 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); | ||
259 | if (!data) | ||
260 | return -ENOMEM; | ||
261 | |||
262 | data->clk = devm_clk_get(&pdev->dev, NULL); | ||
263 | if (!IS_ERR(data->clk)) { | ||
264 | clk_prepare_enable(data->clk); | ||
265 | uart.port.uartclk = clk_get_rate(data->clk); | ||
266 | } | ||
267 | |||
297 | uart.port.iotype = UPIO_MEM; | 268 | uart.port.iotype = UPIO_MEM; |
298 | uart.port.serial_in = dw8250_serial_in; | 269 | uart.port.serial_in = dw8250_serial_in; |
299 | uart.port.serial_out = dw8250_serial_out; | 270 | uart.port.serial_out = dw8250_serial_out; |
271 | uart.port.private_data = data; | ||
300 | 272 | ||
301 | dw8250_setup_port(&uart); | 273 | dw8250_setup_port(&uart); |
302 | 274 | ||
@@ -305,25 +277,22 @@ static int dw8250_probe(struct platform_device *pdev) | |||
305 | if (err) | 277 | if (err) |
306 | return err; | 278 | return err; |
307 | } else if (ACPI_HANDLE(&pdev->dev)) { | 279 | } else if (ACPI_HANDLE(&pdev->dev)) { |
308 | err = dw8250_probe_acpi(&uart.port); | 280 | err = dw8250_probe_acpi(&uart); |
309 | if (err) | 281 | if (err) |
310 | return err; | 282 | return err; |
311 | } else { | 283 | } else { |
312 | return -ENODEV; | 284 | return -ENODEV; |
313 | } | 285 | } |
314 | 286 | ||
315 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); | ||
316 | if (!data) | ||
317 | return -ENOMEM; | ||
318 | |||
319 | uart.port.private_data = data; | ||
320 | |||
321 | data->line = serial8250_register_8250_port(&uart); | 287 | data->line = serial8250_register_8250_port(&uart); |
322 | if (data->line < 0) | 288 | if (data->line < 0) |
323 | return data->line; | 289 | return data->line; |
324 | 290 | ||
325 | platform_set_drvdata(pdev, data); | 291 | platform_set_drvdata(pdev, data); |
326 | 292 | ||
293 | pm_runtime_set_active(&pdev->dev); | ||
294 | pm_runtime_enable(&pdev->dev); | ||
295 | |||
327 | return 0; | 296 | return 0; |
328 | } | 297 | } |
329 | 298 | ||
@@ -331,34 +300,64 @@ static int dw8250_remove(struct platform_device *pdev) | |||
331 | { | 300 | { |
332 | struct dw8250_data *data = platform_get_drvdata(pdev); | 301 | struct dw8250_data *data = platform_get_drvdata(pdev); |
333 | 302 | ||
303 | pm_runtime_get_sync(&pdev->dev); | ||
304 | |||
334 | serial8250_unregister_port(data->line); | 305 | serial8250_unregister_port(data->line); |
335 | 306 | ||
307 | if (!IS_ERR(data->clk)) | ||
308 | clk_disable_unprepare(data->clk); | ||
309 | |||
310 | pm_runtime_disable(&pdev->dev); | ||
311 | pm_runtime_put_noidle(&pdev->dev); | ||
312 | |||
336 | return 0; | 313 | return 0; |
337 | } | 314 | } |
338 | 315 | ||
339 | #ifdef CONFIG_PM | 316 | #ifdef CONFIG_PM |
340 | static int dw8250_suspend(struct platform_device *pdev, pm_message_t state) | 317 | static int dw8250_suspend(struct device *dev) |
341 | { | 318 | { |
342 | struct dw8250_data *data = platform_get_drvdata(pdev); | 319 | struct dw8250_data *data = dev_get_drvdata(dev); |
343 | 320 | ||
344 | serial8250_suspend_port(data->line); | 321 | serial8250_suspend_port(data->line); |
345 | 322 | ||
346 | return 0; | 323 | return 0; |
347 | } | 324 | } |
348 | 325 | ||
349 | static int dw8250_resume(struct platform_device *pdev) | 326 | static int dw8250_resume(struct device *dev) |
350 | { | 327 | { |
351 | struct dw8250_data *data = platform_get_drvdata(pdev); | 328 | struct dw8250_data *data = dev_get_drvdata(dev); |
352 | 329 | ||
353 | serial8250_resume_port(data->line); | 330 | serial8250_resume_port(data->line); |
354 | 331 | ||
355 | return 0; | 332 | return 0; |
356 | } | 333 | } |
357 | #else | ||
358 | #define dw8250_suspend NULL | ||
359 | #define dw8250_resume NULL | ||
360 | #endif /* CONFIG_PM */ | 334 | #endif /* CONFIG_PM */ |
361 | 335 | ||
336 | #ifdef CONFIG_PM_RUNTIME | ||
337 | static int dw8250_runtime_suspend(struct device *dev) | ||
338 | { | ||
339 | struct dw8250_data *data = dev_get_drvdata(dev); | ||
340 | |||
341 | clk_disable_unprepare(data->clk); | ||
342 | |||
343 | return 0; | ||
344 | } | ||
345 | |||
346 | static int dw8250_runtime_resume(struct device *dev) | ||
347 | { | ||
348 | struct dw8250_data *data = dev_get_drvdata(dev); | ||
349 | |||
350 | clk_prepare_enable(data->clk); | ||
351 | |||
352 | return 0; | ||
353 | } | ||
354 | #endif | ||
355 | |||
356 | static const struct dev_pm_ops dw8250_pm_ops = { | ||
357 | SET_SYSTEM_SLEEP_PM_OPS(dw8250_suspend, dw8250_resume) | ||
358 | SET_RUNTIME_PM_OPS(dw8250_runtime_suspend, dw8250_runtime_resume, NULL) | ||
359 | }; | ||
360 | |||
362 | static const struct of_device_id dw8250_of_match[] = { | 361 | static const struct of_device_id dw8250_of_match[] = { |
363 | { .compatible = "snps,dw-apb-uart" }, | 362 | { .compatible = "snps,dw-apb-uart" }, |
364 | { /* Sentinel */ } | 363 | { /* Sentinel */ } |
@@ -366,8 +365,8 @@ static const struct of_device_id dw8250_of_match[] = { | |||
366 | MODULE_DEVICE_TABLE(of, dw8250_of_match); | 365 | MODULE_DEVICE_TABLE(of, dw8250_of_match); |
367 | 366 | ||
368 | static const struct acpi_device_id dw8250_acpi_match[] = { | 367 | static const struct acpi_device_id dw8250_acpi_match[] = { |
369 | { "INT33C4", 100000000 }, | 368 | { "INT33C4", 0 }, |
370 | { "INT33C5", 100000000 }, | 369 | { "INT33C5", 0 }, |
371 | { }, | 370 | { }, |
372 | }; | 371 | }; |
373 | MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match); | 372 | MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match); |
@@ -376,13 +375,12 @@ static struct platform_driver dw8250_platform_driver = { | |||
376 | .driver = { | 375 | .driver = { |
377 | .name = "dw-apb-uart", | 376 | .name = "dw-apb-uart", |
378 | .owner = THIS_MODULE, | 377 | .owner = THIS_MODULE, |
378 | .pm = &dw8250_pm_ops, | ||
379 | .of_match_table = dw8250_of_match, | 379 | .of_match_table = dw8250_of_match, |
380 | .acpi_match_table = ACPI_PTR(dw8250_acpi_match), | 380 | .acpi_match_table = ACPI_PTR(dw8250_acpi_match), |
381 | }, | 381 | }, |
382 | .probe = dw8250_probe, | 382 | .probe = dw8250_probe, |
383 | .remove = dw8250_remove, | 383 | .remove = dw8250_remove, |
384 | .suspend = dw8250_suspend, | ||
385 | .resume = dw8250_resume, | ||
386 | }; | 384 | }; |
387 | 385 | ||
388 | module_platform_driver(dw8250_platform_driver); | 386 | module_platform_driver(dw8250_platform_driver); |
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 3ea5408fcbeb..b2e9e177a354 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c | |||
@@ -29,6 +29,7 @@ | |||
29 | * and hooked into this driver. | 29 | * and hooked into this driver. |
30 | */ | 30 | */ |
31 | 31 | ||
32 | |||
32 | #if defined(CONFIG_SERIAL_AMBA_PL011_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | 33 | #if defined(CONFIG_SERIAL_AMBA_PL011_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) |
33 | #define SUPPORT_SYSRQ | 34 | #define SUPPORT_SYSRQ |
34 | #endif | 35 | #endif |
@@ -72,32 +73,44 @@ | |||
72 | /* There is by now at least one vendor with differing details, so handle it */ | 73 | /* There is by now at least one vendor with differing details, so handle it */ |
73 | struct vendor_data { | 74 | struct vendor_data { |
74 | unsigned int ifls; | 75 | unsigned int ifls; |
75 | unsigned int fifosize; | ||
76 | unsigned int lcrh_tx; | 76 | unsigned int lcrh_tx; |
77 | unsigned int lcrh_rx; | 77 | unsigned int lcrh_rx; |
78 | bool oversampling; | 78 | bool oversampling; |
79 | bool dma_threshold; | 79 | bool dma_threshold; |
80 | bool cts_event_workaround; | 80 | bool cts_event_workaround; |
81 | |||
82 | unsigned int (*get_fifosize)(unsigned int periphid); | ||
81 | }; | 83 | }; |
82 | 84 | ||
85 | static unsigned int get_fifosize_arm(unsigned int periphid) | ||
86 | { | ||
87 | unsigned int rev = (periphid >> 20) & 0xf; | ||
88 | return rev < 3 ? 16 : 32; | ||
89 | } | ||
90 | |||
83 | static struct vendor_data vendor_arm = { | 91 | static struct vendor_data vendor_arm = { |
84 | .ifls = UART011_IFLS_RX4_8|UART011_IFLS_TX4_8, | 92 | .ifls = UART011_IFLS_RX4_8|UART011_IFLS_TX4_8, |
85 | .fifosize = 16, | ||
86 | .lcrh_tx = UART011_LCRH, | 93 | .lcrh_tx = UART011_LCRH, |
87 | .lcrh_rx = UART011_LCRH, | 94 | .lcrh_rx = UART011_LCRH, |
88 | .oversampling = false, | 95 | .oversampling = false, |
89 | .dma_threshold = false, | 96 | .dma_threshold = false, |
90 | .cts_event_workaround = false, | 97 | .cts_event_workaround = false, |
98 | .get_fifosize = get_fifosize_arm, | ||
91 | }; | 99 | }; |
92 | 100 | ||
101 | static unsigned int get_fifosize_st(unsigned int periphid) | ||
102 | { | ||
103 | return 64; | ||
104 | } | ||
105 | |||
93 | static struct vendor_data vendor_st = { | 106 | static struct vendor_data vendor_st = { |
94 | .ifls = UART011_IFLS_RX_HALF|UART011_IFLS_TX_HALF, | 107 | .ifls = UART011_IFLS_RX_HALF|UART011_IFLS_TX_HALF, |
95 | .fifosize = 64, | ||
96 | .lcrh_tx = ST_UART011_LCRH_TX, | 108 | .lcrh_tx = ST_UART011_LCRH_TX, |
97 | .lcrh_rx = ST_UART011_LCRH_RX, | 109 | .lcrh_rx = ST_UART011_LCRH_RX, |
98 | .oversampling = true, | 110 | .oversampling = true, |
99 | .dma_threshold = true, | 111 | .dma_threshold = true, |
100 | .cts_event_workaround = true, | 112 | .cts_event_workaround = true, |
113 | .get_fifosize = get_fifosize_st, | ||
101 | }; | 114 | }; |
102 | 115 | ||
103 | static struct uart_amba_port *amba_ports[UART_NR]; | 116 | static struct uart_amba_port *amba_ports[UART_NR]; |
@@ -117,6 +130,12 @@ struct pl011_dmarx_data { | |||
117 | struct pl011_sgbuf sgbuf_b; | 130 | struct pl011_sgbuf sgbuf_b; |
118 | dma_cookie_t cookie; | 131 | dma_cookie_t cookie; |
119 | bool running; | 132 | bool running; |
133 | struct timer_list timer; | ||
134 | unsigned int last_residue; | ||
135 | unsigned long last_jiffies; | ||
136 | bool auto_poll_rate; | ||
137 | unsigned int poll_rate; | ||
138 | unsigned int poll_timeout; | ||
120 | }; | 139 | }; |
121 | 140 | ||
122 | struct pl011_dmatx_data { | 141 | struct pl011_dmatx_data { |
@@ -223,16 +242,18 @@ static int pl011_fifo_to_tty(struct uart_amba_port *uap) | |||
223 | static int pl011_sgbuf_init(struct dma_chan *chan, struct pl011_sgbuf *sg, | 242 | static int pl011_sgbuf_init(struct dma_chan *chan, struct pl011_sgbuf *sg, |
224 | enum dma_data_direction dir) | 243 | enum dma_data_direction dir) |
225 | { | 244 | { |
226 | sg->buf = kmalloc(PL011_DMA_BUFFER_SIZE, GFP_KERNEL); | 245 | dma_addr_t dma_addr; |
246 | |||
247 | sg->buf = dma_alloc_coherent(chan->device->dev, | ||
248 | PL011_DMA_BUFFER_SIZE, &dma_addr, GFP_KERNEL); | ||
227 | if (!sg->buf) | 249 | if (!sg->buf) |
228 | return -ENOMEM; | 250 | return -ENOMEM; |
229 | 251 | ||
230 | sg_init_one(&sg->sg, sg->buf, PL011_DMA_BUFFER_SIZE); | 252 | sg_init_table(&sg->sg, 1); |
253 | sg_set_page(&sg->sg, phys_to_page(dma_addr), | ||
254 | PL011_DMA_BUFFER_SIZE, offset_in_page(dma_addr)); | ||
255 | sg_dma_address(&sg->sg) = dma_addr; | ||
231 | 256 | ||
232 | if (dma_map_sg(chan->device->dev, &sg->sg, 1, dir) != 1) { | ||
233 | kfree(sg->buf); | ||
234 | return -EINVAL; | ||
235 | } | ||
236 | return 0; | 257 | return 0; |
237 | } | 258 | } |
238 | 259 | ||
@@ -240,8 +261,9 @@ static void pl011_sgbuf_free(struct dma_chan *chan, struct pl011_sgbuf *sg, | |||
240 | enum dma_data_direction dir) | 261 | enum dma_data_direction dir) |
241 | { | 262 | { |
242 | if (sg->buf) { | 263 | if (sg->buf) { |
243 | dma_unmap_sg(chan->device->dev, &sg->sg, 1, dir); | 264 | dma_free_coherent(chan->device->dev, |
244 | kfree(sg->buf); | 265 | PL011_DMA_BUFFER_SIZE, sg->buf, |
266 | sg_dma_address(&sg->sg)); | ||
245 | } | 267 | } |
246 | } | 268 | } |
247 | 269 | ||
@@ -300,6 +322,29 @@ static void pl011_dma_probe_initcall(struct uart_amba_port *uap) | |||
300 | dmaengine_slave_config(chan, &rx_conf); | 322 | dmaengine_slave_config(chan, &rx_conf); |
301 | uap->dmarx.chan = chan; | 323 | uap->dmarx.chan = chan; |
302 | 324 | ||
325 | if (plat->dma_rx_poll_enable) { | ||
326 | /* Set poll rate if specified. */ | ||
327 | if (plat->dma_rx_poll_rate) { | ||
328 | uap->dmarx.auto_poll_rate = false; | ||
329 | uap->dmarx.poll_rate = plat->dma_rx_poll_rate; | ||
330 | } else { | ||
331 | /* | ||
332 | * 100 ms defaults to poll rate if not | ||
333 | * specified. This will be adjusted with | ||
334 | * the baud rate at set_termios. | ||
335 | */ | ||
336 | uap->dmarx.auto_poll_rate = true; | ||
337 | uap->dmarx.poll_rate = 100; | ||
338 | } | ||
339 | /* 3 secs defaults poll_timeout if not specified. */ | ||
340 | if (plat->dma_rx_poll_timeout) | ||
341 | uap->dmarx.poll_timeout = | ||
342 | plat->dma_rx_poll_timeout; | ||
343 | else | ||
344 | uap->dmarx.poll_timeout = 3000; | ||
345 | } else | ||
346 | uap->dmarx.auto_poll_rate = false; | ||
347 | |||
303 | dev_info(uap->port.dev, "DMA channel RX %s\n", | 348 | dev_info(uap->port.dev, "DMA channel RX %s\n", |
304 | dma_chan_name(uap->dmarx.chan)); | 349 | dma_chan_name(uap->dmarx.chan)); |
305 | } | 350 | } |
@@ -701,24 +746,30 @@ static void pl011_dma_rx_chars(struct uart_amba_port *uap, | |||
701 | struct tty_port *port = &uap->port.state->port; | 746 | struct tty_port *port = &uap->port.state->port; |
702 | struct pl011_sgbuf *sgbuf = use_buf_b ? | 747 | struct pl011_sgbuf *sgbuf = use_buf_b ? |
703 | &uap->dmarx.sgbuf_b : &uap->dmarx.sgbuf_a; | 748 | &uap->dmarx.sgbuf_b : &uap->dmarx.sgbuf_a; |
704 | struct device *dev = uap->dmarx.chan->device->dev; | ||
705 | int dma_count = 0; | 749 | int dma_count = 0; |
706 | u32 fifotaken = 0; /* only used for vdbg() */ | 750 | u32 fifotaken = 0; /* only used for vdbg() */ |
707 | 751 | ||
708 | /* Pick everything from the DMA first */ | 752 | struct pl011_dmarx_data *dmarx = &uap->dmarx; |
753 | int dmataken = 0; | ||
754 | |||
755 | if (uap->dmarx.poll_rate) { | ||
756 | /* The data can be taken by polling */ | ||
757 | dmataken = sgbuf->sg.length - dmarx->last_residue; | ||
758 | /* Recalculate the pending size */ | ||
759 | if (pending >= dmataken) | ||
760 | pending -= dmataken; | ||
761 | } | ||
762 | |||
763 | /* Pick the remain data from the DMA */ | ||
709 | if (pending) { | 764 | if (pending) { |
710 | /* Sync in buffer */ | ||
711 | dma_sync_sg_for_cpu(dev, &sgbuf->sg, 1, DMA_FROM_DEVICE); | ||
712 | 765 | ||
713 | /* | 766 | /* |
714 | * First take all chars in the DMA pipe, then look in the FIFO. | 767 | * First take all chars in the DMA pipe, then look in the FIFO. |
715 | * Note that tty_insert_flip_buf() tries to take as many chars | 768 | * Note that tty_insert_flip_buf() tries to take as many chars |
716 | * as it can. | 769 | * as it can. |
717 | */ | 770 | */ |
718 | dma_count = tty_insert_flip_string(port, sgbuf->buf, pending); | 771 | dma_count = tty_insert_flip_string(port, sgbuf->buf + dmataken, |
719 | 772 | pending); | |
720 | /* Return buffer to device */ | ||
721 | dma_sync_sg_for_device(dev, &sgbuf->sg, 1, DMA_FROM_DEVICE); | ||
722 | 773 | ||
723 | uap->port.icount.rx += dma_count; | 774 | uap->port.icount.rx += dma_count; |
724 | if (dma_count < pending) | 775 | if (dma_count < pending) |
@@ -726,6 +777,10 @@ static void pl011_dma_rx_chars(struct uart_amba_port *uap, | |||
726 | "couldn't insert all characters (TTY is full?)\n"); | 777 | "couldn't insert all characters (TTY is full?)\n"); |
727 | } | 778 | } |
728 | 779 | ||
780 | /* Reset the last_residue for Rx DMA poll */ | ||
781 | if (uap->dmarx.poll_rate) | ||
782 | dmarx->last_residue = sgbuf->sg.length; | ||
783 | |||
729 | /* | 784 | /* |
730 | * Only continue with trying to read the FIFO if all DMA chars have | 785 | * Only continue with trying to read the FIFO if all DMA chars have |
731 | * been taken first. | 786 | * been taken first. |
@@ -865,6 +920,57 @@ static inline void pl011_dma_rx_stop(struct uart_amba_port *uap) | |||
865 | writew(uap->dmacr, uap->port.membase + UART011_DMACR); | 920 | writew(uap->dmacr, uap->port.membase + UART011_DMACR); |
866 | } | 921 | } |
867 | 922 | ||
923 | /* | ||
924 | * Timer handler for Rx DMA polling. | ||
925 | * Every polling, It checks the residue in the dma buffer and transfer | ||
926 | * data to the tty. Also, last_residue is updated for the next polling. | ||
927 | */ | ||
928 | static void pl011_dma_rx_poll(unsigned long args) | ||
929 | { | ||
930 | struct uart_amba_port *uap = (struct uart_amba_port *)args; | ||
931 | struct tty_port *port = &uap->port.state->port; | ||
932 | struct pl011_dmarx_data *dmarx = &uap->dmarx; | ||
933 | struct dma_chan *rxchan = uap->dmarx.chan; | ||
934 | unsigned long flags = 0; | ||
935 | unsigned int dmataken = 0; | ||
936 | unsigned int size = 0; | ||
937 | struct pl011_sgbuf *sgbuf; | ||
938 | int dma_count; | ||
939 | struct dma_tx_state state; | ||
940 | |||
941 | sgbuf = dmarx->use_buf_b ? &uap->dmarx.sgbuf_b : &uap->dmarx.sgbuf_a; | ||
942 | rxchan->device->device_tx_status(rxchan, dmarx->cookie, &state); | ||
943 | if (likely(state.residue < dmarx->last_residue)) { | ||
944 | dmataken = sgbuf->sg.length - dmarx->last_residue; | ||
945 | size = dmarx->last_residue - state.residue; | ||
946 | dma_count = tty_insert_flip_string(port, sgbuf->buf + dmataken, | ||
947 | size); | ||
948 | if (dma_count == size) | ||
949 | dmarx->last_residue = state.residue; | ||
950 | dmarx->last_jiffies = jiffies; | ||
951 | } | ||
952 | tty_flip_buffer_push(port); | ||
953 | |||
954 | /* | ||
955 | * If no data is received in poll_timeout, the driver will fall back | ||
956 | * to interrupt mode. We will retrigger DMA at the first interrupt. | ||
957 | */ | ||
958 | if (jiffies_to_msecs(jiffies - dmarx->last_jiffies) | ||
959 | > uap->dmarx.poll_timeout) { | ||
960 | |||
961 | spin_lock_irqsave(&uap->port.lock, flags); | ||
962 | pl011_dma_rx_stop(uap); | ||
963 | spin_unlock_irqrestore(&uap->port.lock, flags); | ||
964 | |||
965 | uap->dmarx.running = false; | ||
966 | dmaengine_terminate_all(rxchan); | ||
967 | del_timer(&uap->dmarx.timer); | ||
968 | } else { | ||
969 | mod_timer(&uap->dmarx.timer, | ||
970 | jiffies + msecs_to_jiffies(uap->dmarx.poll_rate)); | ||
971 | } | ||
972 | } | ||
973 | |||
868 | static void pl011_dma_startup(struct uart_amba_port *uap) | 974 | static void pl011_dma_startup(struct uart_amba_port *uap) |
869 | { | 975 | { |
870 | int ret; | 976 | int ret; |
@@ -927,6 +1033,16 @@ skip_rx: | |||
927 | if (pl011_dma_rx_trigger_dma(uap)) | 1033 | if (pl011_dma_rx_trigger_dma(uap)) |
928 | dev_dbg(uap->port.dev, "could not trigger initial " | 1034 | dev_dbg(uap->port.dev, "could not trigger initial " |
929 | "RX DMA job, fall back to interrupt mode\n"); | 1035 | "RX DMA job, fall back to interrupt mode\n"); |
1036 | if (uap->dmarx.poll_rate) { | ||
1037 | init_timer(&(uap->dmarx.timer)); | ||
1038 | uap->dmarx.timer.function = pl011_dma_rx_poll; | ||
1039 | uap->dmarx.timer.data = (unsigned long)uap; | ||
1040 | mod_timer(&uap->dmarx.timer, | ||
1041 | jiffies + | ||
1042 | msecs_to_jiffies(uap->dmarx.poll_rate)); | ||
1043 | uap->dmarx.last_residue = PL011_DMA_BUFFER_SIZE; | ||
1044 | uap->dmarx.last_jiffies = jiffies; | ||
1045 | } | ||
930 | } | 1046 | } |
931 | } | 1047 | } |
932 | 1048 | ||
@@ -962,6 +1078,8 @@ static void pl011_dma_shutdown(struct uart_amba_port *uap) | |||
962 | /* Clean up the RX DMA */ | 1078 | /* Clean up the RX DMA */ |
963 | pl011_sgbuf_free(uap->dmarx.chan, &uap->dmarx.sgbuf_a, DMA_FROM_DEVICE); | 1079 | pl011_sgbuf_free(uap->dmarx.chan, &uap->dmarx.sgbuf_a, DMA_FROM_DEVICE); |
964 | pl011_sgbuf_free(uap->dmarx.chan, &uap->dmarx.sgbuf_b, DMA_FROM_DEVICE); | 1080 | pl011_sgbuf_free(uap->dmarx.chan, &uap->dmarx.sgbuf_b, DMA_FROM_DEVICE); |
1081 | if (uap->dmarx.poll_rate) | ||
1082 | del_timer_sync(&uap->dmarx.timer); | ||
965 | uap->using_rx_dma = false; | 1083 | uap->using_rx_dma = false; |
966 | } | 1084 | } |
967 | } | 1085 | } |
@@ -976,7 +1094,6 @@ static inline bool pl011_dma_rx_running(struct uart_amba_port *uap) | |||
976 | return uap->using_rx_dma && uap->dmarx.running; | 1094 | return uap->using_rx_dma && uap->dmarx.running; |
977 | } | 1095 | } |
978 | 1096 | ||
979 | |||
980 | #else | 1097 | #else |
981 | /* Blank functions if the DMA engine is not available */ | 1098 | /* Blank functions if the DMA engine is not available */ |
982 | static inline void pl011_dma_probe(struct uart_amba_port *uap) | 1099 | static inline void pl011_dma_probe(struct uart_amba_port *uap) |
@@ -1088,8 +1205,20 @@ static void pl011_rx_chars(struct uart_amba_port *uap) | |||
1088 | dev_dbg(uap->port.dev, "could not trigger RX DMA job " | 1205 | dev_dbg(uap->port.dev, "could not trigger RX DMA job " |
1089 | "fall back to interrupt mode again\n"); | 1206 | "fall back to interrupt mode again\n"); |
1090 | uap->im |= UART011_RXIM; | 1207 | uap->im |= UART011_RXIM; |
1091 | } else | 1208 | } else { |
1092 | uap->im &= ~UART011_RXIM; | 1209 | uap->im &= ~UART011_RXIM; |
1210 | #ifdef CONFIG_DMA_ENGINE | ||
1211 | /* Start Rx DMA poll */ | ||
1212 | if (uap->dmarx.poll_rate) { | ||
1213 | uap->dmarx.last_jiffies = jiffies; | ||
1214 | uap->dmarx.last_residue = PL011_DMA_BUFFER_SIZE; | ||
1215 | mod_timer(&uap->dmarx.timer, | ||
1216 | jiffies + | ||
1217 | msecs_to_jiffies(uap->dmarx.poll_rate)); | ||
1218 | } | ||
1219 | #endif | ||
1220 | } | ||
1221 | |||
1093 | writew(uap->im, uap->port.membase + UART011_IMSC); | 1222 | writew(uap->im, uap->port.membase + UART011_IMSC); |
1094 | } | 1223 | } |
1095 | spin_lock(&uap->port.lock); | 1224 | spin_lock(&uap->port.lock); |
@@ -1164,7 +1293,6 @@ static irqreturn_t pl011_int(int irq, void *dev_id) | |||
1164 | unsigned int dummy_read; | 1293 | unsigned int dummy_read; |
1165 | 1294 | ||
1166 | spin_lock_irqsave(&uap->port.lock, flags); | 1295 | spin_lock_irqsave(&uap->port.lock, flags); |
1167 | |||
1168 | status = readw(uap->port.membase + UART011_MIS); | 1296 | status = readw(uap->port.membase + UART011_MIS); |
1169 | if (status) { | 1297 | if (status) { |
1170 | do { | 1298 | do { |
@@ -1551,6 +1679,13 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1551 | */ | 1679 | */ |
1552 | baud = uart_get_baud_rate(port, termios, old, 0, | 1680 | baud = uart_get_baud_rate(port, termios, old, 0, |
1553 | port->uartclk / clkdiv); | 1681 | port->uartclk / clkdiv); |
1682 | #ifdef CONFIG_DMA_ENGINE | ||
1683 | /* | ||
1684 | * Adjust RX DMA polling rate with baud rate if not specified. | ||
1685 | */ | ||
1686 | if (uap->dmarx.auto_poll_rate) | ||
1687 | uap->dmarx.poll_rate = DIV_ROUND_UP(10000000, baud); | ||
1688 | #endif | ||
1554 | 1689 | ||
1555 | if (baud > port->uartclk/16) | 1690 | if (baud > port->uartclk/16) |
1556 | quot = DIV_ROUND_CLOSEST(port->uartclk * 8, baud); | 1691 | quot = DIV_ROUND_CLOSEST(port->uartclk * 8, baud); |
@@ -2010,7 +2145,7 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) | |||
2010 | uap->lcrh_rx = vendor->lcrh_rx; | 2145 | uap->lcrh_rx = vendor->lcrh_rx; |
2011 | uap->lcrh_tx = vendor->lcrh_tx; | 2146 | uap->lcrh_tx = vendor->lcrh_tx; |
2012 | uap->old_cr = 0; | 2147 | uap->old_cr = 0; |
2013 | uap->fifosize = vendor->fifosize; | 2148 | uap->fifosize = vendor->get_fifosize(dev->periphid); |
2014 | uap->port.dev = &dev->dev; | 2149 | uap->port.dev = &dev->dev; |
2015 | uap->port.mapbase = dev->res.start; | 2150 | uap->port.mapbase = dev->res.start; |
2016 | uap->port.membase = base; | 2151 | uap->port.membase = base; |
diff --git a/drivers/tty/serial/arc_uart.c b/drivers/tty/serial/arc_uart.c index d97e194b6bc5..cbf1d155b7b2 100644 --- a/drivers/tty/serial/arc_uart.c +++ b/drivers/tty/serial/arc_uart.c | |||
@@ -162,7 +162,7 @@ static unsigned int arc_serial_tx_empty(struct uart_port *port) | |||
162 | /* | 162 | /* |
163 | * Driver internal routine, used by both tty(serial core) as well as tx-isr | 163 | * Driver internal routine, used by both tty(serial core) as well as tx-isr |
164 | * -Called under spinlock in either cases | 164 | * -Called under spinlock in either cases |
165 | * -also tty->stopped / tty->hw_stopped has already been checked | 165 | * -also tty->stopped has already been checked |
166 | * = by uart_start( ) before calling us | 166 | * = by uart_start( ) before calling us |
167 | * = tx_ist checks that too before calling | 167 | * = tx_ist checks that too before calling |
168 | */ | 168 | */ |
diff --git a/drivers/tty/serial/bfin_uart.c b/drivers/tty/serial/bfin_uart.c index 12dceda9db33..26a3be7ced7d 100644 --- a/drivers/tty/serial/bfin_uart.c +++ b/drivers/tty/serial/bfin_uart.c | |||
@@ -1011,24 +1011,6 @@ static int bfin_serial_poll_get_char(struct uart_port *port) | |||
1011 | } | 1011 | } |
1012 | #endif | 1012 | #endif |
1013 | 1013 | ||
1014 | #if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \ | ||
1015 | defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE) | ||
1016 | static void bfin_kgdboc_port_shutdown(struct uart_port *port) | ||
1017 | { | ||
1018 | if (kgdboc_break_enabled) { | ||
1019 | kgdboc_break_enabled = 0; | ||
1020 | bfin_serial_shutdown(port); | ||
1021 | } | ||
1022 | } | ||
1023 | |||
1024 | static int bfin_kgdboc_port_startup(struct uart_port *port) | ||
1025 | { | ||
1026 | kgdboc_port_line = port->line; | ||
1027 | kgdboc_break_enabled = !bfin_serial_startup(port); | ||
1028 | return 0; | ||
1029 | } | ||
1030 | #endif | ||
1031 | |||
1032 | static struct uart_ops bfin_serial_pops = { | 1014 | static struct uart_ops bfin_serial_pops = { |
1033 | .tx_empty = bfin_serial_tx_empty, | 1015 | .tx_empty = bfin_serial_tx_empty, |
1034 | .set_mctrl = bfin_serial_set_mctrl, | 1016 | .set_mctrl = bfin_serial_set_mctrl, |
@@ -1047,11 +1029,6 @@ static struct uart_ops bfin_serial_pops = { | |||
1047 | .request_port = bfin_serial_request_port, | 1029 | .request_port = bfin_serial_request_port, |
1048 | .config_port = bfin_serial_config_port, | 1030 | .config_port = bfin_serial_config_port, |
1049 | .verify_port = bfin_serial_verify_port, | 1031 | .verify_port = bfin_serial_verify_port, |
1050 | #if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \ | ||
1051 | defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE) | ||
1052 | .kgdboc_port_startup = bfin_kgdboc_port_startup, | ||
1053 | .kgdboc_port_shutdown = bfin_kgdboc_port_shutdown, | ||
1054 | #endif | ||
1055 | #ifdef CONFIG_CONSOLE_POLL | 1032 | #ifdef CONFIG_CONSOLE_POLL |
1056 | .poll_put_char = bfin_serial_poll_put_char, | 1033 | .poll_put_char = bfin_serial_poll_put_char, |
1057 | .poll_get_char = bfin_serial_poll_get_char, | 1034 | .poll_get_char = bfin_serial_poll_get_char, |
diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c index 5f37c31e32bc..477f22f773fc 100644 --- a/drivers/tty/serial/crisv10.c +++ b/drivers/tty/serial/crisv10.c | |||
@@ -169,7 +169,6 @@ static int get_lsr_info(struct e100_serial *info, unsigned int *value); | |||
169 | 169 | ||
170 | 170 | ||
171 | #define DEF_BAUD 115200 /* 115.2 kbit/s */ | 171 | #define DEF_BAUD 115200 /* 115.2 kbit/s */ |
172 | #define STD_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) | ||
173 | #define DEF_RX 0x20 /* or SERIAL_CTRL_W >> 8 */ | 172 | #define DEF_RX 0x20 /* or SERIAL_CTRL_W >> 8 */ |
174 | /* Default value of tx_ctrl register: has txd(bit 7)=1 (idle) as default */ | 173 | /* Default value of tx_ctrl register: has txd(bit 7)=1 (idle) as default */ |
175 | #define DEF_TX 0x80 /* or SERIAL_CTRL_B */ | 174 | #define DEF_TX 0x80 /* or SERIAL_CTRL_B */ |
@@ -246,7 +245,6 @@ static struct e100_serial rs_table[] = { | |||
246 | .ifirstadr = R_DMA_CH7_FIRST, | 245 | .ifirstadr = R_DMA_CH7_FIRST, |
247 | .icmdadr = R_DMA_CH7_CMD, | 246 | .icmdadr = R_DMA_CH7_CMD, |
248 | .idescradr = R_DMA_CH7_DESCR, | 247 | .idescradr = R_DMA_CH7_DESCR, |
249 | .flags = STD_FLAGS, | ||
250 | .rx_ctrl = DEF_RX, | 248 | .rx_ctrl = DEF_RX, |
251 | .tx_ctrl = DEF_TX, | 249 | .tx_ctrl = DEF_TX, |
252 | .iseteop = 2, | 250 | .iseteop = 2, |
@@ -300,7 +298,6 @@ static struct e100_serial rs_table[] = { | |||
300 | .ifirstadr = R_DMA_CH9_FIRST, | 298 | .ifirstadr = R_DMA_CH9_FIRST, |
301 | .icmdadr = R_DMA_CH9_CMD, | 299 | .icmdadr = R_DMA_CH9_CMD, |
302 | .idescradr = R_DMA_CH9_DESCR, | 300 | .idescradr = R_DMA_CH9_DESCR, |
303 | .flags = STD_FLAGS, | ||
304 | .rx_ctrl = DEF_RX, | 301 | .rx_ctrl = DEF_RX, |
305 | .tx_ctrl = DEF_TX, | 302 | .tx_ctrl = DEF_TX, |
306 | .iseteop = 3, | 303 | .iseteop = 3, |
@@ -356,7 +353,6 @@ static struct e100_serial rs_table[] = { | |||
356 | .ifirstadr = R_DMA_CH3_FIRST, | 353 | .ifirstadr = R_DMA_CH3_FIRST, |
357 | .icmdadr = R_DMA_CH3_CMD, | 354 | .icmdadr = R_DMA_CH3_CMD, |
358 | .idescradr = R_DMA_CH3_DESCR, | 355 | .idescradr = R_DMA_CH3_DESCR, |
359 | .flags = STD_FLAGS, | ||
360 | .rx_ctrl = DEF_RX, | 356 | .rx_ctrl = DEF_RX, |
361 | .tx_ctrl = DEF_TX, | 357 | .tx_ctrl = DEF_TX, |
362 | .iseteop = 0, | 358 | .iseteop = 0, |
@@ -410,7 +406,6 @@ static struct e100_serial rs_table[] = { | |||
410 | .ifirstadr = R_DMA_CH5_FIRST, | 406 | .ifirstadr = R_DMA_CH5_FIRST, |
411 | .icmdadr = R_DMA_CH5_CMD, | 407 | .icmdadr = R_DMA_CH5_CMD, |
412 | .idescradr = R_DMA_CH5_DESCR, | 408 | .idescradr = R_DMA_CH5_DESCR, |
413 | .flags = STD_FLAGS, | ||
414 | .rx_ctrl = DEF_RX, | 409 | .rx_ctrl = DEF_RX, |
415 | .tx_ctrl = DEF_TX, | 410 | .tx_ctrl = DEF_TX, |
416 | .iseteop = 1, | 411 | .iseteop = 1, |
@@ -2263,8 +2258,7 @@ TODO: The break will be delayed until an F or V character is received. | |||
2263 | 2258 | ||
2264 | */ | 2259 | */ |
2265 | 2260 | ||
2266 | static | 2261 | static void handle_ser_rx_interrupt_no_dma(struct e100_serial *info) |
2267 | struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info) | ||
2268 | { | 2262 | { |
2269 | unsigned long data_read; | 2263 | unsigned long data_read; |
2270 | 2264 | ||
@@ -2370,10 +2364,9 @@ more_data: | |||
2370 | } | 2364 | } |
2371 | 2365 | ||
2372 | tty_flip_buffer_push(&info->port); | 2366 | tty_flip_buffer_push(&info->port); |
2373 | return info; | ||
2374 | } | 2367 | } |
2375 | 2368 | ||
2376 | static struct e100_serial* handle_ser_rx_interrupt(struct e100_serial *info) | 2369 | static void handle_ser_rx_interrupt(struct e100_serial *info) |
2377 | { | 2370 | { |
2378 | unsigned char rstat; | 2371 | unsigned char rstat; |
2379 | 2372 | ||
@@ -2382,7 +2375,8 @@ static struct e100_serial* handle_ser_rx_interrupt(struct e100_serial *info) | |||
2382 | #endif | 2375 | #endif |
2383 | /* DEBUG_LOG(info->line, "ser_interrupt stat %03X\n", rstat | (i << 8)); */ | 2376 | /* DEBUG_LOG(info->line, "ser_interrupt stat %03X\n", rstat | (i << 8)); */ |
2384 | if (!info->uses_dma_in) { | 2377 | if (!info->uses_dma_in) { |
2385 | return handle_ser_rx_interrupt_no_dma(info); | 2378 | handle_ser_rx_interrupt_no_dma(info); |
2379 | return; | ||
2386 | } | 2380 | } |
2387 | /* DMA is used */ | 2381 | /* DMA is used */ |
2388 | rstat = info->ioport[REG_STATUS]; | 2382 | rstat = info->ioport[REG_STATUS]; |
@@ -2489,7 +2483,6 @@ static struct e100_serial* handle_ser_rx_interrupt(struct e100_serial *info) | |||
2489 | /* Restarting the DMA never hurts */ | 2483 | /* Restarting the DMA never hurts */ |
2490 | *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, restart); | 2484 | *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, restart); |
2491 | START_FLUSH_FAST_TIMER(info, "ser_int"); | 2485 | START_FLUSH_FAST_TIMER(info, "ser_int"); |
2492 | return info; | ||
2493 | } /* handle_ser_rx_interrupt */ | 2486 | } /* handle_ser_rx_interrupt */ |
2494 | 2487 | ||
2495 | static void handle_ser_tx_interrupt(struct e100_serial *info) | 2488 | static void handle_ser_tx_interrupt(struct e100_serial *info) |
@@ -2534,8 +2527,7 @@ static void handle_ser_tx_interrupt(struct e100_serial *info) | |||
2534 | } | 2527 | } |
2535 | /* Normal char-by-char interrupt */ | 2528 | /* Normal char-by-char interrupt */ |
2536 | if (info->xmit.head == info->xmit.tail | 2529 | if (info->xmit.head == info->xmit.tail |
2537 | || info->port.tty->stopped | 2530 | || info->port.tty->stopped) { |
2538 | || info->port.tty->hw_stopped) { | ||
2539 | DFLOW(DEBUG_LOG(info->line, "tx_int: stopped %i\n", | 2531 | DFLOW(DEBUG_LOG(info->line, "tx_int: stopped %i\n", |
2540 | info->port.tty->stopped)); | 2532 | info->port.tty->stopped)); |
2541 | e100_disable_serial_tx_ready_irq(info); | 2533 | e100_disable_serial_tx_ready_irq(info); |
@@ -2722,7 +2714,7 @@ startup(struct e100_serial * info) | |||
2722 | 2714 | ||
2723 | /* if it was already initialized, skip this */ | 2715 | /* if it was already initialized, skip this */ |
2724 | 2716 | ||
2725 | if (info->flags & ASYNC_INITIALIZED) { | 2717 | if (info->port.flags & ASYNC_INITIALIZED) { |
2726 | local_irq_restore(flags); | 2718 | local_irq_restore(flags); |
2727 | free_page(xmit_page); | 2719 | free_page(xmit_page); |
2728 | return 0; | 2720 | return 0; |
@@ -2847,7 +2839,7 @@ startup(struct e100_serial * info) | |||
2847 | 2839 | ||
2848 | #endif /* CONFIG_SVINTO_SIM */ | 2840 | #endif /* CONFIG_SVINTO_SIM */ |
2849 | 2841 | ||
2850 | info->flags |= ASYNC_INITIALIZED; | 2842 | info->port.flags |= ASYNC_INITIALIZED; |
2851 | 2843 | ||
2852 | local_irq_restore(flags); | 2844 | local_irq_restore(flags); |
2853 | return 0; | 2845 | return 0; |
@@ -2892,7 +2884,7 @@ shutdown(struct e100_serial * info) | |||
2892 | 2884 | ||
2893 | #endif /* CONFIG_SVINTO_SIM */ | 2885 | #endif /* CONFIG_SVINTO_SIM */ |
2894 | 2886 | ||
2895 | if (!(info->flags & ASYNC_INITIALIZED)) | 2887 | if (!(info->port.flags & ASYNC_INITIALIZED)) |
2896 | return; | 2888 | return; |
2897 | 2889 | ||
2898 | #ifdef SERIAL_DEBUG_OPEN | 2890 | #ifdef SERIAL_DEBUG_OPEN |
@@ -2923,7 +2915,7 @@ shutdown(struct e100_serial * info) | |||
2923 | if (info->port.tty) | 2915 | if (info->port.tty) |
2924 | set_bit(TTY_IO_ERROR, &info->port.tty->flags); | 2916 | set_bit(TTY_IO_ERROR, &info->port.tty->flags); |
2925 | 2917 | ||
2926 | info->flags &= ~ASYNC_INITIALIZED; | 2918 | info->port.flags &= ~ASYNC_INITIALIZED; |
2927 | local_irq_restore(flags); | 2919 | local_irq_restore(flags); |
2928 | } | 2920 | } |
2929 | 2921 | ||
@@ -2948,7 +2940,7 @@ change_speed(struct e100_serial *info) | |||
2948 | /* possibly, the tx/rx should be disabled first to do this safely */ | 2940 | /* possibly, the tx/rx should be disabled first to do this safely */ |
2949 | 2941 | ||
2950 | /* change baud-rate and write it to the hardware */ | 2942 | /* change baud-rate and write it to the hardware */ |
2951 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) { | 2943 | if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) { |
2952 | /* Special baudrate */ | 2944 | /* Special baudrate */ |
2953 | u32 mask = 0xFF << (info->line*8); /* Each port has 8 bits */ | 2945 | u32 mask = 0xFF << (info->line*8); /* Each port has 8 bits */ |
2954 | unsigned long alt_source = | 2946 | unsigned long alt_source = |
@@ -3098,7 +3090,6 @@ rs_flush_chars(struct tty_struct *tty) | |||
3098 | if (info->tr_running || | 3090 | if (info->tr_running || |
3099 | info->xmit.head == info->xmit.tail || | 3091 | info->xmit.head == info->xmit.tail || |
3100 | tty->stopped || | 3092 | tty->stopped || |
3101 | tty->hw_stopped || | ||
3102 | !info->xmit.buf) | 3093 | !info->xmit.buf) |
3103 | return; | 3094 | return; |
3104 | 3095 | ||
@@ -3176,7 +3167,6 @@ static int rs_raw_write(struct tty_struct *tty, | |||
3176 | 3167 | ||
3177 | if (info->xmit.head != info->xmit.tail && | 3168 | if (info->xmit.head != info->xmit.tail && |
3178 | !tty->stopped && | 3169 | !tty->stopped && |
3179 | !tty->hw_stopped && | ||
3180 | !info->tr_running) { | 3170 | !info->tr_running) { |
3181 | start_transmit(info); | 3171 | start_transmit(info); |
3182 | } | 3172 | } |
@@ -3400,10 +3390,10 @@ get_serial_info(struct e100_serial * info, | |||
3400 | tmp.line = info->line; | 3390 | tmp.line = info->line; |
3401 | tmp.port = (int)info->ioport; | 3391 | tmp.port = (int)info->ioport; |
3402 | tmp.irq = info->irq; | 3392 | tmp.irq = info->irq; |
3403 | tmp.flags = info->flags; | 3393 | tmp.flags = info->port.flags; |
3404 | tmp.baud_base = info->baud_base; | 3394 | tmp.baud_base = info->baud_base; |
3405 | tmp.close_delay = info->close_delay; | 3395 | tmp.close_delay = info->port.close_delay; |
3406 | tmp.closing_wait = info->closing_wait; | 3396 | tmp.closing_wait = info->port.closing_wait; |
3407 | tmp.custom_divisor = info->custom_divisor; | 3397 | tmp.custom_divisor = info->custom_divisor; |
3408 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) | 3398 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) |
3409 | return -EFAULT; | 3399 | return -EFAULT; |
@@ -3425,16 +3415,16 @@ set_serial_info(struct e100_serial *info, | |||
3425 | 3415 | ||
3426 | if (!capable(CAP_SYS_ADMIN)) { | 3416 | if (!capable(CAP_SYS_ADMIN)) { |
3427 | if ((new_serial.type != info->type) || | 3417 | if ((new_serial.type != info->type) || |
3428 | (new_serial.close_delay != info->close_delay) || | 3418 | (new_serial.close_delay != info->port.close_delay) || |
3429 | ((new_serial.flags & ~ASYNC_USR_MASK) != | 3419 | ((new_serial.flags & ~ASYNC_USR_MASK) != |
3430 | (info->flags & ~ASYNC_USR_MASK))) | 3420 | (info->port.flags & ~ASYNC_USR_MASK))) |
3431 | return -EPERM; | 3421 | return -EPERM; |
3432 | info->flags = ((info->flags & ~ASYNC_USR_MASK) | | 3422 | info->port.flags = ((info->port.flags & ~ASYNC_USR_MASK) | |
3433 | (new_serial.flags & ASYNC_USR_MASK)); | 3423 | (new_serial.flags & ASYNC_USR_MASK)); |
3434 | goto check_and_exit; | 3424 | goto check_and_exit; |
3435 | } | 3425 | } |
3436 | 3426 | ||
3437 | if (info->count > 1) | 3427 | if (info->port.count > 1) |
3438 | return -EBUSY; | 3428 | return -EBUSY; |
3439 | 3429 | ||
3440 | /* | 3430 | /* |
@@ -3443,16 +3433,16 @@ set_serial_info(struct e100_serial *info, | |||
3443 | */ | 3433 | */ |
3444 | 3434 | ||
3445 | info->baud_base = new_serial.baud_base; | 3435 | info->baud_base = new_serial.baud_base; |
3446 | info->flags = ((info->flags & ~ASYNC_FLAGS) | | 3436 | info->port.flags = ((info->port.flags & ~ASYNC_FLAGS) | |
3447 | (new_serial.flags & ASYNC_FLAGS)); | 3437 | (new_serial.flags & ASYNC_FLAGS)); |
3448 | info->custom_divisor = new_serial.custom_divisor; | 3438 | info->custom_divisor = new_serial.custom_divisor; |
3449 | info->type = new_serial.type; | 3439 | info->type = new_serial.type; |
3450 | info->close_delay = new_serial.close_delay; | 3440 | info->port.close_delay = new_serial.close_delay; |
3451 | info->closing_wait = new_serial.closing_wait; | 3441 | info->port.closing_wait = new_serial.closing_wait; |
3452 | info->port.low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 3442 | info->port.low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
3453 | 3443 | ||
3454 | check_and_exit: | 3444 | check_and_exit: |
3455 | if (info->flags & ASYNC_INITIALIZED) { | 3445 | if (info->port.flags & ASYNC_INITIALIZED) { |
3456 | change_speed(info); | 3446 | change_speed(info); |
3457 | } else | 3447 | } else |
3458 | retval = startup(info); | 3448 | retval = startup(info); |
@@ -3733,10 +3723,8 @@ rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
3733 | 3723 | ||
3734 | /* Handle turning off CRTSCTS */ | 3724 | /* Handle turning off CRTSCTS */ |
3735 | if ((old_termios->c_cflag & CRTSCTS) && | 3725 | if ((old_termios->c_cflag & CRTSCTS) && |
3736 | !(tty->termios.c_cflag & CRTSCTS)) { | 3726 | !(tty->termios.c_cflag & CRTSCTS)) |
3737 | tty->hw_stopped = 0; | ||
3738 | rs_start(tty); | 3727 | rs_start(tty); |
3739 | } | ||
3740 | 3728 | ||
3741 | } | 3729 | } |
3742 | 3730 | ||
@@ -3772,7 +3760,7 @@ rs_close(struct tty_struct *tty, struct file * filp) | |||
3772 | printk("[%d] rs_close ttyS%d, count = %d\n", current->pid, | 3760 | printk("[%d] rs_close ttyS%d, count = %d\n", current->pid, |
3773 | info->line, info->count); | 3761 | info->line, info->count); |
3774 | #endif | 3762 | #endif |
3775 | if ((tty->count == 1) && (info->count != 1)) { | 3763 | if ((tty->count == 1) && (info->port.count != 1)) { |
3776 | /* | 3764 | /* |
3777 | * Uh, oh. tty->count is 1, which means that the tty | 3765 | * Uh, oh. tty->count is 1, which means that the tty |
3778 | * structure will be freed. Info->count should always | 3766 | * structure will be freed. Info->count should always |
@@ -3782,32 +3770,32 @@ rs_close(struct tty_struct *tty, struct file * filp) | |||
3782 | */ | 3770 | */ |
3783 | printk(KERN_ERR | 3771 | printk(KERN_ERR |
3784 | "rs_close: bad serial port count; tty->count is 1, " | 3772 | "rs_close: bad serial port count; tty->count is 1, " |
3785 | "info->count is %d\n", info->count); | 3773 | "info->count is %d\n", info->port.count); |
3786 | info->count = 1; | 3774 | info->port.count = 1; |
3787 | } | 3775 | } |
3788 | if (--info->count < 0) { | 3776 | if (--info->port.count < 0) { |
3789 | printk(KERN_ERR "rs_close: bad serial port count for ttyS%d: %d\n", | 3777 | printk(KERN_ERR "rs_close: bad serial port count for ttyS%d: %d\n", |
3790 | info->line, info->count); | 3778 | info->line, info->port.count); |
3791 | info->count = 0; | 3779 | info->port.count = 0; |
3792 | } | 3780 | } |
3793 | if (info->count) { | 3781 | if (info->port.count) { |
3794 | local_irq_restore(flags); | 3782 | local_irq_restore(flags); |
3795 | return; | 3783 | return; |
3796 | } | 3784 | } |
3797 | info->flags |= ASYNC_CLOSING; | 3785 | info->port.flags |= ASYNC_CLOSING; |
3798 | /* | 3786 | /* |
3799 | * Save the termios structure, since this port may have | 3787 | * Save the termios structure, since this port may have |
3800 | * separate termios for callout and dialin. | 3788 | * separate termios for callout and dialin. |
3801 | */ | 3789 | */ |
3802 | if (info->flags & ASYNC_NORMAL_ACTIVE) | 3790 | if (info->port.flags & ASYNC_NORMAL_ACTIVE) |
3803 | info->normal_termios = tty->termios; | 3791 | info->normal_termios = tty->termios; |
3804 | /* | 3792 | /* |
3805 | * Now we wait for the transmit buffer to clear; and we notify | 3793 | * Now we wait for the transmit buffer to clear; and we notify |
3806 | * the line discipline to only process XON/XOFF characters. | 3794 | * the line discipline to only process XON/XOFF characters. |
3807 | */ | 3795 | */ |
3808 | tty->closing = 1; | 3796 | tty->closing = 1; |
3809 | if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) | 3797 | if (info->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) |
3810 | tty_wait_until_sent(tty, info->closing_wait); | 3798 | tty_wait_until_sent(tty, info->port.closing_wait); |
3811 | /* | 3799 | /* |
3812 | * At this point we stop accepting input. To do this, we | 3800 | * At this point we stop accepting input. To do this, we |
3813 | * disable the serial receiver and the DMA receive interrupt. | 3801 | * disable the serial receiver and the DMA receive interrupt. |
@@ -3820,7 +3808,7 @@ rs_close(struct tty_struct *tty, struct file * filp) | |||
3820 | e100_disable_rx(info); | 3808 | e100_disable_rx(info); |
3821 | e100_disable_rx_irq(info); | 3809 | e100_disable_rx_irq(info); |
3822 | 3810 | ||
3823 | if (info->flags & ASYNC_INITIALIZED) { | 3811 | if (info->port.flags & ASYNC_INITIALIZED) { |
3824 | /* | 3812 | /* |
3825 | * Before we drop DTR, make sure the UART transmitter | 3813 | * Before we drop DTR, make sure the UART transmitter |
3826 | * has completely drained; this is especially | 3814 | * has completely drained; this is especially |
@@ -3836,13 +3824,13 @@ rs_close(struct tty_struct *tty, struct file * filp) | |||
3836 | tty->closing = 0; | 3824 | tty->closing = 0; |
3837 | info->event = 0; | 3825 | info->event = 0; |
3838 | info->port.tty = NULL; | 3826 | info->port.tty = NULL; |
3839 | if (info->blocked_open) { | 3827 | if (info->port.blocked_open) { |
3840 | if (info->close_delay) | 3828 | if (info->port.close_delay) |
3841 | schedule_timeout_interruptible(info->close_delay); | 3829 | schedule_timeout_interruptible(info->port.close_delay); |
3842 | wake_up_interruptible(&info->open_wait); | 3830 | wake_up_interruptible(&info->port.open_wait); |
3843 | } | 3831 | } |
3844 | info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); | 3832 | info->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); |
3845 | wake_up_interruptible(&info->close_wait); | 3833 | wake_up_interruptible(&info->port.close_wait); |
3846 | local_irq_restore(flags); | 3834 | local_irq_restore(flags); |
3847 | 3835 | ||
3848 | /* port closed */ | 3836 | /* port closed */ |
@@ -3935,10 +3923,10 @@ rs_hangup(struct tty_struct *tty) | |||
3935 | rs_flush_buffer(tty); | 3923 | rs_flush_buffer(tty); |
3936 | shutdown(info); | 3924 | shutdown(info); |
3937 | info->event = 0; | 3925 | info->event = 0; |
3938 | info->count = 0; | 3926 | info->port.count = 0; |
3939 | info->flags &= ~ASYNC_NORMAL_ACTIVE; | 3927 | info->port.flags &= ~ASYNC_NORMAL_ACTIVE; |
3940 | info->port.tty = NULL; | 3928 | info->port.tty = NULL; |
3941 | wake_up_interruptible(&info->open_wait); | 3929 | wake_up_interruptible(&info->port.open_wait); |
3942 | } | 3930 | } |
3943 | 3931 | ||
3944 | /* | 3932 | /* |
@@ -3960,11 +3948,11 @@ block_til_ready(struct tty_struct *tty, struct file * filp, | |||
3960 | * until it's done, and then try again. | 3948 | * until it's done, and then try again. |
3961 | */ | 3949 | */ |
3962 | if (tty_hung_up_p(filp) || | 3950 | if (tty_hung_up_p(filp) || |
3963 | (info->flags & ASYNC_CLOSING)) { | 3951 | (info->port.flags & ASYNC_CLOSING)) { |
3964 | wait_event_interruptible_tty(tty, info->close_wait, | 3952 | wait_event_interruptible_tty(tty, info->port.close_wait, |
3965 | !(info->flags & ASYNC_CLOSING)); | 3953 | !(info->port.flags & ASYNC_CLOSING)); |
3966 | #ifdef SERIAL_DO_RESTART | 3954 | #ifdef SERIAL_DO_RESTART |
3967 | if (info->flags & ASYNC_HUP_NOTIFY) | 3955 | if (info->port.flags & ASYNC_HUP_NOTIFY) |
3968 | return -EAGAIN; | 3956 | return -EAGAIN; |
3969 | else | 3957 | else |
3970 | return -ERESTARTSYS; | 3958 | return -ERESTARTSYS; |
@@ -3979,7 +3967,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, | |||
3979 | */ | 3967 | */ |
3980 | if ((filp->f_flags & O_NONBLOCK) || | 3968 | if ((filp->f_flags & O_NONBLOCK) || |
3981 | (tty->flags & (1 << TTY_IO_ERROR))) { | 3969 | (tty->flags & (1 << TTY_IO_ERROR))) { |
3982 | info->flags |= ASYNC_NORMAL_ACTIVE; | 3970 | info->port.flags |= ASYNC_NORMAL_ACTIVE; |
3983 | return 0; | 3971 | return 0; |
3984 | } | 3972 | } |
3985 | 3973 | ||
@@ -3990,23 +3978,23 @@ block_til_ready(struct tty_struct *tty, struct file * filp, | |||
3990 | /* | 3978 | /* |
3991 | * Block waiting for the carrier detect and the line to become | 3979 | * Block waiting for the carrier detect and the line to become |
3992 | * free (i.e., not in use by the callout). While we are in | 3980 | * free (i.e., not in use by the callout). While we are in |
3993 | * this loop, info->count is dropped by one, so that | 3981 | * this loop, info->port.count is dropped by one, so that |
3994 | * rs_close() knows when to free things. We restore it upon | 3982 | * rs_close() knows when to free things. We restore it upon |
3995 | * exit, either normal or abnormal. | 3983 | * exit, either normal or abnormal. |
3996 | */ | 3984 | */ |
3997 | retval = 0; | 3985 | retval = 0; |
3998 | add_wait_queue(&info->open_wait, &wait); | 3986 | add_wait_queue(&info->port.open_wait, &wait); |
3999 | #ifdef SERIAL_DEBUG_OPEN | 3987 | #ifdef SERIAL_DEBUG_OPEN |
4000 | printk("block_til_ready before block: ttyS%d, count = %d\n", | 3988 | printk("block_til_ready before block: ttyS%d, count = %d\n", |
4001 | info->line, info->count); | 3989 | info->line, info->port.count); |
4002 | #endif | 3990 | #endif |
4003 | local_irq_save(flags); | 3991 | local_irq_save(flags); |
4004 | if (!tty_hung_up_p(filp)) { | 3992 | if (!tty_hung_up_p(filp)) { |
4005 | extra_count++; | 3993 | extra_count++; |
4006 | info->count--; | 3994 | info->port.count--; |
4007 | } | 3995 | } |
4008 | local_irq_restore(flags); | 3996 | local_irq_restore(flags); |
4009 | info->blocked_open++; | 3997 | info->port.blocked_open++; |
4010 | while (1) { | 3998 | while (1) { |
4011 | local_irq_save(flags); | 3999 | local_irq_save(flags); |
4012 | /* assert RTS and DTR */ | 4000 | /* assert RTS and DTR */ |
@@ -4015,9 +4003,9 @@ block_til_ready(struct tty_struct *tty, struct file * filp, | |||
4015 | local_irq_restore(flags); | 4003 | local_irq_restore(flags); |
4016 | set_current_state(TASK_INTERRUPTIBLE); | 4004 | set_current_state(TASK_INTERRUPTIBLE); |
4017 | if (tty_hung_up_p(filp) || | 4005 | if (tty_hung_up_p(filp) || |
4018 | !(info->flags & ASYNC_INITIALIZED)) { | 4006 | !(info->port.flags & ASYNC_INITIALIZED)) { |
4019 | #ifdef SERIAL_DO_RESTART | 4007 | #ifdef SERIAL_DO_RESTART |
4020 | if (info->flags & ASYNC_HUP_NOTIFY) | 4008 | if (info->port.flags & ASYNC_HUP_NOTIFY) |
4021 | retval = -EAGAIN; | 4009 | retval = -EAGAIN; |
4022 | else | 4010 | else |
4023 | retval = -ERESTARTSYS; | 4011 | retval = -ERESTARTSYS; |
@@ -4026,7 +4014,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, | |||
4026 | #endif | 4014 | #endif |
4027 | break; | 4015 | break; |
4028 | } | 4016 | } |
4029 | if (!(info->flags & ASYNC_CLOSING) && do_clocal) | 4017 | if (!(info->port.flags & ASYNC_CLOSING) && do_clocal) |
4030 | /* && (do_clocal || DCD_IS_ASSERTED) */ | 4018 | /* && (do_clocal || DCD_IS_ASSERTED) */ |
4031 | break; | 4019 | break; |
4032 | if (signal_pending(current)) { | 4020 | if (signal_pending(current)) { |
@@ -4035,24 +4023,24 @@ block_til_ready(struct tty_struct *tty, struct file * filp, | |||
4035 | } | 4023 | } |
4036 | #ifdef SERIAL_DEBUG_OPEN | 4024 | #ifdef SERIAL_DEBUG_OPEN |
4037 | printk("block_til_ready blocking: ttyS%d, count = %d\n", | 4025 | printk("block_til_ready blocking: ttyS%d, count = %d\n", |
4038 | info->line, info->count); | 4026 | info->line, info->port.count); |
4039 | #endif | 4027 | #endif |
4040 | tty_unlock(tty); | 4028 | tty_unlock(tty); |
4041 | schedule(); | 4029 | schedule(); |
4042 | tty_lock(tty); | 4030 | tty_lock(tty); |
4043 | } | 4031 | } |
4044 | set_current_state(TASK_RUNNING); | 4032 | set_current_state(TASK_RUNNING); |
4045 | remove_wait_queue(&info->open_wait, &wait); | 4033 | remove_wait_queue(&info->port.open_wait, &wait); |
4046 | if (extra_count) | 4034 | if (extra_count) |
4047 | info->count++; | 4035 | info->port.count++; |
4048 | info->blocked_open--; | 4036 | info->port.blocked_open--; |
4049 | #ifdef SERIAL_DEBUG_OPEN | 4037 | #ifdef SERIAL_DEBUG_OPEN |
4050 | printk("block_til_ready after blocking: ttyS%d, count = %d\n", | 4038 | printk("block_til_ready after blocking: ttyS%d, count = %d\n", |
4051 | info->line, info->count); | 4039 | info->line, info->port.count); |
4052 | #endif | 4040 | #endif |
4053 | if (retval) | 4041 | if (retval) |
4054 | return retval; | 4042 | return retval; |
4055 | info->flags |= ASYNC_NORMAL_ACTIVE; | 4043 | info->port.flags |= ASYNC_NORMAL_ACTIVE; |
4056 | return 0; | 4044 | return 0; |
4057 | } | 4045 | } |
4058 | 4046 | ||
@@ -4086,24 +4074,24 @@ rs_open(struct tty_struct *tty, struct file * filp) | |||
4086 | 4074 | ||
4087 | #ifdef SERIAL_DEBUG_OPEN | 4075 | #ifdef SERIAL_DEBUG_OPEN |
4088 | printk("[%d] rs_open %s, count = %d\n", current->pid, tty->name, | 4076 | printk("[%d] rs_open %s, count = %d\n", current->pid, tty->name, |
4089 | info->count); | 4077 | info->port.count); |
4090 | #endif | 4078 | #endif |
4091 | 4079 | ||
4092 | info->count++; | 4080 | info->port.count++; |
4093 | tty->driver_data = info; | 4081 | tty->driver_data = info; |
4094 | info->port.tty = tty; | 4082 | info->port.tty = tty; |
4095 | 4083 | ||
4096 | info->port.low_latency = !!(info->flags & ASYNC_LOW_LATENCY); | 4084 | info->port.low_latency = !!(info->port.flags & ASYNC_LOW_LATENCY); |
4097 | 4085 | ||
4098 | /* | 4086 | /* |
4099 | * If the port is in the middle of closing, bail out now | 4087 | * If the port is in the middle of closing, bail out now |
4100 | */ | 4088 | */ |
4101 | if (tty_hung_up_p(filp) || | 4089 | if (tty_hung_up_p(filp) || |
4102 | (info->flags & ASYNC_CLOSING)) { | 4090 | (info->port.flags & ASYNC_CLOSING)) { |
4103 | wait_event_interruptible_tty(tty, info->close_wait, | 4091 | wait_event_interruptible_tty(tty, info->port.close_wait, |
4104 | !(info->flags & ASYNC_CLOSING)); | 4092 | !(info->port.flags & ASYNC_CLOSING)); |
4105 | #ifdef SERIAL_DO_RESTART | 4093 | #ifdef SERIAL_DO_RESTART |
4106 | return ((info->flags & ASYNC_HUP_NOTIFY) ? | 4094 | return ((info->port.flags & ASYNC_HUP_NOTIFY) ? |
4107 | -EAGAIN : -ERESTARTSYS); | 4095 | -EAGAIN : -ERESTARTSYS); |
4108 | #else | 4096 | #else |
4109 | return -EAGAIN; | 4097 | return -EAGAIN; |
@@ -4113,7 +4101,7 @@ rs_open(struct tty_struct *tty, struct file * filp) | |||
4113 | /* | 4101 | /* |
4114 | * If DMA is enabled try to allocate the irq's. | 4102 | * If DMA is enabled try to allocate the irq's. |
4115 | */ | 4103 | */ |
4116 | if (info->count == 1) { | 4104 | if (info->port.count == 1) { |
4117 | allocated_resources = 1; | 4105 | allocated_resources = 1; |
4118 | if (info->dma_in_enabled) { | 4106 | if (info->dma_in_enabled) { |
4119 | if (request_irq(info->dma_in_irq_nbr, | 4107 | if (request_irq(info->dma_in_irq_nbr, |
@@ -4186,7 +4174,7 @@ rs_open(struct tty_struct *tty, struct file * filp) | |||
4186 | if (allocated_resources) | 4174 | if (allocated_resources) |
4187 | deinit_port(info); | 4175 | deinit_port(info); |
4188 | 4176 | ||
4189 | /* FIXME Decrease count info->count here too? */ | 4177 | /* FIXME Decrease count info->port.count here too? */ |
4190 | return retval; | 4178 | return retval; |
4191 | } | 4179 | } |
4192 | 4180 | ||
@@ -4203,7 +4191,7 @@ rs_open(struct tty_struct *tty, struct file * filp) | |||
4203 | return retval; | 4191 | return retval; |
4204 | } | 4192 | } |
4205 | 4193 | ||
4206 | if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) { | 4194 | if ((info->port.count == 1) && (info->port.flags & ASYNC_SPLIT_TERMIOS)) { |
4207 | tty->termios = info->normal_termios; | 4195 | tty->termios = info->normal_termios; |
4208 | change_speed(info); | 4196 | change_speed(info); |
4209 | } | 4197 | } |
@@ -4256,9 +4244,6 @@ static void seq_line_info(struct seq_file *m, struct e100_serial *info) | |||
4256 | if (info->port.tty->stopped) | 4244 | if (info->port.tty->stopped) |
4257 | seq_printf(m, " stopped:%i", | 4245 | seq_printf(m, " stopped:%i", |
4258 | (int)info->port.tty->stopped); | 4246 | (int)info->port.tty->stopped); |
4259 | if (info->port.tty->hw_stopped) | ||
4260 | seq_printf(m, " hw_stopped:%i", | ||
4261 | (int)info->port.tty->hw_stopped); | ||
4262 | } | 4247 | } |
4263 | 4248 | ||
4264 | { | 4249 | { |
@@ -4455,16 +4440,9 @@ static int __init rs_init(void) | |||
4455 | info->forced_eop = 0; | 4440 | info->forced_eop = 0; |
4456 | info->baud_base = DEF_BAUD_BASE; | 4441 | info->baud_base = DEF_BAUD_BASE; |
4457 | info->custom_divisor = 0; | 4442 | info->custom_divisor = 0; |
4458 | info->flags = 0; | ||
4459 | info->close_delay = 5*HZ/10; | ||
4460 | info->closing_wait = 30*HZ; | ||
4461 | info->x_char = 0; | 4443 | info->x_char = 0; |
4462 | info->event = 0; | 4444 | info->event = 0; |
4463 | info->count = 0; | ||
4464 | info->blocked_open = 0; | ||
4465 | info->normal_termios = driver->init_termios; | 4445 | info->normal_termios = driver->init_termios; |
4466 | init_waitqueue_head(&info->open_wait); | ||
4467 | init_waitqueue_head(&info->close_wait); | ||
4468 | info->xmit.buf = NULL; | 4446 | info->xmit.buf = NULL; |
4469 | info->xmit.tail = info->xmit.head = 0; | 4447 | info->xmit.tail = info->xmit.head = 0; |
4470 | info->first_recv_buffer = info->last_recv_buffer = NULL; | 4448 | info->first_recv_buffer = info->last_recv_buffer = NULL; |
diff --git a/drivers/tty/serial/crisv10.h b/drivers/tty/serial/crisv10.h index ea0beb46a10d..7599014ae03f 100644 --- a/drivers/tty/serial/crisv10.h +++ b/drivers/tty/serial/crisv10.h | |||
@@ -53,8 +53,6 @@ struct e100_serial { | |||
53 | volatile u8 *icmdadr; /* adr to R_DMA_CHx_CMD */ | 53 | volatile u8 *icmdadr; /* adr to R_DMA_CHx_CMD */ |
54 | volatile u32 *idescradr; /* adr to R_DMA_CHx_DESCR */ | 54 | volatile u32 *idescradr; /* adr to R_DMA_CHx_DESCR */ |
55 | 55 | ||
56 | int flags; /* defined in tty.h */ | ||
57 | |||
58 | u8 rx_ctrl; /* shadow for R_SERIALx_REC_CTRL */ | 56 | u8 rx_ctrl; /* shadow for R_SERIALx_REC_CTRL */ |
59 | u8 tx_ctrl; /* shadow for R_SERIALx_TR_CTRL */ | 57 | u8 tx_ctrl; /* shadow for R_SERIALx_TR_CTRL */ |
60 | u8 iseteop; /* bit number for R_SET_EOP for the input dma */ | 58 | u8 iseteop; /* bit number for R_SET_EOP for the input dma */ |
@@ -88,19 +86,10 @@ struct e100_serial { | |||
88 | 86 | ||
89 | volatile int tr_running; /* 1 if output is running */ | 87 | volatile int tr_running; /* 1 if output is running */ |
90 | 88 | ||
91 | struct tty_struct *tty; | ||
92 | int read_status_mask; | ||
93 | int ignore_status_mask; | ||
94 | int x_char; /* xon/xoff character */ | 89 | int x_char; /* xon/xoff character */ |
95 | int close_delay; | ||
96 | unsigned short closing_wait; | ||
97 | unsigned short closing_wait2; | ||
98 | unsigned long event; | 90 | unsigned long event; |
99 | unsigned long last_active; | ||
100 | int line; | 91 | int line; |
101 | int type; /* PORT_ETRAX */ | 92 | int type; /* PORT_ETRAX */ |
102 | int count; /* # of fd on device */ | ||
103 | int blocked_open; /* # of blocked opens */ | ||
104 | struct circ_buf xmit; | 93 | struct circ_buf xmit; |
105 | struct etrax_recv_buffer *first_recv_buffer; | 94 | struct etrax_recv_buffer *first_recv_buffer; |
106 | struct etrax_recv_buffer *last_recv_buffer; | 95 | struct etrax_recv_buffer *last_recv_buffer; |
@@ -110,9 +99,6 @@ struct e100_serial { | |||
110 | struct work_struct work; | 99 | struct work_struct work; |
111 | struct async_icount icount; /* error-statistics etc.*/ | 100 | struct async_icount icount; /* error-statistics etc.*/ |
112 | struct ktermios normal_termios; | 101 | struct ktermios normal_termios; |
113 | struct ktermios callout_termios; | ||
114 | wait_queue_head_t open_wait; | ||
115 | wait_queue_head_t close_wait; | ||
116 | 102 | ||
117 | unsigned long char_time_usec; /* The time for 1 char, in usecs */ | 103 | unsigned long char_time_usec; /* The time for 1 char, in usecs */ |
118 | unsigned long flush_time_usec; /* How often we should flush */ | 104 | unsigned long flush_time_usec; /* How often we should flush */ |
diff --git a/drivers/tty/serial/icom.c b/drivers/tty/serial/icom.c index bc9e6b017b05..18ed5aebb166 100644 --- a/drivers/tty/serial/icom.c +++ b/drivers/tty/serial/icom.c | |||
@@ -1415,8 +1415,7 @@ static int icom_alloc_adapter(struct icom_adapter | |||
1415 | struct icom_adapter *cur_adapter_entry; | 1415 | struct icom_adapter *cur_adapter_entry; |
1416 | struct list_head *tmp; | 1416 | struct list_head *tmp; |
1417 | 1417 | ||
1418 | icom_adapter = (struct icom_adapter *) | 1418 | icom_adapter = kzalloc(sizeof(struct icom_adapter), GFP_KERNEL); |
1419 | kzalloc(sizeof(struct icom_adapter), GFP_KERNEL); | ||
1420 | 1419 | ||
1421 | if (!icom_adapter) { | 1420 | if (!icom_adapter) { |
1422 | return -ENOMEM; | 1421 | return -ENOMEM; |
diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 68d7ce997ede..8b1534c424af 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c | |||
@@ -270,23 +270,6 @@ static void mrdy_assert(struct ifx_spi_device *ifx_dev) | |||
270 | } | 270 | } |
271 | 271 | ||
272 | /** | 272 | /** |
273 | * ifx_spi_hangup - hang up an IFX device | ||
274 | * @ifx_dev: our SPI device | ||
275 | * | ||
276 | * Hang up the tty attached to the IFX device if one is currently | ||
277 | * open. If not take no action | ||
278 | */ | ||
279 | static void ifx_spi_ttyhangup(struct ifx_spi_device *ifx_dev) | ||
280 | { | ||
281 | struct tty_port *pport = &ifx_dev->tty_port; | ||
282 | struct tty_struct *tty = tty_port_tty_get(pport); | ||
283 | if (tty) { | ||
284 | tty_hangup(tty); | ||
285 | tty_kref_put(tty); | ||
286 | } | ||
287 | } | ||
288 | |||
289 | /** | ||
290 | * ifx_spi_timeout - SPI timeout | 273 | * ifx_spi_timeout - SPI timeout |
291 | * @arg: our SPI device | 274 | * @arg: our SPI device |
292 | * | 275 | * |
@@ -298,7 +281,7 @@ static void ifx_spi_timeout(unsigned long arg) | |||
298 | struct ifx_spi_device *ifx_dev = (struct ifx_spi_device *)arg; | 281 | struct ifx_spi_device *ifx_dev = (struct ifx_spi_device *)arg; |
299 | 282 | ||
300 | dev_warn(&ifx_dev->spi_dev->dev, "*** SPI Timeout ***"); | 283 | dev_warn(&ifx_dev->spi_dev->dev, "*** SPI Timeout ***"); |
301 | ifx_spi_ttyhangup(ifx_dev); | 284 | tty_port_tty_hangup(&ifx_dev->tty_port, false); |
302 | mrdy_set_low(ifx_dev); | 285 | mrdy_set_low(ifx_dev); |
303 | clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags); | 286 | clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags); |
304 | } | 287 | } |
@@ -443,25 +426,6 @@ static void ifx_spi_setup_spi_header(unsigned char *txbuffer, int tx_count, | |||
443 | } | 426 | } |
444 | 427 | ||
445 | /** | 428 | /** |
446 | * ifx_spi_wakeup_serial - SPI space made | ||
447 | * @port_data: our SPI device | ||
448 | * | ||
449 | * We have emptied the FIFO enough that we want to get more data | ||
450 | * queued into it. Poke the line discipline via tty_wakeup so that | ||
451 | * it will feed us more bits | ||
452 | */ | ||
453 | static void ifx_spi_wakeup_serial(struct ifx_spi_device *ifx_dev) | ||
454 | { | ||
455 | struct tty_struct *tty; | ||
456 | |||
457 | tty = tty_port_tty_get(&ifx_dev->tty_port); | ||
458 | if (!tty) | ||
459 | return; | ||
460 | tty_wakeup(tty); | ||
461 | tty_kref_put(tty); | ||
462 | } | ||
463 | |||
464 | /** | ||
465 | * ifx_spi_prepare_tx_buffer - prepare transmit frame | 429 | * ifx_spi_prepare_tx_buffer - prepare transmit frame |
466 | * @ifx_dev: our SPI device | 430 | * @ifx_dev: our SPI device |
467 | * | 431 | * |
@@ -506,7 +470,7 @@ static int ifx_spi_prepare_tx_buffer(struct ifx_spi_device *ifx_dev) | |||
506 | tx_count += temp_count; | 470 | tx_count += temp_count; |
507 | if (temp_count == queue_length) | 471 | if (temp_count == queue_length) |
508 | /* poke port to get more data */ | 472 | /* poke port to get more data */ |
509 | ifx_spi_wakeup_serial(ifx_dev); | 473 | tty_port_tty_wakeup(&ifx_dev->tty_port); |
510 | else /* more data in port, use next SPI message */ | 474 | else /* more data in port, use next SPI message */ |
511 | ifx_dev->spi_more = 1; | 475 | ifx_dev->spi_more = 1; |
512 | } | 476 | } |
@@ -683,8 +647,6 @@ static void ifx_spi_insert_flip_string(struct ifx_spi_device *ifx_dev, | |||
683 | static void ifx_spi_complete(void *ctx) | 647 | static void ifx_spi_complete(void *ctx) |
684 | { | 648 | { |
685 | struct ifx_spi_device *ifx_dev = ctx; | 649 | struct ifx_spi_device *ifx_dev = ctx; |
686 | struct tty_struct *tty; | ||
687 | struct tty_ldisc *ldisc = NULL; | ||
688 | int length; | 650 | int length; |
689 | int actual_length; | 651 | int actual_length; |
690 | unsigned char more; | 652 | unsigned char more; |
@@ -762,15 +724,7 @@ complete_exit: | |||
762 | */ | 724 | */ |
763 | ifx_spi_power_state_clear(ifx_dev, | 725 | ifx_spi_power_state_clear(ifx_dev, |
764 | IFX_SPI_POWER_DATA_PENDING); | 726 | IFX_SPI_POWER_DATA_PENDING); |
765 | tty = tty_port_tty_get(&ifx_dev->tty_port); | 727 | tty_port_tty_wakeup(&ifx_dev->tty_port); |
766 | if (tty) { | ||
767 | ldisc = tty_ldisc_ref(tty); | ||
768 | if (ldisc) { | ||
769 | ldisc->ops->write_wakeup(tty); | ||
770 | tty_ldisc_deref(ldisc); | ||
771 | } | ||
772 | tty_kref_put(tty); | ||
773 | } | ||
774 | } | 728 | } |
775 | } | 729 | } |
776 | } | 730 | } |
@@ -962,7 +916,7 @@ static irqreturn_t ifx_spi_reset_interrupt(int irq, void *dev) | |||
962 | set_bit(MR_INPROGRESS, &ifx_dev->mdm_reset_state); | 916 | set_bit(MR_INPROGRESS, &ifx_dev->mdm_reset_state); |
963 | if (!solreset) { | 917 | if (!solreset) { |
964 | /* unsolicited reset */ | 918 | /* unsolicited reset */ |
965 | ifx_spi_ttyhangup(ifx_dev); | 919 | tty_port_tty_hangup(&ifx_dev->tty_port, false); |
966 | } | 920 | } |
967 | } else { | 921 | } else { |
968 | /* exited reset */ | 922 | /* exited reset */ |
@@ -1325,30 +1279,6 @@ static void ifx_spi_spi_shutdown(struct spi_device *spi) | |||
1325 | */ | 1279 | */ |
1326 | 1280 | ||
1327 | /** | 1281 | /** |
1328 | * ifx_spi_spi_suspend - suspend SPI on system suspend | ||
1329 | * @dev: device being suspended | ||
1330 | * | ||
1331 | * Suspend the SPI side. No action needed on Intel MID platforms, may | ||
1332 | * need extending for other systems. | ||
1333 | */ | ||
1334 | static int ifx_spi_spi_suspend(struct spi_device *spi, pm_message_t msg) | ||
1335 | { | ||
1336 | return 0; | ||
1337 | } | ||
1338 | |||
1339 | /** | ||
1340 | * ifx_spi_spi_resume - resume SPI side on system resume | ||
1341 | * @dev: device being suspended | ||
1342 | * | ||
1343 | * Suspend the SPI side. No action needed on Intel MID platforms, may | ||
1344 | * need extending for other systems. | ||
1345 | */ | ||
1346 | static int ifx_spi_spi_resume(struct spi_device *spi) | ||
1347 | { | ||
1348 | return 0; | ||
1349 | } | ||
1350 | |||
1351 | /** | ||
1352 | * ifx_spi_pm_suspend - suspend modem on system suspend | 1282 | * ifx_spi_pm_suspend - suspend modem on system suspend |
1353 | * @dev: device being suspended | 1283 | * @dev: device being suspended |
1354 | * | 1284 | * |
@@ -1437,8 +1367,6 @@ static struct spi_driver ifx_spi_driver = { | |||
1437 | .probe = ifx_spi_spi_probe, | 1367 | .probe = ifx_spi_spi_probe, |
1438 | .shutdown = ifx_spi_spi_shutdown, | 1368 | .shutdown = ifx_spi_spi_shutdown, |
1439 | .remove = ifx_spi_spi_remove, | 1369 | .remove = ifx_spi_spi_remove, |
1440 | .suspend = ifx_spi_spi_suspend, | ||
1441 | .resume = ifx_spi_spi_resume, | ||
1442 | .id_table = ifx_id_table | 1370 | .id_table = ifx_id_table |
1443 | }; | 1371 | }; |
1444 | 1372 | ||
diff --git a/drivers/tty/serial/jsm/jsm_tty.c b/drivers/tty/serial/jsm/jsm_tty.c index 00f250ae14c5..27bb75070c96 100644 --- a/drivers/tty/serial/jsm/jsm_tty.c +++ b/drivers/tty/serial/jsm/jsm_tty.c | |||
@@ -596,12 +596,6 @@ void jsm_input(struct jsm_channel *ch) | |||
596 | 596 | ||
597 | jsm_dbg(READ, &ch->ch_bd->pci_dev, "start 2\n"); | 597 | jsm_dbg(READ, &ch->ch_bd->pci_dev, "start 2\n"); |
598 | 598 | ||
599 | if (data_len <= 0) { | ||
600 | spin_unlock_irqrestore(&ch->ch_lock, lock_flags); | ||
601 | jsm_dbg(READ, &ch->ch_bd->pci_dev, "jsm_input 1\n"); | ||
602 | return; | ||
603 | } | ||
604 | |||
605 | len = tty_buffer_request_room(port, data_len); | 599 | len = tty_buffer_request_room(port, data_len); |
606 | n = len; | 600 | n = len; |
607 | 601 | ||
diff --git a/drivers/tty/serial/max3100.c b/drivers/tty/serial/max3100.c index 32517d4bceab..35866d5872ad 100644 --- a/drivers/tty/serial/max3100.c +++ b/drivers/tty/serial/max3100.c | |||
@@ -778,7 +778,7 @@ static int max3100_probe(struct spi_device *spi) | |||
778 | max3100s[i]->spi = spi; | 778 | max3100s[i]->spi = spi; |
779 | max3100s[i]->irq = spi->irq; | 779 | max3100s[i]->irq = spi->irq; |
780 | spin_lock_init(&max3100s[i]->conf_lock); | 780 | spin_lock_init(&max3100s[i]->conf_lock); |
781 | dev_set_drvdata(&spi->dev, max3100s[i]); | 781 | spi_set_drvdata(spi, max3100s[i]); |
782 | pdata = spi->dev.platform_data; | 782 | pdata = spi->dev.platform_data; |
783 | max3100s[i]->crystal = pdata->crystal; | 783 | max3100s[i]->crystal = pdata->crystal; |
784 | max3100s[i]->loopback = pdata->loopback; | 784 | max3100s[i]->loopback = pdata->loopback; |
@@ -819,7 +819,7 @@ static int max3100_probe(struct spi_device *spi) | |||
819 | 819 | ||
820 | static int max3100_remove(struct spi_device *spi) | 820 | static int max3100_remove(struct spi_device *spi) |
821 | { | 821 | { |
822 | struct max3100_port *s = dev_get_drvdata(&spi->dev); | 822 | struct max3100_port *s = spi_get_drvdata(spi); |
823 | int i; | 823 | int i; |
824 | 824 | ||
825 | mutex_lock(&max3100s_lock); | 825 | mutex_lock(&max3100s_lock); |
@@ -849,11 +849,11 @@ static int max3100_remove(struct spi_device *spi) | |||
849 | return 0; | 849 | return 0; |
850 | } | 850 | } |
851 | 851 | ||
852 | #ifdef CONFIG_PM | 852 | #ifdef CONFIG_PM_SLEEP |
853 | 853 | ||
854 | static int max3100_suspend(struct spi_device *spi, pm_message_t state) | 854 | static int max3100_suspend(struct device *dev) |
855 | { | 855 | { |
856 | struct max3100_port *s = dev_get_drvdata(&spi->dev); | 856 | struct max3100_port *s = dev_get_drvdata(dev); |
857 | 857 | ||
858 | dev_dbg(&s->spi->dev, "%s\n", __func__); | 858 | dev_dbg(&s->spi->dev, "%s\n", __func__); |
859 | 859 | ||
@@ -874,9 +874,9 @@ static int max3100_suspend(struct spi_device *spi, pm_message_t state) | |||
874 | return 0; | 874 | return 0; |
875 | } | 875 | } |
876 | 876 | ||
877 | static int max3100_resume(struct spi_device *spi) | 877 | static int max3100_resume(struct device *dev) |
878 | { | 878 | { |
879 | struct max3100_port *s = dev_get_drvdata(&spi->dev); | 879 | struct max3100_port *s = dev_get_drvdata(dev); |
880 | 880 | ||
881 | dev_dbg(&s->spi->dev, "%s\n", __func__); | 881 | dev_dbg(&s->spi->dev, "%s\n", __func__); |
882 | 882 | ||
@@ -894,21 +894,21 @@ static int max3100_resume(struct spi_device *spi) | |||
894 | return 0; | 894 | return 0; |
895 | } | 895 | } |
896 | 896 | ||
897 | static SIMPLE_DEV_PM_OPS(max3100_pm_ops, max3100_suspend, max3100_resume); | ||
898 | #define MAX3100_PM_OPS (&max3100_pm_ops) | ||
899 | |||
897 | #else | 900 | #else |
898 | #define max3100_suspend NULL | 901 | #define MAX3100_PM_OPS NULL |
899 | #define max3100_resume NULL | ||
900 | #endif | 902 | #endif |
901 | 903 | ||
902 | static struct spi_driver max3100_driver = { | 904 | static struct spi_driver max3100_driver = { |
903 | .driver = { | 905 | .driver = { |
904 | .name = "max3100", | 906 | .name = "max3100", |
905 | .owner = THIS_MODULE, | 907 | .owner = THIS_MODULE, |
908 | .pm = MAX3100_PM_OPS, | ||
906 | }, | 909 | }, |
907 | |||
908 | .probe = max3100_probe, | 910 | .probe = max3100_probe, |
909 | .remove = max3100_remove, | 911 | .remove = max3100_remove, |
910 | .suspend = max3100_suspend, | ||
911 | .resume = max3100_resume, | ||
912 | }; | 912 | }; |
913 | 913 | ||
914 | module_spi_driver(max3100_driver); | 914 | module_spi_driver(max3100_driver); |
diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index 0c2422cb04ea..8941e6418942 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c | |||
@@ -881,12 +881,14 @@ static struct uart_ops max310x_ops = { | |||
881 | .verify_port = max310x_verify_port, | 881 | .verify_port = max310x_verify_port, |
882 | }; | 882 | }; |
883 | 883 | ||
884 | static int max310x_suspend(struct spi_device *spi, pm_message_t state) | 884 | #ifdef CONFIG_PM_SLEEP |
885 | |||
886 | static int max310x_suspend(struct device *dev) | ||
885 | { | 887 | { |
886 | int ret; | 888 | int ret; |
887 | struct max310x_port *s = dev_get_drvdata(&spi->dev); | 889 | struct max310x_port *s = dev_get_drvdata(dev); |
888 | 890 | ||
889 | dev_dbg(&spi->dev, "Suspend\n"); | 891 | dev_dbg(dev, "Suspend\n"); |
890 | 892 | ||
891 | ret = uart_suspend_port(&s->uart, &s->port); | 893 | ret = uart_suspend_port(&s->uart, &s->port); |
892 | 894 | ||
@@ -905,11 +907,11 @@ static int max310x_suspend(struct spi_device *spi, pm_message_t state) | |||
905 | return ret; | 907 | return ret; |
906 | } | 908 | } |
907 | 909 | ||
908 | static int max310x_resume(struct spi_device *spi) | 910 | static int max310x_resume(struct device *dev) |
909 | { | 911 | { |
910 | struct max310x_port *s = dev_get_drvdata(&spi->dev); | 912 | struct max310x_port *s = dev_get_drvdata(dev); |
911 | 913 | ||
912 | dev_dbg(&spi->dev, "Resume\n"); | 914 | dev_dbg(dev, "Resume\n"); |
913 | 915 | ||
914 | if (s->pdata->suspend) | 916 | if (s->pdata->suspend) |
915 | s->pdata->suspend(0); | 917 | s->pdata->suspend(0); |
@@ -928,6 +930,13 @@ static int max310x_resume(struct spi_device *spi) | |||
928 | return uart_resume_port(&s->uart, &s->port); | 930 | return uart_resume_port(&s->uart, &s->port); |
929 | } | 931 | } |
930 | 932 | ||
933 | static SIMPLE_DEV_PM_OPS(max310x_pm_ops, max310x_suspend, max310x_resume); | ||
934 | #define MAX310X_PM_OPS (&max310x_pm_ops) | ||
935 | |||
936 | #else | ||
937 | #define MAX310X_PM_OPS NULL | ||
938 | #endif | ||
939 | |||
931 | #ifdef CONFIG_GPIOLIB | 940 | #ifdef CONFIG_GPIOLIB |
932 | static int max310x_gpio_get(struct gpio_chip *chip, unsigned offset) | 941 | static int max310x_gpio_get(struct gpio_chip *chip, unsigned offset) |
933 | { | 942 | { |
@@ -1242,11 +1251,10 @@ static struct spi_driver max310x_driver = { | |||
1242 | .driver = { | 1251 | .driver = { |
1243 | .name = "max310x", | 1252 | .name = "max310x", |
1244 | .owner = THIS_MODULE, | 1253 | .owner = THIS_MODULE, |
1254 | .pm = MAX310X_PM_OPS, | ||
1245 | }, | 1255 | }, |
1246 | .probe = max310x_probe, | 1256 | .probe = max310x_probe, |
1247 | .remove = max310x_remove, | 1257 | .remove = max310x_remove, |
1248 | .suspend = max310x_suspend, | ||
1249 | .resume = max310x_resume, | ||
1250 | .id_table = max310x_id_table, | 1258 | .id_table = max310x_id_table, |
1251 | }; | 1259 | }; |
1252 | module_spi_driver(max310x_driver); | 1260 | module_spi_driver(max310x_driver); |
diff --git a/drivers/tty/serial/mrst_max3110.c b/drivers/tty/serial/mrst_max3110.c index f641c232beca..9b6ef20420c0 100644 --- a/drivers/tty/serial/mrst_max3110.c +++ b/drivers/tty/serial/mrst_max3110.c | |||
@@ -743,9 +743,10 @@ static struct uart_driver serial_m3110_reg = { | |||
743 | .cons = &serial_m3110_console, | 743 | .cons = &serial_m3110_console, |
744 | }; | 744 | }; |
745 | 745 | ||
746 | #ifdef CONFIG_PM | 746 | #ifdef CONFIG_PM_SLEEP |
747 | static int serial_m3110_suspend(struct spi_device *spi, pm_message_t state) | 747 | static int serial_m3110_suspend(struct device *dev) |
748 | { | 748 | { |
749 | struct spi_device *spi = to_spi_device(dev); | ||
749 | struct uart_max3110 *max = spi_get_drvdata(spi); | 750 | struct uart_max3110 *max = spi_get_drvdata(spi); |
750 | 751 | ||
751 | disable_irq(max->irq); | 752 | disable_irq(max->irq); |
@@ -754,8 +755,9 @@ static int serial_m3110_suspend(struct spi_device *spi, pm_message_t state) | |||
754 | return 0; | 755 | return 0; |
755 | } | 756 | } |
756 | 757 | ||
757 | static int serial_m3110_resume(struct spi_device *spi) | 758 | static int serial_m3110_resume(struct device *dev) |
758 | { | 759 | { |
760 | struct spi_device *spi = to_spi_device(dev); | ||
759 | struct uart_max3110 *max = spi_get_drvdata(spi); | 761 | struct uart_max3110 *max = spi_get_drvdata(spi); |
760 | 762 | ||
761 | max3110_out(max, max->cur_conf); | 763 | max3110_out(max, max->cur_conf); |
@@ -763,9 +765,13 @@ static int serial_m3110_resume(struct spi_device *spi) | |||
763 | enable_irq(max->irq); | 765 | enable_irq(max->irq); |
764 | return 0; | 766 | return 0; |
765 | } | 767 | } |
768 | |||
769 | static SIMPLE_DEV_PM_OPS(serial_m3110_pm_ops, serial_m3110_suspend, | ||
770 | serial_m3110_resume); | ||
771 | #define SERIAL_M3110_PM_OPS (&serial_m3110_pm_ops) | ||
772 | |||
766 | #else | 773 | #else |
767 | #define serial_m3110_suspend NULL | 774 | #define SERIAL_M3110_PM_OPS NULL |
768 | #define serial_m3110_resume NULL | ||
769 | #endif | 775 | #endif |
770 | 776 | ||
771 | static int serial_m3110_probe(struct spi_device *spi) | 777 | static int serial_m3110_probe(struct spi_device *spi) |
@@ -872,11 +878,10 @@ static struct spi_driver uart_max3110_driver = { | |||
872 | .driver = { | 878 | .driver = { |
873 | .name = "spi_max3111", | 879 | .name = "spi_max3111", |
874 | .owner = THIS_MODULE, | 880 | .owner = THIS_MODULE, |
881 | .pm = SERIAL_M3110_PM_OPS, | ||
875 | }, | 882 | }, |
876 | .probe = serial_m3110_probe, | 883 | .probe = serial_m3110_probe, |
877 | .remove = serial_m3110_remove, | 884 | .remove = serial_m3110_remove, |
878 | .suspend = serial_m3110_suspend, | ||
879 | .resume = serial_m3110_resume, | ||
880 | }; | 885 | }; |
881 | 886 | ||
882 | static int __init serial_m3110_init(void) | 887 | static int __init serial_m3110_init(void) |
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c index 4a942c78347e..4ca2f64861e6 100644 --- a/drivers/tty/serial/msm_serial_hs.c +++ b/drivers/tty/serial/msm_serial_hs.c | |||
@@ -907,7 +907,6 @@ static void msm_hs_dmov_rx_callback(struct msm_dmov_cmd *cmd_ptr, | |||
907 | unsigned int error_f = 0; | 907 | unsigned int error_f = 0; |
908 | unsigned long flags; | 908 | unsigned long flags; |
909 | unsigned int flush; | 909 | unsigned int flush; |
910 | struct tty_struct *tty; | ||
911 | struct tty_port *port; | 910 | struct tty_port *port; |
912 | struct uart_port *uport; | 911 | struct uart_port *uport; |
913 | struct msm_hs_port *msm_uport; | 912 | struct msm_hs_port *msm_uport; |
@@ -919,7 +918,6 @@ static void msm_hs_dmov_rx_callback(struct msm_dmov_cmd *cmd_ptr, | |||
919 | clk_enable(msm_uport->clk); | 918 | clk_enable(msm_uport->clk); |
920 | 919 | ||
921 | port = &uport->state->port; | 920 | port = &uport->state->port; |
922 | tty = port->tty; | ||
923 | 921 | ||
924 | msm_hs_write(uport, UARTDM_CR_ADDR, STALE_EVENT_DISABLE); | 922 | msm_hs_write(uport, UARTDM_CR_ADDR, STALE_EVENT_DISABLE); |
925 | 923 | ||
diff --git a/drivers/tty/serial/msm_smd_tty.c b/drivers/tty/serial/msm_smd_tty.c index e722ff163d91..1238ac370bff 100644 --- a/drivers/tty/serial/msm_smd_tty.c +++ b/drivers/tty/serial/msm_smd_tty.c | |||
@@ -90,13 +90,13 @@ static void smd_tty_notify(void *priv, unsigned event) | |||
90 | 90 | ||
91 | static int smd_tty_port_activate(struct tty_port *tport, struct tty_struct *tty) | 91 | static int smd_tty_port_activate(struct tty_port *tport, struct tty_struct *tty) |
92 | { | 92 | { |
93 | struct smd_tty_info *info = container_of(tport, struct smd_tty_info, | ||
94 | port); | ||
93 | int i, res = 0; | 95 | int i, res = 0; |
94 | int n = tty->index; | ||
95 | const char *name = NULL; | 96 | const char *name = NULL; |
96 | struct smd_tty_info *info = smd_tty + n; | ||
97 | 97 | ||
98 | for (i = 0; i < smd_tty_channels_len; i++) { | 98 | for (i = 0; i < smd_tty_channels_len; i++) { |
99 | if (smd_tty_channels[i].id == n) { | 99 | if (smd_tty_channels[i].id == tty->index) { |
100 | name = smd_tty_channels[i].name; | 100 | name = smd_tty_channels[i].name; |
101 | break; | 101 | break; |
102 | } | 102 | } |
@@ -117,17 +117,13 @@ static int smd_tty_port_activate(struct tty_port *tport, struct tty_struct *tty) | |||
117 | 117 | ||
118 | static void smd_tty_port_shutdown(struct tty_port *tport) | 118 | static void smd_tty_port_shutdown(struct tty_port *tport) |
119 | { | 119 | { |
120 | struct smd_tty_info *info; | 120 | struct smd_tty_info *info = container_of(tport, struct smd_tty_info, |
121 | struct tty_struct *tty = tty_port_tty_get(tport); | 121 | port); |
122 | 122 | ||
123 | info = tty->driver_data; | ||
124 | if (info->ch) { | 123 | if (info->ch) { |
125 | smd_close(info->ch); | 124 | smd_close(info->ch); |
126 | info->ch = 0; | 125 | info->ch = 0; |
127 | } | 126 | } |
128 | |||
129 | tty->driver_data = 0; | ||
130 | tty_kref_put(tty); | ||
131 | } | 127 | } |
132 | 128 | ||
133 | static int smd_tty_open(struct tty_struct *tty, struct file *f) | 129 | static int smd_tty_open(struct tty_struct *tty, struct file *f) |
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index d549fe1fa42a..62e7d3b015a1 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c | |||
@@ -883,7 +883,7 @@ auart_console_write(struct console *co, const char *str, unsigned int count) | |||
883 | unsigned int old_ctrl0, old_ctrl2; | 883 | unsigned int old_ctrl0, old_ctrl2; |
884 | unsigned int to = 1000; | 884 | unsigned int to = 1000; |
885 | 885 | ||
886 | if (co->index > MXS_AUART_PORTS || co->index < 0) | 886 | if (co->index >= MXS_AUART_PORTS || co->index < 0) |
887 | return; | 887 | return; |
888 | 888 | ||
889 | s = auart_port[co->index]; | 889 | s = auart_port[co->index]; |
@@ -1103,7 +1103,7 @@ static int mxs_auart_probe(struct platform_device *pdev) | |||
1103 | s->port.fifosize = 16; | 1103 | s->port.fifosize = 16; |
1104 | s->port.uartclk = clk_get_rate(s->clk); | 1104 | s->port.uartclk = clk_get_rate(s->clk); |
1105 | s->port.type = PORT_IMX; | 1105 | s->port.type = PORT_IMX; |
1106 | s->port.dev = s->dev = get_device(&pdev->dev); | 1106 | s->port.dev = s->dev = &pdev->dev; |
1107 | 1107 | ||
1108 | s->ctrl = 0; | 1108 | s->ctrl = 0; |
1109 | 1109 | ||
@@ -1134,7 +1134,6 @@ out_free_irq: | |||
1134 | auart_port[pdev->id] = NULL; | 1134 | auart_port[pdev->id] = NULL; |
1135 | free_irq(s->irq, s); | 1135 | free_irq(s->irq, s); |
1136 | out_free_clk: | 1136 | out_free_clk: |
1137 | put_device(s->dev); | ||
1138 | clk_put(s->clk); | 1137 | clk_put(s->clk); |
1139 | out_free: | 1138 | out_free: |
1140 | kfree(s); | 1139 | kfree(s); |
@@ -1150,7 +1149,6 @@ static int mxs_auart_remove(struct platform_device *pdev) | |||
1150 | 1149 | ||
1151 | auart_port[pdev->id] = NULL; | 1150 | auart_port[pdev->id] = NULL; |
1152 | 1151 | ||
1153 | put_device(s->dev); | ||
1154 | clk_put(s->clk); | 1152 | clk_put(s->clk); |
1155 | free_irq(s->irq, s); | 1153 | free_irq(s->irq, s); |
1156 | kfree(s); | 1154 | kfree(s); |
diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index b025d5438275..39c7ea4cb14f 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/serial_core.h> | 16 | #include <linux/serial_core.h> |
17 | #include <linux/serial_8250.h> | ||
18 | #include <linux/serial_reg.h> | 17 | #include <linux/serial_reg.h> |
19 | #include <linux/of_address.h> | 18 | #include <linux/of_address.h> |
20 | #include <linux/of_irq.h> | 19 | #include <linux/of_irq.h> |
@@ -22,6 +21,8 @@ | |||
22 | #include <linux/nwpserial.h> | 21 | #include <linux/nwpserial.h> |
23 | #include <linux/clk.h> | 22 | #include <linux/clk.h> |
24 | 23 | ||
24 | #include "8250/8250.h" | ||
25 | |||
25 | struct of_serial_info { | 26 | struct of_serial_info { |
26 | struct clk *clk; | 27 | struct clk *clk; |
27 | int type; | 28 | int type; |
@@ -97,6 +98,10 @@ static int of_platform_serial_setup(struct platform_device *ofdev, | |||
97 | if (of_property_read_u32(np, "reg-shift", &prop) == 0) | 98 | if (of_property_read_u32(np, "reg-shift", &prop) == 0) |
98 | port->regshift = prop; | 99 | port->regshift = prop; |
99 | 100 | ||
101 | /* Check for fifo size */ | ||
102 | if (of_property_read_u32(np, "fifo-size", &prop) == 0) | ||
103 | port->fifosize = prop; | ||
104 | |||
100 | port->irq = irq_of_parse_and_map(np, 0); | 105 | port->irq = irq_of_parse_and_map(np, 0); |
101 | port->iotype = UPIO_MEM; | 106 | port->iotype = UPIO_MEM; |
102 | if (of_property_read_u32(np, "reg-io-width", &prop) == 0) { | 107 | if (of_property_read_u32(np, "reg-io-width", &prop) == 0) { |
@@ -167,11 +172,17 @@ static int of_platform_serial_probe(struct platform_device *ofdev) | |||
167 | #ifdef CONFIG_SERIAL_8250 | 172 | #ifdef CONFIG_SERIAL_8250 |
168 | case PORT_8250 ... PORT_MAX_8250: | 173 | case PORT_8250 ... PORT_MAX_8250: |
169 | { | 174 | { |
170 | /* For now the of bindings don't support the extra | ||
171 | 8250 specific bits */ | ||
172 | struct uart_8250_port port8250; | 175 | struct uart_8250_port port8250; |
173 | memset(&port8250, 0, sizeof(port8250)); | 176 | memset(&port8250, 0, sizeof(port8250)); |
174 | port8250.port = port; | 177 | port8250.port = port; |
178 | |||
179 | if (port.fifosize) | ||
180 | port8250.capabilities = UART_CAP_FIFO; | ||
181 | |||
182 | if (of_property_read_bool(ofdev->dev.of_node, | ||
183 | "auto-flow-control")) | ||
184 | port8250.capabilities |= UART_CAP_AFE; | ||
185 | |||
175 | ret = serial8250_register_8250_port(&port8250); | 186 | ret = serial8250_register_8250_port(&port8250); |
176 | break; | 187 | break; |
177 | } | 188 | } |
diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 7a6c989924b3..21a7e179edf3 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c | |||
@@ -1493,29 +1493,6 @@ static int pch_uart_verify_port(struct uart_port *port, | |||
1493 | return 0; | 1493 | return 0; |
1494 | } | 1494 | } |
1495 | 1495 | ||
1496 | static struct uart_ops pch_uart_ops = { | ||
1497 | .tx_empty = pch_uart_tx_empty, | ||
1498 | .set_mctrl = pch_uart_set_mctrl, | ||
1499 | .get_mctrl = pch_uart_get_mctrl, | ||
1500 | .stop_tx = pch_uart_stop_tx, | ||
1501 | .start_tx = pch_uart_start_tx, | ||
1502 | .stop_rx = pch_uart_stop_rx, | ||
1503 | .enable_ms = pch_uart_enable_ms, | ||
1504 | .break_ctl = pch_uart_break_ctl, | ||
1505 | .startup = pch_uart_startup, | ||
1506 | .shutdown = pch_uart_shutdown, | ||
1507 | .set_termios = pch_uart_set_termios, | ||
1508 | /* .pm = pch_uart_pm, Not supported yet */ | ||
1509 | /* .set_wake = pch_uart_set_wake, Not supported yet */ | ||
1510 | .type = pch_uart_type, | ||
1511 | .release_port = pch_uart_release_port, | ||
1512 | .request_port = pch_uart_request_port, | ||
1513 | .config_port = pch_uart_config_port, | ||
1514 | .verify_port = pch_uart_verify_port | ||
1515 | }; | ||
1516 | |||
1517 | #ifdef CONFIG_SERIAL_PCH_UART_CONSOLE | ||
1518 | |||
1519 | /* | 1496 | /* |
1520 | * Wait for transmitter & holding register to empty | 1497 | * Wait for transmitter & holding register to empty |
1521 | */ | 1498 | */ |
@@ -1547,6 +1524,84 @@ static void wait_for_xmitr(struct eg20t_port *up, int bits) | |||
1547 | } | 1524 | } |
1548 | } | 1525 | } |
1549 | 1526 | ||
1527 | #ifdef CONFIG_CONSOLE_POLL | ||
1528 | /* | ||
1529 | * Console polling routines for communicate via uart while | ||
1530 | * in an interrupt or debug context. | ||
1531 | */ | ||
1532 | static int pch_uart_get_poll_char(struct uart_port *port) | ||
1533 | { | ||
1534 | struct eg20t_port *priv = | ||
1535 | container_of(port, struct eg20t_port, port); | ||
1536 | u8 lsr = ioread8(priv->membase + UART_LSR); | ||
1537 | |||
1538 | if (!(lsr & UART_LSR_DR)) | ||
1539 | return NO_POLL_CHAR; | ||
1540 | |||
1541 | return ioread8(priv->membase + PCH_UART_RBR); | ||
1542 | } | ||
1543 | |||
1544 | |||
1545 | static void pch_uart_put_poll_char(struct uart_port *port, | ||
1546 | unsigned char c) | ||
1547 | { | ||
1548 | unsigned int ier; | ||
1549 | struct eg20t_port *priv = | ||
1550 | container_of(port, struct eg20t_port, port); | ||
1551 | |||
1552 | /* | ||
1553 | * First save the IER then disable the interrupts | ||
1554 | */ | ||
1555 | ier = ioread8(priv->membase + UART_IER); | ||
1556 | pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_ALL_INT); | ||
1557 | |||
1558 | wait_for_xmitr(priv, UART_LSR_THRE); | ||
1559 | /* | ||
1560 | * Send the character out. | ||
1561 | * If a LF, also do CR... | ||
1562 | */ | ||
1563 | iowrite8(c, priv->membase + PCH_UART_THR); | ||
1564 | if (c == 10) { | ||
1565 | wait_for_xmitr(priv, UART_LSR_THRE); | ||
1566 | iowrite8(13, priv->membase + PCH_UART_THR); | ||
1567 | } | ||
1568 | |||
1569 | /* | ||
1570 | * Finally, wait for transmitter to become empty | ||
1571 | * and restore the IER | ||
1572 | */ | ||
1573 | wait_for_xmitr(priv, BOTH_EMPTY); | ||
1574 | iowrite8(ier, priv->membase + UART_IER); | ||
1575 | } | ||
1576 | #endif /* CONFIG_CONSOLE_POLL */ | ||
1577 | |||
1578 | static struct uart_ops pch_uart_ops = { | ||
1579 | .tx_empty = pch_uart_tx_empty, | ||
1580 | .set_mctrl = pch_uart_set_mctrl, | ||
1581 | .get_mctrl = pch_uart_get_mctrl, | ||
1582 | .stop_tx = pch_uart_stop_tx, | ||
1583 | .start_tx = pch_uart_start_tx, | ||
1584 | .stop_rx = pch_uart_stop_rx, | ||
1585 | .enable_ms = pch_uart_enable_ms, | ||
1586 | .break_ctl = pch_uart_break_ctl, | ||
1587 | .startup = pch_uart_startup, | ||
1588 | .shutdown = pch_uart_shutdown, | ||
1589 | .set_termios = pch_uart_set_termios, | ||
1590 | /* .pm = pch_uart_pm, Not supported yet */ | ||
1591 | /* .set_wake = pch_uart_set_wake, Not supported yet */ | ||
1592 | .type = pch_uart_type, | ||
1593 | .release_port = pch_uart_release_port, | ||
1594 | .request_port = pch_uart_request_port, | ||
1595 | .config_port = pch_uart_config_port, | ||
1596 | .verify_port = pch_uart_verify_port, | ||
1597 | #ifdef CONFIG_CONSOLE_POLL | ||
1598 | .poll_get_char = pch_uart_get_poll_char, | ||
1599 | .poll_put_char = pch_uart_put_poll_char, | ||
1600 | #endif | ||
1601 | }; | ||
1602 | |||
1603 | #ifdef CONFIG_SERIAL_PCH_UART_CONSOLE | ||
1604 | |||
1550 | static void pch_console_putchar(struct uart_port *port, int ch) | 1605 | static void pch_console_putchar(struct uart_port *port, int ch) |
1551 | { | 1606 | { |
1552 | struct eg20t_port *priv = | 1607 | struct eg20t_port *priv = |
@@ -1655,7 +1710,7 @@ static struct console pch_console = { | |||
1655 | #define PCH_CONSOLE (&pch_console) | 1710 | #define PCH_CONSOLE (&pch_console) |
1656 | #else | 1711 | #else |
1657 | #define PCH_CONSOLE NULL | 1712 | #define PCH_CONSOLE NULL |
1658 | #endif | 1713 | #endif /* CONFIG_SERIAL_PCH_UART_CONSOLE */ |
1659 | 1714 | ||
1660 | static struct uart_driver pch_uart_driver = { | 1715 | static struct uart_driver pch_uart_driver = { |
1661 | .owner = THIS_MODULE, | 1716 | .owner = THIS_MODULE, |
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 2769a38d15b6..074b9194144f 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/tty_flip.h> | 39 | #include <linux/tty_flip.h> |
40 | #include <linux/serial_core.h> | 40 | #include <linux/serial_core.h> |
41 | #include <linux/serial.h> | 41 | #include <linux/serial.h> |
42 | #include <linux/serial_s3c.h> | ||
42 | #include <linux/delay.h> | 43 | #include <linux/delay.h> |
43 | #include <linux/clk.h> | 44 | #include <linux/clk.h> |
44 | #include <linux/cpufreq.h> | 45 | #include <linux/cpufreq.h> |
@@ -46,10 +47,9 @@ | |||
46 | 47 | ||
47 | #include <asm/irq.h> | 48 | #include <asm/irq.h> |
48 | 49 | ||
49 | #include <mach/hardware.h> | 50 | #ifdef CONFIG_SAMSUNG_CLOCK |
50 | |||
51 | #include <plat/regs-serial.h> | ||
52 | #include <plat/clock.h> | 51 | #include <plat/clock.h> |
52 | #endif | ||
53 | 53 | ||
54 | #include "samsung.h" | 54 | #include "samsung.h" |
55 | 55 | ||
@@ -446,6 +446,8 @@ static void s3c24xx_serial_shutdown(struct uart_port *port) | |||
446 | 446 | ||
447 | /* Clear pending interrupts and mask all interrupts */ | 447 | /* Clear pending interrupts and mask all interrupts */ |
448 | if (s3c24xx_serial_has_interrupt_mask(port)) { | 448 | if (s3c24xx_serial_has_interrupt_mask(port)) { |
449 | free_irq(port->irq, ourport); | ||
450 | |||
449 | wr_regl(port, S3C64XX_UINTP, 0xf); | 451 | wr_regl(port, S3C64XX_UINTP, 0xf); |
450 | wr_regl(port, S3C64XX_UINTM, 0xf); | 452 | wr_regl(port, S3C64XX_UINTM, 0xf); |
451 | } | 453 | } |
@@ -505,6 +507,8 @@ static int s3c64xx_serial_startup(struct uart_port *port) | |||
505 | dbg("s3c64xx_serial_startup: port=%p (%08lx,%p)\n", | 507 | dbg("s3c64xx_serial_startup: port=%p (%08lx,%p)\n", |
506 | port->mapbase, port->membase); | 508 | port->mapbase, port->membase); |
507 | 509 | ||
510 | wr_regl(port, S3C64XX_UINTM, 0xf); | ||
511 | |||
508 | ret = request_irq(port->irq, s3c64xx_serial_handle_irq, IRQF_SHARED, | 512 | ret = request_irq(port->irq, s3c64xx_serial_handle_irq, IRQF_SHARED, |
509 | s3c24xx_serial_portname(port), ourport); | 513 | s3c24xx_serial_portname(port), ourport); |
510 | if (ret) { | 514 | if (ret) { |
@@ -894,7 +898,7 @@ console_initcall(s3c24xx_serial_console_init); | |||
894 | #define S3C24XX_SERIAL_CONSOLE NULL | 898 | #define S3C24XX_SERIAL_CONSOLE NULL |
895 | #endif | 899 | #endif |
896 | 900 | ||
897 | #ifdef CONFIG_CONSOLE_POLL | 901 | #if defined(CONFIG_SERIAL_SAMSUNG_CONSOLE) && defined(CONFIG_CONSOLE_POLL) |
898 | static int s3c24xx_serial_get_poll_char(struct uart_port *port); | 902 | static int s3c24xx_serial_get_poll_char(struct uart_port *port); |
899 | static void s3c24xx_serial_put_poll_char(struct uart_port *port, | 903 | static void s3c24xx_serial_put_poll_char(struct uart_port *port, |
900 | unsigned char c); | 904 | unsigned char c); |
@@ -918,7 +922,7 @@ static struct uart_ops s3c24xx_serial_ops = { | |||
918 | .request_port = s3c24xx_serial_request_port, | 922 | .request_port = s3c24xx_serial_request_port, |
919 | .config_port = s3c24xx_serial_config_port, | 923 | .config_port = s3c24xx_serial_config_port, |
920 | .verify_port = s3c24xx_serial_verify_port, | 924 | .verify_port = s3c24xx_serial_verify_port, |
921 | #ifdef CONFIG_CONSOLE_POLL | 925 | #if defined(CONFIG_SERIAL_SAMSUNG_CONSOLE) && defined(CONFIG_CONSOLE_POLL) |
922 | .poll_get_char = s3c24xx_serial_get_poll_char, | 926 | .poll_get_char = s3c24xx_serial_get_poll_char, |
923 | .poll_put_char = s3c24xx_serial_put_poll_char, | 927 | .poll_put_char = s3c24xx_serial_put_poll_char, |
924 | #endif | 928 | #endif |
@@ -1179,6 +1183,7 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, | |||
1179 | return 0; | 1183 | return 0; |
1180 | } | 1184 | } |
1181 | 1185 | ||
1186 | #ifdef CONFIG_SAMSUNG_CLOCK | ||
1182 | static ssize_t s3c24xx_serial_show_clksrc(struct device *dev, | 1187 | static ssize_t s3c24xx_serial_show_clksrc(struct device *dev, |
1183 | struct device_attribute *attr, | 1188 | struct device_attribute *attr, |
1184 | char *buf) | 1189 | char *buf) |
@@ -1194,7 +1199,7 @@ static ssize_t s3c24xx_serial_show_clksrc(struct device *dev, | |||
1194 | } | 1199 | } |
1195 | 1200 | ||
1196 | static DEVICE_ATTR(clock_source, S_IRUGO, s3c24xx_serial_show_clksrc, NULL); | 1201 | static DEVICE_ATTR(clock_source, S_IRUGO, s3c24xx_serial_show_clksrc, NULL); |
1197 | 1202 | #endif | |
1198 | 1203 | ||
1199 | /* Device driver serial port probe */ | 1204 | /* Device driver serial port probe */ |
1200 | 1205 | ||
@@ -1252,9 +1257,11 @@ static int s3c24xx_serial_probe(struct platform_device *pdev) | |||
1252 | uart_add_one_port(&s3c24xx_uart_drv, &ourport->port); | 1257 | uart_add_one_port(&s3c24xx_uart_drv, &ourport->port); |
1253 | platform_set_drvdata(pdev, &ourport->port); | 1258 | platform_set_drvdata(pdev, &ourport->port); |
1254 | 1259 | ||
1260 | #ifdef CONFIG_SAMSUNG_CLOCK | ||
1255 | ret = device_create_file(&pdev->dev, &dev_attr_clock_source); | 1261 | ret = device_create_file(&pdev->dev, &dev_attr_clock_source); |
1256 | if (ret < 0) | 1262 | if (ret < 0) |
1257 | dev_err(&pdev->dev, "failed to add clock source attr.\n"); | 1263 | dev_err(&pdev->dev, "failed to add clock source attr.\n"); |
1264 | #endif | ||
1258 | 1265 | ||
1259 | ret = s3c24xx_serial_cpufreq_register(ourport); | 1266 | ret = s3c24xx_serial_cpufreq_register(ourport); |
1260 | if (ret < 0) | 1267 | if (ret < 0) |
@@ -1272,7 +1279,9 @@ static int s3c24xx_serial_remove(struct platform_device *dev) | |||
1272 | 1279 | ||
1273 | if (port) { | 1280 | if (port) { |
1274 | s3c24xx_serial_cpufreq_deregister(to_ourport(port)); | 1281 | s3c24xx_serial_cpufreq_deregister(to_ourport(port)); |
1282 | #ifdef CONFIG_SAMSUNG_CLOCK | ||
1275 | device_remove_file(&dev->dev, &dev_attr_clock_source); | 1283 | device_remove_file(&dev->dev, &dev_attr_clock_source); |
1284 | #endif | ||
1276 | uart_remove_one_port(&s3c24xx_uart_drv, port); | 1285 | uart_remove_one_port(&s3c24xx_uart_drv, port); |
1277 | } | 1286 | } |
1278 | 1287 | ||
@@ -1307,9 +1316,29 @@ static int s3c24xx_serial_resume(struct device *dev) | |||
1307 | return 0; | 1316 | return 0; |
1308 | } | 1317 | } |
1309 | 1318 | ||
1319 | static int s3c24xx_serial_resume_noirq(struct device *dev) | ||
1320 | { | ||
1321 | struct uart_port *port = s3c24xx_dev_to_port(dev); | ||
1322 | |||
1323 | if (port) { | ||
1324 | /* restore IRQ mask */ | ||
1325 | if (s3c24xx_serial_has_interrupt_mask(port)) { | ||
1326 | unsigned int uintm = 0xf; | ||
1327 | if (tx_enabled(port)) | ||
1328 | uintm &= ~S3C64XX_UINTM_TXD_MSK; | ||
1329 | if (rx_enabled(port)) | ||
1330 | uintm &= ~S3C64XX_UINTM_RXD_MSK; | ||
1331 | wr_regl(port, S3C64XX_UINTM, uintm); | ||
1332 | } | ||
1333 | } | ||
1334 | |||
1335 | return 0; | ||
1336 | } | ||
1337 | |||
1310 | static const struct dev_pm_ops s3c24xx_serial_pm_ops = { | 1338 | static const struct dev_pm_ops s3c24xx_serial_pm_ops = { |
1311 | .suspend = s3c24xx_serial_suspend, | 1339 | .suspend = s3c24xx_serial_suspend, |
1312 | .resume = s3c24xx_serial_resume, | 1340 | .resume = s3c24xx_serial_resume, |
1341 | .resume_noirq = s3c24xx_serial_resume_noirq, | ||
1313 | }; | 1342 | }; |
1314 | #define SERIAL_SAMSUNG_PM_OPS (&s3c24xx_serial_pm_ops) | 1343 | #define SERIAL_SAMSUNG_PM_OPS (&s3c24xx_serial_pm_ops) |
1315 | 1344 | ||
@@ -1343,6 +1372,13 @@ s3c24xx_serial_console_txrdy(struct uart_port *port, unsigned int ufcon) | |||
1343 | return (utrstat & S3C2410_UTRSTAT_TXE) ? 1 : 0; | 1372 | return (utrstat & S3C2410_UTRSTAT_TXE) ? 1 : 0; |
1344 | } | 1373 | } |
1345 | 1374 | ||
1375 | static bool | ||
1376 | s3c24xx_port_configured(unsigned int ucon) | ||
1377 | { | ||
1378 | /* consider the serial port configured if the tx/rx mode set */ | ||
1379 | return (ucon & 0xf) != 0; | ||
1380 | } | ||
1381 | |||
1346 | #ifdef CONFIG_CONSOLE_POLL | 1382 | #ifdef CONFIG_CONSOLE_POLL |
1347 | /* | 1383 | /* |
1348 | * Console polling routines for writing and reading from the uart while | 1384 | * Console polling routines for writing and reading from the uart while |
@@ -1365,6 +1401,11 @@ static void s3c24xx_serial_put_poll_char(struct uart_port *port, | |||
1365 | unsigned char c) | 1401 | unsigned char c) |
1366 | { | 1402 | { |
1367 | unsigned int ufcon = rd_regl(cons_uart, S3C2410_UFCON); | 1403 | unsigned int ufcon = rd_regl(cons_uart, S3C2410_UFCON); |
1404 | unsigned int ucon = rd_regl(cons_uart, S3C2410_UCON); | ||
1405 | |||
1406 | /* not possible to xmit on unconfigured port */ | ||
1407 | if (!s3c24xx_port_configured(ucon)) | ||
1408 | return; | ||
1368 | 1409 | ||
1369 | while (!s3c24xx_serial_console_txrdy(port, ufcon)) | 1410 | while (!s3c24xx_serial_console_txrdy(port, ufcon)) |
1370 | cpu_relax(); | 1411 | cpu_relax(); |
@@ -1377,6 +1418,12 @@ static void | |||
1377 | s3c24xx_serial_console_putchar(struct uart_port *port, int ch) | 1418 | s3c24xx_serial_console_putchar(struct uart_port *port, int ch) |
1378 | { | 1419 | { |
1379 | unsigned int ufcon = rd_regl(cons_uart, S3C2410_UFCON); | 1420 | unsigned int ufcon = rd_regl(cons_uart, S3C2410_UFCON); |
1421 | unsigned int ucon = rd_regl(cons_uart, S3C2410_UCON); | ||
1422 | |||
1423 | /* not possible to xmit on unconfigured port */ | ||
1424 | if (!s3c24xx_port_configured(ucon)) | ||
1425 | return; | ||
1426 | |||
1380 | while (!s3c24xx_serial_console_txrdy(port, ufcon)) | 1427 | while (!s3c24xx_serial_console_txrdy(port, ufcon)) |
1381 | barrier(); | 1428 | barrier(); |
1382 | wr_regb(cons_uart, S3C2410_UTXH, ch); | 1429 | wr_regb(cons_uart, S3C2410_UTXH, ch); |
@@ -1409,9 +1456,7 @@ s3c24xx_serial_get_options(struct uart_port *port, int *baud, | |||
1409 | "registers: ulcon=%08x, ucon=%08x, ubdriv=%08x\n", | 1456 | "registers: ulcon=%08x, ucon=%08x, ubdriv=%08x\n", |
1410 | port, ulcon, ucon, ubrdiv); | 1457 | port, ulcon, ucon, ubrdiv); |
1411 | 1458 | ||
1412 | if ((ucon & 0xf) != 0) { | 1459 | if (s3c24xx_port_configured(ucon)) { |
1413 | /* consider the serial port configured if the tx/rx mode set */ | ||
1414 | |||
1415 | switch (ulcon & S3C2410_LCON_CSMASK) { | 1460 | switch (ulcon & S3C2410_LCON_CSMASK) { |
1416 | case S3C2410_LCON_CS5: | 1461 | case S3C2410_LCON_CS5: |
1417 | *bits = 5; | 1462 | *bits = 5; |
diff --git a/drivers/tty/serial/samsung.h b/drivers/tty/serial/samsung.h index 1a4bca3e4179..00a499ecd385 100644 --- a/drivers/tty/serial/samsung.h +++ b/drivers/tty/serial/samsung.h | |||
@@ -76,7 +76,9 @@ struct s3c24xx_uart_port { | |||
76 | #define wr_regb(port, reg, val) __raw_writeb(val, portaddr(port, reg)) | 76 | #define wr_regb(port, reg, val) __raw_writeb(val, portaddr(port, reg)) |
77 | #define wr_regl(port, reg, val) __raw_writel(val, portaddr(port, reg)) | 77 | #define wr_regl(port, reg, val) __raw_writel(val, portaddr(port, reg)) |
78 | 78 | ||
79 | #ifdef CONFIG_SERIAL_SAMSUNG_DEBUG | 79 | #if defined(CONFIG_SERIAL_SAMSUNG_DEBUG) && \ |
80 | defined(CONFIG_DEBUG_LL) && \ | ||
81 | !defined(MODULE) | ||
80 | 82 | ||
81 | extern void printascii(const char *); | 83 | extern void printascii(const char *); |
82 | 84 | ||
diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c index 08dbfb88d42c..c77304155410 100644 --- a/drivers/tty/serial/sccnxp.c +++ b/drivers/tty/serial/sccnxp.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/spinlock.h> | 27 | #include <linux/spinlock.h> |
28 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
29 | #include <linux/platform_data/serial-sccnxp.h> | 29 | #include <linux/platform_data/serial-sccnxp.h> |
30 | #include <linux/regulator/consumer.h> | ||
30 | 31 | ||
31 | #define SCCNXP_NAME "uart-sccnxp" | 32 | #define SCCNXP_NAME "uart-sccnxp" |
32 | #define SCCNXP_MAJOR 204 | 33 | #define SCCNXP_MAJOR 204 |
@@ -131,6 +132,8 @@ struct sccnxp_port { | |||
131 | struct timer_list timer; | 132 | struct timer_list timer; |
132 | 133 | ||
133 | struct sccnxp_pdata pdata; | 134 | struct sccnxp_pdata pdata; |
135 | |||
136 | struct regulator *regulator; | ||
134 | }; | 137 | }; |
135 | 138 | ||
136 | static inline u8 sccnxp_raw_read(void __iomem *base, u8 reg, u8 shift) | 139 | static inline u8 sccnxp_raw_read(void __iomem *base, u8 reg, u8 shift) |
@@ -789,8 +792,6 @@ static int sccnxp_probe(struct platform_device *pdev) | |||
789 | return -EADDRNOTAVAIL; | 792 | return -EADDRNOTAVAIL; |
790 | } | 793 | } |
791 | 794 | ||
792 | dev_set_name(&pdev->dev, SCCNXP_NAME); | ||
793 | |||
794 | s = devm_kzalloc(&pdev->dev, sizeof(struct sccnxp_port), GFP_KERNEL); | 795 | s = devm_kzalloc(&pdev->dev, sizeof(struct sccnxp_port), GFP_KERNEL); |
795 | if (!s) { | 796 | if (!s) { |
796 | dev_err(&pdev->dev, "Error allocating port structure\n"); | 797 | dev_err(&pdev->dev, "Error allocating port structure\n"); |
@@ -918,6 +919,16 @@ static int sccnxp_probe(struct platform_device *pdev) | |||
918 | goto err_out; | 919 | goto err_out; |
919 | } | 920 | } |
920 | 921 | ||
922 | s->regulator = devm_regulator_get(&pdev->dev, "VCC"); | ||
923 | if (!IS_ERR(s->regulator)) { | ||
924 | ret = regulator_enable(s->regulator); | ||
925 | if (ret) { | ||
926 | dev_err(&pdev->dev, | ||
927 | "Failed to enable regulator: %i\n", ret); | ||
928 | return ret; | ||
929 | } | ||
930 | } | ||
931 | |||
921 | membase = devm_ioremap_resource(&pdev->dev, res); | 932 | membase = devm_ioremap_resource(&pdev->dev, res); |
922 | if (IS_ERR(membase)) { | 933 | if (IS_ERR(membase)) { |
923 | ret = PTR_ERR(membase); | 934 | ret = PTR_ERR(membase); |
@@ -967,10 +978,6 @@ static int sccnxp_probe(struct platform_device *pdev) | |||
967 | s->imr = 0; | 978 | s->imr = 0; |
968 | sccnxp_write(&s->port[0], SCCNXP_IMR_REG, 0); | 979 | sccnxp_write(&s->port[0], SCCNXP_IMR_REG, 0); |
969 | 980 | ||
970 | /* Board specific configure */ | ||
971 | if (s->pdata.init) | ||
972 | s->pdata.init(); | ||
973 | |||
974 | if (!s->poll) { | 981 | if (!s->poll) { |
975 | ret = devm_request_threaded_irq(&pdev->dev, s->irq, NULL, | 982 | ret = devm_request_threaded_irq(&pdev->dev, s->irq, NULL, |
976 | sccnxp_ist, | 983 | sccnxp_ist, |
@@ -1011,8 +1018,8 @@ static int sccnxp_remove(struct platform_device *pdev) | |||
1011 | uart_unregister_driver(&s->uart); | 1018 | uart_unregister_driver(&s->uart); |
1012 | platform_set_drvdata(pdev, NULL); | 1019 | platform_set_drvdata(pdev, NULL); |
1013 | 1020 | ||
1014 | if (s->pdata.exit) | 1021 | if (!IS_ERR(s->regulator)) |
1015 | s->pdata.exit(); | 1022 | return regulator_disable(s->regulator); |
1016 | 1023 | ||
1017 | return 0; | 1024 | return 0; |
1018 | } | 1025 | } |
diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index 372de8ade76a..9799d043a9bd 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/dmaengine.h> | 26 | #include <linux/dmaengine.h> |
27 | #include <linux/dma-mapping.h> | 27 | #include <linux/dma-mapping.h> |
28 | #include <linux/dmapool.h> | 28 | #include <linux/dmapool.h> |
29 | #include <linux/err.h> | ||
29 | #include <linux/io.h> | 30 | #include <linux/io.h> |
30 | #include <linux/irq.h> | 31 | #include <linux/irq.h> |
31 | #include <linux/module.h> | 32 | #include <linux/module.h> |
@@ -1301,11 +1302,9 @@ static int tegra_uart_probe(struct platform_device *pdev) | |||
1301 | } | 1302 | } |
1302 | 1303 | ||
1303 | u->mapbase = resource->start; | 1304 | u->mapbase = resource->start; |
1304 | u->membase = devm_request_and_ioremap(&pdev->dev, resource); | 1305 | u->membase = devm_ioremap_resource(&pdev->dev, resource); |
1305 | if (!u->membase) { | 1306 | if (IS_ERR(u->membase)) |
1306 | dev_err(&pdev->dev, "memregion/iomap address req failed\n"); | 1307 | return PTR_ERR(u->membase); |
1307 | return -EADDRNOTAVAIL; | ||
1308 | } | ||
1309 | 1308 | ||
1310 | tup->uart_clk = devm_clk_get(&pdev->dev, NULL); | 1309 | tup->uart_clk = devm_clk_get(&pdev->dev, NULL); |
1311 | if (IS_ERR(tup->uart_clk)) { | 1310 | if (IS_ERR(tup->uart_clk)) { |
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index a400002dfa84..8fbb6d22cdc8 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c | |||
@@ -1941,6 +1941,8 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) | |||
1941 | mutex_unlock(&port->mutex); | 1941 | mutex_unlock(&port->mutex); |
1942 | return 0; | 1942 | return 0; |
1943 | } | 1943 | } |
1944 | put_device(tty_dev); | ||
1945 | |||
1944 | if (console_suspend_enabled || !uart_console(uport)) | 1946 | if (console_suspend_enabled || !uart_console(uport)) |
1945 | uport->suspended = 1; | 1947 | uport->suspended = 1; |
1946 | 1948 | ||
@@ -2006,9 +2008,11 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) | |||
2006 | disable_irq_wake(uport->irq); | 2008 | disable_irq_wake(uport->irq); |
2007 | uport->irq_wake = 0; | 2009 | uport->irq_wake = 0; |
2008 | } | 2010 | } |
2011 | put_device(tty_dev); | ||
2009 | mutex_unlock(&port->mutex); | 2012 | mutex_unlock(&port->mutex); |
2010 | return 0; | 2013 | return 0; |
2011 | } | 2014 | } |
2015 | put_device(tty_dev); | ||
2012 | uport->suspended = 0; | 2016 | uport->suspended = 0; |
2013 | 2017 | ||
2014 | /* | 2018 | /* |
diff --git a/drivers/tty/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h index 4c22a1529aac..5aca7364634c 100644 --- a/drivers/tty/serial/sh-sci.h +++ b/drivers/tty/serial/sh-sci.h | |||
@@ -15,8 +15,6 @@ | |||
15 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | 15 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ |
16 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ | 16 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ |
17 | defined(CONFIG_ARCH_SH73A0) || \ | 17 | defined(CONFIG_ARCH_SH73A0) || \ |
18 | defined(CONFIG_ARCH_SH7367) || \ | ||
19 | defined(CONFIG_ARCH_SH7377) || \ | ||
20 | defined(CONFIG_ARCH_SH7372) || \ | 18 | defined(CONFIG_ARCH_SH7372) || \ |
21 | defined(CONFIG_ARCH_R8A7740) | 19 | defined(CONFIG_ARCH_R8A7740) |
22 | 20 | ||
diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c index 6bbfe9934a4d..03465b673945 100644 --- a/drivers/tty/serial/sirfsoc_uart.c +++ b/drivers/tty/serial/sirfsoc_uart.c | |||
@@ -758,7 +758,7 @@ static struct of_device_id sirfsoc_uart_ids[] = { | |||
758 | { .compatible = "sirf,marco-uart", }, | 758 | { .compatible = "sirf,marco-uart", }, |
759 | {} | 759 | {} |
760 | }; | 760 | }; |
761 | MODULE_DEVICE_TABLE(of, sirfsoc_serial_of_match); | 761 | MODULE_DEVICE_TABLE(of, sirfsoc_uart_ids); |
762 | 762 | ||
763 | static struct platform_driver sirfsoc_uart_driver = { | 763 | static struct platform_driver sirfsoc_uart_driver = { |
764 | .probe = sirfsoc_uart_probe, | 764 | .probe = sirfsoc_uart_probe, |
diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c index 8de2213664e0..a422c8b55a47 100644 --- a/drivers/tty/serial/sunsab.c +++ b/drivers/tty/serial/sunsab.c | |||
@@ -203,7 +203,7 @@ receive_chars(struct uart_sunsab_port *up, | |||
203 | flag = TTY_FRAME; | 203 | flag = TTY_FRAME; |
204 | } | 204 | } |
205 | 205 | ||
206 | if (uart_handle_sysrq_char(&up->port, ch)) | 206 | if (uart_handle_sysrq_char(&up->port, ch) || !port) |
207 | continue; | 207 | continue; |
208 | 208 | ||
209 | if ((stat->sreg.isr0 & (up->port.ignore_status_mask & 0xff)) == 0 && | 209 | if ((stat->sreg.isr0 & (up->port.ignore_status_mask & 0xff)) == 0 && |
diff --git a/drivers/tty/serial/sunzilog.c b/drivers/tty/serial/sunzilog.c index 27669ff3d446..813ef8eb8eff 100644 --- a/drivers/tty/serial/sunzilog.c +++ b/drivers/tty/serial/sunzilog.c | |||
@@ -388,7 +388,7 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up, | |||
388 | else if (r1 & CRC_ERR) | 388 | else if (r1 & CRC_ERR) |
389 | flag = TTY_FRAME; | 389 | flag = TTY_FRAME; |
390 | } | 390 | } |
391 | if (uart_handle_sysrq_char(&up->port, ch)) | 391 | if (uart_handle_sysrq_char(&up->port, ch) || !port) |
392 | continue; | 392 | continue; |
393 | 393 | ||
394 | if (up->port.ignore_status_mask == 0xff || | 394 | if (up->port.ignore_status_mask == 0xff || |
diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c index 705240e6c4ec..1a8bc2275ea4 100644 --- a/drivers/tty/serial/vt8500_serial.c +++ b/drivers/tty/serial/vt8500_serial.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/clk.h> | 35 | #include <linux/clk.h> |
36 | #include <linux/platform_device.h> | 36 | #include <linux/platform_device.h> |
37 | #include <linux/of.h> | 37 | #include <linux/of.h> |
38 | #include <linux/err.h> | ||
38 | 39 | ||
39 | /* | 40 | /* |
40 | * UART Register offsets | 41 | * UART Register offsets |
@@ -585,9 +586,9 @@ static int vt8500_serial_probe(struct platform_device *pdev) | |||
585 | if (!vt8500_port) | 586 | if (!vt8500_port) |
586 | return -ENOMEM; | 587 | return -ENOMEM; |
587 | 588 | ||
588 | vt8500_port->uart.membase = devm_request_and_ioremap(&pdev->dev, mmres); | 589 | vt8500_port->uart.membase = devm_ioremap_resource(&pdev->dev, mmres); |
589 | if (!vt8500_port->uart.membase) | 590 | if (IS_ERR(vt8500_port->uart.membase)) |
590 | return -EADDRNOTAVAIL; | 591 | return PTR_ERR(vt8500_port->uart.membase); |
591 | 592 | ||
592 | vt8500_port->clk = of_clk_get(pdev->dev.of_node, 0); | 593 | vt8500_port->clk = of_clk_get(pdev->dev.of_node, 0); |
593 | if (IS_ERR(vt8500_port->clk)) { | 594 | if (IS_ERR(vt8500_port->clk)) { |
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index f36bbba1ac8b..4e5c77834c50 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c | |||
@@ -585,9 +585,6 @@ static int xuartps_startup(struct uart_port *port) | |||
585 | xuartps_writel(XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_PARITY | | 585 | xuartps_writel(XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_PARITY | |
586 | XUARTPS_IXR_FRAMING | XUARTPS_IXR_OVERRUN | | 586 | XUARTPS_IXR_FRAMING | XUARTPS_IXR_OVERRUN | |
587 | XUARTPS_IXR_RXTRIG | XUARTPS_IXR_TOUT, XUARTPS_IER_OFFSET); | 587 | XUARTPS_IXR_RXTRIG | XUARTPS_IXR_TOUT, XUARTPS_IER_OFFSET); |
588 | xuartps_writel(~(XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_PARITY | | ||
589 | XUARTPS_IXR_FRAMING | XUARTPS_IXR_OVERRUN | | ||
590 | XUARTPS_IXR_RXTRIG | XUARTPS_IXR_TOUT), XUARTPS_IDR_OFFSET); | ||
591 | 588 | ||
592 | return retval; | 589 | return retval; |
593 | } | 590 | } |
diff --git a/drivers/tty/synclink.c b/drivers/tty/synclink.c index 8983276aa35e..8eaf1ab8addb 100644 --- a/drivers/tty/synclink.c +++ b/drivers/tty/synclink.c | |||
@@ -1058,9 +1058,6 @@ static void mgsl_bh_handler(struct work_struct *work) | |||
1058 | container_of(work, struct mgsl_struct, task); | 1058 | container_of(work, struct mgsl_struct, task); |
1059 | int action; | 1059 | int action; |
1060 | 1060 | ||
1061 | if (!info) | ||
1062 | return; | ||
1063 | |||
1064 | if ( debug_level >= DEBUG_LEVEL_BH ) | 1061 | if ( debug_level >= DEBUG_LEVEL_BH ) |
1065 | printk( "%s(%d):mgsl_bh_handler(%s) entry\n", | 1062 | printk( "%s(%d):mgsl_bh_handler(%s) entry\n", |
1066 | __FILE__,__LINE__,info->device_name); | 1063 | __FILE__,__LINE__,info->device_name); |
@@ -3311,7 +3308,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
3311 | port->blocked_open++; | 3308 | port->blocked_open++; |
3312 | 3309 | ||
3313 | while (1) { | 3310 | while (1) { |
3314 | if (tty->termios.c_cflag & CBAUD) | 3311 | if (C_BAUD(tty) && test_bit(ASYNCB_INITIALIZED, &port->flags)) |
3315 | tty_port_raise_dtr_rts(port); | 3312 | tty_port_raise_dtr_rts(port); |
3316 | 3313 | ||
3317 | set_current_state(TASK_INTERRUPTIBLE); | 3314 | set_current_state(TASK_INTERRUPTIBLE); |
diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index aa9eece35c3b..1abf946463f6 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c | |||
@@ -3308,7 +3308,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3308 | port->blocked_open++; | 3308 | port->blocked_open++; |
3309 | 3309 | ||
3310 | while (1) { | 3310 | while (1) { |
3311 | if ((tty->termios.c_cflag & CBAUD)) | 3311 | if (C_BAUD(tty) && test_bit(ASYNCB_INITIALIZED, &port->flags)) |
3312 | tty_port_raise_dtr_rts(port); | 3312 | tty_port_raise_dtr_rts(port); |
3313 | 3313 | ||
3314 | set_current_state(TASK_INTERRUPTIBLE); | 3314 | set_current_state(TASK_INTERRUPTIBLE); |
diff --git a/drivers/tty/synclinkmp.c b/drivers/tty/synclinkmp.c index 6d5780cf1d57..ff171384ea52 100644 --- a/drivers/tty/synclinkmp.c +++ b/drivers/tty/synclinkmp.c | |||
@@ -3329,7 +3329,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3329 | port->blocked_open++; | 3329 | port->blocked_open++; |
3330 | 3330 | ||
3331 | while (1) { | 3331 | while (1) { |
3332 | if (tty->termios.c_cflag & CBAUD) | 3332 | if (C_BAUD(tty) && test_bit(ASYNCB_INITIALIZED, &port->flags)) |
3333 | tty_port_raise_dtr_rts(port); | 3333 | tty_port_raise_dtr_rts(port); |
3334 | 3334 | ||
3335 | set_current_state(TASK_INTERRUPTIBLE); | 3335 | set_current_state(TASK_INTERRUPTIBLE); |
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 3687f0cad642..0a0de333c765 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c | |||
@@ -101,7 +101,7 @@ static void sysrq_handle_SAK(int key) | |||
101 | } | 101 | } |
102 | static struct sysrq_key_op sysrq_SAK_op = { | 102 | static struct sysrq_key_op sysrq_SAK_op = { |
103 | .handler = sysrq_handle_SAK, | 103 | .handler = sysrq_handle_SAK, |
104 | .help_msg = "saK", | 104 | .help_msg = "sak(k)", |
105 | .action_msg = "SAK", | 105 | .action_msg = "SAK", |
106 | .enable_mask = SYSRQ_ENABLE_KEYBOARD, | 106 | .enable_mask = SYSRQ_ENABLE_KEYBOARD, |
107 | }; | 107 | }; |
@@ -117,7 +117,7 @@ static void sysrq_handle_unraw(int key) | |||
117 | 117 | ||
118 | static struct sysrq_key_op sysrq_unraw_op = { | 118 | static struct sysrq_key_op sysrq_unraw_op = { |
119 | .handler = sysrq_handle_unraw, | 119 | .handler = sysrq_handle_unraw, |
120 | .help_msg = "unRaw", | 120 | .help_msg = "unraw(r)", |
121 | .action_msg = "Keyboard mode set to system default", | 121 | .action_msg = "Keyboard mode set to system default", |
122 | .enable_mask = SYSRQ_ENABLE_KEYBOARD, | 122 | .enable_mask = SYSRQ_ENABLE_KEYBOARD, |
123 | }; | 123 | }; |
@@ -135,7 +135,7 @@ static void sysrq_handle_crash(int key) | |||
135 | } | 135 | } |
136 | static struct sysrq_key_op sysrq_crash_op = { | 136 | static struct sysrq_key_op sysrq_crash_op = { |
137 | .handler = sysrq_handle_crash, | 137 | .handler = sysrq_handle_crash, |
138 | .help_msg = "Crash", | 138 | .help_msg = "crash(c)", |
139 | .action_msg = "Trigger a crash", | 139 | .action_msg = "Trigger a crash", |
140 | .enable_mask = SYSRQ_ENABLE_DUMP, | 140 | .enable_mask = SYSRQ_ENABLE_DUMP, |
141 | }; | 141 | }; |
@@ -148,7 +148,7 @@ static void sysrq_handle_reboot(int key) | |||
148 | } | 148 | } |
149 | static struct sysrq_key_op sysrq_reboot_op = { | 149 | static struct sysrq_key_op sysrq_reboot_op = { |
150 | .handler = sysrq_handle_reboot, | 150 | .handler = sysrq_handle_reboot, |
151 | .help_msg = "reBoot", | 151 | .help_msg = "reboot(b)", |
152 | .action_msg = "Resetting", | 152 | .action_msg = "Resetting", |
153 | .enable_mask = SYSRQ_ENABLE_BOOT, | 153 | .enable_mask = SYSRQ_ENABLE_BOOT, |
154 | }; | 154 | }; |
@@ -159,7 +159,7 @@ static void sysrq_handle_sync(int key) | |||
159 | } | 159 | } |
160 | static struct sysrq_key_op sysrq_sync_op = { | 160 | static struct sysrq_key_op sysrq_sync_op = { |
161 | .handler = sysrq_handle_sync, | 161 | .handler = sysrq_handle_sync, |
162 | .help_msg = "Sync", | 162 | .help_msg = "sync(s)", |
163 | .action_msg = "Emergency Sync", | 163 | .action_msg = "Emergency Sync", |
164 | .enable_mask = SYSRQ_ENABLE_SYNC, | 164 | .enable_mask = SYSRQ_ENABLE_SYNC, |
165 | }; | 165 | }; |
@@ -171,7 +171,7 @@ static void sysrq_handle_show_timers(int key) | |||
171 | 171 | ||
172 | static struct sysrq_key_op sysrq_show_timers_op = { | 172 | static struct sysrq_key_op sysrq_show_timers_op = { |
173 | .handler = sysrq_handle_show_timers, | 173 | .handler = sysrq_handle_show_timers, |
174 | .help_msg = "show-all-timers(Q)", | 174 | .help_msg = "show-all-timers(q)", |
175 | .action_msg = "Show clockevent devices & pending hrtimers (no others)", | 175 | .action_msg = "Show clockevent devices & pending hrtimers (no others)", |
176 | }; | 176 | }; |
177 | 177 | ||
@@ -181,7 +181,7 @@ static void sysrq_handle_mountro(int key) | |||
181 | } | 181 | } |
182 | static struct sysrq_key_op sysrq_mountro_op = { | 182 | static struct sysrq_key_op sysrq_mountro_op = { |
183 | .handler = sysrq_handle_mountro, | 183 | .handler = sysrq_handle_mountro, |
184 | .help_msg = "Unmount", | 184 | .help_msg = "unmount(u)", |
185 | .action_msg = "Emergency Remount R/O", | 185 | .action_msg = "Emergency Remount R/O", |
186 | .enable_mask = SYSRQ_ENABLE_REMOUNT, | 186 | .enable_mask = SYSRQ_ENABLE_REMOUNT, |
187 | }; | 187 | }; |
@@ -194,7 +194,7 @@ static void sysrq_handle_showlocks(int key) | |||
194 | 194 | ||
195 | static struct sysrq_key_op sysrq_showlocks_op = { | 195 | static struct sysrq_key_op sysrq_showlocks_op = { |
196 | .handler = sysrq_handle_showlocks, | 196 | .handler = sysrq_handle_showlocks, |
197 | .help_msg = "show-all-locks(D)", | 197 | .help_msg = "show-all-locks(d)", |
198 | .action_msg = "Show Locks Held", | 198 | .action_msg = "Show Locks Held", |
199 | }; | 199 | }; |
200 | #else | 200 | #else |
@@ -245,7 +245,7 @@ static void sysrq_handle_showallcpus(int key) | |||
245 | 245 | ||
246 | static struct sysrq_key_op sysrq_showallcpus_op = { | 246 | static struct sysrq_key_op sysrq_showallcpus_op = { |
247 | .handler = sysrq_handle_showallcpus, | 247 | .handler = sysrq_handle_showallcpus, |
248 | .help_msg = "show-backtrace-all-active-cpus(L)", | 248 | .help_msg = "show-backtrace-all-active-cpus(l)", |
249 | .action_msg = "Show backtrace of all active CPUs", | 249 | .action_msg = "Show backtrace of all active CPUs", |
250 | .enable_mask = SYSRQ_ENABLE_DUMP, | 250 | .enable_mask = SYSRQ_ENABLE_DUMP, |
251 | }; | 251 | }; |
@@ -260,7 +260,7 @@ static void sysrq_handle_showregs(int key) | |||
260 | } | 260 | } |
261 | static struct sysrq_key_op sysrq_showregs_op = { | 261 | static struct sysrq_key_op sysrq_showregs_op = { |
262 | .handler = sysrq_handle_showregs, | 262 | .handler = sysrq_handle_showregs, |
263 | .help_msg = "show-registers(P)", | 263 | .help_msg = "show-registers(p)", |
264 | .action_msg = "Show Regs", | 264 | .action_msg = "Show Regs", |
265 | .enable_mask = SYSRQ_ENABLE_DUMP, | 265 | .enable_mask = SYSRQ_ENABLE_DUMP, |
266 | }; | 266 | }; |
@@ -271,7 +271,7 @@ static void sysrq_handle_showstate(int key) | |||
271 | } | 271 | } |
272 | static struct sysrq_key_op sysrq_showstate_op = { | 272 | static struct sysrq_key_op sysrq_showstate_op = { |
273 | .handler = sysrq_handle_showstate, | 273 | .handler = sysrq_handle_showstate, |
274 | .help_msg = "show-task-states(T)", | 274 | .help_msg = "show-task-states(t)", |
275 | .action_msg = "Show State", | 275 | .action_msg = "Show State", |
276 | .enable_mask = SYSRQ_ENABLE_DUMP, | 276 | .enable_mask = SYSRQ_ENABLE_DUMP, |
277 | }; | 277 | }; |
@@ -282,7 +282,7 @@ static void sysrq_handle_showstate_blocked(int key) | |||
282 | } | 282 | } |
283 | static struct sysrq_key_op sysrq_showstate_blocked_op = { | 283 | static struct sysrq_key_op sysrq_showstate_blocked_op = { |
284 | .handler = sysrq_handle_showstate_blocked, | 284 | .handler = sysrq_handle_showstate_blocked, |
285 | .help_msg = "show-blocked-tasks(W)", | 285 | .help_msg = "show-blocked-tasks(w)", |
286 | .action_msg = "Show Blocked State", | 286 | .action_msg = "Show Blocked State", |
287 | .enable_mask = SYSRQ_ENABLE_DUMP, | 287 | .enable_mask = SYSRQ_ENABLE_DUMP, |
288 | }; | 288 | }; |
@@ -296,7 +296,7 @@ static void sysrq_ftrace_dump(int key) | |||
296 | } | 296 | } |
297 | static struct sysrq_key_op sysrq_ftrace_dump_op = { | 297 | static struct sysrq_key_op sysrq_ftrace_dump_op = { |
298 | .handler = sysrq_ftrace_dump, | 298 | .handler = sysrq_ftrace_dump, |
299 | .help_msg = "dump-ftrace-buffer(Z)", | 299 | .help_msg = "dump-ftrace-buffer(z)", |
300 | .action_msg = "Dump ftrace buffer", | 300 | .action_msg = "Dump ftrace buffer", |
301 | .enable_mask = SYSRQ_ENABLE_DUMP, | 301 | .enable_mask = SYSRQ_ENABLE_DUMP, |
302 | }; | 302 | }; |
@@ -310,7 +310,7 @@ static void sysrq_handle_showmem(int key) | |||
310 | } | 310 | } |
311 | static struct sysrq_key_op sysrq_showmem_op = { | 311 | static struct sysrq_key_op sysrq_showmem_op = { |
312 | .handler = sysrq_handle_showmem, | 312 | .handler = sysrq_handle_showmem, |
313 | .help_msg = "show-memory-usage(M)", | 313 | .help_msg = "show-memory-usage(m)", |
314 | .action_msg = "Show Memory", | 314 | .action_msg = "Show Memory", |
315 | .enable_mask = SYSRQ_ENABLE_DUMP, | 315 | .enable_mask = SYSRQ_ENABLE_DUMP, |
316 | }; | 316 | }; |
@@ -341,7 +341,7 @@ static void sysrq_handle_term(int key) | |||
341 | } | 341 | } |
342 | static struct sysrq_key_op sysrq_term_op = { | 342 | static struct sysrq_key_op sysrq_term_op = { |
343 | .handler = sysrq_handle_term, | 343 | .handler = sysrq_handle_term, |
344 | .help_msg = "terminate-all-tasks(E)", | 344 | .help_msg = "terminate-all-tasks(e)", |
345 | .action_msg = "Terminate All Tasks", | 345 | .action_msg = "Terminate All Tasks", |
346 | .enable_mask = SYSRQ_ENABLE_SIGNAL, | 346 | .enable_mask = SYSRQ_ENABLE_SIGNAL, |
347 | }; | 347 | }; |
@@ -360,7 +360,7 @@ static void sysrq_handle_moom(int key) | |||
360 | } | 360 | } |
361 | static struct sysrq_key_op sysrq_moom_op = { | 361 | static struct sysrq_key_op sysrq_moom_op = { |
362 | .handler = sysrq_handle_moom, | 362 | .handler = sysrq_handle_moom, |
363 | .help_msg = "memory-full-oom-kill(F)", | 363 | .help_msg = "memory-full-oom-kill(f)", |
364 | .action_msg = "Manual OOM execution", | 364 | .action_msg = "Manual OOM execution", |
365 | .enable_mask = SYSRQ_ENABLE_SIGNAL, | 365 | .enable_mask = SYSRQ_ENABLE_SIGNAL, |
366 | }; | 366 | }; |
@@ -372,7 +372,7 @@ static void sysrq_handle_thaw(int key) | |||
372 | } | 372 | } |
373 | static struct sysrq_key_op sysrq_thaw_op = { | 373 | static struct sysrq_key_op sysrq_thaw_op = { |
374 | .handler = sysrq_handle_thaw, | 374 | .handler = sysrq_handle_thaw, |
375 | .help_msg = "thaw-filesystems(J)", | 375 | .help_msg = "thaw-filesystems(j)", |
376 | .action_msg = "Emergency Thaw of all frozen filesystems", | 376 | .action_msg = "Emergency Thaw of all frozen filesystems", |
377 | .enable_mask = SYSRQ_ENABLE_SIGNAL, | 377 | .enable_mask = SYSRQ_ENABLE_SIGNAL, |
378 | }; | 378 | }; |
@@ -385,7 +385,7 @@ static void sysrq_handle_kill(int key) | |||
385 | } | 385 | } |
386 | static struct sysrq_key_op sysrq_kill_op = { | 386 | static struct sysrq_key_op sysrq_kill_op = { |
387 | .handler = sysrq_handle_kill, | 387 | .handler = sysrq_handle_kill, |
388 | .help_msg = "kill-all-tasks(I)", | 388 | .help_msg = "kill-all-tasks(i)", |
389 | .action_msg = "Kill All Tasks", | 389 | .action_msg = "Kill All Tasks", |
390 | .enable_mask = SYSRQ_ENABLE_SIGNAL, | 390 | .enable_mask = SYSRQ_ENABLE_SIGNAL, |
391 | }; | 391 | }; |
@@ -396,7 +396,7 @@ static void sysrq_handle_unrt(int key) | |||
396 | } | 396 | } |
397 | static struct sysrq_key_op sysrq_unrt_op = { | 397 | static struct sysrq_key_op sysrq_unrt_op = { |
398 | .handler = sysrq_handle_unrt, | 398 | .handler = sysrq_handle_unrt, |
399 | .help_msg = "nice-all-RT-tasks(N)", | 399 | .help_msg = "nice-all-RT-tasks(n)", |
400 | .action_msg = "Nice All RT Tasks", | 400 | .action_msg = "Nice All RT Tasks", |
401 | .enable_mask = SYSRQ_ENABLE_RTNICE, | 401 | .enable_mask = SYSRQ_ENABLE_RTNICE, |
402 | }; | 402 | }; |
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 578aa7594b11..9121c1f7aeef 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c | |||
@@ -449,11 +449,6 @@ static void flush_to_ldisc(struct work_struct *work) | |||
449 | tty_buffer_free(port, head); | 449 | tty_buffer_free(port, head); |
450 | continue; | 450 | continue; |
451 | } | 451 | } |
452 | /* Ldisc or user is trying to flush the buffers | ||
453 | we are feeding to the ldisc, stop feeding the | ||
454 | line discipline as we want to empty the queue */ | ||
455 | if (test_bit(TTYP_FLUSHPENDING, &port->iflags)) | ||
456 | break; | ||
457 | if (!tty->receive_room) | 452 | if (!tty->receive_room) |
458 | break; | 453 | break; |
459 | if (count > tty->receive_room) | 454 | if (count > tty->receive_room) |
@@ -465,17 +460,20 @@ static void flush_to_ldisc(struct work_struct *work) | |||
465 | disc->ops->receive_buf(tty, char_buf, | 460 | disc->ops->receive_buf(tty, char_buf, |
466 | flag_buf, count); | 461 | flag_buf, count); |
467 | spin_lock_irqsave(&buf->lock, flags); | 462 | spin_lock_irqsave(&buf->lock, flags); |
463 | /* Ldisc or user is trying to flush the buffers. | ||
464 | We may have a deferred request to flush the | ||
465 | input buffer, if so pull the chain under the lock | ||
466 | and empty the queue */ | ||
467 | if (test_bit(TTYP_FLUSHPENDING, &port->iflags)) { | ||
468 | __tty_buffer_flush(port); | ||
469 | clear_bit(TTYP_FLUSHPENDING, &port->iflags); | ||
470 | wake_up(&tty->read_wait); | ||
471 | break; | ||
472 | } | ||
468 | } | 473 | } |
469 | clear_bit(TTYP_FLUSHING, &port->iflags); | 474 | clear_bit(TTYP_FLUSHING, &port->iflags); |
470 | } | 475 | } |
471 | 476 | ||
472 | /* We may have a deferred request to flush the input buffer, | ||
473 | if so pull the chain under the lock and empty the queue */ | ||
474 | if (test_bit(TTYP_FLUSHPENDING, &port->iflags)) { | ||
475 | __tty_buffer_flush(port); | ||
476 | clear_bit(TTYP_FLUSHPENDING, &port->iflags); | ||
477 | wake_up(&tty->read_wait); | ||
478 | } | ||
479 | spin_unlock_irqrestore(&buf->lock, flags); | 477 | spin_unlock_irqrestore(&buf->lock, flags); |
480 | 478 | ||
481 | tty_ldisc_deref(disc); | 479 | tty_ldisc_deref(disc); |
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index b0452688308c..97ebc8c5864e 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
@@ -533,6 +533,60 @@ void tty_wakeup(struct tty_struct *tty) | |||
533 | EXPORT_SYMBOL_GPL(tty_wakeup); | 533 | EXPORT_SYMBOL_GPL(tty_wakeup); |
534 | 534 | ||
535 | /** | 535 | /** |
536 | * tty_signal_session_leader - sends SIGHUP to session leader | ||
537 | * @tty controlling tty | ||
538 | * @exit_session if non-zero, signal all foreground group processes | ||
539 | * | ||
540 | * Send SIGHUP and SIGCONT to the session leader and its process group. | ||
541 | * Optionally, signal all processes in the foreground process group. | ||
542 | * | ||
543 | * Returns the number of processes in the session with this tty | ||
544 | * as their controlling terminal. This value is used to drop | ||
545 | * tty references for those processes. | ||
546 | */ | ||
547 | static int tty_signal_session_leader(struct tty_struct *tty, int exit_session) | ||
548 | { | ||
549 | struct task_struct *p; | ||
550 | int refs = 0; | ||
551 | struct pid *tty_pgrp = NULL; | ||
552 | |||
553 | read_lock(&tasklist_lock); | ||
554 | if (tty->session) { | ||
555 | do_each_pid_task(tty->session, PIDTYPE_SID, p) { | ||
556 | spin_lock_irq(&p->sighand->siglock); | ||
557 | if (p->signal->tty == tty) { | ||
558 | p->signal->tty = NULL; | ||
559 | /* We defer the dereferences outside fo | ||
560 | the tasklist lock */ | ||
561 | refs++; | ||
562 | } | ||
563 | if (!p->signal->leader) { | ||
564 | spin_unlock_irq(&p->sighand->siglock); | ||
565 | continue; | ||
566 | } | ||
567 | __group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p); | ||
568 | __group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p); | ||
569 | put_pid(p->signal->tty_old_pgrp); /* A noop */ | ||
570 | spin_lock(&tty->ctrl_lock); | ||
571 | tty_pgrp = get_pid(tty->pgrp); | ||
572 | if (tty->pgrp) | ||
573 | p->signal->tty_old_pgrp = get_pid(tty->pgrp); | ||
574 | spin_unlock(&tty->ctrl_lock); | ||
575 | spin_unlock_irq(&p->sighand->siglock); | ||
576 | } while_each_pid_task(tty->session, PIDTYPE_SID, p); | ||
577 | } | ||
578 | read_unlock(&tasklist_lock); | ||
579 | |||
580 | if (tty_pgrp) { | ||
581 | if (exit_session) | ||
582 | kill_pgrp(tty_pgrp, SIGHUP, exit_session); | ||
583 | put_pid(tty_pgrp); | ||
584 | } | ||
585 | |||
586 | return refs; | ||
587 | } | ||
588 | |||
589 | /** | ||
536 | * __tty_hangup - actual handler for hangup events | 590 | * __tty_hangup - actual handler for hangup events |
537 | * @work: tty device | 591 | * @work: tty device |
538 | * | 592 | * |
@@ -554,15 +608,13 @@ EXPORT_SYMBOL_GPL(tty_wakeup); | |||
554 | * tasklist_lock to walk task list for hangup event | 608 | * tasklist_lock to walk task list for hangup event |
555 | * ->siglock to protect ->signal/->sighand | 609 | * ->siglock to protect ->signal/->sighand |
556 | */ | 610 | */ |
557 | static void __tty_hangup(struct tty_struct *tty) | 611 | static void __tty_hangup(struct tty_struct *tty, int exit_session) |
558 | { | 612 | { |
559 | struct file *cons_filp = NULL; | 613 | struct file *cons_filp = NULL; |
560 | struct file *filp, *f = NULL; | 614 | struct file *filp, *f = NULL; |
561 | struct task_struct *p; | ||
562 | struct tty_file_private *priv; | 615 | struct tty_file_private *priv; |
563 | int closecount = 0, n; | 616 | int closecount = 0, n; |
564 | unsigned long flags; | 617 | int refs; |
565 | int refs = 0; | ||
566 | 618 | ||
567 | if (!tty) | 619 | if (!tty) |
568 | return; | 620 | return; |
@@ -599,39 +651,18 @@ static void __tty_hangup(struct tty_struct *tty) | |||
599 | } | 651 | } |
600 | spin_unlock(&tty_files_lock); | 652 | spin_unlock(&tty_files_lock); |
601 | 653 | ||
654 | refs = tty_signal_session_leader(tty, exit_session); | ||
655 | /* Account for the p->signal references we killed */ | ||
656 | while (refs--) | ||
657 | tty_kref_put(tty); | ||
658 | |||
602 | /* | 659 | /* |
603 | * it drops BTM and thus races with reopen | 660 | * it drops BTM and thus races with reopen |
604 | * we protect the race by TTY_HUPPING | 661 | * we protect the race by TTY_HUPPING |
605 | */ | 662 | */ |
606 | tty_ldisc_hangup(tty); | 663 | tty_ldisc_hangup(tty); |
607 | 664 | ||
608 | read_lock(&tasklist_lock); | 665 | spin_lock_irq(&tty->ctrl_lock); |
609 | if (tty->session) { | ||
610 | do_each_pid_task(tty->session, PIDTYPE_SID, p) { | ||
611 | spin_lock_irq(&p->sighand->siglock); | ||
612 | if (p->signal->tty == tty) { | ||
613 | p->signal->tty = NULL; | ||
614 | /* We defer the dereferences outside fo | ||
615 | the tasklist lock */ | ||
616 | refs++; | ||
617 | } | ||
618 | if (!p->signal->leader) { | ||
619 | spin_unlock_irq(&p->sighand->siglock); | ||
620 | continue; | ||
621 | } | ||
622 | __group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p); | ||
623 | __group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p); | ||
624 | put_pid(p->signal->tty_old_pgrp); /* A noop */ | ||
625 | spin_lock_irqsave(&tty->ctrl_lock, flags); | ||
626 | if (tty->pgrp) | ||
627 | p->signal->tty_old_pgrp = get_pid(tty->pgrp); | ||
628 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | ||
629 | spin_unlock_irq(&p->sighand->siglock); | ||
630 | } while_each_pid_task(tty->session, PIDTYPE_SID, p); | ||
631 | } | ||
632 | read_unlock(&tasklist_lock); | ||
633 | |||
634 | spin_lock_irqsave(&tty->ctrl_lock, flags); | ||
635 | clear_bit(TTY_THROTTLED, &tty->flags); | 666 | clear_bit(TTY_THROTTLED, &tty->flags); |
636 | clear_bit(TTY_PUSH, &tty->flags); | 667 | clear_bit(TTY_PUSH, &tty->flags); |
637 | clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); | 668 | clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); |
@@ -640,11 +671,7 @@ static void __tty_hangup(struct tty_struct *tty) | |||
640 | tty->session = NULL; | 671 | tty->session = NULL; |
641 | tty->pgrp = NULL; | 672 | tty->pgrp = NULL; |
642 | tty->ctrl_status = 0; | 673 | tty->ctrl_status = 0; |
643 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | 674 | spin_unlock_irq(&tty->ctrl_lock); |
644 | |||
645 | /* Account for the p->signal references we killed */ | ||
646 | while (refs--) | ||
647 | tty_kref_put(tty); | ||
648 | 675 | ||
649 | /* | 676 | /* |
650 | * If one of the devices matches a console pointer, we | 677 | * If one of the devices matches a console pointer, we |
@@ -666,7 +693,6 @@ static void __tty_hangup(struct tty_struct *tty) | |||
666 | */ | 693 | */ |
667 | set_bit(TTY_HUPPED, &tty->flags); | 694 | set_bit(TTY_HUPPED, &tty->flags); |
668 | clear_bit(TTY_HUPPING, &tty->flags); | 695 | clear_bit(TTY_HUPPING, &tty->flags); |
669 | tty_ldisc_enable(tty); | ||
670 | 696 | ||
671 | tty_unlock(tty); | 697 | tty_unlock(tty); |
672 | 698 | ||
@@ -679,7 +705,7 @@ static void do_tty_hangup(struct work_struct *work) | |||
679 | struct tty_struct *tty = | 705 | struct tty_struct *tty = |
680 | container_of(work, struct tty_struct, hangup_work); | 706 | container_of(work, struct tty_struct, hangup_work); |
681 | 707 | ||
682 | __tty_hangup(tty); | 708 | __tty_hangup(tty, 0); |
683 | } | 709 | } |
684 | 710 | ||
685 | /** | 711 | /** |
@@ -717,7 +743,7 @@ void tty_vhangup(struct tty_struct *tty) | |||
717 | 743 | ||
718 | printk(KERN_DEBUG "%s vhangup...\n", tty_name(tty, buf)); | 744 | printk(KERN_DEBUG "%s vhangup...\n", tty_name(tty, buf)); |
719 | #endif | 745 | #endif |
720 | __tty_hangup(tty); | 746 | __tty_hangup(tty, 0); |
721 | } | 747 | } |
722 | 748 | ||
723 | EXPORT_SYMBOL(tty_vhangup); | 749 | EXPORT_SYMBOL(tty_vhangup); |
@@ -741,6 +767,27 @@ void tty_vhangup_self(void) | |||
741 | } | 767 | } |
742 | 768 | ||
743 | /** | 769 | /** |
770 | * tty_vhangup_session - hangup session leader exit | ||
771 | * @tty: tty to hangup | ||
772 | * | ||
773 | * The session leader is exiting and hanging up its controlling terminal. | ||
774 | * Every process in the foreground process group is signalled SIGHUP. | ||
775 | * | ||
776 | * We do this synchronously so that when the syscall returns the process | ||
777 | * is complete. That guarantee is necessary for security reasons. | ||
778 | */ | ||
779 | |||
780 | static void tty_vhangup_session(struct tty_struct *tty) | ||
781 | { | ||
782 | #ifdef TTY_DEBUG_HANGUP | ||
783 | char buf[64]; | ||
784 | |||
785 | printk(KERN_DEBUG "%s vhangup session...\n", tty_name(tty, buf)); | ||
786 | #endif | ||
787 | __tty_hangup(tty, 1); | ||
788 | } | ||
789 | |||
790 | /** | ||
744 | * tty_hung_up_p - was tty hung up | 791 | * tty_hung_up_p - was tty hung up |
745 | * @filp: file pointer of tty | 792 | * @filp: file pointer of tty |
746 | * | 793 | * |
@@ -797,18 +844,18 @@ void disassociate_ctty(int on_exit) | |||
797 | 844 | ||
798 | tty = get_current_tty(); | 845 | tty = get_current_tty(); |
799 | if (tty) { | 846 | if (tty) { |
800 | struct pid *tty_pgrp = get_pid(tty->pgrp); | 847 | if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) { |
801 | if (on_exit) { | 848 | tty_vhangup_session(tty); |
802 | if (tty->driver->type != TTY_DRIVER_TYPE_PTY) | 849 | } else { |
803 | tty_vhangup(tty); | 850 | struct pid *tty_pgrp = tty_get_pgrp(tty); |
804 | } | 851 | if (tty_pgrp) { |
805 | tty_kref_put(tty); | 852 | kill_pgrp(tty_pgrp, SIGHUP, on_exit); |
806 | if (tty_pgrp) { | ||
807 | kill_pgrp(tty_pgrp, SIGHUP, on_exit); | ||
808 | if (!on_exit) | ||
809 | kill_pgrp(tty_pgrp, SIGCONT, on_exit); | 853 | kill_pgrp(tty_pgrp, SIGCONT, on_exit); |
810 | put_pid(tty_pgrp); | 854 | put_pid(tty_pgrp); |
855 | } | ||
811 | } | 856 | } |
857 | tty_kref_put(tty); | ||
858 | |||
812 | } else if (on_exit) { | 859 | } else if (on_exit) { |
813 | struct pid *old_pgrp; | 860 | struct pid *old_pgrp; |
814 | spin_lock_irq(¤t->sighand->siglock); | 861 | spin_lock_irq(¤t->sighand->siglock); |
@@ -1358,9 +1405,7 @@ static int tty_reopen(struct tty_struct *tty) | |||
1358 | } | 1405 | } |
1359 | tty->count++; | 1406 | tty->count++; |
1360 | 1407 | ||
1361 | mutex_lock(&tty->ldisc_mutex); | ||
1362 | WARN_ON(!test_bit(TTY_LDISC, &tty->flags)); | 1408 | WARN_ON(!test_bit(TTY_LDISC, &tty->flags)); |
1363 | mutex_unlock(&tty->ldisc_mutex); | ||
1364 | 1409 | ||
1365 | return 0; | 1410 | return 0; |
1366 | } | 1411 | } |
@@ -1477,6 +1522,17 @@ void tty_free_termios(struct tty_struct *tty) | |||
1477 | } | 1522 | } |
1478 | EXPORT_SYMBOL(tty_free_termios); | 1523 | EXPORT_SYMBOL(tty_free_termios); |
1479 | 1524 | ||
1525 | /** | ||
1526 | * tty_flush_works - flush all works of a tty | ||
1527 | * @tty: tty device to flush works for | ||
1528 | * | ||
1529 | * Sync flush all works belonging to @tty. | ||
1530 | */ | ||
1531 | static void tty_flush_works(struct tty_struct *tty) | ||
1532 | { | ||
1533 | flush_work(&tty->SAK_work); | ||
1534 | flush_work(&tty->hangup_work); | ||
1535 | } | ||
1480 | 1536 | ||
1481 | /** | 1537 | /** |
1482 | * release_one_tty - release tty structure memory | 1538 | * release_one_tty - release tty structure memory |
@@ -1562,6 +1618,7 @@ static void release_tty(struct tty_struct *tty, int idx) | |||
1562 | tty_free_termios(tty); | 1618 | tty_free_termios(tty); |
1563 | tty_driver_remove_tty(tty->driver, tty); | 1619 | tty_driver_remove_tty(tty->driver, tty); |
1564 | tty->port->itty = NULL; | 1620 | tty->port->itty = NULL; |
1621 | cancel_work_sync(&tty->port->buf.work); | ||
1565 | 1622 | ||
1566 | if (tty->link) | 1623 | if (tty->link) |
1567 | tty_kref_put(tty->link); | 1624 | tty_kref_put(tty->link); |
@@ -1791,12 +1848,21 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1791 | return 0; | 1848 | return 0; |
1792 | 1849 | ||
1793 | #ifdef TTY_DEBUG_HANGUP | 1850 | #ifdef TTY_DEBUG_HANGUP |
1794 | printk(KERN_DEBUG "%s: freeing tty structure...\n", __func__); | 1851 | printk(KERN_DEBUG "%s: %s: final close\n", __func__, tty_name(tty, buf)); |
1795 | #endif | 1852 | #endif |
1796 | /* | 1853 | /* |
1797 | * Ask the line discipline code to release its structures | 1854 | * Ask the line discipline code to release its structures |
1798 | */ | 1855 | */ |
1799 | tty_ldisc_release(tty, o_tty); | 1856 | tty_ldisc_release(tty, o_tty); |
1857 | |||
1858 | /* Wait for pending work before tty destruction commmences */ | ||
1859 | tty_flush_works(tty); | ||
1860 | if (o_tty) | ||
1861 | tty_flush_works(o_tty); | ||
1862 | |||
1863 | #ifdef TTY_DEBUG_HANGUP | ||
1864 | printk(KERN_DEBUG "%s: %s: freeing structure...\n", __func__, tty_name(tty, buf)); | ||
1865 | #endif | ||
1800 | /* | 1866 | /* |
1801 | * The release_tty function takes care of the details of clearing | 1867 | * The release_tty function takes care of the details of clearing |
1802 | * the slots and preserving the termios structure. The tty_unlock_pair | 1868 | * the slots and preserving the termios structure. The tty_unlock_pair |
diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index d58b92cc187c..3500d4114147 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c | |||
@@ -106,6 +106,7 @@ void tty_throttle(struct tty_struct *tty) | |||
106 | if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) && | 106 | if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) && |
107 | tty->ops->throttle) | 107 | tty->ops->throttle) |
108 | tty->ops->throttle(tty); | 108 | tty->ops->throttle(tty); |
109 | tty->flow_change = 0; | ||
109 | mutex_unlock(&tty->termios_mutex); | 110 | mutex_unlock(&tty->termios_mutex); |
110 | } | 111 | } |
111 | EXPORT_SYMBOL(tty_throttle); | 112 | EXPORT_SYMBOL(tty_throttle); |
@@ -129,11 +130,74 @@ void tty_unthrottle(struct tty_struct *tty) | |||
129 | if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) && | 130 | if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) && |
130 | tty->ops->unthrottle) | 131 | tty->ops->unthrottle) |
131 | tty->ops->unthrottle(tty); | 132 | tty->ops->unthrottle(tty); |
133 | tty->flow_change = 0; | ||
132 | mutex_unlock(&tty->termios_mutex); | 134 | mutex_unlock(&tty->termios_mutex); |
133 | } | 135 | } |
134 | EXPORT_SYMBOL(tty_unthrottle); | 136 | EXPORT_SYMBOL(tty_unthrottle); |
135 | 137 | ||
136 | /** | 138 | /** |
139 | * tty_throttle_safe - flow control | ||
140 | * @tty: terminal | ||
141 | * | ||
142 | * Similar to tty_throttle() but will only attempt throttle | ||
143 | * if tty->flow_change is TTY_THROTTLE_SAFE. Prevents an accidental | ||
144 | * throttle due to race conditions when throttling is conditional | ||
145 | * on factors evaluated prior to throttling. | ||
146 | * | ||
147 | * Returns 0 if tty is throttled (or was already throttled) | ||
148 | */ | ||
149 | |||
150 | int tty_throttle_safe(struct tty_struct *tty) | ||
151 | { | ||
152 | int ret = 0; | ||
153 | |||
154 | mutex_lock(&tty->termios_mutex); | ||
155 | if (!test_bit(TTY_THROTTLED, &tty->flags)) { | ||
156 | if (tty->flow_change != TTY_THROTTLE_SAFE) | ||
157 | ret = 1; | ||
158 | else { | ||
159 | set_bit(TTY_THROTTLED, &tty->flags); | ||
160 | if (tty->ops->throttle) | ||
161 | tty->ops->throttle(tty); | ||
162 | } | ||
163 | } | ||
164 | mutex_unlock(&tty->termios_mutex); | ||
165 | |||
166 | return ret; | ||
167 | } | ||
168 | |||
169 | /** | ||
170 | * tty_unthrottle_safe - flow control | ||
171 | * @tty: terminal | ||
172 | * | ||
173 | * Similar to tty_unthrottle() but will only attempt unthrottle | ||
174 | * if tty->flow_change is TTY_UNTHROTTLE_SAFE. Prevents an accidental | ||
175 | * unthrottle due to race conditions when unthrottling is conditional | ||
176 | * on factors evaluated prior to unthrottling. | ||
177 | * | ||
178 | * Returns 0 if tty is unthrottled (or was already unthrottled) | ||
179 | */ | ||
180 | |||
181 | int tty_unthrottle_safe(struct tty_struct *tty) | ||
182 | { | ||
183 | int ret = 0; | ||
184 | |||
185 | mutex_lock(&tty->termios_mutex); | ||
186 | if (test_bit(TTY_THROTTLED, &tty->flags)) { | ||
187 | if (tty->flow_change != TTY_UNTHROTTLE_SAFE) | ||
188 | ret = 1; | ||
189 | else { | ||
190 | clear_bit(TTY_THROTTLED, &tty->flags); | ||
191 | if (tty->ops->unthrottle) | ||
192 | tty->ops->unthrottle(tty); | ||
193 | } | ||
194 | } | ||
195 | mutex_unlock(&tty->termios_mutex); | ||
196 | |||
197 | return ret; | ||
198 | } | ||
199 | |||
200 | /** | ||
137 | * tty_wait_until_sent - wait for I/O to finish | 201 | * tty_wait_until_sent - wait for I/O to finish |
138 | * @tty: tty we are waiting for | 202 | * @tty: tty we are waiting for |
139 | * @timeout: how long we will wait | 203 | * @timeout: how long we will wait |
@@ -415,34 +479,6 @@ void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud) | |||
415 | EXPORT_SYMBOL_GPL(tty_encode_baud_rate); | 479 | EXPORT_SYMBOL_GPL(tty_encode_baud_rate); |
416 | 480 | ||
417 | /** | 481 | /** |
418 | * tty_get_baud_rate - get tty bit rates | ||
419 | * @tty: tty to query | ||
420 | * | ||
421 | * Returns the baud rate as an integer for this terminal. The | ||
422 | * termios lock must be held by the caller and the terminal bit | ||
423 | * flags may be updated. | ||
424 | * | ||
425 | * Locking: none | ||
426 | */ | ||
427 | |||
428 | speed_t tty_get_baud_rate(struct tty_struct *tty) | ||
429 | { | ||
430 | speed_t baud = tty_termios_baud_rate(&tty->termios); | ||
431 | |||
432 | if (baud == 38400 && tty->alt_speed) { | ||
433 | if (!tty->warned) { | ||
434 | printk(KERN_WARNING "Use of setserial/setrocket to " | ||
435 | "set SPD_* flags is deprecated\n"); | ||
436 | tty->warned = 1; | ||
437 | } | ||
438 | baud = tty->alt_speed; | ||
439 | } | ||
440 | |||
441 | return baud; | ||
442 | } | ||
443 | EXPORT_SYMBOL(tty_get_baud_rate); | ||
444 | |||
445 | /** | ||
446 | * tty_termios_copy_hw - copy hardware settings | 482 | * tty_termios_copy_hw - copy hardware settings |
447 | * @new: New termios | 483 | * @new: New termios |
448 | * @old: Old termios | 484 | * @old: Old termios |
@@ -1086,14 +1122,12 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file, | |||
1086 | } | 1122 | } |
1087 | EXPORT_SYMBOL_GPL(tty_mode_ioctl); | 1123 | EXPORT_SYMBOL_GPL(tty_mode_ioctl); |
1088 | 1124 | ||
1089 | int tty_perform_flush(struct tty_struct *tty, unsigned long arg) | 1125 | |
1126 | /* Caller guarantees ldisc reference is held */ | ||
1127 | static int __tty_perform_flush(struct tty_struct *tty, unsigned long arg) | ||
1090 | { | 1128 | { |
1091 | struct tty_ldisc *ld; | 1129 | struct tty_ldisc *ld = tty->ldisc; |
1092 | int retval = tty_check_change(tty); | ||
1093 | if (retval) | ||
1094 | return retval; | ||
1095 | 1130 | ||
1096 | ld = tty_ldisc_ref_wait(tty); | ||
1097 | switch (arg) { | 1131 | switch (arg) { |
1098 | case TCIFLUSH: | 1132 | case TCIFLUSH: |
1099 | if (ld && ld->ops->flush_buffer) { | 1133 | if (ld && ld->ops->flush_buffer) { |
@@ -1111,12 +1145,24 @@ int tty_perform_flush(struct tty_struct *tty, unsigned long arg) | |||
1111 | tty_driver_flush_buffer(tty); | 1145 | tty_driver_flush_buffer(tty); |
1112 | break; | 1146 | break; |
1113 | default: | 1147 | default: |
1114 | tty_ldisc_deref(ld); | ||
1115 | return -EINVAL; | 1148 | return -EINVAL; |
1116 | } | 1149 | } |
1117 | tty_ldisc_deref(ld); | ||
1118 | return 0; | 1150 | return 0; |
1119 | } | 1151 | } |
1152 | |||
1153 | int tty_perform_flush(struct tty_struct *tty, unsigned long arg) | ||
1154 | { | ||
1155 | struct tty_ldisc *ld; | ||
1156 | int retval = tty_check_change(tty); | ||
1157 | if (retval) | ||
1158 | return retval; | ||
1159 | |||
1160 | ld = tty_ldisc_ref_wait(tty); | ||
1161 | retval = __tty_perform_flush(tty, arg); | ||
1162 | if (ld) | ||
1163 | tty_ldisc_deref(ld); | ||
1164 | return retval; | ||
1165 | } | ||
1120 | EXPORT_SYMBOL_GPL(tty_perform_flush); | 1166 | EXPORT_SYMBOL_GPL(tty_perform_flush); |
1121 | 1167 | ||
1122 | int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, | 1168 | int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, |
@@ -1155,7 +1201,7 @@ int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, | |||
1155 | } | 1201 | } |
1156 | return 0; | 1202 | return 0; |
1157 | case TCFLSH: | 1203 | case TCFLSH: |
1158 | return tty_perform_flush(tty, arg); | 1204 | return __tty_perform_flush(tty, arg); |
1159 | default: | 1205 | default: |
1160 | /* Try the mode commands */ | 1206 | /* Try the mode commands */ |
1161 | return tty_mode_ioctl(tty, file, cmd, arg); | 1207 | return tty_mode_ioctl(tty, file, cmd, arg); |
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index d794087c327e..1afe192bef6a 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c | |||
@@ -20,6 +20,17 @@ | |||
20 | #include <linux/uaccess.h> | 20 | #include <linux/uaccess.h> |
21 | #include <linux/ratelimit.h> | 21 | #include <linux/ratelimit.h> |
22 | 22 | ||
23 | #undef LDISC_DEBUG_HANGUP | ||
24 | |||
25 | #ifdef LDISC_DEBUG_HANGUP | ||
26 | #define tty_ldisc_debug(tty, f, args...) ({ \ | ||
27 | char __b[64]; \ | ||
28 | printk(KERN_DEBUG "%s: %s: " f, __func__, tty_name(tty, __b), ##args); \ | ||
29 | }) | ||
30 | #else | ||
31 | #define tty_ldisc_debug(tty, f, args...) | ||
32 | #endif | ||
33 | |||
23 | /* | 34 | /* |
24 | * This guards the refcounted line discipline lists. The lock | 35 | * This guards the refcounted line discipline lists. The lock |
25 | * must be taken with irqs off because there are hangup path | 36 | * must be taken with irqs off because there are hangup path |
@@ -31,44 +42,6 @@ static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); | |||
31 | /* Line disc dispatch table */ | 42 | /* Line disc dispatch table */ |
32 | static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS]; | 43 | static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS]; |
33 | 44 | ||
34 | static inline struct tty_ldisc *get_ldisc(struct tty_ldisc *ld) | ||
35 | { | ||
36 | if (ld) | ||
37 | atomic_inc(&ld->users); | ||
38 | return ld; | ||
39 | } | ||
40 | |||
41 | static void put_ldisc(struct tty_ldisc *ld) | ||
42 | { | ||
43 | unsigned long flags; | ||
44 | |||
45 | if (WARN_ON_ONCE(!ld)) | ||
46 | return; | ||
47 | |||
48 | /* | ||
49 | * If this is the last user, free the ldisc, and | ||
50 | * release the ldisc ops. | ||
51 | * | ||
52 | * We really want an "atomic_dec_and_raw_lock_irqsave()", | ||
53 | * but we don't have it, so this does it by hand. | ||
54 | */ | ||
55 | raw_spin_lock_irqsave(&tty_ldisc_lock, flags); | ||
56 | if (atomic_dec_and_test(&ld->users)) { | ||
57 | struct tty_ldisc_ops *ldo = ld->ops; | ||
58 | |||
59 | ldo->refcount--; | ||
60 | module_put(ldo->owner); | ||
61 | raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); | ||
62 | |||
63 | kfree(ld); | ||
64 | return; | ||
65 | } | ||
66 | raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); | ||
67 | |||
68 | if (waitqueue_active(&ld->wq_idle)) | ||
69 | wake_up(&ld->wq_idle); | ||
70 | } | ||
71 | |||
72 | /** | 45 | /** |
73 | * tty_register_ldisc - install a line discipline | 46 | * tty_register_ldisc - install a line discipline |
74 | * @disc: ldisc number | 47 | * @disc: ldisc number |
@@ -206,6 +179,29 @@ static struct tty_ldisc *tty_ldisc_get(int disc) | |||
206 | return ld; | 179 | return ld; |
207 | } | 180 | } |
208 | 181 | ||
182 | /** | ||
183 | * tty_ldisc_put - release the ldisc | ||
184 | * | ||
185 | * Complement of tty_ldisc_get(). | ||
186 | */ | ||
187 | static inline void tty_ldisc_put(struct tty_ldisc *ld) | ||
188 | { | ||
189 | unsigned long flags; | ||
190 | |||
191 | if (WARN_ON_ONCE(!ld)) | ||
192 | return; | ||
193 | |||
194 | raw_spin_lock_irqsave(&tty_ldisc_lock, flags); | ||
195 | |||
196 | /* unreleased reader reference(s) will cause this WARN */ | ||
197 | WARN_ON(!atomic_dec_and_test(&ld->users)); | ||
198 | |||
199 | ld->ops->refcount--; | ||
200 | module_put(ld->ops->owner); | ||
201 | kfree(ld); | ||
202 | raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); | ||
203 | } | ||
204 | |||
209 | static void *tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos) | 205 | static void *tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos) |
210 | { | 206 | { |
211 | return (*pos < NR_LDISCS) ? pos : NULL; | 207 | return (*pos < NR_LDISCS) ? pos : NULL; |
@@ -255,24 +251,6 @@ const struct file_operations tty_ldiscs_proc_fops = { | |||
255 | }; | 251 | }; |
256 | 252 | ||
257 | /** | 253 | /** |
258 | * tty_ldisc_assign - set ldisc on a tty | ||
259 | * @tty: tty to assign | ||
260 | * @ld: line discipline | ||
261 | * | ||
262 | * Install an instance of a line discipline into a tty structure. The | ||
263 | * ldisc must have a reference count above zero to ensure it remains. | ||
264 | * The tty instance refcount starts at zero. | ||
265 | * | ||
266 | * Locking: | ||
267 | * Caller must hold references | ||
268 | */ | ||
269 | |||
270 | static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld) | ||
271 | { | ||
272 | tty->ldisc = ld; | ||
273 | } | ||
274 | |||
275 | /** | ||
276 | * tty_ldisc_try - internal helper | 254 | * tty_ldisc_try - internal helper |
277 | * @tty: the tty | 255 | * @tty: the tty |
278 | * | 256 | * |
@@ -289,10 +267,13 @@ static struct tty_ldisc *tty_ldisc_try(struct tty_struct *tty) | |||
289 | unsigned long flags; | 267 | unsigned long flags; |
290 | struct tty_ldisc *ld; | 268 | struct tty_ldisc *ld; |
291 | 269 | ||
270 | /* FIXME: this allows reference acquire after TTY_LDISC is cleared */ | ||
292 | raw_spin_lock_irqsave(&tty_ldisc_lock, flags); | 271 | raw_spin_lock_irqsave(&tty_ldisc_lock, flags); |
293 | ld = NULL; | 272 | ld = NULL; |
294 | if (test_bit(TTY_LDISC, &tty->flags)) | 273 | if (test_bit(TTY_LDISC, &tty->flags) && tty->ldisc) { |
295 | ld = get_ldisc(tty->ldisc); | 274 | ld = tty->ldisc; |
275 | atomic_inc(&ld->users); | ||
276 | } | ||
296 | raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); | 277 | raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); |
297 | return ld; | 278 | return ld; |
298 | } | 279 | } |
@@ -352,14 +333,23 @@ EXPORT_SYMBOL_GPL(tty_ldisc_ref); | |||
352 | 333 | ||
353 | void tty_ldisc_deref(struct tty_ldisc *ld) | 334 | void tty_ldisc_deref(struct tty_ldisc *ld) |
354 | { | 335 | { |
355 | put_ldisc(ld); | 336 | unsigned long flags; |
356 | } | ||
357 | EXPORT_SYMBOL_GPL(tty_ldisc_deref); | ||
358 | 337 | ||
359 | static inline void tty_ldisc_put(struct tty_ldisc *ld) | 338 | if (WARN_ON_ONCE(!ld)) |
360 | { | 339 | return; |
361 | put_ldisc(ld); | 340 | |
341 | raw_spin_lock_irqsave(&tty_ldisc_lock, flags); | ||
342 | /* | ||
343 | * WARNs if one-too-many reader references were released | ||
344 | * - the last reference must be released with tty_ldisc_put | ||
345 | */ | ||
346 | WARN_ON(atomic_dec_and_test(&ld->users)); | ||
347 | raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); | ||
348 | |||
349 | if (waitqueue_active(&ld->wq_idle)) | ||
350 | wake_up(&ld->wq_idle); | ||
362 | } | 351 | } |
352 | EXPORT_SYMBOL_GPL(tty_ldisc_deref); | ||
363 | 353 | ||
364 | /** | 354 | /** |
365 | * tty_ldisc_enable - allow ldisc use | 355 | * tty_ldisc_enable - allow ldisc use |
@@ -373,8 +363,9 @@ static inline void tty_ldisc_put(struct tty_ldisc *ld) | |||
373 | * Clearing directly is allowed. | 363 | * Clearing directly is allowed. |
374 | */ | 364 | */ |
375 | 365 | ||
376 | void tty_ldisc_enable(struct tty_struct *tty) | 366 | static void tty_ldisc_enable(struct tty_struct *tty) |
377 | { | 367 | { |
368 | clear_bit(TTY_LDISC_HALTED, &tty->flags); | ||
378 | set_bit(TTY_LDISC, &tty->flags); | 369 | set_bit(TTY_LDISC, &tty->flags); |
379 | clear_bit(TTY_LDISC_CHANGING, &tty->flags); | 370 | clear_bit(TTY_LDISC_CHANGING, &tty->flags); |
380 | wake_up(&tty_ldisc_wait); | 371 | wake_up(&tty_ldisc_wait); |
@@ -479,7 +470,7 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old) | |||
479 | /* There is an outstanding reference here so this is safe */ | 470 | /* There is an outstanding reference here so this is safe */ |
480 | old = tty_ldisc_get(old->ops->num); | 471 | old = tty_ldisc_get(old->ops->num); |
481 | WARN_ON(IS_ERR(old)); | 472 | WARN_ON(IS_ERR(old)); |
482 | tty_ldisc_assign(tty, old); | 473 | tty->ldisc = old; |
483 | tty_set_termios_ldisc(tty, old->ops->num); | 474 | tty_set_termios_ldisc(tty, old->ops->num); |
484 | if (tty_ldisc_open(tty, old) < 0) { | 475 | if (tty_ldisc_open(tty, old) < 0) { |
485 | tty_ldisc_put(old); | 476 | tty_ldisc_put(old); |
@@ -487,7 +478,7 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old) | |||
487 | new_ldisc = tty_ldisc_get(N_TTY); | 478 | new_ldisc = tty_ldisc_get(N_TTY); |
488 | if (IS_ERR(new_ldisc)) | 479 | if (IS_ERR(new_ldisc)) |
489 | panic("n_tty: get"); | 480 | panic("n_tty: get"); |
490 | tty_ldisc_assign(tty, new_ldisc); | 481 | tty->ldisc = new_ldisc; |
491 | tty_set_termios_ldisc(tty, N_TTY); | 482 | tty_set_termios_ldisc(tty, N_TTY); |
492 | r = tty_ldisc_open(tty, new_ldisc); | 483 | r = tty_ldisc_open(tty, new_ldisc); |
493 | if (r < 0) | 484 | if (r < 0) |
@@ -498,52 +489,98 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old) | |||
498 | } | 489 | } |
499 | 490 | ||
500 | /** | 491 | /** |
492 | * tty_ldisc_wait_idle - wait for the ldisc to become idle | ||
493 | * @tty: tty to wait for | ||
494 | * @timeout: for how long to wait at most | ||
495 | * | ||
496 | * Wait for the line discipline to become idle. The discipline must | ||
497 | * have been halted for this to guarantee it remains idle. | ||
498 | */ | ||
499 | static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout) | ||
500 | { | ||
501 | long ret; | ||
502 | ret = wait_event_timeout(tty->ldisc->wq_idle, | ||
503 | atomic_read(&tty->ldisc->users) == 1, timeout); | ||
504 | return ret > 0 ? 0 : -EBUSY; | ||
505 | } | ||
506 | |||
507 | /** | ||
501 | * tty_ldisc_halt - shut down the line discipline | 508 | * tty_ldisc_halt - shut down the line discipline |
502 | * @tty: tty device | 509 | * @tty: tty device |
510 | * @o_tty: paired pty device (can be NULL) | ||
511 | * @timeout: # of jiffies to wait for ldisc refs to be released | ||
503 | * | 512 | * |
504 | * Shut down the line discipline and work queue for this tty device. | 513 | * Shut down the line discipline and work queue for this tty device and |
505 | * The TTY_LDISC flag being cleared ensures no further references can | 514 | * its paired pty (if exists). Clearing the TTY_LDISC flag ensures |
506 | * be obtained while the delayed work queue halt ensures that no more | 515 | * no further references can be obtained, while waiting for existing |
507 | * data is fed to the ldisc. | 516 | * references to be released ensures no more data is fed to the ldisc. |
508 | * | 517 | * |
509 | * You need to do a 'flush_scheduled_work()' (outside the ldisc_mutex) | 518 | * You need to do a 'flush_scheduled_work()' (outside the ldisc_mutex) |
510 | * in order to make sure any currently executing ldisc work is also | 519 | * in order to make sure any currently executing ldisc work is also |
511 | * flushed. | 520 | * flushed. |
512 | */ | 521 | */ |
513 | 522 | ||
514 | static int tty_ldisc_halt(struct tty_struct *tty) | 523 | static int tty_ldisc_halt(struct tty_struct *tty, struct tty_struct *o_tty, |
524 | long timeout) | ||
515 | { | 525 | { |
526 | int retval; | ||
527 | |||
516 | clear_bit(TTY_LDISC, &tty->flags); | 528 | clear_bit(TTY_LDISC, &tty->flags); |
517 | return cancel_work_sync(&tty->port->buf.work); | 529 | if (o_tty) |
518 | } | 530 | clear_bit(TTY_LDISC, &o_tty->flags); |
519 | 531 | ||
520 | /** | 532 | retval = tty_ldisc_wait_idle(tty, timeout); |
521 | * tty_ldisc_flush_works - flush all works of a tty | 533 | if (!retval && o_tty) |
522 | * @tty: tty device to flush works for | 534 | retval = tty_ldisc_wait_idle(o_tty, timeout); |
523 | * | 535 | if (retval) |
524 | * Sync flush all works belonging to @tty. | 536 | return retval; |
525 | */ | 537 | |
526 | static void tty_ldisc_flush_works(struct tty_struct *tty) | 538 | set_bit(TTY_LDISC_HALTED, &tty->flags); |
527 | { | 539 | if (o_tty) |
528 | flush_work(&tty->hangup_work); | 540 | set_bit(TTY_LDISC_HALTED, &o_tty->flags); |
529 | flush_work(&tty->SAK_work); | 541 | |
530 | flush_work(&tty->port->buf.work); | 542 | return 0; |
531 | } | 543 | } |
532 | 544 | ||
533 | /** | 545 | /** |
534 | * tty_ldisc_wait_idle - wait for the ldisc to become idle | 546 | * tty_ldisc_hangup_halt - halt the line discipline for hangup |
535 | * @tty: tty to wait for | 547 | * @tty: tty being hung up |
536 | * @timeout: for how long to wait at most | ||
537 | * | 548 | * |
538 | * Wait for the line discipline to become idle. The discipline must | 549 | * Shut down the line discipline and work queue for the tty device |
539 | * have been halted for this to guarantee it remains idle. | 550 | * being hungup. Clear the TTY_LDISC flag to ensure no further |
551 | * references can be obtained and wait for remaining references to be | ||
552 | * released to ensure no more data is fed to this ldisc. | ||
553 | * Caller must hold legacy and ->ldisc_mutex. | ||
554 | * | ||
555 | * NB: tty_set_ldisc() is prevented from changing the ldisc concurrently | ||
556 | * with this function by checking the TTY_HUPPING flag. | ||
540 | */ | 557 | */ |
541 | static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout) | 558 | static bool tty_ldisc_hangup_halt(struct tty_struct *tty) |
542 | { | 559 | { |
543 | long ret; | 560 | char cur_n[TASK_COMM_LEN], tty_n[64]; |
544 | ret = wait_event_timeout(tty->ldisc->wq_idle, | 561 | long timeout = 3 * HZ; |
545 | atomic_read(&tty->ldisc->users) == 1, timeout); | 562 | |
546 | return ret > 0 ? 0 : -EBUSY; | 563 | clear_bit(TTY_LDISC, &tty->flags); |
564 | |||
565 | if (tty->ldisc) { /* Not yet closed */ | ||
566 | tty_unlock(tty); | ||
567 | |||
568 | while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) { | ||
569 | timeout = MAX_SCHEDULE_TIMEOUT; | ||
570 | printk_ratelimited(KERN_WARNING | ||
571 | "%s: waiting (%s) for %s took too long, but we keep waiting...\n", | ||
572 | __func__, get_task_comm(cur_n, current), | ||
573 | tty_name(tty, tty_n)); | ||
574 | } | ||
575 | |||
576 | set_bit(TTY_LDISC_HALTED, &tty->flags); | ||
577 | |||
578 | /* must reacquire both locks and preserve lock order */ | ||
579 | mutex_unlock(&tty->ldisc_mutex); | ||
580 | tty_lock(tty); | ||
581 | mutex_lock(&tty->ldisc_mutex); | ||
582 | } | ||
583 | return !!tty->ldisc; | ||
547 | } | 584 | } |
548 | 585 | ||
549 | /** | 586 | /** |
@@ -563,7 +600,6 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
563 | { | 600 | { |
564 | int retval; | 601 | int retval; |
565 | struct tty_ldisc *o_ldisc, *new_ldisc; | 602 | struct tty_ldisc *o_ldisc, *new_ldisc; |
566 | int work, o_work = 0; | ||
567 | struct tty_struct *o_tty; | 603 | struct tty_struct *o_tty; |
568 | 604 | ||
569 | new_ldisc = tty_ldisc_get(ldisc); | 605 | new_ldisc = tty_ldisc_get(ldisc); |
@@ -589,15 +625,6 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
589 | return 0; | 625 | return 0; |
590 | } | 626 | } |
591 | 627 | ||
592 | tty_unlock(tty); | ||
593 | /* | ||
594 | * Problem: What do we do if this blocks ? | ||
595 | * We could deadlock here | ||
596 | */ | ||
597 | |||
598 | tty_wait_until_sent(tty, 0); | ||
599 | |||
600 | tty_lock(tty); | ||
601 | mutex_lock(&tty->ldisc_mutex); | 628 | mutex_lock(&tty->ldisc_mutex); |
602 | 629 | ||
603 | /* | 630 | /* |
@@ -637,20 +664,16 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
637 | * parallel to the change and re-referencing the tty. | 664 | * parallel to the change and re-referencing the tty. |
638 | */ | 665 | */ |
639 | 666 | ||
640 | work = tty_ldisc_halt(tty); | 667 | retval = tty_ldisc_halt(tty, o_tty, 5 * HZ); |
641 | if (o_tty) | ||
642 | o_work = tty_ldisc_halt(o_tty); | ||
643 | 668 | ||
644 | /* | 669 | /* |
645 | * Wait for ->hangup_work and ->buf.work handlers to terminate. | 670 | * Wait for hangup to complete, if pending. |
646 | * We must drop the mutex here in case a hangup is also in process. | 671 | * We must drop the mutex here in case a hangup is also in process. |
647 | */ | 672 | */ |
648 | 673 | ||
649 | mutex_unlock(&tty->ldisc_mutex); | 674 | mutex_unlock(&tty->ldisc_mutex); |
650 | 675 | ||
651 | tty_ldisc_flush_works(tty); | 676 | flush_work(&tty->hangup_work); |
652 | |||
653 | retval = tty_ldisc_wait_idle(tty, 5 * HZ); | ||
654 | 677 | ||
655 | tty_lock(tty); | 678 | tty_lock(tty); |
656 | mutex_lock(&tty->ldisc_mutex); | 679 | mutex_lock(&tty->ldisc_mutex); |
@@ -675,7 +698,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
675 | tty_ldisc_close(tty, o_ldisc); | 698 | tty_ldisc_close(tty, o_ldisc); |
676 | 699 | ||
677 | /* Now set up the new line discipline. */ | 700 | /* Now set up the new line discipline. */ |
678 | tty_ldisc_assign(tty, new_ldisc); | 701 | tty->ldisc = new_ldisc; |
679 | tty_set_termios_ldisc(tty, ldisc); | 702 | tty_set_termios_ldisc(tty, ldisc); |
680 | 703 | ||
681 | retval = tty_ldisc_open(tty, new_ldisc); | 704 | retval = tty_ldisc_open(tty, new_ldisc); |
@@ -705,10 +728,10 @@ enable: | |||
705 | 728 | ||
706 | /* Restart the work queue in case no characters kick it off. Safe if | 729 | /* Restart the work queue in case no characters kick it off. Safe if |
707 | already running */ | 730 | already running */ |
708 | if (work) | 731 | schedule_work(&tty->port->buf.work); |
709 | schedule_work(&tty->port->buf.work); | 732 | if (o_tty) |
710 | if (o_work) | ||
711 | schedule_work(&o_tty->port->buf.work); | 733 | schedule_work(&o_tty->port->buf.work); |
734 | |||
712 | mutex_unlock(&tty->ldisc_mutex); | 735 | mutex_unlock(&tty->ldisc_mutex); |
713 | tty_unlock(tty); | 736 | tty_unlock(tty); |
714 | return retval; | 737 | return retval; |
@@ -749,11 +772,10 @@ static int tty_ldisc_reinit(struct tty_struct *tty, int ldisc) | |||
749 | 772 | ||
750 | tty_ldisc_close(tty, tty->ldisc); | 773 | tty_ldisc_close(tty, tty->ldisc); |
751 | tty_ldisc_put(tty->ldisc); | 774 | tty_ldisc_put(tty->ldisc); |
752 | tty->ldisc = NULL; | ||
753 | /* | 775 | /* |
754 | * Switch the line discipline back | 776 | * Switch the line discipline back |
755 | */ | 777 | */ |
756 | tty_ldisc_assign(tty, ld); | 778 | tty->ldisc = ld; |
757 | tty_set_termios_ldisc(tty, ldisc); | 779 | tty_set_termios_ldisc(tty, ldisc); |
758 | 780 | ||
759 | return 0; | 781 | return 0; |
@@ -780,6 +802,8 @@ void tty_ldisc_hangup(struct tty_struct *tty) | |||
780 | int reset = tty->driver->flags & TTY_DRIVER_RESET_TERMIOS; | 802 | int reset = tty->driver->flags & TTY_DRIVER_RESET_TERMIOS; |
781 | int err = 0; | 803 | int err = 0; |
782 | 804 | ||
805 | tty_ldisc_debug(tty, "closing ldisc: %p\n", tty->ldisc); | ||
806 | |||
783 | /* | 807 | /* |
784 | * FIXME! What are the locking issues here? This may me overdoing | 808 | * FIXME! What are the locking issues here? This may me overdoing |
785 | * things... This question is especially important now that we've | 809 | * things... This question is especially important now that we've |
@@ -812,40 +836,12 @@ void tty_ldisc_hangup(struct tty_struct *tty) | |||
812 | */ | 836 | */ |
813 | mutex_lock(&tty->ldisc_mutex); | 837 | mutex_lock(&tty->ldisc_mutex); |
814 | 838 | ||
815 | /* | 839 | if (tty_ldisc_hangup_halt(tty)) { |
816 | * this is like tty_ldisc_halt, but we need to give up | ||
817 | * the BTM before calling cancel_work_sync, which may | ||
818 | * need to wait for another function taking the BTM | ||
819 | */ | ||
820 | clear_bit(TTY_LDISC, &tty->flags); | ||
821 | tty_unlock(tty); | ||
822 | cancel_work_sync(&tty->port->buf.work); | ||
823 | mutex_unlock(&tty->ldisc_mutex); | ||
824 | retry: | ||
825 | tty_lock(tty); | ||
826 | mutex_lock(&tty->ldisc_mutex); | ||
827 | |||
828 | /* At this point we have a closed ldisc and we want to | ||
829 | reopen it. We could defer this to the next open but | ||
830 | it means auditing a lot of other paths so this is | ||
831 | a FIXME */ | ||
832 | if (tty->ldisc) { /* Not yet closed */ | ||
833 | if (atomic_read(&tty->ldisc->users) != 1) { | ||
834 | char cur_n[TASK_COMM_LEN], tty_n[64]; | ||
835 | long timeout = 3 * HZ; | ||
836 | tty_unlock(tty); | ||
837 | |||
838 | while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) { | ||
839 | timeout = MAX_SCHEDULE_TIMEOUT; | ||
840 | printk_ratelimited(KERN_WARNING | ||
841 | "%s: waiting (%s) for %s took too long, but we keep waiting...\n", | ||
842 | __func__, get_task_comm(cur_n, current), | ||
843 | tty_name(tty, tty_n)); | ||
844 | } | ||
845 | mutex_unlock(&tty->ldisc_mutex); | ||
846 | goto retry; | ||
847 | } | ||
848 | 840 | ||
841 | /* At this point we have a halted ldisc; we want to close it and | ||
842 | reopen a new ldisc. We could defer the reopen to the next | ||
843 | open but it means auditing a lot of other paths so this is | ||
844 | a FIXME */ | ||
849 | if (reset == 0) { | 845 | if (reset == 0) { |
850 | 846 | ||
851 | if (!tty_ldisc_reinit(tty, tty->termios.c_line)) | 847 | if (!tty_ldisc_reinit(tty, tty->termios.c_line)) |
@@ -864,6 +860,8 @@ retry: | |||
864 | mutex_unlock(&tty->ldisc_mutex); | 860 | mutex_unlock(&tty->ldisc_mutex); |
865 | if (reset) | 861 | if (reset) |
866 | tty_reset_termios(tty); | 862 | tty_reset_termios(tty); |
863 | |||
864 | tty_ldisc_debug(tty, "re-opened ldisc: %p\n", tty->ldisc); | ||
867 | } | 865 | } |
868 | 866 | ||
869 | /** | 867 | /** |
@@ -899,11 +897,6 @@ int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty) | |||
899 | 897 | ||
900 | static void tty_ldisc_kill(struct tty_struct *tty) | 898 | static void tty_ldisc_kill(struct tty_struct *tty) |
901 | { | 899 | { |
902 | /* There cannot be users from userspace now. But there still might be | ||
903 | * drivers holding a reference via tty_ldisc_ref. Do not steal them the | ||
904 | * ldisc until they are done. */ | ||
905 | tty_ldisc_wait_idle(tty, MAX_SCHEDULE_TIMEOUT); | ||
906 | |||
907 | mutex_lock(&tty->ldisc_mutex); | 900 | mutex_lock(&tty->ldisc_mutex); |
908 | /* | 901 | /* |
909 | * Now kill off the ldisc | 902 | * Now kill off the ldisc |
@@ -931,18 +924,13 @@ static void tty_ldisc_kill(struct tty_struct *tty) | |||
931 | void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) | 924 | void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) |
932 | { | 925 | { |
933 | /* | 926 | /* |
934 | * Prevent flush_to_ldisc() from rescheduling the work for later. Then | 927 | * Shutdown this line discipline. As this is the final close, |
935 | * kill any delayed work. As this is the final close it does not | 928 | * it does not race with the set_ldisc code path. |
936 | * race with the set_ldisc code path. | ||
937 | */ | 929 | */ |
938 | 930 | ||
939 | tty_ldisc_halt(tty); | 931 | tty_ldisc_debug(tty, "closing ldisc: %p\n", tty->ldisc); |
940 | if (o_tty) | ||
941 | tty_ldisc_halt(o_tty); | ||
942 | 932 | ||
943 | tty_ldisc_flush_works(tty); | 933 | tty_ldisc_halt(tty, o_tty, MAX_SCHEDULE_TIMEOUT); |
944 | if (o_tty) | ||
945 | tty_ldisc_flush_works(o_tty); | ||
946 | 934 | ||
947 | tty_lock_pair(tty, o_tty); | 935 | tty_lock_pair(tty, o_tty); |
948 | /* This will need doing differently if we need to lock */ | 936 | /* This will need doing differently if we need to lock */ |
@@ -953,6 +941,8 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) | |||
953 | tty_unlock_pair(tty, o_tty); | 941 | tty_unlock_pair(tty, o_tty); |
954 | /* And the memory resources remaining (buffers, termios) will be | 942 | /* And the memory resources remaining (buffers, termios) will be |
955 | disposed of when the kref hits zero */ | 943 | disposed of when the kref hits zero */ |
944 | |||
945 | tty_ldisc_debug(tty, "ldisc closed\n"); | ||
956 | } | 946 | } |
957 | 947 | ||
958 | /** | 948 | /** |
@@ -968,7 +958,7 @@ void tty_ldisc_init(struct tty_struct *tty) | |||
968 | struct tty_ldisc *ld = tty_ldisc_get(N_TTY); | 958 | struct tty_ldisc *ld = tty_ldisc_get(N_TTY); |
969 | if (IS_ERR(ld)) | 959 | if (IS_ERR(ld)) |
970 | panic("n_tty: init_tty"); | 960 | panic("n_tty: init_tty"); |
971 | tty_ldisc_assign(tty, ld); | 961 | tty->ldisc = ld; |
972 | } | 962 | } |
973 | 963 | ||
974 | /** | 964 | /** |
@@ -980,8 +970,8 @@ void tty_ldisc_init(struct tty_struct *tty) | |||
980 | */ | 970 | */ |
981 | void tty_ldisc_deinit(struct tty_struct *tty) | 971 | void tty_ldisc_deinit(struct tty_struct *tty) |
982 | { | 972 | { |
983 | put_ldisc(tty->ldisc); | 973 | tty_ldisc_put(tty->ldisc); |
984 | tty_ldisc_assign(tty, NULL); | 974 | tty->ldisc = NULL; |
985 | } | 975 | } |
986 | 976 | ||
987 | void tty_ldisc_begin(void) | 977 | void tty_ldisc_begin(void) |
diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index b7ff59d3db88..121aeb9393e1 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c | |||
@@ -132,6 +132,7 @@ EXPORT_SYMBOL(tty_port_free_xmit_buf); | |||
132 | */ | 132 | */ |
133 | void tty_port_destroy(struct tty_port *port) | 133 | void tty_port_destroy(struct tty_port *port) |
134 | { | 134 | { |
135 | cancel_work_sync(&port->buf.work); | ||
135 | tty_buffer_free_all(port); | 136 | tty_buffer_free_all(port); |
136 | } | 137 | } |
137 | EXPORT_SYMBOL(tty_port_destroy); | 138 | EXPORT_SYMBOL(tty_port_destroy); |
@@ -196,12 +197,24 @@ void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty) | |||
196 | } | 197 | } |
197 | EXPORT_SYMBOL(tty_port_tty_set); | 198 | EXPORT_SYMBOL(tty_port_tty_set); |
198 | 199 | ||
199 | static void tty_port_shutdown(struct tty_port *port) | 200 | static void tty_port_shutdown(struct tty_port *port, struct tty_struct *tty) |
200 | { | 201 | { |
201 | mutex_lock(&port->mutex); | 202 | mutex_lock(&port->mutex); |
202 | if (port->ops->shutdown && !port->console && | 203 | if (port->console) |
203 | test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags)) | 204 | goto out; |
205 | |||
206 | if (test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags)) { | ||
207 | /* | ||
208 | * Drop DTR/RTS if HUPCL is set. This causes any attached | ||
209 | * modem to hang up the line. | ||
210 | */ | ||
211 | if (tty && C_HUPCL(tty)) | ||
212 | tty_port_lower_dtr_rts(port); | ||
213 | |||
214 | if (port->ops->shutdown) | ||
204 | port->ops->shutdown(port); | 215 | port->ops->shutdown(port); |
216 | } | ||
217 | out: | ||
205 | mutex_unlock(&port->mutex); | 218 | mutex_unlock(&port->mutex); |
206 | } | 219 | } |
207 | 220 | ||
@@ -215,24 +228,58 @@ static void tty_port_shutdown(struct tty_port *port) | |||
215 | 228 | ||
216 | void tty_port_hangup(struct tty_port *port) | 229 | void tty_port_hangup(struct tty_port *port) |
217 | { | 230 | { |
231 | struct tty_struct *tty; | ||
218 | unsigned long flags; | 232 | unsigned long flags; |
219 | 233 | ||
220 | spin_lock_irqsave(&port->lock, flags); | 234 | spin_lock_irqsave(&port->lock, flags); |
221 | port->count = 0; | 235 | port->count = 0; |
222 | port->flags &= ~ASYNC_NORMAL_ACTIVE; | 236 | port->flags &= ~ASYNC_NORMAL_ACTIVE; |
223 | if (port->tty) { | 237 | tty = port->tty; |
224 | set_bit(TTY_IO_ERROR, &port->tty->flags); | 238 | if (tty) |
225 | tty_kref_put(port->tty); | 239 | set_bit(TTY_IO_ERROR, &tty->flags); |
226 | } | ||
227 | port->tty = NULL; | 240 | port->tty = NULL; |
228 | spin_unlock_irqrestore(&port->lock, flags); | 241 | spin_unlock_irqrestore(&port->lock, flags); |
242 | tty_port_shutdown(port, tty); | ||
243 | tty_kref_put(tty); | ||
229 | wake_up_interruptible(&port->open_wait); | 244 | wake_up_interruptible(&port->open_wait); |
230 | wake_up_interruptible(&port->delta_msr_wait); | 245 | wake_up_interruptible(&port->delta_msr_wait); |
231 | tty_port_shutdown(port); | ||
232 | } | 246 | } |
233 | EXPORT_SYMBOL(tty_port_hangup); | 247 | EXPORT_SYMBOL(tty_port_hangup); |
234 | 248 | ||
235 | /** | 249 | /** |
250 | * tty_port_tty_hangup - helper to hang up a tty | ||
251 | * | ||
252 | * @port: tty port | ||
253 | * @check_clocal: hang only ttys with CLOCAL unset? | ||
254 | */ | ||
255 | void tty_port_tty_hangup(struct tty_port *port, bool check_clocal) | ||
256 | { | ||
257 | struct tty_struct *tty = tty_port_tty_get(port); | ||
258 | |||
259 | if (tty && (!check_clocal || !C_CLOCAL(tty))) { | ||
260 | tty_hangup(tty); | ||
261 | tty_kref_put(tty); | ||
262 | } | ||
263 | } | ||
264 | EXPORT_SYMBOL_GPL(tty_port_tty_hangup); | ||
265 | |||
266 | /** | ||
267 | * tty_port_tty_wakeup - helper to wake up a tty | ||
268 | * | ||
269 | * @port: tty port | ||
270 | */ | ||
271 | void tty_port_tty_wakeup(struct tty_port *port) | ||
272 | { | ||
273 | struct tty_struct *tty = tty_port_tty_get(port); | ||
274 | |||
275 | if (tty) { | ||
276 | tty_wakeup(tty); | ||
277 | tty_kref_put(tty); | ||
278 | } | ||
279 | } | ||
280 | EXPORT_SYMBOL_GPL(tty_port_tty_wakeup); | ||
281 | |||
282 | /** | ||
236 | * tty_port_carrier_raised - carrier raised check | 283 | * tty_port_carrier_raised - carrier raised check |
237 | * @port: tty port | 284 | * @port: tty port |
238 | * | 285 | * |
@@ -350,7 +397,7 @@ int tty_port_block_til_ready(struct tty_port *port, | |||
350 | 397 | ||
351 | while (1) { | 398 | while (1) { |
352 | /* Indicate we are open */ | 399 | /* Indicate we are open */ |
353 | if (tty->termios.c_cflag & CBAUD) | 400 | if (C_BAUD(tty) && test_bit(ASYNCB_INITIALIZED, &port->flags)) |
354 | tty_port_raise_dtr_rts(port); | 401 | tty_port_raise_dtr_rts(port); |
355 | 402 | ||
356 | prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE); | 403 | prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE); |
@@ -395,6 +442,20 @@ int tty_port_block_til_ready(struct tty_port *port, | |||
395 | } | 442 | } |
396 | EXPORT_SYMBOL(tty_port_block_til_ready); | 443 | EXPORT_SYMBOL(tty_port_block_til_ready); |
397 | 444 | ||
445 | static void tty_port_drain_delay(struct tty_port *port, struct tty_struct *tty) | ||
446 | { | ||
447 | unsigned int bps = tty_get_baud_rate(tty); | ||
448 | long timeout; | ||
449 | |||
450 | if (bps > 1200) { | ||
451 | timeout = (HZ * 10 * port->drain_delay) / bps; | ||
452 | timeout = max_t(long, timeout, HZ / 10); | ||
453 | } else { | ||
454 | timeout = 2 * HZ; | ||
455 | } | ||
456 | schedule_timeout_interruptible(timeout); | ||
457 | } | ||
458 | |||
398 | int tty_port_close_start(struct tty_port *port, | 459 | int tty_port_close_start(struct tty_port *port, |
399 | struct tty_struct *tty, struct file *filp) | 460 | struct tty_struct *tty, struct file *filp) |
400 | { | 461 | { |
@@ -427,31 +488,19 @@ int tty_port_close_start(struct tty_port *port, | |||
427 | set_bit(ASYNCB_CLOSING, &port->flags); | 488 | set_bit(ASYNCB_CLOSING, &port->flags); |
428 | tty->closing = 1; | 489 | tty->closing = 1; |
429 | spin_unlock_irqrestore(&port->lock, flags); | 490 | spin_unlock_irqrestore(&port->lock, flags); |
430 | /* Don't block on a stalled port, just pull the chain */ | 491 | |
431 | if (tty->flow_stopped) | 492 | if (test_bit(ASYNCB_INITIALIZED, &port->flags)) { |
432 | tty_driver_flush_buffer(tty); | 493 | /* Don't block on a stalled port, just pull the chain */ |
433 | if (test_bit(ASYNCB_INITIALIZED, &port->flags) && | 494 | if (tty->flow_stopped) |
434 | port->closing_wait != ASYNC_CLOSING_WAIT_NONE) | 495 | tty_driver_flush_buffer(tty); |
435 | tty_wait_until_sent_from_close(tty, port->closing_wait); | 496 | if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) |
436 | if (port->drain_delay) { | 497 | tty_wait_until_sent_from_close(tty, port->closing_wait); |
437 | unsigned int bps = tty_get_baud_rate(tty); | 498 | if (port->drain_delay) |
438 | long timeout; | 499 | tty_port_drain_delay(port, tty); |
439 | |||
440 | if (bps > 1200) | ||
441 | timeout = max_t(long, | ||
442 | (HZ * 10 * port->drain_delay) / bps, HZ / 10); | ||
443 | else | ||
444 | timeout = 2 * HZ; | ||
445 | schedule_timeout_interruptible(timeout); | ||
446 | } | 500 | } |
447 | /* Flush the ldisc buffering */ | 501 | /* Flush the ldisc buffering */ |
448 | tty_ldisc_flush(tty); | 502 | tty_ldisc_flush(tty); |
449 | 503 | ||
450 | /* Drop DTR/RTS if HUPCL is set. This causes any attached modem to | ||
451 | hang up the line */ | ||
452 | if (tty->termios.c_cflag & HUPCL) | ||
453 | tty_port_lower_dtr_rts(port); | ||
454 | |||
455 | /* Don't call port->drop for the last reference. Callers will want | 504 | /* Don't call port->drop for the last reference. Callers will want |
456 | to drop the last active reference in ->shutdown() or the tty | 505 | to drop the last active reference in ->shutdown() or the tty |
457 | shutdown path */ | 506 | shutdown path */ |
@@ -486,7 +535,7 @@ void tty_port_close(struct tty_port *port, struct tty_struct *tty, | |||
486 | { | 535 | { |
487 | if (tty_port_close_start(port, tty, filp) == 0) | 536 | if (tty_port_close_start(port, tty, filp) == 0) |
488 | return; | 537 | return; |
489 | tty_port_shutdown(port); | 538 | tty_port_shutdown(port, tty); |
490 | set_bit(TTY_IO_ERROR, &tty->flags); | 539 | set_bit(TTY_IO_ERROR, &tty->flags); |
491 | tty_port_close_end(port, tty); | 540 | tty_port_close_end(port, tty); |
492 | tty_port_tty_set(port, NULL); | 541 | tty_port_tty_set(port, NULL); |
diff --git a/drivers/tty/vt/consolemap.c b/drivers/tty/vt/consolemap.c index 248381b30722..2978ca596a7f 100644 --- a/drivers/tty/vt/consolemap.c +++ b/drivers/tty/vt/consolemap.c | |||
@@ -194,8 +194,7 @@ static void set_inverse_transl(struct vc_data *conp, struct uni_pagedir *p, int | |||
194 | q = p->inverse_translations[i]; | 194 | q = p->inverse_translations[i]; |
195 | 195 | ||
196 | if (!q) { | 196 | if (!q) { |
197 | q = p->inverse_translations[i] = (unsigned char *) | 197 | q = p->inverse_translations[i] = kmalloc(MAX_GLYPH, GFP_KERNEL); |
198 | kmalloc(MAX_GLYPH, GFP_KERNEL); | ||
199 | if (!q) return; | 198 | if (!q) return; |
200 | } | 199 | } |
201 | memset(q, 0, MAX_GLYPH); | 200 | memset(q, 0, MAX_GLYPH); |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 387dc6c8ad25..c77f7ae48f1c 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -292,7 +292,6 @@ static void acm_ctrl_irq(struct urb *urb) | |||
292 | { | 292 | { |
293 | struct acm *acm = urb->context; | 293 | struct acm *acm = urb->context; |
294 | struct usb_cdc_notification *dr = urb->transfer_buffer; | 294 | struct usb_cdc_notification *dr = urb->transfer_buffer; |
295 | struct tty_struct *tty; | ||
296 | unsigned char *data; | 295 | unsigned char *data; |
297 | int newctrl; | 296 | int newctrl; |
298 | int retval; | 297 | int retval; |
@@ -327,17 +326,12 @@ static void acm_ctrl_irq(struct urb *urb) | |||
327 | break; | 326 | break; |
328 | 327 | ||
329 | case USB_CDC_NOTIFY_SERIAL_STATE: | 328 | case USB_CDC_NOTIFY_SERIAL_STATE: |
330 | tty = tty_port_tty_get(&acm->port); | ||
331 | newctrl = get_unaligned_le16(data); | 329 | newctrl = get_unaligned_le16(data); |
332 | 330 | ||
333 | if (tty) { | 331 | if (!acm->clocal && (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) { |
334 | if (!acm->clocal && | 332 | dev_dbg(&acm->control->dev, "%s - calling hangup\n", |
335 | (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) { | 333 | __func__); |
336 | dev_dbg(&acm->control->dev, | 334 | tty_port_tty_hangup(&acm->port, false); |
337 | "%s - calling hangup\n", __func__); | ||
338 | tty_hangup(tty); | ||
339 | } | ||
340 | tty_kref_put(tty); | ||
341 | } | 335 | } |
342 | 336 | ||
343 | acm->ctrlin = newctrl; | 337 | acm->ctrlin = newctrl; |
@@ -475,15 +469,10 @@ static void acm_write_bulk(struct urb *urb) | |||
475 | static void acm_softint(struct work_struct *work) | 469 | static void acm_softint(struct work_struct *work) |
476 | { | 470 | { |
477 | struct acm *acm = container_of(work, struct acm, work); | 471 | struct acm *acm = container_of(work, struct acm, work); |
478 | struct tty_struct *tty; | ||
479 | 472 | ||
480 | dev_vdbg(&acm->data->dev, "%s\n", __func__); | 473 | dev_vdbg(&acm->data->dev, "%s\n", __func__); |
481 | 474 | ||
482 | tty = tty_port_tty_get(&acm->port); | 475 | tty_port_tty_wakeup(&acm->port); |
483 | if (!tty) | ||
484 | return; | ||
485 | tty_wakeup(tty); | ||
486 | tty_kref_put(tty); | ||
487 | } | 476 | } |
488 | 477 | ||
489 | /* | 478 | /* |
@@ -1519,15 +1508,9 @@ err_out: | |||
1519 | static int acm_reset_resume(struct usb_interface *intf) | 1508 | static int acm_reset_resume(struct usb_interface *intf) |
1520 | { | 1509 | { |
1521 | struct acm *acm = usb_get_intfdata(intf); | 1510 | struct acm *acm = usb_get_intfdata(intf); |
1522 | struct tty_struct *tty; | ||
1523 | 1511 | ||
1524 | if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags)) { | 1512 | if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags)) |
1525 | tty = tty_port_tty_get(&acm->port); | 1513 | tty_port_tty_hangup(&acm->port, false); |
1526 | if (tty) { | ||
1527 | tty_hangup(tty); | ||
1528 | tty_kref_put(tty); | ||
1529 | } | ||
1530 | } | ||
1531 | 1514 | ||
1532 | return acm_resume(intf); | 1515 | return acm_resume(intf); |
1533 | } | 1516 | } |
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index ebe45fa0ed50..31191581060c 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c | |||
@@ -210,7 +210,6 @@ struct digi_port { | |||
210 | 210 | ||
211 | /* Local Function Declarations */ | 211 | /* Local Function Declarations */ |
212 | 212 | ||
213 | static void digi_wakeup_write(struct usb_serial_port *port); | ||
214 | static void digi_wakeup_write_lock(struct work_struct *work); | 213 | static void digi_wakeup_write_lock(struct work_struct *work); |
215 | static int digi_write_oob_command(struct usb_serial_port *port, | 214 | static int digi_write_oob_command(struct usb_serial_port *port, |
216 | unsigned char *buf, int count, int interruptible); | 215 | unsigned char *buf, int count, int interruptible); |
@@ -374,20 +373,10 @@ static void digi_wakeup_write_lock(struct work_struct *work) | |||
374 | unsigned long flags; | 373 | unsigned long flags; |
375 | 374 | ||
376 | spin_lock_irqsave(&priv->dp_port_lock, flags); | 375 | spin_lock_irqsave(&priv->dp_port_lock, flags); |
377 | digi_wakeup_write(port); | 376 | tty_port_tty_wakeup(&port->port); |
378 | spin_unlock_irqrestore(&priv->dp_port_lock, flags); | 377 | spin_unlock_irqrestore(&priv->dp_port_lock, flags); |
379 | } | 378 | } |
380 | 379 | ||
381 | static void digi_wakeup_write(struct usb_serial_port *port) | ||
382 | { | ||
383 | struct tty_struct *tty = tty_port_tty_get(&port->port); | ||
384 | if (tty) { | ||
385 | tty_wakeup(tty); | ||
386 | tty_kref_put(tty); | ||
387 | } | ||
388 | } | ||
389 | |||
390 | |||
391 | /* | 380 | /* |
392 | * Digi Write OOB Command | 381 | * Digi Write OOB Command |
393 | * | 382 | * |
@@ -1044,7 +1033,7 @@ static void digi_write_bulk_callback(struct urb *urb) | |||
1044 | } | 1033 | } |
1045 | } | 1034 | } |
1046 | /* wake up processes sleeping on writes immediately */ | 1035 | /* wake up processes sleeping on writes immediately */ |
1047 | digi_wakeup_write(port); | 1036 | tty_port_tty_wakeup(&port->port); |
1048 | /* also queue up a wakeup at scheduler time, in case we */ | 1037 | /* also queue up a wakeup at scheduler time, in case we */ |
1049 | /* lost the race in write_chan(). */ | 1038 | /* lost the race in write_chan(). */ |
1050 | schedule_work(&priv->dp_wakeup_work); | 1039 | schedule_work(&priv->dp_wakeup_work); |
@@ -1522,7 +1511,7 @@ static int digi_read_oob_callback(struct urb *urb) | |||
1522 | /* port must be open to use tty struct */ | 1511 | /* port must be open to use tty struct */ |
1523 | if (rts) { | 1512 | if (rts) { |
1524 | tty->hw_stopped = 0; | 1513 | tty->hw_stopped = 0; |
1525 | digi_wakeup_write(port); | 1514 | tty_port_tty_wakeup(&port->port); |
1526 | } | 1515 | } |
1527 | } else { | 1516 | } else { |
1528 | priv->dp_modem_signals &= ~TIOCM_CTS; | 1517 | priv->dp_modem_signals &= ~TIOCM_CTS; |
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index efd8b978128c..cf0b0a2f7b56 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c | |||
@@ -564,7 +564,6 @@ static void edge_interrupt_callback(struct urb *urb) | |||
564 | struct device *dev; | 564 | struct device *dev; |
565 | struct edgeport_port *edge_port; | 565 | struct edgeport_port *edge_port; |
566 | struct usb_serial_port *port; | 566 | struct usb_serial_port *port; |
567 | struct tty_struct *tty; | ||
568 | unsigned char *data = urb->transfer_buffer; | 567 | unsigned char *data = urb->transfer_buffer; |
569 | int length = urb->actual_length; | 568 | int length = urb->actual_length; |
570 | int bytes_avail; | 569 | int bytes_avail; |
@@ -643,12 +642,7 @@ static void edge_interrupt_callback(struct urb *urb) | |||
643 | 642 | ||
644 | /* tell the tty driver that something | 643 | /* tell the tty driver that something |
645 | has changed */ | 644 | has changed */ |
646 | tty = tty_port_tty_get( | 645 | tty_port_tty_wakeup(&edge_port->port->port); |
647 | &edge_port->port->port); | ||
648 | if (tty) { | ||
649 | tty_wakeup(tty); | ||
650 | tty_kref_put(tty); | ||
651 | } | ||
652 | /* Since we have more credit, check | 646 | /* Since we have more credit, check |
653 | if more data can be sent */ | 647 | if more data can be sent */ |
654 | send_more_port_data(edge_serial, | 648 | send_more_port_data(edge_serial, |
@@ -737,7 +731,6 @@ static void edge_bulk_in_callback(struct urb *urb) | |||
737 | static void edge_bulk_out_data_callback(struct urb *urb) | 731 | static void edge_bulk_out_data_callback(struct urb *urb) |
738 | { | 732 | { |
739 | struct edgeport_port *edge_port = urb->context; | 733 | struct edgeport_port *edge_port = urb->context; |
740 | struct tty_struct *tty; | ||
741 | int status = urb->status; | 734 | int status = urb->status; |
742 | 735 | ||
743 | if (status) { | 736 | if (status) { |
@@ -746,14 +739,8 @@ static void edge_bulk_out_data_callback(struct urb *urb) | |||
746 | __func__, status); | 739 | __func__, status); |
747 | } | 740 | } |
748 | 741 | ||
749 | tty = tty_port_tty_get(&edge_port->port->port); | 742 | if (edge_port->open) |
750 | 743 | tty_port_tty_wakeup(&edge_port->port->port); | |
751 | if (tty && edge_port->open) { | ||
752 | /* let the tty driver wakeup if it has a special | ||
753 | write_wakeup function */ | ||
754 | tty_wakeup(tty); | ||
755 | } | ||
756 | tty_kref_put(tty); | ||
757 | 744 | ||
758 | /* Release the Write URB */ | 745 | /* Release the Write URB */ |
759 | edge_port->write_in_progress = false; | 746 | edge_port->write_in_progress = false; |
@@ -772,7 +759,6 @@ static void edge_bulk_out_data_callback(struct urb *urb) | |||
772 | static void edge_bulk_out_cmd_callback(struct urb *urb) | 759 | static void edge_bulk_out_cmd_callback(struct urb *urb) |
773 | { | 760 | { |
774 | struct edgeport_port *edge_port = urb->context; | 761 | struct edgeport_port *edge_port = urb->context; |
775 | struct tty_struct *tty; | ||
776 | int status = urb->status; | 762 | int status = urb->status; |
777 | 763 | ||
778 | atomic_dec(&CmdUrbs); | 764 | atomic_dec(&CmdUrbs); |
@@ -793,13 +779,9 @@ static void edge_bulk_out_cmd_callback(struct urb *urb) | |||
793 | return; | 779 | return; |
794 | } | 780 | } |
795 | 781 | ||
796 | /* Get pointer to tty */ | ||
797 | tty = tty_port_tty_get(&edge_port->port->port); | ||
798 | |||
799 | /* tell the tty driver that something has changed */ | 782 | /* tell the tty driver that something has changed */ |
800 | if (tty && edge_port->open) | 783 | if (edge_port->open) |
801 | tty_wakeup(tty); | 784 | tty_port_tty_wakeup(&edge_port->port->port); |
802 | tty_kref_put(tty); | ||
803 | 785 | ||
804 | /* we have completed the command */ | 786 | /* we have completed the command */ |
805 | edge_port->commandPending = false; | 787 | edge_port->commandPending = false; |
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 1fd1935c8316..b011478d2e5f 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c | |||
@@ -378,7 +378,6 @@ static void usa26_instat_callback(struct urb *urb) | |||
378 | struct usb_serial *serial; | 378 | struct usb_serial *serial; |
379 | struct usb_serial_port *port; | 379 | struct usb_serial_port *port; |
380 | struct keyspan_port_private *p_priv; | 380 | struct keyspan_port_private *p_priv; |
381 | struct tty_struct *tty; | ||
382 | int old_dcd_state, err; | 381 | int old_dcd_state, err; |
383 | int status = urb->status; | 382 | int status = urb->status; |
384 | 383 | ||
@@ -421,12 +420,8 @@ static void usa26_instat_callback(struct urb *urb) | |||
421 | p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0); | 420 | p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0); |
422 | p_priv->ri_state = ((msg->ri) ? 1 : 0); | 421 | p_priv->ri_state = ((msg->ri) ? 1 : 0); |
423 | 422 | ||
424 | if (old_dcd_state != p_priv->dcd_state) { | 423 | if (old_dcd_state != p_priv->dcd_state) |
425 | tty = tty_port_tty_get(&port->port); | 424 | tty_port_tty_hangup(&port->port, true); |
426 | if (tty && !C_CLOCAL(tty)) | ||
427 | tty_hangup(tty); | ||
428 | tty_kref_put(tty); | ||
429 | } | ||
430 | 425 | ||
431 | /* Resubmit urb so we continue receiving */ | 426 | /* Resubmit urb so we continue receiving */ |
432 | err = usb_submit_urb(urb, GFP_ATOMIC); | 427 | err = usb_submit_urb(urb, GFP_ATOMIC); |
@@ -510,7 +505,6 @@ static void usa28_instat_callback(struct urb *urb) | |||
510 | struct usb_serial *serial; | 505 | struct usb_serial *serial; |
511 | struct usb_serial_port *port; | 506 | struct usb_serial_port *port; |
512 | struct keyspan_port_private *p_priv; | 507 | struct keyspan_port_private *p_priv; |
513 | struct tty_struct *tty; | ||
514 | int old_dcd_state; | 508 | int old_dcd_state; |
515 | int status = urb->status; | 509 | int status = urb->status; |
516 | 510 | ||
@@ -551,12 +545,8 @@ static void usa28_instat_callback(struct urb *urb) | |||
551 | p_priv->dcd_state = ((msg->dcd) ? 1 : 0); | 545 | p_priv->dcd_state = ((msg->dcd) ? 1 : 0); |
552 | p_priv->ri_state = ((msg->ri) ? 1 : 0); | 546 | p_priv->ri_state = ((msg->ri) ? 1 : 0); |
553 | 547 | ||
554 | if (old_dcd_state != p_priv->dcd_state && old_dcd_state) { | 548 | if (old_dcd_state != p_priv->dcd_state && old_dcd_state) |
555 | tty = tty_port_tty_get(&port->port); | 549 | tty_port_tty_hangup(&port->port, true); |
556 | if (tty && !C_CLOCAL(tty)) | ||
557 | tty_hangup(tty); | ||
558 | tty_kref_put(tty); | ||
559 | } | ||
560 | 550 | ||
561 | /* Resubmit urb so we continue receiving */ | 551 | /* Resubmit urb so we continue receiving */ |
562 | err = usb_submit_urb(urb, GFP_ATOMIC); | 552 | err = usb_submit_urb(urb, GFP_ATOMIC); |
@@ -642,12 +632,8 @@ static void usa49_instat_callback(struct urb *urb) | |||
642 | p_priv->dcd_state = ((msg->dcd) ? 1 : 0); | 632 | p_priv->dcd_state = ((msg->dcd) ? 1 : 0); |
643 | p_priv->ri_state = ((msg->ri) ? 1 : 0); | 633 | p_priv->ri_state = ((msg->ri) ? 1 : 0); |
644 | 634 | ||
645 | if (old_dcd_state != p_priv->dcd_state && old_dcd_state) { | 635 | if (old_dcd_state != p_priv->dcd_state && old_dcd_state) |
646 | struct tty_struct *tty = tty_port_tty_get(&port->port); | 636 | tty_port_tty_hangup(&port->port, true); |
647 | if (tty && !C_CLOCAL(tty)) | ||
648 | tty_hangup(tty); | ||
649 | tty_kref_put(tty); | ||
650 | } | ||
651 | 637 | ||
652 | /* Resubmit urb so we continue receiving */ | 638 | /* Resubmit urb so we continue receiving */ |
653 | err = usb_submit_urb(urb, GFP_ATOMIC); | 639 | err = usb_submit_urb(urb, GFP_ATOMIC); |
@@ -851,7 +837,6 @@ static void usa90_instat_callback(struct urb *urb) | |||
851 | struct usb_serial *serial; | 837 | struct usb_serial *serial; |
852 | struct usb_serial_port *port; | 838 | struct usb_serial_port *port; |
853 | struct keyspan_port_private *p_priv; | 839 | struct keyspan_port_private *p_priv; |
854 | struct tty_struct *tty; | ||
855 | int old_dcd_state, err; | 840 | int old_dcd_state, err; |
856 | int status = urb->status; | 841 | int status = urb->status; |
857 | 842 | ||
@@ -880,12 +865,8 @@ static void usa90_instat_callback(struct urb *urb) | |||
880 | p_priv->dcd_state = ((msg->dcd) ? 1 : 0); | 865 | p_priv->dcd_state = ((msg->dcd) ? 1 : 0); |
881 | p_priv->ri_state = ((msg->ri) ? 1 : 0); | 866 | p_priv->ri_state = ((msg->ri) ? 1 : 0); |
882 | 867 | ||
883 | if (old_dcd_state != p_priv->dcd_state && old_dcd_state) { | 868 | if (old_dcd_state != p_priv->dcd_state && old_dcd_state) |
884 | tty = tty_port_tty_get(&port->port); | 869 | tty_port_tty_hangup(&port->port, true); |
885 | if (tty && !C_CLOCAL(tty)) | ||
886 | tty_hangup(tty); | ||
887 | tty_kref_put(tty); | ||
888 | } | ||
889 | 870 | ||
890 | /* Resubmit urb so we continue receiving */ | 871 | /* Resubmit urb so we continue receiving */ |
891 | err = usb_submit_urb(urb, GFP_ATOMIC); | 872 | err = usb_submit_urb(urb, GFP_ATOMIC); |
@@ -953,12 +934,8 @@ static void usa67_instat_callback(struct urb *urb) | |||
953 | p_priv->cts_state = ((msg->hskia_cts) ? 1 : 0); | 934 | p_priv->cts_state = ((msg->hskia_cts) ? 1 : 0); |
954 | p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0); | 935 | p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0); |
955 | 936 | ||
956 | if (old_dcd_state != p_priv->dcd_state && old_dcd_state) { | 937 | if (old_dcd_state != p_priv->dcd_state && old_dcd_state) |
957 | struct tty_struct *tty = tty_port_tty_get(&port->port); | 938 | tty_port_tty_hangup(&port->port, true); |
958 | if (tty && !C_CLOCAL(tty)) | ||
959 | tty_hangup(tty); | ||
960 | tty_kref_put(tty); | ||
961 | } | ||
962 | 939 | ||
963 | /* Resubmit urb so we continue receiving */ | 940 | /* Resubmit urb so we continue receiving */ |
964 | err = usb_submit_urb(urb, GFP_ATOMIC); | 941 | err = usb_submit_urb(urb, GFP_ATOMIC); |
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 3b17d5d13dc8..2230223978ca 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c | |||
@@ -104,10 +104,8 @@ static void keyspan_pda_wakeup_write(struct work_struct *work) | |||
104 | struct keyspan_pda_private *priv = | 104 | struct keyspan_pda_private *priv = |
105 | container_of(work, struct keyspan_pda_private, wakeup_work); | 105 | container_of(work, struct keyspan_pda_private, wakeup_work); |
106 | struct usb_serial_port *port = priv->port; | 106 | struct usb_serial_port *port = priv->port; |
107 | struct tty_struct *tty = tty_port_tty_get(&port->port); | 107 | |
108 | if (tty) | 108 | tty_port_tty_wakeup(&port->port); |
109 | tty_wakeup(tty); | ||
110 | tty_kref_put(tty); | ||
111 | } | 109 | } |
112 | 110 | ||
113 | static void keyspan_pda_request_unthrottle(struct work_struct *work) | 111 | static void keyspan_pda_request_unthrottle(struct work_struct *work) |
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index e0ebec3b5d6a..e956eae198fd 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c | |||
@@ -932,7 +932,6 @@ static void mos7720_bulk_in_callback(struct urb *urb) | |||
932 | static void mos7720_bulk_out_data_callback(struct urb *urb) | 932 | static void mos7720_bulk_out_data_callback(struct urb *urb) |
933 | { | 933 | { |
934 | struct moschip_port *mos7720_port; | 934 | struct moschip_port *mos7720_port; |
935 | struct tty_struct *tty; | ||
936 | int status = urb->status; | 935 | int status = urb->status; |
937 | 936 | ||
938 | if (status) { | 937 | if (status) { |
@@ -946,11 +945,8 @@ static void mos7720_bulk_out_data_callback(struct urb *urb) | |||
946 | return ; | 945 | return ; |
947 | } | 946 | } |
948 | 947 | ||
949 | tty = tty_port_tty_get(&mos7720_port->port->port); | 948 | if (mos7720_port->open) |
950 | 949 | tty_port_tty_wakeup(&mos7720_port->port->port); | |
951 | if (tty && mos7720_port->open) | ||
952 | tty_wakeup(tty); | ||
953 | tty_kref_put(tty); | ||
954 | } | 950 | } |
955 | 951 | ||
956 | /* | 952 | /* |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index b8051fa61911..2be376a2e0e3 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -816,7 +816,6 @@ static void mos7840_bulk_out_data_callback(struct urb *urb) | |||
816 | { | 816 | { |
817 | struct moschip_port *mos7840_port; | 817 | struct moschip_port *mos7840_port; |
818 | struct usb_serial_port *port; | 818 | struct usb_serial_port *port; |
819 | struct tty_struct *tty; | ||
820 | int status = urb->status; | 819 | int status = urb->status; |
821 | int i; | 820 | int i; |
822 | 821 | ||
@@ -839,10 +838,8 @@ static void mos7840_bulk_out_data_callback(struct urb *urb) | |||
839 | if (mos7840_port_paranoia_check(port, __func__)) | 838 | if (mos7840_port_paranoia_check(port, __func__)) |
840 | return; | 839 | return; |
841 | 840 | ||
842 | tty = tty_port_tty_get(&port->port); | 841 | if (mos7840_port->open) |
843 | if (tty && mos7840_port->open) | 842 | tty_port_tty_wakeup(&port->port); |
844 | tty_wakeup(tty); | ||
845 | tty_kref_put(tty); | ||
846 | 843 | ||
847 | } | 844 | } |
848 | 845 | ||
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 558adfc05007..09cd3967b8df 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -1537,13 +1537,8 @@ static void option_instat_callback(struct urb *urb) | |||
1537 | portdata->dsr_state = ((signals & 0x02) ? 1 : 0); | 1537 | portdata->dsr_state = ((signals & 0x02) ? 1 : 0); |
1538 | portdata->ri_state = ((signals & 0x08) ? 1 : 0); | 1538 | portdata->ri_state = ((signals & 0x08) ? 1 : 0); |
1539 | 1539 | ||
1540 | if (old_dcd_state && !portdata->dcd_state) { | 1540 | if (old_dcd_state && !portdata->dcd_state) |
1541 | struct tty_struct *tty = | 1541 | tty_port_tty_hangup(&port->port, true); |
1542 | tty_port_tty_get(&port->port); | ||
1543 | if (tty && !C_CLOCAL(tty)) | ||
1544 | tty_hangup(tty); | ||
1545 | tty_kref_put(tty); | ||
1546 | } | ||
1547 | } else { | 1542 | } else { |
1548 | dev_dbg(dev, "%s: type %x req %x\n", __func__, | 1543 | dev_dbg(dev, "%s: type %x req %x\n", __func__, |
1549 | req_pkt->bRequestType, req_pkt->bRequest); | 1544 | req_pkt->bRequestType, req_pkt->bRequest); |
diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c index 75f125ddb0c9..ef3a7d5eaab4 100644 --- a/drivers/usb/serial/quatech2.c +++ b/drivers/usb/serial/quatech2.c | |||
@@ -116,7 +116,6 @@ struct qt2_serial_private { | |||
116 | }; | 116 | }; |
117 | 117 | ||
118 | struct qt2_port_private { | 118 | struct qt2_port_private { |
119 | bool is_open; | ||
120 | u8 device_port; | 119 | u8 device_port; |
121 | 120 | ||
122 | spinlock_t urb_lock; | 121 | spinlock_t urb_lock; |
@@ -397,7 +396,6 @@ static int qt2_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
397 | return status; | 396 | return status; |
398 | } | 397 | } |
399 | 398 | ||
400 | port_priv->is_open = true; | ||
401 | port_priv->device_port = (u8) device_port; | 399 | port_priv->device_port = (u8) device_port; |
402 | 400 | ||
403 | if (tty) | 401 | if (tty) |
@@ -417,8 +415,6 @@ static void qt2_close(struct usb_serial_port *port) | |||
417 | serial = port->serial; | 415 | serial = port->serial; |
418 | port_priv = usb_get_serial_port_data(port); | 416 | port_priv = usb_get_serial_port_data(port); |
419 | 417 | ||
420 | port_priv->is_open = false; | ||
421 | |||
422 | spin_lock_irqsave(&port_priv->urb_lock, flags); | 418 | spin_lock_irqsave(&port_priv->urb_lock, flags); |
423 | usb_kill_urb(port_priv->write_urb); | 419 | usb_kill_urb(port_priv->write_urb); |
424 | port_priv->urb_in_use = false; | 420 | port_priv->urb_in_use = false; |
@@ -664,9 +660,7 @@ void qt2_process_read_urb(struct urb *urb) | |||
664 | __func__); | 660 | __func__); |
665 | break; | 661 | break; |
666 | } | 662 | } |
667 | 663 | tty_flip_buffer_push(&port->port); | |
668 | if (port_priv->is_open) | ||
669 | tty_flip_buffer_push(&port->port); | ||
670 | 664 | ||
671 | newport = *(ch + 3); | 665 | newport = *(ch + 3); |
672 | 666 | ||
@@ -709,8 +703,7 @@ void qt2_process_read_urb(struct urb *urb) | |||
709 | tty_insert_flip_string(&port->port, ch, 1); | 703 | tty_insert_flip_string(&port->port, ch, 1); |
710 | } | 704 | } |
711 | 705 | ||
712 | if (port_priv->is_open) | 706 | tty_flip_buffer_push(&port->port); |
713 | tty_flip_buffer_push(&port->port); | ||
714 | } | 707 | } |
715 | 708 | ||
716 | static void qt2_write_bulk_callback(struct urb *urb) | 709 | static void qt2_write_bulk_callback(struct urb *urb) |
@@ -910,12 +903,6 @@ static void qt2_break_ctl(struct tty_struct *tty, int break_state) | |||
910 | 903 | ||
911 | port_priv = usb_get_serial_port_data(port); | 904 | port_priv = usb_get_serial_port_data(port); |
912 | 905 | ||
913 | if (!port_priv->is_open) { | ||
914 | dev_err(&port->dev, | ||
915 | "%s - port is not open\n", __func__); | ||
916 | return; | ||
917 | } | ||
918 | |||
919 | val = (break_state == -1) ? 1 : 0; | 906 | val = (break_state == -1) ? 1 : 0; |
920 | 907 | ||
921 | status = qt2_control_msg(port->serial->dev, QT2_BREAK_CONTROL, | 908 | status = qt2_control_msg(port->serial->dev, QT2_BREAK_CONTROL, |
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index c13f6e747748..d66148a17fe3 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
@@ -628,7 +628,6 @@ static void sierra_instat_callback(struct urb *urb) | |||
628 | unsigned char signals = *((unsigned char *) | 628 | unsigned char signals = *((unsigned char *) |
629 | urb->transfer_buffer + | 629 | urb->transfer_buffer + |
630 | sizeof(struct usb_ctrlrequest)); | 630 | sizeof(struct usb_ctrlrequest)); |
631 | struct tty_struct *tty; | ||
632 | 631 | ||
633 | dev_dbg(&port->dev, "%s: signal x%x\n", __func__, | 632 | dev_dbg(&port->dev, "%s: signal x%x\n", __func__, |
634 | signals); | 633 | signals); |
@@ -639,11 +638,8 @@ static void sierra_instat_callback(struct urb *urb) | |||
639 | portdata->dsr_state = ((signals & 0x02) ? 1 : 0); | 638 | portdata->dsr_state = ((signals & 0x02) ? 1 : 0); |
640 | portdata->ri_state = ((signals & 0x08) ? 1 : 0); | 639 | portdata->ri_state = ((signals & 0x08) ? 1 : 0); |
641 | 640 | ||
642 | tty = tty_port_tty_get(&port->port); | 641 | if (old_dcd_state && !portdata->dcd_state) |
643 | if (tty && !C_CLOCAL(tty) && | 642 | tty_port_tty_hangup(&port->port, true); |
644 | old_dcd_state && !portdata->dcd_state) | ||
645 | tty_hangup(tty); | ||
646 | tty_kref_put(tty); | ||
647 | } else { | 643 | } else { |
648 | dev_dbg(&port->dev, "%s: type %x req %x\n", | 644 | dev_dbg(&port->dev, "%s: type %x req %x\n", |
649 | __func__, req_pkt->bRequestType, | 645 | __func__, req_pkt->bRequestType, |
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 73deb029fc05..19a71a9eecf0 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
@@ -1229,7 +1229,6 @@ static void ti_send(struct ti_port *tport) | |||
1229 | { | 1229 | { |
1230 | int count, result; | 1230 | int count, result; |
1231 | struct usb_serial_port *port = tport->tp_port; | 1231 | struct usb_serial_port *port = tport->tp_port; |
1232 | struct tty_struct *tty = tty_port_tty_get(&port->port); /* FIXME */ | ||
1233 | unsigned long flags; | 1232 | unsigned long flags; |
1234 | 1233 | ||
1235 | spin_lock_irqsave(&tport->tp_lock, flags); | 1234 | spin_lock_irqsave(&tport->tp_lock, flags); |
@@ -1270,14 +1269,12 @@ static void ti_send(struct ti_port *tport) | |||
1270 | } | 1269 | } |
1271 | 1270 | ||
1272 | /* more room in the buffer for new writes, wakeup */ | 1271 | /* more room in the buffer for new writes, wakeup */ |
1273 | if (tty) | 1272 | tty_port_tty_wakeup(&port->port); |
1274 | tty_wakeup(tty); | 1273 | |
1275 | tty_kref_put(tty); | ||
1276 | wake_up_interruptible(&tport->tp_write_wait); | 1274 | wake_up_interruptible(&tport->tp_write_wait); |
1277 | return; | 1275 | return; |
1278 | unlock: | 1276 | unlock: |
1279 | spin_unlock_irqrestore(&tport->tp_lock, flags); | 1277 | spin_unlock_irqrestore(&tport->tp_lock, flags); |
1280 | tty_kref_put(tty); | ||
1281 | return; | 1278 | return; |
1282 | } | 1279 | } |
1283 | 1280 | ||
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 5d9b178484fd..650be17a68f2 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -542,16 +542,8 @@ static void usb_serial_port_work(struct work_struct *work) | |||
542 | { | 542 | { |
543 | struct usb_serial_port *port = | 543 | struct usb_serial_port *port = |
544 | container_of(work, struct usb_serial_port, work); | 544 | container_of(work, struct usb_serial_port, work); |
545 | struct tty_struct *tty; | ||
546 | 545 | ||
547 | tty = tty_port_tty_get(&port->port); | 546 | tty_port_tty_wakeup(&port->port); |
548 | if (!tty) | ||
549 | return; | ||
550 | |||
551 | dev_dbg(tty->dev, "%s - port %d\n", __func__, port->number); | ||
552 | |||
553 | tty_wakeup(tty); | ||
554 | tty_kref_put(tty); | ||
555 | } | 547 | } |
556 | 548 | ||
557 | static void kill_traffic(struct usb_serial_port *port) | 549 | static void kill_traffic(struct usb_serial_port *port) |
diff --git a/include/linux/amba/serial.h b/include/linux/amba/serial.h index f612c783170f..62d9303c2837 100644 --- a/include/linux/amba/serial.h +++ b/include/linux/amba/serial.h | |||
@@ -203,6 +203,9 @@ struct amba_pl011_data { | |||
203 | bool (*dma_filter)(struct dma_chan *chan, void *filter_param); | 203 | bool (*dma_filter)(struct dma_chan *chan, void *filter_param); |
204 | void *dma_rx_param; | 204 | void *dma_rx_param; |
205 | void *dma_tx_param; | 205 | void *dma_tx_param; |
206 | bool dma_rx_poll_enable; | ||
207 | unsigned int dma_rx_poll_rate; | ||
208 | unsigned int dma_rx_poll_timeout; | ||
206 | void (*init) (void); | 209 | void (*init) (void); |
207 | void (*exit) (void); | 210 | void (*exit) (void); |
208 | }; | 211 | }; |
diff --git a/include/linux/platform_data/serial-sccnxp.h b/include/linux/platform_data/serial-sccnxp.h index 215574d1e81d..bdc510d03245 100644 --- a/include/linux/platform_data/serial-sccnxp.h +++ b/include/linux/platform_data/serial-sccnxp.h | |||
@@ -86,10 +86,6 @@ struct sccnxp_pdata { | |||
86 | const u32 mctrl_cfg[SCCNXP_MAX_UARTS]; | 86 | const u32 mctrl_cfg[SCCNXP_MAX_UARTS]; |
87 | /* Timer value for polling mode (usecs) */ | 87 | /* Timer value for polling mode (usecs) */ |
88 | const unsigned int poll_time_us; | 88 | const unsigned int poll_time_us; |
89 | /* Called during startup */ | ||
90 | void (*init)(void); | ||
91 | /* Called before finish */ | ||
92 | void (*exit)(void); | ||
93 | }; | 89 | }; |
94 | 90 | ||
95 | #endif | 91 | #endif |
diff --git a/include/linux/serial_s3c.h b/include/linux/serial_s3c.h new file mode 100644 index 000000000000..907d9d1d56cf --- /dev/null +++ b/include/linux/serial_s3c.h | |||
@@ -0,0 +1,260 @@ | |||
1 | /* | ||
2 | * Internal header file for Samsung S3C2410 serial ports (UART0-2) | ||
3 | * | ||
4 | * Copyright (C) 2002 Shane Nay (shane@minirl.com) | ||
5 | * | ||
6 | * Additional defines, Copyright 2003 Simtec Electronics (linux@simtec.co.uk) | ||
7 | * | ||
8 | * Adapted from: | ||
9 | * | ||
10 | * Internal header file for MX1ADS serial ports (UART1 & 2) | ||
11 | * | ||
12 | * Copyright (C) 2002 Shane Nay (shane@minirl.com) | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License as published by | ||
16 | * the Free Software Foundation; either version 2 of the License, or | ||
17 | * (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
27 | */ | ||
28 | |||
29 | #ifndef __ASM_ARM_REGS_SERIAL_H | ||
30 | #define __ASM_ARM_REGS_SERIAL_H | ||
31 | |||
32 | #define S3C2410_URXH (0x24) | ||
33 | #define S3C2410_UTXH (0x20) | ||
34 | #define S3C2410_ULCON (0x00) | ||
35 | #define S3C2410_UCON (0x04) | ||
36 | #define S3C2410_UFCON (0x08) | ||
37 | #define S3C2410_UMCON (0x0C) | ||
38 | #define S3C2410_UBRDIV (0x28) | ||
39 | #define S3C2410_UTRSTAT (0x10) | ||
40 | #define S3C2410_UERSTAT (0x14) | ||
41 | #define S3C2410_UFSTAT (0x18) | ||
42 | #define S3C2410_UMSTAT (0x1C) | ||
43 | |||
44 | #define S3C2410_LCON_CFGMASK ((0xF<<3)|(0x3)) | ||
45 | |||
46 | #define S3C2410_LCON_CS5 (0x0) | ||
47 | #define S3C2410_LCON_CS6 (0x1) | ||
48 | #define S3C2410_LCON_CS7 (0x2) | ||
49 | #define S3C2410_LCON_CS8 (0x3) | ||
50 | #define S3C2410_LCON_CSMASK (0x3) | ||
51 | |||
52 | #define S3C2410_LCON_PNONE (0x0) | ||
53 | #define S3C2410_LCON_PEVEN (0x5 << 3) | ||
54 | #define S3C2410_LCON_PODD (0x4 << 3) | ||
55 | #define S3C2410_LCON_PMASK (0x7 << 3) | ||
56 | |||
57 | #define S3C2410_LCON_STOPB (1<<2) | ||
58 | #define S3C2410_LCON_IRM (1<<6) | ||
59 | |||
60 | #define S3C2440_UCON_CLKMASK (3<<10) | ||
61 | #define S3C2440_UCON_CLKSHIFT (10) | ||
62 | #define S3C2440_UCON_PCLK (0<<10) | ||
63 | #define S3C2440_UCON_UCLK (1<<10) | ||
64 | #define S3C2440_UCON_PCLK2 (2<<10) | ||
65 | #define S3C2440_UCON_FCLK (3<<10) | ||
66 | #define S3C2443_UCON_EPLL (3<<10) | ||
67 | |||
68 | #define S3C6400_UCON_CLKMASK (3<<10) | ||
69 | #define S3C6400_UCON_CLKSHIFT (10) | ||
70 | #define S3C6400_UCON_PCLK (0<<10) | ||
71 | #define S3C6400_UCON_PCLK2 (2<<10) | ||
72 | #define S3C6400_UCON_UCLK0 (1<<10) | ||
73 | #define S3C6400_UCON_UCLK1 (3<<10) | ||
74 | |||
75 | #define S3C2440_UCON2_FCLK_EN (1<<15) | ||
76 | #define S3C2440_UCON0_DIVMASK (15 << 12) | ||
77 | #define S3C2440_UCON1_DIVMASK (15 << 12) | ||
78 | #define S3C2440_UCON2_DIVMASK (7 << 12) | ||
79 | #define S3C2440_UCON_DIVSHIFT (12) | ||
80 | |||
81 | #define S3C2412_UCON_CLKMASK (3<<10) | ||
82 | #define S3C2412_UCON_CLKSHIFT (10) | ||
83 | #define S3C2412_UCON_UCLK (1<<10) | ||
84 | #define S3C2412_UCON_USYSCLK (3<<10) | ||
85 | #define S3C2412_UCON_PCLK (0<<10) | ||
86 | #define S3C2412_UCON_PCLK2 (2<<10) | ||
87 | |||
88 | #define S3C2410_UCON_CLKMASK (1 << 10) | ||
89 | #define S3C2410_UCON_CLKSHIFT (10) | ||
90 | #define S3C2410_UCON_UCLK (1<<10) | ||
91 | #define S3C2410_UCON_SBREAK (1<<4) | ||
92 | |||
93 | #define S3C2410_UCON_TXILEVEL (1<<9) | ||
94 | #define S3C2410_UCON_RXILEVEL (1<<8) | ||
95 | #define S3C2410_UCON_TXIRQMODE (1<<2) | ||
96 | #define S3C2410_UCON_RXIRQMODE (1<<0) | ||
97 | #define S3C2410_UCON_RXFIFO_TOI (1<<7) | ||
98 | #define S3C2443_UCON_RXERR_IRQEN (1<<6) | ||
99 | #define S3C2443_UCON_LOOPBACK (1<<5) | ||
100 | |||
101 | #define S3C2410_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ | ||
102 | S3C2410_UCON_RXILEVEL | \ | ||
103 | S3C2410_UCON_TXIRQMODE | \ | ||
104 | S3C2410_UCON_RXIRQMODE | \ | ||
105 | S3C2410_UCON_RXFIFO_TOI) | ||
106 | |||
107 | #define S3C2410_UFCON_FIFOMODE (1<<0) | ||
108 | #define S3C2410_UFCON_TXTRIG0 (0<<6) | ||
109 | #define S3C2410_UFCON_RXTRIG8 (1<<4) | ||
110 | #define S3C2410_UFCON_RXTRIG12 (2<<4) | ||
111 | |||
112 | /* S3C2440 FIFO trigger levels */ | ||
113 | #define S3C2440_UFCON_RXTRIG1 (0<<4) | ||
114 | #define S3C2440_UFCON_RXTRIG8 (1<<4) | ||
115 | #define S3C2440_UFCON_RXTRIG16 (2<<4) | ||
116 | #define S3C2440_UFCON_RXTRIG32 (3<<4) | ||
117 | |||
118 | #define S3C2440_UFCON_TXTRIG0 (0<<6) | ||
119 | #define S3C2440_UFCON_TXTRIG16 (1<<6) | ||
120 | #define S3C2440_UFCON_TXTRIG32 (2<<6) | ||
121 | #define S3C2440_UFCON_TXTRIG48 (3<<6) | ||
122 | |||
123 | #define S3C2410_UFCON_RESETBOTH (3<<1) | ||
124 | #define S3C2410_UFCON_RESETTX (1<<2) | ||
125 | #define S3C2410_UFCON_RESETRX (1<<1) | ||
126 | |||
127 | #define S3C2410_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \ | ||
128 | S3C2410_UFCON_TXTRIG0 | \ | ||
129 | S3C2410_UFCON_RXTRIG8 ) | ||
130 | |||
131 | #define S3C2410_UMCOM_AFC (1<<4) | ||
132 | #define S3C2410_UMCOM_RTS_LOW (1<<0) | ||
133 | |||
134 | #define S3C2412_UMCON_AFC_63 (0<<5) /* same as s3c2443 */ | ||
135 | #define S3C2412_UMCON_AFC_56 (1<<5) | ||
136 | #define S3C2412_UMCON_AFC_48 (2<<5) | ||
137 | #define S3C2412_UMCON_AFC_40 (3<<5) | ||
138 | #define S3C2412_UMCON_AFC_32 (4<<5) | ||
139 | #define S3C2412_UMCON_AFC_24 (5<<5) | ||
140 | #define S3C2412_UMCON_AFC_16 (6<<5) | ||
141 | #define S3C2412_UMCON_AFC_8 (7<<5) | ||
142 | |||
143 | #define S3C2410_UFSTAT_TXFULL (1<<9) | ||
144 | #define S3C2410_UFSTAT_RXFULL (1<<8) | ||
145 | #define S3C2410_UFSTAT_TXMASK (15<<4) | ||
146 | #define S3C2410_UFSTAT_TXSHIFT (4) | ||
147 | #define S3C2410_UFSTAT_RXMASK (15<<0) | ||
148 | #define S3C2410_UFSTAT_RXSHIFT (0) | ||
149 | |||
150 | /* UFSTAT S3C2443 same as S3C2440 */ | ||
151 | #define S3C2440_UFSTAT_TXFULL (1<<14) | ||
152 | #define S3C2440_UFSTAT_RXFULL (1<<6) | ||
153 | #define S3C2440_UFSTAT_TXSHIFT (8) | ||
154 | #define S3C2440_UFSTAT_RXSHIFT (0) | ||
155 | #define S3C2440_UFSTAT_TXMASK (63<<8) | ||
156 | #define S3C2440_UFSTAT_RXMASK (63) | ||
157 | |||
158 | #define S3C2410_UTRSTAT_TXE (1<<2) | ||
159 | #define S3C2410_UTRSTAT_TXFE (1<<1) | ||
160 | #define S3C2410_UTRSTAT_RXDR (1<<0) | ||
161 | |||
162 | #define S3C2410_UERSTAT_OVERRUN (1<<0) | ||
163 | #define S3C2410_UERSTAT_FRAME (1<<2) | ||
164 | #define S3C2410_UERSTAT_BREAK (1<<3) | ||
165 | #define S3C2443_UERSTAT_PARITY (1<<1) | ||
166 | |||
167 | #define S3C2410_UERSTAT_ANY (S3C2410_UERSTAT_OVERRUN | \ | ||
168 | S3C2410_UERSTAT_FRAME | \ | ||
169 | S3C2410_UERSTAT_BREAK) | ||
170 | |||
171 | #define S3C2410_UMSTAT_CTS (1<<0) | ||
172 | #define S3C2410_UMSTAT_DeltaCTS (1<<2) | ||
173 | |||
174 | #define S3C2443_DIVSLOT (0x2C) | ||
175 | |||
176 | /* S3C64XX interrupt registers. */ | ||
177 | #define S3C64XX_UINTP 0x30 | ||
178 | #define S3C64XX_UINTSP 0x34 | ||
179 | #define S3C64XX_UINTM 0x38 | ||
180 | |||
181 | #define S3C64XX_UINTM_RXD (0) | ||
182 | #define S3C64XX_UINTM_TXD (2) | ||
183 | #define S3C64XX_UINTM_RXD_MSK (1 << S3C64XX_UINTM_RXD) | ||
184 | #define S3C64XX_UINTM_TXD_MSK (1 << S3C64XX_UINTM_TXD) | ||
185 | |||
186 | /* Following are specific to S5PV210 */ | ||
187 | #define S5PV210_UCON_CLKMASK (1<<10) | ||
188 | #define S5PV210_UCON_CLKSHIFT (10) | ||
189 | #define S5PV210_UCON_PCLK (0<<10) | ||
190 | #define S5PV210_UCON_UCLK (1<<10) | ||
191 | |||
192 | #define S5PV210_UFCON_TXTRIG0 (0<<8) | ||
193 | #define S5PV210_UFCON_TXTRIG4 (1<<8) | ||
194 | #define S5PV210_UFCON_TXTRIG8 (2<<8) | ||
195 | #define S5PV210_UFCON_TXTRIG16 (3<<8) | ||
196 | #define S5PV210_UFCON_TXTRIG32 (4<<8) | ||
197 | #define S5PV210_UFCON_TXTRIG64 (5<<8) | ||
198 | #define S5PV210_UFCON_TXTRIG128 (6<<8) | ||
199 | #define S5PV210_UFCON_TXTRIG256 (7<<8) | ||
200 | |||
201 | #define S5PV210_UFCON_RXTRIG1 (0<<4) | ||
202 | #define S5PV210_UFCON_RXTRIG4 (1<<4) | ||
203 | #define S5PV210_UFCON_RXTRIG8 (2<<4) | ||
204 | #define S5PV210_UFCON_RXTRIG16 (3<<4) | ||
205 | #define S5PV210_UFCON_RXTRIG32 (4<<4) | ||
206 | #define S5PV210_UFCON_RXTRIG64 (5<<4) | ||
207 | #define S5PV210_UFCON_RXTRIG128 (6<<4) | ||
208 | #define S5PV210_UFCON_RXTRIG256 (7<<4) | ||
209 | |||
210 | #define S5PV210_UFSTAT_TXFULL (1<<24) | ||
211 | #define S5PV210_UFSTAT_RXFULL (1<<8) | ||
212 | #define S5PV210_UFSTAT_TXMASK (255<<16) | ||
213 | #define S5PV210_UFSTAT_TXSHIFT (16) | ||
214 | #define S5PV210_UFSTAT_RXMASK (255<<0) | ||
215 | #define S5PV210_UFSTAT_RXSHIFT (0) | ||
216 | |||
217 | #define S3C2410_UCON_CLKSEL0 (1 << 0) | ||
218 | #define S3C2410_UCON_CLKSEL1 (1 << 1) | ||
219 | #define S3C2410_UCON_CLKSEL2 (1 << 2) | ||
220 | #define S3C2410_UCON_CLKSEL3 (1 << 3) | ||
221 | |||
222 | /* Default values for s5pv210 UCON and UFCON uart registers */ | ||
223 | #define S5PV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ | ||
224 | S3C2410_UCON_RXILEVEL | \ | ||
225 | S3C2410_UCON_TXIRQMODE | \ | ||
226 | S3C2410_UCON_RXIRQMODE | \ | ||
227 | S3C2410_UCON_RXFIFO_TOI | \ | ||
228 | S3C2443_UCON_RXERR_IRQEN) | ||
229 | |||
230 | #define S5PV210_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \ | ||
231 | S5PV210_UFCON_TXTRIG4 | \ | ||
232 | S5PV210_UFCON_RXTRIG4) | ||
233 | |||
234 | #ifndef __ASSEMBLY__ | ||
235 | |||
236 | /* configuration structure for per-machine configurations for the | ||
237 | * serial port | ||
238 | * | ||
239 | * the pointer is setup by the machine specific initialisation from the | ||
240 | * arch/arm/mach-s3c2410/ directory. | ||
241 | */ | ||
242 | |||
243 | struct s3c2410_uartcfg { | ||
244 | unsigned char hwport; /* hardware port number */ | ||
245 | unsigned char unused; | ||
246 | unsigned short flags; | ||
247 | upf_t uart_flags; /* default uart flags */ | ||
248 | unsigned int clk_sel; | ||
249 | |||
250 | unsigned int has_fracval; | ||
251 | |||
252 | unsigned long ucon; /* value of ucon for port */ | ||
253 | unsigned long ulcon; /* value of ulcon for port */ | ||
254 | unsigned long ufcon; /* value of ufcon for port */ | ||
255 | }; | ||
256 | |||
257 | #endif /* __ASSEMBLY__ */ | ||
258 | |||
259 | #endif /* __ASM_ARM_REGS_SERIAL_H */ | ||
260 | |||
diff --git a/include/linux/tty.h b/include/linux/tty.h index c75d886b0307..367a9dfc4ea2 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
@@ -255,9 +255,9 @@ struct tty_struct { | |||
255 | int count; | 255 | int count; |
256 | struct winsize winsize; /* termios mutex */ | 256 | struct winsize winsize; /* termios mutex */ |
257 | unsigned char stopped:1, hw_stopped:1, flow_stopped:1, packet:1; | 257 | unsigned char stopped:1, hw_stopped:1, flow_stopped:1, packet:1; |
258 | unsigned char warned:1; | ||
259 | unsigned char ctrl_status; /* ctrl_lock */ | 258 | unsigned char ctrl_status; /* ctrl_lock */ |
260 | unsigned int receive_room; /* Bytes free for queue */ | 259 | unsigned int receive_room; /* Bytes free for queue */ |
260 | int flow_change; | ||
261 | 261 | ||
262 | struct tty_struct *link; | 262 | struct tty_struct *link; |
263 | struct fasync_struct *fasync; | 263 | struct fasync_struct *fasync; |
@@ -315,9 +315,25 @@ struct tty_file_private { | |||
315 | #define TTY_NO_WRITE_SPLIT 17 /* Preserve write boundaries to driver */ | 315 | #define TTY_NO_WRITE_SPLIT 17 /* Preserve write boundaries to driver */ |
316 | #define TTY_HUPPED 18 /* Post driver->hangup() */ | 316 | #define TTY_HUPPED 18 /* Post driver->hangup() */ |
317 | #define TTY_HUPPING 21 /* ->hangup() in progress */ | 317 | #define TTY_HUPPING 21 /* ->hangup() in progress */ |
318 | #define TTY_LDISC_HALTED 22 /* Line discipline is halted */ | ||
318 | 319 | ||
319 | #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty)) | 320 | #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty)) |
320 | 321 | ||
322 | /* Values for tty->flow_change */ | ||
323 | #define TTY_THROTTLE_SAFE 1 | ||
324 | #define TTY_UNTHROTTLE_SAFE 2 | ||
325 | |||
326 | static inline void __tty_set_flow_change(struct tty_struct *tty, int val) | ||
327 | { | ||
328 | tty->flow_change = val; | ||
329 | } | ||
330 | |||
331 | static inline void tty_set_flow_change(struct tty_struct *tty, int val) | ||
332 | { | ||
333 | tty->flow_change = val; | ||
334 | smp_mb(); | ||
335 | } | ||
336 | |||
321 | #ifdef CONFIG_TTY | 337 | #ifdef CONFIG_TTY |
322 | extern void console_init(void); | 338 | extern void console_init(void); |
323 | extern void tty_kref_put(struct tty_struct *tty); | 339 | extern void tty_kref_put(struct tty_struct *tty); |
@@ -400,6 +416,8 @@ extern int tty_write_room(struct tty_struct *tty); | |||
400 | extern void tty_driver_flush_buffer(struct tty_struct *tty); | 416 | extern void tty_driver_flush_buffer(struct tty_struct *tty); |
401 | extern void tty_throttle(struct tty_struct *tty); | 417 | extern void tty_throttle(struct tty_struct *tty); |
402 | extern void tty_unthrottle(struct tty_struct *tty); | 418 | extern void tty_unthrottle(struct tty_struct *tty); |
419 | extern int tty_throttle_safe(struct tty_struct *tty); | ||
420 | extern int tty_unthrottle_safe(struct tty_struct *tty); | ||
403 | extern int tty_do_resize(struct tty_struct *tty, struct winsize *ws); | 421 | extern int tty_do_resize(struct tty_struct *tty, struct winsize *ws); |
404 | extern void tty_driver_remove_tty(struct tty_driver *driver, | 422 | extern void tty_driver_remove_tty(struct tty_driver *driver, |
405 | struct tty_struct *tty); | 423 | struct tty_struct *tty); |
@@ -419,13 +437,28 @@ extern void tty_flush_to_ldisc(struct tty_struct *tty); | |||
419 | extern void tty_buffer_free_all(struct tty_port *port); | 437 | extern void tty_buffer_free_all(struct tty_port *port); |
420 | extern void tty_buffer_flush(struct tty_struct *tty); | 438 | extern void tty_buffer_flush(struct tty_struct *tty); |
421 | extern void tty_buffer_init(struct tty_port *port); | 439 | extern void tty_buffer_init(struct tty_port *port); |
422 | extern speed_t tty_get_baud_rate(struct tty_struct *tty); | ||
423 | extern speed_t tty_termios_baud_rate(struct ktermios *termios); | 440 | extern speed_t tty_termios_baud_rate(struct ktermios *termios); |
424 | extern speed_t tty_termios_input_baud_rate(struct ktermios *termios); | 441 | extern speed_t tty_termios_input_baud_rate(struct ktermios *termios); |
425 | extern void tty_termios_encode_baud_rate(struct ktermios *termios, | 442 | extern void tty_termios_encode_baud_rate(struct ktermios *termios, |
426 | speed_t ibaud, speed_t obaud); | 443 | speed_t ibaud, speed_t obaud); |
427 | extern void tty_encode_baud_rate(struct tty_struct *tty, | 444 | extern void tty_encode_baud_rate(struct tty_struct *tty, |
428 | speed_t ibaud, speed_t obaud); | 445 | speed_t ibaud, speed_t obaud); |
446 | |||
447 | /** | ||
448 | * tty_get_baud_rate - get tty bit rates | ||
449 | * @tty: tty to query | ||
450 | * | ||
451 | * Returns the baud rate as an integer for this terminal. The | ||
452 | * termios lock must be held by the caller and the terminal bit | ||
453 | * flags may be updated. | ||
454 | * | ||
455 | * Locking: none | ||
456 | */ | ||
457 | static inline speed_t tty_get_baud_rate(struct tty_struct *tty) | ||
458 | { | ||
459 | return tty_termios_baud_rate(&tty->termios); | ||
460 | } | ||
461 | |||
429 | extern void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old); | 462 | extern void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old); |
430 | extern int tty_termios_hw_change(struct ktermios *a, struct ktermios *b); | 463 | extern int tty_termios_hw_change(struct ktermios *a, struct ktermios *b); |
431 | extern int tty_set_termios(struct tty_struct *tty, struct ktermios *kt); | 464 | extern int tty_set_termios(struct tty_struct *tty, struct ktermios *kt); |
@@ -502,6 +535,8 @@ extern int tty_port_carrier_raised(struct tty_port *port); | |||
502 | extern void tty_port_raise_dtr_rts(struct tty_port *port); | 535 | extern void tty_port_raise_dtr_rts(struct tty_port *port); |
503 | extern void tty_port_lower_dtr_rts(struct tty_port *port); | 536 | extern void tty_port_lower_dtr_rts(struct tty_port *port); |
504 | extern void tty_port_hangup(struct tty_port *port); | 537 | extern void tty_port_hangup(struct tty_port *port); |
538 | extern void tty_port_tty_hangup(struct tty_port *port, bool check_clocal); | ||
539 | extern void tty_port_tty_wakeup(struct tty_port *port); | ||
505 | extern int tty_port_block_til_ready(struct tty_port *port, | 540 | extern int tty_port_block_til_ready(struct tty_port *port, |
506 | struct tty_struct *tty, struct file *filp); | 541 | struct tty_struct *tty, struct file *filp); |
507 | extern int tty_port_close_start(struct tty_port *port, | 542 | extern int tty_port_close_start(struct tty_port *port, |
@@ -526,8 +561,6 @@ extern void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty); | |||
526 | extern void tty_ldisc_init(struct tty_struct *tty); | 561 | extern void tty_ldisc_init(struct tty_struct *tty); |
527 | extern void tty_ldisc_deinit(struct tty_struct *tty); | 562 | extern void tty_ldisc_deinit(struct tty_struct *tty); |
528 | extern void tty_ldisc_begin(void); | 563 | extern void tty_ldisc_begin(void); |
529 | /* This last one is just for the tty layer internals and shouldn't be used elsewhere */ | ||
530 | extern void tty_ldisc_enable(struct tty_struct *tty); | ||
531 | 564 | ||
532 | 565 | ||
533 | /* n_tty.c */ | 566 | /* n_tty.c */ |
diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h index 455a0d7bf220..58390c73df8b 100644 --- a/include/linux/tty_ldisc.h +++ b/include/linux/tty_ldisc.h | |||
@@ -9,89 +9,89 @@ | |||
9 | * | 9 | * |
10 | * int (*open)(struct tty_struct *); | 10 | * int (*open)(struct tty_struct *); |
11 | * | 11 | * |
12 | * This function is called when the line discipline is associated | 12 | * This function is called when the line discipline is associated |
13 | * with the tty. The line discipline can use this as an | 13 | * with the tty. The line discipline can use this as an |
14 | * opportunity to initialize any state needed by the ldisc routines. | 14 | * opportunity to initialize any state needed by the ldisc routines. |
15 | * | 15 | * |
16 | * void (*close)(struct tty_struct *); | 16 | * void (*close)(struct tty_struct *); |
17 | * | 17 | * |
18 | * This function is called when the line discipline is being | 18 | * This function is called when the line discipline is being |
19 | * shutdown, either because the tty is being closed or because | 19 | * shutdown, either because the tty is being closed or because |
20 | * the tty is being changed to use a new line discipline | 20 | * the tty is being changed to use a new line discipline |
21 | * | 21 | * |
22 | * void (*flush_buffer)(struct tty_struct *tty); | 22 | * void (*flush_buffer)(struct tty_struct *tty); |
23 | * | 23 | * |
24 | * This function instructs the line discipline to clear its | 24 | * This function instructs the line discipline to clear its |
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); | 28 | * ssize_t (*chars_in_buffer)(struct tty_struct *tty); |
29 | * | 29 | * |
30 | * This function returns the number of input characters the line | 30 | * This function returns the number of input characters the line |
31 | * discipline may have queued up to be delivered to the user mode | 31 | * discipline may have queued up to be delivered to the user mode |
32 | * process. | 32 | * process. |
33 | * | 33 | * |
34 | * ssize_t (*read)(struct tty_struct * tty, struct file * file, | 34 | * ssize_t (*read)(struct tty_struct * tty, struct file * file, |
35 | * unsigned char * buf, size_t nr); | 35 | * unsigned char * buf, size_t nr); |
36 | * | 36 | * |
37 | * This function is called when the user requests to read from | 37 | * This function is called when the user requests to read from |
38 | * the tty. The line discipline will return whatever characters | 38 | * the tty. The line discipline will return whatever characters |
39 | * it has buffered up for the user. If this function is not | 39 | * it has buffered up for the user. If this function is not |
40 | * defined, the user will receive an EIO error. | 40 | * defined, the user will receive an EIO error. |
41 | * | 41 | * |
42 | * ssize_t (*write)(struct tty_struct * tty, struct file * file, | 42 | * ssize_t (*write)(struct tty_struct * tty, struct file * file, |
43 | * const unsigned char * buf, size_t nr); | 43 | * const unsigned char * buf, size_t nr); |
44 | * | 44 | * |
45 | * This function is called when the user requests to write to the | 45 | * This function is called when the user requests to write to the |
46 | * tty. The line discipline will deliver the characters to the | 46 | * tty. The line discipline will deliver the characters to the |
47 | * low-level tty device for transmission, optionally performing | 47 | * low-level tty device for transmission, optionally performing |
48 | * some processing on the characters first. If this function is | 48 | * some processing on the characters first. If this function is |
49 | * not defined, the user will receive an EIO error. | 49 | * not defined, the user will receive an EIO error. |
50 | * | 50 | * |
51 | * int (*ioctl)(struct tty_struct * tty, struct file * file, | 51 | * int (*ioctl)(struct tty_struct * tty, struct file * file, |
52 | * unsigned int cmd, unsigned long arg); | 52 | * unsigned int cmd, unsigned long arg); |
53 | * | 53 | * |
54 | * This function is called when the user requests an ioctl which | 54 | * This function is called when the user requests an ioctl which |
55 | * is not handled by the tty layer or the low-level tty driver. | 55 | * is not handled by the tty layer or the low-level tty driver. |
56 | * It is intended for ioctls which affect line discpline | 56 | * It is intended for ioctls which affect line discpline |
57 | * operation. Note that the search order for ioctls is (1) tty | 57 | * operation. Note that the search order for ioctls is (1) tty |
58 | * layer, (2) tty low-level driver, (3) line discpline. So a | 58 | * layer, (2) tty low-level driver, (3) line discpline. So a |
59 | * low-level driver can "grab" an ioctl request before the line | 59 | * low-level driver can "grab" an ioctl request before the line |
60 | * discpline has a chance to see it. | 60 | * discpline has a chance to see it. |
61 | * | 61 | * |
62 | * long (*compat_ioctl)(struct tty_struct * tty, struct file * file, | 62 | * long (*compat_ioctl)(struct tty_struct * tty, struct file * file, |
63 | * unsigned int cmd, unsigned long arg); | 63 | * unsigned int cmd, unsigned long arg); |
64 | * | 64 | * |
65 | * Process ioctl calls from 32-bit process on 64-bit system | 65 | * Process ioctl calls from 32-bit process on 64-bit system |
66 | * | 66 | * |
67 | * void (*set_termios)(struct tty_struct *tty, struct ktermios * old); | 67 | * void (*set_termios)(struct tty_struct *tty, struct ktermios * old); |
68 | * | 68 | * |
69 | * This function notifies the line discpline that a change has | 69 | * This function notifies the line discpline that a change has |
70 | * been made to the termios structure. | 70 | * been made to the termios structure. |
71 | * | 71 | * |
72 | * int (*poll)(struct tty_struct * tty, struct file * file, | 72 | * int (*poll)(struct tty_struct * tty, struct file * file, |
73 | * poll_table *wait); | 73 | * poll_table *wait); |
74 | * | 74 | * |
75 | * This function is called when a user attempts to select/poll on a | 75 | * This function is called when a user attempts to select/poll on a |
76 | * tty device. It is solely the responsibility of the line | 76 | * tty device. It is solely the responsibility of the line |
77 | * discipline to handle poll requests. | 77 | * discipline to handle poll requests. |
78 | * | 78 | * |
79 | * void (*receive_buf)(struct tty_struct *, const unsigned char *cp, | 79 | * void (*receive_buf)(struct tty_struct *, const unsigned char *cp, |
80 | * char *fp, int count); | 80 | * char *fp, int count); |
81 | * | 81 | * |
82 | * This function is called by the low-level tty driver to send | 82 | * This function is called by the low-level tty driver to send |
83 | * characters received by the hardware to the line discpline for | 83 | * characters received by the hardware to the line discpline for |
84 | * processing. <cp> is a pointer to the buffer of input | 84 | * processing. <cp> is a pointer to the buffer of input |
85 | * character received by the device. <fp> is a pointer to a | 85 | * character received by the device. <fp> is a pointer to a |
86 | * pointer of flag bytes which indicate whether a character was | 86 | * pointer of flag bytes which indicate whether a character was |
87 | * received with a parity error, etc. | 87 | * received with a parity error, etc. |
88 | * | 88 | * |
89 | * void (*write_wakeup)(struct tty_struct *); | 89 | * void (*write_wakeup)(struct tty_struct *); |
90 | * | 90 | * |
91 | * This function is called by the low-level tty driver to signal | 91 | * This function is called by the low-level tty driver to signal |
92 | * that line discpline should try to send more characters to the | 92 | * that line discpline should try to send more characters to the |
93 | * low-level driver for transmission. If the line discpline does | 93 | * low-level driver for transmission. If the line discpline does |
94 | * not have any more data to send, it can just return. | 94 | * not have any more data to send, it can just return. |
95 | * | 95 | * |
96 | * int (*hangup)(struct tty_struct *) | 96 | * int (*hangup)(struct tty_struct *) |
97 | * | 97 | * |
@@ -115,7 +115,7 @@ struct tty_ldisc_ops { | |||
115 | char *name; | 115 | char *name; |
116 | int num; | 116 | int num; |
117 | int flags; | 117 | int flags; |
118 | 118 | ||
119 | /* | 119 | /* |
120 | * The following routines are called from above. | 120 | * The following routines are called from above. |
121 | */ | 121 | */ |
@@ -123,19 +123,19 @@ struct tty_ldisc_ops { | |||
123 | void (*close)(struct tty_struct *); | 123 | void (*close)(struct tty_struct *); |
124 | void (*flush_buffer)(struct tty_struct *tty); | 124 | void (*flush_buffer)(struct tty_struct *tty); |
125 | ssize_t (*chars_in_buffer)(struct tty_struct *tty); | 125 | ssize_t (*chars_in_buffer)(struct tty_struct *tty); |
126 | ssize_t (*read)(struct tty_struct * tty, struct file * file, | 126 | ssize_t (*read)(struct tty_struct *tty, struct file *file, |
127 | unsigned char __user * buf, size_t nr); | 127 | unsigned char __user *buf, size_t nr); |
128 | ssize_t (*write)(struct tty_struct * tty, struct file * file, | 128 | ssize_t (*write)(struct tty_struct *tty, struct file *file, |
129 | const unsigned char * buf, size_t nr); | 129 | const unsigned char *buf, size_t nr); |
130 | int (*ioctl)(struct tty_struct * tty, struct file * file, | 130 | int (*ioctl)(struct tty_struct *tty, struct file *file, |
131 | unsigned int cmd, unsigned long arg); | 131 | unsigned int cmd, unsigned long arg); |
132 | long (*compat_ioctl)(struct tty_struct * tty, struct file * file, | 132 | long (*compat_ioctl)(struct tty_struct *tty, struct file *file, |
133 | unsigned int cmd, unsigned long arg); | 133 | unsigned int cmd, unsigned long arg); |
134 | void (*set_termios)(struct tty_struct *tty, struct ktermios * old); | 134 | void (*set_termios)(struct tty_struct *tty, struct ktermios *old); |
135 | unsigned int (*poll)(struct tty_struct *, struct file *, | 135 | unsigned int (*poll)(struct tty_struct *, struct file *, |
136 | struct poll_table_struct *); | 136 | struct poll_table_struct *); |
137 | int (*hangup)(struct tty_struct *tty); | 137 | int (*hangup)(struct tty_struct *tty); |
138 | 138 | ||
139 | /* | 139 | /* |
140 | * The following routines are called from below. | 140 | * The following routines are called from below. |
141 | */ | 141 | */ |
@@ -145,7 +145,7 @@ struct tty_ldisc_ops { | |||
145 | void (*dcd_change)(struct tty_struct *, unsigned int); | 145 | void (*dcd_change)(struct tty_struct *, unsigned int); |
146 | 146 | ||
147 | struct module *owner; | 147 | struct module *owner; |
148 | 148 | ||
149 | int refcount; | 149 | int refcount; |
150 | }; | 150 | }; |
151 | 151 | ||
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c index 362ba47968e4..41ac7938268b 100644 --- a/net/irda/ircomm/ircomm_tty.c +++ b/net/irda/ircomm/ircomm_tty.c | |||
@@ -328,7 +328,7 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self, | |||
328 | spin_unlock_irqrestore(&port->lock, flags); | 328 | spin_unlock_irqrestore(&port->lock, flags); |
329 | 329 | ||
330 | while (1) { | 330 | while (1) { |
331 | if (tty->termios.c_cflag & CBAUD) | 331 | if (C_BAUD(tty) && test_bit(ASYNCB_INITIALIZED, &port->flags)) |
332 | tty_port_raise_dtr_rts(port); | 332 | tty_port_raise_dtr_rts(port); |
333 | 333 | ||
334 | set_current_state(TASK_INTERRUPTIBLE); | 334 | set_current_state(TASK_INTERRUPTIBLE); |
diff --git a/net/irda/ircomm/ircomm_tty_attach.c b/net/irda/ircomm/ircomm_tty_attach.c index edab393e0c82..a2a508f5f268 100644 --- a/net/irda/ircomm/ircomm_tty_attach.c +++ b/net/irda/ircomm/ircomm_tty_attach.c | |||
@@ -997,12 +997,8 @@ static int ircomm_tty_state_ready(struct ircomm_tty_cb *self, | |||
997 | self->settings.dce = IRCOMM_DELTA_CD; | 997 | self->settings.dce = IRCOMM_DELTA_CD; |
998 | ircomm_tty_check_modem_status(self); | 998 | ircomm_tty_check_modem_status(self); |
999 | } else { | 999 | } else { |
1000 | struct tty_struct *tty = tty_port_tty_get(&self->port); | ||
1001 | IRDA_DEBUG(0, "%s(), hanging up!\n", __func__ ); | 1000 | IRDA_DEBUG(0, "%s(), hanging up!\n", __func__ ); |
1002 | if (tty) { | 1001 | tty_port_tty_hangup(&self->port, false); |
1003 | tty_hangup(tty); | ||
1004 | tty_kref_put(tty); | ||
1005 | } | ||
1006 | } | 1002 | } |
1007 | break; | 1003 | break; |
1008 | default: | 1004 | default: |